bool AttachableObject::changeAttacherType(const char* typeName) { //check if we need to actually change anything if (_attacher){ if (strcmp(_attacher->getTypeId().getName(),typeName)==0){ return false; } } else if (strlen(typeName) == 0){ return false; } if (strlen(typeName) == 0){ setAttacher(nullptr); return true; } Base::Type t = Base::Type::fromName(typeName); if (t.isDerivedFrom(AttachEngine::getClassTypeId())){ AttachEngine* pNewAttacher = static_cast<Attacher::AttachEngine*>(Base::Type::createInstanceByName(typeName)); this->setAttacher(pNewAttacher); return true; } else { std::stringstream errMsg; errMsg << "Object if this type is not derived from AttachEngine: " << typeName; throw Base::Exception(errMsg.str()); } assert(false);//exec shouldn't ever get here return false; }
void Primitive::Restore(Base::XMLReader &reader) { reader.readElement("Properties"); int Cnt = reader.getAttributeAsInteger("Count"); for (int i=0 ;i<Cnt ;i++) { reader.readElement("Property"); const char* PropName = reader.getAttribute("name"); const char* TypeName = reader.getAttribute("type"); App::Property* prop = getPropertyByName(PropName); // For #0001652 the property types of many primitive features have changed // from PropertyFloat or PropertyFloatConstraint to a more meaningful type. // In order to load older project files there must be checked in case the // types don't match if both inherit from PropertyFloat because all derived // classes do not re-implement the Save/Restore methods. try { if (prop && strcmp(prop->getTypeId().getName(), TypeName) == 0) { prop->Restore(reader); } else if (prop) { Base::Type inputType = Base::Type::fromName(TypeName); if (prop->getTypeId().isDerivedFrom(App::PropertyFloat::getClassTypeId()) && inputType.isDerivedFrom(App::PropertyFloat::getClassTypeId())) { // Do not directly call the property's Restore method in case the implmentation // has changed. So, create a temporary PropertyFloat object and assign the value. App::PropertyFloat floatProp; floatProp.Restore(reader); static_cast<App::PropertyFloat*>(prop)->setValue(floatProp.getValue()); } } } catch (const Base::XMLParseException&) { throw; // re-throw } catch (const Base::Exception &e) { Base::Console().Error("%s\n", e.what()); } catch (const std::exception &e) { Base::Console().Error("%s\n", e.what()); } catch (const char* e) { Base::Console().Error("%s\n", e); } #ifndef FC_DEBUG catch (...) { Base::Console().Error("Primitive::Restore: Unknown C++ exception thrown"); } #endif reader.readEndElement("Property"); } reader.readEndElement("Properties"); }
void Transformed::Restore(Base::XMLReader &reader) { reader.readElement("Properties"); int Cnt = reader.getAttributeAsInteger("Count"); for (int i=0 ;i<Cnt ;i++) { reader.readElement("Property"); const char* PropName = reader.getAttribute("name"); const char* TypeName = reader.getAttribute("type"); App::Property* prop = getPropertyByName(PropName); // The property 'Angle' of PolarPattern has changed from PropertyFloat // to PropertyAngle and the property 'Length' has changed to PropertyLength. try { if (prop && strcmp(prop->getTypeId().getName(), TypeName) == 0) { prop->Restore(reader); } else if (prop) { Base::Type inputType = Base::Type::fromName(TypeName); if (prop->getTypeId().isDerivedFrom(App::PropertyFloat::getClassTypeId()) && inputType.isDerivedFrom(App::PropertyFloat::getClassTypeId())) { // Do not directly call the property's Restore method in case the implmentation // has changed. So, create a temporary PropertyFloat object and assign the value. App::PropertyFloat floatProp; floatProp.Restore(reader); static_cast<App::PropertyFloat*>(prop)->setValue(floatProp.getValue()); } } } catch (const Base::XMLParseException&) { throw; // re-throw } catch (const Base::Exception &e) { Base::Console().Error("%s\n", e.what()); } catch (const std::exception &e) { Base::Console().Error("%s\n", e.what()); } catch (const char* e) { Base::Console().Error("%s\n", e); } #ifndef FC_DEBUG catch (...) { Base::Console().Error("Primitive::Restore: Unknown C++ exception thrown"); } #endif reader.readEndElement("Property"); } reader.readEndElement("Properties"); }
PyObject* DocumentPy::findObjects(PyObject *args) { char *sType="App::DocumentObject", *sName=0; if (!PyArg_ParseTuple(args, "|ss",&sType, &sName)) // convert args: Python->C return NULL; // NULL triggers exception Base::Type type = Base::Type::fromName(sType); if (type == Base::Type::badType()) { PyErr_Format(PyExc_Exception, "'%s' is not a valid type", sType); return NULL; } if (!type.isDerivedFrom(App::DocumentObject::getClassTypeId())) { PyErr_Format(PyExc_Exception, "Type '%s' does not inherit from 'App::DocumentObject'", sType); return NULL; } std::vector<DocumentObject*> res; std::vector<DocumentObject*> objs = getDocumentPtr()->getObjectsOfType(type); if (sName) { try { boost::regex rx(sName); boost::cmatch what; for (std::vector<DocumentObject*>::const_iterator It = objs.begin();It != objs.end();++It) { if (boost::regex_match((*It)->getNameInDocument(), what, rx)) res.push_back(*It); } } catch (const boost::regex_error& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); return 0; } } else { res = objs; } Py_ssize_t index=0; PyObject* list = PyList_New((Py_ssize_t)res.size()); for (std::vector<DocumentObject*>::const_iterator It = res.begin();It != res.end();++It, index++) PyList_SetItem(list, index, (*It)->getPyObject()); return list; }
PyObject* ExtensionContainerPy::hasExtension(PyObject *args) { char *type; if (!PyArg_ParseTuple(args, "s", &type)) return NULL; // NULL triggers exception //get the extension type asked for Base::Type extension = Base::Type::fromName(type); if(extension.isBad() || !extension.isDerivedFrom(App::Extension::getExtensionClassTypeId())) { std::stringstream str; str << "No extension found of type '" << type << "'" << std::ends; throw Py::Exception(Base::BaseExceptionFreeCADError,str.str()); } bool val = false; if (getExtensionContainerPtr()->hasExtension(extension)) { val = true; } return PyBool_FromLong(val ? 1 : 0); }
// constructor method int AttachEnginePy::PyInit(PyObject* args, PyObject* /*kwd*/) { PyObject* o; if (PyArg_ParseTuple(args, "")) { return 0; } PyErr_Clear(); if (PyArg_ParseTuple(args, "O!", &(AttachEnginePy::Type), &o)) { AttachEngine* attacher = static_cast<AttachEnginePy*>(o)->getAttachEnginePtr(); AttachEngine* oldAttacher = this->getAttachEnginePtr(); this->_pcTwinPointer = attacher->copy(); delete oldAttacher; return 0; } PyErr_Clear(); char* typeName; if (PyArg_ParseTuple(args, "s", &typeName)) { Base::Type t = Base::Type::fromName(typeName); AttachEngine* pNewAttacher = nullptr; if (t.isDerivedFrom(AttachEngine::getClassTypeId())){ pNewAttacher = static_cast<Attacher::AttachEngine*>(Base::Type::createInstanceByName(typeName)); } if (!pNewAttacher) { std::stringstream errMsg; errMsg << "Object if this type is not derived from AttachEngine: " << typeName; PyErr_SetString(Base::BaseExceptionFreeCADError, errMsg.str().c_str()); return -1; } AttachEngine* oldAttacher = this->getAttachEnginePtr(); this->_pcTwinPointer = pNewAttacher; delete oldAttacher; return 0; } PyErr_SetString(Base::BaseExceptionFreeCADError, "Wrong set of constructor arguments. Can be: (), ('Attacher::AttachEngine3D'), ('Attacher::AttachEnginePlane'), ('Attacher::AttachEngineLine'), ('Attacher::AttachEnginePoint'), (other_attacher_instance)."); return -1; }
void Document::createView(const Base::Type& typeId) { if (!typeId.isDerivedFrom(MDIView::getClassTypeId())) return; std::list<MDIView*> theViews = this->getMDIViewsOfType(typeId); if (typeId == View3DInventor::getClassTypeId()) { View3DInventor* firstView = 0; QGLWidget* shareWidget = 0; if (!theViews.empty()) { firstView = dynamic_cast<View3DInventor*>(theViews.front()); shareWidget = qobject_cast<QGLWidget*>(firstView->getViewer()->getGLWidget()); } View3DInventor* view3D = new View3DInventor(this, getMainWindow(), shareWidget); if (firstView) { std::string overrideMode = firstView->getViewer()->getOverrideMode(); view3D->getViewer()->setOverrideMode(overrideMode); } // attach the viewprovider std::map<const App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator It1; for (It1=d->_ViewProviderMap.begin();It1!=d->_ViewProviderMap.end();++It1) view3D->getViewer()->addViewProvider(It1->second); std::map<std::string,ViewProvider*>::const_iterator It2; for (It2=d->_ViewProviderMapAnnotation.begin();It2!=d->_ViewProviderMapAnnotation.end();++It2) view3D->getViewer()->addViewProvider(It2->second); const char* name = getDocument()->Label.getValue(); QString title = QString::fromAscii("%1 : %2[*]") .arg(QString::fromUtf8(name)).arg(d->_iWinCount++); view3D->setWindowTitle(title); view3D->setWindowModified(this->isModified()); view3D->setWindowIcon(QApplication::windowIcon()); view3D->resize(400, 300); getMainWindow()->addWindow(view3D); } }
PyObject* ExtensionContainerPy::addExtension(PyObject *args) { char *typeId; PyObject* proxy; if (!PyArg_ParseTuple(args, "sO", &typeId, &proxy)) return NULL; //get the extension type asked for Base::Type extension = Base::Type::fromName(typeId); if (extension.isBad() || !extension.isDerivedFrom(App::Extension::getExtensionClassTypeId())) { std::stringstream str; str << "No extension found of type '" << typeId << "'" << std::ends; throw Py::Exception(Base::BaseExceptionFreeCADError,str.str()); } //register the extension App::Extension* ext = static_cast<App::Extension*>(extension.createInstance()); //check if this really is a python extension! if (!ext->isPythonExtension()) { delete ext; std::stringstream str; str << "Extension is not a python addable version: '" << typeId << "'" << std::ends; throw Py::Exception(Base::BaseExceptionFreeCADError,str.str()); } ext->initExtension(getExtensionContainerPtr()); //set the proxy to allow python overrides App::Property* pp = ext->extensionGetPropertyByName("ExtensionProxy"); if (!pp) { std::stringstream str; str << "Accessing the proxy property failed!" << std::ends; throw Py::Exception(Base::BaseExceptionFreeCADError,str.str()); } static_cast<PropertyPythonObject*>(pp)->setPyObject(proxy); // The PyTypeObject is shared by all instances of this type and therefore // we have to add new methods only once. PyObject* obj = ext->getExtensionPyObject(); PyMethodDef* meth = reinterpret_cast<PyMethodDef*>(obj->ob_type->tp_methods); PyTypeObject *type = this->ob_type; PyObject *dict = type->tp_dict; // make sure to do the initialization only once if (meth->ml_name) { PyObject* item = PyDict_GetItemString(dict, meth->ml_name); if (item == NULL) { // Note: this adds the methods to the type object to make sure // it appears in the call tips. The function will not be bound // to an instance Py_INCREF(dict); while (meth->ml_name) { PyObject *func; func = PyCFunction_New(meth, 0); if (func == NULL) break; if (PyDict_SetItemString(dict, meth->ml_name, func) < 0) break; Py_DECREF(func); ++meth; } Py_DECREF(dict); } } Py_DECREF(obj); Py_Return; }