propertyeditorview.cpp 25.3 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
2
**
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
hjk's avatar
hjk committed
4
** Contact: http://www.qt-project.org/legal
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
7
**
hjk's avatar
hjk committed
8
9
10
11
12
13
14
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
15
16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17
18
19
20
21
22
23
24
25
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
con's avatar
con committed
26
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
29

30
#include "propertyeditorview.h"
31

32
33
#include <qmldesignerconstants.h>

34
35
36
#include <nodemetainfo.h>

#include <invalididexception.h>
37
#include <rewritingexception.h>
38
39
#include <variantproperty.h>

40
41
42
#include <bindingproperty.h>

#include <nodeabstractproperty.h>
43
#include <rewriterview.h>
44

45
#include "propertyeditorvalue.h"
46
#include "propertyeditortransaction.h"
47

48
49
#include <utils/fileutils.h>

50
51
52
53
54
55
56
#include <QCoreApplication>
#include <QDir>
#include <QFileSystemWatcher>
#include <QFileInfo>
#include <QDebug>
#include <QTimer>
#include <QShortcut>
57
#include <QMessageBox>
58
#include <QApplication>
59
60
61
62
63

enum {
    debug = false
};

64
namespace QmlDesigner {
65

66
PropertyEditorView::PropertyEditorView(QWidget *parent) :
Marco Bubke's avatar
Marco Bubke committed
67
        AbstractView(parent),
68
69
70
        m_parent(parent),
        m_updateShortcut(0),
        m_timerId(0),
71
        m_stackedWidget(new PropertyEditorWidget(parent)),
72
        m_qmlBackEndForCurrentType(0),
73
        m_locked(false),
74
75
        m_setupCompleted(false),
        m_singleShotTimer(new QTimer(this))
76
{
77
    m_updateShortcut = new QShortcut(QKeySequence("F3"), m_stackedWidget);
78
79
    connect(m_updateShortcut, SIGNAL(activated()), this, SLOT(reloadQml()));

80
81
    m_stackedWidget->setStyleSheet(
            QLatin1String(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css")));
82
    m_stackedWidget->setMinimumWidth(320);
83
    m_stackedWidget->move(0, 0);
84
    connect(m_stackedWidget, SIGNAL(resized()), this, SLOT(updateSize()));
85
86
87

    m_stackedWidget->insertWidget(0, new QWidget(m_stackedWidget));

88
    QuickPropertyEditorView::registerQmlTypes();
89
    setQmlDir(PropertyEditorQmlBackend::propertyEditorResourcesPath());
90
    m_stackedWidget->setWindowTitle(tr("Properties"));
91
92
}

93
PropertyEditorView::~PropertyEditorView()
94
{
95
    qDeleteAll(m_qmlBackendHash);
96
97
}

98
void PropertyEditorView::setupPane(const TypeName &typeName)
99
{
100
    NodeMetaInfo metaInfo = model()->metaInfo(typeName);
101

102
    QUrl qmlFile = PropertyEditorQmlBackend::getQmlFileUrl(QLatin1String("Qt/ItemPane"), metaInfo);
103
104
    QUrl qmlSpecificsFile;

105
    qmlSpecificsFile = PropertyEditorQmlBackend::getQmlFileUrl(typeName + "Specifics", metaInfo);
106

107
    PropertyEditorQmlBackend *qmlBackend = m_qmlBackendHash.value(qmlFile.toString());
108

109
110
    if (!qmlBackend) {
        qmlBackend = new PropertyEditorQmlBackend(this);
111

112
113
114
115
116
117
118
        qmlBackend->context()->setContextProperty("finishedNotify", QVariant(false) );
        qmlBackend->initialSetup(typeName, qmlSpecificsFile, this);
        qmlBackend->setSource(qmlFile);
        qmlBackend->context()->setContextProperty("finishedNotify", QVariant(true) );

        m_stackedWidget->addWidget(qmlBackend->widget());
        m_qmlBackendHash.insert(qmlFile.toString(), qmlBackend);
119
    } else {
120
        qmlBackend->context()->setContextProperty("finishedNotify", QVariant(false) );
Thomas Hartmann's avatar
Thomas Hartmann committed
121

122
123
        qmlBackend->initialSetup(typeName, qmlSpecificsFile, this);
        qmlBackend->context()->setContextProperty("finishedNotify", QVariant(true) );
124
    }
125
126
}

127
void PropertyEditorView::changeValue(const QString &name)
128
{
129
130
    PropertyName propertyName = name.toUtf8();

131
    if (propertyName.isNull())
132
        return;
133
134
135
136

    if (m_locked)
        return;

137
    if (propertyName == "type")
138
139
        return;

140
141
142
    if (!m_selectedNode.isValid())
        return;

143
    if (propertyName == "id") {
144
        PropertyEditorValue *value = m_qmlBackEndForCurrentType->propertyValueForName(propertyName);
145
146
        const QString newId = value->value().toString();

147
148
149
150
        if (newId == m_selectedNode.id())
            return;

        if (m_selectedNode.isValidId(newId)  && !modelNodeForId(newId).isValid() ) {
151
152
153
154
            if (m_selectedNode.id().isEmpty() || newId.isEmpty()) { //no id
                try {
                    m_selectedNode.setId(newId);
                } catch (InvalidIdException &e) { //better save then sorry
155
                    m_locked = true;
156
                    value->setValue(m_selectedNode.id());
157
                    m_locked = false;
158
159
160
161
162
163
                    QMessageBox::warning(0, tr("Invalid Id"), e.description());
                }
            } else { //there is already an id, so we refactor
                if (rewriterView())
                    rewriterView()->renameId(m_selectedNode.id(), newId);
            }
164
        } else {
165
            m_locked = true;
166
            value->setValue(m_selectedNode.id());
167
168
169
170
171
            m_locked = false;
            if (!m_selectedNode.isValidId(newId))
                QMessageBox::warning(0, tr("Invalid Id"),  tr("%1 is an invalid id").arg(newId));
            else
                QMessageBox::warning(0, tr("Invalid Id"),  tr("%1 already exists").arg(newId));
172
173
174
175
        }
        return;
    }

176
    //.replace(QLatin1Char('.'), QLatin1Char('_'))
177
178
    PropertyName underscoreName(propertyName);
    underscoreName.replace('.', '_');
179
    PropertyEditorValue *value = m_qmlBackEndForCurrentType->propertyValueForName(underscoreName);
180

181
    if (value ==0)
182
183
        return;

184
    QmlObjectNode qmlObjectNode(m_selectedNode);
185
186
187

    QVariant castedValue;

188
189
    if (qmlObjectNode.modelNode().metaInfo().isValid() && qmlObjectNode.modelNode().metaInfo().hasProperty(propertyName)) {
        castedValue = qmlObjectNode.modelNode().metaInfo().propertyCastedValue(propertyName, value->value());
190
    } else {
191
        qWarning() << "PropertyEditor:" <<propertyName << "cannot be casted (metainfo)";
192
193
194
195
        return ;
    }

    if (value->value().isValid() && !castedValue.isValid()) {
196
        qWarning() << "PropertyEditor:" << propertyName << "not properly casted (metainfo)";
197
198
199
        return ;
    }

200
201
202
    if (qmlObjectNode.modelNode().metaInfo().isValid() && qmlObjectNode.modelNode().metaInfo().hasProperty(propertyName))
        if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(propertyName) == "QUrl"
                || qmlObjectNode.modelNode().metaInfo().propertyTypeName(propertyName) == "url") { //turn absolute local file paths into relative paths
203
            QString filePath = castedValue.toUrl().toString();
204
205
206
207
208
209
        if (QFileInfo(filePath).exists() && QFileInfo(filePath).isAbsolute()) {
            QDir fileDir(QFileInfo(model()->fileUrl().toLocalFile()).absolutePath());
            castedValue = QUrl(fileDir.relativeFilePath(filePath));
        }
    }

210
211
212
213
214
215
216
        if (castedValue.type() == QVariant::Color) {
            QColor color = castedValue.value<QColor>();
            QColor newColor = QColor(color.name());
            newColor.setAlpha(color.alpha());
            castedValue = QVariant(newColor);
        }

217
218
        try {
            if (!value->value().isValid()) { //reset
219
                qmlObjectNode.removeProperty(propertyName);
220
            } else {
221
                if (castedValue.isValid() && !castedValue.isNull()) {
222
                    m_locked = true;
223
                    qmlObjectNode.setVariantProperty(propertyName, castedValue);
224
225
                    m_locked = false;
                }
226
227
228
229
            }
        }
        catch (RewritingException &e) {
            QMessageBox::warning(0, "Error", e.description());
230
231
232
        }
}

233
void PropertyEditorView::changeExpression(const QString &propertyName)
234
{
235
236
    PropertyName name = propertyName.toUtf8();

237
238
239
240
241
242
    if (name.isNull())
        return;

    if (m_locked)
        return;

243
244
    RewriterTransaction transaction = beginRewriterTransaction();

245
    try {
246
247
        PropertyName underscoreName(name);
        underscoreName.replace('.', '_');
248

249
        QmlObjectNode qmlObjectNode(m_selectedNode);
250
        PropertyEditorValue *value = m_qmlBackEndForCurrentType->propertyValueForName(underscoreName);
251

252
253
        if (qmlObjectNode.modelNode().metaInfo().isValid() && qmlObjectNode.modelNode().metaInfo().hasProperty(name)) {
            if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "QColor") {
254
                if (QColor(value->expression().remove('"')).isValid()) {
255
                    qmlObjectNode.setVariantProperty(name, QColor(value->expression().remove('"')));
256
257
258
                    transaction.commit(); //committing in the try block
                    return;
                }
259
            } else if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "bool") {
260
261
                if (value->expression().compare("false", Qt::CaseInsensitive) == 0 || value->expression().compare("true", Qt::CaseInsensitive) == 0) {
                    if (value->expression().compare("true", Qt::CaseInsensitive) == 0)
262
                        qmlObjectNode.setVariantProperty(name, true);
263
                    else
264
                        qmlObjectNode.setVariantProperty(name, false);
265
266
267
                    transaction.commit(); //committing in the try block
                    return;
                }
268
            } else if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "int") {
269
270
271
                bool ok;
                int intValue = value->expression().toInt(&ok);
                if (ok) {
272
                    qmlObjectNode.setVariantProperty(name, intValue);
273
274
275
                    transaction.commit(); //committing in the try block
                    return;
                }
276
            } else if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "qreal") {
277
278
279
                bool ok;
                qreal realValue = value->expression().toFloat(&ok);
                if (ok) {
280
                    qmlObjectNode.setVariantProperty(name, realValue);
281
282
283
                    transaction.commit(); //committing in the try block
                    return;
                }
284
            }
285
286
        }

287
288
289
290
        if (!value) {
            qWarning() << "PropertyEditor::changeExpression no value for " << underscoreName;
            return;
        }
291

292
293
294
        if (value->expression().isEmpty())
            return;

295
296
        if (qmlObjectNode.expression(name) != value->expression() || !qmlObjectNode.propertyAffectedByCurrentState(name))
            qmlObjectNode.setBindingProperty(name, value->expression());
297
298

        transaction.commit(); //committing in the try block
299
300
    }

301
    catch (RewritingException &e) {
302
        QMessageBox::warning(0, "Error", e.description());
303
304
305
    }
}

306
void PropertyEditorView::updateSize()
307
{
308
    if (!m_qmlBackEndForCurrentType)
309
        return;
310
    QWidget* frame = m_qmlBackEndForCurrentType->widget()->findChild<QWidget*>("propertyEditorFrame");
311
312
    if (frame)
        frame->resize(m_stackedWidget->size());
313
314
}

315
void PropertyEditorView::setupPanes()
316
317
{
    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
318
    setupPane("QtQuick.Item");
319
320
321
322
323
    resetView();
    m_setupCompleted = true;
    QApplication::restoreOverrideCursor();
}

324
void PropertyEditorView::setQmlDir(const QString &qmlDir)
325
326
327
{
    m_qmlDir = qmlDir;

328

329
330
331
332
333
    QFileSystemWatcher *watcher = new QFileSystemWatcher(this);
    watcher->addPath(m_qmlDir);
    connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(reloadQml()));
}

334
void PropertyEditorView::delayedResetView()
335
336
{
    if (m_timerId == 0)
337
        m_timerId = startTimer(100);
338
339
}

340
void PropertyEditorView::timerEvent(QTimerEvent *timerEvent)
341
{
342
    if (m_timerId == timerEvent->timerId())
343
344
345
        resetView();
}

346
void PropertyEditorView::resetView()
347
348
349
350
{
    if (model() == 0)
        return;

Thomas Hartmann's avatar
Thomas Hartmann committed
351
352
    m_locked = true;

353
354
355
356
357
358
359
360
361
    if (debug)
        qDebug() << "________________ RELOADING PROPERTY EDITOR QML _______________________";

    if (m_timerId)
        killTimer(m_timerId);

    if (m_selectedNode.isValid() && model() != m_selectedNode.model())
        m_selectedNode = ModelNode();

362
363
364
365
366
367
368
369
370
371
372
373
374
    setupQmlBackend();

    m_locked = false;

    if (m_timerId)
        m_timerId = 0;

    updateSize();
}


void PropertyEditorView::setupQmlBackend()
{
375
    TypeName specificsClassName;
376
    QUrl qmlFile(PropertyEditorQmlBackend::getQmlUrlForModelNode(m_selectedNode, specificsClassName));
377
    QUrl qmlSpecificsFile;
378

379
    TypeName diffClassName;
380
381
382
383
384
385
    if (m_selectedNode.isValid()) {
        diffClassName = m_selectedNode.metaInfo().typeName();
        QList<NodeMetaInfo> hierarchy;
        hierarchy << m_selectedNode.metaInfo();
        hierarchy << m_selectedNode.metaInfo().superClasses();

386
387
        foreach (const NodeMetaInfo &metaInfo, hierarchy) {
            if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile))
388
                break;
389
390
            qmlSpecificsFile = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName() + QLatin1String("Specifics"), metaInfo);
            diffClassName = metaInfo.typeName();
391
392
393
        }
    }

394
    if (!PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile))
395
        diffClassName = specificsClassName;
396

397
398
    QString specificQmlData;

399
    if (m_selectedNode.isValid() && m_selectedNode.metaInfo().isValid() && diffClassName != m_selectedNode.type()) {
400
        specificQmlData = PropertyEditorQmlBackend::templateGeneration(m_selectedNode.metaInfo(), model()->metaInfo(diffClassName), m_selectedNode);
401
402
    }

403
    PropertyEditorQmlBackend *currentQmlBackend = m_qmlBackendHash.value(qmlFile.toString());
404

405
    QString currentStateName = currentState().isBaseState() ? currentState().name() : QLatin1String("invalid state");
406

407
408
    if (!currentQmlBackend) {
        currentQmlBackend = new PropertyEditorQmlBackend(this);
409

410
411
        m_stackedWidget->addWidget(currentQmlBackend->widget());
        m_qmlBackendHash.insert(qmlFile.toString(), currentQmlBackend);
412

413
        QmlObjectNode qmlObjectNode;
414
        if (m_selectedNode.isValid()) {
415
416
            qmlObjectNode = QmlObjectNode(m_selectedNode);
            Q_ASSERT(qmlObjectNode.isValid());
417
        }
418
419
        currentQmlBackend->setup(qmlObjectNode, currentStateName, qmlSpecificsFile, this);
        currentQmlBackend->context()->setContextProperty("finishedNotify", QVariant(false));
420
        if (specificQmlData.isEmpty())
421
            currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
Orgad Shaneh's avatar
Orgad Shaneh committed
422

423
424
425
426
        currentQmlBackend->contextObject()->setGlobalBaseUrl(qmlFile);
        currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
        currentQmlBackend->setSource(qmlFile);
        currentQmlBackend->context()->setContextProperty("finishedNotify", QVariant(true));
427
    } else {
428
        QmlObjectNode qmlObjectNode;
429
        if (m_selectedNode.isValid())
430
            qmlObjectNode = QmlObjectNode(m_selectedNode);
Orgad Shaneh's avatar
Orgad Shaneh committed
431

432
        currentQmlBackend->context()->setContextProperty("finishedNotify", QVariant(false));
433
        if (specificQmlData.isEmpty())
434
435
436
437
            currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
        currentQmlBackend->setup(qmlObjectNode, currentStateName, qmlSpecificsFile, this);
        currentQmlBackend->contextObject()->setGlobalBaseUrl(qmlFile);
        currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
438
439
    }

440
    m_stackedWidget->setCurrentWidget(currentQmlBackend->widget());
441

442
    currentQmlBackend->context()->setContextProperty("finishedNotify", QVariant(true));
443

444
    currentQmlBackend->contextObject()->triggerSelectionChanged();
445

446
    m_qmlBackEndForCurrentType = currentQmlBackend;
447
448
449

}

450
void PropertyEditorView::selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
451
                                          const QList<ModelNode> &lastSelectedNodeList)
452
453
454
{
    Q_UNUSED(lastSelectedNodeList);

455
    if (selectedNodeList.isEmpty() || selectedNodeList.count() > 1)
456
        select(ModelNode());
457
    else if (m_selectedNode != selectedNodeList.first())
458
459
460
        select(selectedNodeList.first());
}

461
void PropertyEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
462
463
464
465
466
{
    if (m_selectedNode.isValid() && removedNode.isValid() && m_selectedNode == removedNode)
        select(m_selectedNode.parentProperty().parentModelNode());
}

467
void PropertyEditorView::modelAttached(Model *model)
468
{
Marco Bubke's avatar
Marco Bubke committed
469
    AbstractView::modelAttached(model);
470
471
472
473

    if (debug)
        qDebug() << Q_FUNC_INFO;

Thomas Hartmann's avatar
Thomas Hartmann committed
474
475
    m_locked = true;

476
    resetView();
477
478
    if (!m_setupCompleted) {
        m_singleShotTimer->setSingleShot(true);
Thomas Hartmann's avatar
Thomas Hartmann committed
479
        m_singleShotTimer->setInterval(100);
480
481
482
        connect(m_singleShotTimer, SIGNAL(timeout()), this, SLOT(setupPanes()));
        m_singleShotTimer->start();
    }
Thomas Hartmann's avatar
Thomas Hartmann committed
483
484

    m_locked = false;
485
486
}

487
void PropertyEditorView::modelAboutToBeDetached(Model *model)
488
{
Marco Bubke's avatar
Marco Bubke committed
489
    AbstractView::modelAboutToBeDetached(model);
490
    m_qmlBackEndForCurrentType->propertyEditorTransaction()->end();
491
492
493
494

    resetView();
}

495
void PropertyEditorView::propertiesRemoved(const QList<AbstractProperty>& propertyList)
496
497
498
499
{
    if (!m_selectedNode.isValid())
        return;

500
501
502
    if (!QmlObjectNode(m_selectedNode).isValid())
        return;

503
    foreach (const AbstractProperty &property, propertyList) {
504
505
506
        ModelNode node(property.parentModelNode());
        if (node == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == node) {
            setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name()));
507
            if (property.name().contains("anchor"))
508
                m_qmlBackEndForCurrentType->backendAnchorBinding().invalidate(m_selectedNode);
509
510
511
512
        }
    }
}

513
void PropertyEditorView::variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
514
{
515

516
517
518
    if (!m_selectedNode.isValid())
        return;

519
520
521
    if (!QmlObjectNode(m_selectedNode).isValid())
        return;

522
523
524
525
526
    foreach (const VariantProperty &property, propertyList) {
        ModelNode node(property.parentModelNode());

        if (node == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == node) {
            if ( QmlObjectNode(m_selectedNode).modelNode().property(property.name()).isBindingProperty())
527
                setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name()));
528
            else
529
                setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name()));
530
531
532
533
        }
    }
}

534
void PropertyEditorView::bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
535
536
537
538
{
    if (!m_selectedNode.isValid())
        return;

539
540
541
       if (!QmlObjectNode(m_selectedNode).isValid())
        return;

542
543
544
545
    foreach (const BindingProperty &property, propertyList) {
        ModelNode node(property.parentModelNode());

        if (node == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == node) {
546
            if (property.name().contains("anchor"))
547
                m_qmlBackEndForCurrentType->backendAnchorBinding().invalidate(m_selectedNode);
548
            if ( QmlObjectNode(m_selectedNode).modelNode().property(property.name()).isBindingProperty())
549
                setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name()));
550
            else
551
                setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name()));
552
553
554
555
        }
    }
}

556
void PropertyEditorView::signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty> & /*propertyList*/,
557
558
559
560
                                                    AbstractView::PropertyChangeFlags /*propertyChange*/)
{
}

561
void PropertyEditorView::instanceInformationsChange(const QMultiHash<ModelNode, InformationName> &informationChangeHash)
562
563
564
565
{
    if (!m_selectedNode.isValid())
        return;

566
    m_locked = true;
567
    QList<InformationName> informationNameList = informationChangeHash.values(m_selectedNode);
568
569
    if (informationNameList.contains(Anchor)
            || informationNameList.contains(HasAnchor))
570
        m_qmlBackEndForCurrentType->backendAnchorBinding().setup(QmlItemNode(m_selectedNode));
571
    m_locked = false;
572
573
}

574
void PropertyEditorView::nodeIdChanged(const ModelNode& node, const QString& newId, const QString& /*oldId*/)
575
{
576
    if (!m_selectedNode.isValid())
577
578
        return;

579
580
581
    if (!QmlObjectNode(m_selectedNode).isValid())
        return;

582
    if (node == m_selectedNode) {
583

584
        if (m_qmlBackEndForCurrentType)
585
            setValue(node, "id", newId);
586
    }
587
588
}

589
void PropertyEditorView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/)
Marco Bubke's avatar
Marco Bubke committed
590
591
592
{
}

593
void PropertyEditorView::select(const ModelNode &node)
594
{
595
    if (QmlObjectNode(node).isValid())
596
597
598
599
600
601
602
        m_selectedNode = node;
    else
        m_selectedNode = ModelNode();

    delayedResetView();
}

603
bool PropertyEditorView::hasWidget() const
604
605
606
607
{
    return true;
}

608
WidgetInfo PropertyEditorView::widgetInfo()
609
{
610
    return createWidgetInfo(m_stackedWidget, 0, QLatin1String("Properties"), WidgetInfo::RightPane, 0);
611
}
Thomas Hartmann's avatar
Thomas Hartmann committed
612

613
void PropertyEditorView::currentStateChanged(const ModelNode &node)
614
{
Thomas Hartmann's avatar
Thomas Hartmann committed
615
    QmlModelState newQmlModelState(node);
616
617
618
619
620
621
    Q_ASSERT(newQmlModelState.isValid());
    if (debug)
        qDebug() << Q_FUNC_INFO << newQmlModelState.name();
    delayedResetView();
}

622
void PropertyEditorView::instancePropertyChange(const QList<QPair<ModelNode, PropertyName> > &propertyList)
623
624
625
626
627
628
629
630
631
632
633
{
    if (!m_selectedNode.isValid())
        return;
    m_locked = true;

    typedef QPair<ModelNode, PropertyName> ModelNodePropertyPair;
    foreach (const ModelNodePropertyPair &propertyPair, propertyList) {
        const ModelNode modelNode = propertyPair.first;
        const QmlObjectNode qmlObjectNode(modelNode);
        const PropertyName propertyName = propertyPair.second;

634
        if (qmlObjectNode.isValid() && m_qmlBackEndForCurrentType && modelNode == m_selectedNode && qmlObjectNode.currentState().isValid()) {
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
            const AbstractProperty property = modelNode.property(propertyName);
            if (modelNode == m_selectedNode || qmlObjectNode.propertyChangeForCurrentState() == qmlObjectNode) {
                if ( !modelNode.hasProperty(propertyName) || modelNode.property(property.name()).isBindingProperty() )
                    setValue(modelNode, property.name(), qmlObjectNode.instanceValue(property.name()));
                else
                    setValue(modelNode, property.name(), qmlObjectNode.modelValue(property.name()));
            }
        }

    }

    m_locked = false;

}

650
void PropertyEditorView::nodeCreated(const ModelNode &/*createdNode*/)
651
652
653
654
{

}

655
void PropertyEditorView::nodeRemoved(const ModelNode &/*removedNode*/, const NodeAbstractProperty &/*parentProperty*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
656
657
658
659
{

}

660
void PropertyEditorView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
661
662
663
664
{

}

665
void PropertyEditorView::nodeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
666
667
668
669
{

}

670
void PropertyEditorView::propertiesAboutToBeRemoved(const QList<AbstractProperty> &/*propertyList*/)
671
672
673
674
{

}

675
void PropertyEditorView::rootNodeTypeChanged(const QString &/*type*/, int /*majorVersion*/, int /*minorVersion*/)
676
677
678
679
{
    // TODO: we should react to this case
}

680
void PropertyEditorView::instancesCompleted(const QVector<ModelNode> &/*completedNodeList*/)
681
682
683
684
{

}

685
void PropertyEditorView::instancesRenderImageChanged(const QVector<ModelNode> &/*nodeList*/)
686
687
688
689
{

}

690
void PropertyEditorView::instancesPreviewImageChanged(const QVector<ModelNode> &/*nodeList*/)
691
692
693
694
{

}

695
void PropertyEditorView::instancesChildrenChanged(const QVector<ModelNode> &/*nodeList*/)
696
697
698
699
{

}

700
void PropertyEditorView::instancesToken(const QString &/*tokenName*/, int /*tokenNumber*/, const QVector<ModelNode> &/*nodeVector*/)
701
702
703
704
{

}

705
void PropertyEditorView::nodeSourceChanged(const ModelNode &/*modelNode*/, const QString &/*newNodeSource*/)
706
707
708
709
{

}

710
void PropertyEditorView::rewriterBeginTransaction()
711
712
713
714
{

}

715
void PropertyEditorView::rewriterEndTransaction()
716
717
718
719
{

}

720
void PropertyEditorView::nodeOrderChanged(const NodeListProperty &/*listProperty*/, const ModelNode &/*movedNode*/, int /*oldIndex*/)
721
722
723
724
{

}

725
void PropertyEditorView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/)
726
727
728
729
{

}

730
void PropertyEditorView::setValue(const QmlObjectNode &qmlObjectNode, const PropertyName &name, const QVariant &value)
731
732
{
    m_locked = true;
733
    m_qmlBackEndForCurrentType->setValue(qmlObjectNode, name, value);
734
735
736
    m_locked = false;
}

737
void PropertyEditorView::reloadQml()
738
{
739
    m_qmlBackendHash.clear();
740
741
742
743
    while (QWidget *widget = m_stackedWidget->widget(0)) {
        m_stackedWidget->removeWidget(widget);
        delete widget;
    }
744
    m_qmlBackEndForCurrentType = 0;
745
746
747
748

    delayedResetView();
}

749

750
751
} //QmlDesigner