/* This file is part of the KDE project
   Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
   Copyright (C) 2005-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.
*/

#ifndef FORMIO_H
#define FORMIO_H

#include <tqobject.h>
#include <tqdict.h>
#include <tqstring.h>
#include <tqwidget.h>
#include <tqmap.h>

class TQString;
class TQDomElement;
class TQDomNode;
class TQDomDocument;
class TQDomText;
class TQVariant;
class TQLabel;

//! A blank widget displayed when class is not supported
class KFORMEDITOR_EXPORT CustomWidget : public TQWidget
{
	Q_OBJECT
  

	public:
		CustomWidget(const TQCString &className, TQWidget *parent, const char *name);
		virtual ~CustomWidget();

		virtual void paintEvent(TQPaintEvent *ev);

	private:
		TQCString m_className;
};

namespace KFormDesigner {

class WidgetPropertySet;
class Form;
class ObjectTreeItem;
class Container;
class WidgetLibrary;

//! KFormDesigner API version number. Increased on every breaking of backward compatibility.
//! Use KFormDesigner::version() to get real version number of the library.
#define KFORMDESIGNER_VERSION 2

//! \return KFormDesigner API version number for this library. This information is stored
KFORMEDITOR_EXPORT uint version();

/** This class act as a namespace for all .ui files related functions, ie saving/loading .ui files.
    You don't need to create a FormIO object, as all methods are static.\n
    This class is able to read and write Forms to .ui files, and to save each type of properties, including set and enum
    properties, and pixmaps(pixmap-related code was taken from TQt Designer).
 **/
 //! A class to save/load forms from .ui files
class KFORMEDITOR_EXPORT FormIO : public TQObject
{
	Q_OBJECT
  

	public:
		FormIO();
		~FormIO();

		/*! Save the Form in the \a domDoc TQDomDocument. Called by saveForm().
		    \return true if saving succeeded.
		    \sa saveForm() */
		static bool saveFormToDom(Form *form, TQDomDocument &domDoc);

		/*! Save the Form \a form to the file \a filename. If \a filename is null or not given,
		    a Save File dialog will be shown to choose dest file.
		    \return true if saving succeeded.
		    \todo Add errors code and error dialog
		*/
		static bool saveFormToFile(Form *form, const TQString &filename=TQString());

		/*! Saves the Form to the \a dest string. \a indent can be specified to apply indentation.
		    \return true if saving succeeded.
		    \sa saveForm()
		 */
		static bool saveFormToString(Form *form, TQString &dest, int indent = 0);

		/*! Saves the \a form inside the \a dest TQByteArray.
		    \return true if saving succeeded.
		    \sa saveFormToDom(), saveForm()
		 */
		static bool saveFormToByteArray(Form *form, TQByteArray &dest);

		/*! Loads a form from the \a domDoc TQDomDocument. Called by loadForm() and loadFormData().
		    \return true if loading succeeded. */
		static bool loadFormFromDom(Form *form, TQWidget *container, TQDomDocument &domDoc);

		/*! Loads a form from the \a src TQByteArray.
		    \sa loadFormFromDom(), loadForm().
		    \return true if loading succeeded.
		 */
		static bool loadFormFromByteArray(Form *form, TQWidget *container, TQByteArray &src,
			bool preview=false);

		static bool loadFormFromString(Form *form, TQWidget *container, TQString &src, bool preview=false);

		/*! Loads the .ui file \a filename in the Form \a form. If \a filename is null or not given,
		    a Open File dialog will be shown to select the file to open.
		    createToplevelWidget() is used to load the Form's toplevel widget.
		    \return true if loading succeeded.
		    \todo Add errors code and error dialog
		*/
		static bool loadFormFromFile(Form *form, TQWidget *container, const TQString &filename=TQString());

		/*! Saves the widget associated to the ObjectTreeItem \a item into DOM document \a domDoc,
		    with \a parent as parent node.
		    It calls readPropertyValue() for each object property, readAttribute() for each attribute and
		    itself to save child widgets.\n
		    \return true if saving succeeded.
		    This is used to copy/paste widgets.
		*/
		static void saveWidget(ObjectTreeItem *item, TQDomElement &parent, TQDomDocument &domDoc,
			bool insideGridLayout=false);

		/*! Cleans the "UI" TQDomElement after saving widget. It deletes the "includes" element
		 not needed when pasting, and make sure all the "widget" elements are at the beginning.
		 Call this after copying a widget, before pasting.*/
		static void cleanClipboard(TQDomElement &uiElement);

		/*! Loads the widget associated to the TQDomElement \a el into the Container \a container,
		    with \a parent as parent widget.
		    If parent = 0, the Container::widget() is used as parent widget.
		    This is used to copy/paste widgets.
		*/
		static void loadWidget(Container *container,
			const TQDomElement &el, TQWidget *parent=0);

		/*! Save an element in the \a domDoc as child of \a parentNode.
		  The element will be saved like this :
		  \code  <$(tagName) name = "$(property)">< value_as_XML ><$(tagName)/>
		  \endcode
		*/
		static void savePropertyElement(TQDomElement &parentNode, TQDomDocument &domDoc, const TQString &tagName,
			const TQString &property, const TQVariant &value);

		/*! Read an object property in the DOM doc.
		   \param node   the TQDomNode of the property
		   \param obj    the widget whose property is being read
		   \param name   the name of the property being read
		*/
		static TQVariant readPropertyValue(TQDomNode node, TQObject *obj, const TQString &name);

		/*! Write an object property in the DOM doc.
		   \param parentNode the DOM document to write to
		   \param name   the name of the property being saved
		   \param value  the value of this property
		   \param w      the widget whose property is being saved
		   \param lib    the widget library for which the property is being saved

			 Properties of subwidget are saved with subwidget="true" arribute added 
			 to 'property' XML element.
		*/
		static void savePropertyValue(TQDomElement &parentNode, TQDomDocument &parent, const char *name,
			const TQVariant &value, TQWidget *w, WidgetLibrary *lib=0);

	protected:
		/*! Saves the TQVariant \a value as text to be included in an xml file, with \a parentNode.*/
		static void writeVariant(TQDomDocument &parent, TQDomElement &parentNode, TQVariant value);

		/*! Creates a toplevel widget from the TQDomElement \a element in the Form \a form,
		 with \a parent as parent widget.
		 It calls readPropertyValue() and loadWidget() to load child widgets.
		*/
		static void createToplevelWidget(Form *form, TQWidget *container, TQDomElement &element);

		/*! \return the name of the pixmap saved, to use to access it
		    This function save the TQPixmap \a pixmap into the DOM document \a domDoc.
		    The pixmap is converted to XPM and compressed for compatibility with TQt Designer.
		    Encoding code is taken from Designer.
		*/
		static TQString saveImage(TQDomDocument &domDoc, const TQPixmap &pixmap);

		/*! \return the loaded pixmap
		    This function loads the pixmap named \a name in the DOM document \a domDoc.
		    Decoding code is taken from QT Designer.
		*/
		static TQPixmap loadImage(TQDomDocument domDoc, const TQString& name);

		/*! Reads the child nodes of a "widget" element. */
		static void readChildNodes(ObjectTreeItem *tree, Container *container, 
			const TQDomElement &el, TQWidget *w);

		/*! Adds an include file name to be saved in the "includehints" part of .ui file,
		 which is needed by uic. */
		static void addIncludeFileName(const TQString &include, TQDomDocument &domDoc);

	private:
		// This dict stores buddies associations until the Form is completely loaded.
		static TQDict<TQLabel>  *m_buddies;

		/// Instead of having to pass these for every functions, we just store them in the class
		//static TQWidgdet  *m_currentWidget;
		static ObjectTreeItem   *m_currentItem;
		static Form *m_currentForm;
		static bool m_savePixmapsInline;
};

}

#endif