/****************************************************************************
**
** 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."
**
****************************************************************************/


#ifndef QTVARIANTPROPERTY_H
#define QTVARIANTPROPERTY_H

#include "qtpropertybrowser.h"
#include <QtCore/QVariant>
#include <QtGui/QIcon>

#if QT_VERSION >= 0x040400
QT_BEGIN_NAMESPACE
#endif

class QRegularExpression;

typedef QMap<int, QIcon> QtIconMap;

class QtVariantPropertyManager;
class QtVariantPropertyPrivate;

/**
 * @ingroup group_sdk_libraries_qtpropertybrowser
 *
    \class QtVariantProperty

    \brief The QtVariantProperty class is a convenience class handling
    QVariant based properties.

    QtVariantProperty provides additional API: A property's type,
    value type, attribute values and current value can easily be
    retrieved using the propertyType(), valueType(), attributeValue()
    and value() functions respectively. In addition, the attribute
    values and the current value can be set using the corresponding
    setValue() and setAttribute() functions.

    For example, instead of writing:

    \code
        QtVariantPropertyManager *variantPropertyManager;
        QtProperty *property;

        variantPropertyManager->setValue(property, 10);
    \endcode

    you can write:

    \code
        QtVariantPropertyManager *variantPropertyManager;
        QtVariantProperty *property;

        property->setValue(10);
    \endcode

    QtVariantProperty instances can only be created by the
    QtVariantPropertyManager class.

    \sa QtProperty, QtVariantPropertyManager, QtVariantEditorFactory
 **/
class QT_QTPROPERTYBROWSER_EXPORT QtVariantProperty : public QtProperty {
public:
    ~QtVariantProperty() override;
    QVariant value() const;
    QVariant attributeValue(const QString& attribute) const;
    int valueType() const;
    int propertyType() const;

    void setValue(const QVariant& value);
    void setAttribute(const QString& attribute, const QVariant& value);
    // Added in CamiTK for enum icon management
    virtual void setAttribute(const QString& attribute, const QMap<int, QIcon>& value);

protected:
    QtVariantProperty(QtVariantPropertyManager* manager);
private:
    friend class QtVariantPropertyManager;
    QtVariantPropertyPrivate* d_ptr;
};

class QtVariantPropertyManagerPrivate;

class QT_QTPROPERTYBROWSER_EXPORT QtVariantPropertyManager : public QtAbstractPropertyManager {
    Q_OBJECT
public:
    QtVariantPropertyManager(QObject* parent = nullptr);
    ~QtVariantPropertyManager() override;

    virtual QtVariantProperty* addProperty(int propertyType, const QString& name = QString());

    int propertyType(const QtProperty* property) const;
    int valueType(const QtProperty* property) const;
    QtVariantProperty* variantProperty(const QtProperty* property) const;

    virtual bool isPropertyTypeSupported(int propertyType) const;
    virtual int valueType(int propertyType) const;
    virtual QStringList attributes(int propertyType) const;
    virtual int attributeType(int propertyType, const QString& attribute) const;

    virtual QVariant value(const QtProperty* property) const;
    virtual QVariant attributeValue(const QtProperty* property, const QString& attribute) const;

    static int enumTypeId();
    static int flagTypeId();
    static int groupTypeId();
    static int iconMapTypeId();
public Q_SLOTS:
    virtual void setValue(QtProperty* property, const QVariant& val);
    virtual void setAttribute(QtProperty* property,
                              const QString& attribute, const QVariant& value);
    // Added in CamiTK for enum icon management
    virtual void setAttribute(QtProperty* property,
                              const QString& attribute, const QMap<int, QIcon>& value);
Q_SIGNALS:
    void valueChanged(QtProperty* property, const QVariant& val);
    void attributeChanged(QtProperty* property,
                          const QString& attribute, const QVariant& val);
protected:
    bool hasValue(const QtProperty* property) const override;
    QString valueText(const QtProperty* property) const override;
    QIcon valueIcon(const QtProperty* property) const override;
    void initializeProperty(QtProperty* property) override;
    void uninitializeProperty(QtProperty* property) override;
    QtProperty* createProperty() override;
private:
    QtVariantPropertyManagerPrivate* d_ptr;
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(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 slotValueChanged(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 slotValueChanged(QtProperty*, bool))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QString&))
    Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty*, const QRegularExpression&))
    Q_PRIVATE_SLOT(d_func(), void slotEchoModeChanged(QtProperty*, int))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QDate&))
    Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty*, const QDate&, const QDate&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QTime&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QDateTime&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QKeySequence&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QChar&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QLocale&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QPoint&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QPointF&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QVector3D&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QSize&))
    Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty*, const QSize&, const QSize&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QSizeF&))
    Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty*, const QSizeF&, const QSizeF&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QRect&))
    Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty*, const QRect&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QRectF&))
    Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty*, const QRectF&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QColor&))
    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 slotValueChanged(QtProperty*, const QSizePolicy&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QFont&))
    Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty*, const QCursor&))
    Q_PRIVATE_SLOT(d_func(), void slotFlagNamesChanged(QtProperty*, const QStringList&))

    Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty*, QtProperty*, QtProperty*))
    Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty*, QtProperty*))
    Q_DECLARE_PRIVATE(QtVariantPropertyManager)
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
    Q_DISABLE_COPY_MOVE(QtVariantPropertyManager)
#else
    Q_DISABLE_COPY(QtVariantPropertyManager)
#endif
};

class QtVariantEditorFactoryPrivate;

class QT_QTPROPERTYBROWSER_EXPORT QtVariantEditorFactory : public QtAbstractEditorFactory<QtVariantPropertyManager> {
    Q_OBJECT
public:
    QtVariantEditorFactory(QObject* parent = nullptr);
    ~QtVariantEditorFactory() override;
protected:
    void connectPropertyManager(QtVariantPropertyManager* manager) override;
    QWidget* createEditor(QtVariantPropertyManager* manager, QtProperty* property,
                          QWidget* parent) override;
    void disconnectPropertyManager(QtVariantPropertyManager* manager) override;
private:
    QtVariantEditorFactoryPrivate* d_ptr;
    Q_DECLARE_PRIVATE(QtVariantEditorFactory)
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
    Q_DISABLE_COPY_MOVE(QtVariantEditorFactory)
#else
    Q_DISABLE_COPY(QtVariantEditorFactory)
#endif
};

#if QT_VERSION >= 0x040400
QT_END_NAMESPACE
#endif

Q_DECLARE_METATYPE(QIcon)
Q_DECLARE_METATYPE(QtIconMap)
#endif
