/****************************************************************************
 **
 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 **
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
 ** This file is part of a Qt Solutions component.
 **
 ** You may use this file under the terms of the BSD license as follows:
 **
 ** "Redistribution and use in source and binary forms, with or without
 ** modification, are permitted provided that the following conditions are
 ** met:
 **   * Redistributions of source code must retain the above copyright
 **     notice, this list of conditions and the following disclaimer.
 **   * Redistributions in binary form must reproduce the above copyright
 **     notice, this list of conditions and the following disclaimer in
 **     the documentation and/or other materials provided with the
 **     distribution.
 **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
 **     the names of its contributors may be used to endorse or promote
 **     products derived from this software without specific prior written
 **     permission.
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 **
 ****************************************************************************/

#pragma GCC system_header

#ifndef QTEDITORFACTORY_H
#define QTEDITORFACTORY_H

#include <QtWidgets/QSpinBox>
#include <QtWidgets/QScrollBar>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QAbstractItemView>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QDateTimeEdit>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QMenu>
#include <QtGui/QKeyEvent>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QToolButton>
#include <QtWidgets/QColorDialog>
#include <QtWidgets/QFontDialog>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QStyleOption>
#include <QtGui/QPainter>
#include <QtCore/QMap>

#include "qtpropertymanager.h"
#include "qtpropertybrowserutils_p.h"

#if QT_VERSION >= 0x040400
QT_BEGIN_NAMESPACE
#endif

// ---------- EditorFactoryPrivate :

// Base class for editor factory private classes. Manages mapping of
// properties to editors and vice versa.

template <class Editor>
class EditorFactoryPrivate
{
  public:

    typedef QList<Editor *> EditorList;
    typedef QMap<QtProperty *, EditorList> PropertyToEditorListMap;
    typedef QMap<Editor *, QtProperty *> EditorToPropertyMap;

    Editor *createEditor(QtProperty *property, QWidget *parent);
    void initializeEditor(QtProperty *property, Editor *e);
    void slotEditorDestroyed(QObject *object);

    PropertyToEditorListMap  m_createdEditors;
    EditorToPropertyMap m_editorToProperty;
};

  template <class Editor>
Editor *EditorFactoryPrivate<Editor>::createEditor(QtProperty *property,
    QWidget *parent)
{
  Editor *editor = new Editor(parent);
  initializeEditor(property, editor);
  return editor;
}

  template <class Editor>
void EditorFactoryPrivate<Editor>::initializeEditor(QtProperty *property,
    Editor *editor)
{
  typename PropertyToEditorListMap::iterator it =
    m_createdEditors.find(property);
  if (it == m_createdEditors.end())
    it = m_createdEditors.insert(property, EditorList());
  it.value().append(editor);
  m_editorToProperty.insert(editor, property);
}

  template <class Editor>
void EditorFactoryPrivate<Editor>::slotEditorDestroyed(QObject *object)
{
  const typename EditorToPropertyMap::iterator ecend =
    m_editorToProperty.end();
  for (typename EditorToPropertyMap::iterator itEditor =
      m_editorToProperty.begin(); itEditor !=  ecend; ++itEditor)
  {
    if (itEditor.key() == object)
    {
      Editor *editor = itEditor.key();
      QtProperty *property = itEditor.value();
      const typename PropertyToEditorListMap::iterator pit =
        m_createdEditors.find(property);
      if (pit != m_createdEditors.end())
      {
        pit.value().removeAll(editor);
        if (pit.value().empty())
          m_createdEditors.erase(pit);
      }
      m_editorToProperty.erase(itEditor);
      return;
    }
  }
}

class QtCharEdit
: public QWidget
{
  Q_OBJECT
  public:
    explicit QtCharEdit(QWidget *parent = 0);

    QChar value() const;
    bool eventFilter(QObject *o, QEvent *e);
    public Q_SLOTS:
      void setValue(const QChar &value);
  Q_SIGNALS:
    void valueChanged(const QChar &value);
  protected:
    void focusInEvent(QFocusEvent *e);
    void focusOutEvent(QFocusEvent *e);
    void keyPressEvent(QKeyEvent *e);
    void keyReleaseEvent(QKeyEvent *e);
    void paintEvent(QPaintEvent *e);
    bool event(QEvent *e);
    private slots:
      void slotClearChar();
  private:
    void handleKeyEvent(QKeyEvent *e);

    QChar m_value;
    QLineEdit *m_lineEdit;
};

class QtColorEditWidget
: public QWidget {
  Q_OBJECT

  public:
    explicit QtColorEditWidget(QWidget *parent);

    bool eventFilter(QObject *obj, QEvent *ev);

    public Q_SLOTS:
      void setValue(const QColor &value);

  Q_SIGNALS:
    void valueChanged(const QColor &value);

  protected:
    void paintEvent(QPaintEvent *e);

    private Q_SLOTS:
      void buttonClicked();

  private:
    QColor m_color;
    QLabel *m_pixmapLabel;
    QLabel *m_label;
    QToolButton *m_button;
};

class QtFontEditWidget
: public QWidget {
  Q_OBJECT

  public:
    explicit QtFontEditWidget(QWidget *parent);

    bool eventFilter(QObject *obj, QEvent *ev);

    public Q_SLOTS:
      void setValue(const QFont &value);

    Q_SIGNALS:
    void valueChanged(const QFont &value);

  protected:
    void paintEvent(QPaintEvent *e);

    private Q_SLOTS:
      void buttonClicked();

  private:
    QFont m_font;
    QLabel *m_pixmapLabel;
    QLabel *m_label;
    QToolButton *m_button;
};
class QtSpinBoxFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtSpinBoxFactory
: public QtAbstractEditorFactory<QtIntPropertyManager>
{
  Q_OBJECT
  public:
    explicit QtSpinBoxFactory(QObject *parent = 0);
    ~QtSpinBoxFactory();
  protected:
    void connectPropertyManager(QtIntPropertyManager *manager);
    QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtIntPropertyManager *manager);
  private:
    QtSpinBoxFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtSpinBoxFactory)
      Q_DISABLE_COPY(QtSpinBoxFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
      Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
      Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};

class QtSpinBoxFactoryPrivate
: public EditorFactoryPrivate<QSpinBox>
{
  QtSpinBoxFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtSpinBoxFactory)
  public:
    QtSpinBoxFactoryPrivate() : q_ptr(NULL) {}
    void slotPropertyChanged(QtProperty *property, int value);
    void slotRangeChanged(QtProperty *property, int min, int max);
    void slotSingleStepChanged(QtProperty *property, int step);
    void slotSetValue(int value);
};


class QtSliderFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtSliderFactory
: public QtAbstractEditorFactory<QtIntPropertyManager>
{
  Q_OBJECT
  public:
    explicit QtSliderFactory(QObject *parent = 0);
    ~QtSliderFactory();
  protected:
    void connectPropertyManager(QtIntPropertyManager *manager);
    QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtIntPropertyManager *manager);
  private:
    QtSliderFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtSliderFactory)
      Q_DISABLE_COPY(QtSliderFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
      Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
      Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};
class QtSliderFactoryPrivate
: public EditorFactoryPrivate<QSlider>
{
  QtSliderFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtSliderFactory)
  public:
    QtSliderFactoryPrivate() : q_ptr(NULL) {}
    void slotPropertyChanged(QtProperty *property, int value);
    void slotRangeChanged(QtProperty *property, int min, int max);
    void slotSingleStepChanged(QtProperty *property, int step);
    void slotSetValue(int value);
};


class QtScrollBarFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtScrollBarFactory
: public QtAbstractEditorFactory<QtIntPropertyManager>
{
  Q_OBJECT
  public:
    explicit QtScrollBarFactory(QObject *parent = 0);
    ~QtScrollBarFactory();
  protected:
    void connectPropertyManager(QtIntPropertyManager *manager);
    QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtIntPropertyManager *manager);
  private:
    QtScrollBarFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtScrollBarFactory)
      Q_DISABLE_COPY(QtScrollBarFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
      Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
      Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};
class QtScrollBarFactoryPrivate
: public  EditorFactoryPrivate<QScrollBar>
{
  QtScrollBarFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtScrollBarFactory)
  public:
    QtScrollBarFactoryPrivate() : q_ptr(NULL) {}
    void slotPropertyChanged(QtProperty *property, int value);
    void slotRangeChanged(QtProperty *property, int min, int max);
    void slotSingleStepChanged(QtProperty *property, int step);
    void slotSetValue(int value);
};


class QtCheckBoxFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtCheckBoxFactory
: public QtAbstractEditorFactory<QtBoolPropertyManager>
{
  Q_OBJECT
  public:
    explicit QtCheckBoxFactory(QObject *parent = 0);
    ~QtCheckBoxFactory();
  protected:
    void connectPropertyManager(QtBoolPropertyManager *manager);
    QWidget *createEditor(QtBoolPropertyManager *manager, QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtBoolPropertyManager *manager);
  private:
    QtCheckBoxFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtCheckBoxFactory)
      Q_DISABLE_COPY(QtCheckBoxFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};
class QtCheckBoxFactoryPrivate
: public EditorFactoryPrivate<QtBoolEdit>
{
  QtCheckBoxFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtCheckBoxFactory)
  public:
    QtCheckBoxFactoryPrivate() : q_ptr(NULL) {}
    void slotPropertyChanged(QtProperty *property, bool value);
    void slotSetValue(bool value);
};


class QtDoubleSpinBoxFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtDoubleSpinBoxFactory
: public QtAbstractEditorFactory<QtDoublePropertyManager>
{
  Q_OBJECT
  public:
    explicit QtDoubleSpinBoxFactory(QObject *parent = 0);
    ~QtDoubleSpinBoxFactory();
  protected:
    void connectPropertyManager(QtDoublePropertyManager *manager);
    QWidget *createEditor(QtDoublePropertyManager *manager,
        QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtDoublePropertyManager *manager);
  private:
    QtDoubleSpinBoxFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtDoubleSpinBoxFactory)
      Q_DISABLE_COPY(QtDoubleSpinBoxFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, double))
      Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double,
            double))
      Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double))
      Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(double))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};

class QtDoubleSpinBoxFactoryPrivate
: public EditorFactoryPrivate<QDoubleSpinBox>
{
  QtDoubleSpinBoxFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtDoubleSpinBoxFactory)
  public:
    QtDoubleSpinBoxFactoryPrivate() : q_ptr(NULL) {}
    void slotPropertyChanged(QtProperty *property, double value);
    void slotRangeChanged(QtProperty *property, double min, double max);
    void slotSingleStepChanged(QtProperty *property, double step);
    void slotDecimalsChanged(QtProperty *property, int prec);
    void slotSetValue(double value);
};


class QtLineEditFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtLineEditFactory
: public QtAbstractEditorFactory<QtStringPropertyManager>
{
  Q_OBJECT
  public:
    explicit QtLineEditFactory(QObject *parent = 0);
    ~QtLineEditFactory();
  protected:
    void connectPropertyManager(QtStringPropertyManager *manager);
    QWidget *createEditor(QtStringPropertyManager *manager,
        QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtStringPropertyManager *manager);
  private:
    QtLineEditFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtLineEditFactory)
      Q_DISABLE_COPY(QtLineEditFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *,
            const QString &))
      Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *,
            const QRegExp &))
      Q_PRIVATE_SLOT(d_func(), void slotEchoModeChanged(QtProperty *, int))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};
class QtLineEditFactoryPrivate
: public EditorFactoryPrivate<QLineEdit>
{
  QtLineEditFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtLineEditFactory)
  public:
    QtLineEditFactoryPrivate() : q_ptr(NULL) {}

    void slotPropertyChanged(QtProperty *property, const QString &value);
    void slotRegExpChanged(QtProperty *property, const QRegExp &regExp);
    void slotSetValue(const QString &value);
    void slotEchoModeChanged(QtProperty *, int);
};


class QtDateEditFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtDateEditFactory
: public QtAbstractEditorFactory<QtDatePropertyManager>
{
  Q_OBJECT
  public:
    explicit QtDateEditFactory(QObject *parent = 0);
    ~QtDateEditFactory();
  protected:
    void connectPropertyManager(QtDatePropertyManager *manager);
    QWidget *createEditor(QtDatePropertyManager *manager, QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtDatePropertyManager *manager);
  private:
    QtDateEditFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtDateEditFactory)
      Q_DISABLE_COPY(QtDateEditFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *,
            const QDate &))
      Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *,
            const QDate &, const QDate &))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDate &))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};
class QtDateEditFactoryPrivate
: public EditorFactoryPrivate<QDateEdit>
{
  QtDateEditFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtDateEditFactory)
  public:
    QtDateEditFactoryPrivate() : q_ptr(NULL) {}
    void slotPropertyChanged(QtProperty *property, const QDate &value);
    void slotRangeChanged(QtProperty *property, const QDate &min,
        const QDate &max);
    void slotSetValue(const QDate &value);
};


class QtTimeEditFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtTimeEditFactory
: public QtAbstractEditorFactory<QtTimePropertyManager>
{
  Q_OBJECT
  public:
    explicit QtTimeEditFactory(QObject *parent = 0);
    ~QtTimeEditFactory();
  protected:
    void connectPropertyManager(QtTimePropertyManager *manager);
    QWidget *createEditor(QtTimePropertyManager *manager, QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtTimePropertyManager *manager);
  private:
    QtTimeEditFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtTimeEditFactory)
      Q_DISABLE_COPY(QtTimeEditFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *,
            const QTime &))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QTime &))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};

class QtTimeEditFactoryPrivate
: public EditorFactoryPrivate<QTimeEdit>
{
  QtTimeEditFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtTimeEditFactory)
  public:
    QtTimeEditFactoryPrivate() : q_ptr(NULL) {}
    void slotPropertyChanged(QtProperty *property, const QTime &value);
    void slotSetValue(const QTime &value);
};


class QtDateTimeEditFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtDateTimeEditFactory
: public QtAbstractEditorFactory<QtDateTimePropertyManager>
{
  Q_OBJECT
  public:
    explicit QtDateTimeEditFactory(QObject *parent = 0);
    ~QtDateTimeEditFactory();
  protected:
    void connectPropertyManager(QtDateTimePropertyManager *manager);
    QWidget *createEditor(QtDateTimePropertyManager *manager,
        QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtDateTimePropertyManager *manager);
  private:
    QtDateTimeEditFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtDateTimeEditFactory)
      Q_DISABLE_COPY(QtDateTimeEditFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *,
            const QDateTime &))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDateTime &))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};

class QtDateTimeEditFactoryPrivate
: public EditorFactoryPrivate<QDateTimeEdit>
{
  QtDateTimeEditFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtDateTimeEditFactory)
  public:
    QtDateTimeEditFactoryPrivate() : q_ptr(NULL) {}

    void slotPropertyChanged(QtProperty *property, const QDateTime &value);
    void slotSetValue(const QDateTime &value);
};


class QtKeySequenceEditorFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtKeySequenceEditorFactory
: public QtAbstractEditorFactory<QtKeySequencePropertyManager>
{
  Q_OBJECT
  public:
    explicit QtKeySequenceEditorFactory(QObject *parent = 0);
    ~QtKeySequenceEditorFactory();
  protected:
    void connectPropertyManager(QtKeySequencePropertyManager *manager);
    QWidget *createEditor(QtKeySequencePropertyManager *manager,
        QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtKeySequencePropertyManager *manager);
  private:
    QtKeySequenceEditorFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtKeySequenceEditorFactory)
      Q_DISABLE_COPY(QtKeySequenceEditorFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *,
            const QKeySequence &))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QKeySequence &))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};


class QtKeySequenceEditorFactoryPrivate
: public EditorFactoryPrivate<QtKeySequenceEdit>
{
  QtKeySequenceEditorFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtKeySequenceEditorFactory)
  public:
    QtKeySequenceEditorFactoryPrivate() : q_ptr(NULL) {}
    void slotPropertyChanged(QtProperty *property, const QKeySequence &value);
    void slotSetValue(const QKeySequence &value);
};

class QtCharEditorFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtCharEditorFactory
: public QtAbstractEditorFactory<QtCharPropertyManager>
{
  Q_OBJECT
  public:
    explicit QtCharEditorFactory(QObject *parent = 0);
    ~QtCharEditorFactory();
  protected:
    void connectPropertyManager(QtCharPropertyManager *manager);
    QWidget *createEditor(QtCharPropertyManager *manager, QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtCharPropertyManager *manager);
  private:
    QtCharEditorFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtCharEditorFactory)
      Q_DISABLE_COPY(QtCharEditorFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *,
            const QChar &))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QChar &))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};

class QtCharEditorFactoryPrivate
: public EditorFactoryPrivate<QtCharEdit>
{
  QtCharEditorFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtCharEditorFactory)
  public:
    QtCharEditorFactoryPrivate() : q_ptr(NULL) {}

    void slotPropertyChanged(QtProperty *property, const QChar &value);
    void slotSetValue(const QChar &value);
};

class QtEnumEditorFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtEnumEditorFactory
: public QtAbstractEditorFactory<QtEnumPropertyManager>
{
  Q_OBJECT
  public:
    explicit QtEnumEditorFactory(QObject *parent = 0);
    ~QtEnumEditorFactory();
  protected:
    void connectPropertyManager(QtEnumPropertyManager *manager);
    QWidget *createEditor(QtEnumPropertyManager *manager, QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtEnumPropertyManager *manager);
  private:
    QtEnumEditorFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtEnumEditorFactory)
      Q_DISABLE_COPY(QtEnumEditorFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
      Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *,
            const QStringList &))
      Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *,
            const QMap<int, QIcon> &))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};

class QtEnumEditorFactoryPrivate
: public EditorFactoryPrivate<QComboBox>
{
  QtEnumEditorFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtEnumEditorFactory)
  public:
    QtEnumEditorFactoryPrivate() : q_ptr(NULL) {}

    void slotPropertyChanged(QtProperty *property, int value);
    void slotEnumNamesChanged(QtProperty *property, const QStringList &);
    void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &);
    void slotSetValue(int value);
};


class QtCursorEditorFactoryPrivate;

class QT_QTPROPERTYBROWSER_EXPORT QtCursorEditorFactory
: public QtAbstractEditorFactory<QtCursorPropertyManager>
{
  Q_OBJECT
  public:
    explicit QtCursorEditorFactory(QObject *parent = 0);
    ~QtCursorEditorFactory();
  protected:
    void connectPropertyManager(QtCursorPropertyManager *manager);
    QWidget *createEditor(QtCursorPropertyManager *manager,
        QtProperty *property, QWidget *parent);
    void disconnectPropertyManager(QtCursorPropertyManager *manager);
  private:
    QtCursorEditorFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtCursorEditorFactory)
      Q_DISABLE_COPY(QtCursorEditorFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *,
            const QCursor &))
      Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
};

class QtCursorEditorFactoryPrivate
{
  QtCursorEditorFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtCursorEditorFactory)
  public:
    QtCursorEditorFactoryPrivate();

    void slotPropertyChanged(QtProperty *property, const QCursor &cursor);
    void slotEnumChanged(QtProperty *property, int value);
    void slotEditorDestroyed(QObject *object);

    QtEnumEditorFactory *m_enumEditorFactory;
    QtEnumPropertyManager *m_enumPropertyManager;

    QMap<QtProperty *, QtProperty *> m_propertyToEnum;
    QMap<QtProperty *, QtProperty *> m_enumToProperty;
    QMap<QtProperty *, QList<QWidget *> > m_enumToEditors;
    QMap<QWidget *, QtProperty *> m_editorToEnum;
    bool m_updatingEnum;
};
class QtColorEditorFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtColorEditorFactory
: public QtAbstractEditorFactory<QtColorPropertyManager>
{
  Q_OBJECT
  public:
    explicit QtColorEditorFactory(QObject *parent = 0);
    ~QtColorEditorFactory();
  protected:
    void connectPropertyManager(QtColorPropertyManager *manager);
    QWidget *createEditor(QtColorPropertyManager *manager, QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtColorPropertyManager *manager);
  private:
    QtColorEditorFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtColorEditorFactory)
      Q_DISABLE_COPY(QtColorEditorFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *,
            const QColor &))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QColor &))
};


class QtColorEditorFactoryPrivate
: public EditorFactoryPrivate<QtColorEditWidget>
{
  QtColorEditorFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtColorEditorFactory)
  public:
    QtColorEditorFactoryPrivate() : q_ptr(NULL) {}
    void slotPropertyChanged(QtProperty *property, const QColor &value);
    void slotSetValue(const QColor &value);
};

class QtFontEditorFactoryPrivate;


class QT_QTPROPERTYBROWSER_EXPORT QtFontEditorFactory
: public QtAbstractEditorFactory<QtFontPropertyManager>
{
  Q_OBJECT
  public:
    explicit QtFontEditorFactory(QObject *parent = 0);
    ~QtFontEditorFactory();
  protected:
    void connectPropertyManager(QtFontPropertyManager *manager);
    QWidget *createEditor(QtFontPropertyManager *manager, QtProperty *property,
        QWidget *parent);
    void disconnectPropertyManager(QtFontPropertyManager *manager);
  private:
    QtFontEditorFactoryPrivate *d_ptr;
    Q_DECLARE_PRIVATE(QtFontEditorFactory)
      Q_DISABLE_COPY(QtFontEditorFactory)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *,
            const QFont &))
      Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
      Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &))
};

class QtFontEditorFactoryPrivate
: public EditorFactoryPrivate<QtFontEditWidget>
{
  QtFontEditorFactory *q_ptr;
  Q_DECLARE_PUBLIC(QtFontEditorFactory)
  public:
    QtFontEditorFactoryPrivate() : q_ptr(NULL) {}

    void slotPropertyChanged(QtProperty *property, const QFont &value);
    void slotSetValue(const QFont &value);
};
#if QT_VERSION >= 0x040400
QT_END_NAMESPACE
#endif

#endif
