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 "abstractformbuilder.h"
30
#include <QtDesigner/ui4.h>
32
#include <QtCore/QVariant>
33
#include <QtCore/QMetaProperty>
34
#include <QtCore/QDateTime>
35
#include <QtCore/QFileInfo>
36
#include <QtCore/QDir>
38
#include <QtGui/QAction>
39
#include <QtGui/QActionGroup>
40
#include <QtGui/QGridLayout>
41
#include <QtGui/QWidget>
42
#include <QtGui/QIcon>
43
#include <QtGui/QPixmap>
44
#include <QtGui/QListWidget>
45
#include <QtGui/QTreeWidget>
46
#include <QtGui/QComboBox>
47
#include <QtGui/QStatusBar>
48
#include <QtGui/QMainWindow>
50
#include <QtXml/QDomDocument>
53
#include <QtGui/QToolBox>
54
#include <QtGui/QStackedWidget>
55
#include <QtGui/QTabWidget>
56
#include <QtGui/QToolBar>
57
#include <QtGui/QMenuBar>
59
#include <QtCore/qdebug.h>
64
class FriendlyLayout: public QLayout
67
inline FriendlyLayout() { Q_ASSERT(0); }
69
friend class QAbstractFormBuilder;
72
class QAbstractFormBuilderGadget: public QWidget
75
Q_PROPERTY(Qt::Orientation orientation READ fakeOrientation)
76
Q_PROPERTY(QSizePolicy::Policy sizeType READ fakeSizeType)
77
Q_PROPERTY(QPalette::ColorRole colorRole READ fakeColorRole)
78
Q_PROPERTY(QPalette::ColorGroup colorGroup READ fakeColorGroup)
80
QAbstractFormBuilderGadget() { Q_ASSERT(0); }
82
Qt::Orientation fakeOrientation() const { Q_ASSERT(0); return Qt::Horizontal; }
83
QSizePolicy::Policy fakeSizeType() const { Q_ASSERT(0); return QSizePolicy::Expanding; }
84
QPalette::ColorGroup fakeColorGroup() const { Q_ASSERT(0); return static_cast<QPalette::ColorGroup>(0); }
85
QPalette::ColorRole fakeColorRole() const { Q_ASSERT(0); return static_cast<QPalette::ColorRole>(0); }
89
\class QAbstractFormBuilder
95
QAbstractFormBuilder::QAbstractFormBuilder()
97
m_defaultMargin = INT_MIN;
98
m_defaultSpacing = INT_MIN;
103
QAbstractFormBuilder::~QAbstractFormBuilder()
109
QWidget *QAbstractFormBuilder::load(QIODevice *dev, QWidget *parentWidget)
112
if (!doc.setContent(dev))
115
QDomElement root = doc.firstChild().toElement();
117
ui.read(root); /// ### check the result
119
return create(&ui, parentWidget);
122
QWidget *QAbstractFormBuilder::create(DomUI *ui, QWidget *parentWidget)
124
if (DomLayoutDefault *def = ui->elementLayoutDefault()) {
125
m_defaultMargin = def->hasAttributeMargin() ? def->attributeMargin() : INT_MIN;
126
m_defaultSpacing = def->hasAttributeSpacing() ? def->attributeSpacing() : INT_MIN;
129
DomWidget *ui_widget = ui->elementWidget();
133
createCustomWidgets(ui->elementCustomWidgets());
135
if (QWidget *widget = create(ui_widget, parentWidget)) {
136
createConnections(ui->elementConnections(), widget);
137
createResources(ui->elementResources());
138
applyTabStops(widget, ui->elementTabStops());
147
QWidget *QAbstractFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidget)
149
QWidget *w = createWidget(ui_widget->attributeClass(), parentWidget, ui_widget->attributeName());
153
applyProperties(w, ui_widget->elementProperty());
155
foreach (DomAction *ui_action, ui_widget->elementAction()) {
156
QAction *child_action = create(ui_action, w);
157
Q_UNUSED( child_action );
160
foreach (DomActionGroup *ui_action_group, ui_widget->elementActionGroup()) {
161
QActionGroup *child_action_group = create(ui_action_group, w);
162
Q_UNUSED( child_action_group );
165
foreach (DomWidget *ui_child, ui_widget->elementWidget()) {
166
QWidget *child_w = create(ui_child, w);
170
foreach (DomLayout *ui_lay, ui_widget->elementLayout()) {
171
QLayout *child_lay = create(ui_lay, 0, w);
172
Q_UNUSED( child_lay );
175
foreach (DomActionRef *ui_action_ref, ui_widget->elementAddAction()) {
176
QString name = ui_action_ref->attributeName();
177
if (name == QLatin1String("separator")) {
178
QAction *sep = new QAction(w);
179
sep->setSeparator(true);
182
} else if (QAction *a = m_actions.value(name)) {
184
} else if (QActionGroup *g = m_actionGroups.value(name)) {
185
foreach (QAction *a, g->actions()) {
188
} else if (QMenu *menu = qFindChild<QMenu*>(w, name)) {
189
QMenu *parentMenu = qobject_cast<QMenu*>(w);
190
QMenuBar *parentMenuBar = qobject_cast<QMenuBar*>(w);
192
menu->setParent(w, Qt::Popup);
194
QAction *menuAction = 0;
197
menuAction = parentMenuBar->addMenu(menu);
199
menuAction = parentMenu->addMenu(menu);
202
menuAction->setObjectName(menu->objectName() + QLatin1String("Action"));
203
addMenuAction(menuAction);
208
loadExtraInfo(ui_widget, w, parentWidget);
209
addItem(ui_widget, w, parentWidget);
214
QAction *QAbstractFormBuilder::create(DomAction *ui_action, QObject *parent)
216
QAction *a = createAction(parent, ui_action->attributeName());
220
applyProperties(a, ui_action->elementProperty());
224
QActionGroup *QAbstractFormBuilder::create(DomActionGroup *ui_action_group, QObject *parent)
226
QActionGroup *a = createActionGroup(parent, ui_action_group->attributeName());
230
applyProperties(a, ui_action_group->elementProperty());
232
foreach (DomAction *ui_action, ui_action_group->elementAction()) {
233
QAction *child_action = create(ui_action, a);
234
Q_UNUSED( child_action );
237
foreach (DomActionGroup *g, ui_action_group->elementActionGroup()) {
238
QActionGroup *child_action_group = create(g, a);
239
Q_UNUSED( child_action_group );
246
bool QAbstractFormBuilder::addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
248
QHash<QString, DomProperty*> attributes = propertyMap(ui_widget->elementAttribute());
250
QString title = QLatin1String("Page");
251
if (attributes.contains(QLatin1String("title")))
252
title = toString(attributes.value(QLatin1String("title"))->elementString());
254
QString label = QLatin1String(QLatin1String("Page"));
255
if (attributes.contains(QLatin1String("label")))
256
label = toString(attributes.value(QLatin1String("label"))->elementString());
258
if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(parentWidget)) {
259
widget->setParent(0);
260
tabWidget->addTab(widget, title);
264
if (QStackedWidget *stackedWidget = qobject_cast<QStackedWidget*>(parentWidget)) {
265
stackedWidget->addWidget(widget);
269
if (QToolBox *toolBox = qobject_cast<QToolBox*>(parentWidget)) {
270
toolBox->addItem(widget, label);
277
void QAbstractFormBuilder::layoutInfo(DomLayout *ui_layout, QObject *parent, int *margin, int *spacing)
279
QHash<QString, DomProperty*> properties = propertyMap(ui_layout->elementProperty());
282
*margin = properties.contains(QLatin1String("margin"))
283
? properties.value(QLatin1String("margin"))->elementNumber()
287
*spacing = properties.contains(QLatin1String("spacing"))
288
? properties.value(QLatin1String("spacing"))->elementNumber()
291
if (margin && m_defaultMargin == INT_MIN) {
293
if (qstrcmp(parent->metaObject()->className(), "QLayoutWidget") == 0)
298
QLayout *QAbstractFormBuilder::create(DomLayout *ui_layout, QLayout *parentLayout, QWidget *parentWidget)
300
QObject *p = parentLayout;
307
bool tracking = false;
309
if (p == parentWidget && parentWidget->layout()) {
311
p = parentWidget->layout();
314
QLayout *layout = createLayout(ui_layout->attributeClass(), p, QString());
319
if (tracking && layout->parent() == 0) {
320
QBoxLayout *box = qobject_cast<QBoxLayout*>(parentWidget->layout());
321
Q_ASSERT(box != 0); // only QBoxLayout is supported
322
box->addLayout(layout);
325
int margin = INT_MIN, spacing = INT_MIN;
326
layoutInfo(ui_layout, p, &margin, &spacing);
328
if (margin != INT_MIN)
329
layout->setMargin(margin);
331
if (spacing != INT_MIN)
332
layout->setSpacing(spacing);
334
applyProperties(layout, ui_layout->elementProperty());
336
foreach (DomLayoutItem *ui_item, ui_layout->elementItem()) {
337
if (QLayoutItem *item = create(ui_item, layout, parentWidget)) {
338
addItem(ui_item, item, layout);
345
bool QAbstractFormBuilder::addItem(DomLayoutItem *ui_item, QLayoutItem *item, QLayout *layout)
347
if (item->widget()) {
348
static_cast<FriendlyLayout*>(layout)->addChildWidget(item->widget());
349
} else if (item->layout()) {
350
static_cast<FriendlyLayout*>(layout)->addChildLayout(item->layout ());
353
if (QGridLayout *grid = qobject_cast<QGridLayout*>(layout)) {
354
int rowSpan = ui_item->hasAttributeRowSpan() ? ui_item->attributeRowSpan() : 1;
355
int colSpan = ui_item->hasAttributeColSpan() ? ui_item->attributeColSpan() : 1;
356
grid->addItem(item, ui_item->attributeRow(), ui_item->attributeColumn(),
357
rowSpan, colSpan, item->alignment());
359
layout->addItem(item);
365
QLayoutItem *QAbstractFormBuilder::create(DomLayoutItem *ui_layoutItem, QLayout *layout, QWidget *parentWidget)
367
switch (ui_layoutItem->kind()) {
368
case DomLayoutItem::Widget:
369
return new QWidgetItem(create(ui_layoutItem->elementWidget(), parentWidget));
371
case DomLayoutItem::Spacer: {
373
QSizePolicy::Policy sizeType = QSizePolicy::Expanding;
374
bool isVspacer = false;
376
DomSpacer *ui_spacer = ui_layoutItem->elementSpacer();
378
int e_index = QAbstractFormBuilderGadget::staticMetaObject.indexOfEnumerator("QSizePolicy::Policy");
379
Q_ASSERT(e_index != -1);
381
QMetaEnum sizePolicy_enum = QAbstractFormBuilderGadget::staticMetaObject.enumerator(e_index);
383
e_index = QAbstractFormBuilderGadget::staticMetaObject.indexOfEnumerator("Qt::Orientation");
384
Q_ASSERT(e_index != -1);
386
QMetaEnum orientation_enum = QAbstractFormBuilderGadget::staticMetaObject.enumerator(e_index);
388
foreach (DomProperty *p, ui_spacer->elementProperty()) {
389
QVariant v = toVariant(&QAbstractFormBuilderGadget::staticMetaObject, p); // ### remove me
393
if (p->attributeName() == QLatin1String("sizeHint") && p->kind() == DomProperty::Size) {
394
size = v.toSize(); // ### remove me
395
} else if (p->attributeName() == QLatin1String("sizeType") && p->kind() == DomProperty::Enum) {
396
sizeType = static_cast<QSizePolicy::Policy>(sizePolicy_enum.keyToValue(p->elementEnum().toUtf8()));
397
} else if (p->attributeName() == QLatin1String("orientation") && p->kind() == DomProperty::Enum) {
398
Qt::Orientation o = static_cast<Qt::Orientation>(orientation_enum.keyToValue(p->elementEnum().toUtf8()));
399
isVspacer = (o == Qt::Vertical);
403
QSpacerItem *spacer = 0;
405
spacer = new QSpacerItem(size.width(), size.height(), QSizePolicy::Minimum, sizeType);
407
spacer = new QSpacerItem(size.width(), size.height(), sizeType, QSizePolicy::Minimum);
410
case DomLayoutItem::Layout:
411
return create(ui_layoutItem->elementLayout(), layout, parentWidget);
420
void QAbstractFormBuilder::applyProperties(QObject *o, const QList<DomProperty*> &properties)
422
foreach (DomProperty *p, properties) {
423
QVariant v = toVariant(o->metaObject(), p);
425
o->setProperty(p->attributeName().toUtf8(), v);
429
QVariant QAbstractFormBuilder::toVariant(const QMetaObject *meta, DomProperty *p)
434
case DomProperty::Bool: {
435
v = toBool(p->elementBool());
438
case DomProperty::Cstring: {
439
v = p->elementCstring();
442
case DomProperty::Point: {
443
DomPoint *point = p->elementPoint();
444
QPoint pt(point->elementX(), point->elementY());
448
case DomProperty::Size: {
449
DomSize *size = p->elementSize();
450
QSize sz(size->elementWidth(), size->elementHeight());
454
case DomProperty::Rect: {
455
DomRect *rc = p->elementRect();
456
QRect g(rc->elementX(), rc->elementY(), rc->elementWidth(), rc->elementHeight());
460
case DomProperty::String: {
461
int index = meta->indexOfProperty(p->attributeName().toUtf8());
462
if (index != -1 && meta->property(index).type() == QVariant::KeySequence)
463
v = qVariantFromValue(QKeySequence(p->elementString()->text()));
465
v = p->elementString()->text();
468
case DomProperty::Number: {
469
v = p->elementNumber();
472
case DomProperty::Double: {
473
v = p->elementDouble();
476
case DomProperty::Color: {
477
DomColor *color = p->elementColor();
478
QColor c(color->elementRed(), color->elementGreen(), color->elementBlue());
479
v = qVariantFromValue(c);
482
case DomProperty::Font: {
483
DomFont *font = p->elementFont();
485
QFont f(font->elementFamily(), font->elementPointSize(), font->elementWeight(), font->elementItalic());
486
f.setBold(font->elementBold());
487
f.setUnderline(font->elementUnderline());
488
f.setStrikeOut(font->elementStrikeOut());
489
v = qVariantFromValue(f);
492
case DomProperty::Date: {
493
DomDate *date = p->elementDate();
495
QDate d(date->elementYear(), date->elementMonth(), date->elementDay());
499
case DomProperty::Time: {
500
DomTime *t = p->elementTime();
502
QTime tm(t->elementHour(), t->elementMinute(), t->elementSecond());
506
case DomProperty::DateTime: {
507
DomDateTime *dateTime = p->elementDateTime();
508
QDate d(dateTime->elementYear(), dateTime->elementMonth(), dateTime->elementDay());
509
QTime tm(dateTime->elementHour(), dateTime->elementMinute(), dateTime->elementSecond());
515
case DomProperty::Pixmap:
516
case DomProperty::IconSet: {
517
DomResourcePixmap *resource = 0;
518
if (p->kind() == DomProperty::IconSet)
519
resource = p->elementIconSet();
521
resource = p->elementPixmap();
524
QString icon_path = resource->text();
525
QString qrc_path = resource->attributeResource();
527
if (icon_path.isEmpty()) {
528
if (p->kind() == DomProperty::IconSet)
534
if (qrc_path.isEmpty())
535
icon_path = workingDirectory().absoluteFilePath(icon_path);
537
qrc_path = workingDirectory().absoluteFilePath(qrc_path);
539
if (p->kind() == DomProperty::IconSet) {
540
QIcon icon = nameToIcon(icon_path, qrc_path);
542
v = qVariantFromValue(icon);
544
QPixmap pixmap = nameToPixmap(icon_path, qrc_path);
545
v = qVariantFromValue(pixmap);
550
case DomProperty::Palette: {
551
DomPalette *dom = p->elementPalette();
554
if (dom->elementActive()) {
555
palette.setCurrentColorGroup(QPalette::Active);
556
setupColorGroup(palette, dom->elementActive());
559
if (dom->elementInactive()) {
560
palette.setCurrentColorGroup(QPalette::Inactive);
561
setupColorGroup(palette, dom->elementInactive());
564
if (dom->elementDisabled()) {
565
palette.setCurrentColorGroup(QPalette::Disabled);
566
setupColorGroup(palette, dom->elementDisabled());
569
palette.setCurrentColorGroup(QPalette::Active);
570
v = qVariantFromValue(palette);
573
case DomProperty::Cursor: {
574
v = qVariantFromValue(QCursor(static_cast<Qt::CursorShape>(p->elementCursor())));
577
case DomProperty::Set: {
578
QByteArray pname = p->attributeName().toUtf8();
579
int index = meta->indexOfProperty(pname);
581
qWarning() << "property" << pname << "is not supported";
585
QMetaEnum e = meta->property(index).enumerator();
586
Q_ASSERT(e.isFlag() == true);
588
v = e.keysToValue(p->elementSet().toUtf8());
591
case DomProperty::Enum: {
592
QByteArray pname = p->attributeName().toUtf8();
593
int index = meta->indexOfProperty(pname);
595
qWarning() << "property" << pname << "is not supported";
599
QMetaEnum e = meta->property(index).enumerator();
600
v = e.keyToValue(p->elementEnum().toUtf8());
603
case DomProperty::SizePolicy: {
604
DomSizePolicy *sizep = p->elementSizePolicy();
606
QSizePolicy sizePolicy;
607
sizePolicy.setHorizontalStretch(sizep->elementHorStretch());
608
sizePolicy.setVerticalStretch(sizep->elementVerStretch());
610
sizePolicy.setHorizontalPolicy((QSizePolicy::Policy) sizep->elementHSizeType());
611
sizePolicy.setVerticalPolicy((QSizePolicy::Policy) sizep->elementVSizeType());
612
v = qVariantFromValue(sizePolicy);
616
qWarning() << "QAbstractFormBuilder::toVariant:" << p->kind() << " not implemented yet!";
623
void QAbstractFormBuilder::setupColorGroup(QPalette &palette, DomColorGroup *group)
625
const QMetaObject meta = QAbstractFormBuilderGadget::staticMetaObject;
627
QList<DomColor*> colors = group->elementColor();
628
for (int role = 0; role < colors.size(); ++role) {
629
DomColor *color = colors.at(role);
630
QColor c(color->elementRed(), color->elementGreen(), color->elementBlue());
631
palette.setColor(QPalette::ColorRole(role), c); // ### TODO: support the QPalette::ColorRole as string
635
DomColorGroup *QAbstractFormBuilder::saveColorGroup(const QPalette &palette)
637
DomColorGroup *group = new DomColorGroup();
638
QList<DomColor*> colors;
640
for (int role = QPalette::Foreground; role < QPalette::NColorRoles; ++role) {
641
QColor c = palette.color(QPalette::ColorRole(role));
643
DomColor *color = new DomColor();
644
color->setElementRed(c.red());
645
color->setElementGreen(c.green());
646
color->setElementBlue(c.blue());
647
colors.append(color);
650
group->setElementColor(colors);
654
QWidget *QAbstractFormBuilder::createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name)
656
Q_UNUSED(widgetName);
657
Q_UNUSED(parentWidget);
662
QLayout *QAbstractFormBuilder::createLayout(const QString &layoutName, QObject *parent, const QString &name)
664
Q_UNUSED(layoutName);
670
QAction *QAbstractFormBuilder::createAction(QObject *parent, const QString &name)
672
QAction *action = new QAction(parent);
673
action->setObjectName(name);
674
m_actions.insert(name, action);
679
QActionGroup *QAbstractFormBuilder::createActionGroup(QObject *parent, const QString &name)
681
QActionGroup *g = new QActionGroup(parent);
682
g->setObjectName(name);
683
m_actionGroups.insert(name, g);
690
void QAbstractFormBuilder::save(QIODevice *dev, QWidget *widget)
692
DomWidget *ui_widget = createDom(widget, 0);
693
Q_ASSERT( ui_widget != 0 );
695
DomUI *ui = new DomUI();
696
ui->setAttributeVersion(QLatin1String("4.0"));
697
ui->setElementWidget(ui_widget);
702
doc.appendChild(ui->write(doc));
703
QByteArray bytes = doc.toString().toUtf8();
704
dev->write(bytes, bytes.size());
711
void QAbstractFormBuilder::saveDom(DomUI *ui, QWidget *widget)
713
ui->setElementClass(widget->objectName());
715
if (DomConnections *ui_connections = saveConnections()) {
716
ui->setElementConnections(ui_connections);
719
if (DomCustomWidgets *ui_customWidgets = saveCustomWidgets()) {
720
ui->setElementCustomWidgets(ui_customWidgets);
723
if (DomTabStops *ui_tabStops = saveTabStops()) {
724
ui->setElementTabStops(ui_tabStops);
727
if (DomResources *ui_resources = saveResources()) {
728
ui->setElementResources(ui_resources);
732
DomConnections *QAbstractFormBuilder::saveConnections()
734
return new DomConnections;
737
DomWidget *QAbstractFormBuilder::createDom(QWidget *widget, DomWidget *ui_parentWidget, bool recursive)
739
DomWidget *ui_widget = new DomWidget();
740
ui_widget->setAttributeClass(QLatin1String(widget->metaObject()->className()));
741
ui_widget->setElementProperty(computeProperties(widget));
744
if (QLayout *layout = widget->layout()) {
745
if (DomLayout *ui_layout = createDom(layout, 0, ui_parentWidget)) {
746
QList<DomLayout*> ui_layouts;
747
ui_layouts.append(ui_layout);
749
ui_widget->setElementLayout(ui_layouts);
754
// widgets, actions and action groups
755
QList<DomWidget*> ui_widgets;
756
QList<DomAction*> ui_actions;
757
QList<DomActionGroup*> ui_action_groups;
759
QList<QObject*> children = widget->children();
760
foreach (QObject *obj, children) {
761
if (QWidget *childWidget = qobject_cast<QWidget*>(obj)) {
762
if (m_laidout.contains(childWidget) || recursive == false)
765
if (DomWidget *ui_child = createDom(childWidget, ui_widget)) {
766
ui_widgets.append(ui_child);
768
} else if (QAction *childAction = qobject_cast<QAction*>(obj)) {
769
if (childAction->actionGroup() != 0) {
770
// it will be added later.
774
if (DomAction *ui_action = createDom(childAction)) {
775
ui_actions.append(ui_action);
777
} else if (QActionGroup *childActionGroup = qobject_cast<QActionGroup*>(obj)) {
778
if (DomActionGroup *ui_action_group = createDom(childActionGroup)) {
779
ui_action_groups.append(ui_action_group);
785
QList<DomActionRef*> ui_action_refs;
786
foreach (QAction *action, widget->actions()) {
787
if (DomActionRef *ui_action_ref = createActionRefDom(action)) {
788
ui_action_refs.append(ui_action_ref);
793
ui_widget->setElementWidget(ui_widgets);
795
ui_widget->setElementAction(ui_actions);
796
ui_widget->setElementActionGroup(ui_action_groups);
797
ui_widget->setElementAddAction(ui_action_refs);
799
saveExtraInfo(widget, ui_widget, ui_parentWidget);
805
DomActionRef *QAbstractFormBuilder::createActionRefDom(QAction *action)
807
QString name = action->objectName();
809
if (action->menu() != 0 && name.endsWith(QLatin1String("Action")))
810
name = name.left(name.count() - 6);
812
DomActionRef *ui_action_ref = new DomActionRef();
813
if (action->isSeparator())
814
ui_action_ref->setAttributeName(QLatin1String("separator"));
816
ui_action_ref->setAttributeName(name);
818
return ui_action_ref;
821
DomLayout *QAbstractFormBuilder::createDom(QLayout *layout, DomLayout *ui_layout, DomWidget *ui_parentWidget)
824
DomLayout *lay = new DomLayout();
825
lay->setAttributeClass(QLatin1String(layout->metaObject()->className()));
826
lay->setElementProperty(computeProperties(layout));
828
QList<DomLayoutItem*> ui_items;
830
for (int idx=0; layout->itemAt(idx); ++idx) {
831
QLayoutItem *item = layout->itemAt(idx);
833
DomLayoutItem *ui_item = createDom(item, lay, ui_parentWidget);
835
ui_items.append(ui_item);
838
lay->setElementItem(ui_items);
843
DomLayoutItem *QAbstractFormBuilder::createDom(QLayoutItem *item, DomLayout *ui_layout, DomWidget *ui_parentWidget)
845
DomLayoutItem *ui_item = new DomLayoutItem();
847
if (item->widget()) {
848
ui_item->setElementWidget(createDom(item->widget(), ui_parentWidget));
849
m_laidout.insert(item->widget(), true);
850
} else if (item->layout()) {
851
ui_item->setElementLayout(createDom(item->layout(), ui_layout, ui_parentWidget));
852
} else if (item->spacerItem()) {
853
ui_item->setElementSpacer(createDom(item->spacerItem(), ui_layout, ui_parentWidget));
859
DomSpacer *QAbstractFormBuilder::createDom(QSpacerItem *spacer, DomLayout *ui_layout, DomWidget *ui_parentWidget)
862
Q_UNUSED(ui_parentWidget);
864
DomSpacer *ui_spacer = new DomSpacer();
865
QList<DomProperty*> properties;
867
DomProperty *prop = 0;
870
prop = new DomProperty();
871
prop->setAttributeName(QLatin1String("sizeHint"));
872
prop->setElementSize(new DomSize());
873
prop->elementSize()->setElementWidth(spacer->sizeHint().width());
874
prop->elementSize()->setElementHeight(spacer->sizeHint().height());
875
properties.append(prop);
877
// orientation property
878
prop = new DomProperty(); // ### we don't implemented the case where expandingDirections() is both Vertical and Horizontal
879
prop->setAttributeName(QLatin1String("orientation"));
880
prop->setElementEnum((spacer->expandingDirections() & Qt::Horizontal) ? QLatin1String("Qt::Horizontal") : QLatin1String("Qt::Vertical"));
881
properties.append(prop);
883
ui_spacer->setElementProperty(properties);
887
DomProperty *QAbstractFormBuilder::createProperty(QObject *obj, const QString &pname, const QVariant &v)
889
if (!checkProperty(obj, pname)) {
893
DomProperty *dom_prop = new DomProperty();
895
const QMetaObject *meta = obj->metaObject();
896
int pindex = meta->indexOfProperty(pname.toLatin1());
898
QMetaProperty meta_property = meta->property(pindex);
899
if (!meta_property.hasStdCppSet())
900
dom_prop->setAttributeStdset(0);
904
case QVariant::String: {
905
DomString *str = new DomString();
906
str->setText(v.toString());
908
if (pname == QLatin1String("objectName"))
909
str->setAttributeNotr(QLatin1String("true"));
911
dom_prop->setElementString(str);
914
case QVariant::ByteArray: {
915
dom_prop->setElementCstring(QString::fromUtf8(v.toByteArray()));
918
case QVariant::Int: {
919
dom_prop->setElementNumber(v.toInt());
922
case QVariant::UInt: {
923
dom_prop->setElementNumber(v.toUInt());
926
case QVariant::Double: {
927
dom_prop->setElementDouble(v.toDouble());
930
case QVariant::Bool: {
931
dom_prop->setElementBool(v.toBool() ? QLatin1String("true") : QLatin1String("false"));
934
case QVariant::Point: {
935
DomPoint *pt = new DomPoint();
936
QPoint point = v.toPoint();
937
pt->setElementX(point.x());
938
pt->setElementY(point.y());
939
dom_prop->setElementPoint(pt);
942
case QVariant::Color: {
943
DomColor *clr = new DomColor();
944
QColor color = qvariant_cast<QColor>(v);
945
clr->setElementRed(color.red());
946
clr->setElementGreen(color.green());
947
clr->setElementBlue(color.blue());
948
dom_prop->setElementColor(clr);
951
case QVariant::Size: {
952
DomSize *sz = new DomSize();
953
QSize size = v.toSize();
954
sz->setElementWidth(size.width());
955
sz->setElementHeight(size.height());
956
dom_prop->setElementSize(sz);
959
case QVariant::Rect: {
960
DomRect *rc = new DomRect();
961
QRect rect = v.toRect();
962
rc->setElementX(rect.x());
963
rc->setElementY(rect.y());
964
rc->setElementWidth(rect.width());
965
rc->setElementHeight(rect.height());
966
dom_prop->setElementRect(rc);
969
case QVariant::Font: {
970
DomFont *fnt = new DomFont();
971
QFont font = qvariant_cast<QFont>(v);
972
fnt->setElementBold(font.bold());
973
fnt->setElementFamily(font.family());
974
fnt->setElementItalic(font.italic());
975
fnt->setElementPointSize(font.pointSize());
976
fnt->setElementStrikeOut(font.strikeOut());
977
fnt->setElementUnderline(font.underline());
978
fnt->setElementWeight(font.weight());
979
dom_prop->setElementFont(fnt);
982
case QVariant::Cursor: {
983
dom_prop->setElementCursor(qvariant_cast<QCursor>(v).shape());
986
case QVariant::KeySequence: {
987
DomString *s = new DomString();
988
s->setText(qvariant_cast<QKeySequence>(v));
989
dom_prop->setElementString(s);
992
case QVariant::Palette: {
993
DomPalette *dom = new DomPalette();
994
QPalette palette = qvariant_cast<QPalette>(v);
996
palette.setCurrentColorGroup(QPalette::Active);
997
dom->setElementActive(saveColorGroup(palette));
999
palette.setCurrentColorGroup(QPalette::Inactive);
1000
dom->setElementInactive(saveColorGroup(palette));
1002
palette.setCurrentColorGroup(QPalette::Disabled);
1003
dom->setElementDisabled(saveColorGroup(palette));
1005
dom_prop->setElementPalette(dom);
1008
case QVariant::SizePolicy: {
1009
DomSizePolicy *dom = new DomSizePolicy();
1010
QSizePolicy sizePolicy = qvariant_cast<QSizePolicy>(v);
1012
dom->setElementHorStretch(sizePolicy.horizontalStretch());
1013
dom->setElementVerStretch(sizePolicy.verticalStretch());
1015
dom->setElementHSizeType(sizePolicy.horizontalPolicy());
1016
dom->setElementVSizeType(sizePolicy.verticalPolicy());
1018
dom_prop->setElementSizePolicy(dom);
1021
case QVariant::Pixmap:
1022
case QVariant::Icon: {
1023
DomResourcePixmap *r = new DomResourcePixmap;
1026
if (v.type() == QVariant::Icon) {
1027
QIcon icon = qvariant_cast<QIcon>(v);
1028
icon_path = iconToFilePath(icon);
1029
qrc_path = iconToQrcPath(icon);
1031
QPixmap pixmap = qvariant_cast<QPixmap>(v);
1032
icon_path = pixmapToFilePath(pixmap);
1033
qrc_path = pixmapToQrcPath(pixmap);
1036
if (qrc_path.isEmpty())
1037
icon_path = workingDirectory().relativeFilePath(icon_path);
1039
qrc_path = workingDirectory().relativeFilePath(qrc_path);
1041
r->setText(icon_path);
1042
if (!qrc_path.isEmpty())
1043
r->setAttributeResource(qrc_path);
1045
if (v.type() == QVariant::Icon)
1046
dom_prop->setElementIconSet(r);
1048
dom_prop->setElementPixmap(r);
1052
qWarning("support for property `%s' of type `%d' not implemented yet!!",
1053
pname.toUtf8().data(), v.type());
1057
dom_prop->setAttributeName(pname);
1058
// ### dom_prop->setAttributeStdset(true);
1060
if (dom_prop->kind() == DomProperty::Unknown) {
1068
QList<DomProperty*> QAbstractFormBuilder::computeProperties(QObject *obj)
1070
QList<DomProperty*> lst;
1072
const QMetaObject *meta = obj->metaObject();
1074
QHash<QByteArray, bool> properties;
1075
for(int i=0; i<meta->propertyCount(); ++i)
1076
properties.insert(meta->property(i).name(), true);
1078
QList<QByteArray> propertyNames = properties.keys();
1080
for(int i=0; i<propertyNames.size(); ++i) {
1081
QString pname = QString::fromUtf8(propertyNames.at(i));
1082
QMetaProperty prop = meta->property(meta->indexOfProperty(pname.toUtf8()));
1084
if (!prop.isWritable() || !checkProperty(obj, QLatin1String(prop.name())))
1087
QVariant v = prop.read(obj);
1089
DomProperty *dom_prop = 0;
1090
if (v.type() == QVariant::Int) {
1091
dom_prop = new DomProperty();
1093
if (prop.isFlagType())
1094
qWarning("flags property not supported yet!!");
1096
if (prop.isEnumType()) {
1097
QString scope = QString::fromUtf8(prop.enumerator().scope());
1099
scope += QString::fromUtf8("::");
1100
QString e = QString::fromUtf8(prop.enumerator().valueToKey(v.toInt()));
1102
dom_prop->setElementEnum(scope + e);
1104
dom_prop->setElementNumber(v.toInt());
1105
dom_prop->setAttributeName(pname);
1107
dom_prop = createProperty(obj, pname, v);
1110
if (!dom_prop || dom_prop->kind() == DomProperty::Unknown)
1113
lst.append(dom_prop);
1119
bool QAbstractFormBuilder::toBool(const QString &str)
1121
return str.toLower() == QLatin1String("true");
1124
QHash<QString, DomProperty*> QAbstractFormBuilder::propertyMap(const QList<DomProperty*> &properties)
1126
QHash<QString, DomProperty*> map;
1128
foreach (DomProperty *p, properties)
1129
map.insert(p->attributeName(), p);
1134
bool QAbstractFormBuilder::checkProperty(QObject *obj, const QString &prop) const
1142
QString QAbstractFormBuilder::toString(const DomString *str)
1144
return str ? str->text() : QString();
1147
void QAbstractFormBuilder::applyTabStops(QWidget *widget, DomTabStops *tabStops)
1152
QWidget *lastWidget = 0;
1154
QStringList l = tabStops->elementTabStop();
1155
for (int i=0; i<l.size(); ++i) {
1156
QString name = l.at(i);
1158
QWidget *child = qFindChild<QWidget*>(widget, name);
1160
qWarning("'%s' isn't a valid widget\n", name.toUtf8().data());
1165
lastWidget = qFindChild<QWidget*>(widget, name);
1167
} else if (!child || !lastWidget) {
1171
QWidget::setTabOrder(lastWidget, child);
1173
lastWidget = qFindChild<QWidget*>(widget, name);
1177
DomCustomWidgets *QAbstractFormBuilder::saveCustomWidgets()
1182
DomTabStops *QAbstractFormBuilder::saveTabStops()
1187
DomResources *QAbstractFormBuilder::saveResources()
1192
void QAbstractFormBuilder::saveTreeWidgetExtraInfo(QTreeWidget *treeWidget, DomWidget *ui_widget, DomWidget *ui_parentWidget)
1194
Q_UNUSED(ui_parentWidget);
1196
QList<DomColumn*> columns;
1199
for (int c = 0; c<treeWidget->columnCount(); ++c) {
1200
DomColumn *column = new DomColumn;
1202
QList<DomProperty*> properties;
1205
DomProperty *ptext = new DomProperty;
1206
DomString *str = new DomString;
1207
str->setText(treeWidget->headerItem()->text(c));
1208
ptext->setAttributeName(QLatin1String("text"));
1209
ptext->setElementString(str);
1210
properties.append(ptext);
1212
QIcon icon = treeWidget->headerItem()->icon(c);
1213
if (!icon.isNull()) {
1214
QString iconPath = iconToFilePath(icon);
1215
QString qrcPath = iconToQrcPath(icon);
1217
DomProperty *p = new DomProperty;
1219
DomResourcePixmap *pix = new DomResourcePixmap;
1220
if (!qrcPath.isEmpty())
1221
pix->setAttributeResource(qrcPath);
1223
pix->setText(iconPath);
1225
p->setAttributeName(QLatin1String("icon"));
1226
p->setElementIconSet(pix);
1228
properties.append(p);
1231
column->setElementProperty(properties);
1232
columns.append(column);
1235
ui_widget->setElementColumn(columns);
1238
void QAbstractFormBuilder::saveListWidgetExtraInfo(QListWidget *listWidget, DomWidget *ui_widget, DomWidget *ui_parentWidget)
1240
Q_UNUSED(ui_parentWidget);
1242
QList<DomItem*> ui_items = ui_widget->elementItem();
1244
for (int i=0; i<listWidget->count(); ++i) {
1245
QListWidgetItem *item = listWidget->item(i);
1246
DomItem *ui_item = new DomItem();
1248
QList<DomProperty*> properties;
1251
DomString *str = new DomString;
1252
str->setText(item->text());
1256
p = new DomProperty;
1257
p->setAttributeName(QLatin1String("text"));
1258
p->setElementString(str);
1259
properties.append(p);
1261
if (!item->icon().isNull()) {
1262
QString iconPath = iconToFilePath(item->icon());
1263
QString qrcPath = iconToQrcPath(item->icon());
1265
p = new DomProperty;
1267
DomResourcePixmap *pix = new DomResourcePixmap;
1268
if (!qrcPath.isEmpty())
1269
pix->setAttributeResource(qrcPath);
1271
pix->setText(iconPath);
1273
p->setAttributeName(QLatin1String("icon"));
1274
p->setElementIconSet(pix);
1276
properties.append(p);
1279
ui_item->setElementProperty(properties);
1280
ui_items.append(ui_item);
1283
ui_widget->setElementItem(ui_items);
1286
void QAbstractFormBuilder::saveComboBoxExtraInfo(QComboBox *comboBox, DomWidget *ui_widget, DomWidget *ui_parentWidget)
1288
Q_UNUSED(ui_parentWidget);
1290
QList<DomItem*> ui_items = ui_widget->elementItem();
1292
for (int i=0; i<comboBox->count(); ++i) {
1293
DomItem *ui_item = new DomItem();
1295
QList<DomProperty*> properties;
1298
DomString *str = new DomString;
1299
str->setText(comboBox->itemText(i));
1303
p = new DomProperty;
1304
p->setAttributeName(QLatin1String("text"));
1305
p->setElementString(str);
1306
properties.append(p);
1308
QIcon icon = comboBox->itemIcon(i);
1309
if (!icon.isNull()) {
1310
QString iconPath = iconToFilePath(icon);
1311
QString qrcPath = iconToQrcPath(icon);
1313
DomProperty *p = new DomProperty;
1315
DomResourcePixmap *pix = new DomResourcePixmap;
1316
if (!qrcPath.isEmpty())
1317
pix->setAttributeResource(qrcPath);
1319
pix->setText(iconPath);
1321
p->setAttributeName(QLatin1String("icon"));
1322
p->setElementIconSet(pix);
1324
properties.append(p);
1327
ui_item->setElementProperty(properties);
1328
ui_items.append(ui_item);
1331
ui_widget->setElementItem(ui_items);
1334
void QAbstractFormBuilder::saveExtraInfo(QWidget *widget, DomWidget *ui_widget, DomWidget *ui_parentWidget)
1336
if (QListWidget *listWidget = qobject_cast<QListWidget*>(widget)) {
1337
saveListWidgetExtraInfo(listWidget, ui_widget, ui_parentWidget);
1338
} else if (QTreeWidget *treeWidget = qobject_cast<QTreeWidget*>(widget)) {
1339
saveTreeWidgetExtraInfo(treeWidget, ui_widget, ui_parentWidget);
1340
} else if (QComboBox *comboBox = qobject_cast<QComboBox*>(widget)) {
1341
saveComboBoxExtraInfo(comboBox, ui_widget, ui_parentWidget);
1345
void QAbstractFormBuilder::loadListWidgetExtraInfo(DomWidget *ui_widget, QListWidget *listWidget, QWidget *parentWidget)
1347
Q_UNUSED(parentWidget);
1349
foreach (DomItem *ui_item, ui_widget->elementItem()) {
1350
QHash<QString, DomProperty*> properties = propertyMap(ui_item->elementProperty());
1351
QListWidgetItem *item = new QListWidgetItem(listWidget);
1355
p = properties.value(QLatin1String("text"));
1356
if (p && p->kind() == DomProperty::String) {
1357
item->setText(p->elementString()->text());
1360
p = properties.value(QLatin1String("icon"));
1361
if (p && p->kind() == DomProperty::IconSet) {
1362
DomResourcePixmap *icon = p->elementIconSet();
1363
Q_ASSERT(icon != 0);
1364
QString iconPath = icon->text();
1365
QString qrcPath = icon->attributeResource();
1367
item->setIcon(nameToIcon(iconPath, qrcPath));
1372
void QAbstractFormBuilder::loadTreeWidgetExtraInfo(DomWidget *ui_widget, QTreeWidget *treeWidget, QWidget *parentWidget)
1374
Q_UNUSED(parentWidget);
1376
QList<DomColumn*> columns = ui_widget->elementColumn();
1378
treeWidget->setColumnCount(columns.count());
1380
for (int i = 0; i<columns.count(); ++i) {
1381
DomColumn *c = columns.at(i);
1382
QHash<QString, DomProperty*> properties = propertyMap(c->elementProperty());
1384
DomProperty *ptext = properties.value(QLatin1String("text"));
1385
DomProperty *picon = properties.value(QLatin1String("icon"));
1387
if (ptext != 0 && ptext->elementString())
1388
treeWidget->headerItem()->setText(i, ptext->elementString()->text());
1390
if (picon && picon->kind() == DomProperty::IconSet) {
1391
DomResourcePixmap *icon = picon->elementIconSet();
1392
Q_ASSERT(icon != 0);
1393
QString iconPath = icon->text();
1394
QString qrcPath = icon->attributeResource();
1396
treeWidget->headerItem()->setIcon(i, nameToIcon(iconPath, qrcPath));
1401
void QAbstractFormBuilder::loadComboBoxExtraInfo(DomWidget *ui_widget, QComboBox *comboBox, QWidget *parentWidget)
1403
Q_UNUSED(parentWidget);
1405
foreach (DomItem *ui_item, ui_widget->elementItem()) {
1406
QHash<QString, DomProperty*> properties = propertyMap(ui_item->elementProperty());
1412
p = properties.value(QLatin1String("text"));
1413
if (p && p->elementString()) {
1414
text = p->elementString()->text();
1417
p = properties.value(QLatin1String("icon"));
1418
if (p && p->kind() == DomProperty::IconSet) {
1419
DomResourcePixmap *picon = p->elementIconSet();
1420
Q_ASSERT(picon != 0);
1421
QString iconPath = picon->text();
1422
QString qrcPath = picon->attributeResource();
1424
icon = nameToIcon(iconPath, qrcPath);
1427
comboBox->addItem(text, icon);
1432
void QAbstractFormBuilder::loadExtraInfo(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
1434
if (QListWidget *listWidget = qobject_cast<QListWidget*>(widget)) {
1435
loadListWidgetExtraInfo(ui_widget, listWidget, parentWidget);
1436
} else if (QTreeWidget *treeWidget = qobject_cast<QTreeWidget*>(widget)) {
1437
loadTreeWidgetExtraInfo(ui_widget, treeWidget, parentWidget);
1438
} else if (QComboBox *comboBox = qobject_cast<QComboBox*>(widget)) {
1439
loadComboBoxExtraInfo(ui_widget, comboBox, parentWidget);
1443
QIcon QAbstractFormBuilder::nameToIcon(const QString &filePath, const QString &qrcPath)
1451
QString QAbstractFormBuilder::iconToFilePath(const QIcon &pm) const
1457
QString QAbstractFormBuilder::iconToQrcPath(const QIcon &pm) const
1463
QPixmap QAbstractFormBuilder::nameToPixmap(const QString &filePath, const QString &qrcPath)
1471
QString QAbstractFormBuilder::pixmapToFilePath(const QPixmap &pm) const
1477
QString QAbstractFormBuilder::pixmapToQrcPath(const QPixmap &pm) const
1485
QDir QAbstractFormBuilder::workingDirectory() const
1487
return m_workingDirectory;
1492
void QAbstractFormBuilder::setWorkingDirectory(const QDir &directory)
1494
m_workingDirectory = directory;
1497
DomAction *QAbstractFormBuilder::createDom(QAction *action)
1499
if (action->parentWidget() == action->menu())
1502
DomAction *ui_action = new DomAction;
1503
ui_action->setAttributeName(action->objectName());
1505
QList<DomProperty*> properties = computeProperties(action);
1506
ui_action->setElementProperty(properties);
1511
DomActionGroup *QAbstractFormBuilder::createDom(QActionGroup *actionGroup)
1513
DomActionGroup *ui_action_group = new DomActionGroup;
1514
ui_action_group->setAttributeName(actionGroup->objectName());
1516
QList<DomProperty*> properties = computeProperties(actionGroup);
1517
ui_action_group->setElementProperty(properties);
1519
QList<DomAction*> ui_actions;
1521
foreach (QAction *action, actionGroup->actions()) {
1522
if (DomAction *ui_action = createDom(action)) {
1523
ui_actions.append(ui_action);
1527
ui_action_group->setElementAction(ui_actions);
1529
return ui_action_group;
1532
void QAbstractFormBuilder::addMenuAction(QAction *action)
1537
void QAbstractFormBuilder::reset()
1541
m_actionGroups.clear();
1542
m_defaultMargin = INT_MIN;
1543
m_defaultSpacing = INT_MIN;
1548
#include "abstractformbuilder.moc"