summaryrefslogtreecommitdiffstats
path: root/kexi/formeditor/widgetfactory.h
diff options
context:
space:
mode:
Diffstat (limited to 'kexi/formeditor/widgetfactory.h')
-rw-r--r--kexi/formeditor/widgetfactory.h518
1 files changed, 518 insertions, 0 deletions
diff --git a/kexi/formeditor/widgetfactory.h b/kexi/formeditor/widgetfactory.h
new file mode 100644
index 00000000..43736ebc
--- /dev/null
+++ b/kexi/formeditor/widgetfactory.h
@@ -0,0 +1,518 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at>
+ Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
+ Copyright (C) 2004-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.
+*/
+
+#ifndef KFORMDESIGNERWIDGETFACTORY_H
+#define KFORMDESIGNERWIDGETFACTORY_H
+
+
+#include <qobject.h>
+#include <qguardedptr.h>
+#include <qpixmap.h>
+#include <qpopupmenu.h>
+#include <qasciidict.h>
+
+#include <kexiutils/tristate.h>
+
+// class QPixmap;
+template<class type> class QValueVector;
+template<class type> class QPtrList;
+template<class type> class QDict;
+class QWidget;
+class QDomElement;
+class QDomDocument;
+class QVariant;
+class QListView;
+class KActionCollection;
+class KTextEdit;
+class KLineEdit;
+class KXMLGUIClient;
+
+namespace KoProperty {
+ class Set;
+}
+
+namespace KFormDesigner {
+
+class WidgetFactory;
+class WidgetLibrary;
+class Container;
+class ResizeHandleSet;
+class ObjectTreeItem;
+class WidgetPropertySet;
+class Form;
+
+/**
+ * This class holds properties of widget classes provided by a factory.
+ */
+class KFORMEDITOR_EXPORT WidgetInfo
+{
+ public:
+ typedef QPtrList<WidgetInfo> List;
+ typedef QAsciiDict<WidgetInfo> Dict;
+
+ WidgetInfo(WidgetFactory *f);
+
+ WidgetInfo(WidgetFactory *f, const char* parentFactoryName, const char* inheritedClassName = 0);
+
+ virtual ~WidgetInfo();
+
+ //! \return a pixmap associated with the widget
+ QString pixmap() const { return m_pixmap; }
+
+ //! \return the class name of a widget e.g. 'QLineEdit'
+ QCString className() const { return m_class; }
+
+ /*! \return the name used to name widget, that will appear eg in scripts (must not contain spaces
+ nor non-latin1 characters) */
+ QString namePrefix() const { return m_prefixName; }
+
+ //! \return the real name e.g. 'Line Edit', showed eg in ObjectTreeView
+ QString name() const { return m_name; }
+
+ QString description() const { return m_desc; }
+ QString includeFileName() const { return m_include; }
+ QValueList<QCString> alternateClassNames() const { return m_alternateNames; }
+ QString savingName() const { return m_saveName; }
+ WidgetFactory *factory() const { return m_factory; }
+
+ void setPixmap(const QString &p) { m_pixmap = p; }
+ void setClassName(const QCString &s) { m_class = s; }
+ void setName(const QString &n) { m_name = n; }
+ void setNamePrefix(const QString &n) { m_prefixName = n; }
+ void setDescription(const QString &desc) { m_desc = desc;}
+
+ /*! Sets the C++ include file corresponding to this class,
+ that uic will need to add when creating the file. You don't have to set this for Qt std widgets.*/
+ void setIncludeFileName(const QString &name) { m_include = name;}
+
+ /*! Sets alternate names for this class.
+ If this name is found when loading a .ui file, the className() will be used instead.
+ It allows to support both KDE and Qt versions of widget, without duplicating code.
+ As a rule, className() should always return a class name which is inherited from
+ alternate class. For example KListView class has alternate QListView class.
+
+ \a override parameter overrides class name of a widget,
+ even if it was implemented in other factory.
+ By default it's set to false, what means that no other class is overridden
+ by this widget class if there is already a class implementing it
+ (no matter in which factory).
+ By forced overriding existing class with other - custom, user
+ will be able to see more or less properties and experience different behaviour.
+ For example, in Kexi application, KLineEdit class contains additional
+ "datasource" property for binding to database sources.
+ */
+ void addAlternateClassName(const QCString& alternateName, bool override = false);
+
+ /*! \return true is a class \a alternateName is defined as alternate name with
+ 'override' flag set to true, using addAlternateClassName().
+ If this flag is set to false (the default) or there's no such alternate class
+ name defined. */
+ bool isOverriddenClassName(const QCString& alternateName) const;
+
+ /*! Sets the name that will be written in the .ui file when saving.
+ This name must be one of alternate names (or loading will be impossible).
+
+ On form data saving to XML .ui format, saveName is used instead,
+ so .ui format is not broken and still usable with other software as Qt Designer.
+ Custom properties are saved as well with 'stdset' attribute set to 0. */
+ void setSavingName(const QString &saveName) { m_saveName = saveName; }
+
+ /*! Sets autoSync flag for property \a propertyName.
+ This allows to override autoSync flag for certain widget's property, because
+ e.g. KoProperty::Editor can have autoSync flag set to false or true, but
+ not all properties have to comply with that.
+ \a flag equal to cancelled value means there is no overriding (the default). */
+ void setAutoSyncForProperty(const char *propertyName, tristate flag);
+
+ /*! \return autoSync override value (true or false) for \a propertyName.
+ If cancelled value is returned, there is no overriding (the default). */
+ tristate autoSyncForProperty(const char *propertyName) const;
+
+ QCString parentFactoryName() const { return m_parentFactoryName; }
+
+ WidgetInfo* inheritedClass() const { return m_inheritedClass; }
+
+ /*! Sets custom type \a type for property \a propertyName.
+ This allows to override default type, especially when custom property
+ and custom property editor item has to be used. */
+ void setCustomTypeForProperty(const char *propertyName, int type);
+
+ /*! \return custom type for property \a propertyName. If no specific custom type has been assigned,
+ KoProperty::Auto is returned.
+ @see setCustomTypeForProperty() */
+ int customTypeForProperty(const char *propertyName) const;
+
+ protected:
+ QCString m_parentFactoryName, m_inheritedClassName; //!< Used for inheriting widgets between factories
+ WidgetInfo* m_inheritedClass;
+
+ private:
+ QString m_pixmap;
+ QCString m_class;
+ QString m_name;
+ QString m_prefixName;
+ QString m_desc;
+ QString m_include;
+ QValueList<QCString> m_alternateNames;
+ QAsciiDict<char> *m_overriddenAlternateNames;
+ QString m_saveName;
+ QGuardedPtr<WidgetFactory> m_factory;
+ QAsciiDict<char> *m_propertiesWithDisabledAutoSync;
+ QMap<QCString,int> *m_customTypesForProperty;
+
+ friend class WidgetLibrary;
+};
+
+//! The base class for all widget Factories
+/*! This is the class you need to inherit to create a new Factory. There are few
+ virtuals you need to implement, and some other functions
+ to implement if you want more features.\n \n
+
+ <b>Widget Creation</b>\n
+ To be able to create widgets, you need to implement the create() function, an classes(),
+ which should return all the widgets supported by this factory.\n \n
+
+ <b>GUI Integration</b>\n
+ The following functions allow you to customize even more the look-n-feel of your widgets inside KFormDesigner.
+ You can use createMenuActions() to add custom items in widget's context menu. The previewWidget()
+ is called when the Form gets in Preview mode, and you have a last opportunity to remove all editing-related
+ stuff (see eg \ref Spring class).\n
+ You can also choose which properties to show in the Property Editor.
+ By default, most all properties are shown (see implementation for details),
+ but you can hide some reimplementing isPropertyVisibleInternal() (don't forget to call superclass' method)
+ To add new properties, just define new Q_PROPERTY in widget class definition.\n \n
+
+ <b>Inline editing</b>\n
+ KFormDesigner allow you to edit the widget's contents inside Form, without using a dialog.
+ You can of course customize the behaviour of your widgets, using startEditing(). There are some editing
+ modes already implemented in WidgetFactroy, but you can create your own if you want:
+ \li Editing using a line edit (createEditor()): a line edit is created on top of widget,
+ where the user inputs text. As the text changes, changeText() is called
+ (where you should set your widget's text and resize widget to fit the text if needed) and resizeEditor()
+ to update editor's position when widget is moved/resized.\n
+ \li Editing by disabling event filter: if you call disableFilter(), the event filter
+ on the object is temporarily disabled, so the widget behaves as usual. This
+ can be used for more complex widgets, such as spinbox, date/time edit, etc.
+ \li Other modes: there are 3 other modes, to edit a string list: editList()
+ (for combo box, listbox), to edit rich text: editRichText() (for labels, etc.)
+ and to edit a listview: editListView(). \n \n
+
+ <b>Widget saving/loading</b>\n
+ You can also control how your widget are saved/loaded. You can choose which properties to save
+ (see autoSaveProperties()), and save/load custom properties, ie
+ properties that are not Q_PROPERTY but you want to save in the UI file. This is used eg to
+ save combo box or listview contents (see saveSpecialProperty() and
+ readSpecialProperty()). \n \n
+
+ <b>Special internal properties</b>\n
+ Use void setInternalProperty(const QCString& classname, const QCString& property, const QString& value);
+ to set values of special internal properties.
+ Currently these properties are used for customizing popup menu items used for orientation selection.
+ Customization for class ClassName should look like:
+ <code> void setInternalProperty("ClassName", "orientationSelectionPopup", "myicon"); </code>
+ Available internal properties:
+ * "orientationSelectionPopup" - set it to "1" if you want a given class to offer orientation selection,
+ so orientation selection popup will be displayed when needed.
+ * "orientationSelectionPopup:horizontalIcon" - sets a name of icon for "Horizontal" item
+ for objects of class 'ClassName'. Set this property only for classes supporting orientations.
+ * "orientationSelectionPopup:verticalIcon" - the same for "Vertical" item.
+ Set this property only for classes supporting orientations.
+ * "orientationSelectionPopup:horizontalText" - sets a i18n'd text for "Horizontal" item
+ for objects of class 'ClassName', e.g. i18n("Insert Horizontal Line").
+ Set this property only for classes supporting orientations.
+ * "orientationSelectionPopup:verticalText" - the same for "Vertical" item,
+ e.g. i18n("Insert Vertical Line"). Set this property only for classes supporting orientations.
+ * "dontStartEditingOnInserting" - if not empty, WidgetFactory::startEditing() will not be executed upon
+ widget inseting by a user.
+ * "forceShowAdvancedProperty:{propertyname}" - set it to "1" for "{propertyname}" advanced property
+ if you want to force it to be visible even if WidgetLibrary::setAdvancedPropertiesVisible(false)
+ has been called. For example, setting "forceShowAdvancedProperty:pixmap" to "1"
+ unhides "pixmap" property for a given class.
+
+ See StdWidgetFactory::StdWidgetFactory() for properties like
+ "Line:orientationSelectionPopup:horizontalIcon".
+
+ \n\n
+ See the standard factories in formeditor/factories for an example of factories,
+ and how to deal with complex widgets (eg tabwidget).
+ */
+class KFORMEDITOR_EXPORT WidgetFactory : public QObject
+{
+ Q_OBJECT
+ public:
+ //! Options used in createWidget()
+ enum CreateWidgetOptions {
+ AnyOrientation = 1, //!< any orientation hint
+ HorizontalOrientation = 2, //!< horizontal orientation hint
+ VerticalOrientation = 4, //!< vertical orientation hint
+ DesignViewMode = 8, //!< create widget in design view mode, otherwise preview mode
+ DefaultOptions = AnyOrientation | DesignViewMode
+ };
+
+ WidgetFactory(QObject *parent=0, const char *name=0);
+ virtual ~WidgetFactory();
+
+ /*! Adds a new class described by \a w. */
+ void addClass(WidgetInfo *w);
+
+ /*! This method allows to force a class \a classname to hidden.
+ It is useful if you do not want a class to be available
+ (e.g. because it is not implemented well yet for our purposes).
+ All widget libraries are affected by this setting. */
+ void hideClass(const char *classname);
+
+ /**
+ * \return all classes which are provided by this factory
+ */
+ const WidgetInfo::Dict classes() const { return m_classesByName; }
+
+ /**
+ * Creates a widget (and if needed a KFormDesigner::Container)
+ * \return the created widget
+ * \param classname the classname of the widget, which should get created
+ * \param parent the parent for the created widget
+ * \param name the name of the created widget
+ * \param container the toplevel Container (if a container should get created)
+ * \param options options for the created widget: orientation and view mode (see CreateWidgetOptions)
+ */
+ virtual QWidget* createWidget(const QCString &classname, QWidget *parent, const char *name,
+ KFormDesigner::Container *container,
+ int options = DefaultOptions) = 0;
+
+ /*! Creates custom actions. Reimplement this if you need to add some
+ actions coming from the factory. */
+ virtual void createCustomActions(KActionCollection *col) { Q_UNUSED(col); };
+
+ /*! This function can be used to add custom items in widget \a w context
+ menu \a menu. */
+ virtual bool createMenuActions(const QCString &classname, QWidget *w, QPopupMenu *menu,
+ KFormDesigner::Container *container)=0;
+
+ /*! Creates (if necessary) an editor to edit the contents of the widget directly in the Form
+ (eg creates a line edit to change the text of a label). \a classname is
+ the class the widget belongs to, \a w is the widget to edit
+ and \a container is the parent container of this widget (to access Form etc.).
+ */
+ virtual bool startEditing(const QCString &classname, QWidget *w, Container *container)=0;
+
+ /*! This function is called just before the Form is previewed. It allows widgets
+ to make changes before switching (ie for a Spring, hiding the cross) */
+ virtual bool previewWidget(const QCString &classname, QWidget *widget, Container *container)=0;
+
+ virtual bool clearWidgetContent(const QCString &classname, QWidget *w);
+
+ /*! This function is called when FormIO finds a property, at save time,
+ that it cannot handle (ie not a normal property).
+ This way you can save special properties, for example the contents of a listbox.
+ \sa readSpecialProperty()
+ */
+ virtual bool saveSpecialProperty(const QCString &classname, const QString &name,
+ const QVariant &value, QWidget *w,
+ QDomElement &parentNode, QDomDocument &parent);
+
+ /*! This function is called when FormIO finds a property or an unknown
+ element in a .ui file. You can this way load a special property, for
+ example the contents of a listbox.
+ \sa saveSpecialProperty()
+ */
+ virtual bool readSpecialProperty(const QCString &classname, QDomElement &node,
+ QWidget *w, ObjectTreeItem *item);
+
+ /*! This function is used to know whether the \a property for the widget \a w
+ should be shown or not in the PropertyEditor. If \a multiple is true,
+ then multiple widgets of the same class are selected, and you should
+ only show properties shared by widgets (eg font, color). By default,
+ all properties are shown if multiple == true, and none if multiple == false. */
+ bool isPropertyVisible(const QCString &classname, QWidget *w,
+ const QCString &property, bool multiple, bool isTopLevel);
+
+ /*! You need to return here a list of the properties that should automatically be saved
+ for a widget belonging to \a classname, and your custom properties (eg "text"
+ for label or button, "contents" for combobox...). */
+ virtual QValueList<QCString> autoSaveProperties(const QCString &classname)=0;
+
+ /*! \return The i18n'ed name of the property whose name is \a name,
+ that will be displayed in PropertyEditor. */
+ inline QString propertyDescForName(const QCString &name) { return m_propDesc[name]; };
+
+ /*! \return The i18n'ed name of the property's value whose name is \a name. */
+ inline QString propertyDescForValue(const QCString &name) { return m_propValDesc[name]; };
+
+ /*! This method is called after WidgetPropertySet was filled with properties
+ of a widget \a w, of class defined by \a info.
+ Default implementation does nothing.
+ Implement this if you need to set options for properties within the set \a buf. */
+ virtual void setPropertyOptions( WidgetPropertySet& buf, const WidgetInfo& info, QWidget *w );
+
+ /*! \return internal property \a property for a class \a classname.
+ Internal properties are not stored within objects, but can be just provided
+ to describe classes' details. */
+ inline QString internalProperty(const QCString& classname, const QCString& property) const {
+ return m_internalProp[classname+":"+property];
+ }
+
+ protected:
+ /*! This function is called when we want to know whether the property should be visible.
+ Implement it in the factory; don't forget to call implementation in the superclass.
+ Default implementation hides "caption", "icon", "sizeIncrement" and "iconText" properties. */
+ virtual bool isPropertyVisibleInternal(const QCString &classname, QWidget *w,
+ const QCString &property, bool isTopLevel);
+
+ /*! Sometimes property sets should be reloaded when a given property value changed.
+ Implement it in the factory. Default implementation always returns false. */
+ virtual bool propertySetShouldBeReloadedAfterPropertyChange(const QCString& classname, QWidget *w,
+ const QCString& property);
+
+ /*! This function creates a KLineEdit to input some text and edit a widget's contents.
+ This can be used in startEditing(). \a text is the text to display by default
+ in the line edit, \a w is the edited widget, \a geometry is the geometry the new line
+ edit should have, and \a align is Qt::AlignmentFlags of the new line edit. */
+ void createEditor(const QCString &classname, const QString &text,
+ QWidget *w, Container *container, QRect geometry,
+ int align, bool useFrame=false, bool multiLine = false,
+ BackgroundMode background = Qt::NoBackground);
+
+ /*! This function provides a simple editing mode : it justs disable event filtering
+ for the widget, and it install it again when
+ the widget loose focus or Enter is pressed.
+ */
+ void disableFilter(QWidget *w, Container *container);
+
+ /*! This function creates a little dialog (a KEditListBox) to modify the contents
+ of a list (of strings). It can be used to modify the contents
+ of a combo box for instance. The modified list is copied
+ into \a list when the user presses "Ok".*/
+ bool editList(QWidget *w, QStringList &list);
+
+ /*! This function creates a little editor to modify rich text. It supports alignment,
+ subscript and superscript and all basic formatting properties.
+ If the user presses "Ok", the edited text is put in \a text.
+ If he presses "Cancel", nothing happens. */
+ bool editRichText(QWidget *w, QString &text);
+
+ /*! This function creates a dialog to modify the contents of a ListView. You can modify both
+ columns and list items. The listview is automatically updated if the user presses "Ok".*/
+ void editListView(QListView *listview);
+
+ /*! This function destroys the editor when it loses focus or Enter is pressed. */
+ virtual bool eventFilter(QObject *obj, QEvent *ev);
+
+ /*! This function is used to modify a property of a widget (eg after editing it).
+ Please use it instead of w->setProperty() to allow sync inside PropertyEditor.
+ */
+ void changeProperty(const char *name, const QVariant &value, Form *form);
+
+ /*! This function is called when the widget is resized,
+ and the \a editor size needs to be updated. */
+ virtual void resizeEditor(QWidget *editor, QWidget *widget, const QCString &classname);
+
+// /*! Adds the i18n'ed description of a property, which will be shown in PropertyEditor. */
+// void addPropertyDescription(Container *container, const char *prop, const QString &desc);
+
+// /*! Adds the i18n'ed description of a property value, which will be shown in PropertyEditor. */
+// void addValueDescription(Container *container, const char *value, const QString &desc);
+
+ /*! \return true if at least one class defined by this factory inherits
+ a class from other factory. Used in WidgetLibrary::loadFactories()
+ to load factories in proper order. */
+ bool inheritsFactories();
+
+ public slots:
+
+ /*! @internal. This slot is called when the editor has lost focus or the user pressed Enter.
+ It destroys the editor or installs again the event filter on the widget. */
+ void resetEditor();
+
+ protected slots:
+ /*!
+ Default implementation changes "text" property.
+ You have to reimplement this function for editing inside the Form to work if your widget's
+ property you want to change isn't named "text".
+ This slot is called when the line edit text changes, and you have to make
+ it really change the good property of the widget using changeProperty() (text, or title, etc.).
+ */
+ virtual bool changeText(const QString &newText);
+
+ void changeTextInternal(const QString& text);
+
+ void slotTextChanged();
+
+ /*! This slot is called when the editor is destroyed.*/
+ void editorDeleted();
+ void widgetDestroyed();
+
+ protected:
+ QString editorText() const;
+ void setEditorText(const QString& text);
+ void setEditor(QWidget *widget, QWidget *editor);
+ QWidget *editor(QWidget *widget) const;
+ void setWidget(QWidget *widget, Container *container);
+ QWidget *widget() const;
+
+ /*! Assigns \a value for internal property \a property for a class \a classname.
+ Internal properties are not stored within objects, but can be provided
+ to describe classes' details. */
+ void setInternalProperty(const QCString& classname, const QCString& property, const QString& value);
+
+ WidgetLibrary *m_library;
+ QCString m_editedWidgetClass;
+//#ifdef KEXI_KTEXTEDIT
+// QGuardedPtr<KTextEdit> m_editor;
+//#else
+// QGuardedPtr<KLineEdit> m_editor;
+//#endif
+ QString m_firstText;
+ QGuardedPtr<ResizeHandleSet> m_handles;
+ QGuardedPtr<Container> m_container;
+// WidgetInfo::List m_classes;
+ WidgetInfo::Dict m_classesByName;
+ QAsciiDict<char>* m_hiddenClasses;
+
+ //! i18n stuff
+ QMap<QCString, QString> m_propDesc;
+ QMap<QCString, QString> m_propValDesc;
+ //! internal properties
+ QMap<QCString, QString> m_internalProp;
+
+ /*! flag useful to decide whether to hide some properties.
+ It's value is inherited from WidgetLibrary. */
+ bool m_showAdvancedProperties;
+
+ /*! Contains name of an XMLGUI file providing toolbar buttons
+ (and menu items in the future?) for the factory.
+ Can be empty, e.g. for the main factory which has XMLGUI defined in the shell window itself
+ (e.g. kexiformpartinstui.rc for Kexi Forms). This name is set in WidgetLibrary::loadFactories() */
+ QString m_xmlGUIFileName;
+
+ KXMLGUIClient *m_guiClient;
+
+ QGuardedPtr<QWidget> m_widget;
+ QGuardedPtr<QWidget> m_editor;
+
+ friend class WidgetLibrary;
+};
+
+//! macro to declare KFormDesigner-compatible widget factory as a KDE Component factory
+#define KFORMDESIGNER_WIDGET_FACTORY(factoryClassName, libraryName) \
+ K_EXPORT_COMPONENT_FACTORY(kformdesigner_ ## libraryName, KGenericFactory<factoryClassName>("kformdesigner_" # libraryName))
+
+}
+#endif