src/declarative/qml/qdeclarativeenginedebug.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    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 {
   394         bool ok = m_watch->addWatch(queryId, debugId, expr);
   419         bool ok = m_watch->addWatch(queryId, debugId, expr);
   395 
   420 
   396         QByteArray reply;
   421         QByteArray reply;
   397         QDataStream rs(&reply, QIODevice::WriteOnly);
   422         QDataStream rs(&reply, QIODevice::WriteOnly);
   398         rs << QByteArray("WATCH_EXPR_OBJECT_R") << queryId << ok;
   423         rs << QByteArray("WATCH_EXPR_OBJECT_R") << queryId << ok;
   399 
       
   400         sendMessage(reply);
   424         sendMessage(reply);
   401     } else if (type == "NO_WATCH") {
   425     } else if (type == "NO_WATCH") {
   402         int queryId;
   426         int queryId;
   403 
   427 
   404         ds >> queryId;
   428         ds >> queryId;
   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;