/* This file is part of the KDE project
   Copyright (C) 2005-2006 Jaroslaw Staniek <js@iidea.pl>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#include "kexiactionselectiondialog.h"
#include "kexiactionselectiondialog_p.h"

#include <keximainwindow.h>
#include <kexipartitem.h>
#include <kexiproject.h>
#include <kexipartinfo.h>
#include <kexipart.h>
#include <kexiactioncategories.h>

#include <tdelistview.h>
#include <tdeaction.h>
#include <kiconloader.h>
#include <kdebug.h>
#include <kstdguiitem.h>
#include <kpushbutton.h>

#include <tqbitmap.h>
#include <tqlabel.h>
#include <tqheader.h>
#include <tqvbox.h>
#include <tqtooltip.h>
#include <tqwidgetstack.h>

#include <widget/utils/tdelistviewitemtemplate.h>
#include <widget/kexibrowser.h>
#include <widget/kexibrowseritem.h>
#include <kexiutils/utils.h>

typedef TDEListViewItemTemplate<TQString> ActionSelectorDialogListItemBase;

class ActionSelectorDialogListItem : public ActionSelectorDialogListItemBase
{
public:
	ActionSelectorDialogListItem(const TQString& data, TQListView *parent, TQString label1)
	 : ActionSelectorDialogListItemBase(data, parent, label1)
	 , fifoSorting(true)
	{
		m_sortKey.sprintf("%2.2d", parent->childCount());
	}

	ActionSelectorDialogListItem(const TQString& data, TQListViewItem *parent, TQString label1)
	 : ActionSelectorDialogListItemBase(data, parent, label1)
	 , fifoSorting(true)
	{
		m_sortKey.sprintf("%2.2d", parent->childCount());
	}

	virtual TQString key( int column, bool ascending ) const
	{
		return fifoSorting ? m_sortKey : ActionSelectorDialogListItemBase::key(column, ascending);
	}

	bool fifoSorting : 1;

protected:
	TQString m_sortKey;
};

//---------------------------------------

ActionsListViewBase::ActionsListViewBase(TQWidget* parent)
 : TDEListView(parent)
{
	setResizeMode(TQListView::AllColumns);
	addColumn("");
	header()->hide();
	setColumnWidthMode(0, TQListView::Maximum);
	setAllColumnsShowFocus(true);
	setTooltipColumn(0);
}

ActionsListViewBase::~ActionsListViewBase()
{
}

TQListViewItem *ActionsListViewBase::itemForAction(const TQString& actionName)
{
	for (TQListViewItemIterator it(this); it.current(); ++it) {
		ActionSelectorDialogListItem* item = dynamic_cast<ActionSelectorDialogListItem*>(it.current());
		if (item && item->data == actionName)
			return item;
	}
	return 0;
}

void ActionsListViewBase::selectAction(const TQString& actionName)
{
	TQListViewItem *item = itemForAction(actionName);
	if (item) {
		setSelected(item, true);
		ensureItemVisible(firstChild());
		ensureItemVisible(selectedItem());
	}
}

//---------------------------------------

TDEActionsListViewBase::TDEActionsListViewBase(TQWidget* parent, KexiMainWindow* mainWin)
	: ActionsListViewBase(parent)
	, m_mainWin(mainWin)
{
}

TDEActionsListViewBase::~TDEActionsListViewBase() {}

void TDEActionsListViewBase::init()
{
	setSorting(0);
	const TQPixmap noIcon( KexiUtils::emptyIcon(TDEIcon::Small) );
	TDEActionPtrList sharedActions( m_mainWin->allActions() );
	const Kexi::ActionCategories *acat = Kexi::actionCategories();
	foreach (TDEActionPtrList::ConstIterator, it, sharedActions) {
//			kdDebug() << (*it)->name() << " " << (*it)->text() << endl;
		//! @todo group actions
		//! @todo: store TDEAction* here?
		const int actionCategories = acat->actionCategories((*it)->name());
		if (actionCategories==-1) {
			kexipluginswarn << "TDEActionsListViewBase(): no category declared for action \"" 
				<< (*it)->name() << "\"! Fix this!" << endl;
			continue;
		}
		if (!isActionVisible((*it)->name(), actionCategories))
			continue;
		ActionSelectorDialogListItem *pitem = new ActionSelectorDialogListItem((*it)->name(), 
			this, (*it)->toolTip().isEmpty() ? (*it)->text().replace("&", "") : (*it)->toolTip() );
		pitem->fifoSorting = false; //alpha sort
		pitem->setPixmap( 0, (*it)->iconSet( TDEIcon::Small, 16 ).pixmap( TQIconSet::Small, TQIconSet::Active ) );
		if (!pitem->pixmap(0) || pitem->pixmap(0)->isNull())
			pitem->setPixmap( 0, noIcon );
	}
}

//---------------------------------------

//! @internal Used to display TDEActions (in column 2)
class TDEActionsListView : public TDEActionsListViewBase
{
public:
	TDEActionsListView(TQWidget* parent, KexiMainWindow* mainWin)
		: TDEActionsListViewBase(parent, mainWin)
	{
	}
	virtual ~TDEActionsListView() {}

	virtual bool isActionVisible(const char* actionName, int actionCategories) const {
		Q_UNUSED(actionName);
		return actionCategories & Kexi::GlobalActionCategory;
	}
};

//! @internal Used to display TDEActions (in column 2)
class CurrentFormActionsListView : public TDEActionsListViewBase
{
public:
	CurrentFormActionsListView(TQWidget* parent, KexiMainWindow* mainWin)
		: TDEActionsListViewBase(parent, mainWin)
	{
	}
	virtual ~CurrentFormActionsListView() {}

	virtual bool isActionVisible(const char* actionName, int actionCategories) const {
		return actionCategories & Kexi::WindowActionCategory
				&& Kexi::actionCategories()->actionSupportsObjectType(actionName, KexiPart::FormObjectType);
	}
};

//! @internal a list view displaying action categories user can select from (column 1)
class ActionCategoriesListView : public ActionsListViewBase
{
public:
	ActionCategoriesListView(TQWidget* parent) //, KexiProject& project)
	 : ActionsListViewBase(parent)
	{
		TQListViewItem *item = new ActionSelectorDialogListItem("noaction", this, i18n("No action") );
		const TQPixmap noIcon( KexiUtils::emptyIcon(TDEIcon::Small) );
		item->setPixmap(0, noIcon);
		item = new ActionSelectorDialogListItem("tdeaction", this, i18n("Application actions") );
		item->setPixmap(0, SmallIcon("form_action"));

		KexiPart::PartInfoList *pl = Kexi::partManager().partInfoList();
		for (KexiPart::Info *info = pl->first(); info; info = pl->next()) {
			KexiPart::Part *part = Kexi::partManager().part(info);
			if (!info->isVisibleInNavigator() || !part)
				continue;
			item = new KexiBrowserItem(this, info);
			item->setText(0, part->instanceCaption());
		}
		TQListViewItem *formItem = itemForAction("form");
		if (formItem) {
			item = new ActionSelectorDialogListItem("currentForm", formItem, 
				i18n("Current form's actions", "Current"));
		}
		adjustColumn(0);
		setMinimumWidth( columnWidth(0) + 6 );
	}

	~ActionCategoriesListView()
	{
	}

	//! \return item for action \a actionName, reimplemented to support KexiBrowserItem items
	virtual TQListViewItem *itemForAction(const TQString& actionName)
	{
		for (TQListViewItemIterator it(this); it.current(); ++it) {
			//simple case
			ActionSelectorDialogListItem* item = dynamic_cast<ActionSelectorDialogListItem*>(it.current());
			if (item) {
				if (item->data == actionName)
					return it.current();
				continue;
			}
			KexiBrowserItem* bitem = dynamic_cast<KexiBrowserItem*>(it.current());
			if (bitem) {
				if (bitem->info()->objectName() == actionName)
					return it.current();
			}
		}
		return 0;
	}
};

//! @internal Used to display list of actions available to executing (column 3)
class ActionToExecuteListView : public ActionsListViewBase
{
	public:
		ActionToExecuteListView(TQWidget* parent)
		 : ActionsListViewBase(parent)
		{
		}

		~ActionToExecuteListView()
		{
		}

		//! Updates actions
		void showActionsForMimeType(const TQString& mimeType) {
			if (m_currentMimeType == mimeType)
				return;
			m_currentMimeType = mimeType;
			clear();
			KexiPart::Part *part = Kexi::partManager().partForMimeType( m_currentMimeType );
			if (!part)
				return;
			int supportedViewModes = part->supportedViewModes();
			ActionSelectorDialogListItem *item;
			const TQPixmap noIcon( KexiUtils::emptyIcon(TDEIcon::Small) );
			if (supportedViewModes & Kexi::DataViewMode) {
				item = new ActionSelectorDialogListItem("open", this, i18n("Open in Data View"));
				item->setPixmap(0, SmallIcon("fileopen"));
			}
			if (part->info()->isExecuteSupported()) {
				item = new ActionSelectorDialogListItem("execute", this, i18n("Execute"));
				item->setPixmap(0, SmallIcon("player_play"));
			}
			if (part->info()->isPrintingSupported()) {
				ActionSelectorDialogListItem *printItem = new ActionSelectorDialogListItem(
					"print", this, i18n("Print"));
				printItem->setPixmap(0, SmallIcon("fileprint"));
				TDEAction *a = KStdAction::printPreview(0, 0, 0);
				item = new ActionSelectorDialogListItem("printPreview", printItem, 
					a->text().replace("&", "").replace("...", ""));
				item->setPixmap(0, SmallIcon(a->icon()));
				delete a;
				item = new ActionSelectorDialogListItem("pageSetup", printItem, i18n("Show Page Setup"));
				item->setPixmap(0, noIcon);
				setOpen(printItem, true);
				printItem->setExpandable(false);
			}
			if (part->info()->isDataExportSupported()) {
				ActionSelectorDialogListItem *exportItem = new ActionSelectorDialogListItem(
					"exportToCSV", this, 
					i18n("Note: use multiple rows if needed", "Export to File\nAs Data Table"));
				exportItem->setMultiLinesEnabled(true);
				exportItem->setPixmap(0, SmallIcon("table"));
				item = new ActionSelectorDialogListItem("copyToClipboardAsCSV", 
					exportItem, 
					i18n("Note: use multiple rows if needed", "Copy to Clipboard\nAs Data Table"));
				item->setPixmap(0, SmallIcon("table"));
				item->setMultiLinesEnabled(true);
				setOpen(exportItem, true);
				exportItem->setExpandable(false);
			}
			item = new ActionSelectorDialogListItem("new", this, i18n("Create New Object"));
			item->setPixmap(0, SmallIcon("filenew"));
			if (supportedViewModes & Kexi::DesignViewMode) {
				item = new ActionSelectorDialogListItem("design", this, i18n("Open in Design View"));
				item->setPixmap(0, SmallIcon("edit"));
			}
			if (supportedViewModes & Kexi::TextViewMode) {
				item = new ActionSelectorDialogListItem("editText", this, i18n("Open in Text View"));
				item->setPixmap(0, noIcon);
			}
			item = new ActionSelectorDialogListItem("close", this, i18n("Close View"));
			item->setPixmap(0, SmallIcon("fileclose"));
			updateWidth();
		}

		void updateWidth()
		{
			adjustColumn(0);
			setMinimumWidth( columnWidth(0) );
		}

		TQString m_currentMimeType;
};

//-------------------------------------

//! @internal
class KexiActionSelectionDialog::KexiActionSelectionDialogPrivate
{
public:
	KexiActionSelectionDialogPrivate() 
		: tdeactionPageWidget(0), tdeactionListView(0), objectsListView(0)
		, currentFormActionsPageWidget(0)
		, currentFormActionsListView(0)
		, secondAnd3rdColumnMainWidget(0)
		, hideActionToExecuteListView(false)
	{
	}

	void raiseWidget(TQWidget *w)
	{
		secondAnd3rdColumnStack->raiseWidget( w );
		selectActionToBeExecutedLbl->setBuddy(w);
	}

	void updateSelectActionToBeExecutedMessage(const TQString& actionType)
	{
		TQString msg;
		if (actionType=="noaction")
			msg = TQString();
		// hardcoded, but it's not that bad
		else if (actionType=="macro")
			msg = i18n("&Select macro to be executed after clicking \"%1\" button:").arg(actionWidgetName);
		else if (actionType=="script")
			msg = i18n("&Select script to be executed after clicking \"%1\" button:").arg(actionWidgetName);
		//default: table/query/form/report...
		else
			msg = i18n("&Select object to be opened after clicking \"%1\" button:").arg(actionWidgetName);
		selectActionToBeExecutedLbl->setText(msg);
	}

	// changes 3rd column visibility
	void setActionToExecuteSectionVisible(bool visible, bool force = false)
	{
		if (!force && hideActionToExecuteListView != visible)
			return;
		hideActionToExecuteListView = !visible;
		actionToExecuteListView->hide();
		actionToExecuteLbl->hide();
		actionToExecuteListView->show();
		actionToExecuteLbl->show();
	}

	KexiMainWindow* mainWin;
	TQString actionWidgetName;
	ActionCategoriesListView* actionCategoriesListView; //!< for column #1
	TQWidget *tdeactionPageWidget;
	TDEActionsListView* tdeactionListView;  //!< for column #2
	KexiBrowser* objectsListView; //!< for column #2
	TQWidget *currentFormActionsPageWidget; //!< for column #2
	CurrentFormActionsListView* currentFormActionsListView; //!< for column #2
	TQWidget *emptyWidget;
	TQLabel* selectActionToBeExecutedLbl;
	ActionToExecuteListView* actionToExecuteListView;
	TQLabel *actionToExecuteLbl;
	TQWidget *secondAnd3rdColumnMainWidget;
	TQGridLayout *glyr;
	TQGridLayout *secondAnd3rdColumnGrLyr;
	TQWidgetStack *secondAnd3rdColumnStack, *secondColumnStack;
	bool hideActionToExecuteListView;
};

//-------------------------------------

KexiActionSelectionDialog::KexiActionSelectionDialog(KexiMainWindow* mainWin, TQWidget *parent, 
	const KexiFormEventAction::ActionData& action, const TQCString& actionWidgetName)
	: KDialogBase(parent, "actionSelectorDialog", true, i18n("Assigning Action to Command Button"), 
		KDialogBase::Ok | KDialogBase::Cancel )
	, d( new KexiActionSelectionDialogPrivate() )
{
	d->mainWin = mainWin;
	d->actionWidgetName = actionWidgetName;
	setButtonOK( KGuiItem(i18n("Assign action", "&Assign"), "button_ok", i18n("Assign action")) );

	TQWidget *mainWidget = new TQWidget( this );
	mainWidget->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum);
	setMainWidget(mainWidget);

/*    lbl 1
   +------------+ +-------------------------------+
   |            | |              [a]              |
   | 1st column | | +----------- + +------------+ |
   |            | | | 2nd column | | 3rd column | |
   |            | | +            + +            + |
   |            | | +------------+ +------------+ |
   +------------+ +-------------------------------+
   \______________________________________________/
                        glyr
  [a]- TQWidgetStack *secondAnd3rdColumnStack, 
    - for displaying TDEActions, the stack contains d->tdeactionPageWidget TQWidget
    - for displaying objects, the stack contains secondAnd3rdColumnMainWidget TQWidget and TQGridLayout *secondAnd3rdColumnGrLyr
	 - tdeactionPageWidget contains only a TQVBoxLayout and label+tdeactionListView
*/
	d->glyr = new TQGridLayout(mainWidget, 2, 2, KDialog::marginHint(), KDialog::spacingHint());
	d->glyr->setRowStretch(1, 1);

	// 1st column: action types
	d->actionCategoriesListView = new ActionCategoriesListView(mainWidget);
	d->actionCategoriesListView->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Minimum);
	d->glyr->addWidget(d->actionCategoriesListView, 1, 0);
	connect( d->actionCategoriesListView, TQT_SIGNAL(selectionChanged(TQListViewItem*)), 
		this, TQT_SLOT(slotActionCategorySelected(TQListViewItem*)));

	TQLabel *lbl = new TQLabel(d->actionCategoriesListView, i18n("Action category:"), mainWidget);
	lbl->setMinimumHeight(lbl->fontMetrics().height()*2);
	lbl->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed);
	lbl->setAlignment(TQt::AlignTop|TQt::AlignLeft|TQt::WordBreak);
	d->glyr->addWidget(lbl, 0, 0, TQt::AlignTop|TQt::AlignLeft);
	
	// widget stack for 2nd and 3rd column
	d->secondAnd3rdColumnStack = new TQWidgetStack(mainWidget);
	d->secondAnd3rdColumnStack->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum);
	d->glyr->addMultiCellWidget(d->secondAnd3rdColumnStack, 0, 1, 1, 1);//, TQt::AlignTop|TQt::AlignLeft);

	d->secondAnd3rdColumnMainWidget = new TQWidget(d->secondAnd3rdColumnStack);
	d->secondAnd3rdColumnMainWidget->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum);
	d->secondAnd3rdColumnGrLyr = new TQGridLayout(d->secondAnd3rdColumnMainWidget, 2, 2, 0, KDialog::spacingHint());
	d->secondAnd3rdColumnGrLyr->setRowStretch(1, 2);
	d->secondAnd3rdColumnStack->addWidget(d->secondAnd3rdColumnMainWidget);

	// 2nd column: list of actions/objects
	d->objectsListView = new KexiBrowser(d->secondAnd3rdColumnMainWidget, d->mainWin, 0/*features*/);
	d->secondAnd3rdColumnGrLyr->addWidget(d->objectsListView, 1, 0);
	connect(d->objectsListView, TQT_SIGNAL(selectionChanged(KexiPart::Item*)),
		this, TQT_SLOT(slotItemForOpeningOrExecutingSelected(KexiPart::Item*)));

	d->selectActionToBeExecutedLbl = new TQLabel(d->secondAnd3rdColumnMainWidget);
	d->selectActionToBeExecutedLbl->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
	d->selectActionToBeExecutedLbl->setAlignment(TQt::AlignTop|TQt::AlignLeft|TQt::WordBreak);
	d->selectActionToBeExecutedLbl->setMinimumHeight(d->selectActionToBeExecutedLbl->fontMetrics().height()*2);
	d->secondAnd3rdColumnGrLyr->addWidget(d->selectActionToBeExecutedLbl, 0, 0, TQt::AlignTop|TQt::AlignLeft);

	d->emptyWidget = new TQWidget(d->secondAnd3rdColumnStack);
	d->secondAnd3rdColumnStack->addWidget(d->emptyWidget);

	// 3rd column: actions to execute
	d->actionToExecuteListView = new ActionToExecuteListView(d->secondAnd3rdColumnMainWidget);
	d->actionToExecuteListView->installEventFilter(this); //to be able to disable painting
	d->actionToExecuteListView->viewport()->installEventFilter(this); //to be able to disable painting
	d->actionToExecuteListView->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Minimum);
	connect(d->actionToExecuteListView, TQT_SIGNAL(executed(TQListViewItem*)),
		this, TQT_SLOT(slotActionToExecuteItemExecuted(TQListViewItem*)));
	connect(d->actionToExecuteListView, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
		this, TQT_SLOT(slotActionToExecuteItemSelected(TQListViewItem*)));
	d->secondAnd3rdColumnGrLyr->addWidget(d->actionToExecuteListView, 1, 1);

	d->actionToExecuteLbl = new TQLabel(d->actionToExecuteListView, 
		i18n("Action to execute:"), d->secondAnd3rdColumnMainWidget);
	d->actionToExecuteLbl->installEventFilter(this); //to be able to disable painting
	d->actionToExecuteLbl->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
	d->actionToExecuteLbl->setAlignment(TQt::AlignTop|TQt::AlignLeft|TQt::WordBreak);
	d->secondAnd3rdColumnGrLyr->addWidget(d->actionToExecuteLbl, 0, 1, TQt::AlignTop|TQt::AlignLeft);

	// temporary show all sections to avoid resizing the dialog in the future
	d->actionCategoriesListView->selectAction("table");
	d->setActionToExecuteSectionVisible(true);
	adjustSize();
	resize(TQMAX(700, width()), TQMAX(450, height()));
	d->actionToExecuteListView->updateWidth();

	bool ok;
	TQString actionType, actionArg;
	KexiPart::Info* partInfo = action.decodeString(actionType, actionArg, ok);
	if (ok) {
		d->actionCategoriesListView->selectAction(actionType);
		if (actionType=="tdeaction") {
			d->tdeactionListView->selectAction(actionArg);
			d->tdeactionListView->setFocus();
		}
		else if (actionType=="currentForm") {
			d->currentFormActionsListView->selectAction(actionArg);
			d->currentFormActionsListView->setFocus();
		}
		else if (partInfo
			&& Kexi::partManager().part(partInfo)) // We use the Part Manager
			// to determine whether the Kexi-plugin is installed and whether we like to show 
			// it in our list of actions.
		{
			KexiPart::Item *item = d->mainWin->project()->item(partInfo, actionArg);
			if (d->objectsListView && item) {
				d->objectsListView->selectItem(*item);
				TQString actionOption( action.option );
				if (actionOption.isEmpty())
					actionOption = "open"; // for backward compatibility
				d->actionToExecuteListView->selectAction(actionOption);
				d->objectsListView->setFocus();
			}
		}
	}
	else {//invalid assignment or 'noaction'
		d->actionCategoriesListView->selectAction("noaction");
		d->actionCategoriesListView->setFocus();
	}
}

KexiActionSelectionDialog::~KexiActionSelectionDialog()
{
	delete d;
}

void KexiActionSelectionDialog::slotTDEActionItemExecuted(TQListViewItem*)
{
	accept();
}

void KexiActionSelectionDialog::slotTDEActionItemSelected(TQListViewItem*)
{
	d->setActionToExecuteSectionVisible(false);
	updateOKButtonStatus();
}

void KexiActionSelectionDialog::slotCurrentFormActionItemExecuted(TQListViewItem*)
{
	accept();
}

void KexiActionSelectionDialog::slotCurrentFormActionItemSelected(TQListViewItem*)
{
	d->setActionToExecuteSectionVisible(false);
	updateOKButtonStatus();
}

void KexiActionSelectionDialog::slotItemForOpeningOrExecutingSelected(KexiPart::Item* item)
{
	d->setActionToExecuteSectionVisible(item);
}

void KexiActionSelectionDialog::slotActionToExecuteItemExecuted(TQListViewItem* item)
{
	if (!item)
		return;
	ActionSelectorDialogListItemBase *listItem = dynamic_cast<ActionSelectorDialogListItemBase*>(item);
	if (listItem && !listItem->data.isEmpty())
		accept();
}

void KexiActionSelectionDialog::slotActionToExecuteItemSelected(TQListViewItem*)
{
	updateOKButtonStatus();
}

void KexiActionSelectionDialog::slotActionCategorySelected(TQListViewItem* item)
{
	ActionSelectorDialogListItem *simpleItem = dynamic_cast<ActionSelectorDialogListItem*>(item);
	// simple case: part-less item, e.g. tdeaction:
	if (simpleItem) {
		d->updateSelectActionToBeExecutedMessage(simpleItem->data);
		TQString selectActionToBeExecutedMsg(
			i18n("&Select action to be executed after clicking \"%1\" button:")); // msg for a label
		if (simpleItem->data == "tdeaction") {
			if (!d->tdeactionPageWidget) {
				//create lbl+list view with a vlayout
				d->tdeactionPageWidget = new TQWidget();
				d->tdeactionPageWidget->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum);
				TQVBoxLayout *vlyr = new TQVBoxLayout(d->tdeactionPageWidget, 0, KDialog::spacingHint());
				d->tdeactionListView = new TDEActionsListView(d->tdeactionPageWidget, d->mainWin);
				d->tdeactionListView->init();
				TQLabel *lbl = new TQLabel(d->tdeactionListView, selectActionToBeExecutedMsg.arg(d->actionWidgetName),
					d->tdeactionPageWidget);
				lbl->setAlignment(TQt::AlignTop|TQt::AlignLeft|TQt::WordBreak);
				lbl->setMinimumHeight(lbl->fontMetrics().height()*2);
				vlyr->addWidget(lbl);
				vlyr->addWidget(d->tdeactionListView);
				d->secondAnd3rdColumnStack->addWidget(d->tdeactionPageWidget);
				connect(d->tdeactionListView, TQT_SIGNAL(executed(TQListViewItem*)),
					this, TQT_SLOT(slotTDEActionItemExecuted(TQListViewItem*)));
				connect( d->tdeactionListView, TQT_SIGNAL(selectionChanged(TQListViewItem*)), 
					this, TQT_SLOT(slotTDEActionItemSelected(TQListViewItem*)));
			}
			d->setActionToExecuteSectionVisible(false);
			d->raiseWidget(d->tdeactionPageWidget);
			slotTDEActionItemSelected(d->tdeactionListView->selectedItem()); //to refresh column #3
		}
		else if (simpleItem->data == "currentForm") {
			if (!d->currentFormActionsPageWidget) {
				//create lbl+list view with a vlayout
				d->currentFormActionsPageWidget = new TQWidget();
				d->currentFormActionsPageWidget->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum);
				TQVBoxLayout *vlyr = new TQVBoxLayout(d->currentFormActionsPageWidget, 0, KDialog::spacingHint());
				d->currentFormActionsListView = new CurrentFormActionsListView(
					d->currentFormActionsPageWidget, d->mainWin);
				d->currentFormActionsListView->init();
				TQLabel *lbl = new TQLabel(d->currentFormActionsListView, 
					selectActionToBeExecutedMsg.arg(d->actionWidgetName), d->currentFormActionsPageWidget);
				lbl->setAlignment(TQt::AlignTop|TQt::AlignLeft|TQt::WordBreak);
				lbl->setMinimumHeight(lbl->fontMetrics().height()*2);
				vlyr->addWidget(lbl);
				vlyr->addWidget(d->currentFormActionsListView);
				d->secondAnd3rdColumnStack->addWidget(d->currentFormActionsPageWidget);
				connect(d->currentFormActionsListView, TQT_SIGNAL(executed(TQListViewItem*)),
					this, TQT_SLOT(slotCurrentFormActionItemExecuted(TQListViewItem*)));
				connect( d->currentFormActionsListView, TQT_SIGNAL(selectionChanged(TQListViewItem*)), 
					this, TQT_SLOT(slotCurrentFormActionItemSelected(TQListViewItem*)));
			}
			d->setActionToExecuteSectionVisible(false);
			d->raiseWidget(d->currentFormActionsPageWidget);
			slotCurrentFormActionItemSelected(d->currentFormActionsListView->selectedItem()); //to refresh column #3
		}
		else if (simpleItem->data == "noaction") {
			d->raiseWidget(d->emptyWidget);
			d->objectsListView->clearSelection();
			//hide column #3
			d->setActionToExecuteSectionVisible(false);
		}
		d->actionCategoriesListView->update();
		updateOKButtonStatus();
		return;
	}
	// other case
	KexiBrowserItem* browserItem = dynamic_cast<KexiBrowserItem*>(item);
	if (browserItem) {
		d->updateSelectActionToBeExecutedMessage(browserItem->info()->objectName());
		if (d->objectsListView->itemsMimeType().latin1()!=browserItem->info()->mimeType()) {
			d->objectsListView->setProject(d->mainWin->project(), browserItem->info()->mimeType());
			d->actionToExecuteListView->showActionsForMimeType( browserItem->info()->mimeType() );
			d->setActionToExecuteSectionVisible(false);
		}
		if (d->secondAnd3rdColumnStack->visibleWidget()!=d->secondAnd3rdColumnMainWidget) {
			d->raiseWidget( d->secondAnd3rdColumnMainWidget );
			d->objectsListView->clearSelection();
			d->setActionToExecuteSectionVisible(false, true);
		}
		else
			d->raiseWidget( d->secondAnd3rdColumnMainWidget );
	}
	d->actionCategoriesListView->update();
	updateOKButtonStatus();
}

KexiMainWindow* KexiActionSelectionDialog::mainWin() const
{
	return d->mainWin;
}

KexiFormEventAction::ActionData KexiActionSelectionDialog::currentAction() const
{
	KexiFormEventAction::ActionData data;
	ActionSelectorDialogListItem *simpleItem = dynamic_cast<ActionSelectorDialogListItem*>(
		d->actionCategoriesListView->selectedItem());
	// simple case: part-less item, e.g. tdeaction:
	if (simpleItem) {
		if (simpleItem->data == "tdeaction") {
			if (d->tdeactionListView->selectedItem()) {
				data.string = TQString("tdeaction:")
					+ dynamic_cast<ActionSelectorDialogListItem*>( d->tdeactionListView->selectedItem() )->data;
				return data;
			}
		}
		else if (simpleItem->data == "currentForm") {
			if (d->currentFormActionsListView->selectedItem()) {
				data.string = TQString("currentForm:")
					+ dynamic_cast<ActionSelectorDialogListItem*>( 
						d->currentFormActionsListView->selectedItem() )->data;
				return data;
			}
		}
	}
	KexiBrowserItem* browserItem = dynamic_cast<KexiBrowserItem*>( d->actionCategoriesListView->selectedItem() );
	if (browserItem) {
		ActionSelectorDialogListItem *actionToExecute = dynamic_cast<ActionSelectorDialogListItem*>(
			d->actionToExecuteListView->selectedItem());
		if (d->objectsListView && actionToExecute && !actionToExecute->data.isEmpty()) {
			KexiPart::Item* partItem = d->objectsListView->selectedPartItem();
			KexiPart::Info* partInfo = partItem ? Kexi::partManager().infoForMimeType( partItem->mimeType() ) : 0;
			if (partInfo) {
				// opening or executing: table:name, query:name, form:name, macro:name, script:name, etc.
				data.string = TQString("%1:%2").arg(partInfo->objectName()).arg(partItem->name());
				data.option = actionToExecute->data;
				return data;
			}
		}
	}
	return data; // No Action
}

void KexiActionSelectionDialog::updateOKButtonStatus()
{
	TQPushButton *btn = actionButton(Ok);
	ActionSelectorDialogListItem *simpleItem = dynamic_cast<ActionSelectorDialogListItem*>(
		d->actionCategoriesListView->selectedItem());
	btn->setEnabled( (simpleItem && simpleItem->data == "noaction") || !currentAction().isEmpty() );
}

bool KexiActionSelectionDialog::eventFilter(TQObject *o, TQEvent *e)
{
	if (d->hideActionToExecuteListView)
		return true;
	return KDialogBase::eventFilter(o, e);
}

#include "kexiactionselectiondialog.moc"
#include "kexiactionselectiondialog_p.moc"
