void updateModel(QStandardItem* parentItem, const std::string& propertyPrefix = "") { // Go throw keys of parentItem for (int iRow = 0; iRow < parentItem->rowCount(); ++iRow) { QStandardItem* valueItem = parentItem->child(iRow, 1); if (valueItem && valueItem->data(Qt::UserRole).canConvert<PropertyReference>()) { PropertyReference ref = valueItem->data(Qt::UserRole).value<PropertyReference>(); IReflectableAttribute* reflectable = ref.getProperty()->getAttribute<IReflectableAttribute>(); if (reflectable) { ReflectableClass* subObject = reflectable->getValuePtr(*ref.getObject(), ref.getProperty()); // If the type of the reflectable object has changed, the subtree needs to be rebuild. // You need to know the previous type in order to detect a change. ScalarAttributes are // no longer supported in order to guarantee, that the string value is always set to the // previous type name. if (subObject) { std::string oldClassName(valueItem->text().toStdString()); if (oldClassName.compare(subObject->getClassName())) { valueItem->setText(subObject->getClassName().c_str()); buildModel(parentItem->child(iRow, 0), subObject, ref.getNode().get(), propertyPrefix + ref.getProperty()->getName() + "."); } else { updateModel(parentItem->child(iRow, 0), propertyPrefix + ref.getProperty()->getName() + "."); } } else { valueItem->setText(ref.getProperty()->getStringValue(*ref.getObject()).c_str()); } } else if (ref.getProperty()->getAttribute<FlagAttribute>()) { ClassProperty<bool>* boolProperty = dynamic_cast<ClassProperty<bool>* >(ref.getProperty()); // properties tagged as Flag() must be of type bool assert(boolProperty); if (boolProperty->getValue(*ref.getObject())) valueItem->setCheckState(Qt::Checked); else valueItem->setCheckState(Qt::Unchecked); } else{ valueItem->setText(ref.getProperty()->getStringValue(*ref.getObject()).c_str()); } } else { if (parentItem->child(iRow, 0)->hasChildren()) { updateModel(parentItem->child(iRow, 0), propertyPrefix); } } } }
void Edge::changedHandler(capputils::ObservableClass* object, int eventId) { // check for the right property ID if ((object != this && eventId == (int)outputId) || (object == this && eventId == positionId)) { PropertyReference* inputRef = getInputReference().get(); PropertyReference* outputRef = getOutputReference().get(); if (!inputRef || !outputRef) return; capputils::reflection::IClassProperty* inProp = inputRef->getProperty(); capputils::reflection::IClassProperty* outProp = outputRef->getProperty(); if (inProp && outProp) { IMergeAttribute* merge = inProp->getAttribute<IMergeAttribute>(); if (merge) { merge->setValue(*inputRef->getObject(), inProp, getInputPosition(), *outputRef->getObject(), outProp); } else { inProp->setValue(*inputRef->getObject(), *outputRef->getObject(), outProp); } } } }
void ModelHarmonizer::itemChanged(QStandardItem* item) { if (!item) return; if (modelLocked) return; if (item->data(Qt::UserRole).canConvert<int>()) { int from = item->data(Qt::UserRole).value<int>(); int to = item->index().row(); // Delete new row if new row (new row if value does not have a property reference) if (!model->item(to, 1) || !model->item(to, 1)->data(Qt::UserRole).canConvert<PropertyReference>()) { model->removeRow(to, item->index().parent()); if (from != to) { // move rows to first valid position (count number of workflow module properties) // Update grid positions of all keys // Update workflow interface node order boost::shared_ptr<gapputils::workflow::Node> node = this->node.lock(); int firstInterfaceProperty = 0; for (int iRow = 0; iRow < model->rowCount(); ++iRow) { if (model->item(iRow, 1) && model->item(iRow, 1)->data(Qt::UserRole).canConvert<PropertyReference>()) { PropertyReference ref = model->item(iRow, 1)->data(Qt::UserRole).value<PropertyReference>(); if (ref.getObject() != node->getModule().get()) { firstInterfaceProperty = iRow; break; } } } to = std::max(to, firstInterfaceProperty); if (from < to) --to; model->insertRow(to, model->takeRow(from)); modelLocked = true; for (int gridPos = 0; gridPos < model->rowCount(); ++gridPos) model->item(gridPos, 0)->setData(QVariant::fromValue(gridPos), Qt::UserRole); modelLocked = false; gapputils::Workflow* workflow = dynamic_cast<gapputils::Workflow*>(node.get()); if (workflow) { workflow->moveInterfaceNode(from - firstInterfaceProperty, to - firstInterfaceProperty); } } return; } } // Update model if necessary if (item->data(Qt::UserRole).canConvert<PropertyReference>()) { const PropertyReference& reference = item->data(Qt::UserRole).value<PropertyReference>(); ReflectableClass* object = reference.getObject(); IClassProperty* prop = reference.getProperty(); QString qstr = item->text(); std::string str(qstr.toUtf8().data()); if (prop->getAttribute<FlagAttribute>()) { if ((prop->getStringValue(*object) != "0") != (item->checkState() == Qt::Checked)) { prop->setStringValue(*object, (item->checkState() == Qt::Checked ? "1" : "0")); } } else if (prop->getStringValue(*object).compare(str)) { IReflectableAttribute* reflectable = prop->getAttribute<IReflectableAttribute>(); if (reflectable) { ReflectableClass* subObject = reflectable->getValuePtr(*object, prop); if (dynamic_cast<AbstractEnumerator*>(subObject)) { stringstream stream(str); subObject->fromStream(stream); reflectable->setValuePtr(*object, prop, subObject); } } else { prop->setStringValue(*object, str); } } } }