/* This file is part of the KDE project
   Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
   Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
   Copyright (C) 2006-2007 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 <tqwidgetstack.h>
#include <tqframe.h>
#include <tqbuttongroup.h>
#include <tqwidget.h>
#include <tqhbox.h>
#include <tqvbox.h>
#include <tqstring.h>
#include <tqpopupmenu.h>
#include <tqdom.h>
#include <tqevent.h>
#include <tqobjectlist.h>
#include <tqpainter.h>
#include <tqvaluevector.h>
#include <tqfileinfo.h>
#include <tqscrollview.h>
#include <tqtabbar.h>
#include <tqsplitter.h>
#include <tqlayout.h>

#include <kiconloader.h>
#include <kgenericfactory.h>
#include <ktextedit.h>
#include <klineedit.h>
#include <tdelocale.h>
#include <kdebug.h>

#include "containerfactory.h"
#include "container.h"
#include "form.h"
#include "formIO.h"
#include "objecttree.h"
#include "commands.h"
#include "formmanager.h"
#include "widgetlibrary.h"
#include <formeditor/utils.h>
#include <kinputdialog.h>

ContainerWidget::ContainerWidget(TQWidget *parent, const char *name)
 : TQWidget(parent, name)
{
}

ContainerWidget::~ContainerWidget()
{
}

TQSize ContainerWidget::sizeHint() const
{
	return TQSize(30,30); //default
}

void ContainerWidget::dragMoveEvent( TQDragMoveEvent *e )
{
	TQWidget::dragMoveEvent(e);
	emit handleDragMoveEvent(e);
}

void ContainerWidget::dropEvent( TQDropEvent *e )
{
	TQWidget::dropEvent(e);
	emit handleDropEvent(e);
}

////////////////////////

GroupBox::GroupBox(const TQString & title, TQWidget *parent, const char *name)
 : TQGroupBox(title, parent, name)
{
}

GroupBox::~GroupBox()
{
}

void GroupBox::dragMoveEvent( TQDragMoveEvent *e )
{
	TQGroupBox::dragMoveEvent(e);
	emit handleDragMoveEvent(e);
}

void GroupBox::dropEvent( TQDropEvent *e )
{
	TQGroupBox::dropEvent(e);
	emit handleDropEvent(e);
}

////////////////////////

KFDTabWidget::KFDTabWidget(TQWidget *parent, const char *name)
 : KFormDesigner::TabWidget(parent, name)
{
}

KFDTabWidget::~KFDTabWidget()
{
}

TQSize
KFDTabWidget::sizeHint() const
{
	TQSize s(30,30); // default min size
	for(int i=0; i < count(); i++)
		s = s.expandedTo( KFormDesigner::getSizeFromChildren(page(i)) );

	return s + TQSize(10/*margin*/, tabBar()->height() + 20/*margin*/);
}

void KFDTabWidget::dragMoveEvent( TQDragMoveEvent *e )
{
	TabWidgetBase::dragMoveEvent( e );
	if (dynamic_cast<ContainerWidget*>(currentPage()))
		emit dynamic_cast<ContainerWidget*>(currentPage())->handleDragMoveEvent(e);
	emit handleDragMoveEvent(e);
}

void KFDTabWidget::dropEvent( TQDropEvent *e ) 
{
	TabWidgetBase::dropEvent( e );
	if (dynamic_cast<ContainerWidget*>(currentPage()))
		emit dynamic_cast<ContainerWidget*>(currentPage())->handleDropEvent(e);
	emit handleDropEvent(e);
}

/// Various layout widgets /////////////////:

HBox::HBox(TQWidget *parent, const char *name)
 : TQFrame(parent, name), m_preview(false)
{}

void
HBox::paintEvent(TQPaintEvent *)
{
	if(m_preview) return;
	TQPainter p(this);
	p.setPen(TQPen(red, 2, TQt::DashLine));
	p.drawRect(1, 1, width()-1, height() - 1);
}

VBox::VBox(TQWidget *parent, const char *name)
 : TQFrame(parent, name), m_preview(false)
{}

void
VBox::paintEvent(TQPaintEvent *)
{
	if(m_preview) return;
	TQPainter p(this);
	p.setPen(TQPen(blue, 2, TQt::DashLine));
	p.drawRect(1, 1, width()-1, height() - 1);
}

Grid::Grid(TQWidget *parent, const char *name)
 : TQFrame(parent, name), m_preview(false)
{}

void
Grid::paintEvent(TQPaintEvent *)
{
	if(m_preview) return;
	TQPainter p(this);
	p.setPen(TQPen(darkGreen, 2, TQt::DashLine));
	p.drawRect(1, 1, width()-1, height() - 1);
}

HFlow::HFlow(TQWidget *parent, const char *name)
 : TQFrame(parent, name), m_preview(false)
{}

void
HFlow::paintEvent(TQPaintEvent *)
{
	if(m_preview) return;
	TQPainter p(this);
	p.setPen(TQPen(magenta, 2, TQt::DashLine));
	p.drawRect(1, 1, width()-1, height() - 1);
}

VFlow::VFlow(TQWidget *parent, const char *name)
 : TQFrame(parent, name), m_preview(false)
{}

void
VFlow::paintEvent(TQPaintEvent *)
{
	if(m_preview) return;
	TQPainter p(this);
	p.setPen(TQPen(cyan, 2, TQt::DashLine));
	p.drawRect(1, 1, width()-1, height() - 1);
}

TQSize
VFlow::sizeHint() const
{
	if(layout())
		return layout()->sizeHint();
	else
		return TQSize(700, 50); // default
}

///////  Tab related KCommand (to allow tab creation/deletion undoing)

InsertPageCommand::InsertPageCommand(KFormDesigner::Container *container, TQWidget *parent)
  : KCommand()
{
	m_containername = container->widget()->name();
	m_form = container->form();
	m_parentname = parent->name();
	m_pageid = -1;
}

void
InsertPageCommand::execute()
{
	KFormDesigner::Container *container = m_form->objectTree()->lookup(m_containername)->container();
	TQWidget *parent = m_form->objectTree()->lookup(m_parentname)->widget();
	if(m_name.isEmpty()) {
		m_name = container->form()->objectTree()->generateUniqueName(
			container->form()->library()->displayName("TQWidget").latin1(),
			/*!numberSuffixRequired*/false);
	}

	TQWidget *page = container->form()->library()->createWidget("TQWidget", parent, m_name.latin1(), container);
//	TQWidget *page = new ContainerWidget(parent, m_name.latin1());
//	new KFormDesigner::Container(container, page, parent);

	TQCString classname = parent->className();
	if(classname == "KFDTabWidget")
	{
		TabWidgetBase *tab = dynamic_cast<TabWidgetBase*>(parent);
		TQString n = i18n("Page %1").arg(tab->count() + 1);
		tab->addTab(page, n);
		tab->showPage(page);

		KFormDesigner::ObjectTreeItem *item = container->form()->objectTree()->lookup(m_name);
		item->addModifiedProperty("title", n);
	}
	else if(classname == "TQWidgetStack")
	{
		TQWidgetStack *stack = (TQWidgetStack*)parent;
		stack->addWidget(page, m_pageid);
		stack->raiseWidget(page);
		m_pageid = stack->id(page);

		KFormDesigner::ObjectTreeItem *item = container->form()->objectTree()->lookup(m_name);
		item->addModifiedProperty("id", stack->id(page));
	}
}

void
InsertPageCommand::unexecute()
{
	TQWidget *page = m_form->objectTree()->lookup(m_name)->widget();
	TQWidget *parent = m_form->objectTree()->lookup(m_parentname)->widget();

	KFormDesigner::WidgetList list;
	list.append(page);
	KCommand *com = new KFormDesigner::DeleteWidgetCommand(list, m_form);

	TQCString classname = parent->className();
	if(classname == "KFDTabWidget")
	{
		TabWidgetBase *tab = dynamic_cast<TabWidgetBase*>(parent);
		tab->removePage(page);
	}
	else if(classname == "TQWidgetStack")
	{
		TQWidgetStack *stack = (TQWidgetStack*)parent;
		int id = stack->id(page) - 1;
		while(!stack->widget(id))
			id--;

		stack->raiseWidget(id);
		stack->removeWidget(page);
	}

	com->execute();
	delete com;
}

TQString
InsertPageCommand::name() const
{
	return i18n("Add Page");
}

/////// Sub forms ////////////////////////:

SubForm::SubForm(TQWidget *parent, const char *name)
: TQScrollView(parent, name), m_form(0), m_widget(0)
{
	setFrameStyle(TQFrame::WinPanel | TQFrame::Sunken);
	viewport()->setPaletteBackgroundColor(colorGroup().mid());
}

void
SubForm::setFormName(const TQString &name)
{
	if(name.isEmpty())
		return;

	TQFileInfo info(name);
	if(!info.exists()
		|| (KFormDesigner::FormManager::self()->activeForm()
			&& (info.fileName() == KFormDesigner::FormManager::self()->activeForm()->filename()) ) )
		return; // we check if this is valid form

	// we create the container widget
	delete m_widget;
	m_widget = new TQWidget(viewport(), "subform_widget");
//	m_widget->show();
	addChild(m_widget);
	m_form = new KFormDesigner::Form(
		KFormDesigner::FormManager::self()->activeForm()->library(), this->name());
	m_form->createToplevel(m_widget);

	// and load the sub form
	KFormDesigner::FormIO::loadFormFromFile(m_form, m_widget, name);
	m_form->setDesignMode(false);

	m_formName = name;

}

/////   The factory /////////////////////////

ContainerFactory::ContainerFactory(TQObject *parent, const char *, const TQStringList &)
 : KFormDesigner::WidgetFactory(parent, "containers")
{
	KFormDesigner::WidgetInfo *wBtnGroup = new KFormDesigner::WidgetInfo(this);
	wBtnGroup->setPixmap("frame");
	wBtnGroup->setClassName("TQButtonGroup");
	wBtnGroup->setName(i18n("Button Group"));
	wBtnGroup->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "buttonGroup"));
	wBtnGroup->setDescription(i18n("A simple container to group buttons"));
	addClass(wBtnGroup);

	KFormDesigner::WidgetInfo *wTabWidget = new KFormDesigner::WidgetInfo(this);
	wTabWidget->setPixmap("tabwidget");
	wTabWidget->setClassName("KFDTabWidget");
	wTabWidget->addAlternateClassName("KTabWidget");
	wTabWidget->addAlternateClassName("TQTabWidget");
//tmp:	wTabWidget->setSavingName("TQTabWidget");
	wTabWidget->setSavingName("KTabWidget");
	wTabWidget->setIncludeFileName("ktabwidget.h");
	wTabWidget->setName(i18n("Tab Widget"));
	wTabWidget->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "tabWidget"));
	wTabWidget->setDescription(i18n("A widget to display multiple pages using tabs"));
	addClass(wTabWidget);

	KFormDesigner::WidgetInfo *wWidget = new KFormDesigner::WidgetInfo(this);
	wWidget->setPixmap("frame");
	wWidget->setClassName("TQWidget");
	wWidget->addAlternateClassName("ContainerWidget");
	wWidget->setName(i18n("Basic container"));
	wWidget->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "container"));
	wWidget->setDescription(i18n("An empty container with no frame"));
	addClass(wWidget);

	KFormDesigner::WidgetInfo *wGroupBox = new KFormDesigner::WidgetInfo(this);
	wGroupBox->setPixmap("groupbox");
	wGroupBox->setClassName("TQGroupBox");
	wGroupBox->addAlternateClassName("GroupBox");
	wGroupBox->setName(i18n("Group Box"));
	wGroupBox->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "groupBox"));
	wGroupBox->setDescription(i18n("A container to group some widgets"));
	addClass(wGroupBox);

	KFormDesigner::WidgetInfo *wFrame = new KFormDesigner::WidgetInfo(this);
	wFrame->setPixmap("frame");
	wFrame->setClassName("TQFrame");
	wFrame->setName(i18n("Frame"));
	wFrame->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "frame"));
	wFrame->setDescription(i18n("A simple frame container"));
	addClass(wFrame);

	KFormDesigner::WidgetInfo *wWidgetStack = new KFormDesigner::WidgetInfo(this);
	wWidgetStack->setPixmap("widgetstack");
	wWidgetStack->setClassName("TQWidgetStack");
	wWidgetStack->setName(i18n("Widget Stack"));
	wWidgetStack->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "widgetStack"));
	wWidgetStack->setDescription(i18n("A container with multiple pages"));
	addClass(wWidgetStack);

	KFormDesigner::WidgetInfo *wHBox = new KFormDesigner::WidgetInfo(this);
	wHBox->setPixmap("frame");
	wHBox->setClassName("HBox");
	wHBox->setName(i18n("Horizontal Box"));
	wHBox->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "horizontalBox"));
	wHBox->setDescription(i18n("A simple container to group widgets horizontally"));
	addClass(wHBox);

	KFormDesigner::WidgetInfo *wVBox = new KFormDesigner::WidgetInfo(this);
	wVBox->setPixmap("frame");
	wVBox->setClassName("VBox");
	wVBox->setName(i18n("Vertical Box"));
	wVBox->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "verticalBox"));
	wVBox->setDescription(i18n("A simple container to group widgets vertically"));
	addClass(wVBox);

	KFormDesigner::WidgetInfo *wGrid = new KFormDesigner::WidgetInfo(this);
	wGrid->setPixmap("frame");
	wGrid->setClassName("Grid");
	wGrid->setName(i18n("Grid Box"));
	wGrid->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "gridBox"));
	wGrid->setDescription(i18n("A simple container to group widgets in a grid"));
	addClass(wGrid);

	KFormDesigner::WidgetInfo *wSplitter = new KFormDesigner::WidgetInfo(this);
//! @todo horizontal/vertical splitter icons
	wSplitter->setPixmap("frame");
	wSplitter->setClassName("Splitter");
	wSplitter->addAlternateClassName("TQSplitter");
	wSplitter->setName(i18n("Splitter"));
	wSplitter->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "splitter"));
	wSplitter->setDescription(i18n("A container that enables user to resize its children"));
	addClass(wSplitter);

	KFormDesigner::WidgetInfo *wHFlow = new KFormDesigner::WidgetInfo(this);
//! @todo hflow icon
	wHFlow->setPixmap("frame");
	wHFlow->setClassName("HFlow");
	wHFlow->setName(i18n("Row Layout"));
	wHFlow->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "rowLayout"));
	wHFlow->setDescription(i18n("A simple container to group widgets by rows"));
	addClass(wHFlow);

	KFormDesigner::WidgetInfo *wVFlow = new KFormDesigner::WidgetInfo(this);
//! @todo vflow icon
	wVFlow->setPixmap("frame");
	wVFlow->setClassName("VFlow");
	wVFlow->setName(i18n("Column Layout"));
	wVFlow->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "columnLayout"));
	wVFlow->setDescription(i18n("A simple container to group widgets by columns"));
	addClass(wVFlow);

	KFormDesigner::WidgetInfo *wSubForm = new KFormDesigner::WidgetInfo(this);
	wSubForm->setPixmap("form");
	wSubForm->setClassName("SubForm");
	wSubForm->setName(i18n("Sub Form"));
	wSubForm->setNamePrefix(
		i18n("Widget name. This string will be used to name widgets of this class. It must _not_ contain white spaces and non latin1 characters.", "subForm"));
	wSubForm->setDescription(i18n("A form widget included in another Form"));
	wSubForm->setAutoSyncForProperty( "formName", false );
	addClass(wSubForm);

	//groupbox
	m_propDesc["title"] = i18n("Title");
	m_propDesc["flat"] = i18n("Flat");

	//tab widget
	m_propDesc["tabPosition"] = i18n("Tab Position");
	m_propDesc["currentPage"] = i18n("Current Page");
	m_propDesc["tabShape"] = i18n("Tab Shape");

	m_propDesc["tabPosition"] = i18n("Tab Position");
	m_propDesc["tabPosition"] = i18n("Tab Position");

	m_propValDesc["Rounded"] = i18n("for Tab Shape", "Rounded");
	m_propValDesc["Triangular"] = i18n("for Tab Shape", "Triangular");
}

TQWidget*
ContainerFactory::createWidget(const TQCString &c, TQWidget *p, const char *n,
	KFormDesigner::Container *container, int options)
{
	if(c == "TQButtonGroup")
	{
		TQString text = container->form()->library()->textForWidgetName(n, c);
		TQButtonGroup *w = new TQButtonGroup(/*i18n("Button Group")*/text, p, n);
		new KFormDesigner::Container(container, w, container);
		return w;
	}
	else if(c == "KFDTabWidget")
	{
		KFDTabWidget *tab = new KFDTabWidget(p, n);
#if defined(USE_KTabWidget)
		tab->setTabReorderingEnabled(true);
		connect(tab, TQ_SIGNAL(movedTab(int,int)), this, TQ_SLOT(reorderTabs(int,int)));
#endif
		container->form()->objectTree()->addItem(container->objectTree(),
			new KFormDesigner::ObjectTreeItem(
				container->form()->library()->displayName(c), n, tab, container));
//		m_manager = container->form()->manager();

		// if we are loading, don't add this tab
		if(container->form()->interactiveMode())
		{
			//m_widget=tab;
			setWidget(tab, container);
//			m_container=container;
			addTabPage();
		}

		return tab;
	}
	else if(c == "TQWidget" || c=="ContainerWidget")
	{
		TQWidget *w = new ContainerWidget(p, n);
		new KFormDesigner::Container(container, w, p);
		return w;
	}
	else if(c == "TQGroupBox" || c == "GroupBox")
	{
		TQString text = container->form()->library()->textForWidgetName(n, c);
		TQGroupBox *w = new GroupBox(text, p, n);
		new KFormDesigner::Container(container, w, container);
		return w;
	}
	else if(c == "TQFrame")
	{
		TQFrame *w = new TQFrame(p, n);
		w->setLineWidth(2);
		w->setFrameStyle(TQFrame::StyledPanel|TQFrame::Raised);
		new KFormDesigner::Container(container, w, container);
		return w;
	}
	else if(c == "TQWidgetStack")
	{
		TQWidgetStack *stack = new TQWidgetStack(p, n);
		stack->setLineWidth(2);
		stack->setFrameStyle(TQFrame::StyledPanel|TQFrame::Raised);
		container->form()->objectTree()->addItem( container->objectTree(),
			new KFormDesigner::ObjectTreeItem(
				container->form()->library()->displayName(c), n, stack, container));

		if(container->form()->interactiveMode())
		{
			//m_widget = stack;
			setWidget(stack, container);
//			m_container = container;
			addStackPage();
		}
		return stack;
	}
	else if(c == "HBox") {
		HBox *w = new HBox(p, n);
		new KFormDesigner::Container(container, w, container);
		return w;
	}
	else if(c == "VBox") {
		VBox *w = new VBox(p, n);
		new KFormDesigner::Container(container, w, container);
		return w;
	}
	else if(c == "Grid") {
		Grid *w = new Grid(p, n);
		new KFormDesigner::Container(container, w, container);
		return w;
	}
	else if(c == "HFlow") {
		HFlow *w = new HFlow(p, n);
		new KFormDesigner::Container(container, w, container);
		return w;
	}
	else if(c == "VFlow") {
		VFlow *w = new VFlow(p, n);
		new KFormDesigner::Container(container, w, container);
		return w;
	}
	else if(c == "SubForm") {
		SubForm *subform = new SubForm(p, n);
		return subform;
	}
	else if(c == "TQSplitter") {
		TQSplitter *split = new TQSplitter(p, n);
		if (0 == (options & WidgetFactory::AnyOrientation))
			split->setOrientation(
				(options & WidgetFactory::VerticalOrientation) ? TQt::Vertical : TQt::Horizontal);
		new KFormDesigner::Container(container, split, container);
		return split;
	}

	return 0;
}

bool
ContainerFactory::previewWidget(const TQCString &classname, TQWidget *widget, KFormDesigner::Container *container)
{
	if(classname == "WidgetStack")
	{
		TQWidgetStack *stack = ((TQWidgetStack*)widget);
		KFormDesigner::ObjectTreeItem *tree = container->form()->objectTree()->lookup(widget->name());
		if(!tree->modifiedProperties()->contains("frameShape"))
			stack->setFrameStyle(TQFrame::NoFrame);
	}
	else if(classname == "HBox")
		((HBox*)widget)->setPreviewMode();
	else if(classname == "VBox")
		((VBox*)widget)->setPreviewMode();
	else if(classname == "Grid")
		((Grid*)widget)->setPreviewMode();
	else if(classname == "HFlow")
		((HFlow*)widget)->setPreviewMode();
	else if(classname == "VFlow")
		((VFlow*)widget)->setPreviewMode();
	else
		return false;
	return true;
}

bool
ContainerFactory::createMenuActions(const TQCString &classname, TQWidget *w, TQPopupMenu *menu,
	KFormDesigner::Container *container)
{
	setWidget(w, container);
	//m_widget = w;
//	m_container = container;

	if((classname == "KFDTabWidget") || (w->parentWidget()->parentWidget()->inherits("TQTabWidget")))
	{
		if(w->parentWidget()->parentWidget()->inherits("TQTabWidget"))
		{
			//m_widget = w->parentWidget()->parentWidget();
			setWidget(w->parentWidget()->parentWidget(), m_container->toplevel());
//			m_container = m_container->toplevel();
		}

		int id = menu->insertItem(SmallIconSet("tab_new"), i18n("Add Page"), this, TQ_SLOT(addTabPage()) );
		id = menu->insertItem(SmallIconSet("edit"), i18n("Rename Page..."), this, TQ_SLOT(renameTabPage()));
		id = menu->insertItem(SmallIconSet("tab_remove"), i18n("Remove Page"), this, TQ_SLOT(removeTabPage()));
//		if( dynamic_cast<TabWidgetBase*>(m_widget)->count() == 1)
		if( dynamic_cast<TabWidgetBase*>(widget())->count() == 1)
			menu->setItemEnabled(id, false);
		return true;
	}
	else if(w->parentWidget()->isA("TQWidgetStack") && !w->parentWidget()->parentWidget()->inherits("TQTabWidget"))
	{
		//m_widget = w->parentWidget();
		TQWidgetStack *stack = (TQWidgetStack*)w->parentWidget(); //m_widget;
		setWidget(
			w->parentWidget(),
			container->form()->objectTree()->lookup(stack->name())->parent()->container()
		);
//		m_container = container->form()->objectTree()->lookup(m_widget->name())->parent()->container();
//		m_container = container->form()->objectTree()->lookup(stack->name())->parent()->container();

		int id = menu->insertItem(SmallIconSet("tab_new"), i18n("Add Page"), this, TQ_SLOT(addStackPage()) );

		id = menu->insertItem(SmallIconSet("tab_remove"), i18n("Remove Page"), this, TQ_SLOT(removeStackPage()) );
//		if( ((TQWidgetStack*)m_widget)->children()->count() == 4) // == the stack has only one page
		if(stack->childrenListObject().count() == 4) // == the stack has only one page
			menu->setItemEnabled(id, false);

		id = menu->insertItem(SmallIconSet("go-next"), i18n("Jump to Next Page"), this, TQ_SLOT(nextStackPage()));
		if(!stack->widget(stack->id(stack->visibleWidget())+1))
			menu->setItemEnabled(id, false);

		id = menu->insertItem(SmallIconSet("go-previous"), i18n("Jump to Previous Page"), this, TQ_SLOT(prevStackPage()));
		if(!stack->widget(stack->id(stack->visibleWidget()) -1) )
			menu->setItemEnabled(id, false);
		return true;
	}
	return false;
}

bool
ContainerFactory::startEditing(const TQCString &classname, TQWidget *w, KFormDesigner::Container *container)
{
	m_container = container;
	if(classname == "TQButtonGroup")
	{
		TQButtonGroup *group = static_cast<TQButtonGroup*>(w);
		TQRect r = TQRect(group->x()+2, group->y()-5, group->width()-10, w->fontMetrics().height() + 10);
		createEditor(classname, group->title(), group, container, r, TQt::AlignAuto);
		return true;
	}
	if(classname == "TQGroupBox" || classname == "GroupBox")
	{
		TQGroupBox *group = static_cast<TQGroupBox*>(w);
		TQRect r = TQRect(group->x()+2, group->y()-5, group->width()-10, w->fontMetrics().height() + 10);
		createEditor(classname, group->title(), group, container, r, TQt::AlignAuto);
		return true;
	}
	return false;
}

bool
ContainerFactory::saveSpecialProperty(const TQCString &, const TQString &name, const TQVariant &, TQWidget *w, TQDomElement &parentNode, TQDomDocument &parent)
{
	if((name == "title") && (w->parentWidget()->parentWidget()->inherits("TQTabWidget")))
	{
		TabWidgetBase *tab = dynamic_cast<TabWidgetBase*>(w->parentWidget()->parentWidget());
		KFormDesigner::FormIO::savePropertyElement(parentNode, parent, "attribute", "title", tab->tabLabel(w));
	}
	else if((name == "id") && (w->parentWidget()->isA("TQWidgetStack")))
	{
		TQWidgetStack *stack = (TQWidgetStack*)w->parentWidget();
		KFormDesigner::FormIO::savePropertyElement(parentNode, parent, "attribute", "id", stack->id(w));
	}
	else
		return false;
	return true;
}

bool
ContainerFactory::readSpecialProperty(const TQCString &, TQDomElement &node, TQWidget *w, KFormDesigner::ObjectTreeItem *item)
{
	TQString name = node.attribute("name");
	if((name == "title") && (item->parent()->widget()->inherits("TQTabWidget")))
	{
		TabWidgetBase *tab = dynamic_cast<TabWidgetBase*>(w->parentWidget());
		tab->addTab(w, node.firstChild().toElement().text());
		item->addModifiedProperty("title", node.firstChild().toElement().text());
		return true;
	}

	if((name == "id") && (w->parentWidget()->isA("TQWidgetStack")))
	{
		TQWidgetStack *stack = (TQWidgetStack*)w->parentWidget();
		int id = KFormDesigner::FormIO::readPropertyValue(node.firstChild(), w, name).toInt();
		stack->addWidget(w, id);
		stack->raiseWidget(w);
		item->addModifiedProperty("id", id);
		return true;
	}

	return false;
}

TQValueList<TQCString>
ContainerFactory::autoSaveProperties(const TQCString &c)
{
	TQValueList<TQCString> lst;
//	if(c == "SubForm")
//		lst << "formName";
	if(c == "TQSplitter")
		lst << "orientation";
	return lst;
}

bool
ContainerFactory::isPropertyVisibleInternal(const TQCString &classname,
	TQWidget *w, const TQCString &property, bool isTopLevel)
{
	bool ok = true;

	if((classname == "HBox") || (classname == "VBox") || (classname == "Grid") ||
		(classname == "HFlow") || (classname == "VFlow"))
	{
		return property == "name" || property == "geometry";
	}
	else if (classname == "TQGroupBox" || classname=="GroupBox") {
		ok =
#ifdef KEXI_NO_UNFINISHED
/*! @todo Hidden for now in Kexi. "checkable" and "checked" props need adding
a fake properties which will allow to properly work in design mode, otherwise
child widgets become frozen when checked==true */
			(m_showAdvancedProperties || (property != "checkable" && property != "checked")) &&
#endif
			true
			;
	}
	else if (classname == "KFDTabWidget") {
		ok = (m_showAdvancedProperties || (property != "tabReorderingEnabled" && property != "hoverCloseButton" && property != "hoverCloseButtonDelayed"));
	}

	return ok && WidgetFactory::isPropertyVisibleInternal(classname, w, property, isTopLevel);
}

bool
ContainerFactory::changeText(const TQString &text)
{
	changeProperty("title", text, m_container->form());
	return true;
}

void
ContainerFactory::resizeEditor(TQWidget *editor, TQWidget *widget, const TQCString &)
{
	TQSize s = widget->size();
	editor->move(widget->x() + 2, widget->y() - 5);
	editor->resize(s.width() - 20, widget->fontMetrics().height() +10);
}

// Widget Specific slots used in menu items

void ContainerFactory::addTabPage()
{
//	if (!m_widget->inherits("TQTabWidget"))
	if (!widget()->inherits("TQTabWidget"))
		return;
	KCommand *com = new InsertPageCommand(m_container, widget());
	if(dynamic_cast<TabWidgetBase*>(widget())->count() == 0)
	{
		com->execute();
		delete com;
	}
	else
		m_container->form()->addCommand(com, true);
}

void ContainerFactory::removeTabPage()
{
	if (!widget()->inherits("TQTabWidget"))
		return;
	TabWidgetBase *tab = dynamic_cast<TabWidgetBase*>(widget());
	TQWidget *w = tab->currentPage();

	KFormDesigner::WidgetList list;
	list.append(w);
	KCommand *com = new KFormDesigner::DeleteWidgetCommand(list, m_container->form());
	tab->removePage(w);
	m_container->form()->addCommand(com, true);
}

void ContainerFactory::renameTabPage()
{
	if (!widget()->inherits("TQTabWidget"))
		return;
	TabWidgetBase *tab = dynamic_cast<TabWidgetBase*>(widget());
	TQWidget *w = tab->currentPage();
	bool ok;

	TQString name = KInputDialog::getText(i18n("New Page Title"), i18n("Enter a new title for the current page:"),
	tab->tabLabel(w), &ok, w->topLevelWidget());
	if(ok)
		tab->changeTab(w, name);
}

void ContainerFactory::reorderTabs(int oldpos, int newpos)
{
	KFormDesigner::ObjectTreeItem *tab
		= KFormDesigner::FormManager::self()->activeForm()->objectTree()->lookup(sender()->name());
	if(!tab)
		return;

	KFormDesigner::ObjectTreeItem *item = tab->children()->take(oldpos);
	tab->children()->insert(newpos, item);
}

void ContainerFactory::addStackPage()
{
	if (!widget()->isA("TQWidgetStack"))
		return;
	KCommand *com = new InsertPageCommand(m_container, widget());
	if(!((TQWidgetStack*)widget())->visibleWidget())
	{
		com->execute();
		delete com;
	}
	else
		m_container->form()->addCommand(com, true);
}

void ContainerFactory::removeStackPage()
{
	if (!widget()->isA("TQWidgetStack"))
		return;
	TQWidgetStack *stack = (TQWidgetStack*)widget();
	TQWidget *page = stack->visibleWidget();

	KFormDesigner::WidgetList list;
	list.append(page);
	KCommand *com = new KFormDesigner::DeleteWidgetCommand(list, m_container->form());

	// raise prev widget
	int id = stack->id(page) - 1;
	while(!stack->widget(id))
		id--;
	stack->raiseWidget(id);

	stack->removeWidget(page);
	m_container->form()->addCommand(com, true);
}

void ContainerFactory::prevStackPage()
{
	TQWidgetStack *stack = (TQWidgetStack*)widget();
	int id = stack->id(stack->visibleWidget()) - 1;
	if(stack->widget(id))
		stack->raiseWidget(id);
}

void ContainerFactory::nextStackPage()
{
	TQWidgetStack *stack = (TQWidgetStack*)widget();
	int id = stack->id(stack->visibleWidget()) + 1;
	if(stack->widget(id))
		stack->raiseWidget(id);
}

ContainerFactory::~ContainerFactory()
{
}

KFORMDESIGNER_WIDGET_FACTORY(ContainerFactory, containers)

#include "containerfactory.moc"
