void PropertyExpressionEngine::slotObjectRenamed(const DocumentObject &obj) { #ifdef FC_PROPERTYEXPRESSIONENGINE_LOG std::clog << "Object " << obj.getOldLabel() << " renamed to " << obj.Label.getValue() << std::endl; #endif DocumentObject * docObj = freecad_dynamic_cast<DocumentObject>(getContainer()); /* In a document object, and on undo stack? */ if (!docObj || docObj->getNameInDocument() == 0) return; RelabelDocumentObjectExpressionVisitor v(boost::bind( &PropertyExpressionEngine::aboutToSetValue, this), boost::bind( &PropertyExpressionEngine::hasSetValue, this), obj.getOldLabel(), obj.Label.getStrValue()); for (ExpressionMap::iterator it = expressions.begin(); it != expressions.end(); ++it) { int changed = v.getChanged(); it->second.expression->visit(v); if (changed != v.getChanged()) expressionChanged(it->first); } }
void PropertyLink::Restore(Base::XMLReader &reader) { // read my element reader.readElement("Link"); // get the value of my attribute std::string name = reader.getAttribute("value"); // Property not in a DocumentObject! assert(getContainer()->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId()) ); if (name != "") { DocumentObject* parent = static_cast<DocumentObject*>(getContainer()); App::Document* document = parent->getDocument(); DocumentObject* object = document ? document->getObject(name.c_str()) : 0; if (!object) { if (reader.isVerbose()) { Base::Console().Warning("Lost link to '%s' while loading, maybe " "an object was not loaded correctly\n",name.c_str()); } } else if (parent == object) { if (reader.isVerbose()) { Base::Console().Warning("Object '%s' links to itself, nullify it\n",name.c_str()); } object = 0; } setValue(object); } else { setValue(0); } }
Py::Object DocumentPy::getActiveObject(void) const { DocumentObject *pcFtr = getDocumentPtr()->getActiveObject(); if(pcFtr) return Py::Object(pcFtr->getPyObject(), true); return Py::None(); }
void PropertyLinkSubList::Restore(Base::XMLReader &reader) { // read my element reader.readElement("LinkSubList"); // get the value of my attribute int count = reader.getAttributeAsInteger("count"); std::vector<DocumentObject*> values; values.reserve(count); std::vector<std::string> SubNames; SubNames.reserve(count); for (int i = 0; i < count; i++) { reader.readElement("Link"); std::string name = reader.getAttribute("obj"); // In order to do copy/paste it must be allowed to have defined some // referenced objects in XML which do not exist anymore in the new // document. Thus, we should silently ignore this. // Property not in an object! DocumentObject* father = static_cast<DocumentObject*>(getContainer()); App::Document* document = father->getDocument(); DocumentObject* child = document ? document->getObject(name.c_str()) : 0; if (child) values.push_back(child); else if (reader.isVerbose()) Base::Console().Warning("Lost link to '%s' while loading, maybe " "an object was not loaded correctly\n",name.c_str()); std::string subName = reader.getAttribute("sub"); SubNames.push_back(subName); } reader.readEndElement("LinkSubList"); // assignment setValues(values,SubNames); }
// returns a string which represent the object e.g. when printed in python std::string DocumentObjectPy::representation(void) const { DocumentObject* object = this->getDocumentObjectPtr(); std::stringstream str; str << "<" << object->getTypeId().getName() << " object>"; return str.str(); }
boost::shared_ptr<App::Expression> ExpressionBinding::getExpression() const { DocumentObject * docObj = path.getDocumentObject(); Q_ASSERT(isBound() && docObj != 0); return docObj->getExpression(path).expression; }
Py::String DocumentObjectPy::getName(void) const { DocumentObject* object = this->getDocumentObjectPtr(); const char* internal = object->getNameInDocument(); if (!internal) { throw Py::RuntimeError(std::string("This object is currently not part of a document")); } return Py::String(std::string(internal)); }
DocumentObject* GroupExtension::addObject(const char* sType, const char* pObjectName) { DocumentObject* obj = getExtendedObject()->getDocument()->addObject(sType, pObjectName); if(!allowObject(obj)) { getExtendedObject()->getDocument()->remObject(obj->getNameInDocument()); return nullptr; } if (obj) addObject(obj); return obj; }
Py::Object DocumentObjectPy::getDocument(void) const { DocumentObject* object = this->getDocumentObjectPtr(); Document* doc = object->getDocument(); if (!doc) { return Py::None(); } else { return Py::Object(doc->getPyObject(), true); } }
PyObject* DocumentPy::getObject(PyObject *args) { char *sName; if (!PyArg_ParseTuple(args, "s",&sName)) // convert args: Python->C return NULL; // NULL triggers exception DocumentObject *pcFtr = getDocumentPtr()->getObject(sName); if (pcFtr) return pcFtr->getPyObject(); else Py_Return; }
PyObject* DocumentObjectGroupPy::getObject(PyObject *args) { char* pcName; if (!PyArg_ParseTuple(args, "s", &pcName)) // convert args: Python->C return NULL; // NULL triggers exception DocumentObject* obj = getDocumentObjectGroupPtr()->getObject(pcName); if ( obj ) { return obj->getPyObject(); } else { Py_Return; } }
PyObject* DocumentPy::addObject(PyObject *args) { char *sType,*sName=0; PyObject* obj=0; PyObject* view=0; if (!PyArg_ParseTuple(args, "s|sOO", &sType,&sName,&obj,&view)) // convert args: Python->C return NULL; // NULL triggers exception DocumentObject *pcFtr; pcFtr = getDocumentPtr()->addObject(sType,sName); if (pcFtr) { // Allows to hide the handling with Proxy in client python code if (obj) { try { // the python binding class to the document object Py::Object pyftr = Py::asObject(pcFtr->getPyObject()); // 'pyobj' is the python class with the implementation for DocumentObject Py::Object pyobj(obj); if (pyobj.hasAttr("__object__")) { pyobj.setAttr("__object__", pyftr); } pyftr.setAttr("Proxy", pyobj); // if a document class is set we also need a view provider defined which must be // something different to None Py::Object pyvp; if (view) pyvp = Py::Object(view); if (pyvp.isNone()) pyvp = Py::Int(1); // 'pyvp' is the python class with the implementation for ViewProvider if (pyvp.hasAttr("__vobject__")) { pyvp.setAttr("__vobject__", pyftr.getAttr("ViewObject")); } pyftr.getAttr("ViewObject").setAttr("Proxy", pyvp); return Py::new_reference_to(pyftr); } catch (Py::Exception& e) { e.clear(); } } return pcFtr->getPyObject(); } else { std::stringstream str; str << "No document object found of type '" << sType << "'" << std::ends; throw Py::Exception(PyExc_Exception,str.str()); } }
void PropertyLinkList::Save(Base::Writer &writer) const { writer.Stream() << writer.ind() << "<LinkList count=\"" << getSize() << "\">" << endl; writer.incInd(); for (int i = 0; i<getSize(); i++) { DocumentObject* obj = _lValueList[i]; if (obj) writer.Stream() << writer.ind() << "<Link value=\"" << obj->getNameInDocument() << "\"/>" << endl; else writer.Stream() << writer.ind() << "<Link value=\"\"/>" << endl; } writer.decInd(); writer.Stream() << writer.ind() << "</LinkList>" << endl; }
void PropertyExpressionEngine::slotObjectRenamed(const DocumentObject &obj) { #ifdef FC_PROPERTYEXPRESSIONENGINE_LOG std::clog << "Object " << obj.getOldLabel() << " renamed to " << obj.Label.getValue() << std::endl; #endif RelabelDocumentObjectExpressionVisitor v(obj.getOldLabel(), obj.Label.getStrValue()); aboutToSetValue(); for (ExpressionMap::iterator it = expressions.begin(); it != expressions.end(); ++it) it->second.expression->visit(v); hasSetValue(); }
PyObject* DocumentObjectGroupPy::newObject(PyObject *args) { char *sType,*sName=0; if (!PyArg_ParseTuple(args, "s|s", &sType,&sName)) // convert args: Python->C return NULL; DocumentObject *object = getDocumentObjectGroupPtr()->addObject(sType, sName); if ( object ) { return object->getPyObject(); } else { PyErr_Format(Base::BaseExceptionFreeCADError, "Cannot create object of type '%s'", sType); return NULL; } }
PyObject* DocumentPy::moveObject(PyObject *args) { PyObject *obj, *rec=Py_False; if (!PyArg_ParseTuple(args, "O!|O!",&(DocumentObjectPy::Type),&obj,&PyBool_Type,&rec)) return NULL; // NULL triggers exception DocumentObjectPy* docObj = static_cast<DocumentObjectPy*>(obj); DocumentObject* move = getDocumentPtr()->moveObject(docObj->getDocumentObjectPtr(), PyObject_IsTrue(rec) ? true : false); if (move) { return move->getPyObject(); } else { std::string str("Failed to move the object"); throw Py::Exception(PyExc_Exception,str); } }
PyObject* DocumentPy::copyObject(PyObject *args) { PyObject *obj, *rec=0; if (!PyArg_ParseTuple(args, "O!|O!",&(DocumentObjectPy::Type),&obj,&PyBool_Type,&rec)) return NULL; // NULL triggers exception DocumentObjectPy* docObj = static_cast<DocumentObjectPy*>(obj); DocumentObject* copy = getDocumentPtr()->copyObject(docObj->getDocumentObjectPtr(), rec==Py_True); if (copy) { return copy->getPyObject(); } else { std::string str("Failed to copy the object"); throw Py::Exception(PyExc_Exception,str); } }
Py::List DocumentObjectPy::getState(void) const { DocumentObject* object = this->getDocumentObjectPtr(); Py::List list; bool uptodate = true; if (object->isTouched()) { uptodate = false; list.append(Py::String("Touched")); } if (object->isError()) { uptodate = false; list.append(Py::String("Invalid")); } if (uptodate) { list.append(Py::String("Up-to-date")); } return list; }
void PropertyExpressionEngine::slotObjectDeleted(const DocumentObject &obj) { DocumentObject * docObj = freecad_dynamic_cast<DocumentObject>(getContainer()); /* In a document object, and on undo stack? */ if (!docObj || docObj->getNameInDocument() == 0) return; ObjectDeletedExpressionVisitor v(&obj); for (ExpressionMap::iterator it = expressions.begin(); it != expressions.end(); ++it) { it->second.expression->visit(v); if (v.isFound()) { touch(); // Touch to force recompute; that will trigger a proper error return; } } }
PyObject *DocumentPy::getCustomAttributes(const char* attr) const { // Note: Here we want to return only a document object if its // name matches 'attr'. However, it is possible to have an object // with the same name as an attribute. If so, we return 0 as other- // wise it wouldn't be possible to address this attribute any more. // The object must then be addressed by the getObject() method directly. App::Property* prop = getPropertyContainerPtr()->getPropertyByName(attr); if (prop) return 0; if (this->ob_type->tp_dict == NULL) { if (PyType_Ready(this->ob_type) < 0) return 0; } PyObject* item = PyDict_GetItemString(this->ob_type->tp_dict, attr); if (item) return 0; // search for an object with this name DocumentObject* obj = getDocumentPtr()->getObject(attr); return (obj ? obj->getPyObject() : 0); }
bool ExpressionBinding::apply(const std::string & propName) { if (hasExpression()) { DocumentObject * docObj = path.getDocumentObject(); if (!docObj) throw Base::Exception("Document object not found."); Gui::Command::doCommand(Gui::Command::Doc,"App.getDocument('%s').%s.setExpression('%s', u'%s')", docObj->getDocument()->getName(), docObj->getNameInDocument(), path.toEscapedString().c_str(), getEscapedExpressionString().c_str()); return true; } else { if (isBound()) { DocumentObject * docObj = path.getDocumentObject(); if (!docObj) throw Base::Exception("Document object not found."); if (lastExpression) Gui::Command::doCommand(Gui::Command::Doc,"App.getDocument('%s').%s.setExpression('%s', None)", docObj->getDocument()->getName(), docObj->getNameInDocument(), path.toEscapedString().c_str()); } return false; } }
void PropertyLinkList::Restore(Base::XMLReader &reader) { // read my element reader.readElement("LinkList"); // get the value of my attribute int count = reader.getAttributeAsInteger("count"); App::PropertyContainer* container = getContainer(); if (!container) throw Base::RuntimeError("Property is not part of a container"); if (!container->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId())) { std::stringstream str; str << "Container is not a document object (" << container->getTypeId().getName() << ")"; throw Base::TypeError(str.str()); } std::vector<DocumentObject*> values; values.reserve(count); for (int i = 0; i < count; i++) { reader.readElement("Link"); std::string name = reader.getAttribute("value"); // In order to do copy/paste it must be allowed to have defined some // referenced objects in XML which do not exist anymore in the new // document. Thus, we should silently ignore this. // Property not in an object! DocumentObject* father = static_cast<DocumentObject*>(getContainer()); App::Document* document = father->getDocument(); DocumentObject* child = document ? document->getObject(name.c_str()) : 0; if (child) values.push_back(child); else if (reader.isVerbose()) Base::Console().Warning("Lost link to '%s' while loading, maybe " "an object was not loaded correctly\n", name.c_str()); } reader.readEndElement("LinkList"); // assignment setValues(values); }