1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the designer application of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qdesigner_propertysheet_p.h"
30
#include "qdesigner_utils_p.h"
32
#include <QtDesigner/QDesignerFormWindowInterface>
34
#include <QtCore/QVariant>
35
#include <QtCore/QMetaObject>
36
#include <QtCore/QMetaProperty>
37
#include <QtGui/QImage>
38
#include <QtGui/QPixmap>
39
#include <QtCore/qdebug.h>
41
static const QMetaObject *introducedBy(const QMetaObject *meta, int index)
43
if (index >= meta->propertyOffset())
46
if (meta->superClass())
47
return introducedBy(meta->superClass(), index);
52
QDesignerPropertySheet::QDesignerPropertySheet(QObject *object, QObject *parent)
55
meta(object->metaObject())
57
const QMetaObject *baseMeta = meta;
59
while (baseMeta && QString::fromUtf8(baseMeta->className()).startsWith(QLatin1String("QDesigner"))) {
60
baseMeta = baseMeta->superClass();
62
Q_ASSERT(baseMeta != 0);
65
for (int index=0; index<count(); ++index) {
66
QMetaProperty p = meta->property(index);
67
setVisible(index, p.isDesignable(m_object));
69
if (p.type() == QVariant::KeySequence)
70
createFakeProperty(QString::fromUtf8(p.name()));
72
QString pgroup = QString::fromUtf8(baseMeta->className());
74
if (const QMetaObject *pmeta = introducedBy(baseMeta, index)) {
75
pgroup = QString::fromUtf8(pmeta->className());
78
setPropertyGroup(index, pgroup);
81
if (object->isWidgetType()) {
82
createFakeProperty(QLatin1String("focusPolicy"));
83
createFakeProperty(QLatin1String("cursor"));
84
createFakeProperty(QLatin1String("toolTip"));
85
createFakeProperty(QLatin1String("whatsThis"));
86
createFakeProperty(QLatin1String("acceptDrops"));
87
createFakeProperty(QLatin1String("dragEnabled"));
88
createFakeProperty(QLatin1String("modal"));
92
QDesignerPropertySheet::~QDesignerPropertySheet()
96
void QDesignerPropertySheet::createFakeProperty(const QString &propertyName, const QVariant &value)
99
int index = meta->indexOfProperty(propertyName.toUtf8());
101
setVisible(index, false);
102
QVariant v = value.isValid() ? value : metaProperty(index);
103
m_fakeProperties.insert(index, v);
104
} else if (value.isValid()) { // additional properties
106
m_addIndex.insert(propertyName, index);
107
m_addProperties.insert(index, value);
111
bool QDesignerPropertySheet::isAdditionalProperty(int index) const
113
return m_addProperties.contains(index);
116
bool QDesignerPropertySheet::isFakeProperty(int index) const
118
// additional properties must be fake
119
return (m_fakeProperties.contains(index) || isAdditionalProperty(index));
122
int QDesignerPropertySheet::count() const
124
return meta->propertyCount() + m_addProperties.count();
127
int QDesignerPropertySheet::indexOf(const QString &name) const
129
int index = meta->indexOfProperty(name.toUtf8());
132
index = m_addIndex.value(name, -1);
137
QString QDesignerPropertySheet::propertyName(int index) const
139
if (isAdditionalProperty(index))
140
return m_addIndex.key(index);
142
return QString::fromUtf8(meta->property(index).name());
145
QString QDesignerPropertySheet::propertyGroup(int index) const
147
QString g = m_info.value(index).group;
152
if (propertyName(index).startsWith(QLatin1String("accessible")))
153
return QString::fromUtf8("Accessibility");
155
if (isAdditionalProperty(index))
156
return QString::fromUtf8(meta->className());
161
void QDesignerPropertySheet::setPropertyGroup(int index, const QString &group)
163
if (!m_info.contains(index))
164
m_info.insert(index, Info());
166
m_info[index].group = group;
169
QVariant QDesignerPropertySheet::property(int index) const
171
if (isAdditionalProperty(index)) {
172
return m_addProperties.value(index);
175
if (isFakeProperty(index)) {
176
return m_fakeProperties.value(index);
179
QMetaProperty p = meta->property(index);
180
QVariant v = p.read(m_object);
182
if (p.isFlagType()) {
185
QMetaEnum me = p.enumerator();
186
for (int i=0; i<me.keyCount(); ++i) {
187
QString k = QString::fromUtf8(me.scope());
188
k += QString::fromUtf8("::");
189
k += QLatin1String(me.key(i));
190
e.items.insert(k, me.keyToValue(k.toUtf8()));
193
qVariantSetValue(v, e);
194
} else if (p.isEnumType()) {
197
QMetaEnum me = p.enumerator();
198
for (int i=0; i<me.keyCount(); ++i) {
199
QString k = QString::fromUtf8(me.scope());
200
k += QString::fromUtf8("::");
201
k += QLatin1String(me.key(i));
202
e.items.insert(k, me.keyToValue(k.toUtf8()));
205
qVariantSetValue(v, e);
211
QVariant QDesignerPropertySheet::metaProperty(int index) const
213
Q_ASSERT(!isFakeProperty(index));
215
QMetaProperty p = meta->property(index);
216
QVariant v = p.read(m_object);
218
if (p.isFlagType()) {
221
QMetaEnum me = p.enumerator();
222
for (int i=0; i<me.keyCount(); ++i) {
224
key += QLatin1String(me.scope());
225
key += QLatin1String("::");
226
key += QLatin1String(me.key(i));
228
e.items.insert(key, me.keyToValue(key.toUtf8()));
231
qVariantSetValue(v, e);
232
} else if (p.isEnumType()) {
235
QMetaEnum me = p.enumerator();
236
for (int i=0; i<me.keyCount(); ++i) {
238
key += QLatin1String(me.scope());
239
key += QLatin1String("::");
240
key += QLatin1String(me.key(i));
242
e.items.insert(key, me.keyToValue(key.toUtf8()));
245
qVariantSetValue(v, e);
251
QVariant QDesignerPropertySheet::resolvePropertyValue(const QVariant &value) const
257
if (qVariantCanConvert<FlagType>(value))
258
v = qvariant_cast<FlagType>(value).value;
259
else if (qVariantCanConvert<EnumType>(value))
260
v = qvariant_cast<EnumType>(value).value;
267
void QDesignerPropertySheet::setFakeProperty(int index, const QVariant &value)
269
Q_ASSERT(isFakeProperty(index));
271
QVariant &v = m_fakeProperties[index];
273
if (qVariantCanConvert<FlagType>(value) || qVariantCanConvert<EnumType>(value)) {
275
} else if (qVariantCanConvert<FlagType>(v)) {
276
FlagType f = qvariant_cast<FlagType>(v);
278
qVariantSetValue(v, f);
279
Q_ASSERT(f.value.type() == QVariant::Int);
280
} else if (qVariantCanConvert<EnumType>(v)) {
281
EnumType e = qvariant_cast<EnumType>(v);
283
qVariantSetValue(v, e);
284
Q_ASSERT(e.value.type() == QVariant::Int);
290
void QDesignerPropertySheet::setProperty(int index, const QVariant &value)
292
if (isAdditionalProperty(index)) {
293
m_addProperties[index] = value;
294
} else if (isFakeProperty(index)) {
295
setFakeProperty(index, value);
297
QMetaProperty p = meta->property(index);
298
p.write(m_object, resolvePropertyValue(value));
302
bool QDesignerPropertySheet::hasReset(int index) const
304
if (isAdditionalProperty(index))
305
return m_info.value(index).reset;
310
bool QDesignerPropertySheet::reset(int index)
312
if (isAdditionalProperty(index))
314
else if (isFakeProperty(index)) {
315
QMetaProperty p = meta->property(index);
316
bool result = p.reset(m_object);
317
m_fakeProperties[index] = p.read(m_object);
321
// ### TODO: reset for fake properties.
323
QMetaProperty p = meta->property(index);
324
return p.reset(m_object);
327
bool QDesignerPropertySheet::isChanged(int index) const
329
return m_info.value(index).changed;
332
void QDesignerPropertySheet::setChanged(int index, bool changed)
334
if (!m_info.contains(index))
335
m_info.insert(index, Info());
337
m_info[index].changed = changed;
340
bool QDesignerPropertySheet::isVisible(int index) const
342
if (isAdditionalProperty(index))
343
return m_info.value(index).visible;
345
if (isFakeProperty(index))
348
QMetaProperty p = meta->property(index);
349
return p.isWritable() && m_info.value(index).visible;
352
void QDesignerPropertySheet::setVisible(int index, bool visible)
354
if (!m_info.contains(index))
355
m_info.insert(index, Info());
357
m_info[index].visible = visible;
360
bool QDesignerPropertySheet::isAttribute(int index) const
362
if (isAdditionalProperty(index))
363
return m_info.value(index).attribute;
365
if (isFakeProperty(index))
368
return m_info.value(index).attribute;
371
void QDesignerPropertySheet::setAttribute(int index, bool attribute)
373
if (!m_info.contains(index))
374
m_info.insert(index, Info());
376
m_info[index].attribute = attribute;
380
QDesignerPropertySheetFactory::QDesignerPropertySheetFactory(QExtensionManager *parent)
381
: QExtensionFactory(parent)
385
QObject *QDesignerPropertySheetFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
387
if (iid == Q_TYPEID(QDesignerPropertySheetExtension))
388
return new QDesignerPropertySheet(object, parent);