/***************************************************************************
 *   Copyright (C) 2003 by Lucijan Busch <lucijan@kde.org>                 *
 *   Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>            *
 *   This program 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.                       *
 ***************************************************************************/

#include <tqlabel.h>
#include <tqpopupmenu.h>
#include <tqcursor.h>
#include <tqradiobutton.h>
#include <tqcheckbox.h>
#include <tqslider.h>
#include <tqobjectlist.h>
#include <tqstring.h>
#include <tqvariant.h>
#include <tqheader.h>
#include <tqdom.h>
#include <tqstyle.h>
#include <tqvaluevector.h>

#include <klineedit.h>
#include <kpushbutton.h>
#include <knuminput.h>
#include <kcombobox.h>
#include <tdelistbox.h>
#include <ktextedit.h>
#include <tdelistview.h>
#include <kprogress.h>
#include <kiconloader.h>
#include <kgenericfactory.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <tdeversion.h>

#if TDE_VERSION < TDE_MAKE_VERSION(3,1,9)
# include <tqdatetimeedit.h>
# define KTimeWidget TQTimeEdit
# define KDateWidget TQDateEdit
# define KDateTimeWidget TQDateTimeEdit
#else
# include <ktimewidget.h>
# include <kdatewidget.h>
# include <kdatetimewidget.h>
#endif

#include "spring.h"
#include "formIO.h"
#include "form.h"
#include "formmanager.h"
#include "widgetlibrary.h"
#include "widgetpropertyset.h"
#include <koproperty/property.h>

#include "stdwidgetfactory.h"

// Some widgets subclass to allow event filtering and some other things
KexiPictureLabel::KexiPictureLabel(const TQPixmap &pix, TQWidget *parent, const char *name)
 : TQLabel(parent, name)
{
	setPixmap(pix);
	setScaledContents(false);
}

bool
KexiPictureLabel::setProperty(const char *name, const TQVariant &value)
{
	if(TQString(name) == "pixmap")
		resize(value.toPixmap().height(), value.toPixmap().width());
	return TQLabel::setProperty(name, value);
}

Line::Line(Qt::Orientation orient, TQWidget *parent, const char *name)
 : TQFrame(parent, name)
{
	setFrameShadow(Sunken);
	if(orient ==Qt::Horizontal)
		setFrameShape(HLine);
	else
		setFrameShape(VLine);
}

void
Line::setOrientation(Qt::Orientation orient)
{
	if(orient ==Qt::Horizontal)
		setFrameShape(HLine);
	else
		setFrameShape(VLine);
}

Qt::Orientation
Line::orientation() const
{
	if(frameShape() == HLine)
		return Qt::Horizontal;
	else
		return Qt::Vertical;
}

// The factory itself

StdWidgetFactory::StdWidgetFactory(TQObject *parent, const char *, const TQStringList &)
 : KFormDesigner::WidgetFactory(parent, "stdwidgets")
{
	KFormDesigner::WidgetInfo *wFormWidget = new KFormDesigner::WidgetInfo(this);
	wFormWidget->setPixmap("form");
	wFormWidget->setClassName("FormWidgetBase");
	wFormWidget->setName(i18n("Form"));
	wFormWidget->setNamePrefix(i18n("This string will be used to name widgets of this class. It must _not_ contain white "
	"spaces and non latin1 characters.", "form"));
	wFormWidget->setDescription(i18n("A simple form widget"));
	addClass(wFormWidget);

	KFormDesigner::WidgetInfo *wCustomWidget = new KFormDesigner::WidgetInfo(this);
	wCustomWidget->setPixmap("unknown_widget");
	wCustomWidget->setClassName("CustomWidget");
	wCustomWidget->setName(i18n("Custom Widget"));
	wCustomWidget->setNamePrefix(i18n("This string will be used to name widgets of this class. It must _not_ contain white "
	"spaces and non latin1 characters.", "customWidget"));
	wCustomWidget->setDescription(i18n("A custom or non-supported widget"));
	addClass(wCustomWidget);

	KFormDesigner::WidgetInfo *wLabel = new KFormDesigner::WidgetInfo(this);
	wLabel->setPixmap("label");
	wLabel->setClassName(TQLABEL_OBJECT_NAME_STRING);
	wLabel->setName(i18n("Text Label"));
	wLabel->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.", "label"));
	wLabel->setDescription(i18n("A widget to display text"));
	addClass(wLabel);

	KFormDesigner::WidgetInfo *wPixLabel = new KFormDesigner::WidgetInfo(this);
	wPixLabel->setPixmap("pixmaplabel");
	wPixLabel->setClassName("KexiPictureLabel");
	wPixLabel->setName(i18n("Picture Label"));
//! @todo TQt designer compatibility: maybe use this class when TQLabel has a pixmap set...?
	//wPixLabel->addAlternateClassName(TQLABEL_OBJECT_NAME_STRING);
	wPixLabel->setSavingName("KexiPictureLabel");
	wPixLabel->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.", "picture"));
	wPixLabel->setDescription(i18n("A widget to display pictures"));
	addClass(wPixLabel);

	KFormDesigner::WidgetInfo *wLineEdit = new KFormDesigner::WidgetInfo(this);
	wLineEdit->setPixmap("lineedit");
	wLineEdit->setClassName("KLineEdit");
	wLineEdit->addAlternateClassName(TQLINEEDIT_OBJECT_NAME_STRING);
	wLineEdit->setIncludeFileName("klineedit.h");
	wLineEdit->setName(i18n("Line Edit"));
	wLineEdit->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.", "lineEdit"));
	wLineEdit->setDescription(i18n("A widget to input text"));
	addClass(wLineEdit);

	KFormDesigner::WidgetInfo *wSpring = new KFormDesigner::WidgetInfo(this);
	wSpring->setPixmap("spring");
	wSpring->setClassName("Spring");
	wSpring->setName(i18n("Spring"));
	wSpring->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.", "spring"));
	wSpring->setDescription(i18n("A spring to place between widgets"));
	addClass(wSpring);

	KFormDesigner::WidgetInfo *wPushButton = new KFormDesigner::WidgetInfo(this);
	wPushButton->setPixmap("button");
	wPushButton->setClassName("KPushButton");
	wPushButton->addAlternateClassName(TQPUSHBUTTON_OBJECT_NAME_STRING);
	wPushButton->setIncludeFileName("kpushbutton.h");
	wPushButton->setName(i18n("Push Button"));
	wPushButton->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.", "button"));
	wPushButton->setDescription(i18n("A simple push button to execute actions"));
	addClass(wPushButton);

	KFormDesigner::WidgetInfo *wRadioButton = new KFormDesigner::WidgetInfo(this);
	wRadioButton->setPixmap("radio");
	wRadioButton->setClassName(TQRADIOBUTTON_OBJECT_NAME_STRING);
	wRadioButton->setName(i18n("Option Button"));
	wRadioButton->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.", "optionButton"));
	wRadioButton->setDescription(i18n("An option button with text or pixmap label"));
	addClass(wRadioButton);

	KFormDesigner::WidgetInfo *wCheckBox = new KFormDesigner::WidgetInfo(this);
	wCheckBox->setPixmap("check");
	wCheckBox->setClassName(TQCHECKBOX_OBJECT_NAME_STRING);
	wCheckBox->setName(i18n("Check Box"));
	wCheckBox->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.", "checkBox"));
	wCheckBox->setDescription(i18n("A check box with text or pixmap label"));
	addClass(wCheckBox);

	KFormDesigner::WidgetInfo *wSpinBox = new KFormDesigner::WidgetInfo(this);
	wSpinBox->setPixmap("spin");
	wSpinBox->setClassName("KIntSpinBox");
	wSpinBox->addAlternateClassName(TQSPINBOX_OBJECT_NAME_STRING);
	wSpinBox->setIncludeFileName("knuminput.h");
	wSpinBox->setName(i18n("Spin Box"));
	wSpinBox->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.", "spinBox"));
	wSpinBox->setDescription(i18n("A spin box widget"));
	addClass(wSpinBox);

	KFormDesigner::WidgetInfo *wComboBox = new KFormDesigner::WidgetInfo(this);
	wComboBox->setPixmap("combo");
	wComboBox->setClassName("KComboBox");
	wComboBox->addAlternateClassName(TQCOMBOBOX_OBJECT_NAME_STRING);
	wComboBox->setIncludeFileName("kcombobox.h");
	wComboBox->setName(i18n("Combo Box"));
	wComboBox->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.", "comboBox"));
	wComboBox->setDescription(i18n("A combo box widget"));
	addClass(wComboBox);

	KFormDesigner::WidgetInfo *wListBox = new KFormDesigner::WidgetInfo(this);
	wListBox->setPixmap("listbox");
	wListBox->setClassName("TDEListBox");
	wListBox->addAlternateClassName(TQLISTBOX_OBJECT_NAME_STRING);
	wListBox->setIncludeFileName("tdelistbox.h");
	wListBox->setName(i18n("List Box"));
	wListBox->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.", "listBox"));
	wListBox->setDescription(i18n("A simple list widget"));
	addClass(wListBox);

	KFormDesigner::WidgetInfo *wTextEdit = new KFormDesigner::WidgetInfo(this);
	wTextEdit->setPixmap("textedit");
	wTextEdit->setClassName("KTextEdit");
	wTextEdit->addAlternateClassName(TQTEXTEDIT_OBJECT_NAME_STRING);
	wTextEdit->setIncludeFileName("ktextedit.h");
	wTextEdit->setName(i18n("Text Editor"));
	wTextEdit->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.", "textEditor"));
	wTextEdit->setDescription(i18n("A simple single-page rich text editor"));
	addClass(wTextEdit);

	KFormDesigner::WidgetInfo *wListView = new KFormDesigner::WidgetInfo(this);
	wListView->setPixmap("listview");
	wListView->setClassName("TDEListView");
	wListView->addAlternateClassName(TQLISTVIEW_OBJECT_NAME_STRING);
	wListView->setIncludeFileName("tdelistview.h");
	wListView->setName(i18n("List View"));
	wListView->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.", "listView"));
	wListView->setDescription(i18n("A list (or tree) widget"));
	addClass(wListView);

	KFormDesigner::WidgetInfo *wSlider = new KFormDesigner::WidgetInfo(this);
	wSlider->setPixmap("slider");
	wSlider->setClassName(TQSLIDER_OBJECT_NAME_STRING);
	wSlider->setName(i18n("Slider"));
	wSlider->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.", "slider"));
	wSlider->setDescription(i18n("An horizontal slider"));
	addClass(wSlider);

	KFormDesigner::WidgetInfo *wProgressBar = new KFormDesigner::WidgetInfo(this);
	wProgressBar->setPixmap("progress");
	wProgressBar->setClassName("KProgress");
	wProgressBar->addAlternateClassName(TQPROGRESSBAR_OBJECT_NAME_STRING);
	wProgressBar->setIncludeFileName("kprogress.h");
	wProgressBar->setName(i18n("Progress Bar"));
	wProgressBar->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.", "progressBar"));
	wProgressBar->setDescription(i18n("A progress indicator widget"));
	addClass(wProgressBar);

	KFormDesigner::WidgetInfo *wLine = new KFormDesigner::WidgetInfo(this);
	wLine->setPixmap("line");
	wLine->setClassName("Line");
	wLine->setName(i18n("Line"));
	wLine->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.", "line"));
	wLine->setDescription(i18n("A line to be used as a separator"));
	addClass(wLine);

	KFormDesigner::WidgetInfo *wDate = new KFormDesigner::WidgetInfo(this);
	wDate->setPixmap("dateedit");
	wDate->setClassName("KDateWidget");
#if TDE_VERSION >= TDE_MAKE_VERSION(3,1,9)
	wDate->addAlternateClassName(TQDATEEDIT_OBJECT_NAME_STRING);
	wDate->setIncludeFileName("kdatewidget.h");
#endif
	wDate->setName(i18n("Date Widget"));
	wDate->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.", "dateWidget"));
	wDate->setDescription(i18n("A widget to input and display a date"));
	addClass(wDate);

	KFormDesigner::WidgetInfo *wTime = new KFormDesigner::WidgetInfo(this);
	wTime->setPixmap("timeedit");
	wTime->setClassName("KTimeWidget");
#if TDE_VERSION >= TDE_MAKE_VERSION(3,1,9)
	wTime->addAlternateClassName(TQTIMEEDIT_OBJECT_NAME_STRING);
	wTime->setIncludeFileName("ktimewidget.h");
#endif
	wTime->setName(i18n("Time Widget"));
	wTime->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.", "timeWidget"));
	wTime->setDescription(i18n("A widget to input and display a time"));
	addClass(wTime);

	KFormDesigner::WidgetInfo *wDateTime = new KFormDesigner::WidgetInfo(this);
	wDateTime->setPixmap("datetimeedit");
	wDateTime->setClassName("KDateTimeWidget");
#if TDE_VERSION >= TDE_MAKE_VERSION(3,1,9)
	wDateTime->addAlternateClassName(TQDATETIMEEDIT_OBJECT_NAME_STRING);
	wDateTime->setIncludeFileName("kdatetimewidget.h");
#endif
	wDateTime->setName(i18n("Date/Time Widget"));
	wDateTime->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.", "dateTimeWidget"));
	wDateTime->setDescription(i18n("A widget to input and display a time and a date"));
	addClass(wDateTime);

	m_propDesc["toggleButton"] = i18n("Toggle");
	m_propDesc["autoRepeat"] = i18n("Auto Repeat");
	m_propDesc["autoDefault"] = i18n("Auto Default");
	m_propDesc["default"] = i18n("Default");
	m_propDesc["flat"] = i18n("Flat");
	m_propDesc["echoMode"] =
		i18n("Echo mode for Line Edit widget eg. Normal, NoEcho, Password","Echo Mode");
	m_propDesc["indent"] = i18n("Indent");
	//line
	m_propDesc["orientation"] = i18n("Orientation");
	//checkbox
	m_propDesc["checked"] = i18n("Checked checkbox", "Checked");
	m_propDesc["tristate"] = i18n("Tristate checkbox", "Tristate");

	//for EchoMode
	m_propValDesc["Normal"] = i18n("For Echo Mode", "Normal");
	m_propValDesc["NoEcho"] = i18n("For Echo Mode", "No Echo");
	m_propValDesc["Password"] = i18n("For Echo Mode", "Password");

	//for spring
	m_propDesc["sizeType"] = i18n("Size Type");

	//for labels
	m_propDesc["textFormat"] = i18n("Text Format");
	m_propValDesc["PlainText"] = i18n("For Text Format", "Plain");
	m_propValDesc["RichText"] = i18n("For Text Format", "Hypertext");
	m_propValDesc["AutoText"] = i18n("For Text Format", "Auto");
	m_propValDesc["LogText"] = i18n("For Text Format", "Log");

	//KTextEdit
	m_propDesc["tabStopWidth"] = i18n("Tab Stop Width");
	m_propDesc["tabChangesFocus"] = i18n("Tab Changes Focus");
	m_propDesc["wrapPolicy"] = i18n("Word Wrap Policy");
	m_propValDesc["AtWordBoundary"] = i18n("For Word Wrap Policy", "At Word Boundary");
	m_propValDesc["Anywhere"] = i18n("For Word Wrap Policy", "Anywhere");
	m_propValDesc["AtWordOrDocumentBoundary"] = i18n("For Word Wrap Policy", "At Word Boundary If Possible");
	m_propDesc["wordWrap"] = i18n("Word Wrapping");
	m_propDesc["wrapColumnOrWidth"] = i18n("Word Wrap Position");
	m_propValDesc["NoWrap"] = i18n("For Word Wrap Position", "None");
	m_propValDesc["WidgetWidth"] = i18n("For Word Wrap Position", "Widget's Width");
	m_propValDesc["FixedPixelWidth"] = i18n("For Word Wrap Position", "In Pixels");
	m_propValDesc["FixedColumnWidth"] = i18n("For Word Wrap Position", "In Columns");
	m_propDesc["linkUnderline"] = i18n("Links Underlined");

	//internal props
	setInternalProperty("Line","orientationSelectionPopup","1");
	setInternalProperty("Line","orientationSelectionPopup:horizontalIcon","line_horizontal");
	setInternalProperty("Line","orientationSelectionPopup:verticalIcon","line_vertical");
	setInternalProperty("Line","orientationSelectionPopup:horizontalText",i18n("Insert &Horizontal Line"));
	setInternalProperty("Line","orientationSelectionPopup:verticalText",i18n("Insert &Vertical Line"));
	setInternalProperty("Spring","orientationSelectionPopup","1");
	setInternalProperty("Spring","orientationSelectionPopup:horizontalIcon","spring");
	setInternalProperty("Spring","orientationSelectionPopup:verticalIcon","spring_vertical");
	setInternalProperty("Spring","orientationSelectionPopup:horizontalText",i18n("Insert &Horizontal Spring"));
	setInternalProperty("Spring","orientationSelectionPopup:verticalText",i18n("Insert &Vertical Spring"));
}

StdWidgetFactory::~StdWidgetFactory()
{
}

TQWidget*
StdWidgetFactory::createWidget(const TQCString &c, TQWidget *p, const char *n, 
	KFormDesigner::Container *container, int options)
{
	TQWidget *w=0;
	TQString text( container->form()->library()->textForWidgetName(n, c) );
	const bool designMode = options & KFormDesigner::WidgetFactory::DesignViewMode;

	if(c == TQLABEL_OBJECT_NAME_STRING)
		w = new TQLabel(text, p, n);
	else if(c == "KexiPictureLabel")
		w = new KexiPictureLabel(DesktopIcon("image"), p, n);

	else if(c == "KLineEdit")
	{
		w = new KLineEdit(p, n);
		if (designMode)
			w->setCursor(TQCursor(TQt::ArrowCursor));
	}
	else if(c == "KPushButton")
		w = new KPushButton(/*i18n("Button")*/text, p, n);

	else if(c == TQRADIOBUTTON_OBJECT_NAME_STRING)
		w = new TQRadioButton(/*i18n("Radio Button")*/text, p, n);

	else if(c == TQCHECKBOX_OBJECT_NAME_STRING)
		w = new TQCheckBox(/*i18n("Check Box")*/text, p, n);

	else if(c == "KIntSpinBox")
		w = new KIntSpinBox(p, n);

	else if(c == "KComboBox")
		w = new KComboBox(p, n);

	else if(c == "TDEListBox")
		w = new TDEListBox(p, n);

	else if(c == "KTextEdit")
		w = new KTextEdit(/*i18n("Enter your text here")*/text, TQString(), p, n);

	else if(c == "TDEListView")
	{
		w = new TDEListView(p, n);
		if(container->form()->interactiveMode())
			((TDEListView*)w)->addColumn(i18n("Column 1"));
		((TDEListView*)w)->setRootIsDecorated(true);
	}
	else if(c == TQSLIDER_OBJECT_NAME_STRING)
		w = new TQSlider(Qt::Horizontal, p, n);

	else if(c == "KProgress")
		w = new KProgress(p, n);

	else if(c == "KDateWidget")
		w = new KDateWidget(TQDate::currentDate(), p, n);

	else if(c == "KTimeWidget")
		w = new KTimeWidget(TQTime::currentTime(), p, n);

	else if(c == "KDateTimeWidget")
		w = new KDateTimeWidget(TQDateTime::currentDateTime(), p, n);

	else if(c == "Line")
		w = new Line(options & WidgetFactory::VerticalOrientation ? Qt::Vertical : Qt::Horizontal, p, n);

	else if(c == "Spring") {
		w = new Spring(p, n);
		if (0 == (options & WidgetFactory::AnyOrientation))
			static_cast<Spring*>(w)->setOrientation(
				(options & WidgetFactory::VerticalOrientation) ? Qt::Vertical : Qt::Horizontal);
	}

	if(w)
		return w;

	kdDebug() << "WARNING :: w == 0 "  << endl;
	return 0;
}

bool
StdWidgetFactory::previewWidget(const TQCString &classname, TQWidget *widget, KFormDesigner::Container *)
{
	if(classname == "Spring") {
		((Spring*)widget)->setPreviewMode();
		return true;
	}
	return false;
}

bool
StdWidgetFactory::createMenuActions(const TQCString &classname, TQWidget *, TQPopupMenu *menu,
	KFormDesigner::Container *)
{
	if((classname == TQLABEL_OBJECT_NAME_STRING) || (classname == "KTextEdit"))
	{
		menu->insertItem(SmallIconSet("edit"), i18n("Edit Rich Text"), this, TQT_SLOT(editText()));
		return true;
	}
	else if(classname == "TDEListView")
	{
		menu->insertItem(SmallIconSet("edit"), i18n("Edit Listview Contents"), this, TQT_SLOT(editListContents()));
		return true;
	}

	return false;
}

bool
StdWidgetFactory::startEditing(const TQCString &classname, TQWidget *w, KFormDesigner::Container *container)
{
	setWidget(w, container);
//	m_container = container;
	if(classname == "KLineEdit")
	{
		KLineEdit *lineedit = static_cast<KLineEdit*>(w);
		createEditor(classname, lineedit->text(), lineedit, container, lineedit->geometry(), lineedit->alignment(), true);
		return true;
	}
	else if(classname == TQLABEL_OBJECT_NAME_STRING)
	{
		TQLabel *label = static_cast<TQLabel*>(w);
		if(label->textFormat() == RichText)
		{
			//m_widget = w;
//			setWidget(w, container);
			editText();
		}
		else
			createEditor(classname, label->text(), label, container, label->geometry(), label->alignment());
		return true;
	}
	else if(classname == "KPushButton")
	{
		KPushButton *push = static_cast<KPushButton*>(w);
		TQRect r = w->style().subRect(TQStyle::SR_PushButtonContents, w);
		TQRect editorRect = TQRect(push->x() + r.x(), push->y() + r.y(), r.width(), r.height());
		//r.setX(r.x() + 5);
		//r.setY(r.y() + 5);
		//r.setWidth(r.width()-10);
		//r.setHeight(r.height() - 10);
		createEditor(classname, push->text(), push, container, editorRect, TQt::AlignCenter, false, false, TQt::PaletteButton);
		return true;
	}
	else if(classname == TQRADIOBUTTON_OBJECT_NAME_STRING)
	{
		TQRadioButton *radio = static_cast<TQRadioButton*>(w);
		TQRect r = w->style().subRect(TQStyle::SR_RadioButtonContents, w);
		TQRect editorRect = TQRect(radio->x() + r.x(), radio->y() + r.y(), r.width(), r.height());
		createEditor(classname, radio->text(), radio, container, editorRect, TQt::AlignAuto);
		return true;
	}
	else if(classname == TQCHECKBOX_OBJECT_NAME_STRING)
	{
		TQCheckBox *check = static_cast<TQCheckBox*>(w);
		//TQRect r(check->geometry());
		//r.setX(r.x() + 20);
		TQRect r = w->style().subRect(TQStyle::SR_CheckBoxContents, w);
		TQRect editorRect = TQRect(check->x() + r.x(), check->y() + r.y(), r.width(), r.height());
		createEditor(classname, check->text(), check, container, editorRect, TQt::AlignAuto);
		return true;
	}
	else if((classname == "KComboBox") || (classname == "TDEListBox"))
	{
		TQStringList list;
		if(classname == "TDEListBox")
		{
			TDEListBox *listbox = (TDEListBox*)w;
			for(uint i=0; i < listbox->count(); i++)
				list.append(listbox->text(i));
		}
		else if(classname == "KComboBox")
		{
			KComboBox *combo = (KComboBox*)w;
			for(int i=0; i < combo->count(); i++)
				list.append(combo->text(i));
		}

		if(editList(w, list))
		{
			if(classname == "TDEListBox")
			{
				((TDEListBox*)w)->clear();
				((TDEListBox*)w)->insertStringList(list);
			}
			else if(classname == "KComboBox")
			{
				((KComboBox*)w)->clear();
				((KComboBox*)w)->insertStringList(list);
			}
		}
		return true;
	}
	else if((classname == "KTextEdit") || (classname == "KDateTimeWidget") || (classname == "KTimeWidget") ||
		(classname == "KDateWidget") || (classname == "KIntSpinBox")) {
		disableFilter(w, container);
		return true;
	}
	return false;
}

bool
StdWidgetFactory::clearWidgetContent(const TQCString &classname, TQWidget *w)
{
	if(classname == "KLineEdit")
		((KLineEdit*)w)->clear();
	else if(classname == "TDEListBox")
		((TDEListBox*)w)->clear();
	else if(classname == "TDEListView")
		((TDEListView*)w)->clear();
	else if(classname == "KComboBox")
		((KComboBox*)w)->clear();
	else if(classname == "KTextEdit")
		((KTextEdit*)w)->clear();
	else
		return false;
	return true;
}

bool
StdWidgetFactory::changeText(const TQString &text)
{
	TQCString n = WidgetFactory::widget()->className();
	TQWidget *w = WidgetFactory::widget();
	if(n == "KIntSpinBox")
		((KIntSpinBox*)w)->setValue(text.toInt());
	else
		changeProperty("text", text, m_container->form());

	/* By-hand method not needed as sizeHint() can do that for us
	TQFontMetrics fm = w->fontMetrics();
	TQSize s(fm.width( text ), fm.height());
	int width;
	if(n == TQLABEL_OBJECT_NAME_STRING) // labels are resized to fit the text
	{
		w->resize(w->sizeHint());
		WidgetFactory::m_editor->resize(w->size());
		return;
	}
	// and other widgets are just enlarged if needed
	else if(n == "KPushButton")
		width = w->style().sizeFromContents( TQStyle::CT_PushButton, w, s).width();
	else if(n == TQCHECKBOX_OBJECT_NAME_STRING)
		width = w->style().sizeFromContents( TQStyle::CT_CheckBox, w, s).width();
	else if(n == TQRADIOBUTTON_OBJECT_NAME_STRING)
		width = w->style().sizeFromContents( TQStyle::CT_RadioButton, w, s).width();
	else
		return;
	int width = w->sizeHint().width();*/

#if 0 //not needed here, size hint is used on creation in InsertWidgetCommand::execute()
	if(w->width() < width)
	{
		w->resize(width, w->height() );
		//WidgetFactory::m_editor->resize(w->size());
	}
#endif
	return true;
}

void
StdWidgetFactory::resizeEditor(TQWidget *editor, TQWidget *widget, const TQCString &classname)
{
	TQSize s = widget->size();
	TQPoint p = widget->pos();
	TQRect r;

	if(classname == TQRADIOBUTTON_OBJECT_NAME_STRING)
	{
		r = widget->style().subRect(TQStyle::SR_RadioButtonContents, widget);
		p += r.topLeft();
		s.setWidth(r.width());
	}
	else if(classname == TQCHECKBOX_OBJECT_NAME_STRING)
	{
		r = widget->style().subRect(TQStyle::SR_CheckBoxContents, widget);
		p += r.topLeft();
		s.setWidth(r.width());
	}
	else if(classname == "KPushButton")
	{
		r = widget->style().subRect(TQStyle::SR_PushButtonContents, widget);
		p += r.topLeft();
		s = r.size();
	}

	editor->resize(s);
	editor->move(p);
}

bool
StdWidgetFactory::saveSpecialProperty(const TQCString &classname, const TQString &name, const TQVariant &, TQWidget *w, TQDomElement &parentNode, TQDomDocument &domDoc)
{
	if(name == "list_items" && classname == "KComboBox")
	{
		KComboBox *combo = (KComboBox*)w;
		for(int i=0; i < combo->count(); i++)
		{
			TQDomElement item = domDoc.createElement("item");
			KFormDesigner::FormIO::savePropertyElement(item, domDoc, "property", "text", combo->text(i));
			parentNode.appendChild(item);
		}
		return true;
	}
	else if(name == "list_items" && classname == "TDEListBox")
	{
		TDEListBox *listbox = (TDEListBox*)w;
		for(uint i=0; i < listbox->count(); i++)
		{
			TQDomElement item = domDoc.createElement("item");
			KFormDesigner::FormIO::savePropertyElement(item, domDoc, "property", "text", listbox->text(i));
			parentNode.appendChild(item);
		}
		return true;
	}
	else if(name == "list_contents" && classname == "TDEListView")
	{
		TDEListView *listview = (TDEListView*)w;
		// First we save the columns
		for(int i = 0; i < listview->columns(); i++)
		{
			TQDomElement item = domDoc.createElement("column");
			KFormDesigner::FormIO::savePropertyElement(item, domDoc, "property", "text", listview->columnText(i));
			KFormDesigner::FormIO::savePropertyElement(item, domDoc, "property", "width", listview->columnWidth(i));
			KFormDesigner::FormIO::savePropertyElement(item, domDoc, "property", "resizable", listview->header()->isResizeEnabled(i));
			KFormDesigner::FormIO::savePropertyElement(item, domDoc, "property", "clickable", listview->header()->isClickEnabled(i));
			KFormDesigner::FormIO::savePropertyElement(item, domDoc, "property", "fullwidth", listview->header()->isStretchEnabled(i));
			parentNode.appendChild(item);
		}

		// Then we save the list view items
		TQListViewItem *item = listview->firstChild();
		while(item)
		{
			saveListItem(item, parentNode, domDoc);
			item = item->nextSibling();
		}
		return true;
	}

	return false;
}

void
StdWidgetFactory::saveListItem(TQListViewItem *item, TQDomNode &parentNode, TQDomDocument &domDoc)
{
	TQDomElement element = domDoc.createElement("item");
	parentNode.appendChild(element);

	// We save the text of each column
	for(int i = 0; i < item->listView()->columns(); i++)
		KFormDesigner::FormIO::savePropertyElement(element, domDoc, "property", "text", item->text(i));

	// Then we save every sub items
	TQListViewItem *child = item->firstChild();
	while(child)
	{
		saveListItem(child, element, domDoc);
		child = child->nextSibling();
	}
}

bool
StdWidgetFactory::readSpecialProperty(const TQCString &classname, TQDomElement &node, TQWidget *w, KFormDesigner::ObjectTreeItem *)
{
	TQString tag = node.tagName();
	TQString name = node.attribute("name");

	if((tag == "item") && (classname == "KComboBox"))
	{
		KComboBox *combo = (KComboBox*)w;
		TQVariant val = KFormDesigner::FormIO::readPropertyValue(node.firstChild().firstChild(), TQT_TQOBJECT(w), name);
		if(val.canCast(TQVariant::Pixmap))
			combo->insertItem(val.toPixmap());
		else
			combo->insertItem(val.toString());
		return true;
	}

	if((tag == "item") && (classname == "TDEListBox"))
	{
		TDEListBox *listbox = (TDEListBox*)w;
		TQVariant val = KFormDesigner::FormIO::readPropertyValue(node.firstChild().firstChild(), TQT_TQOBJECT(w), name);
		if(val.canCast(TQVariant::Pixmap))
			listbox->insertItem(val.toPixmap());
		else
			listbox->insertItem(val.toString());
		return true;
	}

	if((tag == "column") && (classname == "TDEListView"))
	{
		TDEListView *listview = (TDEListView*)w;
		int id=0;
		for(TQDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling())
		{
			TQString prop = n.toElement().attribute("name");
			TQVariant val = KFormDesigner::FormIO::readPropertyValue(n.firstChild(), TQT_TQOBJECT(w), name);
			if(prop == "text")
				id = listview->addColumn(val.toString());
			else if(prop == "width")
				listview->setColumnWidth(id, val.toInt());
			else if(prop == "resizable")
				listview->header()->setResizeEnabled(val.toBool(), id);
			else if(prop == "clickable")
				listview->header()->setClickEnabled(val.toBool(), id);
			else if(prop == "fullwidth")
				listview->header()->setStretchEnabled(val.toBool(), id);
		}
		return true;
	}
	else if((tag == "item") && (classname == "TDEListView"))
	{
		TDEListView *listview = (TDEListView*)w;
		readListItem(node, 0, listview);
		return true;
	}

	return false;
}

void
StdWidgetFactory::readListItem(TQDomElement &node, TQListViewItem *parent, TDEListView *listview)
{
	TQListViewItem *item;
	if(parent)
		item = new TDEListViewItem(parent);
	else
		item = new TDEListViewItem(listview);

	// We need to move the item at the end of the list
	TQListViewItem *last;
	if(parent)
		last = parent->firstChild();
	else
		last = listview->firstChild();

	while(last->nextSibling())
		last = last->nextSibling();
	item->moveItem(last);

	int i = 0;
	for(TQDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling())
	{
		TQDomElement childEl = n.toElement();
		TQString prop = childEl.attribute("name");
		TQString tag = childEl.tagName();

		// We read sub items
		if(tag == "item")
		{
			item->setOpen(true);
			readListItem(childEl, item, listview);
		}
		// and column texts
		else if((tag == "property") && (prop == "text"))
		{
			TQVariant val = KFormDesigner::FormIO::readPropertyValue(n.firstChild(), TQT_TQOBJECT(listview), "item");
			item->setText(i, val.toString());
			i++;
		}
	}
}

bool
StdWidgetFactory::isPropertyVisibleInternal(const TQCString &classname, 
	TQWidget *w, const TQCString &property, bool isTopLevel)
{
	bool ok = true;
	if(classname == "FormWidgetBase")
	{
		if(property == "iconText" 
			|| property == "geometry" /*nonsense for toplevel widget*/)
			return false;
	}
	else if (classname == "CustomWidget")
	{
	}
	else if(classname == "Spring")
	{
		return Spring::isPropertyVisible(property);
	}
	else if(classname == "KexiPictureLabel")
	{
		if((property == "text") || (property == "indent") || (property == "textFormat") || (property == "font") || (property == "alignment"))
			return false;
	}
	else if(classname == TQLABEL_OBJECT_NAME_STRING)
	{
		if(property == "pixmap")
			return false;
	}
	else if(classname == "KLineEdit")
	{
		if(property == "vAlign")
			return false;
	}
	else if(classname == "KTextEdit")
		ok = m_showAdvancedProperties ||
			   property!="undoDepth"
			&& property!="undoRedoEnabled" //always true!
			&& property!="dragAutoScroll" //always true!
			&& property!="overwriteMode" //always false!
			&& property!="resizePolicy"
			&& property!="autoFormatting" //too complex
#ifdef KEXI_NO_UNFINISHED
			&& property!="paper"
#endif
			;
	else if(classname == "Line")
	{
		if((property == "frameShape") || (property == "font") || (property == "margin"))
			return false;
	}
	else if(classname==TQCHECKBOX_OBJECT_NAME_STRING)
	{
		ok = m_showAdvancedProperties || (property != "autoRepeat");
	}
	else if(classname==TQRADIOBUTTON_OBJECT_NAME_STRING)
	{
		ok = m_showAdvancedProperties || (property != "autoRepeat");
	}
	else if(classname=="KPushButton")
	{
//! @todo reenable autoDefault / default if the top level window is dialog...
		ok = m_showAdvancedProperties || (property != "autoDefault" && property != "default");
	}
	return ok && WidgetFactory::isPropertyVisibleInternal(classname, w, property, isTopLevel);
}

TQValueList<TQCString>
StdWidgetFactory::autoSaveProperties(const TQCString &classname)
{
	TQValueList<TQCString> l;

	if(classname == TQLABEL_OBJECT_NAME_STRING)
		l << "text";
	if(classname == "KPushButton")
		l << "text";
	else if(classname == "KexiPictureLabel")
		l << "pixmap";
	else if(classname == "KComboBox")
		l << "list_items";
	else if(classname == "TDEListBox")
		l << "list_items";
	else if(classname == "TDEListView")
		l << "list_contents";
	else if(classname == "Line")
		l << "orientation";
	else if(classname == "KTimeWidget")
		l << "time";
	else if(classname == "KDateWidget")
		l << "date";
	else if(classname == "KDateTimeWidget")
		l << "dateTime";
	else if(classname == "Spring")
		l << "sizeType" << "orientation";
	else if(classname == "KTextEdit")
		l << "textFormat" << "text";

	return l;
}

void
StdWidgetFactory::editText()
{
	TQCString classname = widget()->className();
	TQString text;
	if(classname == "KTextEdit")
		text = ((KTextEdit*)widget())->text();
	else if(classname == TQLABEL_OBJECT_NAME_STRING)
		text = ((TQLabel*)widget())->text();

	if(editRichText(widget(), text))
	{
		changeProperty("textFormat", "RichText", m_container->form());
		changeProperty("text", text, m_container->form());
	}

	if(classname == TQLABEL_OBJECT_NAME_STRING)
		widget()->resize(widget()->sizeHint());
}

void
StdWidgetFactory::editListContents()
{
	if(widget()->inherits(TQLISTVIEW_OBJECT_NAME_STRING))
		editListView((TQListView*)widget());
}

void
StdWidgetFactory::setPropertyOptions( KFormDesigner::WidgetPropertySet& buf, const KFormDesigner::WidgetInfo& info, TQWidget *w )
{
	Q_UNUSED( info );
	Q_UNUSED( w );

	if (buf.contains("indent")) {
		buf["indent"].setOption("min", -1);
		buf["indent"].setOption("minValueText", i18n("default indent value", "default"));
	}
}

KFORMDESIGNER_WIDGET_FACTORY(StdWidgetFactory, stdwidgets)

#include "stdwidgetfactory.moc"

