Exemplo n.º 1
0
QScriptValue UniversalInputDialogScript::add(const QScriptValue& def, const QScriptValue& description, const QScriptValue& id){
	QWidget* w = 0;
	if (def.isArray()) {
		QStringList options;
		QScriptValueIterator it(def);
		while (it.hasNext()) {
			it.next();
			if (it.flags() & QScriptValue::SkipInEnumeration)
				continue;
			if (it.value().isString() || it.value().isNumber()) options << it.value().toString();
			else engine->currentContext()->throwError("Invalid default value in array (must be string or number): "+it.value().toString());
		}
		w = addComboBox(ManagedProperty::fromValue(options), description.toString());
	} else if (def.isBool()) {
		w = addCheckBox(ManagedProperty::fromValue(def.toBool()), description.toString());
	} else if (def.isNumber()) {
		w = addDoubleSpinBox(ManagedProperty::fromValue(def.toNumber()), description.toString());
	} else if (def.isString()) {
		w = addLineEdit(ManagedProperty::fromValue(def.toString()), description.toString());
	} else {	
		
		engine->currentContext()->throwError(tr("Invalid default value: %1").arg(def.toString()));
		return QScriptValue();
	}
	if (id.isValid()) properties.last().name = id.toString();
	return engine->newQObject(w);
}
void tst_QScriptContext::qobjectAsActivationObject()
{
    QScriptEngine eng;
    QObject object;
    QScriptValue scriptObject = eng.newQObject(&object);
    QScriptContext *ctx = eng.pushContext();
    ctx->setActivationObject(scriptObject);
    QVERIFY(ctx->activationObject().equals(scriptObject));

    QVERIFY(!scriptObject.property("foo").isValid());
    eng.evaluate("function foo() { return 123; }");
    {
        QScriptValue val = scriptObject.property("foo");
        QVERIFY(val.isValid());
        QVERIFY(val.isFunction());
    }
    QVERIFY(!eng.globalObject().property("foo").isValid());

    QVERIFY(!scriptObject.property("bar").isValid());
    eng.evaluate("var bar = 123");
    {
        QScriptValue val = scriptObject.property("bar");
        QVERIFY(val.isValid());
        QVERIFY(val.isNumber());
        QCOMPARE(val.toInt32(), 123);
    }
    QVERIFY(!eng.globalObject().property("bar").isValid());

    {
        QScriptValue val = eng.evaluate("delete foo");
        QVERIFY(val.isBool());
        QVERIFY(val.toBool());
        QVERIFY(!scriptObject.property("foo").isValid());
    }
}
Exemplo n.º 3
0
bool EnvWrap::evalBool( const QString& nm )
{
	QScriptValue result = evalExp(nm);
	if (result.isBool())
		return result.toBool();
	else
		throw ExpressionHasNotThisTypeException("Bool",nm);
	return false;
}
Exemplo n.º 4
0
void ScriptHandler::validateData(DataInformation* data)
{
    if (!data)
        return;

    data->setHasBeenValidated(false); //not yet validated

    if (data->hasChildren())
    {
        //first validate the children
        for (uint i = 0; i < data->childCount(); ++i)
        {
            validateData(data->childAt(i));
        }
    }

    //check if has a validation function:
    AdditionalData* additionalData = data->additionalData();
    if (additionalData && additionalData->validationFunction().isValid())
    {
        //value exists, we assume it has been checked to be a function
#ifdef OKTETA_DEBUG_SCRIPT
        mDebugger->attachTo(mEngine);
        mDebugger->action(QScriptEngineDebugger::InterruptAction)->trigger();
        kDebug()
        << "validating element: " << data->name();
#endif

//         QScriptValue thisObject = mEngine->newQObject(data,
//                 QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater);
//         QScriptValue mainStruct = mEngine->newQObject(data->mainStructure(),
//                 QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater);
        QScriptValue thisObject = data->toScriptValue(mEngine, &mHandlerInfo);
        QScriptValue mainStruct = data->mainStructure()->toScriptValue(mEngine, &mHandlerInfo);
        QScriptValueList args;
        args << mainStruct;
        QScriptValue result = additionalData->validationFunction().call(thisObject, args);
        if (result.isError())
        {
            ScriptUtils::object()->logScriptError(QLatin1String("error occurred while "
                "validating element ") + data->name(), result);
            data->setValidationError(QLatin1String("Error occurred in validation: ")
                    + result.toString());
        }
        if (mEngine->hasUncaughtException())
        {
            ScriptUtils::object()->logScriptError(
                    mEngine->uncaughtExceptionBacktrace());
            data->setValidationError(QLatin1String("Error occurred in validation: ")
                    + result.toString());
        }
        if (result.isBool() || result.isBoolean())
        {
            data->setValidationSuccessful(result.toBool());
        }
    }
}
Exemplo n.º 5
0
static JSAgentWatchData fromScriptValue(const QString &expression,
                                        const QScriptValue &value)
{
    static const QString arrayStr = QCoreApplication::translate
            ("Debugger::JSAgentWatchData", "[Array of length %1]");
    static const QString undefinedStr = QCoreApplication::translate
            ("Debugger::JSAgentWatchData", "<undefined>");

    JSAgentWatchData data;
    data.exp = expression.toUtf8();
    data.name = data.exp;
    data.hasChildren = false;
    data.value = value.toString().toUtf8();
    data.objectId = value.objectId();
    if (value.isArray()) {
        data.type = "Array";
        data.value = arrayStr.arg(value.property(QLatin1String("length")).toString()).toUtf8();
        data.hasChildren = true;
    } else if (value.isBool()) {
        data.type = "Bool";
        // data.value = value.toBool() ? "true" : "false";
    } else if (value.isDate()) {
        data.type = "Date";
        data.value = value.toDateTime().toString().toUtf8();
    } else if (value.isError()) {
        data.type = "Error";
    } else if (value.isFunction()) {
        data.type = "Function";
    } else if (value.isUndefined()) {
        data.type = undefinedStr.toUtf8();
    } else if (value.isNumber()) {
        data.type = "Number";
    } else if (value.isRegExp()) {
        data.type = "RegExp";
    } else if (value.isString()) {
        data.type = "String";
    } else if (value.isVariant()) {
        data.type = "Variant";
    } else if (value.isQObject()) {
        const QObject *obj = value.toQObject();
        data.type = "Object";
        data.value += '[';
        data.value += obj->metaObject()->className();
        data.value += ']';
        data.hasChildren = true;
    } else if (value.isObject()) {
        data.type = "Object";
        data.hasChildren = true;
        data.value = "[Object]";
    } else if (value.isNull()) {
        data.type = "<null>";
    } else {
        data.type = "<unknown>";
    }
    return data;
}
Exemplo n.º 6
0
/*! Emits the \a saving() signal which triggers any widgets to save that have a mapped \a savedMethod()
  specified by \sa insert().  Also reloads metrics, privileges, preferences, and the menubar in the
  main application.  The screen will close if \a close is true.

  \sa apply()
  */
void setup::save(bool close)
{
  emit saving();

  QMapIterator<QString, ItemProps> i(_itemMap);
  while (i.hasNext())
  {
    bool ok = false;

    i.next();

    XAbstractConfigure *cw = qobject_cast<XAbstractConfigure*>(i.value().implementation);
    QScriptEngine  *engine = qobject_cast<QScriptEngine*>(i.value().implementation);
    QString method = QString(i.value().saveMethod).remove("(").remove(")");

    if (! i.value().implementation)
      continue;
    else if (cw)
      ok = cw->sSave();
    else if (engine && engine->globalObject().property(method).isFunction())
    {
      QScriptValue saveresult = engine->globalObject().property(method).call();
      if (saveresult.isBool())
        ok = saveresult.toBool();
      else
        qWarning("Problem executing %s method for script %s",
                 qPrintable(i.value().saveMethod), qPrintable(i.key()));
    }
    else
    {
      qWarning("Could not call save method for %s; it's a(n) %s (%p)",
               qPrintable(i.key()),
               qobject_cast<QObject*>(i.value().implementation) ?
               qobject_cast<QObject*>(i.value().implementation)->metaObject()->className() : "unknown class",
               i.value().implementation);
      ok = true;
    }

    if (! ok)
    {
      setCurrentIndex(i.key());
      return;
    }
  }

  _metrics->load();
  _privileges->load();
  _preferences->load();
  omfgThis->initMenuBar();

  if (close)
    accept();
}
Exemplo n.º 7
0
void AnimVariantMap::animVariantMapFromScriptValue(const QScriptValue& source) {
    if (QThread::currentThread() != source.engine()->thread()) {
        qCWarning(animation) << "Cannot examine Javacript object from non-script thread" << QThread::currentThread();
        Q_ASSERT(false);
        return;
    }
    // POTENTIAL OPTIMIZATION: cache the types we've seen. I.e, keep a dictionary mapping property names to an enumeration of types.
    // Whenever we identify a new outbound type in animVariantMapToScriptValue above, or a new inbound type in the code that follows here,
    // we would enter it into the dictionary. Then switch on that type here, with the code that follow being executed only if
    // the type is not known. One problem with that is that there is no checking that two different script use the same name differently.
    QScriptValueIterator property(source);
    // Note: QScriptValueIterator iterates only over source's own properties. It does not follow the prototype chain.
    while (property.hasNext()) {
        property.next();
        QScriptValue value = property.value();
        if (value.isBool()) {
            set(property.name(), value.toBool());
        } else if (value.isString()) {
            set(property.name(), value.toString());
        } else if (value.isNumber()) {
            int asInteger = value.toInt32();
            float asFloat = value.toNumber();
            if (asInteger == asFloat) {
                set(property.name(), asInteger);
            } else {
                set(property.name(), asFloat);
            }
        } else { // Try to get x,y,z and possibly w
            if (value.isObject()) {
                QScriptValue x = value.property("x");
                if (x.isNumber()) {
                    QScriptValue y = value.property("y");
                    if (y.isNumber()) {
                        QScriptValue z = value.property("z");
                        if (z.isNumber()) {
                            QScriptValue w = value.property("w");
                            if (w.isNumber()) {
                                set(property.name(), glm::quat(w.toNumber(), x.toNumber(), y.toNumber(), z.toNumber()));
                            } else {
                                set(property.name(), glm::vec3(x.toNumber(), y.toNumber(), z.toNumber()));
                            }
                            continue; // we got either a vector or quaternion object, so don't fall through to warning
                        }
                    }
                }
            }
            qCWarning(animation) << "Ignoring unrecognized data" << value.toString() << "for animation property" << property.name();
            Q_ASSERT(false);
        }
    }
}
Exemplo n.º 8
0
QScriptValue ScriptableSyntaxDefinition::OPTION_(QScriptContext* context, QScriptEngine* engine)
{
	checkNumberOfArguments(context, 2);
	const char* name = 0;
	constCharFromScriptValue(context->argument(0), name);
	QScriptValue value = context->argument(1);
	if (value.isBool())
		super(context)->OPTION(name, value.toBool());
	/*else if (value.isNumber())
		super(context)->OPTION(name, value.toInt32());
	else if (value.isString())
		super(context)->OPTION(name, value.toString());*/
	return QScriptValue();
}
Exemplo n.º 9
0
void JavascriptInstance::GetObjectInformation(const QScriptValue &object, QSet<qint64> &ids, uint &valueCount, uint &objectCount, uint &nullCount, uint &numberCount, 
    uint &boolCount, uint &stringCount, uint &arrayCount, uint &funcCount, uint &qobjCount, uint &qobjMethodCount)
{
    if (!ids.contains(object.objectId()))       
        ids << object.objectId();
    
    QScriptValueIterator iter(object);
    while(iter.hasNext()) 
    {
        iter.next();
        QScriptValue v = iter.value();

        if (ids.contains(v.objectId()))
            continue;
        ids << v.objectId();
        
        valueCount++;
        if (v.isNull())
            nullCount++;

        if (v.isNumber())
            numberCount++;
        else if (v.isBool())
            boolCount++;
        else if (v.isString())
            stringCount++;
        else if (v.isArray())
            arrayCount++;
        else if (v.isFunction())
            funcCount++;
        else if (v.isQObject())
            qobjCount++;
        
        if (v.isObject())
            objectCount++;

        if (v.isQMetaObject())
            qobjMethodCount += v.toQMetaObject()->methodCount();
        
        // Recurse
        if ((v.isObject() || v.isArray()) && !v.isFunction() && !v.isString() && !v.isNumber() && !v.isBool() && !v.isQObject() && !v.isQMetaObject())
            GetObjectInformation(v, ids, valueCount, objectCount, nullCount, numberCount, boolCount, stringCount, arrayCount, funcCount, qobjCount, qobjMethodCount);
    }
}
Exemplo n.º 10
0
void ScriptHandler::validateData(DataInformation* data)
{
    Q_CHECK_PTR(data);

    if (data->hasBeenValidated())
        return;
    //first validate the children
    for (uint i = 0; i < data->childCount(); ++i)
        validateData(data->childAt(i));

    //check if has a validation function:
    QScriptValue validationFunc = data->validationFunc();
    if (validationFunc.isValid())
    {
        QScriptValue result = callFunction(validationFunc, data, ScriptHandlerInfo::Validating);
        if (result.isError())
        {
            mTopLevel->logger()->error(data) << "Error occurred while validating element: "
                    << result.toString();
            data->setValidationError(QStringLiteral("Error occurred in validation: ")
                    + result.toString());
        }
        else if (mEngine->hasUncaughtException())
        {
            mTopLevel->logger()->error(data) << "Error occurred while validating element:"
                    << result.toString() << "\nBacktrace:" << mEngine->uncaughtExceptionBacktrace();
            data->setValidationError(QStringLiteral("Error occurred in validation: ")
                    + result.toString());
            mEngine->clearExceptions();
        }
        if (result.isBool() || result.isBoolean())
        {
            data->mValidationSuccessful = result.toBool();
        }
        if (result.isString())
        {
            //error string
            QString str = result.toString();
            if (!str.isEmpty())
                data->setValidationError(str);
        }
        data->mHasBeenValidated = true;
    }
}
Exemplo n.º 11
0
bool BreakpointConditionChecker::evaluateCondition(const AttributeScript *conditionContext) {
    Q_ASSERT(NULL != conditionContext);

    QMutexLocker lock(&engineGuard);

    if (NULL == engine || NULL == engine->getWorkflowContext()) {
        return false;
    }
    if (conditionText.isEmpty() || !enabled) {
        return true;
    }

    QMap<QString, QScriptValue> scriptVars;
    foreach (const Descriptor & key, conditionContext->getScriptVars().uniqueKeys()) {
        assert(!key.getId().isEmpty());
        scriptVars[key.getId()] = engine->newVariant(conditionContext->getScriptVars().value(key));
    }
    TaskStateInfo stateInfo;
    QScriptValue evaluationResult = ScriptTask::runScript(engine, scriptVars, conditionText,
        stateInfo);
    if (stateInfo.hasError()) {
        coreLog.error("Breakpoint condition evaluation failed. Error:\n" + stateInfo.getError());
        return false;
    } else if (evaluationResult.isBool()) {
        bool evaluatedResult = evaluationResult.toBool();
        if (HAS_CHANGED == parameter) {
            const bool returningValue = (DEFAULT_CONDITION_EVAL_RESULT == lastConditionEvaluation)
                ? false : (static_cast<bool>(lastConditionEvaluation) != evaluatedResult);
            lastConditionEvaluation = static_cast<int>(evaluatedResult);
            evaluatedResult = returningValue;
        }
        coreLog.trace(QString("Condition of breakpoint is %1").arg(evaluatedResult
            ? "true" : "false"));
        return evaluatedResult;
    } else {
        coreLog.error("Breakpoint condition's evaluation has provided no boolean value");
        return false;
    }
}
Exemplo n.º 12
0
QVariant scriptValueToVariant(const QScriptValue &value)
{
	QVariant var;
	if (value.isBool() || value.isNumber()
		|| value.isString() || value.isVariant()
		|| value.isDate() || value.isRegExp()) {
		var = value.toVariant();
	} else if (value.isArray()) {
		QVariantList list;
		int len = value.property(QLatin1String("length")).toInt32();
		for (int i = 0; i < len; i++)
			list << scriptValueToVariant(value.property(i));
		var = list;
	} else if (value.isObject()) {
		QVariantMap map;
		QScriptValueIterator it(value);
		while (it.hasNext()) {
			it.next();
			map.insert(it.name(), scriptValueToVariant(it.value()));
		}
		var = map;
	}
	return var;
}
Exemplo n.º 13
0
/// Display a form layout with an edit box
/// \param const QString& title title to display
/// \param const QScriptValue form to display (array containing labels and values)
/// \return QScriptValue result form (unchanged is dialog canceled)
QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptValue form) {
    if (form.isArray() && form.property("length").toInt32() > 0) {
        QDialog* editDialog = new QDialog(Application::getInstance()->getWindow());
        editDialog->setWindowTitle(title);
        
        QVBoxLayout* layout = new QVBoxLayout();
        editDialog->setLayout(layout);
        
        QScrollArea* area = new QScrollArea();
        layout->addWidget(area);
        area->setWidgetResizable(true);
        QWidget* container = new QWidget();
        QFormLayout* formLayout = new QFormLayout();
        container->setLayout(formLayout);
        container->sizePolicy().setHorizontalStretch(1);
        formLayout->setRowWrapPolicy(QFormLayout::DontWrapRows);
        formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
        formLayout->setFormAlignment(Qt::AlignHCenter | Qt::AlignTop);
        formLayout->setLabelAlignment(Qt::AlignLeft);
        
        area->setWidget(container);
        
        QVector<QLineEdit*> edits;
        for (int i = 0; i < form.property("length").toInt32(); ++i) {
            QScriptValue item = form.property(i);
            edits.push_back(new QLineEdit(item.property("value").toString()));
            formLayout->addRow(item.property("label").toString(), edits.back());
        }
        QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok);
        connect(buttons, SIGNAL(accepted()), editDialog, SLOT(accept()));
        layout->addWidget(buttons);
        
        if (editDialog->exec() == QDialog::Accepted) {
            for (int i = 0; i < form.property("length").toInt32(); ++i) {
                QScriptValue item = form.property(i);
                QScriptValue value = item.property("value");
                bool ok = true;
                if (value.isNumber()) {
                    value = edits.at(i)->text().toDouble(&ok);
                } else if (value.isString()) {
                    value = edits.at(i)->text();
                } else if (value.isBool()) {
                    if (edits.at(i)->text() == "true") {
                        value = true;
                    } else if (edits.at(i)->text() == "false") {
                        value = false;
                    } else {
                        ok = false;
                    }
                }
                if (ok) {
                    item.setProperty("value", value);
                    form.setProperty(i, item);
                }
            }
        }
        
        delete editDialog;
    }
    
    return form;
}
Exemplo n.º 14
0
bool operator==(const QScriptValue& first, const QScriptValue& second) {
    if (first.isUndefined()) {
        return second.isUndefined();
        
    } else if (first.isNull()) {
        return second.isNull();
    
    } else if (first.isBool()) {
        return second.isBool() && first.toBool() == second.toBool();
    
    } else if (first.isNumber()) {
        return second.isNumber() && first.toNumber() == second.toNumber();
    
    } else if (first.isString()) {
        return second.isString() && first.toString() == second.toString();
    
    } else if (first.isVariant()) {
        return second.isVariant() && first.toVariant() == second.toVariant();
        
    } else if (first.isQObject()) {
        return second.isQObject() && first.toQObject() == second.toQObject();
    
    } else if (first.isQMetaObject()) {
        return second.isQMetaObject() && first.toQMetaObject() == second.toQMetaObject();
        
    } else if (first.isDate()) {
        return second.isDate() && first.toDateTime() == second.toDateTime();
    
    } else if (first.isRegExp()) {
        return second.isRegExp() && first.toRegExp() == second.toRegExp();
    
    } else if (first.isArray()) {
        if (!second.isArray()) {
            return false;
        }
        int length = first.property(ScriptCache::getInstance()->getLengthString()).toInt32();
        if (second.property(ScriptCache::getInstance()->getLengthString()).toInt32() != length) {
            return false;
        }
        for (int i = 0; i < length; i++) {
            if (first.property(i) != second.property(i)) {
                return false;
            }
        }
        return true;
        
    } else if (first.isObject()) {
        if (!second.isObject()) {
            return false;
        }
        int propertyCount = 0;
        for (QScriptValueIterator it(first); it.hasNext(); ) {
            it.next();
            if (second.property(it.scriptName()) != it.value()) {
                return false;
            }
            propertyCount++;
        }
        // make sure the second has exactly as many properties as the first
        for (QScriptValueIterator it(second); it.hasNext(); ) {
            it.next();
            if (--propertyCount < 0) {
                return false;
            }
        }
        return true;
        
    } else {
        // if none of the above tests apply, first must be invalid
        return !second.isValid();
    }
}
Exemplo n.º 15
0
bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut,
        bool& wasChanged, EntityTree::FilterType filterType, EntityItemID& itemID, EntityItemPointer& existingEntity) {
    
    // get the ids of all the zones (plus the global entity edit filter) that the position
    // lies within
    auto zoneIDs = getZonesByPosition(position);
    for (auto id : zoneIDs) {
        if (!itemID.isInvalidID() && id == itemID) {
            continue;
        }
        
        // get the filter pair, etc...  
        _lock.lockForRead();
        FilterData filterData = _filterDataMap.value(id);
        _lock.unlock();
    
        if (filterData.valid()) {
            if (filterData.rejectAll) {
                return false;
            }

            // check to see if this filter wants to filter this message type
            if ((!filterData.wantsToFilterEdit && filterType == EntityTree::FilterType::Edit) ||
                (!filterData.wantsToFilterPhysics && filterType == EntityTree::FilterType::Physics) ||
                (!filterData.wantsToFilterDelete && filterType == EntityTree::FilterType::Delete) ||
                (!filterData.wantsToFilterAdd && filterType == EntityTree::FilterType::Add)) {

                wasChanged = false;
                return true; // accept the message
            }

            auto oldProperties = propertiesIn.getDesiredProperties();
            auto specifiedProperties = propertiesIn.getChangedProperties();
            propertiesIn.setDesiredProperties(specifiedProperties);
            QScriptValue inputValues = propertiesIn.copyToScriptValue(filterData.engine, false, true, true);
            propertiesIn.setDesiredProperties(oldProperties);

            auto in = QJsonValue::fromVariant(inputValues.toVariant()); // grab json copy now, because the inputValues might be side effected by the filter.

            QScriptValueList args;
            args << inputValues;
            args << filterType;

            // get the current properties for then entity and include them for the filter call
            if (existingEntity && filterData.wantsOriginalProperties) {
                auto currentProperties = existingEntity->getProperties(filterData.includedOriginalProperties);
                QScriptValue currentValues = currentProperties.copyToScriptValue(filterData.engine, false, true, true);
                args << currentValues;
            }


            // get the zone properties
            if (filterData.wantsZoneProperties) {
                auto zoneEntity = _tree->findEntityByEntityItemID(id);
                if (zoneEntity) {
                    auto zoneProperties = zoneEntity->getProperties(filterData.includedZoneProperties);
                    QScriptValue zoneValues = zoneProperties.copyToScriptValue(filterData.engine, false, true, true);

                    if (filterData.wantsZoneBoundingBox) {
                        bool success = true;
                        AABox aaBox = zoneEntity->getAABox(success);
                        if (success) {
                            QScriptValue boundingBox = filterData.engine->newObject();
                            QScriptValue bottomRightNear = vec3ToScriptValue(filterData.engine, aaBox.getCorner());
                            QScriptValue topFarLeft = vec3ToScriptValue(filterData.engine, aaBox.calcTopFarLeft());
                            QScriptValue center = vec3ToScriptValue(filterData.engine, aaBox.calcCenter());
                            QScriptValue boundingBoxDimensions = vec3ToScriptValue(filterData.engine, aaBox.getDimensions());
                            boundingBox.setProperty("brn", bottomRightNear);
                            boundingBox.setProperty("tfl", topFarLeft);
                            boundingBox.setProperty("center", center);
                            boundingBox.setProperty("dimensions", boundingBoxDimensions);
                            zoneValues.setProperty("boundingBox", boundingBox);
                        }
                    }

                    // If this is an add or delete, or original properties weren't requested
                    // there won't be original properties in the args, but zone properties need
                    // to be the fourth parameter, so we need to pad the args accordingly
                    int EXPECTED_ARGS = 3;
                    if (args.length() < EXPECTED_ARGS) {
                        args << QScriptValue();
                    }
                    assert(args.length() == EXPECTED_ARGS); // we MUST have 3 args by now!
                    args << zoneValues;
                }
            }

            QScriptValue result = filterData.filterFn.call(_nullObjectForFilter, args);

            if (filterData.uncaughtExceptions()) {
                return false;
            }

            if (result.isObject()) {
                // make propertiesIn reflect the changes, for next filter...
                propertiesIn.copyFromScriptValue(result, false);

                // and update propertiesOut too.  TODO: this could be more efficient...
                propertiesOut.copyFromScriptValue(result, false);
                // Javascript objects are == only if they are the same object. To compare arbitrary values, we need to use JSON.
                auto out = QJsonValue::fromVariant(result.toVariant());
                wasChanged |= (in != out);
            } else if (result.isBool()) {

                // if the filter returned false, then it's authoritative
                if (!result.toBool()) {
                    return false;
                }

                // otherwise, assume it wants to pass all properties
                propertiesOut = propertiesIn;
                wasChanged = false;
                
            } else {
                return false;
            }
        }
    }
    // if we made it here, 
    return true;
}
Exemplo n.º 16
0
/*!
 \brief

 \param tag
 \param fileInfo
 \param log
 \return bool
*/
bool PlayList::evaluateScript( Tag* tag, const QFileInfo& fileInfo, QString *log, QString *extInf, QString *sortBy ) const {

    if(script_.isEmpty()){
        return true;
    }

    ScriptEngine engine;
    QHash<QString,QVariant> frameFields = guiSettings->value("frameFields").toHash();

    //add all possible/specified id3v2 frames/ape items etc. to script, with empty array as value
    QHash< QString, QHash<QString,QStringList> > tagFrames = tag->frames(); //returns both ID3v2,asf,mp4,xiph and APE frames/items
    QStringList frameTypes = frameFields.keys(); //defined list of possible frames
    for(int j=0;j<frameTypes.size();j++){
        QString type = frameTypes[j]; //e.g. APE, ID3V2 etc.
        QStringList frameTypeKeys = frameFields[type].toStringList();
        QScriptValue array = engine.newArray(frameTypeKeys.size());
        QHash<QString,QStringList> tagTypeFrames = tagFrames[type];
        QStringList tagTypeFramesKeys = tagTypeFrames.keys();
        //loop for instance all ID3V2 frames
        QScriptValue v = engine.newArray(0);
        for(int i=0;i<frameTypeKeys.size();i++){
            v.setProperty(0, QScriptValue(&engine, "")); //set default value an empty array
            array.setProperty(frameTypeKeys[i].toUpper(), v);
        }//now add all frames from current tag
        for(int i=0;i<tagTypeFramesKeys.size();i++){
            QStringList list = tagTypeFrames[tagTypeFramesKeys[i]];
            for(int k=0;k<list.size();k++){
                v.setProperty(k, list[k]);
            }
            array.setProperty(tagTypeFramesKeys[i].toUpper(), v);
        }
        engine.globalObject().setProperty(type,array);
    }


    //add tag data  as variables to script
    engine.globalObject().setProperty("ARTIST",tag->artist());
    engine.globalObject().setProperty("ALBUM",tag->album());
    engine.globalObject().setProperty("GENRE",tag->genre());
    engine.globalObject().setProperty("TITLE",tag->title());
    engine.globalObject().setProperty("COMMENT",tag->comment());
    engine.globalObject().setProperty("YEAR",tag->year());
    engine.globalObject().setProperty("TRACK",tag->track());
    engine.globalObject().setProperty("LENGTH",tag->length());
    engine.globalObject().setProperty("BITRATE",tag->bitRate());
    engine.globalObject().setProperty("SAMPLERATE",tag->sampleRate());
    engine.globalObject().setProperty("CHANNELS",tag->channels());
    engine.globalObject().setProperty("TAGOK",tag->tagOk());
    engine.globalObject().setProperty("AUDIOPROPERTIESOK",tag->audioPropertiesOk());

    engine.globalObject().setProperty("FILENAME",fileInfo.fileName());
    engine.globalObject().setProperty("FILEPATH",fileInfo.filePath());    

    QScriptValue result = engine.evaluate( script_ );

    *extInf = engine.globalObject().property("EXTINF").toString();
    *sortBy = "";
    QScriptValue sortByValue = engine.globalObject().property("SORTBY");
    if( sortByValue.isValid() ){
        *sortBy = sortByValue.toString();
    }

    if( engine.hasUncaughtException() ){
        QString err = engine.uncaughtExceptionBacktrace().join("\n");
        log->append(err);
        return false;
    }
    bool res=false;
    if( result.isBool() ){
        res = result.toBool();
    }else{
        log->append("\nResult of evaluated script is not boolean");
    }
    return res;

}
Exemplo n.º 17
0
static void convertToPropertyType_impl(const QString &pathPropertiesBaseDir, const Item *item,
                                       const PropertyDeclaration& decl,
                                       const CodeLocation &location, QScriptValue &v)
{
    if (v.isUndefined() || v.isError())
        return;
    QString srcDir;
    QString actualBaseDir;
    if (item && !pathPropertiesBaseDir.isEmpty()) {
        const VariantValueConstPtr itemSourceDir
                = item->variantProperty(QLatin1String("sourceDirectory"));
        actualBaseDir = itemSourceDir ? itemSourceDir->value().toString() : pathPropertiesBaseDir;
    }
    switch (decl.type()) {
    case PropertyDeclaration::UnknownType:
    case PropertyDeclaration::Variant:
        break;
    case PropertyDeclaration::Boolean:
        if (!v.isBool())
            v = v.toBool();
        break;
    case PropertyDeclaration::Integer:
        if (!v.isNumber())
            makeTypeError(decl, location, v);
        break;
    case PropertyDeclaration::Path:
    {
        if (!v.isString()) {
            makeTypeError(decl, location, v);
            break;
        }
        const QString srcDir = item ? overriddenSourceDirectory(item, actualBaseDir)
                                    : pathPropertiesBaseDir;
        if (!srcDir.isEmpty())
            v = v.engine()->toScriptValue(QDir::cleanPath(
                                              FileInfo::resolvePath(srcDir, v.toString())));
        break;
    }
    case PropertyDeclaration::String:
        if (!v.isString())
            makeTypeError(decl, location, v);
        break;
    case PropertyDeclaration::PathList:
        srcDir = item ? overriddenSourceDirectory(item, actualBaseDir)
                      : pathPropertiesBaseDir;
        // Fall-through.
    case PropertyDeclaration::StringList:
    {
        if (!v.isArray()) {
            QScriptValue x = v.engine()->newArray(1);
            x.setProperty(0, v);
            v = x;
        }
        const quint32 c = v.property(StringConstants::lengthProperty()).toUInt32();
        for (quint32 i = 0; i < c; ++i) {
            QScriptValue elem = v.property(i);
            if (elem.isUndefined()) {
                ErrorInfo error(Tr::tr("Element at index %1 of list property '%2' is undefined. "
                                       "String expected.").arg(i).arg(decl.name()), location);
                makeTypeError(error, v);
                break;
            }
            if (elem.isNull()) {
                ErrorInfo error(Tr::tr("Element at index %1 of list property '%2' is null. "
                                       "String expected.").arg(i).arg(decl.name()), location);
                makeTypeError(error, v);
                break;
            }
            if (!elem.isString()) {
                ErrorInfo error(Tr::tr("Element at index %1 of list property '%2' does not have "
                                       "string type.").arg(i).arg(decl.name()), location);
                makeTypeError(error, v);
                break;
            }
            if (srcDir.isEmpty())
                continue;
            elem = v.engine()->toScriptValue(
                        QDir::cleanPath(FileInfo::resolvePath(srcDir, elem.toString())));
            v.setProperty(i, elem);
        }
        break;
    }
    case PropertyDeclaration::VariantList:
        if (!v.isArray()) {
            QScriptValue x = v.engine()->newArray(1);
            x.setProperty(0, v);
            v = x;
        }
        break;
    }
}
void tst_QScriptValueGenerated::isBool_test(const char*, const QScriptValue& value)
{
    QFETCH(bool, expected);
    QCOMPARE(value.isBool(), expected);
    QCOMPARE(value.isBool(), expected);
}
Exemplo n.º 19
0
static void marshall_basetype(Marshall *m)
{
    switch(m->type().element()) {        
    case Smoke::t_bool:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (!value.isBool()) {
                m->item().s_bool = false;
            } else {
                m->item().s_bool = value.toBool();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_bool);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
    
    case Smoke::t_char:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_char = 0;
            } else {
                m->item().s_char = (char) value.toInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_char);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
    
    case Smoke::t_uchar:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_uchar = 0;
            } else {
                m->item().s_uchar = (uchar) value.toUInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_uchar);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
    
    case Smoke::t_short:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_short = 0;
            } else {
                m->item().s_short = (short) value.toInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_short);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_ushort:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_ushort = 0;
            } else {
                m->item().s_ushort = value.toUInt16();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_ushort);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_int:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_int = 0;
            } else {
                m->item().s_int = value.toInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_int);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_uint:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_uint = 0;
            } else {
                m->item().s_uint = value.toUInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_uint);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_long:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_long = 0;
            } else {
                m->item().s_long = (long) value.toInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), (int) m->item().s_long);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_ulong:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_ulong = 0;
            } else {
                m->item().s_ulong = (ulong) value.toUInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), (uint) m->item().s_ulong);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_float:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_float = 0.0;
            } else {
                m->item().s_float = (float) value.toNumber();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_float);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_double:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_double = 0.0;
            } else {
                m->item().s_double = value.toNumber();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_double);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_enum:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_enum = 0;
            } else if (value.instanceOf(JSmoke::Global::QtEnum)) {
                m->item().s_enum = value.property("value").toUInt32();
            } else {
                m->item().s_enum = value.toUInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
        {
            QScriptValueList args;
            args << (uint) m->item().s_enum << m->type().name();
            *(m->var()) = JSmoke::Global::QtEnum.call(QScriptValue(), args);
            break;
        }
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_class:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_class = 0;
                return;
            }
            
            if (value.isDate()) {
                Smoke::ModuleIndex classId = Smoke::findClass(m->smoke()->classes[m->type().classId()].className);
                if (classId == JSmoke::Global::QDateClassId) {
                    m->item().s_class = new QDate(value.toDateTime().date());
                } else if (classId == JSmoke::Global::QDateTimeClassId) {
                     m->item().s_class = new QDateTime(value.toDateTime());
                } else if (classId == JSmoke::Global::QTimeClassId) {
                     m->item().s_class = new QTime(value.toDateTime().time());
                } else {
                    m->item().s_class = 0;
                }
                
                return;
            } else if (value.isRegExp()) {
                m->item().s_class = new QRegExp(value.toRegExp());
                return;
            }
            
            if (!Object::Instance::isSmokeObject(value)) {
                m->item().s_class = 0;
                return;
            }
            
            Object::Instance * instance = Object::Instance::get(value);
            void * ptr = instance->value;
            
            if (!m->cleanup() && m->type().isStack()) {
                ptr = constructCopy(instance);
            }
            
            ptr = instance->classId.smoke->cast(    ptr, 
                                                    instance->classId, 
                                                    Smoke::ModuleIndex(m->smoke(), m->type().classId()) );
            
            m->item().s_class = ptr;
            break;
        }
        
        case Marshall::ToQScriptValue:
        {
            if (m->item().s_voidp == 0) {
                *(m->var()) = m->engine()->nullValue();
                return;
            }
            
            void * ptr = m->item().s_voidp;
            QScriptValue * value = JSmoke::Global::getScriptValue(ptr);
            
            if (value != 0) {
                *(m->var()) = *value;
                return ;
            }
            
            QByteArray className(m->smoke()->classes[m->type().classId()].className);
            QScriptValue obj = Global::wrapInstance(    m->engine(), 
                                                        Smoke::findClass(className), 
                                                        ptr,
                                                        QScriptEngine::QtOwnership );
            
            if (m->type().isConst() && m->type().isRef()) {
                Object::Instance * instance = Object::Instance::get(obj);
                ptr = constructCopy(instance);

                if (ptr != 0) {
                    instance->value = ptr;
                    instance->ownership = QScriptEngine::ScriptOwnership;
                    Global::mapPointer(new QScriptValue(obj), instance, instance->classId);
                }
            }

            *(m->var()) = obj;
            break;
        }
        
        default:
            m->unsupported();
            break;
        }
        break;
        
    default:
        m->unsupported();
        break;
    }
}
Exemplo n.º 20
0
void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) {
    qDebug() << "script request completed for entity " << entityID;
    auto scriptRequest = qobject_cast<ResourceRequest*>(sender());
    if (scriptRequest && scriptRequest->getResult() == ResourceRequest::Success) {
        const QString urlString = scriptRequest->getUrl().toString();
        auto scriptContents = scriptRequest->getData();
        qInfo() << "Downloaded script:" << scriptContents;
        QScriptProgram program(scriptContents, urlString);
        if (hasCorrectSyntax(program)) {
            // create a QScriptEngine for this script
            QScriptEngine* engine = new QScriptEngine();
            engine->evaluate(scriptContents);
            if (!hadUncaughtExceptions(*engine, urlString)) {
                // put the engine in the engine map (so we don't leak them, etc...)
                FilterData filterData;
                filterData.engine = engine;
                filterData.rejectAll = false;
                
                // define the uncaughtException function
                QScriptEngine& engineRef = *engine;
                filterData.uncaughtExceptions = [&engineRef, urlString]() { return hadUncaughtExceptions(engineRef, urlString); };

                // now get the filter function
                auto global = engine->globalObject();
                auto entitiesObject = engine->newObject();
                entitiesObject.setProperty("ADD_FILTER_TYPE", EntityTree::FilterType::Add);
                entitiesObject.setProperty("EDIT_FILTER_TYPE", EntityTree::FilterType::Edit);
                entitiesObject.setProperty("PHYSICS_FILTER_TYPE", EntityTree::FilterType::Physics);
                entitiesObject.setProperty("DELETE_FILTER_TYPE", EntityTree::FilterType::Delete);
                global.setProperty("Entities", entitiesObject);
                filterData.filterFn = global.property("filter");
                if (!filterData.filterFn.isFunction()) {
                    qDebug() << "Filter function specified but not found. Will reject all edits for those without lock rights.";
                    delete engine;
                    filterData.rejectAll=true;
                }

                // if the wantsToFilterEdit is a boolean evaluate as a boolean, otherwise assume true
                QScriptValue wantsToFilterAddValue = filterData.filterFn.property("wantsToFilterAdd");
                filterData.wantsToFilterAdd = wantsToFilterAddValue.isBool() ? wantsToFilterAddValue.toBool() : true;

                // if the wantsToFilterEdit is a boolean evaluate as a boolean, otherwise assume true
                QScriptValue wantsToFilterEditValue = filterData.filterFn.property("wantsToFilterEdit");
                filterData.wantsToFilterEdit = wantsToFilterEditValue.isBool() ? wantsToFilterEditValue.toBool() : true;

                // if the wantsToFilterPhysics is a boolean evaluate as a boolean, otherwise assume true
                QScriptValue wantsToFilterPhysicsValue = filterData.filterFn.property("wantsToFilterPhysics");
                filterData.wantsToFilterPhysics = wantsToFilterPhysicsValue.isBool() ? wantsToFilterPhysicsValue.toBool() : true;

                // if the wantsToFilterDelete is a boolean evaluate as a boolean, otherwise assume false
                QScriptValue wantsToFilterDeleteValue = filterData.filterFn.property("wantsToFilterDelete");
                filterData.wantsToFilterDelete = wantsToFilterDeleteValue.isBool() ? wantsToFilterDeleteValue.toBool() : false;

                // check to see if the filterFn has properties asking for Original props
                QScriptValue wantsOriginalPropertiesValue = filterData.filterFn.property("wantsOriginalProperties");
                // if the wantsOriginalProperties is a boolean, or a string, or list of strings, then evaluate as follows:
                //   - boolean - true  - include all original properties
                //               false - no properties at all
                //   - string  - empty - no properties at all
                //               any valid property - include just that property in the Original properties
                //   - list of strings - include only those properties in the Original properties
                if (wantsOriginalPropertiesValue.isBool()) {
                    filterData.wantsOriginalProperties = wantsOriginalPropertiesValue.toBool();
                } else if (wantsOriginalPropertiesValue.isString()) {
                    auto stringValue = wantsOriginalPropertiesValue.toString();
                    filterData.wantsOriginalProperties = !stringValue.isEmpty();
                    if (filterData.wantsOriginalProperties) {
                        EntityPropertyFlagsFromScriptValue(wantsOriginalPropertiesValue, filterData.includedOriginalProperties);
                    }
                } else if (wantsOriginalPropertiesValue.isArray()) {
                    EntityPropertyFlagsFromScriptValue(wantsOriginalPropertiesValue, filterData.includedOriginalProperties);
                    filterData.wantsOriginalProperties = !filterData.includedOriginalProperties.isEmpty();
                }

                // check to see if the filterFn has properties asking for Zone props
                QScriptValue wantsZonePropertiesValue = filterData.filterFn.property("wantsZoneProperties");
                // if the wantsZoneProperties is a boolean, or a string, or list of strings, then evaluate as follows:
                //   - boolean - true  - include all Zone properties
                //               false - no properties at all
                //   - string  - empty - no properties at all
                //               any valid property - include just that property in the Zone properties
                //   - list of strings - include only those properties in the Zone properties
                if (wantsZonePropertiesValue.isBool()) {
                    filterData.wantsZoneProperties = wantsZonePropertiesValue.toBool();
                    filterData.wantsZoneBoundingBox = filterData.wantsZoneProperties; // include this too
                } else if (wantsZonePropertiesValue.isString()) {
                    auto stringValue = wantsZonePropertiesValue.toString();
                    filterData.wantsZoneProperties = !stringValue.isEmpty();
                    if (filterData.wantsZoneProperties) {
                        if (stringValue == "boundingBox") {
                            filterData.wantsZoneBoundingBox = true;
                        } else {
                            EntityPropertyFlagsFromScriptValue(wantsZonePropertiesValue, filterData.includedZoneProperties);
                        }
                    }
                } else if (wantsZonePropertiesValue.isArray()) {
                    auto length = wantsZonePropertiesValue.property("length").toInteger();
                    for (int i = 0; i < length; i++) {
                        auto stringValue = wantsZonePropertiesValue.property(i).toString();
                        if (!stringValue.isEmpty()) {
                            filterData.wantsZoneProperties = true;

                            // boundingBox is a special case since it's not a true EntityPropertyFlag, so we
                            // need to detect it here.
                            if (stringValue == "boundingBox") {
                                filterData.wantsZoneBoundingBox = true;
                                break; // we can break here, since there are no other special cases
                            }

                        }
                    }
                    if (filterData.wantsZoneProperties) {
                        EntityPropertyFlagsFromScriptValue(wantsZonePropertiesValue, filterData.includedZoneProperties);
                    }
                }

                _lock.lockForWrite();
                _filterDataMap.insert(entityID, filterData);
                _lock.unlock();

                qDebug() << "script request filter processed for entity id " << entityID;
                
                emit filterAdded(entityID, true);
                return;
            }
        } 
    } else if (scriptRequest) {
        const QString urlString = scriptRequest->getUrl().toString();
        qCritical() << "Failed to download script";
        // See HTTPResourceRequest::onRequestFinished for interpretation of codes. For example, a 404 is code 6 and 403 is 3. A timeout is 2. Go figure.
        qCritical() << "ResourceRequest error was" << scriptRequest->getResult();
    } else {
        qCritical() << "Failed to create script request.";
    }
    emit filterAdded(entityID, false);
}