/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Designer of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "propertyeditor.h"

#include "qttreepropertybrowser.h"
#include "qtbuttonpropertybrowser.h"
#include "qtvariantproperty.h"
#include "designerpropertymanager.h"
#include "qdesigner_propertysheet_p.h"
#include "formwindowbase_p.h"
#include "filterwidget_p.h" // For FilterWidget

#include "newdynamicpropertydialog.h"
#include "dynamicpropertysheet.h"
#include "shared_enums_p.h"

// sdk
#include <QtDesigner/QDesignerFormEditorInterface>
#include <QtDesigner/QDesignerFormWindowManagerInterface>
#include <QtDesigner/QExtensionManager>
#include <QtDesigner/QDesignerPropertySheetExtension>
#include <QtDesigner/QDesignerWidgetDataBaseInterface>
#include <QtDesigner/private/abstractsettings_p.h>
// shared
#include <qdesigner_utils_p.h>
#include <qdesigner_propertycommand_p.h>
#include <metadatabase_p.h>
#include <iconloader_p.h>
#ifdef Q_OS_WIN
#  include <widgetfactory_p.h>
#endif
#include <QtGui/QAction>
#include <QtGui/QLineEdit>
#include <QtGui/QMenu>
#include <QtGui/QApplication>
#include <QtGui/QVBoxLayout>
#include <QtGui/QScrollArea>
#include <QtGui/QStackedWidget>
#include <QtGui/QToolBar>
#include <QtGui/QToolButton>
#include <QtGui/QActionGroup>
#include <QtGui/QLabel>
#include <QtGui/QPainter>

#include <QtCore/QDebug>
#include <QtCore/QTextStream>

static const char *SettingsGroupC = "PropertyEditor";
#if QT_VERSION >= 0x040500
static const char *ViewKeyC = "View";
#endif
static const char *ColorKeyC = "Colored";
static const char *SortedKeyC = "Sorted";
static const char *ExpansionKeyC = "ExpandedItems";

enum SettingsView { TreeView, ButtonView };

QT_BEGIN_NAMESPACE

// ---------------------------------------------------------------------------------

namespace qdesigner_internal {

// ----------- ElidingLabel
// QLabel does not support text eliding so we need a helper class

class ElidingLabel : public QWidget
{
public:
    ElidingLabel(const QString &text = QString(), QWidget *parent = 0)
        : QWidget(parent),
        m_text(text),
        m_mode(Qt::ElideRight) {
        setContentsMargins(3, 2, 3, 2);
    }
    QSize sizeHint() const;
    void paintEvent(QPaintEvent *e);
    void setText(const QString &text) {
        m_text = text;
        updateGeometry();
    }
    void setElidemode(Qt::TextElideMode mode) {
        m_mode = mode;
        updateGeometry();
    }
private:
    QString m_text;
    Qt::TextElideMode m_mode;
};

QSize ElidingLabel::sizeHint() const
{
    QSize size = fontMetrics().boundingRect(m_text).size();
    size += QSize(contentsMargins().left() + contentsMargins().right(),
                  contentsMargins().top() + contentsMargins().bottom());
    return size;
}

void ElidingLabel::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setPen(QColor(0, 0, 0, 60));
    painter.setBrush(QColor(255, 255, 255, 40));
    painter.drawRect(rect().adjusted(0, 0, -1, -1));
    painter.setPen(palette().windowText().color());
    painter.drawText(contentsRect(), Qt::AlignLeft,
                     fontMetrics().elidedText(m_text, Qt::ElideRight, width(), 0));
}


// ----------- PropertyEditor::Strings

PropertyEditor::Strings::Strings() :
    m_fontProperty(QLatin1String("font")),
    m_qLayoutWidget(QLatin1String("QLayoutWidget")),
    m_designerPrefix(QLatin1String("QDesigner")),
    m_layout(QLatin1String("Layout")),
    m_validationModeAttribute(QLatin1String("validationMode")),
    m_fontAttribute(QLatin1String("font")),
    m_superPaletteAttribute(QLatin1String("superPalette")),
    m_enumNamesAttribute(QLatin1String("enumNames")),
    m_resettableAttribute(QLatin1String("resettable")),
    m_flagsAttribute(QLatin1String("flags"))
{
    m_alignmentProperties.insert(QLatin1String("alignment"));
    m_alignmentProperties.insert(QLatin1String("layoutLabelAlignment")); // QFormLayout
    m_alignmentProperties.insert(QLatin1String("layoutFormAlignment"));
}

// ----------- PropertyEditor

QDesignerMetaDataBaseItemInterface* PropertyEditor::metaDataBaseItem() const
{
    QObject *o = object();
    if (!o)
        return 0;
    QDesignerMetaDataBaseInterface *db = core()->metaDataBase();
    if (!db)
        return 0;
    return db->item(o);
}

void PropertyEditor::setupStringProperty(QtVariantProperty *property, bool isMainContainer)
{
    const StringPropertyParameters params = textPropertyValidationMode(core(), m_object, property->propertyName(), isMainContainer);
    // Does a meta DB entry exist - add comment
    const bool hasComment = params.second;
    property->setAttribute(m_strings.m_validationModeAttribute, params.first);
    // assuming comment cannot appear or disappear for the same property in different object instance
    if (!hasComment)
        qDeleteAll(property->subProperties());
}

void PropertyEditor::setupPaletteProperty(QtVariantProperty *property)
{
    QPalette value = qvariant_cast<QPalette>(property->value());
    QPalette superPalette = QPalette();
    QWidget *currentWidget = qobject_cast<QWidget *>(m_object);
    if (currentWidget) {
        if (currentWidget->isWindow())
            superPalette = QApplication::palette(currentWidget);
        else {
            if (currentWidget->parentWidget())
                superPalette = currentWidget->parentWidget()->palette();
        }
    }
    m_updatingBrowser = true;
    property->setAttribute(m_strings.m_superPaletteAttribute, superPalette);
    m_updatingBrowser = false;
}

static inline QToolButton *createDropDownButton(QAction *defaultAction, QWidget *parent = 0)
{
    QToolButton *rc = new QToolButton(parent);
    rc->setDefaultAction(defaultAction);
    rc->setPopupMode(QToolButton::InstantPopup);
    return rc;
}

PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *parent, Qt::WindowFlags flags)  :
    QDesignerPropertyEditor(parent, flags),
    m_core(core),
    m_propertySheet(0),
    m_currentBrowser(0),
    m_treeBrowser(0),
    m_propertyManager(new DesignerPropertyManager(m_core, this)),
    m_dynamicGroup(0),
    m_updatingBrowser(false),
    m_stackedWidget(new QStackedWidget),
    m_filterWidget(new FilterWidget(0, FilterWidget::LayoutAlignNone)),
    m_buttonIndex(-1),
    m_treeIndex(-1),
    m_addDynamicAction(new QAction(createIconSet(QLatin1String("plus.png")), tr("Add Dynamic Property..."), this)),
    m_removeDynamicAction(new QAction(createIconSet(QLatin1String("minus.png")), tr("Remove Dynamic Property"), this)),
    m_sortingAction(new QAction(createIconSet(QLatin1String("sort.png")), tr("Sorting"), this)),
    m_coloringAction(new QAction(createIconSet(QLatin1String("color.png")), tr("Color Groups"), this)),
    m_treeAction(new QAction(tr("Tree View"), this)),
    m_buttonAction(new QAction(tr("Drop Down Button View"), this)),
    m_classLabel(new ElidingLabel),
    m_sorting(false),
    m_coloring(false),
    m_brightness(false)
{
    QVector<QColor> colors;
    colors.reserve(6);
    colors.push_back(QColor(255, 230, 191));
    colors.push_back(QColor(255, 255, 191));
    colors.push_back(QColor(191, 255, 191));
    colors.push_back(QColor(199, 255, 255));
    colors.push_back(QColor(234, 191, 255));
    colors.push_back(QColor(255, 191, 239));
    m_colors.reserve(colors.count());
    const int darknessFactor = 250;
    for (int i = 0; i < colors.count(); i++) {
        QColor c = colors.at(i);
        m_colors.push_back(qMakePair(c, c.darker(darknessFactor)));
    }
    QColor dynamicColor(191, 207, 255);
    QColor layoutColor(255, 191, 191);
    m_dynamicColor = qMakePair(dynamicColor, dynamicColor.darker(darknessFactor));
    m_layoutColor = qMakePair(layoutColor, layoutColor.darker(darknessFactor));

    updateForegroundBrightness();

    QActionGroup *actionGroup = new QActionGroup(this);

    m_treeAction->setCheckable(true);
    m_treeAction->setIcon(createIconSet(QLatin1String("widgets/listview.png")));
    m_buttonAction->setCheckable(true);
    m_buttonAction->setIcon(createIconSet(QLatin1String("dropdownbutton.png")));

    actionGroup->addAction(m_treeAction);
    actionGroup->addAction(m_buttonAction);
    connect(actionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotViewTriggered(QAction*)));

    // Add actions
    QActionGroup *addDynamicActionGroup = new QActionGroup(this);
    connect(addDynamicActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotAddDynamicProperty(QAction*)));

    QMenu *addDynamicActionMenu = new QMenu(this);
    m_addDynamicAction->setMenu(addDynamicActionMenu);
    m_addDynamicAction->setEnabled(false);
    QAction *addDynamicAction = addDynamicActionGroup->addAction(tr("String..."));
    addDynamicAction->setData(static_cast<int>(QVariant::String));
    addDynamicActionMenu->addAction(addDynamicAction);
    addDynamicAction = addDynamicActionGroup->addAction(tr("Bool..."));
    addDynamicAction->setData(static_cast<int>(QVariant::Bool));
    addDynamicActionMenu->addAction(addDynamicAction);
    addDynamicActionMenu->addSeparator();
    addDynamicAction = addDynamicActionGroup->addAction(tr("Other..."));
    addDynamicAction->setData(static_cast<int>(QVariant::Invalid));
    addDynamicActionMenu->addAction(addDynamicAction);
    // remove
    m_removeDynamicAction->setEnabled(false);
    connect(m_removeDynamicAction, SIGNAL(triggered()), this, SLOT(slotRemoveDynamicProperty()));
    // Configure
    QAction *configureAction = new QAction(tr("Configure Property Editor"), this);
    configureAction->setIcon(createIconSet(QLatin1String("configure.png")));
    QMenu *configureMenu = new QMenu(this);
    configureAction->setMenu(configureMenu);

    m_sortingAction->setCheckable(true);
    connect(m_sortingAction, SIGNAL(toggled(bool)), this, SLOT(slotSorting(bool)));

    m_coloringAction->setCheckable(true);
    connect(m_coloringAction, SIGNAL(toggled(bool)), this, SLOT(slotColoring(bool)));

    configureMenu->addAction(m_sortingAction);
    configureMenu->addAction(m_coloringAction);
#if QT_VERSION >= 0x04FF00
    configureMenu->addSeparator();
    configureMenu->addAction(m_treeAction);
    configureMenu->addAction(m_buttonAction);
#endif
    // Assemble toolbar
    QToolBar *toolBar = new QToolBar;
    toolBar->addWidget(m_filterWidget);
    toolBar->addWidget(createDropDownButton(m_addDynamicAction));
    toolBar->addAction(m_removeDynamicAction);
    toolBar->addWidget(createDropDownButton(configureAction));
    // Views
    QScrollArea *buttonScroll = new QScrollArea(m_stackedWidget);
    m_buttonBrowser = new QtButtonPropertyBrowser(buttonScroll);
    buttonScroll->setWidgetResizable(true);
    buttonScroll->setWidget(m_buttonBrowser);
    m_buttonIndex = m_stackedWidget->addWidget(buttonScroll);
    connect(m_buttonBrowser, SIGNAL(currentItemChanged(QtBrowserItem*)), this, SLOT(slotCurrentItemChanged(QtBrowserItem*)));

    m_treeBrowser = new QtTreePropertyBrowser(m_stackedWidget);
    m_treeBrowser->setRootIsDecorated(false);
    m_treeBrowser->setPropertiesWithoutValueMarked(true);
    m_treeBrowser->setResizeMode(QtTreePropertyBrowser::Interactive);
    m_treeIndex = m_stackedWidget->addWidget(m_treeBrowser);
    connect(m_treeBrowser, SIGNAL(currentItemChanged(QtBrowserItem*)), this, SLOT(slotCurrentItemChanged(QtBrowserItem*)));
    connect(m_filterWidget, SIGNAL(filterChanged(QString)), this, SLOT(setFilter(QString)));

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->addWidget(toolBar);
    layout->addWidget(m_classLabel);
    layout->addSpacerItem(new QSpacerItem(0,1));
    layout->addWidget(m_stackedWidget);
    layout->setMargin(0);
    layout->setSpacing(0);

    m_treeFactory = new DesignerEditorFactory(m_core, this);
    m_treeFactory->setSpacing(0);
    m_groupFactory = new DesignerEditorFactory(m_core, this);
    QtVariantPropertyManager *variantManager = m_propertyManager;
    m_buttonBrowser->setFactoryForManager(variantManager, m_groupFactory);
    m_treeBrowser->setFactoryForManager(variantManager, m_treeFactory);

    m_stackedWidget->setCurrentIndex(m_treeIndex);
    m_currentBrowser = m_treeBrowser;
    m_treeAction->setChecked(true);

    connect(m_groupFactory, SIGNAL(resetProperty(QtProperty*)), this, SLOT(slotResetProperty(QtProperty*)));
    connect(m_treeFactory, SIGNAL(resetProperty(QtProperty*)), this, SLOT(slotResetProperty(QtProperty*)));
    connect(variantManager, SIGNAL(valueChanged(QtProperty*,QVariant,bool)), this, SLOT(slotValueChanged(QtProperty*,QVariant,bool)));

    // retrieve initial settings
    QDesignerSettingsInterface *settings = m_core->settingsManager();
    settings->beginGroup(QLatin1String(SettingsGroupC));
#if QT_VERSION >= 0x040500
    const SettingsView view = settings->value(QLatin1String(ViewKeyC), TreeView).toInt() == TreeView ? TreeView :  ButtonView;
#endif
    // Coloring not available unless treeview and not sorted
    m_sorting = settings->value(QLatin1String(SortedKeyC), false).toBool();
    m_coloring = settings->value(QLatin1String(ColorKeyC), true).toBool();
    const QVariantMap expansionState = settings->value(QLatin1String(ExpansionKeyC), QVariantMap()).toMap();
    settings->endGroup();
    // Apply settings
    m_sortingAction->setChecked(m_sorting);
    m_coloringAction->setChecked(m_coloring);
#if QT_VERSION >= 0x040500
    switch (view) {
    case TreeView:
        m_currentBrowser = m_treeBrowser;
        m_stackedWidget->setCurrentIndex(m_treeIndex);
        m_treeAction->setChecked(true);
        break;
    case ButtonView:
        m_currentBrowser = m_buttonBrowser;
        m_stackedWidget->setCurrentIndex(m_buttonIndex);
        m_buttonAction->setChecked(true);
        break;
    }
#endif
    // Restore expansionState from QVariant map
    if (!expansionState.empty()) {
        const QVariantMap::const_iterator cend = expansionState.constEnd();
        for (QVariantMap::const_iterator it = expansionState.constBegin(); it != cend; ++it)
            m_expansionState.insert(it.key(), it.value().toBool());
    }
    updateActionsState();
}

PropertyEditor::~PropertyEditor()
{
    storeExpansionState();
    saveSettings();
}

void PropertyEditor::saveSettings() const
{
    QDesignerSettingsInterface *settings = m_core->settingsManager();
    settings->beginGroup(QLatin1String(SettingsGroupC));
#if QT_VERSION >= 0x040500
    settings->setValue(QLatin1String(ViewKeyC), QVariant(m_treeAction->isChecked() ? TreeView : ButtonView));
#endif
    settings->setValue(QLatin1String(ColorKeyC), QVariant(m_coloring));
    settings->setValue(QLatin1String(SortedKeyC), QVariant(m_sorting));
    // Save last expansionState as QVariant map
    QVariantMap expansionState;
    if (!m_expansionState.empty()) {
        const QMap<QString, bool>::const_iterator cend = m_expansionState.constEnd();
        for (QMap<QString, bool>::const_iterator it = m_expansionState.constBegin(); it != cend; ++it)
            expansionState.insert(it.key(), QVariant(it.value()));
    }
    settings->setValue(QLatin1String(ExpansionKeyC), expansionState);
    settings->endGroup();
}

void PropertyEditor::setExpanded(QtBrowserItem *item, bool expanded)
{
    if (m_buttonBrowser == m_currentBrowser)
        m_buttonBrowser->setExpanded(item, expanded);
    else if (m_treeBrowser == m_currentBrowser)
        m_treeBrowser->setExpanded(item, expanded);
}

bool PropertyEditor::isExpanded(QtBrowserItem *item) const
{
    if (m_buttonBrowser == m_currentBrowser)
        return m_buttonBrowser->isExpanded(item);
    else if (m_treeBrowser == m_currentBrowser)
        return m_treeBrowser->isExpanded(item);
    return false;
}

void PropertyEditor::setItemVisible(QtBrowserItem *item, bool visible)
{
    if (m_currentBrowser == m_treeBrowser) {
        m_treeBrowser->setItemVisible(item, visible);
    } else {
        qWarning("** WARNING %s is not implemented for this browser.", Q_FUNC_INFO);
    }
}

bool PropertyEditor::isItemVisible(QtBrowserItem *item) const
{
    return m_currentBrowser == m_treeBrowser ? m_treeBrowser->isItemVisible(item) : true;
}

/* Default handling of items not found in the map:
 * - Top-level items (classes) are assumed to be expanded
 * - Anything below (properties) is assumed to be collapsed
 * That is, the map is required, the state cannot be stored in a set */

void PropertyEditor::storePropertiesExpansionState(const QList<QtBrowserItem *> &items)
{
    const QChar bar = QLatin1Char('|');
    QListIterator<QtBrowserItem *> itProperty(items);
    while (itProperty.hasNext()) {
        QtBrowserItem *propertyItem = itProperty.next();
        if (!propertyItem->children().empty()) {
            QtProperty *property = propertyItem->property();
            const QString propertyName = property->propertyName();
            const QMap<QtProperty *, QString>::const_iterator itGroup = m_propertyToGroup.constFind(property);
            if (itGroup != m_propertyToGroup.constEnd()) {
                QString key = itGroup.value();
                key += bar;
                key += propertyName;
                m_expansionState[key] = isExpanded(propertyItem);
            }
        }
    }
}

void PropertyEditor::storeExpansionState()
{
    const QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
    if (m_sorting) {
        storePropertiesExpansionState(items);
    } else {
        QListIterator<QtBrowserItem *> itGroup(items);
        while (itGroup.hasNext()) {
            QtBrowserItem *item = itGroup.next();
            const QString groupName = item->property()->propertyName();
            QList<QtBrowserItem *> propertyItems = item->children();
            if (!propertyItems.empty())
                m_expansionState[groupName] = isExpanded(item);

            // properties stuff here
            storePropertiesExpansionState(propertyItems);
        }
    }
}

void PropertyEditor::collapseAll()
{
    QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
    QListIterator<QtBrowserItem *> itGroup(items);
    while (itGroup.hasNext())
        setExpanded(itGroup.next(), false);
}

void PropertyEditor::applyPropertiesExpansionState(const QList<QtBrowserItem *> &items)
{
    const QChar bar = QLatin1Char('|');
    QListIterator<QtBrowserItem *> itProperty(items);
    while (itProperty.hasNext()) {
        const QMap<QString, bool>::const_iterator excend = m_expansionState.constEnd();
        QtBrowserItem *propertyItem = itProperty.next();
        QtProperty *property = propertyItem->property();
        const QString propertyName = property->propertyName();
        const QMap<QtProperty *, QString>::const_iterator itGroup = m_propertyToGroup.constFind(property);
        if (itGroup != m_propertyToGroup.constEnd()) {
            QString key = itGroup.value();
            key += bar;
            key += propertyName;
            const QMap<QString, bool>::const_iterator pit = m_expansionState.constFind(key);
            if (pit != excend)
                setExpanded(propertyItem, pit.value());
            else
                setExpanded(propertyItem, false);
        }
    }
}

void PropertyEditor::applyExpansionState()
{
    const QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
    if (m_sorting) {
        applyPropertiesExpansionState(items);
    } else {
        QListIterator<QtBrowserItem *> itTopLevel(items);
        const QMap<QString, bool>::const_iterator excend = m_expansionState.constEnd();
        while (itTopLevel.hasNext()) {
            QtBrowserItem *item = itTopLevel.next();
            const QString groupName = item->property()->propertyName();
            const QMap<QString, bool>::const_iterator git = m_expansionState.constFind(groupName);
            if (git != excend)
                setExpanded(item, git.value());
            else
                setExpanded(item, true);
            // properties stuff here
            applyPropertiesExpansionState(item->children());
        }
    }
}

int PropertyEditor::applyPropertiesFilter(const QList<QtBrowserItem *> &items)
{
    int showCount = 0;
    const bool matchAll = m_filterPattern.isEmpty();
    QListIterator<QtBrowserItem *> itProperty(items);
    while (itProperty.hasNext()) {
        QtBrowserItem *propertyItem = itProperty.next();
        QtProperty *property = propertyItem->property();
        const QString propertyName = property->propertyName();
        const bool showProperty = matchAll || propertyName.contains(m_filterPattern, Qt::CaseInsensitive);
        setItemVisible(propertyItem, showProperty);
        if (showProperty)
            showCount++;
    }
    return showCount;
}

void PropertyEditor::applyFilter()
{
    const QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
    if (m_sorting) {
        applyPropertiesFilter(items);
    } else {
        QListIterator<QtBrowserItem *> itTopLevel(items);
        while (itTopLevel.hasNext()) {
            QtBrowserItem *item = itTopLevel.next();
            setItemVisible(item, applyPropertiesFilter(item->children()));
        }
    }
}

void PropertyEditor::clearView()
{
    m_currentBrowser->clear();
}

bool PropertyEditor::event(QEvent *event)
{
    if (event->type() == QEvent::PaletteChange)
        updateForegroundBrightness();

    return QDesignerPropertyEditor::event(event);
}

void PropertyEditor::updateForegroundBrightness()
{
    QColor c = palette().color(QPalette::Text);
    bool newBrightness = qRound(0.3 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF());

    if (m_brightness == newBrightness)
        return;

    m_brightness = newBrightness;

    updateColors();
}

QColor PropertyEditor::propertyColor(QtProperty *property) const
{
    if (!m_coloring)
        return QColor();

    QtProperty *groupProperty = property;

    QMap<QtProperty *, QString>::ConstIterator itProp = m_propertyToGroup.constFind(property);
    if (itProp != m_propertyToGroup.constEnd())
        groupProperty = m_nameToGroup.value(itProp.value());

    const int groupIdx = m_groups.indexOf(groupProperty);
    QPair<QColor, QColor> pair;
    if (groupIdx != -1) {
        if (groupProperty == m_dynamicGroup)
            pair = m_dynamicColor;
        else if (isLayoutGroup(groupProperty))
            pair = m_layoutColor;
        else
            pair = m_colors[groupIdx % m_colors.count()];
    }
    if (!m_brightness)
        return pair.first;
    return pair.second;
}

void PropertyEditor::fillView()
{
    if (m_sorting) {
        QMapIterator<QString, QtVariantProperty *> itProperty(m_nameToProperty);
        while (itProperty.hasNext()) {
            QtVariantProperty *property = itProperty.next().value();
            m_currentBrowser->addProperty(property);
        }
    } else {
        QListIterator<QtProperty *> itGroup(m_groups);
        while (itGroup.hasNext()) {
            QtProperty *group = itGroup.next();
            QtBrowserItem *item = m_currentBrowser->addProperty(group);
            if (m_currentBrowser == m_treeBrowser)
                m_treeBrowser->setBackgroundColor(item, propertyColor(group));
            group->setModified(m_currentBrowser == m_treeBrowser);
        }
    }
}

bool PropertyEditor::isLayoutGroup(QtProperty *group) const
{
   return group->propertyName() == m_strings.m_layout;
}

void PropertyEditor::updateActionsState()
{
    m_coloringAction->setEnabled(m_treeAction->isChecked() && !m_sortingAction->isChecked());
}

void PropertyEditor::slotViewTriggered(QAction *action)
{
    storeExpansionState();
    collapseAll();
    {
        UpdateBlocker ub(this);
        clearView();
        int idx = 0;
        if (action == m_treeAction) {
            m_currentBrowser = m_treeBrowser;
            idx = m_treeIndex;
        } else if (action == m_buttonAction) {
            m_currentBrowser = m_buttonBrowser;
            idx = m_buttonIndex;
        }
        fillView();
        m_stackedWidget->setCurrentIndex(idx);
        applyExpansionState();
        applyFilter();
    }
    updateActionsState();
}

void PropertyEditor::slotSorting(bool sort)
{
    if (sort == m_sorting)
        return;

    storeExpansionState();
    m_sorting = sort;
    collapseAll();
    {
        UpdateBlocker ub(this);
        clearView();
        m_treeBrowser->setRootIsDecorated(sort);
        fillView();
        applyExpansionState();
        applyFilter();
    }
    updateActionsState();
}

void PropertyEditor::updateColors()
{
    if (m_treeBrowser && m_currentBrowser == m_treeBrowser) {
        QList<QtBrowserItem *> items = m_treeBrowser->topLevelItems();
        QListIterator<QtBrowserItem *> itItem(items);
        while (itItem.hasNext()) {
            QtBrowserItem *item = itItem.next();
            m_treeBrowser->setBackgroundColor(item, propertyColor(item->property()));
        }
    }
}

void PropertyEditor::slotColoring(bool coloring)
{
    if (coloring == m_coloring)
        return;

    m_coloring = coloring;

    updateColors();
}

void PropertyEditor::slotAddDynamicProperty(QAction *action)
{
    if (!m_propertySheet)
        return;

    const QDesignerDynamicPropertySheetExtension *dynamicSheet =
            qt_extension<QDesignerDynamicPropertySheetExtension*>(m_core->extensionManager(), m_object);

    if (!dynamicSheet)
        return;

    QString newName;
    QVariant newValue;
    { // Make sure the dialog is closed before the signal is emitted.
        const QVariant::Type type = static_cast<QVariant::Type>(action->data().toInt());
        NewDynamicPropertyDialog dlg(core()->dialogGui(), m_currentBrowser);
        if (type != QVariant::Invalid)
            dlg.setPropertyType(type);

        QStringList reservedNames;
        const int propertyCount = m_propertySheet->count();
        for (int i = 0; i < propertyCount; i++) {
            if (!dynamicSheet->isDynamicProperty(i) || m_propertySheet->isVisible(i))
                reservedNames.append(m_propertySheet->propertyName(i));
        }
        dlg.setReservedNames(reservedNames);
        if (dlg.exec() == QDialog::Rejected)
            return;
        newName = dlg.propertyName();
        newValue = dlg.propertyValue();
    }
    m_recentlyAddedDynamicProperty = newName;
    emit addDynamicProperty(newName, newValue);
}

QDesignerFormEditorInterface *PropertyEditor::core() const
{
    return m_core;
}

bool PropertyEditor::isReadOnly() const
{
    return false;
}

void PropertyEditor::setReadOnly(bool /*readOnly*/)
{
    qDebug() << "PropertyEditor::setReadOnly() request";
}

void PropertyEditor::setPropertyValue(const QString &name, const QVariant &value, bool changed)
{
    const QMap<QString, QtVariantProperty*>::const_iterator it = m_nameToProperty.constFind(name);
    if (it == m_nameToProperty.constEnd())
        return;
    QtVariantProperty *property = it.value();
    updateBrowserValue(property, value);
    property->setModified(changed);
}

/* Quick update that assumes the actual count of properties has not changed
 * N/A when for example executing a layout command and margin properties appear. */
void PropertyEditor::updatePropertySheet()
{
    if (!m_propertySheet)
        return;

    updateToolBarLabel();

    const int propertyCount = m_propertySheet->count();
    const  QMap<QString, QtVariantProperty*>::const_iterator npcend = m_nameToProperty.constEnd();
    for (int i = 0; i < propertyCount; ++i) {
        const QString propertyName = m_propertySheet->propertyName(i);
        QMap<QString, QtVariantProperty*>::const_iterator it = m_nameToProperty.constFind(propertyName);
        if (it != npcend)
            updateBrowserValue(it.value(), m_propertySheet->property(i));
    }
}

static inline QLayout *layoutOfQLayoutWidget(QObject *o)
{
    if (o->isWidgetType() && !qstrcmp(o->metaObject()->className(), "QLayoutWidget"))
        return static_cast<QWidget*>(o)->layout();
    return 0;
}

void PropertyEditor::updateToolBarLabel()
{
    QString objectName;
    QString className;
    if (m_object) {
        if (QLayout *l = layoutOfQLayoutWidget(m_object))
            objectName = l->objectName();
        else
            objectName = m_object->objectName();
        className = realClassName(m_object);
    }

    m_classLabel->setVisible(!objectName.isEmpty() || !className.isEmpty());
    m_classLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    QString classLabelText;
    if (!objectName.isEmpty())
        classLabelText += objectName + QLatin1String(" : ");
    classLabelText += className;

    m_classLabel->setText(classLabelText);
    m_classLabel->setToolTip(tr("Object: %1\nClass: %2").arg(objectName).arg(className));
}

void PropertyEditor::updateBrowserValue(QtVariantProperty *property, const QVariant &value)
{
    QVariant v = value;
    const int type = property->propertyType();
    if (type == QtVariantPropertyManager::enumTypeId()) {
        const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(v);
        v = e.metaEnum.keys().indexOf(e.metaEnum.valueToKey(e.value));
    } else if (type == DesignerPropertyManager::designerFlagTypeId()) {
        const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(v);
        v = QVariant(f.value);
    } else if (type == DesignerPropertyManager::designerAlignmentTypeId()) {
        const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(v);
        v = QVariant(f.value);
    }
    QDesignerPropertySheet *sheet = qobject_cast<QDesignerPropertySheet*>(m_core->extensionManager()->extension(m_object, Q_TYPEID(QDesignerPropertySheetExtension)));
    int index = -1;
    if (sheet)
        index = sheet->indexOf(property->propertyName());
    if (sheet && m_propertyToGroup.contains(property)) { // don't do it for comments since property sheet doesn't keep them
        property->setEnabled(sheet->isEnabled(index));
    }

    // Rich text string property with comment: Store/Update the font the rich text editor dialog starts out with
    if (type == QVariant::String && !property->subProperties().empty()) {
        const int fontIndex = m_propertySheet->indexOf(m_strings.m_fontProperty);
        if (fontIndex != -1)
            property->setAttribute(m_strings.m_fontAttribute, m_propertySheet->property(fontIndex));
    }

    m_updatingBrowser = true;
    property->setValue(v);
    if (sheet && sheet->isResourceProperty(index))
        property->setAttribute(QLatin1String("defaultResource"), sheet->defaultResourceProperty(index));
    m_updatingBrowser = false;
}

int PropertyEditor::toBrowserType(const QVariant &value, const QString &propertyName) const
{
    if (qVariantCanConvert<PropertySheetFlagValue>(value)) {
        if (m_strings.m_alignmentProperties.contains(propertyName))
            return DesignerPropertyManager::designerAlignmentTypeId();
        return DesignerPropertyManager::designerFlagTypeId();
    }
    if (qVariantCanConvert<PropertySheetEnumValue>(value))
        return DesignerPropertyManager::enumTypeId();

    return value.userType();
}

QString PropertyEditor::realClassName(QObject *object) const
{
    if (!object)
        return QString();

    QString className = QLatin1String(object->metaObject()->className());
    const QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
    if (QDesignerWidgetDataBaseItemInterface *widgetItem = db->item(db->indexOfObject(object, true))) {
        className = widgetItem->name();

        if (object->isWidgetType() && className == m_strings.m_qLayoutWidget
                && static_cast<QWidget*>(object)->layout()) {
            className = QLatin1String(static_cast<QWidget*>(object)->layout()->metaObject()->className());
        }
    }

    if (className.startsWith(m_strings.m_designerPrefix))
        className.remove(1, m_strings.m_designerPrefix.size() - 1);

    return className;
}

static QString msgUnsupportedType(const QString &propertyName, unsigned type)
{
    QString rc;
    QTextStream str(&rc);
    str << "The property \"" << propertyName << "\" of type " << type;
    if (type == QVariant::Invalid) {
        str << " (invalid) ";
    } else {
        if (type < QVariant::UserType) {
            if (const char *typeName = QVariant::typeToName(static_cast<QVariant::Type>(type)))
                str << " (" << typeName << ") ";
        } else {
            str << " (user type) ";
        }
    }
    str << " is not supported yet!";
    return rc;
}

void PropertyEditor::setObject(QObject *object)
{
    QDesignerFormWindowInterface *oldFormWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
    // In the first setObject() call following the addition of a dynamic property, focus and edit it.
    const bool editNewDynamicProperty = object != 0 && m_object == object && !m_recentlyAddedDynamicProperty.isEmpty();
    m_object = object;
    m_propertyManager->setObject(object);
    QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
    FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
    m_treeFactory->setFormWindowBase(fwb);
    m_groupFactory->setFormWindowBase(fwb);

    storeExpansionState();

    UpdateBlocker ub(this);

    updateToolBarLabel();

    QMap<QString, QtVariantProperty *> toRemove = m_nameToProperty;

    const QDesignerDynamicPropertySheetExtension *dynamicSheet =
            qt_extension<QDesignerDynamicPropertySheetExtension*>(m_core->extensionManager(), m_object);
    const QDesignerPropertySheet *sheet = qobject_cast<QDesignerPropertySheet*>(m_core->extensionManager()->extension(m_object, Q_TYPEID(QDesignerPropertySheetExtension)));

    // Optimizization: Instead of rebuilding the complete list every time, compile a list of properties to remove,
    // remove them, traverse the sheet, in case property exists just set a value, otherwise - create it.
    QExtensionManager *m = m_core->extensionManager();

    m_propertySheet = qobject_cast<QDesignerPropertySheetExtension*>(m->extension(object, Q_TYPEID(QDesignerPropertySheetExtension)));
    if (m_propertySheet) {
        const int propertyCount = m_propertySheet->count();
        for (int i = 0; i < propertyCount; ++i) {
            if (!m_propertySheet->isVisible(i))
                continue;

            const QString propertyName = m_propertySheet->propertyName(i);
            if (m_propertySheet->indexOf(propertyName) != i)
                continue;
            const QString groupName = m_propertySheet->propertyGroup(i);
            const QMap<QString, QtVariantProperty *>::const_iterator rit = toRemove.constFind(propertyName);
            if (rit != toRemove.constEnd()) {
                QtVariantProperty *property = rit.value();
                if (m_propertyToGroup.value(property) == groupName && toBrowserType(m_propertySheet->property(i), propertyName) == property->propertyType())
                    toRemove.remove(propertyName);
            }
        }
    }

    QMapIterator<QString, QtVariantProperty *> itRemove(toRemove);
    while (itRemove.hasNext()) {
        itRemove.next();

        QtVariantProperty *property = itRemove.value();
        m_nameToProperty.remove(itRemove.key());
        m_propertyToGroup.remove(property);
        delete property;
    }

    if (oldFormWindow != formWindow)
        reloadResourceProperties();

    bool isMainContainer = false;
    if (QWidget *widget = qobject_cast<QWidget*>(object)) {
        if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(widget)) {
            isMainContainer = (fw->mainContainer() == widget);
        }
    }
    m_groups.clear();

    if (m_propertySheet) {
        QtProperty *lastProperty = 0;
        QtProperty *lastGroup = 0;
        const int propertyCount = m_propertySheet->count();
        for (int i = 0; i < propertyCount; ++i) {
            if (!m_propertySheet->isVisible(i))
                continue;

            const QString propertyName = m_propertySheet->propertyName(i);
            if (m_propertySheet->indexOf(propertyName) != i)
                continue;
            const QVariant value = m_propertySheet->property(i);

            const int type = toBrowserType(value, propertyName);

            QtVariantProperty *property = m_nameToProperty.value(propertyName, 0);
            bool newProperty = property == 0;
            if (newProperty) {
                property = m_propertyManager->addProperty(type, propertyName);
                if (property) {
                    newProperty = true;
                    if (type == DesignerPropertyManager::enumTypeId()) {
                        const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(value);
                        QStringList names;
                        QStringListIterator it(e.metaEnum.keys());
                        while (it.hasNext())
                            names.append(it.next());
                        m_updatingBrowser = true;
                        property->setAttribute(m_strings.m_enumNamesAttribute, names);
                        m_updatingBrowser = false;
                    } else if (type == DesignerPropertyManager::designerFlagTypeId()) {
                        const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(value);
                        QList<QPair<QString, uint> > flags;
                        QStringListIterator it(f.metaFlags.keys());
                        while (it.hasNext()) {
                            const QString name = it.next();
                            const uint val = f.metaFlags.keyToValue(name);
                            flags.append(qMakePair(name, val));
                        }
                        m_updatingBrowser = true;
                        QVariant v;
                        qVariantSetValue(v, flags);
                        property->setAttribute(m_strings.m_flagsAttribute, v);
                        m_updatingBrowser = false;
                    }
                }
            }

            if (property != 0) {
                const bool dynamicProperty = (dynamicSheet && dynamicSheet->isDynamicProperty(i))
                            || (sheet && sheet->isDefaultDynamicProperty(i));
                switch (type) {
                case QVariant::Palette:
                    setupPaletteProperty(property);
                    break;
                case QVariant::KeySequence:
                    //addCommentProperty(property, propertyName);
                    break;
                default:
                    break;
                }
                if (type == QVariant::String || type == qMetaTypeId<PropertySheetStringValue>())
                    setupStringProperty(property, isMainContainer);
                property->setAttribute(m_strings.m_resettableAttribute, m_propertySheet->hasReset(i));

                const QString groupName = m_propertySheet->propertyGroup(i);
                QtVariantProperty *groupProperty = 0;

                if (newProperty) {
                    QMap<QString, QtVariantProperty*>::const_iterator itPrev = m_nameToProperty.insert(propertyName, property);
                    m_propertyToGroup[property] = groupName;
                    if (m_sorting) {
                        QtProperty *previous = 0;
                        if (itPrev != m_nameToProperty.constBegin())
                            previous = (--itPrev).value();
                        m_currentBrowser->insertProperty(property, previous);
                    }
                }
                const QMap<QString, QtVariantProperty*>::const_iterator gnit = m_nameToGroup.constFind(groupName);
                if (gnit != m_nameToGroup.constEnd()) {
                    groupProperty = gnit.value();
                } else {
                    groupProperty = m_propertyManager->addProperty(QtVariantPropertyManager::groupTypeId(), groupName);
                    QtBrowserItem *item = 0;
                    if (!m_sorting)
                         item = m_currentBrowser->insertProperty(groupProperty, lastGroup);
                    m_nameToGroup[groupName] = groupProperty;
                    m_groups.append(groupProperty);
                    if (dynamicProperty)
                        m_dynamicGroup = groupProperty;
                    if (m_currentBrowser == m_treeBrowser && item) {
                        m_treeBrowser->setBackgroundColor(item, propertyColor(groupProperty));
                        groupProperty->setModified(true);
                    }
                }
                /*  Group changed or new group. Append to last subproperty of
                 * that group. Note that there are cases in which a derived
                 * property sheet appends fake properties for the class
                 * which will appear after the layout group properties
                 * (QWizardPage). To make them appear at the end of the
                 * actual class group, goto last element. */
                if (lastGroup != groupProperty) {
                    lastGroup = groupProperty;
                    lastProperty = 0;  // Append at end
                    const QList<QtProperty*> subProperties = lastGroup->subProperties();
                    if (!subProperties.empty())
                        lastProperty = subProperties.back();
                    lastGroup = groupProperty;
                }
                if (!m_groups.contains(groupProperty))
                    m_groups.append(groupProperty);
                if (newProperty)
                    groupProperty->insertSubProperty(property, lastProperty);

                lastProperty = property;

                updateBrowserValue(property, value);

                property->setModified(m_propertySheet->isChanged(i));
                if (propertyName == QLatin1String("geometry") && type == QVariant::Rect) {
                    QList<QtProperty *> subProperties = property->subProperties();
                    foreach (QtProperty *subProperty, subProperties) {
                        const QString subPropertyName = subProperty->propertyName();
                        if (subPropertyName == QLatin1String("X") || subPropertyName == QLatin1String("Y"))
                            subProperty->setEnabled(!isMainContainer);
                    }
                }
            } else {
                qWarning("%s", qPrintable(msgUnsupportedType(propertyName, type)));
            }
        }
    }
    QMap<QString, QtVariantProperty *> groups = m_nameToGroup;
    QMapIterator<QString, QtVariantProperty *> itGroup(groups);
    while (itGroup.hasNext()) {
        QtVariantProperty *groupProperty = itGroup.next().value();
        if (groupProperty->subProperties().empty()) {
            if (groupProperty == m_dynamicGroup)
                m_dynamicGroup = 0;
            delete groupProperty;
            m_nameToGroup.remove(itGroup.key());
        }
    }
    const bool addEnabled = dynamicSheet ? dynamicSheet->dynamicPropertiesAllowed() : false;
    m_addDynamicAction->setEnabled(addEnabled);
    m_removeDynamicAction->setEnabled(false);
    applyExpansionState();
    applyFilter();
    // In the first setObject() call following the addition of a dynamic property, focus and edit it.
    if (editNewDynamicProperty) {
        // Have QApplication process the events related to completely closing the modal 'add' dialog,
        // otherwise, we cannot focus the property editor in docked mode.
        QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
        editProperty(m_recentlyAddedDynamicProperty);
    }
    m_recentlyAddedDynamicProperty.clear();
    m_filterWidget->setEnabled(object);
}

void PropertyEditor::reloadResourceProperties()
{
    m_updatingBrowser = true;
    m_propertyManager->reloadResourceProperties();
    m_updatingBrowser = false;
}

QtBrowserItem *PropertyEditor::nonFakePropertyBrowserItem(QtBrowserItem *item) const
{
    // Top-level properties are QObject/QWidget groups, etc. Find first item property below
    // which should be nonfake
    const QList<QtBrowserItem *> topLevelItems = m_currentBrowser->topLevelItems();
    do {
        if (topLevelItems.contains(item->parent()))
            return item;
        item = item->parent();
    } while (item);
    return 0;
}

QString PropertyEditor::currentPropertyName() const
{
    if (QtBrowserItem *browserItem = m_currentBrowser->currentItem())
        if (QtBrowserItem *topLevelItem = nonFakePropertyBrowserItem(browserItem)) {
            return topLevelItem->property()->propertyName();
        }
    return QString();
}

void PropertyEditor::slotResetProperty(QtProperty *property)
{
    QDesignerFormWindowInterface *form = m_core->formWindowManager()->activeFormWindow();
    if (!form)
        return;

    if (m_propertyManager->resetFontSubProperty(property))
        return;

    if (m_propertyManager->resetIconSubProperty(property))
        return;

    if (!m_propertyToGroup.contains(property))
        return;

    emit resetProperty(property->propertyName());
}

void PropertyEditor::slotValueChanged(QtProperty *property, const QVariant &value, bool enableSubPropertyHandling)
{
    if (m_updatingBrowser)
        return;

    if (!m_propertySheet)
        return;

    QtVariantProperty *varProp = m_propertyManager->variantProperty(property);

    if (!varProp)
        return;

    if (!m_propertyToGroup.contains(property))
        return;

    if (varProp->propertyType() == QtVariantPropertyManager::enumTypeId()) {
        PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(m_propertySheet->property(m_propertySheet->indexOf(property->propertyName())));
        const int val = value.toInt();
        const QString valName = varProp->attributeValue(m_strings.m_enumNamesAttribute).toStringList().at(val);
        bool ok = false;
        e.value = e.metaEnum.parseEnum(valName, &ok);
        Q_ASSERT(ok);
        QVariant v;
        qVariantSetValue(v, e);
        emitPropertyValueChanged(property->propertyName(), v, true);
        return;
    }

    emitPropertyValueChanged(property->propertyName(), value, enableSubPropertyHandling);
}

bool PropertyEditor::isDynamicProperty(const QtBrowserItem* item) const
{
    if (!item)
        return false;

    const QDesignerDynamicPropertySheetExtension *dynamicSheet =
            qt_extension<QDesignerDynamicPropertySheetExtension*>(m_core->extensionManager(), m_object);

    if (!dynamicSheet)
        return false;

    if (m_propertyToGroup.contains(item->property())
                && dynamicSheet->isDynamicProperty(m_propertySheet->indexOf(item->property()->propertyName())))
        return true;
    return false;
}

void PropertyEditor::editProperty(const QString &name)
{
    // find the browser item belonging to the property, make it current and edit it
    QtBrowserItem *browserItem = 0;
    if (QtVariantProperty *property = m_nameToProperty.value(name, 0)) {
        const QList<QtBrowserItem *> items = m_currentBrowser->items(property);
        if (items.size() == 1)
            browserItem = items.front();
    }
    if (browserItem == 0)
        return;
    m_currentBrowser->setFocus(Qt::OtherFocusReason);
    if (m_currentBrowser == m_treeBrowser) { // edit is currently only supported in tree view
        m_treeBrowser->editItem(browserItem);
    } else {
        m_currentBrowser->setCurrentItem(browserItem);
    }
}

void PropertyEditor::slotCurrentItemChanged(QtBrowserItem *item)
{
    m_removeDynamicAction->setEnabled(isDynamicProperty(item));

}

void PropertyEditor::slotRemoveDynamicProperty()
{
    if (QtBrowserItem* item = m_currentBrowser->currentItem())
        if (isDynamicProperty(item))
            emit removeDynamicProperty(item->property()->propertyName());
}

void PropertyEditor::setFilter(const QString &pattern)
{
    m_filterPattern = pattern;
    applyFilter();
}
}

QT_END_NAMESPACE
