/** * This method is used for the export of several layout elements. * Layout elements can reference model elements, but when a referenced model element * is deleted, the layout is not infomred about this yet, so we end up with dnagling * references. * In order to not write these dangling references to file, we check if the reference * belongs to a valid object in the same datamodel. If not, we issue a warning. * This warning is only issued once during a save process. * * If the key belongs to an object in the same datamodel, true is returned, else false is returned. */ bool CLGraphicalObject::hasValidModelReference() const { bool result = false; // check if the object for this key actually exists // TODO This is only a workaround because it is theoretically // TODO possible that the key no longer belongs to the same object it // TODO originally did. CCopasiObject* pObj = CCopasiRootContainer::getKeyFactory()->get(this->mModelObjectKey); if (pObj != NULL) { // check if the object actually belongs to the same // model as the text glyph const CCopasiDataModel* pDM1 = NULL; const CCopasiDataModel* pDM2 = NULL; const CCopasiContainer* pParent = pObj->getObjectParent(); while (pParent != NULL) { pDM1 = dynamic_cast<const CCopasiDataModel*>(pParent); if (pDM1 != NULL) { break; } pParent = pParent->getObjectParent(); } pParent = this->getObjectParent(); while (pParent != NULL) { pDM2 = dynamic_cast<const CCopasiDataModel*>(pParent); if (pDM2 != NULL) { break; } pParent = pParent->getObjectParent(); } //assert(pDM2 != NULL); if (pDM1 != NULL && pDM2 == NULL) { // if we have been able to resolve the model reference, but // don't have a datamodel parent, that is good enough return true; } if (pDM1 != NULL && pDM1 == pDM2) { result = true; } } return result; }
/** * Returns a pointer to the CCopasiDataModel the element belongs to. * If there is no instance of CCopasiDataModel in the ancestor tree, NULL * is returned. */ CCopasiDataModel* CCopasiObject::getObjectDataModel() { CCopasiObject * pObject = this; while (pObject != NULL) { if (pObject->isDataModel()) return static_cast<CCopasiDataModel *>(pObject); pObject = pObject->getObjectParent(); } return NULL; }
// virtual bool CModelParameter::updateModel() { bool success = true; if (mpObject != NULL) { switch (mType) { case Model: { CModel * pModel = static_cast< CModel * >(mpObject); if (!pModel->isAutonomous()) { pModel->setInitialValue(mValue); } else { pModel->setInitialValue(0.0); } } break; case Compartment: case Species: case ModelValue: { CModelEntity * pEntity = static_cast< CModelEntity * >(mpObject); if (pEntity->getStatus() != CModelEntity::ASSIGNMENT) { pEntity->setInitialValue(mValue); if (mIsInitialExpressionValid) { pEntity->setInitialExpression(getInitialExpression()); } } } break; case ReactionParameter: { CCopasiParameter * pParameter = static_cast< CCopasiParameter * >(mpObject); CReaction * pReaction = static_cast< CReaction * >(mpObject->getObjectAncestor("Reaction")); if (mIsInitialExpressionValid && getInitialExpression() != "") { CModel * pModel = mpParent->getModel(); assert(pModel != NULL); std::vector< CCopasiContainer * > ListOfContainer; ListOfContainer.push_back(pModel); CCopasiObjectName CN = static_cast< CEvaluationNodeObject * >(mpInitialExpression->getRoot())->getObjectCN(); CCopasiObject * pObject = pModel->getObjectDataModel()->ObjectFromName(ListOfContainer, CN); assert(pObject != NULL); // We assign the object value pParameter->setValue(* (C_FLOAT64 *) pObject->getValuePointer()); // We map the parameter to the global quantity pReaction->setParameterMapping(pParameter->getObjectName(), pObject->getObjectParent()->getKey()); } else { pParameter->setValue(mValue); // We need to remove the existing mapping to a global quantity1. pReaction->setParameterMapping(pParameter->getObjectName(), pParameter->getKey()); } } break; default: success = false; break; } } return success; }