48 #include "private/qdeclarativeproperty_p.h" |
48 #include "private/qdeclarativeproperty_p.h" |
49 #include "private/qdeclarativebinding_p.h" |
49 #include "private/qdeclarativebinding_p.h" |
50 #include "private/qdeclarativecontext_p.h" |
50 #include "private/qdeclarativecontext_p.h" |
51 #include "private/qdeclarativewatcher_p.h" |
51 #include "private/qdeclarativewatcher_p.h" |
52 #include "private/qdeclarativevaluetype_p.h" |
52 #include "private/qdeclarativevaluetype_p.h" |
|
53 #include "private/qdeclarativevmemetaobject_p.h" |
|
54 #include "private/qdeclarativeexpression_p.h" |
53 |
55 |
54 #include <QtCore/qdebug.h> |
56 #include <QtCore/qdebug.h> |
55 #include <QtCore/qmetaobject.h> |
57 #include <QtCore/qmetaobject.h> |
56 |
58 |
57 QT_BEGIN_NAMESPACE |
59 QT_BEGIN_NAMESPACE |
58 |
60 |
59 QList<QDeclarativeEngine *> QDeclarativeEngineDebugServer::m_engines; |
61 QList<QDeclarativeEngine *> QDeclarativeEngineDebugServer::m_engines; |
60 QDeclarativeEngineDebugServer::QDeclarativeEngineDebugServer(QObject *parent) |
62 QDeclarativeEngineDebugServer::QDeclarativeEngineDebugServer(QObject *parent) |
61 : QDeclarativeDebugService(QLatin1String("QDeclarativeEngine"), parent), |
63 : QDeclarativeDebugService(QLatin1String("QDeclarativeEngine"), parent), |
62 m_watch(new QDeclarativeWatcher(this)) |
64 m_watch(new QDeclarativeWatcher(this)) |
63 { |
65 { |
64 QObject::connect(m_watch, SIGNAL(propertyChanged(int,int,QMetaProperty,QVariant)), |
66 QObject::connect(m_watch, SIGNAL(propertyChanged(int,int,QMetaProperty,QVariant)), |
65 this, SLOT(propertyChanged(int,int,QMetaProperty,QVariant))); |
67 this, SLOT(propertyChanged(int,int,QMetaProperty,QVariant))); |
66 } |
68 } |
67 |
69 |
95 int type; |
97 int type; |
96 ds >> type >> data.name >> data.value >> data.valueTypeName |
98 ds >> type >> data.name >> data.value >> data.valueTypeName |
97 >> data.binding >> data.hasNotifySignal; |
99 >> data.binding >> data.hasNotifySignal; |
98 data.type = (QDeclarativeEngineDebugServer::QDeclarativeObjectProperty::Type)type; |
100 data.type = (QDeclarativeEngineDebugServer::QDeclarativeObjectProperty::Type)type; |
99 return ds; |
101 return ds; |
|
102 } |
|
103 |
|
104 static inline bool isSignalPropertyName(const QString &signalName) |
|
105 { |
|
106 // see QmlCompiler::isSignalPropertyName |
|
107 return signalName.length() >= 3 && signalName.startsWith(QLatin1String("on")) && |
|
108 signalName.at(2).isLetter() && signalName.at(2).isUpper(); |
|
109 } |
|
110 |
|
111 static bool hasValidSignal(QObject *object, const QString &propertyName) |
|
112 { |
|
113 if (!isSignalPropertyName(propertyName)) |
|
114 return false; |
|
115 |
|
116 QString signalName = propertyName.mid(2); |
|
117 signalName[0] = signalName.at(0).toLower(); |
|
118 |
|
119 int sigIdx = QDeclarativePropertyPrivate::findSignalByName(object->metaObject(), signalName.toLatin1()).methodIndex(); |
|
120 |
|
121 if (sigIdx == -1) |
|
122 return false; |
|
123 |
|
124 return true; |
100 } |
125 } |
101 |
126 |
102 QDeclarativeEngineDebugServer::QDeclarativeObjectProperty |
127 QDeclarativeEngineDebugServer::QDeclarativeObjectProperty |
103 QDeclarativeEngineDebugServer::propertyData(QObject *obj, int propIdx) |
128 QDeclarativeEngineDebugServer::propertyData(QObject *obj, int propIdx) |
104 { |
129 { |
428 QByteArray reply; |
452 QByteArray reply; |
429 QDataStream rs(&reply, QIODevice::WriteOnly); |
453 QDataStream rs(&reply, QIODevice::WriteOnly); |
430 rs << QByteArray("EVAL_EXPRESSION_R") << queryId << result; |
454 rs << QByteArray("EVAL_EXPRESSION_R") << queryId << result; |
431 |
455 |
432 sendMessage(reply); |
456 sendMessage(reply); |
433 } |
457 } else if (type == "SET_BINDING") { |
|
458 int objectId; |
|
459 QString propertyName; |
|
460 QVariant expr; |
|
461 bool isLiteralValue; |
|
462 ds >> objectId >> propertyName >> expr >> isLiteralValue; |
|
463 setBinding(objectId, propertyName, expr, isLiteralValue); |
|
464 } else if (type == "RESET_BINDING") { |
|
465 int objectId; |
|
466 QString propertyName; |
|
467 ds >> objectId >> propertyName; |
|
468 resetBinding(objectId, propertyName); |
|
469 } else if (type == "SET_METHOD_BODY") { |
|
470 int objectId; |
|
471 QString methodName; |
|
472 QString methodBody; |
|
473 ds >> objectId >> methodName >> methodBody; |
|
474 setMethodBody(objectId, methodName, methodBody); |
|
475 } |
|
476 } |
|
477 |
|
478 void QDeclarativeEngineDebugServer::setBinding(int objectId, |
|
479 const QString &propertyName, |
|
480 const QVariant &expression, |
|
481 bool isLiteralValue) |
|
482 { |
|
483 QObject *object = objectForId(objectId); |
|
484 QDeclarativeContext *context = qmlContext(object); |
|
485 |
|
486 if (object && context) { |
|
487 |
|
488 if (isLiteralValue) { |
|
489 QDeclarativeProperty literalProperty(object, propertyName, context); |
|
490 literalProperty.write(expression); |
|
491 } else { |
|
492 if (hasValidSignal(object, propertyName)) { |
|
493 QDeclarativeProperty property(object, propertyName); |
|
494 QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString()); |
|
495 QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression); |
|
496 } else { |
|
497 QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context); |
|
498 QDeclarativeProperty property(object, propertyName, context); |
|
499 binding->setTarget(property); |
|
500 binding->setNotifyOnValueChanged(true); |
|
501 QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding); |
|
502 if (oldBinding) |
|
503 oldBinding->destroy(); |
|
504 binding->update(); |
|
505 } |
|
506 } |
|
507 } |
|
508 } |
|
509 |
|
510 void QDeclarativeEngineDebugServer::resetBinding(int objectId, const QString &propertyName) |
|
511 { |
|
512 QObject *object = objectForId(objectId); |
|
513 QDeclarativeContext *context = qmlContext(object); |
|
514 |
|
515 if (object && context) { |
|
516 if (object->property(propertyName.toLatin1()).isValid()) { |
|
517 QDeclarativeProperty property(object, propertyName); |
|
518 QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(property); |
|
519 if (oldBinding) { |
|
520 QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, 0); |
|
521 if (oldBinding) |
|
522 oldBinding->destroy(); |
|
523 } else { |
|
524 if (property.isResettable()) { |
|
525 property.reset(); |
|
526 } |
|
527 } |
|
528 } |
|
529 } |
|
530 } |
|
531 |
|
532 void QDeclarativeEngineDebugServer::setMethodBody(int objectId, const QString &method, const QString &body) |
|
533 { |
|
534 QObject *object = objectForId(objectId); |
|
535 QDeclarativeContext *context = qmlContext(object); |
|
536 if (!object || !context || !context->engine()) |
|
537 return; |
|
538 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context); |
|
539 if (!contextData) |
|
540 return; |
|
541 |
|
542 QDeclarativePropertyCache::Data dummy; |
|
543 QDeclarativePropertyCache::Data *prop = |
|
544 QDeclarativePropertyCache::property(context->engine(), object, method, dummy); |
|
545 |
|
546 if (!prop || !(prop->flags & QDeclarativePropertyCache::Data::IsVMEFunction)) |
|
547 return; |
|
548 |
|
549 QMetaMethod metaMethod = object->metaObject()->method(prop->coreIndex); |
|
550 QList<QByteArray> paramNames = metaMethod.parameterNames(); |
|
551 |
|
552 QString paramStr; |
|
553 for (int ii = 0; ii < paramNames.count(); ++ii) { |
|
554 if (ii != 0) paramStr.append(QLatin1String(",")); |
|
555 paramStr.append(QString::fromUtf8(paramNames.at(ii))); |
|
556 } |
|
557 |
|
558 QString jsfunction = QLatin1String("(function ") + method + QLatin1String("(") + paramStr + |
|
559 QLatin1String(") {"); |
|
560 jsfunction += body; |
|
561 jsfunction += QLatin1String("\n})"); |
|
562 |
|
563 QDeclarativeVMEMetaObject *vmeMetaObject = |
|
564 static_cast<QDeclarativeVMEMetaObject*>(QObjectPrivate::get(object)->metaObject); |
|
565 Q_ASSERT(vmeMetaObject); // the fact we found the property above should guarentee this |
|
566 |
|
567 int lineNumber = vmeMetaObject->vmeMethodLineNumber(prop->coreIndex); |
|
568 vmeMetaObject->setVmeMethod(prop->coreIndex, QDeclarativeExpressionPrivate::evalInObjectScope(contextData, object, jsfunction, contextData->url.toString(), lineNumber, 0)); |
434 } |
569 } |
435 |
570 |
436 void QDeclarativeEngineDebugServer::propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value) |
571 void QDeclarativeEngineDebugServer::propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value) |
437 { |
572 { |
438 QByteArray reply; |
573 QByteArray reply; |