/****************************************************************************
 **
 ** 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 diagnostic ignored "-Wswitch-default"
#pragma GCC diagnostic ignored "-Wfloat-equal"
#pragma GCC diagnostic ignored "-Wshadow"



#include "qteditorfactory.h"

#if defined(Q_CC_MSVC)
#    pragma warning(disable: 4786)
/* MS VS 6: truncating debug info after 255 characters */
#endif

#if QT_VERSION >= 0x040400
QT_BEGIN_NAMESPACE
#endif

// Set a hard coded left margin to account for the indentation
// of the tree view icon when switching to an editor

static inline void setupTreeViewEditorMargin(QLayout *lt)
{
  enum { DecorationMargin = 4 };
  if (QApplication::layoutDirection() == Qt::LeftToRight)
    lt->setContentsMargins(DecorationMargin, 0, 0, 0);
  else
    lt->setContentsMargins(0, 0, DecorationMargin, 0);
}

// ------------ QtSpinBoxFactory

void QtSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property,
    int value)
{
  if (!m_createdEditors.contains(property))
    return;
  QListIterator<QSpinBox *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QSpinBox *editor = itEditor.next();
    if (editor->value() != value)
    {
      editor->blockSignals(true);
      editor->setValue(value);
      editor->blockSignals(false);
    }
  }
}

void QtSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property, int min,
    int max)
{
  if (!m_createdEditors.contains(property))
    return;

  QtIntPropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  QListIterator<QSpinBox *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QSpinBox *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setRange(min, max);
    editor->setValue(manager->value(property));
    editor->blockSignals(false);
  }
}

void QtSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property,
    int step)
{
  if (!m_createdEditors.contains(property))
    return;
  QListIterator<QSpinBox *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QSpinBox *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setSingleStep(step);
    editor->blockSignals(false);
  }
}

void QtSpinBoxFactoryPrivate::slotSetValue(int value)
{
  QObject *object = q_ptr->sender();
  const QMap<QSpinBox *,
        QtProperty *>::ConstIterator  ecend = m_editorToProperty.constEnd();
  for (QMap<QSpinBox *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor !=  ecend; ++itEditor)
  {
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtIntPropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
  }
}

/*!
  \class QtSpinBoxFactory

  \brief The QtSpinBoxFactory class provides QSpinBox widgets for
  properties created by QtIntPropertyManager objects.

  \sa QtAbstractEditorFactory, QtIntPropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtSpinBoxFactory::QtSpinBoxFactory(QObject *parent)
: QtAbstractEditorFactory<QtIntPropertyManager>(parent)
{
  d_ptr = new QtSpinBoxFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtSpinBoxFactory::~QtSpinBoxFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtSpinBoxFactory::connectPropertyManager(QtIntPropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, int)),
      this, SLOT(slotPropertyChanged(QtProperty *, int)));
  connect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)),
      this, SLOT(slotRangeChanged(QtProperty *, int, int)));
  connect(manager, SIGNAL(singleStepChanged(QtProperty *, int)),
      this, SLOT(slotSingleStepChanged(QtProperty *, int)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtSpinBoxFactory::createEditor(QtIntPropertyManager *manager,
    QtProperty *property,
    QWidget *parent)
{
  QSpinBox *editor = d_ptr->createEditor(property, parent);
  editor->setSingleStep(manager->singleStep(property));
  editor->setRange(manager->minimum(property), manager->maximum(property));
  editor->setValue(manager->value(property));
  editor->setKeyboardTracking(false);

  connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtSpinBoxFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)),
      this, SLOT(slotPropertyChanged(QtProperty *, int)));
  disconnect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)),
      this, SLOT(slotRangeChanged(QtProperty *, int, int)));
  disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, int)),
      this, SLOT(slotSingleStepChanged(QtProperty *, int)));
}

// QtSliderFactory

void QtSliderFactoryPrivate::slotPropertyChanged(QtProperty *property,
    int value)
{
  if (!m_createdEditors.contains(property))
    return;
  QListIterator<QSlider *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QSlider *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setValue(value);
    editor->blockSignals(false);
  }
}

void QtSliderFactoryPrivate::slotRangeChanged(QtProperty *property, int min,
    int max)
{
  if (!m_createdEditors.contains(property))
    return;

  QtIntPropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  QListIterator<QSlider *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QSlider *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setRange(min, max);
    editor->setValue(manager->value(property));
    editor->blockSignals(false);
  }
}

void QtSliderFactoryPrivate::slotSingleStepChanged(QtProperty *property,
    int step)
{
  if (!m_createdEditors.contains(property))
    return;
  QListIterator<QSlider *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QSlider *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setSingleStep(step);
    editor->blockSignals(false);
  }
}

void QtSliderFactoryPrivate::slotSetValue(int value)
{
  QObject *object = q_ptr->sender();
  const QMap<QSlider *,
        QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
  for (QMap<QSlider *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor != ecend; ++itEditor )
  {
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtIntPropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
  }
}

/*!
  \class QtSliderFactory

  \brief The QtSliderFactory class provides QSlider widgets for
  properties created by QtIntPropertyManager objects.

  \sa QtAbstractEditorFactory, QtIntPropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtSliderFactory::QtSliderFactory(QObject *parent)
: QtAbstractEditorFactory<QtIntPropertyManager>(parent)
{
  d_ptr = new QtSliderFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtSliderFactory::~QtSliderFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtSliderFactory::connectPropertyManager(QtIntPropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, int)),
      this, SLOT(slotPropertyChanged(QtProperty *, int)));
  connect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)),
      this, SLOT(slotRangeChanged(QtProperty *, int, int)));
  connect(manager, SIGNAL(singleStepChanged(QtProperty *, int)),
      this, SLOT(slotSingleStepChanged(QtProperty *, int)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtSliderFactory::createEditor(QtIntPropertyManager *manager,
    QtProperty *property,
    QWidget *parent)
{
  QSlider *editor = new QSlider(Qt::Horizontal, parent);
  d_ptr->initializeEditor(property, editor);
  editor->setSingleStep(manager->singleStep(property));
  editor->setRange(manager->minimum(property), manager->maximum(property));
  editor->setValue(manager->value(property));

  connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtSliderFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)),
      this, SLOT(slotPropertyChanged(QtProperty *, int)));
  disconnect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)),
      this, SLOT(slotRangeChanged(QtProperty *, int, int)));
  disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, int)),
      this, SLOT(slotSingleStepChanged(QtProperty *, int)));
}

// QtSliderFactory

void QtScrollBarFactoryPrivate::slotPropertyChanged(QtProperty *property,
    int value)
{
  if (!m_createdEditors.contains(property))
    return;

  QListIterator<QScrollBar *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QScrollBar *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setValue(value);
    editor->blockSignals(false);
  }
}

void QtScrollBarFactoryPrivate::slotRangeChanged(QtProperty *property, int min,
    int max)
{
  if (!m_createdEditors.contains(property))
    return;

  QtIntPropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  QListIterator<QScrollBar *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QScrollBar *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setRange(min, max);
    editor->setValue(manager->value(property));
    editor->blockSignals(false);
  }
}

void QtScrollBarFactoryPrivate::slotSingleStepChanged(QtProperty *property,
    int step)
{
  if (!m_createdEditors.contains(property))
    return;
  QListIterator<QScrollBar *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QScrollBar *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setSingleStep(step);
    editor->blockSignals(false);
  }
}

void QtScrollBarFactoryPrivate::slotSetValue(int value)
{
  QObject *object = q_ptr->sender();
  const QMap<QScrollBar *,
        QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
  for (QMap<QScrollBar *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor != ecend; ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtIntPropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtScrollBarFactory

  \brief The QtScrollBarFactory class provides QScrollBar widgets for
  properties created by QtIntPropertyManager objects.

  \sa QtAbstractEditorFactory, QtIntPropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtScrollBarFactory::QtScrollBarFactory(QObject *parent)
: QtAbstractEditorFactory<QtIntPropertyManager>(parent)
{
  d_ptr = new QtScrollBarFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtScrollBarFactory::~QtScrollBarFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtScrollBarFactory::connectPropertyManager(QtIntPropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, int)),
      this, SLOT(slotPropertyChanged(QtProperty *, int)));
  connect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)),
      this, SLOT(slotRangeChanged(QtProperty *, int, int)));
  connect(manager, SIGNAL(singleStepChanged(QtProperty *, int)),
      this, SLOT(slotSingleStepChanged(QtProperty *, int)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtScrollBarFactory::createEditor(QtIntPropertyManager *manager,
    QtProperty *property,
    QWidget *parent)
{
  QScrollBar *editor = new QScrollBar(Qt::Horizontal, parent);
  d_ptr->initializeEditor(property, editor);
  editor->setSingleStep(manager->singleStep(property));
  editor->setRange(manager->minimum(property), manager->maximum(property));
  editor->setValue(manager->value(property));
  connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtScrollBarFactory::disconnectPropertyManager(
    QtIntPropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)),
      this, SLOT(slotPropertyChanged(QtProperty *, int)));
  disconnect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)),
      this, SLOT(slotRangeChanged(QtProperty *, int, int)));
  disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, int)),
      this, SLOT(slotSingleStepChanged(QtProperty *, int)));
}

// QtCheckBoxFactory

void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property,
    bool value)
{
  if (!m_createdEditors.contains(property))
    return;

  QListIterator<QtBoolEdit *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QtBoolEdit *editor = itEditor.next();
    editor->blockCheckBoxSignals(true);
    editor->setChecked(value);
    editor->blockCheckBoxSignals(false);
  }
}

void QtCheckBoxFactoryPrivate::slotSetValue(bool value)
{
  QObject *object = q_ptr->sender();

  const QMap<QtBoolEdit *,
        QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
  for (QMap<QtBoolEdit *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor != ecend;  ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtBoolPropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtCheckBoxFactory

  \brief The QtCheckBoxFactory class provides QCheckBox widgets for
  properties created by QtBoolPropertyManager objects.

  \sa QtAbstractEditorFactory, QtBoolPropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtCheckBoxFactory::QtCheckBoxFactory(QObject *parent)
: QtAbstractEditorFactory<QtBoolPropertyManager>(parent)
{
  d_ptr = new QtCheckBoxFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtCheckBoxFactory::~QtCheckBoxFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtCheckBoxFactory::connectPropertyManager(QtBoolPropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, bool)),
      this, SLOT(slotPropertyChanged(QtProperty *, bool)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager,
    QtProperty *property,
    QWidget *parent)
{
  QtBoolEdit *editor = d_ptr->createEditor(property, parent);
  editor->setChecked(manager->value(property));

  connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtCheckBoxFactory::disconnectPropertyManager(
    QtBoolPropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, bool)),
      this, SLOT(slotPropertyChanged(QtProperty *, bool)));
}

// QtDoubleSpinBoxFactory

void QtDoubleSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property,
    double value)
{
  QList<QDoubleSpinBox *> editors = m_createdEditors[property];
  QListIterator<QDoubleSpinBox *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QDoubleSpinBox *editor = itEditor.next();
    if (editor->value() != value)
    {
      editor->blockSignals(true);
      editor->setValue(value);
      editor->blockSignals(false);
    }
  }
}

void QtDoubleSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property,
    double min, double max)
{
  if (!m_createdEditors.contains(property))
    return;

  QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  QList<QDoubleSpinBox *> editors = m_createdEditors[property];
  QListIterator<QDoubleSpinBox *> itEditor(editors);
  while (itEditor.hasNext())
  {
    QDoubleSpinBox *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setRange(min, max);
    editor->setValue(manager->value(property));
    editor->blockSignals(false);
  }
}

void QtDoubleSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property,
    double step)
{
  if (!m_createdEditors.contains(property))
    return;

  QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  QList<QDoubleSpinBox *> editors = m_createdEditors[property];
  QListIterator<QDoubleSpinBox *> itEditor(editors);
  while (itEditor.hasNext())
  {
    QDoubleSpinBox *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setSingleStep(step);
    editor->blockSignals(false);
  }
}

void QtDoubleSpinBoxFactoryPrivate::slotDecimalsChanged(QtProperty *property,
    int prec)
{
  if (!m_createdEditors.contains(property))
    return;

  QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  QList<QDoubleSpinBox *> editors = m_createdEditors[property];
  QListIterator<QDoubleSpinBox *> itEditor(editors);
  while (itEditor.hasNext())
  {
    QDoubleSpinBox *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setDecimals(prec);
    editor->setValue(manager->value(property));
    editor->blockSignals(false);
  }
}

void QtDoubleSpinBoxFactoryPrivate::slotSetValue(double value)
{
  QObject *object = q_ptr->sender();
  const QMap<QDoubleSpinBox *,
        QtProperty *>::ConstIterator itcend = m_editorToProperty.constEnd();
  for (QMap<QDoubleSpinBox *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor != itcend; ++itEditor)
  {
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
  }
}

/*! \class QtDoubleSpinBoxFactory

  \brief The QtDoubleSpinBoxFactory class provides QDoubleSpinBox
  widgets for properties created by QtDoublePropertyManager objects.

  \sa QtAbstractEditorFactory, QtDoublePropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtDoubleSpinBoxFactory::QtDoubleSpinBoxFactory(QObject *parent)
: QtAbstractEditorFactory<QtDoublePropertyManager>(parent)
{
  d_ptr = new QtDoubleSpinBoxFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtDoubleSpinBoxFactory::~QtDoubleSpinBoxFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtDoubleSpinBoxFactory::connectPropertyManager(
    QtDoublePropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, double)),
      this, SLOT(slotPropertyChanged(QtProperty *, double)));
  connect(manager, SIGNAL(rangeChanged(QtProperty *, double, double)),
      this, SLOT(slotRangeChanged(QtProperty *, double, double)));
  connect(manager, SIGNAL(singleStepChanged(QtProperty *, double)),
      this, SLOT(slotSingleStepChanged(QtProperty *, double)));
  connect(manager, SIGNAL(decimalsChanged(QtProperty *, int)),
      this, SLOT(slotDecimalsChanged(QtProperty *, int)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtDoubleSpinBoxFactory::createEditor(QtDoublePropertyManager *manager,
    QtProperty *property, QWidget *parent)
{
  QDoubleSpinBox *editor = d_ptr->createEditor(property, parent);
  editor->setSingleStep(manager->singleStep(property));
  editor->setDecimals(manager->decimals(property));
  editor->setRange(manager->minimum(property), manager->maximum(property));
  editor->setValue(manager->value(property));
  editor->setKeyboardTracking(false);

  connect(editor, SIGNAL(valueChanged(double)), this,
      SLOT(slotSetValue(double)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtDoubleSpinBoxFactory::disconnectPropertyManager(
    QtDoublePropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, double)),
      this, SLOT(slotPropertyChanged(QtProperty *, double)));
  disconnect(manager, SIGNAL(rangeChanged(QtProperty *, double, double)),
      this, SLOT(slotRangeChanged(QtProperty *, double, double)));
  disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, double)),
      this, SLOT(slotSingleStepChanged(QtProperty *, double)));
  disconnect(manager, SIGNAL(decimalsChanged(QtProperty *, int)),
      this, SLOT(slotDecimalsChanged(QtProperty *, int)));
}

// QtLineEditFactory

void QtLineEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
    const QString &value)
{
  if (!m_createdEditors.contains(property))
    return;

  QListIterator<QLineEdit *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QLineEdit *editor = itEditor.next();
    if (editor->text() != value)
      editor->setText(value);
  }
}

void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property,
    const QRegExp &regExp)
{
  if (!m_createdEditors.contains(property))
    return;

  QtStringPropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  QListIterator<QLineEdit *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QLineEdit *editor = itEditor.next();
    editor->blockSignals(true);
    const QValidator *oldValidator = editor->validator();
    QValidator *newValidator = 0;
    if (regExp.isValid())
    {
      newValidator = new QRegExpValidator(regExp, editor);
    }
    editor->setValidator(newValidator);
    if (oldValidator)
      delete oldValidator;
    editor->blockSignals(false);
  }
}

void QtLineEditFactoryPrivate::slotEchoModeChanged(QtProperty *property,
    int echoMode)
{
  if (!m_createdEditors.contains(property))
    return;

  QtStringPropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  QListIterator<QLineEdit *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QLineEdit *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setEchoMode((EchoMode)echoMode);
    editor->blockSignals(false);
  }
}

void QtLineEditFactoryPrivate::slotSetValue(const QString &value)
{
  QObject *object = q_ptr->sender();
  const QMap<QLineEdit *,
        QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
  for (QMap<QLineEdit *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor != ecend; ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtStringPropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtLineEditFactory

  \brief The QtLineEditFactory class provides QLineEdit widgets for
  properties created by QtStringPropertyManager objects.

  \sa QtAbstractEditorFactory, QtStringPropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtLineEditFactory::QtLineEditFactory(QObject *parent)
: QtAbstractEditorFactory<QtStringPropertyManager>(parent)
{
  d_ptr = new QtLineEditFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtLineEditFactory::~QtLineEditFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtLineEditFactory::connectPropertyManager(QtStringPropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QString &)));
  connect(manager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)),
      this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &)));
  connect(manager, SIGNAL(echoModeChanged(QtProperty*, int)),
      this, SLOT(slotEchoModeChanged(QtProperty *, int)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtLineEditFactory::createEditor(QtStringPropertyManager *manager,
    QtProperty *property, QWidget *parent)
{
  QLineEdit *editor = d_ptr->createEditor(property, parent);
  editor->setEchoMode((EchoMode)manager->echoMode(property));
  QRegExp regExp = manager->regExp(property);
  if (regExp.isValid())
  {
    QValidator *validator = new QRegExpValidator(regExp, editor);
    editor->setValidator(validator);
  }
  editor->setText(manager->value(property));

  connect(editor, SIGNAL(textEdited(const QString &)),
      this, SLOT(slotSetValue(const QString &)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtLineEditFactory::disconnectPropertyManager(
    QtStringPropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QString &)));
  disconnect(manager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)),
      this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &)));
  disconnect(manager, SIGNAL(echoModeChanged(QtProperty*, int)),
      this, SLOT(slotEchoModeChanged(QtProperty *, int)));
}

// QtDateEditFactory

void QtDateEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
    const QDate &value)
{
  if (!m_createdEditors.contains(property))
    return;
  QListIterator<QDateEdit *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QDateEdit *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setDate(value);
    editor->blockSignals(false);
  }
}

void QtDateEditFactoryPrivate::slotRangeChanged(QtProperty *property,
    const QDate &min, const QDate &max)
{
  if (!m_createdEditors.contains(property))
    return;

  QtDatePropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  QListIterator<QDateEdit *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QDateEdit *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setDateRange(min, max);
    editor->setDate(manager->value(property));
    editor->blockSignals(false);
  }
}

void QtDateEditFactoryPrivate::slotSetValue(const QDate &value)
{
  QObject *object = q_ptr->sender();
  const QMap<QDateEdit *,
        QtProperty *>::ConstIterator  ecend = m_editorToProperty.constEnd();
  for (QMap<QDateEdit *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor != ecend; ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtDatePropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtDateEditFactory

  \brief The QtDateEditFactory class provides QDateEdit widgets for
  properties created by QtDatePropertyManager objects.

  \sa QtAbstractEditorFactory, QtDatePropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtDateEditFactory::QtDateEditFactory(QObject *parent)
: QtAbstractEditorFactory<QtDatePropertyManager>(parent)
{
  d_ptr = new QtDateEditFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtDateEditFactory::~QtDateEditFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtDateEditFactory::connectPropertyManager(QtDatePropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, const QDate &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QDate &)));
  connect(manager, SIGNAL(rangeChanged(QtProperty *, const QDate &,
          const QDate &)),
      this, SLOT(slotRangeChanged(QtProperty *, const QDate &, const QDate &)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtDateEditFactory::createEditor(QtDatePropertyManager *manager,
    QtProperty *property,
    QWidget *parent)
{
  QDateEdit *editor = d_ptr->createEditor(property, parent);
  editor->setCalendarPopup(true);
  editor->setDateRange(manager->minimum(property), manager->maximum(property));
  editor->setDate(manager->value(property));

  connect(editor, SIGNAL(dateChanged(const QDate &)),
      this, SLOT(slotSetValue(const QDate &)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtDateEditFactory::disconnectPropertyManager(
    QtDatePropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QDate &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QDate &)));
  disconnect(manager, SIGNAL(rangeChanged(QtProperty *, const QDate &,
          const QDate &)),
      this, SLOT(slotRangeChanged(QtProperty *, const QDate &, const QDate &)));
}

// QtTimeEditFactory

void QtTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
    const QTime &value)
{
  if (!m_createdEditors.contains(property))
    return;
  QListIterator<QTimeEdit *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QTimeEdit *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setTime(value);
    editor->blockSignals(false);
  }
}

void QtTimeEditFactoryPrivate::slotSetValue(const QTime &value)
{
  QObject *object = q_ptr->sender();
  const  QMap<QTimeEdit *,
         QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
  for (QMap<QTimeEdit *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor != ecend; ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtTimePropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtTimeEditFactory

  \brief The QtTimeEditFactory class provides QTimeEdit widgets for
  properties created by QtTimePropertyManager objects.

  \sa QtAbstractEditorFactory, QtTimePropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtTimeEditFactory::QtTimeEditFactory(QObject *parent)
: QtAbstractEditorFactory<QtTimePropertyManager>(parent)
{
  d_ptr = new QtTimeEditFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtTimeEditFactory::~QtTimeEditFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtTimeEditFactory::connectPropertyManager(QtTimePropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, const QTime &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QTime &)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtTimeEditFactory::createEditor(QtTimePropertyManager *manager,
    QtProperty *property,
    QWidget *parent)
{
  QTimeEdit *editor = d_ptr->createEditor(property, parent);
  editor->setTime(manager->value(property));

  connect(editor, SIGNAL(timeChanged(const QTime &)),
      this, SLOT(slotSetValue(const QTime &)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtTimeEditFactory::disconnectPropertyManager(
    QtTimePropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QTime &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QTime &)));
}

// QtDateTimeEditFactory

void QtDateTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
    const QDateTime &value)
{
  if (!m_createdEditors.contains(property))
    return;

  QListIterator<QDateTimeEdit *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QDateTimeEdit *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setDateTime(value);
    editor->blockSignals(false);
  }
}

void QtDateTimeEditFactoryPrivate::slotSetValue(const QDateTime &value)
{
  QObject *object = q_ptr->sender();
  const  QMap<QDateTimeEdit *,
         QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
  for (QMap<QDateTimeEdit *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor != ecend;  ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtDateTimePropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtDateTimeEditFactory

  \brief The QtDateTimeEditFactory class provides QDateTimeEdit
  widgets for properties created by QtDateTimePropertyManager objects.

  \sa QtAbstractEditorFactory, QtDateTimePropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtDateTimeEditFactory::QtDateTimeEditFactory(QObject *parent)
: QtAbstractEditorFactory<QtDateTimePropertyManager>(parent)
{
  d_ptr = new QtDateTimeEditFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtDateTimeEditFactory::~QtDateTimeEditFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtDateTimeEditFactory::connectPropertyManager(
    QtDateTimePropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, const QDateTime &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QDateTime &)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtDateTimeEditFactory::createEditor(QtDateTimePropertyManager *manager,
    QtProperty *property, QWidget *parent)
{
  QDateTimeEdit *editor =  d_ptr->createEditor(property, parent);
  editor->setDateTime(manager->value(property));

  connect(editor, SIGNAL(dateTimeChanged(const QDateTime &)),
      this, SLOT(slotSetValue(const QDateTime &)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtDateTimeEditFactory::disconnectPropertyManager(
    QtDateTimePropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QDateTime &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QDateTime &)));
}

// QtKeySequenceEditorFactory

void QtKeySequenceEditorFactoryPrivate::slotPropertyChanged(
    QtProperty *property,
    const QKeySequence &value)
{
  if (!m_createdEditors.contains(property))
    return;

  QListIterator<QtKeySequenceEdit *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QtKeySequenceEdit *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setKeySequence(value);
    editor->blockSignals(false);
  }
}

void QtKeySequenceEditorFactoryPrivate::slotSetValue(const QKeySequence &value)
{
  QObject *object = q_ptr->sender();
  const  QMap<QtKeySequenceEdit *,
         QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
  for (QMap<QtKeySequenceEdit *,
      QtProperty *>::ConstIterator itEditor =  m_editorToProperty.constBegin();
      itEditor != ecend; ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtKeySequencePropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtKeySequenceEditorFactory

  \brief The QtKeySequenceEditorFactory class provides editor
  widgets for properties created by QtKeySequencePropertyManager objects.

  \sa QtAbstractEditorFactory
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtKeySequenceEditorFactory::QtKeySequenceEditorFactory(QObject *parent)
: QtAbstractEditorFactory<QtKeySequencePropertyManager>(parent)
{
  d_ptr = new QtKeySequenceEditorFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtKeySequenceEditorFactory::~QtKeySequenceEditorFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtKeySequenceEditorFactory::connectPropertyManager(
    QtKeySequencePropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, const QKeySequence &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QKeySequence &)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtKeySequenceEditorFactory::createEditor(
    QtKeySequencePropertyManager *manager,
    QtProperty *property, QWidget *parent)
{
  QtKeySequenceEdit *editor = d_ptr->createEditor(property, parent);
  editor->setKeySequence(manager->value(property));

  connect(editor, SIGNAL(keySequenceChanged(const QKeySequence &)),
      this, SLOT(slotSetValue(const QKeySequence &)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtKeySequenceEditorFactory::disconnectPropertyManager(
    QtKeySequencePropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QKeySequence &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QKeySequence &)));
}

// QtCharEdit



  QtCharEdit::QtCharEdit(QWidget *parent)
: QWidget(parent),  m_lineEdit(new QLineEdit(this))
{
  QHBoxLayout *layout = new QHBoxLayout(this);
  layout->addWidget(m_lineEdit);
  layout->setMargin(0);
  m_lineEdit->installEventFilter(this);
  m_lineEdit->setReadOnly(true);
  m_lineEdit->setFocusProxy(this);
  setFocusPolicy(m_lineEdit->focusPolicy());
  setAttribute(Qt::WA_InputMethodEnabled);
}

bool QtCharEdit::eventFilter(QObject *o, QEvent *e)
{
  if (o == m_lineEdit && e->type() == QEvent::ContextMenu)
  {
    QContextMenuEvent *c = static_cast<QContextMenuEvent *>(e);
    QMenu *menu = m_lineEdit->createStandardContextMenu();
    QList<QAction *> actions = menu->actions();
    QListIterator<QAction *> itAction(actions);
    while (itAction.hasNext())
    {
      QAction *action = itAction.next();
      action->setShortcut(QKeySequence());
      QString actionString = action->text();
      const int pos = actionString.lastIndexOf(QLatin1Char('\t'));
      if (pos > 0)
        actionString = actionString.remove(pos, actionString.length() - pos);
      action->setText(actionString);
    }
    QAction *actionBefore = 0;
    if (actions.count() > 0)
      actionBefore = actions[0];
    QAction *clearAction = new QAction(tr("Clear Char"), menu);
    menu->insertAction(actionBefore, clearAction);
    menu->insertSeparator(actionBefore);
    clearAction->setEnabled(!m_value.isNull());
    connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearChar()));
    menu->exec(c->globalPos());
    delete menu;
    e->accept();
    return true;
  }

  return QWidget::eventFilter(o, e);
}

void QtCharEdit::slotClearChar()
{
  if (m_value.isNull())
    return;
  setValue(QChar());
  emit valueChanged(m_value);
}

void QtCharEdit::handleKeyEvent(QKeyEvent *e)
{
  const int key = e->key();
  switch (key)
  {
    case Qt::Key_Control:
    case Qt::Key_Shift:
    case Qt::Key_Meta:
    case Qt::Key_Alt:
    case Qt::Key_Super_L:
    case Qt::Key_Return:
      return;
    default:
      break;
  }

  const QString text = e->text();
  if (text.count() != 1)
    return;

  const QChar c = text.at(0);
  if (!c.isPrint())
    return;

  if (m_value == c)
    return;

  m_value = c;
  const QString str = m_value.isNull() ? QString() : QString(m_value);
  m_lineEdit->setText(str);
  e->accept();
  emit valueChanged(m_value);
}

void QtCharEdit::setValue(const QChar &value)
{
  if (value == m_value)
    return;

  m_value = value;
  QString str = value.isNull() ? QString() : QString(value);
  m_lineEdit->setText(str);
}

QChar QtCharEdit::value() const
{
  return m_value;
}

void QtCharEdit::focusInEvent(QFocusEvent *e)
{
  m_lineEdit->event(e);
  m_lineEdit->selectAll();
  QWidget::focusInEvent(e);
}

void QtCharEdit::focusOutEvent(QFocusEvent *e)
{
  m_lineEdit->event(e);
  QWidget::focusOutEvent(e);
}

void QtCharEdit::keyPressEvent(QKeyEvent *e)
{
  handleKeyEvent(e);
  e->accept();
}

void QtCharEdit::keyReleaseEvent(QKeyEvent *e)
{
  m_lineEdit->event(e);
}

void QtCharEdit::paintEvent(QPaintEvent *)
{
  QStyleOption opt;
  opt.init(this);
  QPainter p(this);
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

bool QtCharEdit::event(QEvent *e)
{
  switch (e->type())
  {
    case QEvent::Shortcut:
    case QEvent::ShortcutOverride:
    case QEvent::KeyRelease:
      e->accept();
      return true;
    default:
      break;
  }
  return QWidget::event(e);
}

// QtCharEditorFactory

void QtCharEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
    const QChar &value)
{
  if (!m_createdEditors.contains(property))
    return;

  QListIterator<QtCharEdit *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QtCharEdit *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setValue(value);
    editor->blockSignals(false);
  }
}

void QtCharEditorFactoryPrivate::slotSetValue(const QChar &value)
{
  QObject *object = q_ptr->sender();
  const QMap<QtCharEdit *,
        QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
  for (QMap<QtCharEdit *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor != ecend;  ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtCharPropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtCharEditorFactory

  \brief The QtCharEditorFactory class provides editor
  widgets for properties created by QtCharPropertyManager objects.

  \sa QtAbstractEditorFactory
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtCharEditorFactory::QtCharEditorFactory(QObject *parent)
: QtAbstractEditorFactory<QtCharPropertyManager>(parent)
{
  d_ptr = new QtCharEditorFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtCharEditorFactory::~QtCharEditorFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtCharEditorFactory::connectPropertyManager(QtCharPropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, const QChar &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QChar &)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtCharEditorFactory::createEditor(QtCharPropertyManager *manager,
    QtProperty *property, QWidget *parent)
{
  QtCharEdit *editor = d_ptr->createEditor(property, parent);
  editor->setValue(manager->value(property));

  connect(editor, SIGNAL(valueChanged(const QChar &)),
      this, SLOT(slotSetValue(const QChar &)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtCharEditorFactory::disconnectPropertyManager(
    QtCharPropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QChar &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QChar &)));
}

// QtEnumEditorFactory

void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
    int value)
{
  if (!m_createdEditors.contains(property))
    return;

  QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QComboBox *editor = itEditor.next();
    editor->blockSignals(true);
    editor->setCurrentIndex(value);
    editor->blockSignals(false);
  }
}

void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty *property,
    const QStringList &enumNames)
{
  if (!m_createdEditors.contains(property))
    return;

  QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  QMap<int, QIcon> enumIcons = manager->enumIcons(property);

  QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QComboBox *editor = itEditor.next();
    editor->blockSignals(true);
    editor->clear();
    editor->addItems(enumNames);
    const int nameCount = enumNames.count();
    for (int i = 0; i < nameCount; i++)
      editor->setItemIcon(i, enumIcons.value(i));
    editor->setCurrentIndex(manager->value(property));
    editor->blockSignals(false);
  }
}

void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty *property,
    const QMap<int, QIcon> &enumIcons)
{
  if (!m_createdEditors.contains(property))
    return;

  QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
  if (!manager)
    return;

  const QStringList enumNames = manager->enumNames(property);
  QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
  while (itEditor.hasNext())
  {
    QComboBox *editor = itEditor.next();
    editor->blockSignals(true);
    const int nameCount = enumNames.count();
    for (int i = 0; i < nameCount; i++)
      editor->setItemIcon(i, enumIcons.value(i));
    editor->setCurrentIndex(manager->value(property));
    editor->blockSignals(false);
  }
}

void QtEnumEditorFactoryPrivate::slotSetValue(int value)
{
  QObject *object = q_ptr->sender();
  const  QMap<QComboBox *,
         QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
  for (QMap<QComboBox *,
      QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin();
      itEditor != ecend; ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtEnumEditorFactory

  \brief The QtEnumEditorFactory class provides QComboBox widgets for
  properties created by QtEnumPropertyManager objects.

  \sa QtAbstractEditorFactory, QtEnumPropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtEnumEditorFactory::QtEnumEditorFactory(QObject *parent)
: QtAbstractEditorFactory<QtEnumPropertyManager>(parent)
{
  d_ptr = new QtEnumEditorFactoryPrivate();
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtEnumEditorFactory::~QtEnumEditorFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, int)),
      this, SLOT(slotPropertyChanged(QtProperty *, int)));
  connect(manager, SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)),
      this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager,
    QtProperty *property,
    QWidget *parent)
{
  QComboBox *editor = d_ptr->createEditor(property, parent);
  editor->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
  editor->setMinimumContentsLength(1);
  editor->view()->setTextElideMode(Qt::ElideRight);
  QStringList enumNames = manager->enumNames(property);
  editor->addItems(enumNames);
  QMap<int, QIcon> enumIcons = manager->enumIcons(property);
  const int enumNamesCount = enumNames.count();
  for (int i = 0; i < enumNamesCount; i++)
    editor->setItemIcon(i, enumIcons.value(i));
  editor->setCurrentIndex(manager->value(property));

  connect(editor, SIGNAL(currentIndexChanged(int)), this,
      SLOT(slotSetValue(int)));
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtEnumEditorFactory::disconnectPropertyManager(
    QtEnumPropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)),
      this, SLOT(slotPropertyChanged(QtProperty *, int)));
  disconnect(manager, SIGNAL(enumNamesChanged(QtProperty *,
          const QStringList &)),
      this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &)));
}

// QtCursorEditorFactory

Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase)



  QtCursorEditorFactoryPrivate::QtCursorEditorFactoryPrivate()
: q_ptr(NULL), m_enumEditorFactory(NULL), m_enumPropertyManager(NULL),
  m_updatingEnum(false)
{
}

void QtCursorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
    const QCursor &cursor)
{
  // update enum property
  QtProperty *enumProp = m_propertyToEnum.value(property);
  if (!enumProp)
    return;

  m_updatingEnum = true;
  m_enumPropertyManager->setValue(enumProp,
      cursorDatabase()->cursorToValue(cursor));
  m_updatingEnum = false;
}

void QtCursorEditorFactoryPrivate::slotEnumChanged(QtProperty *property,
    int value)
{
  if (m_updatingEnum)
    return;
  // update cursor property
  QtProperty *prop = m_enumToProperty.value(property);
  if (!prop)
    return;
  QtCursorPropertyManager *cursorManager = q_ptr->propertyManager(prop);
  if (!cursorManager)
    return;
#ifndef QT_NO_CURSOR
  cursorManager->setValue(prop,
      QCursor(cursorDatabase()->valueToCursor(value)));
#endif
}

void QtCursorEditorFactoryPrivate::slotEditorDestroyed(QObject *object)
{
  // remove from m_editorToEnum map;
  // remove from m_enumToEditors map;
  // if m_enumToEditors doesn't contains more editors delete enum property;
  const  QMap<QWidget *,
         QtProperty *>::ConstIterator ecend = m_editorToEnum.constEnd();
  for (QMap<QWidget *,
      QtProperty *>::ConstIterator itEditor = m_editorToEnum.constBegin();
      itEditor != ecend; ++itEditor)
    if (itEditor.key() == object)
    {
      QWidget *editor = itEditor.key();
      QtProperty *enumProp = itEditor.value();
      m_editorToEnum.remove(editor);
      m_enumToEditors[enumProp].removeAll(editor);
      if (m_enumToEditors[enumProp].isEmpty())
      {
        m_enumToEditors.remove(enumProp);
        QtProperty *property = m_enumToProperty.value(enumProp);
        m_enumToProperty.remove(enumProp);
        m_propertyToEnum.remove(property);
        delete enumProp;
      }
      return;
    }
}

/*!
  \class QtCursorEditorFactory

  \brief The QtCursorEditorFactory class provides QComboBox widgets for
  properties created by QtCursorPropertyManager objects.

  \sa QtAbstractEditorFactory, QtCursorPropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
  QtCursorEditorFactory::QtCursorEditorFactory(QObject *parent)
: QtAbstractEditorFactory<QtCursorPropertyManager>(parent)
{
  d_ptr = new QtCursorEditorFactoryPrivate();
  d_ptr->q_ptr = this;

  d_ptr->m_enumEditorFactory = new QtEnumEditorFactory(this);
  d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
  connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)),
      this, SLOT(slotEnumChanged(QtProperty *, int)));
  d_ptr->m_enumEditorFactory->addPropertyManager(d_ptr->m_enumPropertyManager);
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtCursorEditorFactory::~QtCursorEditorFactory()
{
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtCursorEditorFactory::connectPropertyManager(
    QtCursorPropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty *, const QCursor &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QCursor &)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtCursorEditorFactory::createEditor(QtCursorPropertyManager *manager,
    QtProperty *property,
    QWidget *parent)
{
  QtProperty *enumProp = 0;
  if (d_ptr->m_propertyToEnum.contains(property))
  {
    enumProp = d_ptr->m_propertyToEnum[property];
  }
  else
  {
    enumProp =
      d_ptr->m_enumPropertyManager->addProperty(property->propertyName());
    d_ptr->m_enumPropertyManager->setEnumNames(enumProp,
        cursorDatabase()->cursorShapeNames());
    d_ptr->m_enumPropertyManager->setEnumIcons(enumProp,
        cursorDatabase()->cursorShapeIcons());
#ifndef QT_NO_CURSOR
    d_ptr->m_enumPropertyManager->setValue(enumProp,
        cursorDatabase()->cursorToValue(manager->value(property)));
#endif
    d_ptr->m_propertyToEnum[property] = enumProp;
    d_ptr->m_enumToProperty[enumProp] = property;
  }
  QtAbstractEditorFactoryBase *af = d_ptr->m_enumEditorFactory;
  QWidget *editor = af->createEditor(enumProp, parent);
  d_ptr->m_enumToEditors[enumProp].append(editor);
  d_ptr->m_editorToEnum[editor] = enumProp;
  connect(editor, SIGNAL(destroyed(QObject *)),
      this, SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtCursorEditorFactory::disconnectPropertyManager(
    QtCursorPropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QCursor &)),
      this, SLOT(slotPropertyChanged(QtProperty *, const QCursor &)));
}

// QtColorEditWidget


QtColorEditWidget::QtColorEditWidget(QWidget *parent)
  : QWidget(parent),
  m_pixmapLabel(new QLabel),
  m_label(new QLabel),
  m_button(new QToolButton)
{
  QHBoxLayout *lt = new QHBoxLayout(this);
  setupTreeViewEditorMargin(lt);
  lt->setSpacing(0);
  lt->addWidget(m_pixmapLabel);
  lt->addWidget(m_label);
  lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding,
        QSizePolicy::Ignored));

  m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
  m_button->setFixedWidth(20);
  setFocusProxy(m_button);
  setFocusPolicy(m_button->focusPolicy());
  m_button->setText(tr("..."));
  m_button->installEventFilter(this);
  connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
  lt->addWidget(m_button);
  m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(
          m_color)));
  m_label->setText(QtPropertyBrowserUtils::colorValueText(m_color));
}

void QtColorEditWidget::setValue(const QColor &c)
{
  if (m_color != c)
  {
    m_color = c;
    m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(
            c)));
    m_label->setText(QtPropertyBrowserUtils::colorValueText(c));
  }
}

void QtColorEditWidget::buttonClicked()
{
  bool ok = false;
  QRgb oldRgba = m_color.rgba();
  QRgb newRgba = QColorDialog::getRgba(oldRgba, &ok, this);
  if (ok && newRgba != oldRgba)
  {
    setValue(QColor::fromRgba(newRgba));
    emit valueChanged(m_color);
  }
}

bool QtColorEditWidget::eventFilter(QObject *obj, QEvent *ev)
{
  if (obj == m_button)
  {
    switch (ev->type())
    {
      case QEvent::KeyPress:

      case QEvent::KeyRelease:
        {
          switch (static_cast<const QKeyEvent*>(ev)->key())
          {
            case Qt::Key_Escape:
            case Qt::Key_Enter:
            case Qt::Key_Return:
              ev->ignore();
              return true;
            default:
              break;
          }
        }
        break;
      default:
        break;
    }
  }
  return QWidget::eventFilter(obj, ev);
}

void QtColorEditWidget::paintEvent(QPaintEvent *)
{
  QStyleOption opt;
  opt.init(this);
  QPainter p(this);
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

// QtColorEditorFactoryPrivate



void QtColorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
    const QColor &value)
{
  const PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
  if (it == m_createdEditors.end())
    return;
  QListIterator<QtColorEditWidget *> itEditor(it.value());

  while (itEditor.hasNext())
    itEditor.next()->setValue(value);
}

void QtColorEditorFactoryPrivate::slotSetValue(const QColor &value)
{
  QObject *object = q_ptr->sender();
  const EditorToPropertyMap::ConstIterator ecend =
    m_editorToProperty.constEnd();
  for (EditorToPropertyMap::ConstIterator itEditor =
      m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtColorPropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtColorEditorFactory

  \brief The QtColorEditorFactory class provides color editing  for
  properties created by QtColorPropertyManager objects.

  \sa QtAbstractEditorFactory, QtColorPropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
QtColorEditorFactory::QtColorEditorFactory(QObject *parent)
: QtAbstractEditorFactory<QtColorPropertyManager>(parent),
  d_ptr(new QtColorEditorFactoryPrivate())
{
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtColorEditorFactory::~QtColorEditorFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtColorEditorFactory::connectPropertyManager(
    QtColorPropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty*, QColor)),
      this, SLOT(slotPropertyChanged(QtProperty*, QColor)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtColorEditorFactory::createEditor(QtColorPropertyManager *manager,
    QtProperty *property, QWidget *parent)
{
  QtColorEditWidget *editor = d_ptr->createEditor(property, parent);
  editor->setValue(manager->value(property));
  connect(editor, SIGNAL(valueChanged(QColor)), this,
      SLOT(slotSetValue(QColor)));
  connect(editor, SIGNAL(destroyed(QObject *)), this,
      SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtColorEditorFactory::disconnectPropertyManager(
    QtColorPropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty*, QColor)), this,
      SLOT(slotPropertyChanged(QtProperty*, QColor)));
}

// QtFontEditWidget


QtFontEditWidget::QtFontEditWidget(QWidget *parent)
  : QWidget(parent),
  m_pixmapLabel(new QLabel),
  m_label(new QLabel),
  m_button(new QToolButton)
{
  QHBoxLayout *lt = new QHBoxLayout(this);
  setupTreeViewEditorMargin(lt);
  lt->setSpacing(0);
  lt->addWidget(m_pixmapLabel);
  lt->addWidget(m_label);
  lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding,
        QSizePolicy::Ignored));

  m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
  m_button->setFixedWidth(20);
  setFocusProxy(m_button);
  setFocusPolicy(m_button->focusPolicy());
  m_button->setText(tr("..."));
  m_button->installEventFilter(this);
  connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
  lt->addWidget(m_button);
  m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(m_font));
  m_label->setText(QtPropertyBrowserUtils::fontValueText(m_font));
}

void QtFontEditWidget::setValue(const QFont &f)
{
  if (m_font != f)
  {
    m_font = f;
    m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(f));
    m_label->setText(QtPropertyBrowserUtils::fontValueText(f));
  }
}

void QtFontEditWidget::buttonClicked()
{
  bool ok = false;
  QFont newFont = QFontDialog::getFont(&ok, m_font, this, tr("Select Font"));
  if (ok && newFont != m_font)
  {
    QFont f = m_font;
    // prevent mask for unchanged attributes,
    // don't change other attributes (like kerning, etc...)
    if (m_font.family() != newFont.family())
      f.setFamily(newFont.family());
    if (m_font.pointSize() != newFont.pointSize())
      f.setPointSize(newFont.pointSize());
    if (m_font.bold() != newFont.bold())
      f.setBold(newFont.bold());
    if (m_font.italic() != newFont.italic())
      f.setItalic(newFont.italic());
    if (m_font.underline() != newFont.underline())
      f.setUnderline(newFont.underline());
    if (m_font.strikeOut() != newFont.strikeOut())
      f.setStrikeOut(newFont.strikeOut());
    setValue(f);
    emit valueChanged(m_font);
  }
}

bool QtFontEditWidget::eventFilter(QObject *obj, QEvent *ev)
{
  if (obj == m_button)
  {
    switch (ev->type())
    {
      case QEvent::KeyPress:

      case QEvent::KeyRelease:
        {
          switch (static_cast<const QKeyEvent*>(ev)->key())
          {
            case Qt::Key_Escape:
            case Qt::Key_Enter:
            case Qt::Key_Return:
              ev->ignore();
              return true;
            default:
              break;
          }
        }
        break;
      default:
        break;
    }
  }
  return QWidget::eventFilter(obj, ev);
}

void QtFontEditWidget::paintEvent(QPaintEvent *)
{
  QStyleOption opt;
  opt.init(this);
  QPainter p(this);
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

// QtFontEditorFactoryPrivate



void QtFontEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
    const QFont &value)
{
  const PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
  if (it == m_createdEditors.end())
    return;
  QListIterator<QtFontEditWidget *> itEditor(it.value());

  while (itEditor.hasNext())
    itEditor.next()->setValue(value);
}

void QtFontEditorFactoryPrivate::slotSetValue(const QFont &value)
{
  QObject *object = q_ptr->sender();
  const EditorToPropertyMap::ConstIterator ecend =
    m_editorToProperty.constEnd();
  for (EditorToPropertyMap::ConstIterator itEditor =
      m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
    if (itEditor.key() == object)
    {
      QtProperty *property = itEditor.value();
      QtFontPropertyManager *manager = q_ptr->propertyManager(property);
      if (!manager)
        return;
      manager->setValue(property, value);
      return;
    }
}

/*!
  \class QtFontEditorFactory

  \brief The QtFontEditorFactory class provides font editing for
  properties created by QtFontPropertyManager objects.

  \sa QtAbstractEditorFactory, QtFontPropertyManager
  */

/*!
  Creates a factory with the given \a parent.
  */
QtFontEditorFactory::QtFontEditorFactory(QObject *parent)
: QtAbstractEditorFactory<QtFontPropertyManager>(parent),
  d_ptr(new QtFontEditorFactoryPrivate())
{
  d_ptr->q_ptr = this;
}

/*!
  Destroys this factory, and all the widgets it has created.
  */
QtFontEditorFactory::~QtFontEditorFactory()
{
  qDeleteAll(d_ptr->m_editorToProperty.keys());
  delete d_ptr;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtFontEditorFactory::connectPropertyManager(QtFontPropertyManager *manager)
{
  connect(manager, SIGNAL(valueChanged(QtProperty*, QFont)),
      this, SLOT(slotPropertyChanged(QtProperty*, QFont)));
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
QWidget *QtFontEditorFactory::createEditor(QtFontPropertyManager *manager,
    QtProperty *property, QWidget *parent)
{
  QtFontEditWidget *editor = d_ptr->createEditor(property, parent);
  editor->setValue(manager->value(property));
  connect(editor, SIGNAL(valueChanged(QFont)), this, SLOT(slotSetValue(QFont)));
  connect(editor, SIGNAL(destroyed(QObject *)), this,
      SLOT(slotEditorDestroyed(QObject *)));
  return editor;
}

/*!
  \internal

  Reimplemented from the QtAbstractEditorFactory class.
  */
void QtFontEditorFactory::disconnectPropertyManager(
    QtFontPropertyManager *manager)
{
  disconnect(manager, SIGNAL(valueChanged(QtProperty*, QFont)), this,
      SLOT(slotPropertyChanged(QtProperty*, QFont)));
}

#if QT_VERSION >= 0x040400
QT_END_NAMESPACE
#endif

// #include "moc_qteditorfactory.cxx"
// #include "qteditorfactory.moc"
