tools/designer/src/lib/shared/qdesigner_propertysheet.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Designer of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qdesigner_propertysheet_p.h"
       
    43 #include "qdesigner_utils_p.h"
       
    44 #include "formwindowbase_p.h"
       
    45 #include "layoutinfo_p.h"
       
    46 #include "qlayout_widget_p.h"
       
    47 #include "qdesigner_introspection_p.h"
       
    48 
       
    49 #include <formbuilderextra_p.h>
       
    50 
       
    51 #include <QtDesigner/QDesignerFormWindowInterface>
       
    52 #include <QtDesigner/QDesignerFormEditorInterface>
       
    53 #include <QtDesigner/QDesignerWidgetDataBaseInterface>
       
    54 
       
    55 #include <QtCore/QDebug>
       
    56 
       
    57 #include <QtGui/QLayout>
       
    58 #include <QtGui/QDockWidget>
       
    59 #include <QtGui/QDialog>
       
    60 #include <QtGui/QLabel>
       
    61 #include <QtGui/QGroupBox>
       
    62 #include <QtGui/QStyle>
       
    63 #include <QtGui/QApplication>
       
    64 #include <QtGui/QToolBar>
       
    65 #include <QtGui/QMainWindow>
       
    66 #include <QtGui/QMenuBar>
       
    67 
       
    68 QT_BEGIN_NAMESPACE
       
    69 
       
    70 #define USE_LAYOUT_SIZE_CONSTRAINT
       
    71 
       
    72 static const QDesignerMetaObjectInterface *propertyIntroducedBy(const QDesignerMetaObjectInterface *meta, int index)
       
    73 {
       
    74     if (index >= meta->propertyOffset())
       
    75         return meta;
       
    76 
       
    77     if (meta->superClass())
       
    78         return propertyIntroducedBy(meta->superClass(), index);
       
    79 
       
    80     return 0;
       
    81 }
       
    82 
       
    83 // Layout fake properties (prefixed by 'layout' to distinguish them from other 'margins'
       
    84 // that might be around. These are forwarded to the layout sheet (after name transformation).
       
    85 //
       
    86 // 'layoutObjectName' is new for 4.4. It is the name of the actual layout.
       
    87 // Up to 4.3, QLayoutWidget's name was displayed in the objectinspector.
       
    88 // This changes with 4.4; the layout name is displayed. This means that for
       
    89 // old forms, QLayoutWidget will show up as ''; however, the uic code will
       
    90 // still use 'verticalLayout' (in case someone accesses it). New Layouts get autogenerated names,
       
    91 // legacy forms will keep their empty names (unless someone types in a new name).
       
    92 static const char *layoutObjectNameC = "layoutName";
       
    93 static const char *layoutLeftMarginC = "layoutLeftMargin";
       
    94 static const char *layoutTopMarginC = "layoutTopMargin";
       
    95 static const char *layoutRightMarginC = "layoutRightMargin";
       
    96 static const char *layoutBottomMarginC = "layoutBottomMargin";
       
    97 static const char *layoutSpacingC = "layoutSpacing";
       
    98 static const char *layoutHorizontalSpacingC = "layoutHorizontalSpacing";
       
    99 static const char *layoutVerticalSpacingC = "layoutVerticalSpacing";
       
   100 static const char *layoutSizeConstraintC = "layoutSizeConstraint";
       
   101 // form layout
       
   102 static const char *layoutFieldGrowthPolicyC = "layoutFieldGrowthPolicy";
       
   103 static const char *layoutRowWrapPolicyC = "layoutRowWrapPolicy";
       
   104 static const char *layoutLabelAlignmentC = "layoutLabelAlignment";
       
   105 static const char *layoutFormAlignmentC = "layoutFormAlignment";
       
   106 // stretches
       
   107 static const char *layoutboxStretchPropertyC = "layoutStretch";
       
   108 static const char *layoutGridRowStretchPropertyC = "layoutRowStretch";
       
   109 static const char *layoutGridColumnStretchPropertyC = "layoutColumnStretch";
       
   110 static const char *layoutGridRowMinimumHeightC = "layoutRowMinimumHeight";
       
   111 static const char *layoutGridColumnMinimumWidthC = "layoutColumnMinimumWidth";
       
   112 
       
   113 // Find the form editor in the hierarchy.
       
   114 // We know that the parent of the sheet is the extension manager
       
   115 // whose parent is the core.
       
   116 
       
   117 static QDesignerFormEditorInterface *formEditorForObject(QObject *o) {
       
   118     do {
       
   119         if (QDesignerFormEditorInterface* core = qobject_cast<QDesignerFormEditorInterface*>(o))
       
   120             return core;
       
   121         o = o->parent();
       
   122     } while(o);
       
   123     Q_ASSERT(o);
       
   124     return 0;
       
   125 }
       
   126 
       
   127 static bool hasLayoutAttributes(QDesignerFormEditorInterface *core, QObject *object)
       
   128 {
       
   129     if (!object->isWidgetType())
       
   130         return false;
       
   131 
       
   132     QWidget *w =  qobject_cast<QWidget *>(object);
       
   133     if (const QDesignerWidgetDataBaseInterface *db = core->widgetDataBase()) {
       
   134         if (db->isContainer(w))
       
   135             return true;
       
   136     }
       
   137     return false;
       
   138 }
       
   139 
       
   140 // Cache DesignerMetaEnum by scope/name of a  QMetaEnum
       
   141 static const qdesigner_internal::DesignerMetaEnum &designerMetaEnumFor(const QDesignerMetaEnumInterface *me)
       
   142 {
       
   143     typedef QPair<QString, QString> ScopeNameKey;
       
   144     typedef QMap<ScopeNameKey, qdesigner_internal::DesignerMetaEnum> DesignerMetaEnumCache;
       
   145     static DesignerMetaEnumCache cache;
       
   146 
       
   147     const QString name = me->name();
       
   148     const QString scope = me->scope();
       
   149 
       
   150     const ScopeNameKey key = ScopeNameKey(scope, name);
       
   151     DesignerMetaEnumCache::iterator it = cache.find(key);
       
   152     if (it == cache.end()) {
       
   153         qdesigner_internal::DesignerMetaEnum dme = qdesigner_internal::DesignerMetaEnum(name, scope, me->separator());
       
   154         const int keyCount = me->keyCount();
       
   155         for (int i=0; i < keyCount; ++i)
       
   156             dme.addKey(me->value(i), me->key(i));
       
   157         it = cache.insert(key, dme);
       
   158     }
       
   159     return it.value();
       
   160 }
       
   161 
       
   162 // Cache DesignerMetaFlags by scope/name of a  QMetaEnum
       
   163 static const qdesigner_internal::DesignerMetaFlags &designerMetaFlagsFor(const QDesignerMetaEnumInterface *me)
       
   164 {
       
   165     typedef QPair<QString, QString> ScopeNameKey;
       
   166     typedef QMap<ScopeNameKey, qdesigner_internal::DesignerMetaFlags> DesignerMetaFlagsCache;
       
   167     static DesignerMetaFlagsCache cache;
       
   168 
       
   169     const QString name = me->name();
       
   170     const QString scope = me->scope();
       
   171 
       
   172     const ScopeNameKey key = ScopeNameKey(scope, name);
       
   173     DesignerMetaFlagsCache::iterator it = cache.find(key);
       
   174     if (it == cache.end()) {
       
   175         qdesigner_internal::DesignerMetaFlags dme = qdesigner_internal::DesignerMetaFlags(name, scope, me->separator());
       
   176         const int keyCount = me->keyCount();
       
   177         for (int i=0; i < keyCount; ++i)
       
   178             dme.addKey(me->value(i), me->key(i));
       
   179         it = cache.insert(key, dme);
       
   180     }
       
   181     return it.value();
       
   182 }
       
   183 
       
   184 // ------------ QDesignerMemberSheetPrivate
       
   185 class QDesignerPropertySheetPrivate {
       
   186 public:
       
   187     typedef QDesignerPropertySheet::PropertyType PropertyType;
       
   188     typedef QDesignerPropertySheet::ObjectType ObjectType;
       
   189 
       
   190     explicit QDesignerPropertySheetPrivate(QDesignerPropertySheet *sheetPublic, QObject *object, QObject *sheetParent);
       
   191 
       
   192     bool invalidIndex(const char *functionName, int index) const;
       
   193     inline int count() const { return m_meta->propertyCount() + m_addProperties.count(); }
       
   194 
       
   195     PropertyType propertyType(int index) const;
       
   196     QString transformLayoutPropertyName(int index) const;
       
   197     QLayout* layout(QDesignerPropertySheetExtension **layoutPropertySheet = 0) const;
       
   198     static ObjectType objectType(const QObject *o);
       
   199 
       
   200     bool isReloadableProperty(int index) const;
       
   201     bool isResourceProperty(int index) const;
       
   202     void addResourceProperty(int index, QVariant::Type type);
       
   203     QVariant resourceProperty(int index) const;
       
   204     void setResourceProperty(int index, const QVariant &value);
       
   205     QVariant emptyResourceProperty(int index) const; // of type PropertySheetPixmapValue / PropertySheetIconValue
       
   206     QVariant defaultResourceProperty(int index) const; // of type QPixmap / QIcon (maybe it can be generalized for all types, not resource only)
       
   207 
       
   208     bool isStringProperty(int index) const;
       
   209     void addStringProperty(int index);
       
   210     qdesigner_internal::PropertySheetStringValue stringProperty(int index) const;
       
   211     void setStringProperty(int index, const qdesigner_internal::PropertySheetStringValue &value);
       
   212 
       
   213     bool isKeySequenceProperty(int index) const;
       
   214     void addKeySequenceProperty(int index);
       
   215     qdesigner_internal::PropertySheetKeySequenceValue keySequenceProperty(int index) const;
       
   216     void setKeySequenceProperty(int index, const qdesigner_internal::PropertySheetKeySequenceValue &value);
       
   217 
       
   218     enum PropertyKind { NormalProperty, FakeProperty, DynamicProperty, DefaultDynamicProperty };
       
   219     class Info {
       
   220     public:
       
   221         Info();
       
   222 
       
   223         QString group;
       
   224         QVariant defaultValue;
       
   225         bool changed;
       
   226         bool visible;
       
   227         bool attribute;
       
   228         bool reset;
       
   229         PropertyType propertyType;
       
   230         PropertyKind kind;
       
   231     };
       
   232 
       
   233     Info &ensureInfo(int index);
       
   234 
       
   235     QDesignerPropertySheet *q;
       
   236     QDesignerFormEditorInterface *m_core;
       
   237     const QDesignerMetaObjectInterface *m_meta;
       
   238     const ObjectType m_objectType;
       
   239 
       
   240     typedef QHash<int, Info> InfoHash;
       
   241     InfoHash m_info;
       
   242     QHash<int, QVariant> m_fakeProperties;
       
   243     QHash<int, QVariant> m_addProperties;
       
   244     QHash<QString, int> m_addIndex;
       
   245     QHash<int, QVariant> m_resourceProperties; // only PropertySheetPixmapValue snd PropertySheetIconValue here
       
   246     QHash<int, qdesigner_internal::PropertySheetStringValue> m_stringProperties; // only PropertySheetStringValue
       
   247     QHash<int, qdesigner_internal::PropertySheetKeySequenceValue> m_keySequenceProperties; // only PropertySheetKeySequenceValue
       
   248 
       
   249     const bool m_canHaveLayoutAttributes;
       
   250 
       
   251     // Variables used for caching the layout, access via layout().
       
   252     QPointer<QObject> m_object;
       
   253     mutable QPointer<QLayout> m_lastLayout;
       
   254     mutable QDesignerPropertySheetExtension *m_lastLayoutPropertySheet;
       
   255     mutable bool m_LastLayoutByDesigner;
       
   256 
       
   257     qdesigner_internal::DesignerPixmapCache *m_pixmapCache;
       
   258     qdesigner_internal::DesignerIconCache *m_iconCache;
       
   259     QPointer<qdesigner_internal::FormWindowBase> m_fwb;
       
   260 
       
   261     // Enable Qt's internal properties starting with prefix "_q_"
       
   262     static bool m_internalDynamicPropertiesEnabled;
       
   263 };
       
   264 
       
   265 bool QDesignerPropertySheetPrivate::m_internalDynamicPropertiesEnabled = false;
       
   266 
       
   267 /*
       
   268     The property is reloadable if its contents depends on resource.
       
   269 */
       
   270 bool QDesignerPropertySheetPrivate::isReloadableProperty(int index) const
       
   271 {
       
   272     return isResourceProperty(index)
       
   273            || propertyType(index) == QDesignerPropertySheet::PropertyStyleSheet
       
   274            || q->property(index).type() == QVariant::Url;
       
   275 }
       
   276 
       
   277 /*
       
   278     Resource properties are those which:
       
   279         1) are reloadable
       
   280         2) their state is associated with a file which can be taken from resources
       
   281         3) we don't store them in Qt meta object system (because designer keeps different data structure for them)
       
   282 */
       
   283 
       
   284 bool QDesignerPropertySheetPrivate::isResourceProperty(int index) const
       
   285 {
       
   286     return m_resourceProperties.contains(index);
       
   287 }
       
   288 
       
   289 void QDesignerPropertySheetPrivate::addResourceProperty(int index, QVariant::Type type)
       
   290 {
       
   291     if (type == QVariant::Pixmap)
       
   292         m_resourceProperties.insert(index, qVariantFromValue(qdesigner_internal::PropertySheetPixmapValue()));
       
   293     else if (type == QVariant::Icon)
       
   294         m_resourceProperties.insert(index, qVariantFromValue(qdesigner_internal::PropertySheetIconValue()));
       
   295 }
       
   296 
       
   297 QVariant QDesignerPropertySheetPrivate::emptyResourceProperty(int index) const
       
   298 {
       
   299     QVariant v = m_resourceProperties.value(index);
       
   300     if (qVariantCanConvert<qdesigner_internal::PropertySheetPixmapValue>(v))
       
   301         return qVariantFromValue(qdesigner_internal::PropertySheetPixmapValue());
       
   302     if (qVariantCanConvert<qdesigner_internal::PropertySheetIconValue>(v))
       
   303         return qVariantFromValue(qdesigner_internal::PropertySheetIconValue());
       
   304     return v;
       
   305 }
       
   306 
       
   307 QVariant QDesignerPropertySheetPrivate::defaultResourceProperty(int index) const
       
   308 {
       
   309     return m_info.value(index).defaultValue;
       
   310 }
       
   311 
       
   312 QVariant QDesignerPropertySheetPrivate::resourceProperty(int index) const
       
   313 {
       
   314     return m_resourceProperties.value(index);
       
   315 }
       
   316 
       
   317 void QDesignerPropertySheetPrivate::setResourceProperty(int index, const QVariant &value)
       
   318 {
       
   319     Q_ASSERT(isResourceProperty(index));
       
   320 
       
   321     QVariant &v = m_resourceProperties[index];
       
   322     if ((qVariantCanConvert<qdesigner_internal::PropertySheetPixmapValue>(value) && qVariantCanConvert<qdesigner_internal::PropertySheetPixmapValue>(v))
       
   323         || (qVariantCanConvert<qdesigner_internal::PropertySheetIconValue>(value) && qVariantCanConvert<qdesigner_internal::PropertySheetIconValue>(v)))
       
   324         v = value;
       
   325 }
       
   326 
       
   327 bool QDesignerPropertySheetPrivate::isStringProperty(int index) const
       
   328 {
       
   329     return m_stringProperties.contains(index);
       
   330 }
       
   331 
       
   332 void QDesignerPropertySheetPrivate::addStringProperty(int index)
       
   333 {
       
   334     m_stringProperties.insert(index, qdesigner_internal::PropertySheetStringValue());
       
   335 }
       
   336 
       
   337 qdesigner_internal::PropertySheetStringValue QDesignerPropertySheetPrivate::stringProperty(int index) const
       
   338 {
       
   339     return m_stringProperties.value(index);
       
   340 }
       
   341 
       
   342 void QDesignerPropertySheetPrivate::setStringProperty(int index, const qdesigner_internal::PropertySheetStringValue &value)
       
   343 {
       
   344     Q_ASSERT(isStringProperty(index));
       
   345 
       
   346     m_stringProperties[index] = value;
       
   347 }
       
   348 
       
   349 bool QDesignerPropertySheetPrivate::isKeySequenceProperty(int index) const
       
   350 {
       
   351     return m_keySequenceProperties.contains(index);
       
   352 }
       
   353 
       
   354 void QDesignerPropertySheetPrivate::addKeySequenceProperty(int index)
       
   355 {
       
   356     m_keySequenceProperties.insert(index, qdesigner_internal::PropertySheetKeySequenceValue());
       
   357 }
       
   358 
       
   359 qdesigner_internal::PropertySheetKeySequenceValue QDesignerPropertySheetPrivate::keySequenceProperty(int index) const
       
   360 {
       
   361     return m_keySequenceProperties.value(index);
       
   362 }
       
   363 
       
   364 void QDesignerPropertySheetPrivate::setKeySequenceProperty(int index, const qdesigner_internal::PropertySheetKeySequenceValue &value)
       
   365 {
       
   366     Q_ASSERT(isKeySequenceProperty(index));
       
   367 
       
   368     m_keySequenceProperties[index] = value;
       
   369 }
       
   370 
       
   371 QDesignerPropertySheetPrivate::Info::Info() :
       
   372     changed(false),
       
   373     visible(true),
       
   374     attribute(false),
       
   375     reset(true),
       
   376     propertyType(QDesignerPropertySheet::PropertyNone),
       
   377     kind(NormalProperty)
       
   378 {
       
   379 }
       
   380 
       
   381 QDesignerPropertySheetPrivate::QDesignerPropertySheetPrivate(QDesignerPropertySheet *sheetPublic, QObject *object, QObject *sheetParent) :
       
   382     q(sheetPublic),
       
   383     m_core(formEditorForObject(sheetParent)),
       
   384     m_meta(m_core->introspection()->metaObject(object)),
       
   385     m_objectType(QDesignerPropertySheet::objectTypeFromObject(object)),
       
   386     m_canHaveLayoutAttributes(hasLayoutAttributes(m_core, object)),
       
   387     m_object(object),
       
   388     m_lastLayout(0),
       
   389     m_lastLayoutPropertySheet(0),
       
   390     m_LastLayoutByDesigner(false),
       
   391     m_pixmapCache(0),
       
   392     m_iconCache(0)
       
   393 {
       
   394 }
       
   395 
       
   396 qdesigner_internal::FormWindowBase *QDesignerPropertySheet::formWindowBase() const
       
   397 {
       
   398     return d->m_fwb;
       
   399 }
       
   400 
       
   401 bool QDesignerPropertySheetPrivate::invalidIndex(const char *functionName, int index) const
       
   402 {
       
   403     if (index < 0 || index >= count()) {
       
   404         qWarning() <<  "** WARNING " << functionName << " invoked for " << m_object->objectName() << " was  passed an invalid index " << index << '.';
       
   405         return true;
       
   406     }
       
   407     return false;
       
   408 }
       
   409 
       
   410 QLayout* QDesignerPropertySheetPrivate::layout(QDesignerPropertySheetExtension **layoutPropertySheet) const
       
   411 {
       
   412     // Return the layout and its property sheet
       
   413     // only if it is managed by designer and not one created on a custom widget.
       
   414     // (attempt to cache the value as this requires some hoops).
       
   415     if (layoutPropertySheet)
       
   416         *layoutPropertySheet = 0;
       
   417 
       
   418     if (!m_object->isWidgetType() || !m_canHaveLayoutAttributes)
       
   419         return 0;
       
   420 
       
   421     QWidget *widget = qobject_cast<QWidget*>(m_object);
       
   422     QLayout *widgetLayout = qdesigner_internal::LayoutInfo::internalLayout(widget);
       
   423     if (!widgetLayout) {
       
   424         m_lastLayout = 0;
       
   425         m_lastLayoutPropertySheet = 0;
       
   426         return 0;
       
   427     }
       
   428     // Smart logic to avoid retrieving the meta DB from the widget every time.
       
   429     if (widgetLayout != m_lastLayout) {
       
   430         m_lastLayout = widgetLayout;
       
   431         m_LastLayoutByDesigner = false;
       
   432         m_lastLayoutPropertySheet = 0;
       
   433         // Is this a layout managed by designer or some layout on a custom widget?
       
   434         if (qdesigner_internal::LayoutInfo::managedLayout(m_core ,widgetLayout)) {
       
   435             m_LastLayoutByDesigner = true;
       
   436             m_lastLayoutPropertySheet = qt_extension<QDesignerPropertySheetExtension*>(m_core->extensionManager(), m_lastLayout);
       
   437         }
       
   438     }
       
   439     if (!m_LastLayoutByDesigner)
       
   440         return 0;
       
   441 
       
   442     if (layoutPropertySheet)
       
   443         *layoutPropertySheet = m_lastLayoutPropertySheet;
       
   444 
       
   445     return  m_lastLayout;
       
   446 }
       
   447 
       
   448 QDesignerPropertySheetPrivate::Info &QDesignerPropertySheetPrivate::ensureInfo(int index)
       
   449 {
       
   450     InfoHash::iterator it = m_info.find(index);
       
   451     if (it == m_info.end())
       
   452         it = m_info.insert(index, Info());
       
   453     return it.value();
       
   454 }
       
   455 
       
   456 QDesignerPropertySheet::PropertyType QDesignerPropertySheetPrivate::propertyType(int index) const
       
   457 {
       
   458     const InfoHash::const_iterator it = m_info.constFind(index);
       
   459     if (it == m_info.constEnd())
       
   460         return QDesignerPropertySheet::PropertyNone;
       
   461     return it.value().propertyType;
       
   462 }
       
   463 
       
   464 QString QDesignerPropertySheetPrivate::transformLayoutPropertyName(int index) const
       
   465 {
       
   466     typedef QMap<QDesignerPropertySheet::PropertyType, QString> TypeNameMap;
       
   467     static TypeNameMap typeNameMap;
       
   468     if (typeNameMap.empty()) {
       
   469         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutObjectName, QLatin1String("objectName"));
       
   470         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutLeftMargin, QLatin1String("leftMargin"));
       
   471         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutTopMargin, QLatin1String("topMargin"));
       
   472         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutRightMargin, QLatin1String("rightMargin"));
       
   473         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutBottomMargin, QLatin1String("bottomMargin"));
       
   474         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutSpacing, QLatin1String("spacing"));
       
   475         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutHorizontalSpacing, QLatin1String("horizontalSpacing"));
       
   476         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutVerticalSpacing, QLatin1String("verticalSpacing"));
       
   477         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutSizeConstraint, QLatin1String("sizeConstraint"));
       
   478         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutFieldGrowthPolicy, QLatin1String("fieldGrowthPolicy"));
       
   479         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutRowWrapPolicy, QLatin1String("rowWrapPolicy"));
       
   480         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutLabelAlignment, QLatin1String("labelAlignment"));
       
   481         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutFormAlignment, QLatin1String("formAlignment"));
       
   482         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutBoxStretch, QLatin1String("stretch"));
       
   483         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutGridRowStretch, QLatin1String("rowStretch"));
       
   484         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutGridColumnStretch, QLatin1String("columnStretch"));
       
   485         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutGridRowMinimumHeight, QLatin1String("rowMinimumHeight"));
       
   486         typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutGridColumnMinimumWidth, QLatin1String("columnMinimumWidth"));
       
   487     }
       
   488     const TypeNameMap::const_iterator it = typeNameMap.constFind(propertyType(index));
       
   489     if (it != typeNameMap.constEnd())
       
   490         return it.value();
       
   491     return QString();
       
   492 }
       
   493 
       
   494 // ----------- QDesignerPropertySheet
       
   495 
       
   496 QDesignerPropertySheet::ObjectType QDesignerPropertySheet::objectTypeFromObject(const QObject *o)
       
   497 {
       
   498     if (qobject_cast<const QLayout *>(o))
       
   499         return ObjectLayout;
       
   500 
       
   501     if (!o->isWidgetType())
       
   502         return ObjectNone;
       
   503 
       
   504     if (qobject_cast<const QLayoutWidget *>(o))
       
   505         return ObjectLayoutWidget;
       
   506 
       
   507     if (qobject_cast<const QLabel*>(o))
       
   508         return ObjectLabel;
       
   509 
       
   510     if (o->inherits("Q3GroupBox"))
       
   511         return ObjectQ3GroupBox;
       
   512 
       
   513     return ObjectNone;
       
   514 }
       
   515 
       
   516 QDesignerPropertySheet::PropertyType QDesignerPropertySheet::propertyTypeFromName(const QString &name)
       
   517 {
       
   518     typedef QHash<QString, PropertyType> PropertyTypeHash;
       
   519     static PropertyTypeHash propertyTypeHash;
       
   520     if (propertyTypeHash.empty()) {
       
   521         propertyTypeHash.insert(QLatin1String(layoutObjectNameC),         PropertyLayoutObjectName);
       
   522         propertyTypeHash.insert(QLatin1String(layoutLeftMarginC),         PropertyLayoutLeftMargin);
       
   523         propertyTypeHash.insert(QLatin1String(layoutTopMarginC),          PropertyLayoutTopMargin);
       
   524         propertyTypeHash.insert(QLatin1String(layoutRightMarginC),        PropertyLayoutRightMargin);
       
   525         propertyTypeHash.insert(QLatin1String(layoutBottomMarginC),       PropertyLayoutBottomMargin);
       
   526         propertyTypeHash.insert(QLatin1String(layoutSpacingC),            PropertyLayoutSpacing);
       
   527         propertyTypeHash.insert(QLatin1String(layoutHorizontalSpacingC),  PropertyLayoutHorizontalSpacing);
       
   528         propertyTypeHash.insert(QLatin1String(layoutVerticalSpacingC),    PropertyLayoutVerticalSpacing);
       
   529         propertyTypeHash.insert(QLatin1String(layoutSizeConstraintC),     PropertyLayoutSizeConstraint);
       
   530         propertyTypeHash.insert(QLatin1String(layoutFieldGrowthPolicyC),  PropertyLayoutFieldGrowthPolicy);
       
   531         propertyTypeHash.insert(QLatin1String(layoutRowWrapPolicyC),      PropertyLayoutRowWrapPolicy);
       
   532         propertyTypeHash.insert(QLatin1String(layoutLabelAlignmentC),     PropertyLayoutLabelAlignment);
       
   533         propertyTypeHash.insert(QLatin1String(layoutFormAlignmentC),      PropertyLayoutFormAlignment);
       
   534         propertyTypeHash.insert(QLatin1String(layoutboxStretchPropertyC), PropertyLayoutBoxStretch);
       
   535         propertyTypeHash.insert(QLatin1String(layoutGridRowStretchPropertyC),    PropertyLayoutGridRowStretch);
       
   536         propertyTypeHash.insert(QLatin1String(layoutGridColumnStretchPropertyC), PropertyLayoutGridColumnStretch);
       
   537         propertyTypeHash.insert(QLatin1String(layoutGridRowMinimumHeightC),      PropertyLayoutGridRowMinimumHeight);
       
   538         propertyTypeHash.insert(QLatin1String(layoutGridColumnMinimumWidthC),    PropertyLayoutGridColumnMinimumWidth);
       
   539         propertyTypeHash.insert(QLatin1String("buddy"),                   PropertyBuddy);
       
   540         propertyTypeHash.insert(QLatin1String("geometry"),                PropertyGeometry);
       
   541         propertyTypeHash.insert(QLatin1String("checkable"),               PropertyCheckable);
       
   542         propertyTypeHash.insert(QLatin1String("accessibleName"),          PropertyAccessibility);
       
   543         propertyTypeHash.insert(QLatin1String("accessibleDescription"),   PropertyAccessibility);
       
   544         propertyTypeHash.insert(QLatin1String("windowTitle"),             PropertyWindowTitle);
       
   545         propertyTypeHash.insert(QLatin1String("windowIcon"),              PropertyWindowIcon);
       
   546         propertyTypeHash.insert(QLatin1String("windowFilePath"),          PropertyWindowFilePath);
       
   547         propertyTypeHash.insert(QLatin1String("windowOpacity"),           PropertyWindowOpacity);
       
   548         propertyTypeHash.insert(QLatin1String("windowIconText"),          PropertyWindowIconText);
       
   549         propertyTypeHash.insert(QLatin1String("windowModality"),          PropertyWindowModality);
       
   550         propertyTypeHash.insert(QLatin1String("windowModified"),          PropertyWindowModified);
       
   551         propertyTypeHash.insert(QLatin1String("styleSheet"),              PropertyStyleSheet);
       
   552     }
       
   553     return propertyTypeHash.value(name, PropertyNone);
       
   554 }
       
   555 
       
   556 QDesignerPropertySheet::QDesignerPropertySheet(QObject *object, QObject *parent) :
       
   557     QObject(parent),
       
   558     d(new QDesignerPropertySheetPrivate(this, object, parent))
       
   559 {
       
   560     typedef QDesignerPropertySheetPrivate::Info Info;
       
   561     const QDesignerMetaObjectInterface *baseMeta = d->m_meta;
       
   562 
       
   563     while (baseMeta &&baseMeta->className().startsWith(QLatin1String("QDesigner"))) {
       
   564         baseMeta = baseMeta->superClass();
       
   565     }
       
   566     Q_ASSERT(baseMeta != 0);
       
   567 
       
   568     QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(d->m_object);
       
   569     d->m_fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow);
       
   570     if (d->m_fwb) {
       
   571         d->m_pixmapCache = d->m_fwb->pixmapCache();
       
   572         d->m_iconCache = d->m_fwb->iconCache();
       
   573         d->m_fwb->addReloadablePropertySheet(this, object);
       
   574     }
       
   575 
       
   576     for (int index=0; index<count(); ++index) {
       
   577         const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
       
   578         const QString name = p->name();
       
   579         if (p->type() == QVariant::KeySequence) {
       
   580             createFakeProperty(name);
       
   581         } else {
       
   582             setVisible(index, false); // use the default for `real' properties
       
   583         }
       
   584 
       
   585         QString pgroup = baseMeta->className();
       
   586 
       
   587         if (const QDesignerMetaObjectInterface *pmeta = propertyIntroducedBy(baseMeta, index)) {
       
   588             pgroup = pmeta->className();
       
   589         }
       
   590 
       
   591         Info &info = d->ensureInfo(index);
       
   592         info.group = pgroup;
       
   593         info.propertyType = propertyTypeFromName(name);
       
   594 
       
   595         if (p->type() == QVariant::Cursor || p->type() == QVariant::Icon || p->type() == QVariant::Pixmap) {
       
   596             info.defaultValue = p->read(d->m_object);
       
   597             if (p->type() == QVariant::Icon || p->type() == QVariant::Pixmap)
       
   598                 d->addResourceProperty(index, p->type());
       
   599         } else if (p->type() == QVariant::String) {
       
   600             d->addStringProperty(index);
       
   601         } else if (p->type() == QVariant::KeySequence) {
       
   602             d->addKeySequenceProperty(index);
       
   603         }
       
   604     }
       
   605 
       
   606     if (object->isWidgetType()) {
       
   607         createFakeProperty(QLatin1String("focusPolicy"));
       
   608         createFakeProperty(QLatin1String("cursor"));
       
   609         createFakeProperty(QLatin1String("toolTip"));
       
   610         createFakeProperty(QLatin1String("whatsThis"));
       
   611         createFakeProperty(QLatin1String("acceptDrops"));
       
   612         createFakeProperty(QLatin1String("dragEnabled"));
       
   613         // windowModality is visible only for the main container, in which case the form windows enables it on loading
       
   614         setVisible(createFakeProperty(QLatin1String("windowModality")), false);
       
   615         if (qobject_cast<const QToolBar *>(d->m_object)) { // prevent toolbars from being dragged off
       
   616             createFakeProperty(QLatin1String("floatable"), QVariant(true));
       
   617         } else {
       
   618             if (qobject_cast<const QMenuBar *>(d->m_object)) {
       
   619                 // Keep the menu bar editable in the form even if a native menu bar is used.
       
   620                 const bool nativeMenuBarDefault = !qApp->testAttribute(Qt::AA_DontUseNativeMenuBar);
       
   621                 createFakeProperty(QLatin1String("nativeMenuBar"), QVariant(nativeMenuBarDefault));
       
   622             }
       
   623         }
       
   624         if (d->m_canHaveLayoutAttributes) {
       
   625             static const QString layoutGroup = QLatin1String("Layout");
       
   626             const char* fakeLayoutProperties[] = {
       
   627                 layoutObjectNameC, layoutLeftMarginC, layoutTopMarginC, layoutRightMarginC, layoutBottomMarginC, layoutSpacingC, layoutHorizontalSpacingC, layoutVerticalSpacingC,
       
   628                 layoutFieldGrowthPolicyC, layoutRowWrapPolicyC, layoutLabelAlignmentC, layoutFormAlignmentC,
       
   629                 layoutboxStretchPropertyC, layoutGridRowStretchPropertyC, layoutGridColumnStretchPropertyC,
       
   630                 layoutGridRowMinimumHeightC, layoutGridColumnMinimumWidthC
       
   631 #ifdef USE_LAYOUT_SIZE_CONSTRAINT
       
   632                 , layoutSizeConstraintC
       
   633 #endif
       
   634             };
       
   635             const int fakeLayoutPropertyCount = sizeof(fakeLayoutProperties)/sizeof(const char*);
       
   636             const int size = count();
       
   637             for (int i = 0; i < fakeLayoutPropertyCount; i++) {
       
   638                 createFakeProperty(QLatin1String(fakeLayoutProperties[i]), 0);
       
   639                 setAttribute(size  + i, true);
       
   640                 setPropertyGroup(size  + i, layoutGroup);
       
   641             }
       
   642         }
       
   643 
       
   644         if (d->m_objectType == ObjectLabel)
       
   645             createFakeProperty(QLatin1String("buddy"), QVariant(QByteArray()));
       
   646         /* We need to create a fake property since the property does not work
       
   647          * for non-toplevel windows or on other systems than Mac and only if
       
   648          * it is above a certain Mac OS version. */
       
   649         if (qobject_cast<const QMainWindow *>(d->m_object))
       
   650             createFakeProperty(QLatin1String("unifiedTitleAndToolBarOnMac"), false);
       
   651     }
       
   652 
       
   653     if (qobject_cast<const QDialog*>(object)) {
       
   654         createFakeProperty(QLatin1String("modal"));
       
   655     }
       
   656     if (qobject_cast<const QDockWidget*>(object)) {
       
   657         createFakeProperty(QLatin1String("floating"));
       
   658     }
       
   659 
       
   660     typedef QList<QByteArray> ByteArrayList;
       
   661     const ByteArrayList names = object->dynamicPropertyNames();
       
   662     if (!names.empty()) {
       
   663         const ByteArrayList::const_iterator cend =  names.constEnd();
       
   664         for (ByteArrayList::const_iterator it = names.constBegin(); it != cend; ++it) {
       
   665             const char* cName = it->constData();
       
   666             const QString name = QString::fromLatin1(cName);
       
   667             const int idx = addDynamicProperty(name, object->property(cName));
       
   668             if (idx != -1)
       
   669                 d->ensureInfo(idx).kind = QDesignerPropertySheetPrivate::DefaultDynamicProperty;
       
   670         }
       
   671     }
       
   672 }
       
   673 
       
   674 QDesignerPropertySheet::~QDesignerPropertySheet()
       
   675 {
       
   676     if (d->m_fwb)
       
   677         d->m_fwb->removeReloadablePropertySheet(this);
       
   678     delete d;
       
   679 }
       
   680 
       
   681 QObject *QDesignerPropertySheet::object() const
       
   682 {
       
   683     return d->m_object;
       
   684 }
       
   685 
       
   686 bool QDesignerPropertySheet::dynamicPropertiesAllowed() const
       
   687 {
       
   688     return true;
       
   689 }
       
   690 
       
   691 bool QDesignerPropertySheet::canAddDynamicProperty(const QString &propName) const
       
   692 {
       
   693     const int index = d->m_meta->indexOfProperty(propName);
       
   694     if (index != -1)
       
   695         return false; // property already exists and is not a dynamic one
       
   696     if (d->m_addIndex.contains(propName)) {
       
   697         const int idx = d->m_addIndex.value(propName);
       
   698         if (isVisible(idx))
       
   699             return false; // dynamic property already exists
       
   700         else
       
   701             return true;
       
   702     }
       
   703     if (!QDesignerPropertySheet::internalDynamicPropertiesEnabled() && propName.startsWith(QLatin1String("_q_")))
       
   704         return false;
       
   705     return true;
       
   706 }
       
   707 
       
   708 int QDesignerPropertySheet::addDynamicProperty(const QString &propName, const QVariant &value)
       
   709 {
       
   710     typedef QDesignerPropertySheetPrivate::Info Info;
       
   711     if (!value.isValid())
       
   712         return -1; // property has invalid type
       
   713     if (!canAddDynamicProperty(propName))
       
   714         return -1;
       
   715 
       
   716     QVariant v = value;
       
   717     if (value.type() == QVariant::Icon)
       
   718         v = qVariantFromValue(qdesigner_internal::PropertySheetIconValue());
       
   719     else if (value.type() == QVariant::Pixmap)
       
   720         v = qVariantFromValue(qdesigner_internal::PropertySheetPixmapValue());
       
   721     else if (value.type() == QVariant::String)
       
   722         v = qVariantFromValue(qdesigner_internal::PropertySheetStringValue());
       
   723     else if (value.type() == QVariant::KeySequence)
       
   724         v = qVariantFromValue(qdesigner_internal::PropertySheetKeySequenceValue());
       
   725 
       
   726 
       
   727     if (d->m_addIndex.contains(propName)) {
       
   728         const int idx = d->m_addIndex.value(propName);
       
   729         // have to be invisible, this was checked in canAddDynamicProperty() method
       
   730         setVisible(idx, true);
       
   731         d->m_addProperties.insert(idx, v);
       
   732         setChanged(idx, false);
       
   733         const int index = d->m_meta->indexOfProperty(propName);
       
   734         Info &info = d->ensureInfo(index);
       
   735         info.defaultValue = value;
       
   736         info.kind = QDesignerPropertySheetPrivate::DynamicProperty;
       
   737         if (value.type() == QVariant::Icon || value.type() == QVariant::Pixmap)
       
   738             d->addResourceProperty(idx, value.type());
       
   739         else if (value.type() == QVariant::String)
       
   740             d->addStringProperty(idx);
       
   741         else if (value.type() == QVariant::KeySequence)
       
   742             d->addKeySequenceProperty(idx);
       
   743         return idx;
       
   744     }
       
   745 
       
   746     const int index = count();
       
   747     d->m_addIndex.insert(propName, index);
       
   748     d->m_addProperties.insert(index, v);
       
   749     Info &info = d->ensureInfo(index);
       
   750     info.visible = true;
       
   751     info.changed = false;
       
   752     info.defaultValue = value;
       
   753     info.kind = QDesignerPropertySheetPrivate::DynamicProperty;
       
   754     setPropertyGroup(index, tr("Dynamic Properties"));
       
   755     if (value.type() == QVariant::Icon || value.type() == QVariant::Pixmap)
       
   756         d->addResourceProperty(index, value.type());
       
   757     else if (value.type() == QVariant::String)
       
   758         d->addStringProperty(index);
       
   759     else if (value.type() == QVariant::KeySequence)
       
   760         d->addKeySequenceProperty(index);
       
   761     return index;
       
   762 }
       
   763 
       
   764 bool QDesignerPropertySheet::removeDynamicProperty(int index)
       
   765 {
       
   766     if (!d->m_addIndex.contains(propertyName(index)))
       
   767         return false;
       
   768 
       
   769     setVisible(index, false);
       
   770     return true;
       
   771 }
       
   772 
       
   773 bool QDesignerPropertySheet::isDynamic(int index) const
       
   774 {
       
   775     if (!d->m_addProperties.contains(index))
       
   776         return false;
       
   777 
       
   778     switch (propertyType(index)) {
       
   779     case PropertyBuddy:
       
   780         if (d->m_objectType == ObjectLabel)
       
   781             return false;
       
   782         break;
       
   783     case PropertyLayoutLeftMargin:
       
   784     case PropertyLayoutTopMargin:
       
   785     case PropertyLayoutRightMargin:
       
   786     case PropertyLayoutBottomMargin:
       
   787     case PropertyLayoutSpacing:
       
   788     case PropertyLayoutHorizontalSpacing:
       
   789     case PropertyLayoutVerticalSpacing:
       
   790     case PropertyLayoutObjectName:
       
   791     case PropertyLayoutSizeConstraint:
       
   792     case PropertyLayoutFieldGrowthPolicy:
       
   793     case PropertyLayoutRowWrapPolicy:
       
   794     case PropertyLayoutLabelAlignment:
       
   795     case PropertyLayoutFormAlignment:
       
   796     case PropertyLayoutBoxStretch:
       
   797     case PropertyLayoutGridRowStretch:
       
   798     case PropertyLayoutGridColumnStretch:
       
   799     case PropertyLayoutGridRowMinimumHeight:
       
   800     case PropertyLayoutGridColumnMinimumWidth:
       
   801         if (d->m_object->isWidgetType() && d->m_canHaveLayoutAttributes)
       
   802             return false;
       
   803     default:
       
   804         break;
       
   805     }
       
   806     return true;
       
   807 }
       
   808 
       
   809 bool QDesignerPropertySheet::isDynamicProperty(int index) const
       
   810 {
       
   811     // Do not complain here, as an invalid index might be encountered
       
   812     // if someone implements a property sheet only, omitting the dynamic sheet.
       
   813     if (index < 0 || index >= count())
       
   814         return false;
       
   815     return d->m_info.value(index).kind == QDesignerPropertySheetPrivate::DynamicProperty;
       
   816 }
       
   817 
       
   818 bool QDesignerPropertySheet::isDefaultDynamicProperty(int index) const
       
   819 {
       
   820     if (d->invalidIndex(Q_FUNC_INFO, index))
       
   821         return false;
       
   822     return d->m_info.value(index).kind == QDesignerPropertySheetPrivate::DefaultDynamicProperty;
       
   823 }
       
   824 
       
   825 bool QDesignerPropertySheet::isResourceProperty(int index) const
       
   826 {
       
   827     return d->isResourceProperty(index);
       
   828 }
       
   829 
       
   830 QVariant QDesignerPropertySheet::defaultResourceProperty(int index) const
       
   831 {
       
   832     return d->defaultResourceProperty(index);
       
   833 }
       
   834 
       
   835 qdesigner_internal::DesignerPixmapCache *QDesignerPropertySheet::pixmapCache() const
       
   836 {
       
   837     return d->m_pixmapCache;
       
   838 }
       
   839 
       
   840 void QDesignerPropertySheet::setPixmapCache(qdesigner_internal::DesignerPixmapCache *cache)
       
   841 {
       
   842     d->m_pixmapCache = cache;
       
   843 }
       
   844 
       
   845 qdesigner_internal::DesignerIconCache *QDesignerPropertySheet::iconCache() const
       
   846 {
       
   847     return d->m_iconCache;
       
   848 }
       
   849 
       
   850 void QDesignerPropertySheet::setIconCache(qdesigner_internal::DesignerIconCache *cache)
       
   851 {
       
   852     d->m_iconCache = cache;
       
   853 }
       
   854 
       
   855 int QDesignerPropertySheet::createFakeProperty(const QString &propertyName, const QVariant &value)
       
   856 {
       
   857     typedef QDesignerPropertySheetPrivate::Info Info;
       
   858     // fake properties
       
   859     const int index = d->m_meta->indexOfProperty(propertyName);
       
   860     if (index != -1) {
       
   861         if (!(d->m_meta->property(index)->attributes() & QDesignerMetaPropertyInterface::DesignableAttribute))
       
   862             return -1;
       
   863         Info &info = d->ensureInfo(index);
       
   864         info.visible = false;
       
   865         info.kind = QDesignerPropertySheetPrivate::FakeProperty;
       
   866         QVariant v = value.isValid() ? value : metaProperty(index);
       
   867         if (v.type() == QVariant::String)
       
   868             v = qVariantFromValue(qdesigner_internal::PropertySheetStringValue());
       
   869         if (v.type() == QVariant::KeySequence)
       
   870             v = qVariantFromValue(qdesigner_internal::PropertySheetKeySequenceValue());
       
   871         d->m_fakeProperties.insert(index, v);
       
   872         return index;
       
   873     }
       
   874     if (!value.isValid())
       
   875         return -1;
       
   876 
       
   877     const int newIndex = count();
       
   878     d->m_addIndex.insert(propertyName, newIndex);
       
   879     d->m_addProperties.insert(newIndex, value);
       
   880     Info &info = d->ensureInfo(newIndex);
       
   881     info.propertyType = propertyTypeFromName(propertyName);
       
   882     info.kind = QDesignerPropertySheetPrivate::FakeProperty;
       
   883     return newIndex;
       
   884 }
       
   885 
       
   886 bool QDesignerPropertySheet::isAdditionalProperty(int index) const
       
   887 {
       
   888     if (d->invalidIndex(Q_FUNC_INFO, index))
       
   889         return false;
       
   890     return d->m_addProperties.contains(index);
       
   891 }
       
   892 
       
   893 bool QDesignerPropertySheet::isFakeProperty(int index) const
       
   894 {
       
   895     if (d->invalidIndex(Q_FUNC_INFO, index))
       
   896         return false;
       
   897     // additional properties must be fake
       
   898     return (d->m_fakeProperties.contains(index) || isAdditionalProperty(index));
       
   899 }
       
   900 
       
   901 int QDesignerPropertySheet::count() const
       
   902 {
       
   903     return d->count();
       
   904 }
       
   905 
       
   906 int QDesignerPropertySheet::indexOf(const QString &name) const
       
   907 {
       
   908     int index = d->m_meta->indexOfProperty(name);
       
   909 
       
   910     if (index == -1)
       
   911         index = d->m_addIndex.value(name, -1);
       
   912 
       
   913     return index;
       
   914 }
       
   915 
       
   916 QDesignerPropertySheet::PropertyType QDesignerPropertySheet::propertyType(int index) const
       
   917 {
       
   918     if (d->invalidIndex(Q_FUNC_INFO, index))
       
   919         return PropertyNone;
       
   920     return d->propertyType(index);
       
   921 }
       
   922 
       
   923 QDesignerPropertySheet::ObjectType QDesignerPropertySheet::objectType() const
       
   924 {
       
   925     return d->m_objectType;
       
   926 }
       
   927 
       
   928 QString QDesignerPropertySheet::propertyName(int index) const
       
   929 {
       
   930     if (d->invalidIndex(Q_FUNC_INFO, index))
       
   931         return QString();
       
   932     if (isAdditionalProperty(index))
       
   933         return d->m_addIndex.key(index);
       
   934 
       
   935     return d->m_meta->property(index)->name();
       
   936 }
       
   937 
       
   938 QString QDesignerPropertySheet::propertyGroup(int index) const
       
   939 {
       
   940     if (d->invalidIndex(Q_FUNC_INFO, index))
       
   941         return QString();
       
   942     const QString g = d->m_info.value(index).group;
       
   943 
       
   944     if (!g.isEmpty())
       
   945         return g;
       
   946 
       
   947     if (propertyType(index) == PropertyAccessibility)
       
   948         return QString::fromUtf8("Accessibility");
       
   949 
       
   950     if (isAdditionalProperty(index))
       
   951         return d->m_meta->className();
       
   952 
       
   953     return g;
       
   954 }
       
   955 
       
   956 void QDesignerPropertySheet::setPropertyGroup(int index, const QString &group)
       
   957 {
       
   958     if (d->invalidIndex(Q_FUNC_INFO, index))
       
   959         return;
       
   960     d->ensureInfo(index).group = group;
       
   961 }
       
   962 
       
   963 QVariant QDesignerPropertySheet::property(int index) const
       
   964 {
       
   965     if (d->invalidIndex(Q_FUNC_INFO, index))
       
   966         return QVariant();
       
   967     if (isAdditionalProperty(index)) {
       
   968         if (isFakeLayoutProperty(index)) {
       
   969             QDesignerPropertySheetExtension *layoutPropertySheet;
       
   970             if (d->layout(&layoutPropertySheet) && layoutPropertySheet) {
       
   971                 const QString newPropName = d->transformLayoutPropertyName(index);
       
   972                 if (!newPropName.isEmpty()) {
       
   973                     const int newIndex = layoutPropertySheet->indexOf(newPropName);
       
   974                     if (newIndex != -1)
       
   975                         return layoutPropertySheet->property(newIndex);
       
   976                     return QVariant();
       
   977                 }
       
   978             }
       
   979         }
       
   980         return d->m_addProperties.value(index);
       
   981     }
       
   982 
       
   983     if (isFakeProperty(index)) {
       
   984         return d->m_fakeProperties.value(index);
       
   985     }
       
   986 
       
   987     if (d->isResourceProperty(index))
       
   988         return d->resourceProperty(index);
       
   989 
       
   990     if (d->isStringProperty(index)) {
       
   991         QString strValue = metaProperty(index).toString();
       
   992         qdesigner_internal::PropertySheetStringValue value = d->stringProperty(index);
       
   993         if (strValue != value.value()) {
       
   994             value.setValue(strValue);
       
   995             d->setStringProperty(index, value); // cache it
       
   996         }
       
   997         return qVariantFromValue(value);
       
   998     }
       
   999 
       
  1000     if (d->isKeySequenceProperty(index)) {
       
  1001         QKeySequence keyValue = qVariantValue<QKeySequence>(metaProperty(index));
       
  1002         qdesigner_internal::PropertySheetKeySequenceValue value = d->keySequenceProperty(index);
       
  1003         if (keyValue != value.value()) {
       
  1004             value.setValue(keyValue);
       
  1005             d->setKeySequenceProperty(index, value); // cache it
       
  1006         }
       
  1007         return qVariantFromValue(value);
       
  1008     }
       
  1009 
       
  1010     return metaProperty(index);
       
  1011 }
       
  1012 
       
  1013 QVariant QDesignerPropertySheet::metaProperty(int index) const
       
  1014 {
       
  1015     Q_ASSERT(!isFakeProperty(index));
       
  1016 
       
  1017     const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
       
  1018     QVariant v = p->read(d->m_object);
       
  1019     switch (p->kind()) {
       
  1020     case QDesignerMetaPropertyInterface::FlagKind: {
       
  1021         qdesigner_internal::PropertySheetFlagValue psflags = qdesigner_internal::PropertySheetFlagValue(v.toInt(), designerMetaFlagsFor(p->enumerator()));
       
  1022         qVariantSetValue(v, psflags);
       
  1023     }
       
  1024         break;
       
  1025     case QDesignerMetaPropertyInterface::EnumKind: {
       
  1026         qdesigner_internal::PropertySheetEnumValue pse = qdesigner_internal::PropertySheetEnumValue(v.toInt(), designerMetaEnumFor(p->enumerator()));
       
  1027         qVariantSetValue(v, pse);
       
  1028     }
       
  1029         break;
       
  1030     case QDesignerMetaPropertyInterface::OtherKind:
       
  1031         break;
       
  1032     }
       
  1033     return v;
       
  1034 }
       
  1035 
       
  1036 QVariant QDesignerPropertySheet::resolvePropertyValue(int index, const QVariant &value) const
       
  1037 {
       
  1038     if (qVariantCanConvert<qdesigner_internal::PropertySheetEnumValue>(value))
       
  1039         return qvariant_cast<qdesigner_internal::PropertySheetEnumValue>(value).value;
       
  1040 
       
  1041     if (qVariantCanConvert<qdesigner_internal::PropertySheetFlagValue>(value))
       
  1042         return qvariant_cast<qdesigner_internal::PropertySheetFlagValue>(value).value;
       
  1043 
       
  1044     if (qVariantCanConvert<qdesigner_internal::PropertySheetStringValue>(value))
       
  1045         return qVariantValue<qdesigner_internal::PropertySheetStringValue>(value).value();
       
  1046 
       
  1047     if (qVariantCanConvert<qdesigner_internal::PropertySheetKeySequenceValue>(value))
       
  1048         return qVariantValue<qdesigner_internal::PropertySheetKeySequenceValue>(value).value();
       
  1049 
       
  1050     if (qVariantCanConvert<qdesigner_internal::PropertySheetPixmapValue>(value)) {
       
  1051         const QString path = qVariantValue<qdesigner_internal::PropertySheetPixmapValue>(value).path();
       
  1052         if (path.isEmpty())
       
  1053             return defaultResourceProperty(index);
       
  1054         if (d->m_pixmapCache) {
       
  1055             return d->m_pixmapCache->pixmap(qvariant_cast<qdesigner_internal::PropertySheetPixmapValue>(value));
       
  1056         }
       
  1057     }
       
  1058 
       
  1059     if (qVariantCanConvert<qdesigner_internal::PropertySheetIconValue>(value)) {
       
  1060         const int pathCount = qVariantValue<qdesigner_internal::PropertySheetIconValue>(value).paths().count();
       
  1061         if (pathCount == 0)
       
  1062             return defaultResourceProperty(index);
       
  1063         if (d->m_iconCache)
       
  1064             return d->m_iconCache->icon(qvariant_cast<qdesigner_internal::PropertySheetIconValue>(value));
       
  1065     }
       
  1066 
       
  1067     return value;
       
  1068 }
       
  1069 
       
  1070 void QDesignerPropertySheet::setFakeProperty(int index, const QVariant &value)
       
  1071 {
       
  1072     Q_ASSERT(isFakeProperty(index));
       
  1073 
       
  1074     QVariant &v = d->m_fakeProperties[index];
       
  1075 
       
  1076     // set resource properties also (if we are going to have fake resource properties)
       
  1077     if (qVariantCanConvert<qdesigner_internal::PropertySheetFlagValue>(value) || qVariantCanConvert<qdesigner_internal::PropertySheetEnumValue>(value)) {
       
  1078         v = value;
       
  1079     } else if (qVariantCanConvert<qdesigner_internal::PropertySheetFlagValue>(v)) {
       
  1080         qdesigner_internal::PropertySheetFlagValue f = qvariant_cast<qdesigner_internal::PropertySheetFlagValue>(v);
       
  1081         f.value = value.toInt();
       
  1082         qVariantSetValue(v, f);
       
  1083         Q_ASSERT(value.type() == QVariant::Int);
       
  1084     } else if (qVariantCanConvert<qdesigner_internal::PropertySheetEnumValue>(v)) {
       
  1085         qdesigner_internal::PropertySheetEnumValue e = qvariant_cast<qdesigner_internal::PropertySheetEnumValue>(v);
       
  1086         e.value = value.toInt();
       
  1087         qVariantSetValue(v, e);
       
  1088         Q_ASSERT(value.type() == QVariant::Int);
       
  1089     } else {
       
  1090         v = value;
       
  1091     }
       
  1092 }
       
  1093 
       
  1094 void QDesignerPropertySheet::clearFakeProperties()
       
  1095 {
       
  1096     d->m_fakeProperties.clear();
       
  1097 }
       
  1098 
       
  1099 // Buddy needs to be byte array, else uic won't work
       
  1100 static QVariant toByteArray(const QVariant &value) {
       
  1101     if (value.type() == QVariant::ByteArray)
       
  1102         return value;
       
  1103     const QByteArray ba = value.toString().toUtf8();
       
  1104     return QVariant(ba);
       
  1105 }
       
  1106 
       
  1107 void QDesignerPropertySheet::setProperty(int index, const QVariant &value)
       
  1108 {
       
  1109     if (d->invalidIndex(Q_FUNC_INFO, index))
       
  1110         return;
       
  1111     if (isAdditionalProperty(index)) {
       
  1112         if (d->m_objectType == ObjectLabel && propertyType(index) == PropertyBuddy) {
       
  1113             QFormBuilderExtra::applyBuddy(value.toString(), QFormBuilderExtra::BuddyApplyVisibleOnly, qobject_cast<QLabel *>(d->m_object));
       
  1114             d->m_addProperties[index] = toByteArray(value);
       
  1115             return;
       
  1116         }
       
  1117 
       
  1118         if (isFakeLayoutProperty(index)) {
       
  1119             QDesignerPropertySheetExtension *layoutPropertySheet;
       
  1120             if (d->layout(&layoutPropertySheet) && layoutPropertySheet) {
       
  1121                 const QString newPropName = d->transformLayoutPropertyName(index);
       
  1122                 if (!newPropName.isEmpty()) {
       
  1123                     const int newIndex = layoutPropertySheet->indexOf(newPropName);
       
  1124                     if (newIndex != -1)
       
  1125                         layoutPropertySheet->setProperty(newIndex, value);
       
  1126                 }
       
  1127             }
       
  1128         }
       
  1129 
       
  1130         if (isDynamicProperty(index)) {
       
  1131             if (d->isResourceProperty(index))
       
  1132                 d->setResourceProperty(index, value);
       
  1133             if (d->isStringProperty(index))
       
  1134                 d->setStringProperty(index, qVariantValue<qdesigner_internal::PropertySheetStringValue>(value));
       
  1135             if (d->isKeySequenceProperty(index))
       
  1136                 d->setKeySequenceProperty(index, qVariantValue<qdesigner_internal::PropertySheetKeySequenceValue>(value));
       
  1137             d->m_object->setProperty(propertyName(index).toUtf8(), resolvePropertyValue(index, value));
       
  1138             if (d->m_object->isWidgetType()) {
       
  1139                 QWidget *w = qobject_cast<QWidget *>(d->m_object);
       
  1140                 w->setStyleSheet(w->styleSheet());
       
  1141             }
       
  1142         }
       
  1143         d->m_addProperties[index] = value;
       
  1144     } else if (isFakeProperty(index)) {
       
  1145         setFakeProperty(index, value);
       
  1146     } else {
       
  1147         if (d->isResourceProperty(index))
       
  1148             d->setResourceProperty(index, value);
       
  1149         if (d->isStringProperty(index))
       
  1150             d->setStringProperty(index, qVariantValue<qdesigner_internal::PropertySheetStringValue>(value));
       
  1151         if (d->isKeySequenceProperty(index))
       
  1152             d->setKeySequenceProperty(index, qVariantValue<qdesigner_internal::PropertySheetKeySequenceValue>(value));
       
  1153         const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
       
  1154         p->write(d->m_object, resolvePropertyValue(index, value));
       
  1155         if (qobject_cast<QGroupBox *>(d->m_object) && propertyType(index) == PropertyCheckable) {
       
  1156             const int idx = indexOf(QLatin1String("focusPolicy"));
       
  1157             if (!isChanged(idx)) {
       
  1158                 qdesigner_internal::PropertySheetEnumValue e = qVariantValue<qdesigner_internal::PropertySheetEnumValue>(property(idx));
       
  1159                 if (value.toBool()) {
       
  1160                     const QDesignerMetaPropertyInterface *p = d->m_meta->property(idx);
       
  1161                     p->write(d->m_object, Qt::NoFocus);
       
  1162                     e.value = Qt::StrongFocus;
       
  1163                     QVariant v;
       
  1164                     qVariantSetValue(v, e);
       
  1165                     setFakeProperty(idx, v);
       
  1166                 } else {
       
  1167                     e.value = Qt::NoFocus;
       
  1168                     QVariant v;
       
  1169                     qVariantSetValue(v, e);
       
  1170                     setFakeProperty(idx, v);
       
  1171                 }
       
  1172             }
       
  1173         }
       
  1174     }
       
  1175 }
       
  1176 
       
  1177 bool QDesignerPropertySheet::hasReset(int index) const
       
  1178 {
       
  1179     if (d->invalidIndex(Q_FUNC_INFO, index))
       
  1180         return false;
       
  1181     if (isAdditionalProperty(index))
       
  1182         return d->m_info.value(index).reset;
       
  1183     return true;
       
  1184 }
       
  1185 
       
  1186 bool QDesignerPropertySheet::reset(int index)
       
  1187 {
       
  1188     if (d->invalidIndex(Q_FUNC_INFO, index))
       
  1189         return false;
       
  1190     if (d->isStringProperty(index))
       
  1191         setProperty(index, qVariantFromValue(qdesigner_internal::PropertySheetStringValue()));
       
  1192     if (d->isKeySequenceProperty(index))
       
  1193         setProperty(index, qVariantFromValue(qdesigner_internal::PropertySheetKeySequenceValue()));
       
  1194     if (d->isResourceProperty(index)) {
       
  1195         setProperty(index, d->emptyResourceProperty(index));
       
  1196         return true;
       
  1197     } else if (isDynamic(index)) {
       
  1198         const QString propName = propertyName(index);
       
  1199         const QVariant oldValue = d->m_addProperties.value(index);
       
  1200         const QVariant newValue = d->m_info.value(index).defaultValue;
       
  1201         if (oldValue == newValue)
       
  1202             return true;
       
  1203         d->m_object->setProperty(propName.toUtf8(), newValue);
       
  1204         d->m_addProperties[index] = newValue;
       
  1205         return true;
       
  1206     } else if (!d->m_info.value(index).defaultValue.isNull()) {
       
  1207         setProperty(index, d->m_info.value(index).defaultValue);
       
  1208         return true;
       
  1209     }
       
  1210     if (isAdditionalProperty(index)) {
       
  1211         const PropertyType pType = propertyType(index);
       
  1212         if (d->m_objectType == ObjectLabel && pType == PropertyBuddy) {
       
  1213             setProperty(index, QVariant(QByteArray()));
       
  1214             return true;
       
  1215         }
       
  1216         if (isFakeLayoutProperty(index)) {
       
  1217            // special properties
       
  1218            switch (pType) {
       
  1219            case PropertyLayoutObjectName:
       
  1220               setProperty(index, QString());
       
  1221               return true;
       
  1222            case PropertyLayoutSizeConstraint:
       
  1223               setProperty(index, QVariant(QLayout::SetDefaultConstraint));
       
  1224               return true;
       
  1225            case PropertyLayoutBoxStretch:
       
  1226            case PropertyLayoutGridRowStretch:
       
  1227            case PropertyLayoutGridColumnStretch:
       
  1228            case PropertyLayoutGridRowMinimumHeight:
       
  1229            case PropertyLayoutGridColumnMinimumWidth:
       
  1230            case PropertyLayoutFieldGrowthPolicy:
       
  1231            case PropertyLayoutRowWrapPolicy:
       
  1232            case PropertyLayoutLabelAlignment:
       
  1233            case PropertyLayoutFormAlignment: {
       
  1234                QDesignerPropertySheetExtension *layoutPropertySheet;
       
  1235                if (d->layout(&layoutPropertySheet) && layoutPropertySheet)
       
  1236                    return layoutPropertySheet->reset(layoutPropertySheet->indexOf(d->transformLayoutPropertyName(index)));
       
  1237            }
       
  1238                break;
       
  1239            default:
       
  1240               break;
       
  1241            }
       
  1242            // special margins
       
  1243             int value = -1;
       
  1244             switch (d->m_objectType) {
       
  1245             case ObjectQ3GroupBox: {
       
  1246                 const QWidget *w = qobject_cast<const QWidget *>(d->m_object);
       
  1247                 switch (pType) {
       
  1248                 case PropertyLayoutLeftMargin:
       
  1249                     value = w->style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
       
  1250                     break;
       
  1251                 case PropertyLayoutTopMargin:
       
  1252                     value = w->style()->pixelMetric(QStyle::PM_LayoutTopMargin);
       
  1253                     break;
       
  1254                 case PropertyLayoutRightMargin:
       
  1255                     value = w->style()->pixelMetric(QStyle::PM_LayoutRightMargin);
       
  1256                     break;
       
  1257                 case PropertyLayoutBottomMargin:
       
  1258                     value = w->style()->pixelMetric(QStyle::PM_LayoutBottomMargin);
       
  1259                     break;
       
  1260                 case PropertyLayoutSpacing:
       
  1261                 case PropertyLayoutHorizontalSpacing:
       
  1262                 case PropertyLayoutVerticalSpacing:
       
  1263                     value = -1;
       
  1264                     break;
       
  1265                 default:
       
  1266                     break;
       
  1267                 }
       
  1268             }
       
  1269                 break;
       
  1270             case ObjectLayoutWidget:
       
  1271                 if (pType == PropertyLayoutLeftMargin ||
       
  1272                         pType == PropertyLayoutTopMargin ||
       
  1273                         pType == PropertyLayoutRightMargin ||
       
  1274                         pType == PropertyLayoutBottomMargin)
       
  1275                     value = 0;
       
  1276                 break;
       
  1277             default:
       
  1278                 break;
       
  1279             }
       
  1280             setProperty(index, value);
       
  1281             return true;
       
  1282         }
       
  1283         return false;
       
  1284     } else if (isFakeProperty(index)) {
       
  1285         const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
       
  1286         const bool result = p->reset(d->m_object);
       
  1287         d->m_fakeProperties[index] = p->read(d->m_object);
       
  1288         return result;
       
  1289     } else if (propertyType(index) == PropertyGeometry && d->m_object->isWidgetType()) {
       
  1290         if (QWidget *w = qobject_cast<QWidget*>(d->m_object)) {
       
  1291             QWidget *widget = w;
       
  1292             if (qdesigner_internal::Utils::isCentralWidget(d->m_fwb, widget) && d->m_fwb->parentWidget())
       
  1293                 widget = d->m_fwb->parentWidget();
       
  1294 
       
  1295             if (widget != w && widget->parentWidget()) {
       
  1296                 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
       
  1297                 widget->parentWidget()->adjustSize();
       
  1298             }
       
  1299             QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
       
  1300             widget->adjustSize();
       
  1301             return true;
       
  1302         }
       
  1303     }
       
  1304     // ### TODO: reset for fake properties.
       
  1305 
       
  1306     const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
       
  1307     return p->reset(d->m_object);
       
  1308 }
       
  1309 
       
  1310 bool QDesignerPropertySheet::isChanged(int index) const
       
  1311 {
       
  1312     if (d->invalidIndex(Q_FUNC_INFO, index))
       
  1313         return false;
       
  1314     if (isAdditionalProperty(index)) {
       
  1315         if (isFakeLayoutProperty(index)) {
       
  1316             QDesignerPropertySheetExtension *layoutPropertySheet;
       
  1317             if (d->layout(&layoutPropertySheet) && layoutPropertySheet) {
       
  1318                 const QString newPropName = d->transformLayoutPropertyName(index);
       
  1319                 if (!newPropName.isEmpty()) {
       
  1320                     const int newIndex = layoutPropertySheet->indexOf(newPropName);
       
  1321                     if (newIndex != -1)
       
  1322                         return layoutPropertySheet->isChanged(newIndex);
       
  1323                     return false;
       
  1324                 }
       
  1325             }
       
  1326         }
       
  1327     }
       
  1328     return d->m_info.value(index).changed;
       
  1329 }
       
  1330 
       
  1331 void QDesignerPropertySheet::setChanged(int index, bool changed)
       
  1332 {
       
  1333     if (d->invalidIndex(Q_FUNC_INFO, index))
       
  1334         return;
       
  1335     if (isAdditionalProperty(index)) {
       
  1336         if (isFakeLayoutProperty(index)) {
       
  1337             QDesignerPropertySheetExtension *layoutPropertySheet;
       
  1338             if (d->layout(&layoutPropertySheet) && layoutPropertySheet) {
       
  1339                 const QString newPropName = d->transformLayoutPropertyName(index);
       
  1340                 if (!newPropName.isEmpty()) {
       
  1341                     const int newIndex = layoutPropertySheet->indexOf(newPropName);
       
  1342                     if (newIndex != -1)
       
  1343                         layoutPropertySheet->setChanged(newIndex, changed);
       
  1344                 }
       
  1345             }
       
  1346         }
       
  1347     }
       
  1348     if (d->isReloadableProperty(index)) {
       
  1349         if (d->m_fwb) {
       
  1350             if (changed)
       
  1351                 d->m_fwb->addReloadableProperty(this, index);
       
  1352             else
       
  1353                 d->m_fwb->removeReloadableProperty(this, index);
       
  1354         }
       
  1355     }
       
  1356     d->ensureInfo(index).changed = changed;
       
  1357 }
       
  1358 
       
  1359 bool QDesignerPropertySheet::isFakeLayoutProperty(int index) const
       
  1360 {
       
  1361     if (!isAdditionalProperty(index))
       
  1362         return false;
       
  1363 
       
  1364     switch (propertyType(index)) {
       
  1365     case PropertyLayoutObjectName:
       
  1366     case PropertyLayoutSizeConstraint:
       
  1367         return true;
       
  1368     case PropertyLayoutLeftMargin:
       
  1369     case PropertyLayoutTopMargin:
       
  1370     case PropertyLayoutRightMargin:
       
  1371     case PropertyLayoutBottomMargin:
       
  1372     case PropertyLayoutSpacing:
       
  1373     case PropertyLayoutHorizontalSpacing:
       
  1374     case PropertyLayoutVerticalSpacing:
       
  1375     case PropertyLayoutFieldGrowthPolicy:
       
  1376     case PropertyLayoutRowWrapPolicy:
       
  1377     case PropertyLayoutLabelAlignment:
       
  1378     case PropertyLayoutFormAlignment:
       
  1379     case PropertyLayoutBoxStretch:
       
  1380     case PropertyLayoutGridRowStretch:
       
  1381     case PropertyLayoutGridColumnStretch:
       
  1382     case PropertyLayoutGridRowMinimumHeight:
       
  1383     case PropertyLayoutGridColumnMinimumWidth:
       
  1384         return d->m_canHaveLayoutAttributes;
       
  1385     default:
       
  1386         break;
       
  1387     }
       
  1388     return false;
       
  1389 }
       
  1390 
       
  1391 // Determine the "designable" state of a property. Properties, which have
       
  1392 // a per-object boolean test function that returns false are shown in
       
  1393 // disabled state ("checked" depending on "checkable", etc.)
       
  1394 // Properties, which are generally not designable independent
       
  1395 // of the object are not shown at all.
       
  1396 enum DesignableState { PropertyIsDesignable,
       
  1397                        // Object has a Designable test function that returns false.
       
  1398                        PropertyOfObjectNotDesignable,
       
  1399                        PropertyNotDesignable };
       
  1400 
       
  1401 static inline DesignableState designableState(const QDesignerMetaPropertyInterface *p, const QObject *object)
       
  1402 {   
       
  1403     if (p->attributes(object) & QDesignerMetaPropertyInterface::DesignableAttribute)
       
  1404         return PropertyIsDesignable;
       
  1405     return (p->attributes() & QDesignerMetaPropertyInterface::DesignableAttribute) ?
       
  1406             PropertyOfObjectNotDesignable : PropertyNotDesignable;
       
  1407 }
       
  1408 
       
  1409 bool QDesignerPropertySheet::isVisible(int index) const
       
  1410 {
       
  1411     if (d->invalidIndex(Q_FUNC_INFO, index))
       
  1412         return false;
       
  1413 
       
  1414     const PropertyType type = propertyType(index);
       
  1415     if (isAdditionalProperty(index)) {
       
  1416         if (isFakeLayoutProperty(index) && d->m_object->isWidgetType()) {
       
  1417             const QLayout *currentLayout = d->layout();
       
  1418             if (!currentLayout)
       
  1419                 return false;
       
  1420             const int visibleMask = qdesigner_internal::LayoutProperties::visibleProperties(currentLayout);
       
  1421             switch (type) {
       
  1422             case  PropertyLayoutSpacing:
       
  1423                 return visibleMask & qdesigner_internal::LayoutProperties::SpacingProperty;
       
  1424             case PropertyLayoutHorizontalSpacing:
       
  1425             case PropertyLayoutVerticalSpacing:
       
  1426                 return visibleMask & qdesigner_internal::LayoutProperties::HorizSpacingProperty;
       
  1427             case PropertyLayoutFieldGrowthPolicy:
       
  1428                 return visibleMask & qdesigner_internal::LayoutProperties::FieldGrowthPolicyProperty;
       
  1429             case PropertyLayoutRowWrapPolicy:
       
  1430                 return visibleMask & qdesigner_internal::LayoutProperties::RowWrapPolicyProperty;
       
  1431             case PropertyLayoutLabelAlignment:
       
  1432                 return visibleMask & qdesigner_internal::LayoutProperties::LabelAlignmentProperty;
       
  1433             case PropertyLayoutFormAlignment:
       
  1434                 return visibleMask & qdesigner_internal::LayoutProperties::FormAlignmentProperty;
       
  1435             case PropertyLayoutBoxStretch:
       
  1436                 return visibleMask & qdesigner_internal::LayoutProperties::BoxStretchProperty;
       
  1437             case PropertyLayoutGridRowStretch:
       
  1438                 return visibleMask & qdesigner_internal::LayoutProperties::GridRowStretchProperty;
       
  1439             case PropertyLayoutGridColumnStretch:
       
  1440                 return visibleMask & qdesigner_internal::LayoutProperties::GridColumnStretchProperty;
       
  1441             case PropertyLayoutGridRowMinimumHeight:
       
  1442                 return visibleMask & qdesigner_internal::LayoutProperties::GridRowMinimumHeightProperty;
       
  1443             case PropertyLayoutGridColumnMinimumWidth:
       
  1444                 return visibleMask & qdesigner_internal::LayoutProperties::GridColumnMinimumWidthProperty;
       
  1445             default:
       
  1446                 break;
       
  1447             }
       
  1448             return true;
       
  1449         }
       
  1450         return d->m_info.value(index).visible;
       
  1451     }
       
  1452 
       
  1453     if (isFakeProperty(index)) {
       
  1454         if (type == PropertyWindowModality) // Hidden for child widgets
       
  1455             return d->m_info.value(index).visible;
       
  1456         return true;
       
  1457     }
       
  1458 
       
  1459     const bool visible = d->m_info.value(index).visible;
       
  1460     switch (type) {
       
  1461     case PropertyWindowTitle:
       
  1462     case PropertyWindowIcon:
       
  1463     case PropertyWindowFilePath:
       
  1464     case PropertyWindowOpacity:
       
  1465     case PropertyWindowIconText:
       
  1466     case PropertyWindowModified:
       
  1467         return visible;
       
  1468     default:
       
  1469         if (visible)
       
  1470             return true;
       
  1471         break;
       
  1472     }
       
  1473 
       
  1474     const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
       
  1475     if  (!(p->accessFlags() & QDesignerMetaPropertyInterface::WriteAccess))
       
  1476          return false;
       
  1477 
       
  1478     // Enabled handling: Hide only statically not designable properties
       
  1479     return designableState(p, d->m_object) != PropertyNotDesignable;
       
  1480 }
       
  1481 
       
  1482 void QDesignerPropertySheet::setVisible(int index, bool visible)
       
  1483 {
       
  1484     if (d->invalidIndex(Q_FUNC_INFO, index))
       
  1485         return;
       
  1486     d->ensureInfo(index).visible = visible;
       
  1487 }
       
  1488 
       
  1489 bool QDesignerPropertySheet::isEnabled(int index) const
       
  1490 {
       
  1491     if (d->invalidIndex(Q_FUNC_INFO, index))
       
  1492         return false;
       
  1493     if (isAdditionalProperty(index))
       
  1494         return true;
       
  1495 
       
  1496     if (isFakeProperty(index))
       
  1497         return true;
       
  1498 
       
  1499     // Grey out geometry of laid-out widgets (including splitter)
       
  1500     if (propertyType(index) == PropertyGeometry && d->m_object->isWidgetType()) {
       
  1501         bool isManaged;
       
  1502         const qdesigner_internal::LayoutInfo::Type lt = qdesigner_internal::LayoutInfo::laidoutWidgetType(d->m_core, qobject_cast<QWidget *>(d->m_object), &isManaged);
       
  1503         return !isManaged || lt == qdesigner_internal::LayoutInfo::NoLayout;
       
  1504     }
       
  1505 
       
  1506     if (d->m_info.value(index).visible == true) // Sun CC 5.5 oddity, wants true
       
  1507         return true;
       
  1508 
       
  1509     // Enable setting of properties for statically non-designable properties
       
  1510     // as this might be done via TaskMenu/Cursor::setProperty. Note that those
       
  1511     // properties are not visible.
       
  1512     const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
       
  1513     return (p->accessFlags() & QDesignerMetaPropertyInterface::WriteAccess) &&
       
  1514            designableState(p, d->m_object) != PropertyOfObjectNotDesignable;
       
  1515 }
       
  1516 
       
  1517 bool QDesignerPropertySheet::isAttribute(int index) const
       
  1518 {
       
  1519     if (d->invalidIndex(Q_FUNC_INFO, index))
       
  1520         return false;
       
  1521     if (isAdditionalProperty(index))
       
  1522         return d->m_info.value(index).attribute;
       
  1523 
       
  1524     if (isFakeProperty(index))
       
  1525         return false;
       
  1526 
       
  1527     return d->m_info.value(index).attribute;
       
  1528 }
       
  1529 
       
  1530 void QDesignerPropertySheet::setAttribute(int index, bool attribute)
       
  1531 {
       
  1532     if (d->invalidIndex(Q_FUNC_INFO, index))
       
  1533         return;
       
  1534     d->ensureInfo(index).attribute = attribute;
       
  1535 }
       
  1536 
       
  1537 QDesignerFormEditorInterface *QDesignerPropertySheet::core() const
       
  1538 {
       
  1539     return d->m_core;
       
  1540 }
       
  1541 
       
  1542 bool QDesignerPropertySheet::internalDynamicPropertiesEnabled()
       
  1543 {
       
  1544     return QDesignerPropertySheetPrivate::m_internalDynamicPropertiesEnabled;
       
  1545 }
       
  1546 
       
  1547 void QDesignerPropertySheet::setInternalDynamicPropertiesEnabled(bool v)
       
  1548 {
       
  1549     QDesignerPropertySheetPrivate::m_internalDynamicPropertiesEnabled = v;
       
  1550 }
       
  1551 
       
  1552 // ---------- QDesignerAbstractPropertySheetFactory
       
  1553 
       
  1554 struct QDesignerAbstractPropertySheetFactory::PropertySheetFactoryPrivate {
       
  1555     PropertySheetFactoryPrivate();
       
  1556     const QString m_propertySheetId;
       
  1557     const QString m_dynamicPropertySheetId;
       
  1558 
       
  1559     typedef QMap<QObject*, QObject*> ExtensionMap;
       
  1560     ExtensionMap m_extensions;
       
  1561     typedef QHash<QObject*, bool> ExtendedSet;
       
  1562     ExtendedSet m_extended;
       
  1563 };
       
  1564 
       
  1565 QDesignerAbstractPropertySheetFactory::PropertySheetFactoryPrivate::PropertySheetFactoryPrivate() :
       
  1566     m_propertySheetId(Q_TYPEID(QDesignerPropertySheetExtension)),
       
  1567     m_dynamicPropertySheetId(Q_TYPEID(QDesignerDynamicPropertySheetExtension))
       
  1568 {
       
  1569 }
       
  1570 
       
  1571 // ---------- QDesignerAbstractPropertySheetFactory
       
  1572 
       
  1573 
       
  1574 QDesignerAbstractPropertySheetFactory::QDesignerAbstractPropertySheetFactory(QExtensionManager *parent) :
       
  1575     QExtensionFactory(parent),
       
  1576     m_impl(new PropertySheetFactoryPrivate)
       
  1577 {
       
  1578 }
       
  1579 
       
  1580 QDesignerAbstractPropertySheetFactory::~QDesignerAbstractPropertySheetFactory()
       
  1581 {
       
  1582     delete m_impl;
       
  1583 }
       
  1584 
       
  1585 QObject *QDesignerAbstractPropertySheetFactory::extension(QObject *object, const QString &iid) const
       
  1586 {
       
  1587     typedef PropertySheetFactoryPrivate::ExtensionMap ExtensionMap;
       
  1588     if (!object)
       
  1589         return 0;
       
  1590 
       
  1591     if (iid != m_impl->m_propertySheetId && iid != m_impl->m_dynamicPropertySheetId)
       
  1592         return 0;
       
  1593 
       
  1594     ExtensionMap::iterator it = m_impl->m_extensions.find(object);
       
  1595     if (it == m_impl->m_extensions.end()) {
       
  1596         if (QObject *ext = createPropertySheet(object, const_cast<QDesignerAbstractPropertySheetFactory*>(this))) {
       
  1597             connect(ext, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
       
  1598             it = m_impl->m_extensions.insert(object, ext);
       
  1599         }
       
  1600     }
       
  1601 
       
  1602     if (!m_impl->m_extended.contains(object)) {
       
  1603         connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
       
  1604         m_impl->m_extended.insert(object, true);
       
  1605     }
       
  1606 
       
  1607     if (it == m_impl->m_extensions.end())
       
  1608         return 0;
       
  1609 
       
  1610     return it.value();
       
  1611 }
       
  1612 
       
  1613 void QDesignerAbstractPropertySheetFactory::objectDestroyed(QObject *object)
       
  1614 {
       
  1615     QMutableMapIterator<QObject*, QObject*> it(m_impl->m_extensions);
       
  1616     while (it.hasNext()) {
       
  1617         it.next();
       
  1618 
       
  1619         QObject *o = it.key();
       
  1620         if (o == object || object == it.value()) {
       
  1621             it.remove();
       
  1622         }
       
  1623     }
       
  1624 
       
  1625     m_impl->m_extended.remove(object);
       
  1626 }
       
  1627 
       
  1628 QT_END_NAMESPACE