/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qplatformdefs.h>
#include "qitemeditorfactory.h"
#include "qitemeditorfactory_p.h"

#if QT_CONFIG(combobox)
#include <qcombobox.h>
#endif
#if QT_CONFIG(datetimeedit)
#include <qdatetimeedit.h>
#endif
#if QT_CONFIG(label)
#include <qlabel.h>
#endif
#if QT_CONFIG(lineedit)
#include <qlineedit.h>
#endif
#if QT_CONFIG(spinbox)
#include <qspinbox.h>
#endif
#include <qstyle.h>
#include <qstyleoption.h>
#include <limits.h>
#include <float.h>
#include <qapplication.h>
#include <qdebug.h>

#include <vector>
#include <algorithm>
QT_BEGIN_NAMESPACE


#if QT_CONFIG(combobox)

class QBooleanComboBox : public QComboBox
{
    Q_OBJECT
    Q_PROPERTY(bool value READ value WRITE setValue USER true)

public:
    QBooleanComboBox(QWidget *parent);
    void setValue(bool);
    bool value() const;
};

#endif // QT_CONFIG(combobox)


#if QT_CONFIG(spinbox)

class QUIntSpinBox : public QSpinBox
{
    Q_OBJECT
    Q_PROPERTY(uint value READ uintValue WRITE setUIntValue NOTIFY uintValueChanged USER true)
public:
    explicit QUIntSpinBox(QWidget *parent = 0)
      : QSpinBox(parent)
    {
        connect(this, SIGNAL(valueChanged(int)), SIGNAL(uintValueChanged()));
    }

    uint uintValue()
    {
        return value();
    }

    void setUIntValue(uint value_)
    {
        return setValue(value_);
    }

Q_SIGNALS:
    void uintValueChanged();
};

#endif // QT_CONFIG(spinbox)

/*!
    \class QItemEditorFactory
    \brief The QItemEditorFactory class provides widgets for editing item data
    in views and delegates.
    \since 4.2
    \ingroup model-view
    \inmodule QtWidgets

    When editing data in an item view, editors are created and
    displayed by a delegate. QStyledItemDelegate, which is the delegate by
    default installed on Qt's item views, uses a QItemEditorFactory to
    create editors for it. A default unique instance provided by
    QItemEditorFactory is used by all item delegates.  If you set a
    new default factory with setDefaultFactory(), the new factory will
    be used by existing and new delegates.

    A factory keeps a collection of QItemEditorCreatorBase
    instances, which are specialized editors that produce editors
    for one particular QVariant data type (All Qt models store
    their data in \l{QVariant}s).

    \section1 Standard Editing Widgets

    The standard factory implementation provides editors for a variety of data
    types. These are created whenever a delegate needs to provide an editor for
    data supplied by a model. The following table shows the relationship between
    types and the standard editors provided.

    \table
    \header \li Type \li Editor Widget
    \row    \li bool \li QComboBox
    \row    \li double \li QDoubleSpinBox
    \row    \li int \li{1,2} QSpinBox
    \row    \li unsigned int
    \row    \li QDate \li QDateEdit
    \row    \li QDateTime \li QDateTimeEdit
    \row    \li QPixmap \li QLabel
    \row    \li QString \li QLineEdit
    \row    \li QTime \li QTimeEdit
    \endtable

    Additional editors can be registered with the registerEditor() function.

    \sa QStyledItemDelegate, {Model/View Programming}, {Color Editor Factory Example}
*/

/*!
    \fn QItemEditorFactory::QItemEditorFactory()

    Constructs a new item editor factory.
*/

/*!
    Creates an editor widget with the given \a parent for the specified \a userType of data,
    and returns it as a QWidget.

    \sa registerEditor()
*/
QWidget *QItemEditorFactory::createEditor(int userType, QWidget *parent) const
{
    QItemEditorCreatorBase *creator = creatorMap.value(userType, 0);
    if (!creator) {
        const QItemEditorFactory *dfactory = defaultFactory();
        return dfactory == this ? 0 : dfactory->createEditor(userType, parent);
    }
    return creator->createWidget(parent);
}

/*!
    Returns the property name used to access data for the given \a userType of data.
*/
QByteArray QItemEditorFactory::valuePropertyName(int userType) const
{
    QItemEditorCreatorBase *creator = creatorMap.value(userType, 0);
    if (!creator) {
        const QItemEditorFactory *dfactory = defaultFactory();
        return dfactory == this ? QByteArray() : dfactory->valuePropertyName(userType);
    }
    return creator->valuePropertyName();
}

/*!
    Destroys the item editor factory.
*/
QItemEditorFactory::~QItemEditorFactory()
{
    //we make sure we delete all the QItemEditorCreatorBase
    //this has to be done only once, hence the sort-unique idiom
    std::vector<QItemEditorCreatorBase*> creators(creatorMap.cbegin(), creatorMap.cend());
    std::sort(creators.begin(), creators.end());
    const auto it = std::unique(creators.begin(), creators.end());
    qDeleteAll(creators.begin(), it);
}

/*!
    Registers an item editor creator specified by \a creator for the given \a userType of data.

    \b{Note:} The factory takes ownership of the item editor creator and will destroy
    it if a new creator for the same type is registered later.

    \sa createEditor()
*/
void QItemEditorFactory::registerEditor(int userType, QItemEditorCreatorBase *creator)
{
    const auto it = creatorMap.constFind(userType);
    if (it != creatorMap.cend()) {
        QItemEditorCreatorBase *oldCreator = it.value();
        Q_ASSERT(oldCreator);
        creatorMap.erase(it);
        if (std::find(creatorMap.cbegin(), creatorMap.cend(), oldCreator) == creatorMap.cend())
            delete oldCreator; // if it is no more in use we can delete it
    }

    creatorMap[userType] = creator;
}

class QDefaultItemEditorFactory : public QItemEditorFactory
{
public:
    inline QDefaultItemEditorFactory() {}
    QWidget *createEditor(int userType, QWidget *parent) const override;
    QByteArray valuePropertyName(int) const override;
};

QWidget *QDefaultItemEditorFactory::createEditor(int userType, QWidget *parent) const
{
    switch (userType) {
#if QT_CONFIG(combobox)
    case QVariant::Bool: {
        QBooleanComboBox *cb = new QBooleanComboBox(parent);
        cb->setFrame(false);
        cb->setSizePolicy(QSizePolicy::Ignored, cb->sizePolicy().verticalPolicy());
        return cb; }
#endif
#if QT_CONFIG(spinbox)
    case QVariant::UInt: {
        QSpinBox *sb = new QUIntSpinBox(parent);
        sb->setFrame(false);
        sb->setMinimum(0);
        sb->setMaximum(INT_MAX);
        sb->setSizePolicy(QSizePolicy::Ignored, sb->sizePolicy().verticalPolicy());
        return sb; }
    case QVariant::Int: {
        QSpinBox *sb = new QSpinBox(parent);
        sb->setFrame(false);
        sb->setMinimum(INT_MIN);
        sb->setMaximum(INT_MAX);
        sb->setSizePolicy(QSizePolicy::Ignored, sb->sizePolicy().verticalPolicy());
        return sb; }
#endif
#if QT_CONFIG(datetimeedit)
    case QVariant::Date: {
        QDateTimeEdit *ed = new QDateEdit(parent);
        ed->setFrame(false);
        return ed; }
    case QVariant::Time: {
        QDateTimeEdit *ed = new QTimeEdit(parent);
        ed->setFrame(false);
        return ed; }
    case QVariant::DateTime: {
        QDateTimeEdit *ed = new QDateTimeEdit(parent);
        ed->setFrame(false);
        return ed; }
#endif
#if QT_CONFIG(label)
    case QVariant::Pixmap:
        return new QLabel(parent);
#endif
#if QT_CONFIG(spinbox)
    case QVariant::Double: {
        QDoubleSpinBox *sb = new QDoubleSpinBox(parent);
        sb->setFrame(false);
        sb->setMinimum(-DBL_MAX);
        sb->setMaximum(DBL_MAX);
        sb->setSizePolicy(QSizePolicy::Ignored, sb->sizePolicy().verticalPolicy());
        return sb; }
#endif
#if QT_CONFIG(lineedit)
    case QVariant::String:
    default: {
        // the default editor is a lineedit
        QExpandingLineEdit *le = new QExpandingLineEdit(parent);
        le->setFrame(le->style()->styleHint(QStyle::SH_ItemView_DrawDelegateFrame, 0, le));
        if (!le->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, le))
            le->setWidgetOwnsGeometry(true);
        return le; }
#else
    default:
        break;
#endif
    }
    return 0;
}

QByteArray QDefaultItemEditorFactory::valuePropertyName(int userType) const
{
    switch (userType) {
#if QT_CONFIG(combobox)
    case QVariant::Bool:
        return "currentIndex";
#endif
#if QT_CONFIG(spinbox)
    case QVariant::UInt:
    case QVariant::Int:
    case QVariant::Double:
        return "value";
#endif
#if QT_CONFIG(datetimeedit)
    case QVariant::Date:
        return "date";
    case QVariant::Time:
        return "time";
    case QVariant::DateTime:
        return "dateTime";
#endif
    case QVariant::String:
    default:
        // the default editor is a lineedit
        return "text";
    }
}

static QItemEditorFactory *q_default_factory = 0;
struct QDefaultFactoryCleaner
{
    inline QDefaultFactoryCleaner() {}
    ~QDefaultFactoryCleaner() { delete q_default_factory; q_default_factory = 0; }
};

/*!
    Returns the default item editor factory.

    \sa setDefaultFactory()
*/
const QItemEditorFactory *QItemEditorFactory::defaultFactory()
{
    static const QDefaultItemEditorFactory factory;
    if (q_default_factory)
        return q_default_factory;
    return &factory;
}

/*!
    Sets the default item editor factory to the given \a factory.
    Both new and existing delegates will use the new factory.

    \sa defaultFactory()
*/
void QItemEditorFactory::setDefaultFactory(QItemEditorFactory *factory)
{
    static const QDefaultFactoryCleaner cleaner;
    delete q_default_factory;
    q_default_factory = factory;
}

/*!
    \class QItemEditorCreatorBase
    \brief The QItemEditorCreatorBase class provides an abstract base class that
    must be subclassed when implementing new item editor creators.
    \since 4.2
    \ingroup model-view
    \inmodule QtWidgets

    QItemEditorCreatorBase objects are specialized widget factories that
    provide editor widgets for one particular QVariant data type. They
    are used by QItemEditorFactory to create editors for
    \l{QStyledItemDelegate}s. Creator bases must be registered with
    QItemEditorFactory::registerEditor().

    An editor should provide a user property for the data it edits.
    QItemDelagates can then access the property using Qt's
    \l{Meta-Object System}{meta-object system} to set and retrieve the
    editing data. A property is set as the user property with the USER
    keyword:

    \snippet code/src_gui_itemviews_qitemeditorfactory.cpp 0

    If the editor does not provide a user property, it must return the
    name of the property from valuePropertyName(); delegates will then
    use the name to access the property. If a user property exists,
    item delegates will not call valuePropertyName().

    QStandardItemEditorCreator is a convenience template class that can be used
    to register widgets without the need to subclass QItemEditorCreatorBase.

    \sa QStandardItemEditorCreator, QItemEditorFactory,
    {Model/View Programming}, {Color Editor Factory Example}
*/

/*!
    \fn QItemEditorCreatorBase::~QItemEditorCreatorBase()

    Destroys the editor creator object.
*/
QItemEditorCreatorBase::~QItemEditorCreatorBase()
{

}

/*!
    \fn QWidget *QItemEditorCreatorBase::createWidget(QWidget *parent) const

    Returns an editor widget with the given \a parent.

    When implementing this function in subclasses of this class, you must
    construct and return new editor widgets with the parent widget specified.
*/

/*!
    \fn QByteArray QItemEditorCreatorBase::valuePropertyName() const

    Returns the name of the property used to get and set values in the creator's
    editor widgets.

    When implementing this function in subclasses, you must ensure that the
    editor widget's property specified by this function can accept the type
    the creator is registered for. For example, a creator which constructs
    QCheckBox widgets to edit boolean values would return the
    \l{QCheckBox::checkable}{checkable} property name from this function,
    and must be registered in the item editor factory for the QVariant::Bool
    type.

    Note: Since Qt 4.2 the item delegates query the user property of widgets,
    and only call this function if the widget has no user property. You can
    override this behavior by reimplementing QAbstractItemDelegate::setModelData()
    and QAbstractItemDelegate::setEditorData().

    \sa QMetaObject::userProperty(), QItemEditorFactory::registerEditor()
*/

/*!
    \class QItemEditorCreator
    \brief The QItemEditorCreator class makes it possible to create
           item editor creator bases without subclassing
           QItemEditorCreatorBase.

    \since 4.2
    \ingroup model-view
    \inmodule QtWidgets

    QItemEditorCreator is a convenience template class. It uses
    the template class to create editors for QItemEditorFactory.
    This way, it is not necessary to subclass
    QItemEditorCreatorBase.

    \snippet code/src_gui_itemviews_qitemeditorfactory.cpp 1

    The constructor takes the name of the property that contains the
    editing data. QStyledItemDelegate can then access the property by name
    when it sets and retrieves editing data. Only use this class if
    your editor does not define a user property (using the USER
    keyword in the Q_PROPERTY macro).  If the widget has a user
    property, you should use QStandardItemEditorCreator instead.

    \sa QItemEditorCreatorBase, QStandardItemEditorCreator,
        QItemEditorFactory, {Color Editor Factory Example}
*/

/*!
    \fn template <class T> QItemEditorCreator<T>::QItemEditorCreator(const QByteArray &valuePropertyName)

    Constructs an editor creator object using \a valuePropertyName
    as the name of the property to be used for editing. The
    property name is used by QStyledItemDelegate when setting and
    getting editor data.

    Note that the \a valuePropertyName is only used if the editor
    widget does not have a user property defined.
*/

/*!
    \fn template <class T> QWidget *QItemEditorCreator<T>::createWidget(QWidget *parent) const
    \reimp
*/

/*!
    \fn template <class T> QByteArray QItemEditorCreator<T>::valuePropertyName() const
    \reimp
*/

/*!
    \class QStandardItemEditorCreator

    \brief The QStandardItemEditorCreator class provides the
    possibility to register widgets without having to subclass
    QItemEditorCreatorBase.

    \since 4.2
    \ingroup model-view
    \inmodule QtWidgets

    This convenience template class makes it possible to register widgets without
    having to subclass QItemEditorCreatorBase.

    Example:

    \snippet code/src_gui_itemviews_qitemeditorfactory.cpp 2

    Setting the \c editorFactory created above in an item delegate via
    QStyledItemDelegate::setItemEditorFactory() makes sure that all values of type
    QVariant::DateTime will be edited in \c{MyFancyDateTimeEdit}.

    The editor must provide a user property that will contain the
    editing data. The property is used by \l{QStyledItemDelegate}s to set
    and retrieve the data (using Qt's \l{Meta-Object
    System}{meta-object system}). You set the user property with
    the USER keyword:

    \snippet code/src_gui_itemviews_qitemeditorfactory.cpp 3

    \sa QItemEditorCreatorBase, QItemEditorCreator,
        QItemEditorFactory, QStyledItemDelegate, {Color Editor Factory Example}
*/

/*!
    \fn template <class T> QStandardItemEditorCreator<T>::QStandardItemEditorCreator()

    Constructs an editor creator object.
*/

/*!
    \fn template <class T> QWidget *QStandardItemEditorCreator<T>::createWidget(QWidget *parent) const
    \reimp
*/

/*!
    \fn template <class T> QByteArray QStandardItemEditorCreator<T>::valuePropertyName() const
    \reimp
*/

#if QT_CONFIG(lineedit)

QExpandingLineEdit::QExpandingLineEdit(QWidget *parent)
    : QLineEdit(parent), originalWidth(-1), widgetOwnsGeometry(false)
{
    connect(this, SIGNAL(textChanged(QString)), this, SLOT(resizeToContents()));
    updateMinimumWidth();
}

void QExpandingLineEdit::changeEvent(QEvent *e)
{
    switch (e->type())
    {
    case QEvent::FontChange:
    case QEvent::StyleChange:
    case QEvent::ContentsRectChange:
        updateMinimumWidth();
        break;
    default:
        break;
    }

    QLineEdit::changeEvent(e);
}

void QExpandingLineEdit::updateMinimumWidth()
{
    const QMargins tm = textMargins();
    const QMargins cm = contentsMargins();
    const int width = tm.left() + tm.right() + cm.left() + cm.right() + 4 /*horizontalMargin in qlineedit.cpp*/;

    QStyleOptionFrame opt;
    initStyleOption(&opt);

    int minWidth = style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(width, 0).
                                      expandedTo(QApplication::globalStrut()), this).width();
    setMinimumWidth(minWidth);
}

void QExpandingLineEdit::resizeToContents()
{
    int oldWidth = width();
    if (originalWidth == -1)
        originalWidth = oldWidth;
    if (QWidget *parent = parentWidget()) {
        QPoint position = pos();
        int hintWidth = minimumWidth() + fontMetrics().horizontalAdvance(displayText());
        int parentWidth = parent->width();
        int maxWidth = isRightToLeft() ? position.x() + oldWidth : parentWidth - position.x();
        int newWidth = qBound(originalWidth, hintWidth, maxWidth);
        if (widgetOwnsGeometry)
            setMaximumWidth(newWidth);
        if (isRightToLeft())
            move(position.x() - newWidth + oldWidth, position.y());
        resize(newWidth, height());
    }
}

#endif // QT_CONFIG(lineedit)

#if QT_CONFIG(combobox)

QBooleanComboBox::QBooleanComboBox(QWidget *parent)
    : QComboBox(parent)
{
    addItem(QComboBox::tr("False"));
    addItem(QComboBox::tr("True"));
}

void QBooleanComboBox::setValue(bool value)
{
    setCurrentIndex(value ? 1 : 0);
}

bool QBooleanComboBox::value() const
{
    return (currentIndex() == 1);
}

#endif // QT_CONFIG(combobox)

QT_END_NAMESPACE

#if QT_CONFIG(lineedit) || QT_CONFIG(combobox)
#include "qitemeditorfactory.moc"
#endif

#include "moc_qitemeditorfactory_p.cpp"
