/***************************************************************************
    begin                :  2003-07-01 17:33:00 CEST 2003
    copyright            : (C) 2003 by Jeroen Wijnhout
    email                :  Jeroen.Wijnhout@kdemail.net
 ***************************************************************************/

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

// 2005-07-26 dani
//  - cleanup dialog
//  - added new action 'ShowLabel'

// 2007-03-12 dani
//  - use KileDocument::Extensions

#include "kileactions.h"

#include <tqstring.h>
#include <tqstringlist.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqcheckbox.h>
#include <tqfileinfo.h>

#include <klineedit.h>
#include <tdeglobal.h>
#include <kcombobox.h>
#include <kpushbutton.h>
#include <tdelocale.h>
#include <tdefiledialog.h>
#include <kiconloader.h>

#include "kiledebug.h"

#include "kileinfo.h"
#include "kiledocmanager.h"

namespace KileAction
{

////////////////
//    Tag     //
////////////////
Tag::Tag( const TQString &text, const TDEShortcut &cut, const TQObject *receiver, const char *slot, TDEActionCollection *parent
	, const char *name, const TQString &tagBegin, const TQString &tagEnd
	, int dx, int dy, const TQString &description)
	: TDEAction(text, cut, parent, name),
	  m_data(text,tagBegin, tagEnd, dx, dy, description)
{
	init(receiver,slot);
}

Tag::Tag( const TQString &text, const TQString& pix, const TDEShortcut &cut, const TQObject *receiver, const char *slot, TDEActionCollection *parent
	, const char *name, const TQString &tagBegin, const TQString &tagEnd
	, int dx, int dy, const TQString &description)
	: TDEAction(text, pix, cut, parent, name),
	  m_data(text,tagBegin, tagEnd, dx, dy, description)
{
	init(receiver,slot);
}

Tag::Tag( const TQString &text, const TDEShortcut &cut, const TQObject *receiver, const char *slot, TDEActionCollection *parent
	, const char *name, const TagData& data)
	: TDEAction(text, cut, parent, name),
	  m_data(data)
{
	init(receiver,slot);
}

Tag::Tag( const TQString &text, const TQString& pix, const TDEShortcut &cut, const TQObject *receiver, const char *slot, TDEActionCollection *parent
	, const char *name, const TagData& data)
	: TDEAction(text, pix, cut, parent, name),
	  m_data(data)
{
	init(receiver,slot);
}

Tag::~Tag()
{
}

void Tag::init(const TQObject *receiver, const char *slot)
{
	connect(this, TQ_SIGNAL(activated()), TQ_SLOT(emitData()));
	connect(this, TQ_SIGNAL(activated(const KileAction::TagData&)), receiver, slot);
}

void Tag::emitData()
{
	emit(activated(m_data));
}

////////////////
//    InputTag     //
////////////////
InputTag::InputTag(KileInfo* ki, const TQString &text, const TDEShortcut &cut, const TQObject *receiver, const char *slot, TDEActionCollection *parent, const char *name, TQWidget *wparent, uint options
	, const TQString &tagBegin, const TQString &tagEnd
	, int dx, int dy, const TQString &description, const TQString &hint, const TQString &alter)
	: Tag(text, cut, receiver, slot, parent, name, tagBegin, tagEnd, dx, dy, description), m_ki(ki),
	  m_parent(wparent), m_options(options), m_hint(hint), m_alter(alter)
{
	init();
}

InputTag::InputTag( KileInfo* ki, const TQString &text, const TQString& pix, const TDEShortcut &cut, const TQObject *receiver, const char *slot, TDEActionCollection *parent, const char *name, TQWidget *wparent,uint options
	, const TQString &tagBegin, const TQString &tagEnd
	, int dx, int dy, const TQString &description, const TQString &hint, const TQString &alter)
	: Tag(text, pix, cut, receiver, slot, parent, name, tagBegin, tagEnd, dx, dy, description), m_ki(ki),
	  m_parent(wparent), m_options(options), m_hint(hint), m_alter(alter)
{
	init();
}

InputTag::InputTag( KileInfo* ki, const TQString &text, const TDEShortcut &cut, const TQObject *receiver, const char *slot, TDEActionCollection *parent, const char *name, TQWidget *wparent,uint options
	, const TagData& data, const TQString &hint, const TQString &alter)
	: Tag(text,cut,receiver, slot, parent, name,data),  m_ki(ki),
	  m_parent(wparent), m_options(options), m_hint(hint), m_alter(alter)
{
	init();
}

InputTag::InputTag( KileInfo* ki, const TQString &text, const TQString& pix, const TDEShortcut &cut, const TQObject *receiver, const char *slot, TDEActionCollection *parent, const char *name, TQWidget *wparent,uint options
	, const TagData& data, const TQString &hint, const TQString &alter)
	: Tag(text, pix, cut,receiver, slot, parent, name,data), m_ki(ki),
	  m_parent(wparent), m_options(options), m_hint(hint), m_alter(alter)
{
	init();
}

InputTag::~InputTag()
{
}

void InputTag::init()
{
	m_history.clear();
}

void InputTag::emitData()
{
	KILE_DEBUG() << "InputTag::emitData() " << m_ki->getName() << endl;

	InputDialog *dlg = new InputDialog(m_data.text, m_options, m_history, m_hint, m_alter, m_ki, m_parent, "input_dialog");
	if (dlg->exec())
	{
		if ( (! dlg->tag().isEmpty()) && hasHistory()) addToHistory(dlg->tag());

		TagData td(m_data);

		td.tagBegin.replace("%R",dlg->tag());
		td.tagEnd.replace("%R",dlg->tag());

		TQString alt = dlg->useAlternative() ? "*" : "";
		td.tagBegin.replace("%A", alt);
		td.tagEnd.replace("%A", alt);

		if ( dlg->useLabel() ) 
		{
			td.tagEnd += dlg->label();
			td.dy++;
		}

		if (dlg->usedSelection())
			m_ki->clearSelection();
			
		// if a filename was given for a \input- or \include-command,
		// the cursor is moved out of the braces
		if ( (m_options & KileAction::ShowBrowseButton) && !dlg->tag().isEmpty() )
			td.dx += dlg->tag().length() + 1;

		// insert tag
		emit(activated(td));
		// refresh document structure and project tree when a file was inserted
		if ( dlg->useAddProjectFile() ) 
		{
			m_ki->docManager()->projectAddFile( TQFileInfo(m_ki->getCompileName()).dirPath(true) + '/' + dlg->tag() );
		}
	}
	delete dlg;
}


/*
	InputDialog
*/
InputDialog::InputDialog(const TQString &caption, uint options, const TQStringList& history, const TQString& hint, const TQString& alter, KileInfo *ki, TQWidget *parent, const char *name)
	: KDialogBase (parent, name, true, caption, KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok, true), m_ki(ki)
{
	TQString newcaption = caption;
	setCaption(newcaption.remove("&"));
	m_labelprefix = ( newcaption == "chapter" ) ? "chap:" : "sec:";
	
	m_usedSelection = false;

	TQWidget *page = new TQWidget(this);
	setMainWidget(page);
	TQGridLayout *gbox = new TQGridLayout( page, 6,3,5,5,"");

	TQLabel *lb = new TQLabel(hint, page);
	gbox->addMultiCellWidget(lb,0,0,0,2);

	m_tag=TQString();
	TQWidget *focus;
	if ( (options & KileAction::KeepHistory) || (options & KileAction::FromLabelList) || (options & KileAction::FromBibItemList) )
	{
		KComboBox *input = new KComboBox(true, page, "input_dialog_input");
		input->setCompletionMode(TDEGlobalSettings::CompletionAuto);
		input->setMinimumWidth(300);
		focus = input;

		connect(input, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(setTag(const TQString&)));
		connect(this,  TQ_SIGNAL(setInput(const TQString&)), input, TQ_SLOT(setEditText(const TQString&)));
		if ( options & KileAction::ShowBrowseButton )
			gbox->addWidget(input,1,0);
		else
			gbox->addMultiCellWidget(input,1,1,0,2);

		const TQStringList *list;

		if (options & KileAction::FromLabelList)
		{
			list = ki->allLabels();
			input->insertStringList(*list);
			m_tag = list->first();
		}
		else
		if (options & KileAction::FromBibItemList)
		{
			list = ki->allBibItems();
			input->insertStringList(*list);
			m_tag = list->first();
		}
		else
		{
			if (history.size()>0)
			{
				input->insertStringList(history);
				m_tag = history.first();
			}
		}
	}
	else
	{
		KLineEdit *input = new KLineEdit(page);
		input->setMinimumWidth(300);
		focus = input;

		connect(input, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(setTag(const TQString&)));
		connect(this,  TQ_SIGNAL(setInput(const TQString&)), input, TQ_SLOT(setText(const TQString&)));
		if ( options & KileAction::ShowBrowseButton )
			gbox->addWidget(input,1,0);
		else
			gbox->addMultiCellWidget(input,1,1,0,2);

		input->setText(ki->getSelection());
		m_usedSelection=true;
	}

	if (focus)
		lb->setBuddy(focus);

	if ( options & KileAction::ShowBrowseButton)
	{
		KPushButton *pbutton = new KPushButton("", page);
		pbutton->setPixmap( SmallIcon("document-open") );
		gbox->addWidget(pbutton,1,2);
		gbox->setColSpacing(1,8);	
		gbox->setColSpacing(2, pbutton->sizeHint().width()+5 ); 
		connect(pbutton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotBrowse()));
	}

	if ( options & KileAction::ShowAlternative)
	{
		TQCheckBox * m_checkbox = new TQCheckBox(alter, page, "input_dialog_checkbox");
		connect(m_checkbox, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotAltClicked()));
		m_useAlternative=false;
		gbox->addMultiCellWidget(m_checkbox,2,2,0,2);
	}

	m_edLabel = 0L;
	m_useLabel = ( options & KileAction::ShowLabel );
	if ( m_useLabel )
	{
		// Label
		TQLabel *label = new TQLabel(i18n("&Label:"),page);
		m_edLabel = new KLineEdit("",page);
		m_edLabel->setMinimumWidth(300);
		m_edLabel->setText(m_labelprefix);
		label->setBuddy(m_edLabel);
		gbox->addMultiCellWidget(label,3,3,0,2);
		gbox->addMultiCellWidget(m_edLabel,4,4,0,2);
	}

	m_useAddProjectFile = ( options & KileAction::AddProjectFile );
	
	gbox->setRowStretch(5,1);
	gbox->setColStretch(0,1);
	
	focus->setFocus();
}


InputDialog::~InputDialog()
{
}

void InputDialog::slotBrowse()
{
	TQString fn;
	TQFileInfo fi(m_ki->getCompileName());

	// Called from InputDialog after a \input- or \include command:
	// so we are only looking for a LaTeX source document
	TQString filter = m_ki->extensions()->latexDocumentFileFilter() + '\n' + "*|" + i18n("All Files");

	fn = KFileDialog::getOpenFileName(fi.absFilePath(), filter, this,i18n("Select File") );
	if ( !fn.isEmpty() )
	{
		TQString path = m_ki->relativePath(fi.dirPath(), fn);

		// if the file has no extension, we add the default TeX extension
		if ( TQFileInfo(path).extension().isEmpty() )
			path += m_ki->extensions()->latexDocumentDefault();
 
		setTag(path);
		emit(setInput(path));
	}
}

void InputDialog::slotAltClicked()
{
	m_useAlternative = !m_useAlternative;
}

void InputDialog::setTag(const TQString &tag)
{
	m_tag = tag;
}

TQString InputDialog::label()
{
	if ( m_edLabel ) 
	{
		TQString label = m_edLabel->text().stripWhiteSpace();
		if ( !label.isEmpty() && label!=m_labelprefix )
			return "\\label{" + label + "}\n";
	}
	
	return TQString();
}

/////////////////
//  SelectTag  //
/////////////////

Select::Select(const TQString &text, const TDEShortcut &cut, TDEActionCollection *parent, const char *name )
	: TDESelectAction(text,cut,parent,name)
{
	init();
}

void Select::init()
{
	connect(this, TQ_SIGNAL(activated(const TQString&)), TQ_SLOT(emitData(const TQString &)));
}

void Select::emitData(const TQString & name)
{
	m_dict[name]->activate();
}

void Select::setItems(TQPtrList<TDEAction>& list)
{
	TQStringList tmp;

	for (uint i=0; i < list.count(); ++i)
	{
		tmp.append(list.at(i)->text());
		m_dict.insert(list.at(i)->text(), list.at(i));
	}

	TDESelectAction::setItems(tmp);
}

}

#include "kileactions.moc"
