/****************************************************************************
**
** 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 "qdesigner_propertycommand_p.h"
#include "qdesigner_utils_p.h"
#include "dynamicpropertysheet.h"
#include "qdesigner_propertyeditor_p.h"
#include "qdesigner_integration_p.h"
#include "spacer_widget_p.h"
#include "qdesigner_propertysheet_p.h"

#include <QtDesigner/QDesignerFormEditorInterface>
#include <QtDesigner/QDesignerFormWindowInterface>
#include <QtDesigner/QDesignerFormWindowCursorInterface>
#include <QtDesigner/QDesignerDynamicPropertySheetExtension>
#include <QtDesigner/QDesignerPropertySheetExtension>
#include <QtDesigner/QDesignerPropertyEditorInterface>
#include <QtDesigner/QDesignerObjectInspectorInterface>
#include <QtDesigner/QDesignerIntegrationInterface>
#include <QtDesigner/QDesignerWidgetDataBaseInterface>
#include <QtDesigner/QExtensionManager>

#include <QtCore/QSize>
#include <QtCore/QTextStream>
#include <QtGui/QWidget>
#include <QtGui/QApplication>
#include <QtGui/QAction>
#include <QtGui/QDialog>
#include <QtGui/QPushButton>
#include <QtGui/QLayout>
#include <qdebug.h>

QT_BEGIN_NAMESPACE

namespace  {
enum { debugPropertyCommands = 0 };

// Debug resolve mask of font
QString fontMask(unsigned m)
{
    QString rc;
    if (m & QFont::FamilyResolved)
        rc += QLatin1String("Family");
    if (m & QFont::SizeResolved)
        rc += QLatin1String("Size ");
    if (m & QFont::WeightResolved)
        rc += QLatin1String("Bold ");
    if (m & QFont::StyleResolved)
        rc += QLatin1String("Style ");
    if (m & QFont::UnderlineResolved)
        rc += QLatin1String("Underline ");
    if (m & QFont::StrikeOutResolved)
        rc += QLatin1String("StrikeOut ");
    if (m & QFont::KerningResolved)
        rc += QLatin1String("Kerning ");
    if (m & QFont::StyleStrategyResolved)
        rc += QLatin1String("StyleStrategy");
    return rc;
}

// Debug font
QString fontString(const QFont &f)
{
    QString rc; {
        const QChar comma = QLatin1Char(',');
        QTextStream str(&rc);
        str << QLatin1String("QFont(\"") <<  f.family() << comma <<
            f.pointSize();
        if (f.bold())
            str << comma <<  QLatin1String("bold");
        if (f.italic())
            str << comma <<  QLatin1String("italic");
        if (f.underline())
            str << comma <<  QLatin1String("underline");
        if (f.strikeOut())
            str << comma <<  QLatin1String("strikeOut");
        if (f.kerning())
            str << comma << QLatin1String("kerning");
        str <<  comma << f.styleStrategy() << QLatin1String(" resolve: ")
            << fontMask(f.resolve()) << QLatin1Char(')');
    }
    return rc;
}
QSize checkSize(const QSize &size)
{
    return size.boundedTo(QSize(0xFFFFFF, 0xFFFFFF));
}

QSize diffSize(QDesignerFormWindowInterface *fw)
{
    const QWidget *container = fw->core()->integration()->containerWindow(fw);
    if (!container)
        return QSize();

    const QSize diff = container->size() - fw->size(); // decoration offset of container window
    return diff;
}

void checkSizes(QDesignerFormWindowInterface *fw, const QSize &size, QSize *formSize, QSize *containerSize)
{
    const QWidget *container = fw->core()->integration()->containerWindow(fw);
    if (!container)
        return;

    const  QSize diff = diffSize(fw); // decoration offset of container window

    QSize newFormSize = checkSize(size).expandedTo(fw->mainContainer()->minimumSizeHint()); // don't try to resize to smaller size than minimumSizeHint
    QSize newContainerSize = newFormSize + diff;

    newContainerSize = newContainerSize.expandedTo(container->minimumSizeHint());
    newContainerSize = newContainerSize.expandedTo(container->minimumSize());

    newFormSize = newContainerSize - diff;

    newContainerSize = checkSize(newContainerSize);

    if (formSize)
        *formSize = newFormSize;
    if (containerSize)
        *containerSize = newContainerSize;
}

/* SubProperties: When applying a changed property to a multiselection, it sometimes makes
 * sense to apply only parts (subproperties) of the property.
 * For example, if someone changes the x-value of a geometry in the property editor
 * and applies it to a multi-selection, y should not be applied as this would cause all
 * the widgets to overlap.
 * The following routines can be used to find out the changed subproperties of a property,
 * which are represented as a mask, and to apply them while leaving the others intact. */

enum RectSubPropertyMask {  SubPropertyX=1, SubPropertyY = 2, SubPropertyWidth = 4, SubPropertyHeight = 8 };
enum SizePolicySubPropertyMask { SubPropertyHSizePolicy = 1, SubPropertyHStretch = 2, SubPropertyVSizePolicy = 4, SubPropertyVStretch = 8 };
enum AlignmentSubPropertyMask { SubPropertyHorizontalAlignment = 1, SubPropertyVerticalAlignment = 2 };
enum StringSubPropertyMask { SubPropertyStringValue = 1, SubPropertyStringComment = 2, SubPropertyStringTranslatable = 4, SubPropertyStringDisambiguation = 8 };
enum KeySequenceSubPropertyMask { SubPropertyKeySequenceValue = 1, SubPropertyKeySequenceComment = 2, SubPropertyKeySequenceTranslatable = 4, SubPropertyKeySequenceDisambiguation = 8 };

enum CommonSubPropertyMask { SubPropertyAll = 0xFFFFFFFF };

// Set the mask flag in mask if the properties do not match.
#define COMPARE_SUBPROPERTY(object1, object2, getter, mask, maskFlag) if (object1.getter() != object2.getter()) mask |= maskFlag;

// find changed subproperties of a rectangle
unsigned compareSubProperties(const QRect & r1, const QRect & r2)
{
    unsigned rc = 0;
    COMPARE_SUBPROPERTY(r1, r2, x, rc, SubPropertyX)
    COMPARE_SUBPROPERTY(r1, r2, y, rc, SubPropertyY)
    COMPARE_SUBPROPERTY(r1, r2, width, rc, SubPropertyWidth)
    COMPARE_SUBPROPERTY(r1, r2, height, rc, SubPropertyHeight)
    return rc;
}

// find changed subproperties of a QSize
unsigned compareSubProperties(const QSize & r1, const QSize & r2)
{
    unsigned rc = 0;
    COMPARE_SUBPROPERTY(r1, r2, width,  rc, SubPropertyWidth)
    COMPARE_SUBPROPERTY(r1, r2, height, rc, SubPropertyHeight)
    return rc;
}
// find changed subproperties of a QSizePolicy
unsigned compareSubProperties(const QSizePolicy & sp1, const QSizePolicy & sp2)
{
    unsigned rc = 0;
    COMPARE_SUBPROPERTY(sp1, sp2, horizontalPolicy,  rc, SubPropertyHSizePolicy)
    COMPARE_SUBPROPERTY(sp1, sp2, horizontalStretch, rc, SubPropertyHStretch)
    COMPARE_SUBPROPERTY(sp1, sp2, verticalPolicy,    rc, SubPropertyVSizePolicy)
    COMPARE_SUBPROPERTY(sp1, sp2, verticalStretch,   rc, SubPropertyVStretch)
    return rc;
}
// find changed subproperties of qdesigner_internal::PropertySheetStringValue
unsigned compareSubProperties(const qdesigner_internal::PropertySheetStringValue & str1, const qdesigner_internal::PropertySheetStringValue & str2)
{
    unsigned rc = 0;
    COMPARE_SUBPROPERTY(str1, str2, value,          rc, SubPropertyStringValue)
    COMPARE_SUBPROPERTY(str1, str2, comment,        rc, SubPropertyStringComment)
    COMPARE_SUBPROPERTY(str1, str2, translatable,   rc, SubPropertyStringTranslatable)
    COMPARE_SUBPROPERTY(str1, str2, disambiguation, rc, SubPropertyStringDisambiguation)
    return rc;
}
// find changed subproperties of qdesigner_internal::PropertySheetKeySequenceValue
unsigned compareSubProperties(const qdesigner_internal::PropertySheetKeySequenceValue & str1, const qdesigner_internal::PropertySheetKeySequenceValue & str2)
{
    unsigned rc = 0;
    COMPARE_SUBPROPERTY(str1, str2, value,          rc, SubPropertyKeySequenceValue)
    COMPARE_SUBPROPERTY(str1, str2, comment,        rc, SubPropertyKeySequenceComment)
    COMPARE_SUBPROPERTY(str1, str2, translatable,   rc, SubPropertyKeySequenceTranslatable)
    COMPARE_SUBPROPERTY(str1, str2, disambiguation, rc, SubPropertyKeySequenceDisambiguation)
    return rc;
}

// Compare font-subproperties taking the [undocumented]
// resolve flag into account
template <class Property>
void compareFontSubProperty(const QFont & f1,
                            const QFont & f2,
                            Property (QFont::*getter) () const,
                            unsigned maskBit,
                            unsigned &mask)
{
    const bool f1Changed = f1.resolve() & maskBit;
    const bool f2Changed = f2.resolve() & maskBit;
    // Role has been set/reset in editor
    if (f1Changed != f2Changed) {
        mask |= maskBit;
    } else {
        // Was modified in both palettes: Compare values.
        if (f1Changed && f2Changed && (f1.*getter)() != (f2.*getter)())
            mask |= maskBit;
    }
}
// find changed subproperties of a QFont
unsigned compareSubProperties(const QFont & f1, const QFont & f2)
{
    unsigned rc = 0;
    compareFontSubProperty(f1, f2, &QFont::family,        QFont::FamilyResolved, rc);
    compareFontSubProperty(f1, f2, &QFont::pointSize,     QFont::SizeResolved, rc);
    compareFontSubProperty(f1, f2, &QFont::bold,          QFont::WeightResolved, rc);
    compareFontSubProperty(f1, f2, &QFont::italic,        QFont::StyleResolved, rc);
    compareFontSubProperty(f1, f2, &QFont::underline,     QFont::UnderlineResolved, rc);
    compareFontSubProperty(f1, f2, &QFont::strikeOut,     QFont::StrikeOutResolved, rc);
    compareFontSubProperty(f1, f2, &QFont::kerning,       QFont::KerningResolved, rc);
    compareFontSubProperty(f1, f2, &QFont::styleStrategy, QFont::StyleStrategyResolved, rc);
    if (debugPropertyCommands)
        qDebug() << "compareSubProperties " <<  fontString(f1) << fontString(f2) << "\n\treturns " << fontMask(rc);
    return rc;
}

// Compare colors of a role
bool roleColorChanged(const QPalette & p1, const QPalette & p2, QPalette::ColorRole role)
{
    for (int group = QPalette::Active; group < QPalette::NColorGroups;  group++) {
        const QPalette::ColorGroup pgroup = static_cast<QPalette::ColorGroup>(group);
        if (p1.color(pgroup, role) != p2.color(pgroup, role))
            return true;
    }
    return false;
}
// find changed subproperties of a QPalette taking the [undocumented] resolve flags into account
unsigned compareSubProperties(const QPalette & p1, const QPalette & p2)
{
    unsigned rc = 0;
    unsigned maskBit = 1u;
    // generate a mask for each role
    const unsigned p1Changed = p1.resolve();
    const unsigned p2Changed = p2.resolve();
    for (int role = QPalette::WindowText;  role < QPalette::NColorRoles; role++, maskBit <<= 1u) {
        const bool p1RoleChanged = p1Changed & maskBit;
        const bool p2RoleChanged = p2Changed & maskBit;
        // Role has been set/reset in editor
        if (p1RoleChanged != p2RoleChanged) {
            rc |= maskBit;
        } else {
            // Was modified in both palettes: Compare values.
            if (p1RoleChanged && p2RoleChanged && roleColorChanged(p1, p2, static_cast<QPalette::ColorRole>(role)))
                rc |= maskBit;
        }
    }
    return rc;
}

// find changed subproperties of a QAlignment which is a flag combination of vertical and horizontal

unsigned compareSubProperties(Qt::Alignment a1, Qt::Alignment a2)
{
    unsigned rc = 0;
    if ((a1 & Qt::AlignHorizontal_Mask) != (a2 & Qt::AlignHorizontal_Mask))
        rc |= SubPropertyHorizontalAlignment;
    if ((a1 & Qt::AlignVertical_Mask) != (a2 & Qt::AlignVertical_Mask))
        rc |= SubPropertyVerticalAlignment;
    return rc;
}

Qt::Alignment variantToAlignment(const QVariant & q)
{
    return Qt::Alignment(qdesigner_internal::Utils::valueOf(q));
}
// find changed subproperties of a variant
unsigned compareSubProperties(const QVariant & q1, const QVariant & q2, qdesigner_internal::SpecialProperty specialProperty)
{
    // Do not clobber new value in the comparison function in
    // case someone sets a QString on a PropertySheetStringValue.
    if (q1.type() != q2.type())
        return SubPropertyAll;
    switch (q1.type()) {
    case QVariant::Rect:
        return compareSubProperties(q1.toRect(), q2.toRect());
    case QVariant::Size:
        return compareSubProperties(q1.toSize(), q2.toSize());
    case QVariant::SizePolicy:
        return compareSubProperties(qvariant_cast<QSizePolicy>(q1), qvariant_cast<QSizePolicy>(q2));
    case QVariant::Font:
        return compareSubProperties(qvariant_cast<QFont>(q1), qvariant_cast<QFont>(q2));
    case QVariant::Palette:
        return compareSubProperties(qvariant_cast<QPalette>(q1), qvariant_cast<QPalette>(q2));
    default:
        if (q1.userType() == qMetaTypeId<qdesigner_internal::PropertySheetIconValue>())
            return qvariant_cast<qdesigner_internal::PropertySheetIconValue>(q1).compare(qvariant_cast<qdesigner_internal::PropertySheetIconValue>(q2));
        else if (q1.userType() == qMetaTypeId<qdesigner_internal::PropertySheetStringValue>())
            return compareSubProperties(qvariant_cast<qdesigner_internal::PropertySheetStringValue>(q1), qvariant_cast<qdesigner_internal::PropertySheetStringValue>(q2));
        else if (q1.userType() == qMetaTypeId<qdesigner_internal::PropertySheetKeySequenceValue>())
            return compareSubProperties(qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(q1), qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(q2));
        // Enumerations, flags
        switch (specialProperty) {
        case qdesigner_internal::SP_Alignment:
            return compareSubProperties(variantToAlignment(q1), variantToAlignment(q2));
        default:
        break;
        }
        break;
    }
    return SubPropertyAll;
}

// Apply  the sub property if mask flag is set in mask
#define SET_SUBPROPERTY(rc, newValue, getter, setter, mask, maskFlag) if (mask & maskFlag) rc.setter(newValue.getter());

// apply changed subproperties to a rectangle
QRect applyRectSubProperty(const QRect &oldValue, const QRect &newValue, unsigned mask)
{
    QRect rc = oldValue;
    SET_SUBPROPERTY(rc, newValue, x,      moveLeft,  mask, SubPropertyX)
    SET_SUBPROPERTY(rc, newValue, y,      moveTop,   mask, SubPropertyY)
    SET_SUBPROPERTY(rc, newValue, width,  setWidth,  mask, SubPropertyWidth)
    SET_SUBPROPERTY(rc, newValue, height, setHeight, mask, SubPropertyHeight)
    return rc;
}


// apply changed subproperties to a rectangle QSize
QSize applySizeSubProperty(const QSize &oldValue, const QSize &newValue, unsigned mask)
{
    QSize rc = oldValue;
    SET_SUBPROPERTY(rc, newValue, width,  setWidth,  mask, SubPropertyWidth)
    SET_SUBPROPERTY(rc, newValue, height, setHeight, mask, SubPropertyHeight)
    return rc;
}


// apply changed subproperties to a SizePolicy
QSizePolicy applySizePolicySubProperty(const QSizePolicy &oldValue, const QSizePolicy &newValue, unsigned mask)
{
    QSizePolicy rc = oldValue;
    SET_SUBPROPERTY(rc, newValue, horizontalPolicy,  setHorizontalPolicy,  mask, SubPropertyHSizePolicy)
    SET_SUBPROPERTY(rc, newValue, horizontalStretch, setHorizontalStretch, mask, SubPropertyHStretch)
    SET_SUBPROPERTY(rc, newValue, verticalPolicy,    setVerticalPolicy,    mask, SubPropertyVSizePolicy)
    SET_SUBPROPERTY(rc, newValue, verticalStretch,   setVerticalStretch,   mask, SubPropertyVStretch)
    return rc;
}

// apply changed subproperties to a qdesigner_internal::PropertySheetStringValue
qdesigner_internal::PropertySheetStringValue applyStringSubProperty(const qdesigner_internal::PropertySheetStringValue &oldValue,
            const qdesigner_internal::PropertySheetStringValue &newValue, unsigned mask)
{
    qdesigner_internal::PropertySheetStringValue rc = oldValue;
    SET_SUBPROPERTY(rc, newValue, value, setValue, mask, SubPropertyStringValue)
    SET_SUBPROPERTY(rc, newValue, comment, setComment, mask, SubPropertyStringComment)
    SET_SUBPROPERTY(rc, newValue, translatable, setTranslatable, mask, SubPropertyStringTranslatable)
    SET_SUBPROPERTY(rc, newValue, disambiguation, setDisambiguation, mask, SubPropertyStringDisambiguation)
    return rc;
}

// apply changed subproperties to a qdesigner_internal::PropertySheetKeySequenceValue
qdesigner_internal::PropertySheetKeySequenceValue applyKeySequenceSubProperty(const qdesigner_internal::PropertySheetKeySequenceValue &oldValue,
            const qdesigner_internal::PropertySheetKeySequenceValue &newValue, unsigned mask)
{
    qdesigner_internal::PropertySheetKeySequenceValue rc = oldValue;
    SET_SUBPROPERTY(rc, newValue, value, setValue, mask, SubPropertyKeySequenceValue)
    SET_SUBPROPERTY(rc, newValue, comment, setComment, mask, SubPropertyKeySequenceComment)
    SET_SUBPROPERTY(rc, newValue, translatable, setTranslatable, mask, SubPropertyKeySequenceTranslatable)
    SET_SUBPROPERTY(rc, newValue, disambiguation, setDisambiguation, mask, SubPropertyKeySequenceDisambiguation)
    return rc;
}

// Apply the font-subproperties keeping the [undocumented]
// resolve flag in sync (note that PropertySetterType might be something like const T&).
template <class PropertyReturnType, class PropertySetterType>
inline void setFontSubProperty(unsigned mask,
                               const QFont &newValue,
                               unsigned maskBit,
                               PropertyReturnType (QFont::*getter) () const,
                               void (QFont::*setter) (PropertySetterType),
                               QFont &value)
{
    if (mask & maskBit) {
        (value.*setter)((newValue.*getter)());
        // Set the resolve bit from NewValue in return value
        uint r = value.resolve();
        const bool origFlag = newValue.resolve() & maskBit;
        if (origFlag)
            r |= maskBit;
        else
            r &= ~maskBit;
        value.resolve(r);
        if (debugPropertyCommands)
            qDebug() << "setFontSubProperty " <<  fontMask(maskBit) << " resolve=" << origFlag;
    }
}
// apply changed subproperties to a QFont
QFont applyFontSubProperty(const QFont &oldValue, const QFont &newValue, unsigned mask)
{
    QFont  rc = oldValue;
    setFontSubProperty(mask, newValue, QFont::FamilyResolved,        &QFont::family,        &QFont::setFamily, rc);
    setFontSubProperty(mask, newValue, QFont::SizeResolved,          &QFont::pointSize,     &QFont::setPointSize, rc);
    setFontSubProperty(mask, newValue, QFont::WeightResolved,        &QFont::bold,          &QFont::setBold, rc);
    setFontSubProperty(mask, newValue, QFont::StyleResolved,         &QFont::italic,        &QFont::setItalic, rc);
    setFontSubProperty(mask, newValue, QFont::UnderlineResolved,     &QFont::underline,     &QFont::setUnderline, rc);
    setFontSubProperty(mask, newValue, QFont::StrikeOutResolved,     &QFont::strikeOut,     &QFont::setStrikeOut, rc);
    setFontSubProperty(mask, newValue, QFont::KerningResolved,       &QFont::kerning,       &QFont::setKerning, rc);
    setFontSubProperty(mask, newValue, QFont::StyleStrategyResolved, &QFont::styleStrategy, &QFont::setStyleStrategy, rc);
    if (debugPropertyCommands)
        qDebug() << "applyFontSubProperty old " <<  fontMask(oldValue.resolve()) << " new " << fontMask(newValue.resolve()) << " return: " << fontMask(rc.resolve());
    return rc;
}

// apply changed subproperties to a QPalette
QPalette applyPaletteSubProperty(const QPalette &oldValue, const QPalette &newValue, unsigned mask)
{
    QPalette rc = oldValue;
    // apply a mask for each role
    unsigned maskBit = 1u;
    for (int role = QPalette::WindowText;  role < QPalette::NColorRoles; role++, maskBit <<= 1u) {
        if (mask & maskBit) {
            for (int group = QPalette::Active; group < QPalette::NColorGroups;  group++) {
                const QPalette::ColorGroup pgroup = static_cast<QPalette::ColorGroup>(group);
                const QPalette::ColorRole prole =  static_cast<QPalette::ColorRole>(role);
                rc.setColor(pgroup, prole, newValue.color(pgroup, prole));
            }
            // Set the resolve bit from NewValue in return value
            uint r = rc.resolve();
            const bool origFlag = newValue.resolve() & maskBit;
            if (origFlag)
                r |= maskBit;
            else
                r &= ~maskBit;
            rc.resolve(r);
        }
    }
    return rc;
}

// apply changed subproperties to  a QAlignment which is a flag combination of vertical and horizontal
Qt::Alignment applyAlignmentSubProperty(Qt::Alignment oldValue, Qt::Alignment newValue, unsigned mask)
{
    // easy: both changed.
    if (mask == (SubPropertyHorizontalAlignment|SubPropertyVerticalAlignment))
        return newValue;
    // Change subprop
    const Qt::Alignment changeMask   = (mask & SubPropertyHorizontalAlignment) ? Qt::AlignHorizontal_Mask : Qt::AlignVertical_Mask;
    const Qt::Alignment takeOverMask = (mask & SubPropertyHorizontalAlignment) ? Qt::AlignVertical_Mask   : Qt::AlignHorizontal_Mask;
    return (oldValue & takeOverMask) | (newValue & changeMask);
}

}

namespace qdesigner_internal {

// apply changed subproperties to a variant
PropertyHelper::Value applySubProperty(const QVariant &oldValue, const QVariant &newValue, qdesigner_internal::SpecialProperty specialProperty, unsigned mask, bool changed)
{
    if (mask == SubPropertyAll)
        return PropertyHelper::Value(newValue, changed);

    switch (oldValue.type()) {
    case QVariant::Rect:
        return PropertyHelper::Value(applyRectSubProperty(oldValue.toRect(), newValue.toRect(), mask), changed);
    case QVariant::Size:
        return PropertyHelper::Value(applySizeSubProperty(oldValue.toSize(), newValue.toSize(), mask), changed);
    case QVariant::SizePolicy:
        return PropertyHelper::Value(qVariantFromValue(applySizePolicySubProperty(qvariant_cast<QSizePolicy>(oldValue), qvariant_cast<QSizePolicy>(newValue), mask)), changed);
    case QVariant::Font: {
        // Changed flag in case of font and palette depends on resolve mask only, not on the passed "changed" value.

        // The first case: the user changed bold subproperty and then pressed reset button for this subproperty (not for
        // the whole font property). We instantiate SetPropertyCommand passing changed=true. But in this case no
        // subproperty is changed and the whole property should be marked an unchanged.

        // The second case: there are 2 pushbuttons, for 1st the user set bold and italic subproperties,
        // for the 2nd he set bold only. He does multiselection so that the current widget is the 2nd one.
        // He press reset next to bold subproperty. In result the 2nd widget should have the whole
        // font property marked as unchanged and the 1st widget should have the font property
        // marked as changed and only italic subproperty should be marked as changed (the bold should be reset).

        // The third case: there are 2 pushbuttons, for 1st the user set bold and italic subproperties,
        // for the 2nd he set bold only. He does multiselection so that the current widget is the 2nd one.
        // He press reset button for the whole font property. In result whole font properties for both
        // widgets should be marked as unchanged.
        QFont font = applyFontSubProperty(qvariant_cast<QFont>(oldValue), qvariant_cast<QFont>(newValue), mask);
        return PropertyHelper::Value(qVariantFromValue(font), font.resolve());
        }
    case QVariant::Palette: {
        QPalette palette = applyPaletteSubProperty(qvariant_cast<QPalette>(oldValue), qvariant_cast<QPalette>(newValue), mask);
        return PropertyHelper::Value(qVariantFromValue(palette), palette.resolve());
        }
    default:
        if (oldValue.userType() == qMetaTypeId<qdesigner_internal::PropertySheetIconValue>()) {
            PropertySheetIconValue icon = qvariant_cast<qdesigner_internal::PropertySheetIconValue>(oldValue);
            icon.assign(qvariant_cast<qdesigner_internal::PropertySheetIconValue>(newValue), mask);
            return PropertyHelper::Value(qVariantFromValue(icon), icon.mask());
        } else if (oldValue.userType() == qMetaTypeId<qdesigner_internal::PropertySheetStringValue>()) {
            qdesigner_internal::PropertySheetStringValue str = applyStringSubProperty(
                        qvariant_cast<qdesigner_internal::PropertySheetStringValue>(oldValue),
                        qvariant_cast<qdesigner_internal::PropertySheetStringValue>(newValue), mask);
            return PropertyHelper::Value(qVariantFromValue(str), changed);
        } else if (oldValue.userType() == qMetaTypeId<qdesigner_internal::PropertySheetKeySequenceValue>()) {
            qdesigner_internal::PropertySheetKeySequenceValue key = applyKeySequenceSubProperty(
                        qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(oldValue),
                        qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(newValue), mask);
            return PropertyHelper::Value(qVariantFromValue(key), changed);
        }
        // Enumerations, flags
        switch (specialProperty) {
        case qdesigner_internal::SP_Alignment: {
            qdesigner_internal::PropertySheetFlagValue f = qvariant_cast<qdesigner_internal::PropertySheetFlagValue>(oldValue);
            f.value = applyAlignmentSubProperty(variantToAlignment(oldValue), variantToAlignment(newValue), mask);
            QVariant v;
            qVariantSetValue(v, f);
            return PropertyHelper::Value(v, changed);
                                               }
        default:
        break;
        }
        break;
    }
    return PropertyHelper::Value(newValue, changed);

}
// figure out special property
enum SpecialProperty getSpecialProperty(const QString& propertyName)
{
    if (propertyName == QLatin1String("objectName"))
        return SP_ObjectName;
    if (propertyName == QLatin1String("layoutName"))
        return SP_LayoutName;
    if (propertyName == QLatin1String("spacerName"))
        return SP_SpacerName;
    if (propertyName == QLatin1String("icon"))
        return SP_Icon;
    if (propertyName == QLatin1String("currentTabName"))
        return SP_CurrentTabName;
    if (propertyName == QLatin1String("currentItemName"))
        return SP_CurrentItemName;
    if (propertyName == QLatin1String("currentPageName"))
        return SP_CurrentPageName;
    if (propertyName == QLatin1String("geometry"))
        return SP_Geometry;
    if (propertyName == QLatin1String("windowTitle"))
        return SP_WindowTitle;
    if (propertyName == QLatin1String("minimumSize"))
        return SP_MinimumSize;
    if (propertyName == QLatin1String("maximumSize"))
        return SP_MaximumSize;
    if (propertyName == QLatin1String("alignment"))
        return SP_Alignment;
    if (propertyName == QLatin1String("autoDefault"))
        return SP_AutoDefault;
    if (propertyName == QLatin1String("shortcut"))
        return SP_Shortcut;
    if (propertyName == QLatin1String("orientation"))
        return SP_Orientation;
    return SP_None;
}


PropertyHelper::PropertyHelper(QObject* object,
                               SpecialProperty specialProperty,
                               QDesignerPropertySheetExtension *sheet,
                               int index) :
    m_specialProperty(specialProperty),
    m_object(object),
    m_objectType(OT_Object),
    m_propertySheet(sheet),  m_index(index),
    m_oldValue(m_propertySheet->property(m_index), m_propertySheet->isChanged(m_index))
{
    if (object->isWidgetType()) {
        m_parentWidget = (qobject_cast<QWidget*>(object))->parentWidget();
        m_objectType = OT_Widget;
    } else {
        if (const QAction *action = qobject_cast<const QAction *>(m_object))
            m_objectType = action->associatedWidgets().empty() ? OT_FreeAction : OT_AssociatedAction;
    }

    if(debugPropertyCommands)
        qDebug() << "PropertyHelper on " << m_object->objectName() << " index= " << m_index << " type = " << m_objectType;
}

QDesignerIntegration *PropertyHelper::integration(QDesignerFormWindowInterface *fw) const
{
    return qobject_cast<QDesignerIntegration *>(fw->core()->integration());
}

// Set widget value, apply corrections and checks in case of main window.
void PropertyHelper::checkApplyWidgetValue(QDesignerFormWindowInterface *fw, QWidget* w,
                                      SpecialProperty specialProperty, QVariant &value)
{

    bool isMainContainer = false;
    if (QDesignerFormWindowCursorInterface *cursor = fw->cursor()) {
        if (cursor->isWidgetSelected(w)) {
            if (cursor->isWidgetSelected(fw->mainContainer())) {
                isMainContainer = true;
            }
        }
    }
    if (!isMainContainer)
        return;

    QWidget *container = fw->core()->integration()->containerWindow(fw);
    if (!container)
        return;


    switch (specialProperty) {
    case SP_MinimumSize: {
        const QSize size = checkSize(value.toSize());
        qVariantSetValue(value, size);
    }

        break;
    case SP_MaximumSize: {
        QSize fs, cs;
        checkSizes(fw, value.toSize(), &fs, &cs);
        container->setMaximumSize(cs);
        fw->mainContainer()->setMaximumSize(fs);
        qVariantSetValue(value, fs);

    }
        break;
    case SP_Geometry: {
        QRect r = value.toRect();
        QSize fs, cs;
        checkSizes(fw, r.size(), &fs, &cs);
        container->resize(cs);
        r.setSize(fs);
        qVariantSetValue(value, r);
    }
        break;
    default:
        break;
    }
}

unsigned PropertyHelper::updateMask() const
{
    unsigned rc = 0;
    switch (m_specialProperty) {
    case SP_ObjectName:
    case SP_LayoutName:
    case SP_SpacerName:
    case SP_CurrentTabName:
    case SP_CurrentItemName:
    case SP_CurrentPageName:
        if (m_objectType != OT_FreeAction)
            rc |= UpdateObjectInspector;
        break;
    case SP_Icon:
        if (m_objectType == OT_AssociatedAction)
            rc |= UpdateObjectInspector;
        break;
    case SP_Orientation: // for updating splitter icon
        rc |= UpdateObjectInspector;
        break;
    default:
        break;

    }
    return rc;
}


bool PropertyHelper::canMerge(const PropertyHelper &other) const
{
    return m_object == other.m_object &&  m_index == other.m_index;
}

void PropertyHelper::triggerActionChanged(QAction *a)
{
    a->setData(QVariant(true)); // this triggers signal "changed" in QAction
    a->setData(QVariant(false));
}

// Update the object to reflect the changes
void PropertyHelper::updateObject(QDesignerFormWindowInterface *fw, const QVariant &oldValue, const QVariant &newValue)
{
    if(debugPropertyCommands){
         qDebug() << "PropertyHelper::updateObject(" << m_object->objectName() << ") " << oldValue << " -> " << newValue;
    }
    switch (m_objectType) {
    case OT_Widget: {
        switch (m_specialProperty) {
        case SP_ObjectName: {
            const QString oldName = qVariantValue<PropertySheetStringValue>(oldValue).value();
            const QString newName = qVariantValue<PropertySheetStringValue>(newValue).value();
            QDesignerFormWindowCommand::updateBuddies(fw, oldName, newName);
        }
            break;
        default:
            break;
        }
    } break;
    case OT_AssociatedAction:
    case OT_FreeAction:
        // SP_Shortcut is a fake property, so, QAction::changed does not trigger.
        if (m_specialProperty == SP_ObjectName || m_specialProperty == SP_Shortcut)
            triggerActionChanged(qobject_cast<QAction *>(m_object));
        break;
    default:
        break;
    }

    switch (m_specialProperty) {
    case SP_ObjectName:
    case SP_LayoutName:
    case SP_SpacerName:
        if (QDesignerIntegration *integr = integration(fw)) {
            const QString oldName = qVariantValue<PropertySheetStringValue>(oldValue).value();
            const QString newName = qVariantValue<PropertySheetStringValue>(newValue).value();
            integr->emitObjectNameChanged(fw, m_object, newName, oldName);
        }
        break;
    default:
        break;
    }
}

void PropertyHelper::ensureUniqueObjectName(QDesignerFormWindowInterface *fw, QObject *object) const
{
    switch (m_specialProperty) {
    case SP_SpacerName:
        if (object->isWidgetType()) {
            if (Spacer *sp = qobject_cast<Spacer *>(object)) {
                fw->ensureUniqueObjectName(sp);
                return;
            }
        }
        fw->ensureUniqueObjectName(object);
        break;
    case SP_LayoutName: // Layout name is invoked on the parent widget.
        if (object->isWidgetType()) {
            const QWidget * w = qobject_cast<const QWidget *>(object);
            if (QLayout *wlayout = w->layout()) {
                fw->ensureUniqueObjectName(wlayout);
                return;
            }
        }
        fw->ensureUniqueObjectName(object);
        break;
    case SP_ObjectName:
        fw->ensureUniqueObjectName(object);
        break;
    default:
        break;
    }
}

PropertyHelper::Value PropertyHelper::setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask)
{
    // Set new whole value
    if (subPropertyMask == SubPropertyAll)
        return  applyValue(fw, m_oldValue.first, Value(value, changed));

    // apply subproperties
    const PropertyHelper::Value maskedNewValue = applySubProperty(m_oldValue.first, value, m_specialProperty, subPropertyMask, changed);
    return applyValue(fw, m_oldValue.first, maskedNewValue);
}

// Apply the value and update. Returns corrected value
PropertyHelper::Value PropertyHelper::applyValue(QDesignerFormWindowInterface *fw, const QVariant &oldValue, Value newValue)
{
     if(debugPropertyCommands){
         qDebug() << "PropertyHelper::applyValue(" << m_object << ") " << oldValue << " -> " << newValue.first << " changed=" << newValue.second;
     }

    if (m_objectType ==  OT_Widget) {
        checkApplyWidgetValue(fw, qobject_cast<QWidget *>(m_object), m_specialProperty, newValue.first);
    }

    m_propertySheet->setProperty(m_index, newValue.first);
    m_propertySheet->setChanged(m_index, newValue.second);

    switch (m_specialProperty) {
    case SP_LayoutName:
    case SP_ObjectName:
    case SP_SpacerName:
        ensureUniqueObjectName(fw, m_object);
        newValue.first = m_propertySheet->property(m_index);
        break;
    default:
        break;
    }

    updateObject(fw, oldValue, newValue.first);
    return newValue;
}

PropertyHelper::Value PropertyHelper::restoreOldValue(QDesignerFormWindowInterface *fw)
{
    return applyValue(fw, m_propertySheet->property(m_index), m_oldValue);
}

// find the default value in widget DB in case PropertySheet::reset fails
QVariant PropertyHelper::findDefaultValue(QDesignerFormWindowInterface *fw) const
{
    if (m_specialProperty == SP_AutoDefault && qobject_cast<const QPushButton*>(m_object)) {
        // AutoDefault defaults to true on dialogs
        const bool isDialog = qobject_cast<const QDialog *>(fw->mainContainer());
        return QVariant(isDialog);
    }

    const int item_idx = fw->core()->widgetDataBase()->indexOfObject(m_object);
    if (item_idx == -1)
        return  m_oldValue.first; // We simply don't know the value in this case

    const QDesignerWidgetDataBaseItemInterface *item = fw->core()->widgetDataBase()->item(item_idx);
    const QList<QVariant> default_prop_values = item->defaultPropertyValues();
    if (m_index < default_prop_values.size())
        return default_prop_values.at(m_index);

    if (m_oldValue.first.type() == QVariant::Color)
        return QColor();

    return m_oldValue.first; // Again, we just don't know
}

PropertyHelper::Value PropertyHelper::restoreDefaultValue(QDesignerFormWindowInterface *fw)
{

    Value defaultValue = qMakePair(QVariant(), false);
    const QVariant currentValue = m_propertySheet->property(m_index);
    // try to reset sheet, else try to find default
    if (m_propertySheet->reset(m_index)) {
        defaultValue.first = m_propertySheet->property(m_index);
    } else {
        defaultValue.first = findDefaultValue(fw);
        m_propertySheet->setProperty(m_index, defaultValue.first);
    }

    m_propertySheet->setChanged(m_index, defaultValue.second);

    if (m_objectType == OT_Widget) {
        checkApplyWidgetValue(fw, qobject_cast<QWidget *>(m_object), m_specialProperty, defaultValue.first);
    }

    switch (m_specialProperty) {
    case SP_LayoutName:
    case SP_ObjectName:
    case SP_SpacerName:
        ensureUniqueObjectName(fw, m_object);
        defaultValue.first = m_propertySheet->property(m_index);
        break;
    default:
        break;
    }

    updateObject(fw, currentValue, defaultValue.first);
    return defaultValue;
}

// ---- PropertyListCommand::PropertyDescription(


PropertyListCommand::PropertyDescription::PropertyDescription(const QString &propertyName,
                                                              QDesignerPropertySheetExtension *propertySheet,
                                                              int index) :
    m_propertyName(propertyName),
    m_propertyGroup(propertySheet->propertyGroup(index)),
    m_propertyType(propertySheet->property(index).type()),
    m_specialProperty(getSpecialProperty(propertyName))
{
}

PropertyListCommand::PropertyDescription::PropertyDescription() :
    m_propertyType(QVariant::Invalid),
    m_specialProperty(SP_None)
{
}

void PropertyListCommand::PropertyDescription::debug() const
{
    qDebug() << m_propertyName << m_propertyGroup << m_propertyType << m_specialProperty;
}

bool PropertyListCommand::PropertyDescription::equals(const PropertyDescription &p) const
{
    return m_propertyType == p.m_propertyType && m_specialProperty == p.m_specialProperty &&
           m_propertyName == p.m_propertyName && m_propertyGroup   == p.m_propertyGroup;
}


// ---- PropertyListCommand
PropertyListCommand::PropertyListCommand(QDesignerFormWindowInterface *formWindow,
                                         QUndoCommand *parent) :
    QDesignerFormWindowCommand(QString(), formWindow, parent)
{
}

const QString PropertyListCommand::propertyName() const
{
    return m_propertyDescription.m_propertyName;
}

SpecialProperty PropertyListCommand::specialProperty() const
{
    return m_propertyDescription.m_specialProperty;
}

// add an object
bool PropertyListCommand::add(QObject *object, const QString &propertyName)
{
    QDesignerPropertySheetExtension* sheet = propertySheet(object);
    Q_ASSERT(sheet);

    const int index = sheet->indexOf(propertyName);
    if (index == -1)
        return false;

    if (QDesignerPropertySheet *exSheet = qobject_cast<QDesignerPropertySheet*>(core()->extensionManager()->extension(object, Q_TYPEID(QDesignerPropertySheetExtension))))
        if (!exSheet->isEnabled(index))
            return false;

    const PropertyDescription description(propertyName, sheet, index);

    if (m_propertyHelperList.empty()) {
        // first entry
        m_propertyDescription = description;
    } else {
        // checks: mismatch or only one object in case of name
        const bool match = m_propertyDescription.equals(description);
        if (!match || m_propertyDescription.m_specialProperty == SP_ObjectName)
            return false;
    }

    const PropertyHelperPtr ph(createPropertyHelper(object, m_propertyDescription.m_specialProperty, sheet, index));
    m_propertyHelperList.push_back(ph);
    return true;
}

PropertyHelper *PropertyListCommand::createPropertyHelper(QObject *object, SpecialProperty sp,
                                                          QDesignerPropertySheetExtension *sheet, int sheetIndex) const
{
    return new PropertyHelper(object, sp, sheet, sheetIndex);
}

// Init from a list and make sure referenceObject is added first to obtain the right property group
bool PropertyListCommand::initList(const ObjectList &list, const QString &apropertyName, QObject *referenceObject)
{
    propertyHelperList().clear();

    // Ensure the referenceObject (property editor) is first, so the right property group is chosen.
    if (referenceObject) {
        if (!add(referenceObject, apropertyName))
            return false;
    }
    foreach (QObject *o, list) {
        if (o != referenceObject)
            add(o, apropertyName);
    }

    return !propertyHelperList().empty();
}


QObject* PropertyListCommand::object(int index) const
{
    Q_ASSERT(index < m_propertyHelperList.size());
    return m_propertyHelperList.at(index)->object();
}

QVariant PropertyListCommand::oldValue(int index) const
{
    Q_ASSERT(index < m_propertyHelperList.size());
    return m_propertyHelperList.at(index)->oldValue();
}

void PropertyListCommand::setOldValue(const QVariant &oldValue, int index)
{
    Q_ASSERT(index < m_propertyHelperList.size());
    m_propertyHelperList.at(index)->setOldValue(oldValue);
}
// ----- SetValueFunction: Set a new value when applied to a PropertyHelper.
class SetValueFunction {
public:
    SetValueFunction(QDesignerFormWindowInterface *formWindow, const PropertyHelper::Value &newValue, unsigned subPropertyMask);

    PropertyHelper::Value operator()(PropertyHelper&);
private:
    QDesignerFormWindowInterface *m_formWindow;
    const PropertyHelper::Value m_newValue;
    const unsigned m_subPropertyMask;
};


SetValueFunction::SetValueFunction(QDesignerFormWindowInterface *formWindow, const PropertyHelper::Value &newValue, unsigned subPropertyMask) :
    m_formWindow(formWindow),
    m_newValue(newValue),
    m_subPropertyMask(subPropertyMask)
{
}

PropertyHelper::Value SetValueFunction::operator()(PropertyHelper &ph) {
        return ph.setValue(m_formWindow, m_newValue.first, m_newValue.second, m_subPropertyMask);
}

// ----- UndoSetValueFunction: Restore old value when applied to a PropertyHelper.
class UndoSetValueFunction {
public:
    UndoSetValueFunction(QDesignerFormWindowInterface *formWindow) : m_formWindow(formWindow) {}
    PropertyHelper::Value operator()(PropertyHelper& ph) { return ph.restoreOldValue(m_formWindow); }
private:
    QDesignerFormWindowInterface *m_formWindow;
};

// ----- RestoreDefaultFunction: Restore default value when applied to a PropertyHelper.
class RestoreDefaultFunction {
public:
    RestoreDefaultFunction(QDesignerFormWindowInterface *formWindow) : m_formWindow(formWindow) {}
    PropertyHelper::Value operator()(PropertyHelper& ph) { return ph.restoreDefaultValue(m_formWindow); }
private:
    QDesignerFormWindowInterface *m_formWindow;
};

// ----- changePropertyList: Iterates over a sequence of PropertyHelpers and
// applies a function to them.
// The function returns the  corrected value which is then set in  the property editor.
// Returns a combination of update flags.
template <class PropertyListIterator, class Function>
        unsigned changePropertyList(QDesignerFormEditorInterface *core,
                                    const QString &propertyName,
                                    PropertyListIterator begin,
                                    PropertyListIterator end,
                                    Function function)
{
    unsigned updateMask = 0;
    QDesignerPropertyEditorInterface *propertyEditor = core->propertyEditor();
    bool updatedPropertyEditor = false;

    for (PropertyListIterator it = begin; it != end; ++it) {
        PropertyHelper *ph = it->data();
        if (QObject* object = ph->object()) { // Might have been deleted in the meantime
            const PropertyHelper::Value newValue = function( *ph );
            updateMask |= ph->updateMask();
            // Update property editor if it is the current object
            if (!updatedPropertyEditor && propertyEditor && object == propertyEditor->object()) {
                propertyEditor->setPropertyValue(propertyName, newValue.first,  newValue.second);
                updatedPropertyEditor = true;
            }
        }
    }
    if (!updatedPropertyEditor) updateMask |=  PropertyHelper::UpdatePropertyEditor;
    return updateMask;
}


// set a new value, return update mask
unsigned PropertyListCommand::setValue(QVariant value, bool changed, unsigned subPropertyMask)
{
    if(debugPropertyCommands)
        qDebug() << "PropertyListCommand::setValue(" << value
                 << changed << subPropertyMask << ')';
    return changePropertyList(formWindow()->core(),
                              m_propertyDescription.m_propertyName,
                              m_propertyHelperList.begin(), m_propertyHelperList.end(),
                              SetValueFunction(formWindow(), PropertyHelper::Value(value, changed), subPropertyMask));
}

// restore old value,  return update mask
unsigned PropertyListCommand::restoreOldValue()
{
    if(debugPropertyCommands)
        qDebug() << "PropertyListCommand::restoreOldValue()";

    return changePropertyList(formWindow()->core(),
                              m_propertyDescription.m_propertyName, m_propertyHelperList.begin(), m_propertyHelperList.end(),
                              UndoSetValueFunction(formWindow()));
}
// set default value,  return update mask
unsigned PropertyListCommand::restoreDefaultValue()
{
    if(debugPropertyCommands)
        qDebug() << "PropertyListCommand::restoreDefaultValue()";

    return changePropertyList(formWindow()->core(),
                              m_propertyDescription.m_propertyName, m_propertyHelperList.begin(), m_propertyHelperList.end(),
                              RestoreDefaultFunction(formWindow()));
}

// update
void PropertyListCommand::update(unsigned updateMask)
{
    if(debugPropertyCommands)
        qDebug() << "PropertyListCommand::update(" << updateMask << ')';

    if (updateMask & PropertyHelper::UpdateObjectInspector) {
        if (QDesignerObjectInspectorInterface *oi = formWindow()->core()->objectInspector())
            oi->setFormWindow(formWindow());
    }

    if (updateMask & PropertyHelper::UpdatePropertyEditor) {
        // this is needed when f.ex. undo, changes parent's palette, but
        // the child is the active widget,
        // TODO: current object?
        if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
            propertyEditor->setObject(propertyEditor->object());
        }
    }
}

void PropertyListCommand::undo()
{
    update(restoreOldValue());
    QDesignerPropertyEditor *designerPropertyEditor = qobject_cast<QDesignerPropertyEditor *>(core()->propertyEditor());
    if (designerPropertyEditor)
        designerPropertyEditor->updatePropertySheet();
}

// check if lists are aequivalent for command merging (same widgets and props)
bool PropertyListCommand::canMergeLists(const PropertyHelperList& other) const
{
    if (m_propertyHelperList.size() !=  other.size())
        return false;
    for (int i = 0; i < m_propertyHelperList.size(); i++) {
        if (!m_propertyHelperList.at(i)->canMerge(*other.at(i)))
            return false;
    }
    return true;
}

// ---- SetPropertyCommand ----
SetPropertyCommand::SetPropertyCommand(QDesignerFormWindowInterface *formWindow,
                                       QUndoCommand *parent)
    :  PropertyListCommand(formWindow, parent),
       m_subPropertyMask(SubPropertyAll)
{
}

bool SetPropertyCommand::init(QObject *object, const QString &apropertyName, const QVariant &newValue)
{
    Q_ASSERT(object);

    m_newValue = newValue;

    propertyHelperList().clear();
    if (!add(object, apropertyName))
        return false;

    setDescription();
    return true;
}

bool SetPropertyCommand::init(const ObjectList &list, const QString &apropertyName, const QVariant &newValue,
                              QObject *referenceObject, bool enableSubPropertyHandling)
{
    if (!initList(list, apropertyName, referenceObject))
        return false;

    m_newValue = newValue;

    if(debugPropertyCommands)
        qDebug() << "SetPropertyCommand::init()" << propertyHelperList().size() << '/' << list.size() << " reference " << referenceObject;

    setDescription();

    if (enableSubPropertyHandling)
        m_subPropertyMask = subPropertyMask(newValue, referenceObject);
    return true;
}

unsigned SetPropertyCommand::subPropertyMask(const QVariant &newValue, QObject *referenceObject)
{
    // figure out the mask of changed sub properties when comparing newValue to the current value of the reference object.
    if (!referenceObject)
        return SubPropertyAll;

    QDesignerPropertySheetExtension* sheet = propertySheet(referenceObject);
    Q_ASSERT(sheet);

    const int index = sheet->indexOf(propertyName());
    if (index == -1 || !sheet->isVisible(index))
        return SubPropertyAll;

    return compareSubProperties(sheet->property(index), newValue, specialProperty());
}

void SetPropertyCommand::setDescription()
{
    if (propertyHelperList().size() == 1) {
        setText(QApplication::translate("Command", "Changed '%1' of '%2'").arg(propertyName()).arg(propertyHelperList().at(0)->object()->objectName()));
    } else {
        int count = propertyHelperList().size();
        setText(QApplication::translate("Command", "Changed '%1' of %n objects", "", QCoreApplication::UnicodeUTF8, count).arg(propertyName()));
    }
}

void SetPropertyCommand::redo()
{
    update(setValue(m_newValue, true, m_subPropertyMask));
    QDesignerPropertyEditor *designerPropertyEditor = qobject_cast<QDesignerPropertyEditor *>(core()->propertyEditor());
    if (designerPropertyEditor)
        designerPropertyEditor->updatePropertySheet();
}


int SetPropertyCommand::id() const
{
    return 1976;
}

QVariant SetPropertyCommand::mergeValue(const QVariant &newValue)
{
    return newValue;
}

bool SetPropertyCommand::mergeWith(const QUndoCommand *other)
{
    if (id() != other->id() || !formWindow()->isDirty())
        return false;

    // Merging: When  for example when the user types ahead in an inplace-editor,
    // it makes sense to merge all the generated commands containing the one-character changes.
    // In the case of subproperties, if the user changes the font size from 10 to 30 via 20
    // and then changes to bold, it makes sense to merge the font size commands only.
    // This is why the m_subPropertyMask is checked.

    const SetPropertyCommand *cmd = static_cast<const SetPropertyCommand*>(other);
    if (!propertyDescription().equals(cmd->propertyDescription()) ||
        m_subPropertyMask  != cmd->m_subPropertyMask ||
        !canMergeLists(cmd->propertyHelperList()))
        return false;

    const QVariant newValue = mergeValue(cmd->newValue());
    if (!newValue.isValid())
        return false;
    m_newValue = newValue;
    m_subPropertyMask |= cmd->m_subPropertyMask;
    if(debugPropertyCommands)
        qDebug() << "SetPropertyCommand::mergeWith() succeeded " << propertyName();

    return true;
}

// ---- ResetPropertyCommand ----
ResetPropertyCommand::ResetPropertyCommand(QDesignerFormWindowInterface *formWindow)
    : PropertyListCommand(formWindow)
{
}

bool ResetPropertyCommand::init(QObject *object, const QString &apropertyName)
{
    Q_ASSERT(object);

    propertyHelperList().clear();
    if (!add(object, apropertyName))
        return false;

    setDescription();
    return true;
}

bool ResetPropertyCommand::init(const ObjectList &list, const QString &apropertyName, QObject *referenceObject)
{
    if (!initList(list, apropertyName, referenceObject))
        return false;

    if(debugPropertyCommands)
        qDebug() << "ResetPropertyCommand::init()" << propertyHelperList().size() << '/' << list.size();

    setDescription();
    return true;
}

void ResetPropertyCommand::setDescription()
{
    if (propertyHelperList().size() == 1) {
        setText(QApplication::translate("Command", "Reset '%1' of '%2'").arg(propertyName()).arg(propertyHelperList().at(0)->object()->objectName()));
    } else {
        int count = propertyHelperList().size();
        setText(QApplication::translate("Command", "Reset '%1' of %n objects", "", QCoreApplication::UnicodeUTF8, count).arg(propertyName()));
    }
}

void ResetPropertyCommand::redo()
{
    update(restoreDefaultValue());
    QDesignerPropertyEditor *designerPropertyEditor = qobject_cast<QDesignerPropertyEditor *>(core()->propertyEditor());
    if (designerPropertyEditor)
        designerPropertyEditor->updatePropertySheet();
}

AddDynamicPropertyCommand::AddDynamicPropertyCommand(QDesignerFormWindowInterface *formWindow)
    : QDesignerFormWindowCommand(QString(), formWindow)
{

}

bool AddDynamicPropertyCommand::init(const QList<QObject *> &selection, QObject *current,
            const QString &propertyName, const QVariant &value)
{
    Q_ASSERT(current);
    m_propertyName = propertyName;

    QDesignerFormEditorInterface *core = formWindow()->core();
    QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), current);
    Q_ASSERT(dynamicSheet);

    m_selection.clear();

    if (!value.isValid())
        return false;

    if (!dynamicSheet->canAddDynamicProperty(m_propertyName))
        return false;

    m_selection.append(current);

    m_value = value;

    QListIterator<QObject *> it(selection);
    while (it.hasNext()) {
        QObject *obj = it.next();
        if (m_selection.contains(obj))
            continue;
        dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
        Q_ASSERT(dynamicSheet);
        if (dynamicSheet->canAddDynamicProperty(m_propertyName))
            m_selection.append(obj);
    }

    setDescription();
    return true;
}

void AddDynamicPropertyCommand::redo()
{
    QDesignerFormEditorInterface *core = formWindow()->core();
    QListIterator<QObject *> it(m_selection);
    while (it.hasNext()) {
        QObject *obj = it.next();
        QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
        dynamicSheet->addDynamicProperty(m_propertyName, m_value);
        if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
            if (propertyEditor->object() == obj)
                propertyEditor->setObject(obj);
        }
    }
}

void AddDynamicPropertyCommand::undo()
{
    QDesignerFormEditorInterface *core = formWindow()->core();
    QListIterator<QObject *> it(m_selection);
    while (it.hasNext()) {
        QObject *obj = it.next();
        QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), obj);
        QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
        dynamicSheet->removeDynamicProperty(sheet->indexOf(m_propertyName));
        if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
            if (propertyEditor->object() == obj)
                propertyEditor->setObject(obj);
        }
    }
}

void AddDynamicPropertyCommand::setDescription()
{
    if (m_selection.size() == 1) {
        setText(QApplication::translate("Command", "Add dynamic property '%1' to '%2'").arg(m_propertyName).arg(m_selection.first()->objectName()));
    } else {
        int count = m_selection.size();
        setText(QApplication::translate("Command", "Add dynamic property '%1' to %n objects", "", QCoreApplication::UnicodeUTF8, count).arg(m_propertyName));
    }
}


RemoveDynamicPropertyCommand::RemoveDynamicPropertyCommand(QDesignerFormWindowInterface *formWindow)
    : QDesignerFormWindowCommand(QString(), formWindow)
{

}

bool RemoveDynamicPropertyCommand::init(const QList<QObject *> &selection, QObject *current,
            const QString &propertyName)
{
    Q_ASSERT(current);
    m_propertyName = propertyName;

    QDesignerFormEditorInterface *core = formWindow()->core();
    QDesignerPropertySheetExtension *propertySheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), current);
    Q_ASSERT(propertySheet);
    QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), current);
    Q_ASSERT(dynamicSheet);

    m_objectToValueAndChanged.clear();

    const int index = propertySheet->indexOf(m_propertyName);
    if (!dynamicSheet->isDynamicProperty(index))
        return false;

    m_objectToValueAndChanged[current] = qMakePair(propertySheet->property(index), propertySheet->isChanged(index));

    QListIterator<QObject *> it(selection);
    while (it.hasNext()) {
        QObject *obj = it.next();
        if (m_objectToValueAndChanged.contains(obj))
            continue;

        propertySheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), obj);
        dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
        const int idx = propertySheet->indexOf(m_propertyName);
        if (dynamicSheet->isDynamicProperty(idx))
            m_objectToValueAndChanged[obj] = qMakePair(propertySheet->property(idx), propertySheet->isChanged(idx));
    }

    setDescription();
    return true;
}

void RemoveDynamicPropertyCommand::redo()
{
    QDesignerFormEditorInterface *core = formWindow()->core();
    QMap<QObject *, QPair<QVariant, bool> >::ConstIterator it = m_objectToValueAndChanged.constBegin();
    while (it != m_objectToValueAndChanged.constEnd()) {
        QObject *obj = it.key();
        QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
        QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), obj);
        dynamicSheet->removeDynamicProperty(sheet->indexOf(m_propertyName));
        if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
            if (propertyEditor->object() == obj)
                propertyEditor->setObject(obj);
        }
        ++it;
    }
}

void RemoveDynamicPropertyCommand::undo()
{
    QDesignerFormEditorInterface *core = formWindow()->core();
    QMap<QObject *, QPair<QVariant, bool> >::ConstIterator it = m_objectToValueAndChanged.constBegin();
    while (it != m_objectToValueAndChanged.constEnd()) {
        QObject *obj = it.key();
        QDesignerPropertySheetExtension *propertySheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), obj);
        QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
        const int index = dynamicSheet->addDynamicProperty(m_propertyName, it.value().first);
        propertySheet->setChanged(index, it.value().second);
        if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
            if (propertyEditor->object() == obj)
                propertyEditor->setObject(obj);
        }
        ++it;
    }
}

void RemoveDynamicPropertyCommand::setDescription()
{
    if (m_objectToValueAndChanged.size() == 1) {
        setText(QApplication::translate("Command", "Remove dynamic property '%1' from '%2'").arg(m_propertyName).arg(m_objectToValueAndChanged.constBegin().key()->objectName()));
    } else {
        int count = m_objectToValueAndChanged.size();
        setText(QApplication::translate("Command", "Remove dynamic property '%1' from %n objects", "", QCoreApplication::UnicodeUTF8, count).arg(m_propertyName));
    }
}


} // namespace qdesigner_internal

QT_END_NAMESPACE
