diff --git a/src/App/Annotation.cpp b/src/App/Annotation.cpp index ad5ac9134a..fc620feb68 100644 --- a/src/App/Annotation.cpp +++ b/src/App/Annotation.cpp @@ -45,7 +45,7 @@ PROPERTY_SOURCE(App::AnnotationLabel, App::DocumentObject) AnnotationLabel::AnnotationLabel() { - ADD_PROPERTY_TYPE(LabelText, (""), "Label",Prop_Output, "Text label of the annotation"); + ADD_PROPERTY_TYPE(LabelText, (""), "Label", Prop_Output, "Text label of the annotation"); ADD_PROPERTY_TYPE(BasePosition, (Base::Vector3d()), "Label", Prop_Output, "Base position"); ADD_PROPERTY_TYPE(TextPosition, (Base::Vector3d()), "Label", Prop_Output, "Text position"); } diff --git a/src/App/Annotation.h b/src/App/Annotation.h index 4595ae0b58..7fabb50fea 100644 --- a/src/App/Annotation.h +++ b/src/App/Annotation.h @@ -32,7 +32,7 @@ namespace App { -class AppExport Annotation : public DocumentObject +class AppExport Annotation: public DocumentObject { PROPERTY_HEADER_WITH_OVERRIDE(App::Annotation); @@ -45,12 +45,13 @@ public: App::PropertyVector Position; /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderAnnotation"; } }; -class AppExport AnnotationLabel : public DocumentObject +class AppExport AnnotationLabel: public DocumentObject { PROPERTY_HEADER_WITH_OVERRIDE(App::AnnotationLabel); @@ -64,12 +65,13 @@ public: App::PropertyVector TextPosition; /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderAnnotationLabel"; } }; -} //namespace App +} // namespace App -#endif // APP_ANNOTATION_H +#endif // APP_ANNOTATION_H diff --git a/src/App/ApplicationPy.cpp b/src/App/ApplicationPy.cpp index cfa9621103..7303d7e56c 100644 --- a/src/App/ApplicationPy.cpp +++ b/src/App/ApplicationPy.cpp @@ -38,7 +38,7 @@ #include "DocumentObjectPy.h" -//using Base::GetConsole; +// using Base::GetConsole; using namespace Base; using namespace App; @@ -48,118 +48,191 @@ using namespace App; // Application methods structure PyMethodDef Application::Methods[] = { - {"ParamGet", (PyCFunction) Application::sGetParam, METH_VARARGS, - "Get parameters by path"}, - {"saveParameter", (PyCFunction) Application::sSaveParameter, METH_VARARGS, + {"ParamGet", (PyCFunction)Application::sGetParam, METH_VARARGS, "Get parameters by path"}, + {"saveParameter", + (PyCFunction)Application::sSaveParameter, + METH_VARARGS, "saveParameter(config='User parameter') -> None\n" "Save parameter set to file. The default set is 'User parameter'"}, - {"Version", (PyCFunction) Application::sGetVersion, METH_VARARGS, + {"Version", + (PyCFunction)Application::sGetVersion, + METH_VARARGS, "Print the version to the output."}, - {"ConfigGet", (PyCFunction) Application::sGetConfig, METH_VARARGS, + {"ConfigGet", + (PyCFunction)Application::sGetConfig, + METH_VARARGS, "ConfigGet(string) -- Get the value for the given key."}, - {"ConfigSet", (PyCFunction) Application::sSetConfig, METH_VARARGS, + {"ConfigSet", + (PyCFunction)Application::sSetConfig, + METH_VARARGS, "ConfigSet(string, string) -- Set the given key to the given value."}, - {"ConfigDump", (PyCFunction) Application::sDumpConfig, METH_VARARGS, + {"ConfigDump", + (PyCFunction)Application::sDumpConfig, + METH_VARARGS, "Dump the configuration to the output."}, - {"addImportType", (PyCFunction) Application::sAddImportType, METH_VARARGS, + {"addImportType", + (PyCFunction)Application::sAddImportType, + METH_VARARGS, "Register filetype for import"}, - {"changeImportModule", (PyCFunction) Application::sChangeImportModule, METH_VARARGS, + {"changeImportModule", + (PyCFunction)Application::sChangeImportModule, + METH_VARARGS, "Change the import module name of a registered filetype"}, - {"getImportType", (PyCFunction) Application::sGetImportType, METH_VARARGS, + {"getImportType", + (PyCFunction)Application::sGetImportType, + METH_VARARGS, "Get the name of the module that can import the filetype"}, - {"addExportType", (PyCFunction) Application::sAddExportType, METH_VARARGS, + {"addExportType", + (PyCFunction)Application::sAddExportType, + METH_VARARGS, "Register filetype for export"}, - {"changeExportModule", (PyCFunction) Application::sChangeExportModule, METH_VARARGS, + {"changeExportModule", + (PyCFunction)Application::sChangeExportModule, + METH_VARARGS, "Change the export module name of a registered filetype"}, - {"getExportType", (PyCFunction) Application::sGetExportType, METH_VARARGS, + {"getExportType", + (PyCFunction)Application::sGetExportType, + METH_VARARGS, "Get the name of the module that can export the filetype"}, - {"getResourceDir", (PyCFunction) Application::sGetResourcePath, METH_VARARGS, + {"getResourceDir", + (PyCFunction)Application::sGetResourcePath, + METH_VARARGS, "Get the root directory of all resources"}, - {"getLibraryDir", (PyCFunction) Application::sGetLibraryPath, METH_VARARGS, + {"getLibraryDir", + (PyCFunction)Application::sGetLibraryPath, + METH_VARARGS, "Get the directory of all extension modules"}, - {"getTempPath", (PyCFunction) Application::sGetTempPath, METH_VARARGS, + {"getTempPath", + (PyCFunction)Application::sGetTempPath, + METH_VARARGS, "Get the root directory of cached files"}, - {"getUserCachePath", (PyCFunction) Application::sGetUserCachePath, METH_VARARGS, + {"getUserCachePath", + (PyCFunction)Application::sGetUserCachePath, + METH_VARARGS, "Get the root path of cached files"}, - {"getUserConfigDir", (PyCFunction) Application::sGetUserConfigPath, METH_VARARGS, + {"getUserConfigDir", + (PyCFunction)Application::sGetUserConfigPath, + METH_VARARGS, "Get the root path of user config files"}, - {"getUserAppDataDir", (PyCFunction) Application::sGetUserAppDataPath, METH_VARARGS, + {"getUserAppDataDir", + (PyCFunction)Application::sGetUserAppDataPath, + METH_VARARGS, "Get the root directory of application data"}, - {"getUserMacroDir", (PyCFunction) Application::sGetUserMacroPath, METH_VARARGS, + {"getUserMacroDir", + (PyCFunction)Application::sGetUserMacroPath, + METH_VARARGS, "getUserMacroDir(bool=False) -> str\n\n" "Get the directory of the user's macro directory\n" "If parameter is False (the default) it returns the standard path in the" "user's home directory, otherwise it returns the user-defined path."}, - {"getHelpDir", (PyCFunction) Application::sGetHelpPath, METH_VARARGS, + {"getHelpDir", + (PyCFunction)Application::sGetHelpPath, + METH_VARARGS, "Get the directory of the documentation"}, - {"getHomePath", (PyCFunction) Application::sGetHomePath, METH_VARARGS, + {"getHomePath", + (PyCFunction)Application::sGetHomePath, + METH_VARARGS, "Get the home path, i.e. the parent directory of the executable"}, - {"loadFile", (PyCFunction) Application::sLoadFile, METH_VARARGS, + {"loadFile", + (PyCFunction)Application::sLoadFile, + METH_VARARGS, "loadFile(string=filename,[string=module]) -> None\n\n" "Loads an arbitrary file by delegating to the given Python module:\n" "* If no module is given it will be determined by the file extension.\n" "* If more than one module can load a file the first one will be taken.\n" "* If no module exists to load the file an exception will be raised."}, - {"open", reinterpret_cast(reinterpret_cast( Application::sOpenDocument )), METH_VARARGS|METH_KEYWORDS, + {"open", + reinterpret_cast(reinterpret_cast(Application::sOpenDocument)), + METH_VARARGS | METH_KEYWORDS, "See openDocument(string)"}, - {"openDocument", reinterpret_cast(reinterpret_cast( Application::sOpenDocument )), METH_VARARGS|METH_KEYWORDS, + {"openDocument", + reinterpret_cast(reinterpret_cast(Application::sOpenDocument)), + METH_VARARGS | METH_KEYWORDS, "openDocument(filepath,hidden=False) -> object\n" "Create a document and load the project file into the document.\n\n" "filepath: file path to an existing file. If the file doesn't exist\n" " or the file cannot be loaded an I/O exception is thrown.\n" " In this case the document is kept alive.\n" "hidden: whether to hide document 3D view."}, -// {"saveDocument", (PyCFunction) Application::sSaveDocument, METH_VARARGS, -// "saveDocument(string) -- Save the document to a file."}, -// {"saveDocumentAs", (PyCFunction) Application::sSaveDocumentAs, METH_VARARGS}, - {"newDocument", reinterpret_cast(reinterpret_cast( Application::sNewDocument )), METH_VARARGS|METH_KEYWORDS, + // {"saveDocument", (PyCFunction) Application::sSaveDocument, METH_VARARGS, + // "saveDocument(string) -- Save the document to a file."}, + // {"saveDocumentAs", (PyCFunction) Application::sSaveDocumentAs, METH_VARARGS}, + {"newDocument", + reinterpret_cast(reinterpret_cast(Application::sNewDocument)), + METH_VARARGS | METH_KEYWORDS, "newDocument(name, label=None, hidden=False, temp=False) -> object\n" "Create a new document with a given name.\n\n" "name: unique document name which is checked automatically.\n" "label: optional user changeable label for the document.\n" "hidden: whether to hide document 3D view.\n" "temp: mark the document as temporary so that it will not be saved"}, - {"closeDocument", (PyCFunction) Application::sCloseDocument, METH_VARARGS, + {"closeDocument", + (PyCFunction)Application::sCloseDocument, + METH_VARARGS, "closeDocument(string) -> None\n\n" "Close the document with a given name."}, - {"activeDocument", (PyCFunction) Application::sActiveDocument, METH_VARARGS, + {"activeDocument", + (PyCFunction)Application::sActiveDocument, + METH_VARARGS, "activeDocument() -> object or None\n\n" "Return the active document or None if there is no one."}, - {"setActiveDocument", (PyCFunction) Application::sSetActiveDocument, METH_VARARGS, + {"setActiveDocument", + (PyCFunction)Application::sSetActiveDocument, + METH_VARARGS, "setActiveDocement(string) -> None\n\n" "Set the active document by its name."}, - {"getDocument", (PyCFunction) Application::sGetDocument, METH_VARARGS, + {"getDocument", + (PyCFunction)Application::sGetDocument, + METH_VARARGS, "getDocument(string) -> object\n\n" "Get a document by its name or raise an exception\n" "if there is no document with the given name."}, - {"listDocuments", (PyCFunction) Application::sListDocuments, METH_VARARGS, + {"listDocuments", + (PyCFunction)Application::sListDocuments, + METH_VARARGS, "listDocuments(sort=False) -> list\n\n" "Return a list of names of all documents, optionally sort in dependency order."}, - {"addDocumentObserver", (PyCFunction) Application::sAddDocObserver, METH_VARARGS, + {"addDocumentObserver", + (PyCFunction)Application::sAddDocObserver, + METH_VARARGS, "addDocumentObserver() -> None\n\n" "Add an observer to get notified about changes on documents."}, - {"removeDocumentObserver", (PyCFunction) Application::sRemoveDocObserver, METH_VARARGS, + {"removeDocumentObserver", + (PyCFunction)Application::sRemoveDocObserver, + METH_VARARGS, "removeDocumentObserver() -> None\n\n" "Remove an added document observer."}, - {"setLogLevel", (PyCFunction) Application::sSetLogLevel, METH_VARARGS, + {"setLogLevel", + (PyCFunction)Application::sSetLogLevel, + METH_VARARGS, "setLogLevel(tag, level) -- Set the log level for a string tag.\n" "'level' can either be string 'Log', 'Msg', 'Wrn', 'Error', or an integer value"}, - {"getLogLevel", (PyCFunction) Application::sGetLogLevel, METH_VARARGS, + {"getLogLevel", + (PyCFunction)Application::sGetLogLevel, + METH_VARARGS, "getLogLevel(tag) -- Get the log level of a string tag"}, - {"checkLinkDepth", (PyCFunction) Application::sCheckLinkDepth, METH_VARARGS, + {"checkLinkDepth", + (PyCFunction)Application::sCheckLinkDepth, + METH_VARARGS, "checkLinkDepth(depth) -- check link recursion depth"}, - {"getLinksTo", (PyCFunction) Application::sGetLinksTo, METH_VARARGS, + {"getLinksTo", + (PyCFunction)Application::sGetLinksTo, + METH_VARARGS, "getLinksTo(obj,options=0,maxCount=0) -- return the objects linked to 'obj'\n\n" "options: 1: recursive, 2: check link array. Options can combine.\n" "maxCount: to limit the number of links returned\n"}, - {"getDependentObjects", (PyCFunction) Application::sGetDependentObjects, METH_VARARGS, + {"getDependentObjects", + (PyCFunction)Application::sGetDependentObjects, + METH_VARARGS, "getDependentObjects(obj|[obj,...], options=0)\n" "Return a list of dependent objects including the given objects.\n\n" "options: can have the following bit flags,\n" " 1: to sort the list in topological order.\n" " 2: to exclude dependency of Link type object."}, - {"setActiveTransaction", (PyCFunction) Application::sSetActiveTransaction, METH_VARARGS, + {"setActiveTransaction", + (PyCFunction)Application::sSetActiveTransaction, + METH_VARARGS, "setActiveTransaction(name, persist=False) -- setup active transaction with the given name\n\n" "name: the transaction name\n" "persist(False): by default, if the calling code is inside any invocation of a command, it\n" @@ -168,15 +241,23 @@ PyMethodDef Application::Methods[] = { "Returns the transaction ID for the active transaction. An application-wide\n" "active transaction causes any document changes to open a transaction with\n" "the given name and ID."}, - {"getActiveTransaction", (PyCFunction) Application::sGetActiveTransaction, METH_VARARGS, + {"getActiveTransaction", + (PyCFunction)Application::sGetActiveTransaction, + METH_VARARGS, "getActiveTransaction() -> (name,id)\n\n" "return the current active transaction name and ID"}, - {"closeActiveTransaction", (PyCFunction) Application::sCloseActiveTransaction, METH_VARARGS, + {"closeActiveTransaction", + (PyCFunction)Application::sCloseActiveTransaction, + METH_VARARGS, "closeActiveTransaction(abort=False) -- commit or abort current active transaction"}, - {"isRestoring", (PyCFunction) Application::sIsRestoring, METH_VARARGS, + {"isRestoring", + (PyCFunction)Application::sIsRestoring, + METH_VARARGS, "isRestoring() -> bool\n\n" "Test if the application is opening some document"}, - {"checkAbort", (PyCFunction) Application::sCheckAbort, METH_VARARGS, + {"checkAbort", + (PyCFunction)Application::sCheckAbort, + METH_VARARGS, "checkAbort() -- check for user abort in length operation.\n\n" "This only works if there is an active sequencer (or ProgressIndicator in Python).\n" "There is an active sequencer during document restore and recomputation. User may\n" @@ -186,13 +267,14 @@ PyMethodDef Application::Methods[] = { }; -PyObject* Application::sLoadFile(PyObject * /*self*/, PyObject *args) +PyObject* Application::sLoadFile(PyObject* /*self*/, PyObject* args) { - const char *path; - const char *doc=""; - const char *mod=""; - if (!PyArg_ParseTuple(args, "s|ss", &path, &doc, &mod)) + const char* path; + const char* doc = ""; + const char* mod = ""; + if (!PyArg_ParseTuple(args, "s|ss", &path, &doc, &mod)) { return nullptr; + } try { Base::FileInfo fi(path); if (!fi.isFile() || !fi.exists()) { @@ -215,16 +297,18 @@ PyObject* Application::sLoadFile(PyObject * /*self*/, PyObject *args) // path could contain characters that need escaping, such as quote signs // therefore use its representation in the Python code string - PyObject *pathObj = PyUnicode_FromString(path); - PyObject *pathReprObj = PyObject_Repr(pathObj); - const char *pathRepr = PyUnicode_AsUTF8(pathReprObj); + PyObject* pathObj = PyUnicode_FromString(path); + PyObject* pathReprObj = PyObject_Repr(pathObj); + const char* pathRepr = PyUnicode_AsUTF8(pathReprObj); std::stringstream str; str << "import " << module << std::endl; - if (fi.hasExtension("FCStd")) + if (fi.hasExtension("FCStd")) { str << module << ".openDocument(" << pathRepr << ")" << std::endl; - else + } + else { str << module << ".insert(" << pathRepr << ",'" << doc << "')" << std::endl; + } Py_DECREF(pathObj); Py_DECREF(pathReprObj); @@ -243,26 +327,36 @@ PyObject* Application::sLoadFile(PyObject * /*self*/, PyObject *args) } } -PyObject* Application::sIsRestoring(PyObject * /*self*/, PyObject *args) { - if (!PyArg_ParseTuple(args, "")) +PyObject* Application::sIsRestoring(PyObject* /*self*/, PyObject* args) +{ + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } return Py::new_reference_to(Py::Boolean(GetApplication().isRestoring())); } -PyObject* Application::sOpenDocument(PyObject * /*self*/, PyObject *args, PyObject *kwd) +PyObject* Application::sOpenDocument(PyObject* /*self*/, PyObject* args, PyObject* kwd) { char* Name; - PyObject *hidden = Py_False; - static const std::array kwlist {"name", "hidden", nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords(args, kwd, "et|O!", kwlist, - "utf-8", &Name, &PyBool_Type, &hidden)) { + PyObject* hidden = Py_False; + static const std::array kwlist {"name", "hidden", nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + kwd, + "et|O!", + kwlist, + "utf-8", + &Name, + &PyBool_Type, + &hidden)) { return nullptr; } std::string EncodedName = std::string(Name); PyMem_Free(Name); try { // return new document - return (GetApplication().openDocument(EncodedName.c_str(), !Base::asBoolean(hidden))->getPyObject()); + return (GetApplication() + .openDocument(EncodedName.c_str(), !Base::asBoolean(hidden)) + ->getPyObject()); } catch (const Base::Exception& e) { PyErr_SetString(PyExc_IOError, e.what()); @@ -275,31 +369,47 @@ PyObject* Application::sOpenDocument(PyObject * /*self*/, PyObject *args, PyObje } } -PyObject* Application::sNewDocument(PyObject * /*self*/, PyObject *args, PyObject *kwd) +PyObject* Application::sNewDocument(PyObject* /*self*/, PyObject* args, PyObject* kwd) { - char *docName = nullptr; - char *usrName = nullptr; - PyObject *hidden = Py_False; - PyObject *temp = Py_False; - static const std::array kwlist {"name", "label", "hidden", "temp", nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords(args, kwd, "|etetO!O!", kwlist, - "utf-8", &docName, "utf-8", &usrName, &PyBool_Type, &hidden, &PyBool_Type, &temp)) { + char* docName = nullptr; + char* usrName = nullptr; + PyObject* hidden = Py_False; + PyObject* temp = Py_False; + static const std::array kwlist {"name", "label", "hidden", "temp", nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + kwd, + "|etetO!O!", + kwlist, + "utf-8", + &docName, + "utf-8", + &usrName, + &PyBool_Type, + &hidden, + &PyBool_Type, + &temp)) { return nullptr; } - PY_TRY { - App::Document* doc = GetApplication().newDocument(docName, usrName, !Base::asBoolean(hidden), Base::asBoolean(temp)); + PY_TRY + { + App::Document* doc = GetApplication().newDocument(docName, + usrName, + !Base::asBoolean(hidden), + Base::asBoolean(temp)); PyMem_Free(docName); PyMem_Free(usrName); return doc->getPyObject(); - }PY_CATCH; + } + PY_CATCH; } -PyObject* Application::sSetActiveDocument(PyObject * /*self*/, PyObject *args) +PyObject* Application::sSetActiveDocument(PyObject* /*self*/, PyObject* args) { - char *pstr = nullptr; - if (!PyArg_ParseTuple(args, "s", &pstr)) + char* pstr = nullptr; + if (!PyArg_ParseTuple(args, "s", &pstr)) { return nullptr; + } try { GetApplication().setActiveDocument(pstr); @@ -312,11 +422,12 @@ PyObject* Application::sSetActiveDocument(PyObject * /*self*/, PyObject *args) Py_Return; } -PyObject* Application::sCloseDocument(PyObject * /*self*/, PyObject *args) +PyObject* Application::sCloseDocument(PyObject* /*self*/, PyObject* args) { - char *pstr = nullptr; - if (!PyArg_ParseTuple(args, "s", &pstr)) + char* pstr = nullptr; + if (!PyArg_ParseTuple(args, "s", &pstr)) { return nullptr; + } Document* doc = GetApplication().getDocument(pstr); if (!doc) { @@ -336,14 +447,15 @@ PyObject* Application::sCloseDocument(PyObject * /*self*/, PyObject *args) Py_Return; } -PyObject* Application::sSaveDocument(PyObject * /*self*/, PyObject *args) +PyObject* Application::sSaveDocument(PyObject* /*self*/, PyObject* args) { - char *pDoc; - if (!PyArg_ParseTuple(args, "s", &pDoc)) + char* pDoc; + if (!PyArg_ParseTuple(args, "s", &pDoc)) { return nullptr; + } Document* doc = GetApplication().getDocument(pDoc); - if ( doc ) { + if (doc) { if (!doc->save()) { PyErr_Format(Base::PyExc_FC_GeneralError, "Cannot save document '%s'", pDoc); return nullptr; @@ -357,10 +469,11 @@ PyObject* Application::sSaveDocument(PyObject * /*self*/, PyObject *args) Py_Return; } -PyObject* Application::sActiveDocument(PyObject * /*self*/, PyObject *args) +PyObject* Application::sActiveDocument(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } Document* doc = GetApplication().getActiveDocument(); if (doc) { @@ -372,14 +485,15 @@ PyObject* Application::sActiveDocument(PyObject * /*self*/, PyObject *args) } } -PyObject* Application::sGetDocument(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetDocument(PyObject* /*self*/, PyObject* args) { - char *pstr=nullptr; - if (!PyArg_ParseTuple(args, "s", &pstr)) + char* pstr = nullptr; + if (!PyArg_ParseTuple(args, "s", &pstr)) { return nullptr; + } Document* doc = GetApplication().getDocument(pstr); - if ( !doc ) { + if (!doc) { PyErr_Format(PyExc_NameError, "Unknown document '%s'", pstr); return nullptr; } @@ -387,24 +501,29 @@ PyObject* Application::sGetDocument(PyObject * /*self*/, PyObject *args) return doc->getPyObject(); } -PyObject* Application::sGetParam(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetParam(PyObject* /*self*/, PyObject* args) { - char *pstr=nullptr; - if (!PyArg_ParseTuple(args, "s", &pstr)) + char* pstr = nullptr; + if (!PyArg_ParseTuple(args, "s", &pstr)) { return nullptr; + } - PY_TRY { + PY_TRY + { return GetPyObject(GetApplication().GetParameterGroupByPath(pstr)); - }PY_CATCH; + } + PY_CATCH; } -PyObject* Application::sSaveParameter(PyObject * /*self*/, PyObject *args) +PyObject* Application::sSaveParameter(PyObject* /*self*/, PyObject* args) { - const char *pstr = "User parameter"; - if (!PyArg_ParseTuple(args, "|s", &pstr)) + const char* pstr = "User parameter"; + if (!PyArg_ParseTuple(args, "|s", &pstr)) { return nullptr; + } - PY_TRY { + PY_TRY + { ParameterManager* param = App::GetApplication().GetParameterSet(pstr); if (!param) { std::stringstream str; @@ -422,16 +541,18 @@ PyObject* Application::sSaveParameter(PyObject * /*self*/, PyObject *args) param->SaveDocument(); Py_INCREF(Py_None); return Py_None; - }PY_CATCH; + } + PY_CATCH; } -PyObject* Application::sGetConfig(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetConfig(PyObject* /*self*/, PyObject* args) { - char *pstr; + char* pstr; - if (!PyArg_ParseTuple(args, "s", &pstr)) + if (!PyArg_ParseTuple(args, "s", &pstr)) { return nullptr; + } const std::map& Map = GetApplication().Config(); std::map::const_iterator it = Map.find(pstr); @@ -444,24 +565,26 @@ PyObject* Application::sGetConfig(PyObject * /*self*/, PyObject *args) } } -PyObject* Application::sDumpConfig(PyObject * /*self*/, PyObject *args) +PyObject* Application::sDumpConfig(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PyObject *dict = PyDict_New(); - for (const auto & It : GetApplication()._mConfig) { + PyObject* dict = PyDict_New(); + for (const auto& It : GetApplication()._mConfig) { PyDict_SetItemString(dict, It.first.c_str(), PyUnicode_FromString(It.second.c_str())); } return dict; } -PyObject* Application::sSetConfig(PyObject * /*self*/, PyObject *args) +PyObject* Application::sSetConfig(PyObject* /*self*/, PyObject* args) { char *pstr, *pstr2; - if (!PyArg_ParseTuple(args, "ss", &pstr, &pstr2)) + if (!PyArg_ParseTuple(args, "ss", &pstr, &pstr2)) { return nullptr; + } GetApplication()._mConfig[pstr] = pstr2; @@ -469,10 +592,11 @@ PyObject* Application::sSetConfig(PyObject * /*self*/, PyObject *args) return Py_None; } -PyObject* Application::sGetVersion(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetVersion(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } Py::List list; const std::map& cfg = Application::Config(); @@ -497,51 +621,56 @@ PyObject* Application::sGetVersion(PyObject * /*self*/, PyObject *args) list.append(Py::String(it != cfg.end() ? it->second : "")); it = cfg.find("BuildRevisionBranch"); - if (it != cfg.end()) + if (it != cfg.end()) { list.append(Py::String(it->second)); + } it = cfg.find("BuildRevisionHash"); - if (it != cfg.end()) + if (it != cfg.end()) { list.append(Py::String(it->second)); + } return Py::new_reference_to(list); } -PyObject* Application::sAddImportType(PyObject * /*self*/, PyObject *args) +PyObject* Application::sAddImportType(PyObject* /*self*/, PyObject* args) { - char *psKey,*psMod; + char *psKey, *psMod; - if (!PyArg_ParseTuple(args, "ss", &psKey,&psMod)) + if (!PyArg_ParseTuple(args, "ss", &psKey, &psMod)) { return nullptr; + } - GetApplication().addImportType(psKey,psMod); + GetApplication().addImportType(psKey, psMod); Py_Return; } -PyObject* Application::sChangeImportModule(PyObject * /*self*/, PyObject *args) +PyObject* Application::sChangeImportModule(PyObject* /*self*/, PyObject* args) { - char *key,*oldMod,*newMod; + char *key, *oldMod, *newMod; - if (!PyArg_ParseTuple(args, "sss", &key,&oldMod,&newMod)) + if (!PyArg_ParseTuple(args, "sss", &key, &oldMod, &newMod)) { return nullptr; + } - GetApplication().changeImportModule(key,oldMod,newMod); + GetApplication().changeImportModule(key, oldMod, newMod); Py_Return; } -PyObject* Application::sGetImportType(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetImportType(PyObject* /*self*/, PyObject* args) { - char* psKey=nullptr; + char* psKey = nullptr; - if (!PyArg_ParseTuple(args, "|s", &psKey)) + if (!PyArg_ParseTuple(args, "|s", &psKey)) { return nullptr; + } if (psKey) { Py::List list; std::vector modules = GetApplication().getImportModules(psKey); - for (const auto & it : modules) { + for (const auto& it : modules) { list.append(Py::String(it)); } @@ -550,7 +679,7 @@ PyObject* Application::sGetImportType(PyObject * /*self*/, PyObject *args) else { Py::Dict dict; std::vector types = GetApplication().getImportTypes(); - for (const auto & it : types) { + for (const auto& it : types) { std::vector modules = GetApplication().getImportModules(it.c_str()); if (modules.empty()) { dict.setItem(it.c_str(), Py::None()); @@ -560,7 +689,7 @@ PyObject* Application::sGetImportType(PyObject * /*self*/, PyObject *args) } else { Py::List list; - for (const auto & jt : modules) { + for (const auto& jt : modules) { list.append(Py::String(jt)); } dict.setItem(it.c_str(), list); @@ -571,41 +700,44 @@ PyObject* Application::sGetImportType(PyObject * /*self*/, PyObject *args) } } -PyObject* Application::sAddExportType(PyObject * /*self*/, PyObject *args) +PyObject* Application::sAddExportType(PyObject* /*self*/, PyObject* args) { - char *psKey,*psMod; + char *psKey, *psMod; - if (!PyArg_ParseTuple(args, "ss", &psKey,&psMod)) + if (!PyArg_ParseTuple(args, "ss", &psKey, &psMod)) { return nullptr; + } - GetApplication().addExportType(psKey,psMod); + GetApplication().addExportType(psKey, psMod); Py_Return; } -PyObject* Application::sChangeExportModule(PyObject * /*self*/, PyObject *args) +PyObject* Application::sChangeExportModule(PyObject* /*self*/, PyObject* args) { - char *key,*oldMod,*newMod; + char *key, *oldMod, *newMod; - if (!PyArg_ParseTuple(args, "sss", &key,&oldMod,&newMod)) + if (!PyArg_ParseTuple(args, "sss", &key, &oldMod, &newMod)) { return nullptr; + } - GetApplication().changeExportModule(key,oldMod,newMod); + GetApplication().changeExportModule(key, oldMod, newMod); Py_Return; } -PyObject* Application::sGetExportType(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetExportType(PyObject* /*self*/, PyObject* args) { - char* psKey=nullptr; + char* psKey = nullptr; - if (!PyArg_ParseTuple(args, "|s", &psKey)) + if (!PyArg_ParseTuple(args, "|s", &psKey)) { return nullptr; + } if (psKey) { Py::List list; std::vector modules = GetApplication().getExportModules(psKey); - for (const auto & it : modules) { + for (const auto& it : modules) { list.append(Py::String(it)); } @@ -614,7 +746,7 @@ PyObject* Application::sGetExportType(PyObject * /*self*/, PyObject *args) else { Py::Dict dict; std::vector types = GetApplication().getExportTypes(); - for (const auto & it : types) { + for (const auto& it : types) { std::vector modules = GetApplication().getExportModules(it.c_str()); if (modules.empty()) { dict.setItem(it.c_str(), Py::None()); @@ -624,7 +756,7 @@ PyObject* Application::sGetExportType(PyObject * /*self*/, PyObject *args) } else { Py::List list; - for (const auto & jt : modules) { + for (const auto& jt : modules) { list.append(Py::String(jt)); } dict.setItem(it.c_str(), list); @@ -635,112 +767,125 @@ PyObject* Application::sGetExportType(PyObject * /*self*/, PyObject *args) } } -PyObject* Application::sGetResourcePath(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetResourcePath(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - Py::String datadir(Application::getResourceDir(),"utf-8"); + Py::String datadir(Application::getResourceDir(), "utf-8"); return Py::new_reference_to(datadir); } -PyObject* Application::sGetLibraryPath(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetLibraryPath(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - Py::String datadir(Application::getLibraryDir(),"utf-8"); + Py::String datadir(Application::getLibraryDir(), "utf-8"); return Py::new_reference_to(datadir); } -PyObject* Application::sGetTempPath(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetTempPath(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - Py::String datadir(Application::getTempPath(),"utf-8"); + Py::String datadir(Application::getTempPath(), "utf-8"); return Py::new_reference_to(datadir); } -PyObject* Application::sGetUserCachePath(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetUserCachePath(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - Py::String datadir(Application::getUserCachePath(),"utf-8"); + Py::String datadir(Application::getUserCachePath(), "utf-8"); return Py::new_reference_to(datadir); } -PyObject* Application::sGetUserConfigPath(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetUserConfigPath(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - Py::String datadir(Application::getUserConfigPath(),"utf-8"); + Py::String datadir(Application::getUserConfigPath(), "utf-8"); return Py::new_reference_to(datadir); } -PyObject* Application::sGetUserAppDataPath(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetUserAppDataPath(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - Py::String user_data_dir(Application::getUserAppDataDir(),"utf-8"); + Py::String user_data_dir(Application::getUserAppDataDir(), "utf-8"); return Py::new_reference_to(user_data_dir); } -PyObject* Application::sGetUserMacroPath(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetUserMacroPath(PyObject* /*self*/, PyObject* args) { - PyObject *actual = Py_False; - if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &actual)) + PyObject* actual = Py_False; + if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &actual)) { return nullptr; + } std::string macroDir = Application::getUserMacroDir(); if (Base::asBoolean(actual)) { - macroDir = App::GetApplication(). - GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro") - ->GetASCII("MacroPath", macroDir.c_str()); + macroDir = App::GetApplication() + .GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro") + ->GetASCII("MacroPath", macroDir.c_str()); std::replace(macroDir.begin(), macroDir.end(), '/', PATHSEP); } - Py::String user_macro_dir(macroDir,"utf-8"); + Py::String user_macro_dir(macroDir, "utf-8"); return Py::new_reference_to(user_macro_dir); } -PyObject* Application::sGetHelpPath(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetHelpPath(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - Py::String user_macro_dir(Application::getHelpDir(),"utf-8"); + Py::String user_macro_dir(Application::getHelpDir(), "utf-8"); return Py::new_reference_to(user_macro_dir); } -PyObject* Application::sGetHomePath(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetHomePath(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - Py::String homedir(Application::getHomePath(),"utf-8"); + Py::String homedir(Application::getHomePath(), "utf-8"); return Py::new_reference_to(homedir); } -PyObject* Application::sListDocuments(PyObject * /*self*/, PyObject *args) +PyObject* Application::sListDocuments(PyObject* /*self*/, PyObject* args) { - PyObject *sort = Py_False; - if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &sort)) + PyObject* sort = Py_False; + if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &sort)) { return nullptr; - PY_TRY { - PyObject *pDict = PyDict_New(); - PyObject *pKey; + } + PY_TRY + { + PyObject* pDict = PyDict_New(); + PyObject* pKey; Base::PyObjectBase* pValue; - std::vector docs = GetApplication().getDocuments();; - if (Base::asBoolean(sort)) - docs = Document::getDependentDocuments(docs,true); + std::vector docs = GetApplication().getDocuments(); + ; + if (Base::asBoolean(sort)) { + docs = Document::getDependentDocuments(docs, true); + } for (auto doc : docs) { - pKey = PyUnicode_FromString(doc->getName()); + pKey = PyUnicode_FromString(doc->getName()); // GetPyObject() increments pValue = static_cast(doc->getPyObject()); PyDict_SetItem(pDict, pKey, pValue); @@ -749,157 +894,203 @@ PyObject* Application::sListDocuments(PyObject * /*self*/, PyObject *args) } return pDict; - } PY_CATCH; + } + PY_CATCH; } -PyObject* Application::sAddDocObserver(PyObject * /*self*/, PyObject *args) +PyObject* Application::sAddDocObserver(PyObject* /*self*/, PyObject* args) { PyObject* o; - if (!PyArg_ParseTuple(args, "O",&o)) + if (!PyArg_ParseTuple(args, "O", &o)) { return nullptr; - PY_TRY { + } + PY_TRY + { DocumentObserverPython::addObserver(Py::Object(o)); Py_Return; - } PY_CATCH; + } + PY_CATCH; } -PyObject* Application::sRemoveDocObserver(PyObject * /*self*/, PyObject *args) +PyObject* Application::sRemoveDocObserver(PyObject* /*self*/, PyObject* args) { PyObject* o; - if (!PyArg_ParseTuple(args, "O",&o)) + if (!PyArg_ParseTuple(args, "O", &o)) { return nullptr; - PY_TRY { + } + PY_TRY + { DocumentObserverPython::removeObserver(Py::Object(o)); Py_Return; - } PY_CATCH; + } + PY_CATCH; } -PyObject *Application::sSetLogLevel(PyObject * /*self*/, PyObject *args) +PyObject* Application::sSetLogLevel(PyObject* /*self*/, PyObject* args) { - char *tag; - PyObject *pcObj; - if (!PyArg_ParseTuple(args, "sO", &tag, &pcObj)) + char* tag; + PyObject* pcObj; + if (!PyArg_ParseTuple(args, "sO", &tag, &pcObj)) { return nullptr; - PY_TRY{ + } + PY_TRY + { int l; if (PyUnicode_Check(pcObj)) { - const char *pstr = PyUnicode_AsUTF8(pcObj); - if(strcmp(pstr,"Log") == 0) + const char* pstr = PyUnicode_AsUTF8(pcObj); + if (strcmp(pstr, "Log") == 0) { l = FC_LOGLEVEL_LOG; - else if(strcmp(pstr,"Warning") == 0) + } + else if (strcmp(pstr, "Warning") == 0) { l = FC_LOGLEVEL_WARN; - else if(strcmp(pstr,"Message") == 0) + } + else if (strcmp(pstr, "Message") == 0) { l = FC_LOGLEVEL_MSG; - else if(strcmp(pstr,"Error") == 0) + } + else if (strcmp(pstr, "Error") == 0) { l = FC_LOGLEVEL_ERR; - else if(strcmp(pstr,"Trace") == 0) + } + else if (strcmp(pstr, "Trace") == 0) { l = FC_LOGLEVEL_TRACE; - else if(strcmp(pstr,"Default") == 0) + } + else if (strcmp(pstr, "Default") == 0) { l = FC_LOGLEVEL_DEFAULT; + } else { Py_Error(PyExc_ValueError, - "Unknown Log Level (use 'Default', 'Error', 'Warning', 'Message', 'Log', 'Trace' or an integer)"); + "Unknown Log Level (use 'Default', 'Error', 'Warning', 'Message', 'Log', " + "'Trace' or an integer)"); return nullptr; } - }else + } + else { l = PyLong_AsLong(pcObj); - GetApplication().GetParameterGroupByPath("User parameter:BaseApp/LogLevels")->SetInt(tag,l); - if(strcmp(tag,"Default") == 0) { + } + GetApplication() + .GetParameterGroupByPath("User parameter:BaseApp/LogLevels") + ->SetInt(tag, l); + if (strcmp(tag, "Default") == 0) { #ifndef FC_DEBUG - if(l>=0) Base::Console().SetDefaultLogLevel(l); + if (l >= 0) { + Base::Console().SetDefaultLogLevel(l); + } #endif - }else if(strcmp(tag,"DebugDefault") == 0) { + } + else if (strcmp(tag, "DebugDefault") == 0) { #ifdef FC_DEBUG - if(l>=0) Base::Console().SetDefaultLogLevel(l); + if (l >= 0) { + Base::Console().SetDefaultLogLevel(l); + } #endif - }else + } + else { *Base::Console().GetLogLevel(tag) = l; + } Py_INCREF(Py_None); return Py_None; - }PY_CATCH; + } + PY_CATCH; } -PyObject *Application::sGetLogLevel(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetLogLevel(PyObject* /*self*/, PyObject* args) { - char *tag; - if (!PyArg_ParseTuple(args, "s", &tag)) + char* tag; + if (!PyArg_ParseTuple(args, "s", &tag)) { return nullptr; + } - PY_TRY{ + PY_TRY + { int l = -1; - if(strcmp(tag,"Default")==0) { + if (strcmp(tag, "Default") == 0) { #ifdef FC_DEBUG - l = _pcUserParamMngr->GetGroup("BaseApp/LogLevels")->GetInt(tag,-1); + l = _pcUserParamMngr->GetGroup("BaseApp/LogLevels")->GetInt(tag, -1); #endif - }else if(strcmp(tag,"DebugDefault")==0) { + } + else if (strcmp(tag, "DebugDefault") == 0) { #ifndef FC_DEBUG - l = _pcUserParamMngr->GetGroup("BaseApp/LogLevels")->GetInt(tag,-1); + l = _pcUserParamMngr->GetGroup("BaseApp/LogLevels")->GetInt(tag, -1); #endif - }else{ - int *pl = Base::Console().GetLogLevel(tag,false); - l = pl?*pl:-1; + } + else { + int* pl = Base::Console().GetLogLevel(tag, false); + l = pl ? *pl : -1; } // For performance reason, we only output integer value - return Py_BuildValue("i",Base::Console().LogLevel(l)); - } PY_CATCH; + return Py_BuildValue("i", Base::Console().LogLevel(l)); + } + PY_CATCH; } -PyObject *Application::sCheckLinkDepth(PyObject * /*self*/, PyObject *args) +PyObject* Application::sCheckLinkDepth(PyObject* /*self*/, PyObject* args) { short depth = 0; - if (!PyArg_ParseTuple(args, "h", &depth)) + if (!PyArg_ParseTuple(args, "h", &depth)) { return nullptr; + } - PY_TRY { - return Py::new_reference_to(Py::Int(GetApplication().checkLinkDepth(depth, MessageOption::Throw))); - }PY_CATCH; + PY_TRY + { + return Py::new_reference_to( + Py::Int(GetApplication().checkLinkDepth(depth, MessageOption::Throw))); + } + PY_CATCH; } -PyObject *Application::sGetLinksTo(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetLinksTo(PyObject* /*self*/, PyObject* args) { - PyObject *pyobj = Py_None; + PyObject* pyobj = Py_None; int options = 0; short count = 0; - if (!PyArg_ParseTuple(args, "|Oih",&pyobj,&options, &count)) + if (!PyArg_ParseTuple(args, "|Oih", &pyobj, &options, &count)) { return nullptr; + } - PY_TRY { - Base::PyTypeCheck(&pyobj, &DocumentObjectPy::Type, "Expect the first argument of type App.DocumentObject or None"); - DocumentObject *obj = nullptr; - if (pyobj) + PY_TRY + { + Base::PyTypeCheck(&pyobj, + &DocumentObjectPy::Type, + "Expect the first argument of type App.DocumentObject or None"); + DocumentObject* obj = nullptr; + if (pyobj) { obj = static_cast(pyobj)->getDocumentObjectPtr(); + } - auto links = GetApplication().getLinksTo(obj,options,count); + auto links = GetApplication().getLinksTo(obj, options, count); Py::Tuple ret(links.size()); - int i=0; - for(auto o : links) - ret.setItem(i++,Py::Object(o->getPyObject(),true)); + int i = 0; + for (auto o : links) { + ret.setItem(i++, Py::Object(o->getPyObject(), true)); + } return Py::new_reference_to(ret); } PY_CATCH; } -PyObject *Application::sGetDependentObjects(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetDependentObjects(PyObject* /*self*/, PyObject* args) { - PyObject *obj; + PyObject* obj; int options = 0; - if (!PyArg_ParseTuple(args, "O|i", &obj,&options)) + if (!PyArg_ParseTuple(args, "O|i", &obj, &options)) { return nullptr; + } std::vector objs; if (PySequence_Check(obj)) { Py::Sequence seq(obj); - for (Py_ssize_t i=0;i(seq[i].ptr())->getDocumentObjectPtr()); } } - else if(!PyObject_TypeCheck(obj,&DocumentObjectPy::Type)) { - PyErr_SetString(PyExc_TypeError, + else if (!PyObject_TypeCheck(obj, &DocumentObjectPy::Type)) { + PyErr_SetString( + PyExc_TypeError, "Expect first argument to be either a document object or sequence of document objects"); return nullptr; } @@ -907,67 +1098,83 @@ PyObject *Application::sGetDependentObjects(PyObject * /*self*/, PyObject *args) objs.push_back(static_cast(obj)->getDocumentObjectPtr()); } - PY_TRY { - auto ret = App::Document::getDependencyList(objs,options); + PY_TRY + { + auto ret = App::Document::getDependencyList(objs, options); Py::Tuple tuple(ret.size()); - for(size_t i=0;igetPyObject(),true)); + for (size_t i = 0; i < ret.size(); ++i) { + tuple.setItem(i, Py::Object(ret[i]->getPyObject(), true)); + } return Py::new_reference_to(tuple); - } PY_CATCH; + } + PY_CATCH; } -PyObject *Application::sSetActiveTransaction(PyObject * /*self*/, PyObject *args) +PyObject* Application::sSetActiveTransaction(PyObject* /*self*/, PyObject* args) { - char *name; - PyObject *persist = Py_False; - if (!PyArg_ParseTuple(args, "s|O!", &name, &PyBool_Type, &persist)) + char* name; + PyObject* persist = Py_False; + if (!PyArg_ParseTuple(args, "s|O!", &name, &PyBool_Type, &persist)) { return nullptr; + } - PY_TRY { + PY_TRY + { Py::Int ret(GetApplication().setActiveTransaction(name, Base::asBoolean(persist))); return Py::new_reference_to(ret); - }PY_CATCH; + } + PY_CATCH; } -PyObject *Application::sGetActiveTransaction(PyObject * /*self*/, PyObject *args) +PyObject* Application::sGetActiveTransaction(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { int id = 0; - const char *name = GetApplication().getActiveTransaction(&id); - if(!name || id<=0) + const char* name = GetApplication().getActiveTransaction(&id); + if (!name || id <= 0) { Py_Return; + } Py::Tuple ret(2); - ret.setItem(0,Py::String(name)); - ret.setItem(1,Py::Int(id)); + ret.setItem(0, Py::String(name)); + ret.setItem(1, Py::Int(id)); return Py::new_reference_to(ret); - }PY_CATCH; + } + PY_CATCH; } -PyObject *Application::sCloseActiveTransaction(PyObject * /*self*/, PyObject *args) +PyObject* Application::sCloseActiveTransaction(PyObject* /*self*/, PyObject* args) { - PyObject *abort = Py_False; + PyObject* abort = Py_False; int id = 0; - if (!PyArg_ParseTuple(args, "|O!i", &PyBool_Type, &abort,&id)) + if (!PyArg_ParseTuple(args, "|O!i", &PyBool_Type, &abort, &id)) { return nullptr; + } - PY_TRY { + PY_TRY + { GetApplication().closeActiveTransaction(Base::asBoolean(abort), id); Py_Return; - } PY_CATCH; + } + PY_CATCH; } -PyObject *Application::sCheckAbort(PyObject * /*self*/, PyObject *args) +PyObject* Application::sCheckAbort(PyObject* /*self*/, PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { Base::Sequencer().checkAbort(); Py_Return; - }PY_CATCH + } + PY_CATCH } diff --git a/src/App/AutoTransaction.cpp b/src/App/AutoTransaction.cpp index 6597f7109c..b70a4d5797 100644 --- a/src/App/AutoTransaction.cpp +++ b/src/App/AutoTransaction.cpp @@ -37,12 +37,11 @@ using namespace App; static int _TransactionLock; static int _TransactionClosed; -AutoTransaction::AutoTransaction(const char *name, bool tmpName) { - auto &app = GetApplication(); - if(name && app._activeTransactionGuard>=0) { - if(!app.getActiveTransaction() - || (!tmpName && app._activeTransactionTmpName)) - { +AutoTransaction::AutoTransaction(const char* name, bool tmpName) +{ + auto& app = GetApplication(); + if (name && app._activeTransactionGuard >= 0) { + if (!app.getActiveTransaction() || (!tmpName && app._activeTransactionTmpName)) { FC_LOG("auto transaction '" << name << "', " << tmpName); tid = app.setActiveTransaction(name); app._activeTransactionTmpName = tmpName; @@ -52,166 +51,206 @@ AutoTransaction::AutoTransaction(const char *name, bool tmpName) { // and any stack below. This is to support user setting active transaction // before having any existing AutoTransaction on stack, or 'persist' // transaction that can out live AutoTransaction. - if(app._activeTransactionGuard<0) + if (app._activeTransactionGuard < 0) { --app._activeTransactionGuard; - else if(tid || app._activeTransactionGuard>0) + } + else if (tid || app._activeTransactionGuard > 0) { ++app._activeTransactionGuard; - else if(app.getActiveTransaction()) { + } + else if (app.getActiveTransaction()) { FC_LOG("auto transaction disabled because of '" << app._activeTransactionName << "'"); --app._activeTransactionGuard; - } else + } + else { ++app._activeTransactionGuard; + } FC_TRACE("construct auto Transaction " << app._activeTransactionGuard); } -AutoTransaction::~AutoTransaction() { - auto &app = GetApplication(); +AutoTransaction::~AutoTransaction() +{ + auto& app = GetApplication(); FC_TRACE("before destruct auto Transaction " << app._activeTransactionGuard); - if(app._activeTransactionGuard<0) + if (app._activeTransactionGuard < 0) { ++app._activeTransactionGuard; - else if(!app._activeTransactionGuard) { + } + else if (!app._activeTransactionGuard) { #ifdef FC_DEBUG FC_ERR("Transaction guard error"); #endif - } else if(--app._activeTransactionGuard == 0) { + } + else if (--app._activeTransactionGuard == 0) { try { // We don't call close() here, because close() only closes // transaction that we opened during construction time. However, // when _activeTransactionGuard reaches zero here, we are supposed // to close any transaction opened. app.closeActiveTransaction(); - } catch(Base::Exception &e) { + } + catch (Base::Exception& e) { e.ReportException(); - } catch(...) - {} + } + catch (...) { + } } FC_TRACE("destruct auto Transaction " << app._activeTransactionGuard); } -void AutoTransaction::close(bool abort) { - if(tid || abort) { - GetApplication().closeActiveTransaction(abort,abort?0:tid); +void AutoTransaction::close(bool abort) +{ + if (tid || abort) { + GetApplication().closeActiveTransaction(abort, abort ? 0 : tid); tid = 0; } } -void AutoTransaction::setEnable(bool enable) { - auto &app = GetApplication(); - if(!app._activeTransactionGuard) +void AutoTransaction::setEnable(bool enable) +{ + auto& app = GetApplication(); + if (!app._activeTransactionGuard) { return; - if((enable && app._activeTransactionGuard>0) - || (!enable && app._activeTransactionGuard<0)) + } + if ((enable && app._activeTransactionGuard > 0) + || (!enable && app._activeTransactionGuard < 0)) { return; + } app._activeTransactionGuard = -app._activeTransactionGuard; FC_TRACE("toggle auto Transaction " << app._activeTransactionGuard); - if(!enable && app._activeTransactionTmpName) { + if (!enable && app._activeTransactionTmpName) { bool close = true; - for(auto &v : app.DocMap) { - if(v.second->hasPendingTransaction()) { + for (auto& v : app.DocMap) { + if (v.second->hasPendingTransaction()) { close = false; break; } } - if(close) + if (close) { app.closeActiveTransaction(); + } } } -int Application::setActiveTransaction(const char *name, bool persist) { - if(!name || !name[0]) +int Application::setActiveTransaction(const char* name, bool persist) +{ + if (!name || !name[0]) { name = "Command"; + } - if(_activeTransactionGuard>0 && getActiveTransaction()) { - if(_activeTransactionTmpName) { + if (_activeTransactionGuard > 0 && getActiveTransaction()) { + if (_activeTransactionTmpName) { FC_LOG("transaction rename to '" << name << "'"); - for(auto &v : DocMap) - v.second->renameTransaction(name,_activeTransactionID); - } else { - if(persist) + for (auto& v : DocMap) { + v.second->renameTransaction(name, _activeTransactionID); + } + } + else { + if (persist) { AutoTransaction::setEnable(false); + } return 0; } - } else if (_TransactionLock) { - if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) + } + else if (_TransactionLock) { + if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) { FC_WARN("Transaction locked, ignore new transaction '" << name << "'"); + } return 0; - } else { + } + else { FC_LOG("set active transaction '" << name << "'"); _activeTransactionID = 0; - for(auto &v : DocMap) + for (auto& v : DocMap) { v.second->_commitTransaction(); + } _activeTransactionID = Transaction::getNewID(); } _activeTransactionTmpName = false; _activeTransactionName = name; - if(persist) + if (persist) { AutoTransaction::setEnable(false); + } return _activeTransactionID; } -const char *Application::getActiveTransaction(int *id) const { +const char* Application::getActiveTransaction(int* id) const +{ int tid = 0; - if(Transaction::getLastID() == _activeTransactionID) + if (Transaction::getLastID() == _activeTransactionID) { tid = _activeTransactionID; - if (id) + } + if (id) { *id = tid; + } return tid ? _activeTransactionName.c_str() : nullptr; } -void Application::closeActiveTransaction(bool abort, int id) { - if(!id) id = _activeTransactionID; - if(!id) +void Application::closeActiveTransaction(bool abort, int id) +{ + if (!id) { + id = _activeTransactionID; + } + if (!id) { return; + } - if(_activeTransactionGuard>0 && !abort) { + if (_activeTransactionGuard > 0 && !abort) { FC_LOG("ignore close transaction"); return; } - if(_TransactionLock) { - if(_TransactionClosed >= 0) - _TransactionLock = abort?-1:1; - FC_LOG("pending " << (abort?"abort":"close") << " transaction"); + if (_TransactionLock) { + if (_TransactionClosed >= 0) { + _TransactionLock = abort ? -1 : 1; + } + FC_LOG("pending " << (abort ? "abort" : "close") << " transaction"); return; } FC_LOG("close transaction '" << _activeTransactionName << "' " << abort); _activeTransactionID = 0; - TransactionSignaller signaller(abort,false); - for(auto &v : DocMap) { - if(v.second->getTransactionID(true) != id) + TransactionSignaller signaller(abort, false); + for (auto& v : DocMap) { + if (v.second->getTransactionID(true) != id) { continue; - if(abort) + } + if (abort) { v.second->_abortTransaction(); - else + } + else { v.second->_commitTransaction(); + } } } //////////////////////////////////////////////////////////////////////// TransactionLocker::TransactionLocker(bool lock) - :active(lock) + : active(lock) { - if(lock) + if (lock) { ++_TransactionLock; + } } TransactionLocker::~TransactionLocker() { - if(active) { + if (active) { try { activate(false); return; - } catch (Base::Exception &e) { + } + catch (Base::Exception& e) { e.ReportException(); - } catch (Py::Exception &) { + } + catch (Py::Exception&) { Base::PyException e; e.ReportException(); - } catch (std::exception &e) { + } + catch (std::exception& e) { FC_ERR(e.what()); - } catch (...) { + } + catch (...) { } FC_ERR("Exception when unlocking transaction"); } @@ -219,26 +258,28 @@ TransactionLocker::~TransactionLocker() void TransactionLocker::activate(bool enable) { - if(active == enable) + if (active == enable) { return; + } active = enable; - if(active) { + if (active) { ++_TransactionLock; return; } - if(--_TransactionLock != 0) + if (--_TransactionLock != 0) { return; + } - if(_TransactionClosed) { - bool abort = (_TransactionClosed<0); + if (_TransactionClosed) { + bool abort = (_TransactionClosed < 0); _TransactionClosed = 0; GetApplication().closeActiveTransaction(abort); } } -bool TransactionLocker::isLocked() { +bool TransactionLocker::isLocked() +{ return _TransactionLock > 0; } - diff --git a/src/App/AutoTransaction.h b/src/App/AutoTransaction.h index cd44fe7f70..6318d5c7cf 100644 --- a/src/App/AutoTransaction.h +++ b/src/App/AutoTransaction.h @@ -26,15 +26,17 @@ #include #include -namespace App { +namespace App +{ class Application; /// Helper class to manager transaction (i.e. undo/redo) -class AppExport AutoTransaction { +class AppExport AutoTransaction +{ public: /// Private new operator to prevent heap allocation - void* operator new (std::size_t) = delete; + void* operator new(std::size_t) = delete; public: /** Constructor @@ -51,7 +53,7 @@ public: * current active transaction until it reaches zero. It does not have any * effect on aborting transaction, though. */ - AutoTransaction(const char *name=nullptr, bool tmpName=false); + AutoTransaction(const char* name = nullptr, bool tmpName = false); /** Destructor * @@ -67,7 +69,7 @@ public: * transaction, if the current transaction ID matches the one created inside * the constructor. For aborting, it will abort any current transaction */ - void close(bool abort=false); + void close(bool abort = false); /** Enable/Disable any AutoTransaction instance in the current stack * @@ -90,13 +92,13 @@ private: * The helper class is used to protect some critical transaction from being * closed prematurely, e.g. when deleting some object. */ -class AppExport TransactionLocker { +class AppExport TransactionLocker +{ public: - /** Constructor * @param lock: whether to activate the lock */ - TransactionLocker(bool lock=true); + TransactionLocker(bool lock = true); /** Destructor * Unlock the transaction is this locker is active @@ -114,7 +116,10 @@ public: void activate(bool enable); /// Check if the locker is active - bool isActive() const {return active;} + bool isActive() const + { + return active; + } /// Check if transaction is being locked static bool isLocked(); @@ -123,12 +128,12 @@ public: public: /// Private new operator to prevent heap allocation - void* operator new (std::size_t) = delete; + void* operator new(std::size_t) = delete; private: bool active; }; -} // namespace App +} // namespace App -#endif // APP_AUTOTRANSACTION_H +#endif // APP_AUTOTRANSACTION_H diff --git a/src/App/Branding.cpp b/src/App/Branding.cpp index ef50dc5302..2be169e8e6 100644 --- a/src/App/Branding.cpp +++ b/src/App/Branding.cpp @@ -63,10 +63,12 @@ Branding::Branding() bool Branding::readFile(const QString& fn) { QFile file(fn); - if (!file.open(QFile::ReadOnly)) + if (!file.open(QFile::ReadOnly)) { return false; - if (!evaluateXML(&file, domDocument)) + } + if (!evaluateXML(&file, domDocument)) { return false; + } file.close(); return true; } @@ -81,22 +83,22 @@ Branding::XmlConfig Branding::getUserDefines() const while (!child.isNull()) { std::string name = child.localName().toLatin1().constData(); std::string value = child.text().toUtf8().constData(); - if (std::find(filter.begin(), filter.end(), name) != filter.end()) + if (std::find(filter.begin(), filter.end(), name) != filter.end()) { cfg[name] = value; + } child = child.nextSiblingElement(); } } return cfg; } -bool Branding::evaluateXML(QIODevice *device, QDomDocument& xmlDocument) +bool Branding::evaluateXML(QIODevice* device, QDomDocument& xmlDocument) { QString errorStr; int errorLine; int errorColumn; - if (!xmlDocument.setContent(device, true, &errorStr, &errorLine, - &errorColumn)) { + if (!xmlDocument.setContent(device, true, &errorStr, &errorLine, &errorColumn)) { return false; } @@ -106,8 +108,9 @@ bool Branding::evaluateXML(QIODevice *device, QDomDocument& xmlDocument) } else if (root.hasAttribute(QLatin1String("version"))) { QString attr = root.attribute(QLatin1String("version")); - if (attr != QLatin1String("1.0")) + if (attr != QLatin1String("1.0")) { return false; + } } return true; diff --git a/src/App/Branding.h b/src/App/Branding.h index c0293f3270..b8ab7e97e0 100644 --- a/src/App/Branding.h +++ b/src/App/Branding.h @@ -33,7 +33,8 @@ class QIODevice; -namespace App { +namespace App +{ class Branding { @@ -46,10 +47,10 @@ public: private: QVector filter; - bool evaluateXML(QIODevice *device, QDomDocument& xmlDocument); + bool evaluateXML(QIODevice* device, QDomDocument& xmlDocument); QDomDocument domDocument; }; -} +} // namespace App -#endif // APP_BRANDING_H +#endif // APP_BRANDING_H diff --git a/src/App/CleanupProcess.cpp b/src/App/CleanupProcess.cpp index 30fbd35ae2..038de1abd3 100644 --- a/src/App/CleanupProcess.cpp +++ b/src/App/CleanupProcess.cpp @@ -31,7 +31,7 @@ using namespace App; namespace { - static std::list> cleanup_funcs; // NOLINT +static std::list> cleanup_funcs; // NOLINT } void CleanupProcess::registerCleanup(const std::function& func) diff --git a/src/App/CleanupProcess.h b/src/App/CleanupProcess.h index a5d9281b4f..fcc2631840 100644 --- a/src/App/CleanupProcess.h +++ b/src/App/CleanupProcess.h @@ -52,6 +52,6 @@ public: static void callCleanup(); }; -} +} // namespace App #endif // APP_CLEANUPPROCESS_H diff --git a/src/App/ComplexGeoDataPyImp.cpp b/src/App/ComplexGeoDataPyImp.cpp index 1dc12cccdd..878876d9c4 100644 --- a/src/App/ComplexGeoDataPyImp.cpp +++ b/src/App/ComplexGeoDataPyImp.cpp @@ -23,7 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include "ComplexGeoData.h" @@ -50,10 +50,11 @@ std::string ComplexGeoDataPy::representation() const return {""}; } -PyObject* ComplexGeoDataPy::getElementTypes(PyObject *args) +PyObject* ComplexGeoDataPy::getElementTypes(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } std::vector types = getComplexGeoDataPtr()->getElementTypes(); Py::List list; @@ -63,11 +64,12 @@ PyObject* ComplexGeoDataPy::getElementTypes(PyObject *args) return Py::new_reference_to(list); } -PyObject* ComplexGeoDataPy::countSubElements(PyObject *args) +PyObject* ComplexGeoDataPy::countSubElements(PyObject* args) { - char *type; - if (!PyArg_ParseTuple(args, "s", &type)) + char* type; + if (!PyArg_ParseTuple(args, "s", &type)) { return nullptr; + } try { unsigned long count = getComplexGeoDataPtr()->countSubElements(type); @@ -79,12 +81,13 @@ PyObject* ComplexGeoDataPy::countSubElements(PyObject *args) } } -PyObject* ComplexGeoDataPy::getFacesFromSubElement(PyObject *args) +PyObject* ComplexGeoDataPy::getFacesFromSubElement(PyObject* args) { - char *type; + char* type; unsigned long index; - if (!PyArg_ParseTuple(args, "sk", &type, &index)) + if (!PyArg_ParseTuple(args, "sk", &type, &index)) { return nullptr; + } std::vector points; std::vector normals; @@ -100,27 +103,29 @@ PyObject* ComplexGeoDataPy::getFacesFromSubElement(PyObject *args) Py::Tuple tuple(2); Py::List vertex; - for (const auto & it : points) + for (const auto& it : points) { vertex.append(Py::asObject(new Base::VectorPy(it))); + } tuple.setItem(0, vertex); Py::List facet; - for (const auto & it : facets) { + for (const auto& it : facets) { Py::Tuple f(3); - f.setItem(0,Py::Int(int(it.I1))); - f.setItem(1,Py::Int(int(it.I2))); - f.setItem(2,Py::Int(int(it.I3))); + f.setItem(0, Py::Int(int(it.I1))); + f.setItem(1, Py::Int(int(it.I2))); + f.setItem(2, Py::Int(int(it.I3))); facet.append(f); } tuple.setItem(1, facet); return Py::new_reference_to(tuple); } -PyObject* ComplexGeoDataPy::getLinesFromSubElement(PyObject *args) +PyObject* ComplexGeoDataPy::getLinesFromSubElement(PyObject* args) { - char *type; + char* type; int index; - if (!PyArg_ParseTuple(args, "si", &type, &index)) + if (!PyArg_ParseTuple(args, "si", &type, &index)) { return nullptr; + } std::vector points; std::vector lines; @@ -135,25 +140,27 @@ PyObject* ComplexGeoDataPy::getLinesFromSubElement(PyObject *args) Py::Tuple tuple(2); Py::List vertex; - for (const auto & it : points) + for (const auto& it : points) { vertex.append(Py::asObject(new Base::VectorPy(it))); + } tuple.setItem(0, vertex); Py::List line; - for (const auto & it : lines) { + for (const auto& it : lines) { Py::Tuple l(2); - l.setItem(0,Py::Int((int)it.I1)); - l.setItem(1,Py::Int((int)it.I2)); + l.setItem(0, Py::Int((int)it.I1)); + l.setItem(1, Py::Int((int)it.I2)); line.append(l); } tuple.setItem(1, line); return Py::new_reference_to(tuple); } -PyObject* ComplexGeoDataPy::getPoints(PyObject *args) +PyObject* ComplexGeoDataPy::getPoints(PyObject* args) { double accuracy = 0.05; - if (!PyArg_ParseTuple(args, "d", &accuracy)) + if (!PyArg_ParseTuple(args, "d", &accuracy)) { return nullptr; + } std::vector points; std::vector normals; @@ -167,24 +174,25 @@ PyObject* ComplexGeoDataPy::getPoints(PyObject *args) Py::Tuple tuple(2); Py::List vertex; - for (const auto & it : points) { + for (const auto& it : points) { vertex.append(Py::asObject(new Base::VectorPy(it))); } tuple.setItem(0, vertex); Py::List normal; - for (const auto & it : normals) { + for (const auto& it : normals) { normal.append(Py::asObject(new Base::VectorPy(it))); } tuple.setItem(1, normal); return Py::new_reference_to(tuple); } -PyObject* ComplexGeoDataPy::getLines(PyObject *args) +PyObject* ComplexGeoDataPy::getLines(PyObject* args) { double accuracy = 0.05; - if (!PyArg_ParseTuple(args, "d", &accuracy)) + if (!PyArg_ParseTuple(args, "d", &accuracy)) { return nullptr; + } std::vector points; std::vector lines; @@ -198,25 +206,27 @@ PyObject* ComplexGeoDataPy::getLines(PyObject *args) Py::Tuple tuple(2); Py::List vertex; - for (const auto & it : points) + for (const auto& it : points) { vertex.append(Py::asObject(new Base::VectorPy(it))); + } tuple.setItem(0, vertex); Py::List line; - for (const auto & it : lines) { + for (const auto& it : lines) { Py::Tuple l(2); - l.setItem(0,Py::Int((int)it.I1)); - l.setItem(1,Py::Int((int)it.I2)); + l.setItem(0, Py::Int((int)it.I1)); + l.setItem(1, Py::Int((int)it.I2)); line.append(l); } tuple.setItem(1, line); return Py::new_reference_to(tuple); } -PyObject* ComplexGeoDataPy::getFaces(PyObject *args) +PyObject* ComplexGeoDataPy::getFaces(PyObject* args) { double accuracy = 0.05; - if (!PyArg_ParseTuple(args, "d", &accuracy)) + if (!PyArg_ParseTuple(args, "d", &accuracy)) { return nullptr; + } std::vector points; std::vector facets; @@ -230,26 +240,28 @@ PyObject* ComplexGeoDataPy::getFaces(PyObject *args) Py::Tuple tuple(2); Py::List vertex; - for (const auto & it : points) + for (const auto& it : points) { vertex.append(Py::asObject(new Base::VectorPy(it))); + } tuple.setItem(0, vertex); Py::List facet; - for (const auto & it : facets) { + for (const auto& it : facets) { Py::Tuple f(3); - f.setItem(0,Py::Int((int)it.I1)); - f.setItem(1,Py::Int((int)it.I2)); - f.setItem(2,Py::Int((int)it.I3)); + f.setItem(0, Py::Int((int)it.I1)); + f.setItem(1, Py::Int((int)it.I2)); + f.setItem(2, Py::Int((int)it.I3)); facet.append(f); } tuple.setItem(1, facet); return Py::new_reference_to(tuple); } -PyObject* ComplexGeoDataPy::applyTranslation(PyObject *args) +PyObject* ComplexGeoDataPy::applyTranslation(PyObject* args) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type),&obj)) + PyObject* obj; + if (!PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &obj)) { return nullptr; + } try { Base::Vector3d move = static_cast(obj)->value(); @@ -262,11 +274,12 @@ PyObject* ComplexGeoDataPy::applyTranslation(PyObject *args) } } -PyObject* ComplexGeoDataPy::applyRotation(PyObject *args) +PyObject* ComplexGeoDataPy::applyRotation(PyObject* args) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "O!", &(Base::RotationPy::Type),&obj)) + PyObject* obj; + if (!PyArg_ParseTuple(args, "O!", &(Base::RotationPy::Type), &obj)) { return nullptr; + } try { Base::Rotation rot = static_cast(obj)->value(); @@ -279,11 +292,12 @@ PyObject* ComplexGeoDataPy::applyRotation(PyObject *args) } } -PyObject* ComplexGeoDataPy::transformGeometry(PyObject *args) +PyObject* ComplexGeoDataPy::transformGeometry(PyObject* args) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type),&obj)) + PyObject* obj; + if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type), &obj)) { return nullptr; + } try { Base::Matrix4D mat = static_cast(obj)->value(); @@ -377,17 +391,18 @@ PyObject* ComplexGeoDataPy::setElementName(PyObject* args, PyObject* kwds) PyObject* pySid = Py_None; PyObject* overwrite = Py_False; - const std::array kwlist = {"element", "name", "postfix", "overwrite", "sid", "tag", nullptr}; + const std::array kwlist = + {"element", "name", "postfix", "overwrite", "sid", "tag", nullptr}; if (!Wrapped_ParseTupleAndKeywords(args, - kwds, - "s|sssOOi", - kwlist, - &element, - &name, - &postfix, - &overwrite, - &pySid, - &tag)) { + kwds, + "s|sssOOi", + kwlist, + &element, + &name, + &postfix, + &overwrite, + &pySid, + &tag)) { return NULL; } ElementIDRefs sids; @@ -529,8 +544,9 @@ Py::Object ComplexGeoDataPy::getBoundBox() const Py::Object ComplexGeoDataPy::getCenterOfGravity() const { Base::Vector3d center; - if (getComplexGeoDataPtr()->getCenterOfGravity(center)) + if (getComplexGeoDataPtr()->getCenterOfGravity(center)) { return Py::Vector(center); + } throw Py::RuntimeError("Cannot get center of gravity"); } diff --git a/src/App/DocumentObjectExtension.cpp b/src/App/DocumentObjectExtension.cpp index 7072b6baea..85e3922839 100644 --- a/src/App/DocumentObjectExtension.cpp +++ b/src/App/DocumentObjectExtension.cpp @@ -39,55 +39,60 @@ DocumentObjectExtension::DocumentObjectExtension() DocumentObjectExtension::~DocumentObjectExtension() = default; -short int DocumentObjectExtension::extensionMustExecute() { +short int DocumentObjectExtension::extensionMustExecute() +{ return 0; } -App::DocumentObjectExecReturn* DocumentObjectExtension::extensionExecute() { +App::DocumentObjectExecReturn* DocumentObjectExtension::extensionExecute() +{ return App::DocumentObject::StdReturn; } -void DocumentObjectExtension::onExtendedSettingDocument() { +void DocumentObjectExtension::onExtendedSettingDocument() +{} -} +void DocumentObjectExtension::onExtendedDocumentRestored() +{} -void DocumentObjectExtension::onExtendedDocumentRestored() { +void DocumentObjectExtension::onExtendedSetupObject() +{} -} +void DocumentObjectExtension::onExtendedUnsetupObject() +{} -void DocumentObjectExtension::onExtendedSetupObject() { +PyObject* DocumentObjectExtension::getExtensionPyObject() +{ -} - -void DocumentObjectExtension::onExtendedUnsetupObject() { - -} - -PyObject* DocumentObjectExtension::getExtensionPyObject() { - - if (ExtensionPythonObject.is(Py::_None())){ + if (ExtensionPythonObject.is(Py::_None())) { // ref counter is set to 1 - ExtensionPythonObject = Py::Object(new DocumentObjectExtensionPy(this),true); + ExtensionPythonObject = Py::Object(new DocumentObjectExtensionPy(this), true); } return Py::new_reference_to(ExtensionPythonObject); } -const DocumentObject* DocumentObjectExtension::getExtendedObject() const { +const DocumentObject* DocumentObjectExtension::getExtendedObject() const +{ assert(getExtendedContainer()->isDerivedFrom(DocumentObject::getClassTypeId())); return static_cast(getExtendedContainer()); } -DocumentObject* DocumentObjectExtension::getExtendedObject() { +DocumentObject* DocumentObjectExtension::getExtendedObject() +{ assert(getExtendedContainer()->isDerivedFrom(DocumentObject::getClassTypeId())); return static_cast(getExtendedContainer()); } -bool DocumentObjectExtension::extensionGetSubObject(DocumentObject *&, - const char *, PyObject **, Base::Matrix4D *, bool, int) const +bool DocumentObjectExtension::extensionGetSubObject(DocumentObject*&, + const char*, + PyObject**, + Base::Matrix4D*, + bool, + int) const { return false; } @@ -97,8 +102,11 @@ bool DocumentObjectExtension::extensionGetSubObjects(std::vector&, return false; } -bool DocumentObjectExtension::extensionGetLinkedObject( - DocumentObject *&, bool, Base::Matrix4D *, bool, int) const +bool DocumentObjectExtension::extensionGetLinkedObject(DocumentObject*&, + bool, + Base::Matrix4D*, + bool, + int) const { return false; } diff --git a/src/App/DocumentObjectExtension.h b/src/App/DocumentObjectExtension.h index a27b6f680d..71021cd963 100644 --- a/src/App/DocumentObjectExtension.h +++ b/src/App/DocumentObjectExtension.h @@ -26,10 +26,12 @@ #include "Extension.h" -namespace Base { +namespace Base +{ class Matrix4D; } -namespace App { +namespace App +{ class DocumentObject; class DocumentObjectExecReturn; @@ -37,24 +39,23 @@ class DocumentObjectExecReturn; * @brief Extension with special document object calls * */ -class AppExport DocumentObjectExtension : public App::Extension +class AppExport DocumentObjectExtension: public App::Extension { - //The cass does not have properties itself, but it is important to provide the property access - //functions. see cpp file for details + // The cass does not have properties itself, but it is important to provide the property access + // functions. see cpp file for details EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::DocumentObjectExtension); public: + DocumentObjectExtension(); + ~DocumentObjectExtension() override; - DocumentObjectExtension (); - ~DocumentObjectExtension () override; - - App::DocumentObject* getExtendedObject(); + App::DocumentObject* getExtendedObject(); const App::DocumentObject* getExtendedObject() const; - //override if execution is necessary + // override if execution is necessary virtual short extensionMustExecute(); - virtual App::DocumentObjectExecReturn *extensionExecute(); + virtual App::DocumentObjectExecReturn* extensionExecute(); /// get called after setting the document @@ -70,36 +71,55 @@ public: /// returns the type name of the ViewProviderExtension which is automatically attached /// to the viewprovider object when it is initiated - virtual const char* getViewProviderExtensionName() const {return "";} + virtual const char* getViewProviderExtensionName() const + { + return ""; + } /** Get the sub object by name * @sa DocumentObject::getSubObject() * * @return Return turn if handled, the sub object is returned in \c ret */ - virtual bool extensionGetSubObject(DocumentObject *&ret, const char *subname, - PyObject **pyObj, Base::Matrix4D *mat, bool transform, int depth) const; + virtual bool extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject** pyObj, + Base::Matrix4D* mat, + bool transform, + int depth) const; /** Get name references of all sub objects * @sa DocumentObject::getSubObjects() * * @return Return turn if handled, the sub object is returned in \c ret */ - virtual bool extensionGetSubObjects(std::vector &ret, int reason) const; + virtual bool extensionGetSubObjects(std::vector& ret, int reason) const; /** Get the linked object * @sa DocumentObject::getLinkedObject() * * @return Return turn if handled, the linked object is returned in \c ret */ - virtual bool extensionGetLinkedObject(DocumentObject *&ret, bool recursive, - Base::Matrix4D *mat, bool transform, int depth) const; + virtual bool extensionGetLinkedObject(DocumentObject*& ret, + bool recursive, + Base::Matrix4D* mat, + bool transform, + int depth) const; - virtual int extensionSetElementVisible(const char *, bool) {return -1;} - virtual int extensionIsElementVisible(const char *) {return -1;} - virtual bool extensionHasChildElement() const {return false;} + virtual int extensionSetElementVisible(const char*, bool) + { + return -1; + } + virtual int extensionIsElementVisible(const char*) + { + return -1; + } + virtual bool extensionHasChildElement() const + { + return false; + } }; -} //App +} // namespace App -#endif // APP_DOCUMENTOBJECTEXTENSION_H +#endif // APP_DOCUMENTOBJECTEXTENSION_H diff --git a/src/App/DocumentObjectExtensionPy.xml b/src/App/DocumentObjectExtensionPy.xml index 858ebc5fc4..214539b255 100644 --- a/src/App/DocumentObjectExtensionPy.xml +++ b/src/App/DocumentObjectExtensionPy.xml @@ -1,13 +1,13 @@  - diff --git a/src/App/DocumentObjectExtensionPyImp.cpp b/src/App/DocumentObjectExtensionPyImp.cpp index a80f1a1603..16f7ac36b5 100644 --- a/src/App/DocumentObjectExtensionPyImp.cpp +++ b/src/App/DocumentObjectExtensionPyImp.cpp @@ -35,12 +35,12 @@ std::string DocumentObjectExtensionPy::representation() const return {""}; } -PyObject *DocumentObjectExtensionPy::getCustomAttributes(const char* /*attr*/) const +PyObject* DocumentObjectExtensionPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } -int DocumentObjectExtensionPy::setCustomAttributes(const char* /*attr*/, PyObject * /*obj*/) +int DocumentObjectExtensionPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { return 0; } diff --git a/src/App/DocumentObjectFileIncluded.cpp b/src/App/DocumentObjectFileIncluded.cpp index e3bbafe4ae..9f10aacd62 100644 --- a/src/App/DocumentObjectFileIncluded.cpp +++ b/src/App/DocumentObjectFileIncluded.cpp @@ -32,8 +32,11 @@ PROPERTY_SOURCE(App::DocumentObjectFileIncluded, App::DocumentObject) DocumentObjectFileIncluded::DocumentObjectFileIncluded() { - ADD_PROPERTY_TYPE(File,(nullptr),"",(App::PropertyType)(Prop_None),"File to include into Project File"); + ADD_PROPERTY_TYPE(File, + (nullptr), + "", + (App::PropertyType)(Prop_None), + "File to include into Project File"); } DocumentObjectFileIncluded::~DocumentObjectFileIncluded() = default; - diff --git a/src/App/DocumentObjectFileIncluded.h b/src/App/DocumentObjectFileIncluded.h index eb338fedea..55711be609 100644 --- a/src/App/DocumentObjectFileIncluded.h +++ b/src/App/DocumentObjectFileIncluded.h @@ -31,7 +31,7 @@ namespace App { -class AppExport DocumentObjectFileIncluded : public DocumentObject +class AppExport DocumentObjectFileIncluded: public DocumentObject { PROPERTY_HEADER_WITH_OVERRIDE(App::DocumentObjectFileIncluded); @@ -42,16 +42,16 @@ public: /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderDocumentObject"; } /// Properties PropertyFileIncluded File; - }; -} //namespace App +} // namespace App -#endif // APP_DOCUMENTOBJECTFILEINCLUDED_H +#endif // APP_DOCUMENTOBJECTFILEINCLUDED_H diff --git a/src/App/DocumentObjectGroup.cpp b/src/App/DocumentObjectGroup.cpp index c4fdd690f2..167d6de627 100644 --- a/src/App/DocumentObjectGroup.cpp +++ b/src/App/DocumentObjectGroup.cpp @@ -31,19 +31,22 @@ using namespace App; PROPERTY_SOURCE_WITH_EXTENSIONS(App::DocumentObjectGroup, App::DocumentObject) -DocumentObjectGroup::DocumentObjectGroup(): DocumentObject(), GroupExtension() { +DocumentObjectGroup::DocumentObjectGroup() + : DocumentObject() + , GroupExtension() +{ GroupExtension::initExtension(this); - _GroupTouched.setStatus(App::Property::Output,true); + _GroupTouched.setStatus(App::Property::Output, true); } DocumentObjectGroup::~DocumentObjectGroup() = default; -PyObject *DocumentObjectGroup::getPyObject() +PyObject* DocumentObjectGroup::getPyObject() { - if (PythonObject.is(Py::_None())){ + if (PythonObject.is(Py::_None())) { // ref counter is set to 1 - PythonObject = Py::Object(new DocumentObjectGroupPy(this),true); + PythonObject = Py::Object(new DocumentObjectGroupPy(this), true); } return Py::new_reference_to(PythonObject); } @@ -51,17 +54,22 @@ PyObject *DocumentObjectGroup::getPyObject() // Python feature --------------------------------------------------------- -namespace App { +namespace App +{ /// @cond DOXERR PROPERTY_SOURCE_TEMPLATE(App::DocumentObjectGroupPython, App::DocumentObjectGroup) -template<> const char* App::DocumentObjectGroupPython::getViewProviderName() const { +template<> +const char* App::DocumentObjectGroupPython::getViewProviderName() const +{ return "Gui::ViewProviderDocumentObjectGroupPython"; } -template<> PyObject* App::DocumentObjectGroupPython::getPyObject() { +template<> +PyObject* App::DocumentObjectGroupPython::getPyObject() +{ if (PythonObject.is(Py::_None())) { // ref counter is set to 1 - PythonObject = Py::Object(new FeaturePythonPyT(this),true); + PythonObject = Py::Object(new FeaturePythonPyT(this), true); } return Py::new_reference_to(PythonObject); } @@ -69,4 +77,4 @@ template<> PyObject* App::DocumentObjectGroupPython::getPyObject() { // explicit template instantiation template class AppExport FeaturePythonT; -} +} // namespace App diff --git a/src/App/DocumentObjectGroup.h b/src/App/DocumentObjectGroup.h index 2e88e7e946..0f0e6ff550 100644 --- a/src/App/DocumentObjectGroup.h +++ b/src/App/DocumentObjectGroup.h @@ -32,7 +32,8 @@ namespace App { -class AppExport DocumentObjectGroup : public DocumentObject, public GroupExtension { +class AppExport DocumentObjectGroup: public DocumentObject, public GroupExtension +{ PROPERTY_HEADER_WITH_EXTENSIONS(App::DocumentObjectGroup); @@ -42,17 +43,18 @@ public: ~DocumentObjectGroup() override; /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderDocumentObjectGroup"; } - PyObject *getPyObject() override; + PyObject* getPyObject() override; }; using DocumentObjectGroupPython = App::FeaturePythonT; -} //namespace App +} // namespace App -#endif // APP_DOCUMENTOBJECTGROUP_H +#endif // APP_DOCUMENTOBJECTGROUP_H diff --git a/src/App/DocumentObjectGroupPy.xml b/src/App/DocumentObjectGroupPy.xml index 07b37a5caf..c548fe03c5 100644 --- a/src/App/DocumentObjectGroupPy.xml +++ b/src/App/DocumentObjectGroupPy.xml @@ -1,13 +1,13 @@ - diff --git a/src/App/DocumentObjectGroupPyImp.cpp b/src/App/DocumentObjectGroupPyImp.cpp index 4b4c36565f..9c32502c6e 100644 --- a/src/App/DocumentObjectGroupPyImp.cpp +++ b/src/App/DocumentObjectGroupPyImp.cpp @@ -37,7 +37,7 @@ std::string DocumentObjectGroupPy::representation() const return {""}; } -PyObject *DocumentObjectGroupPy::getCustomAttributes(const char* /*attr*/) const +PyObject* DocumentObjectGroupPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } @@ -46,4 +46,3 @@ int DocumentObjectGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* / { return 0; } - diff --git a/src/App/DocumentObjectPy.xml b/src/App/DocumentObjectPy.xml index 463c013edf..cb93c974db 100644 --- a/src/App/DocumentObjectPy.xml +++ b/src/App/DocumentObjectPy.xml @@ -1,13 +1,13 @@ - @@ -95,7 +95,7 @@ referencing subobject. PyObject: return a python binding object for the (sub)object referenced in each 'subname' The actual type of 'PyObject' is implementation dependent. For Part::Feature compatible objects, this will be of type TopoShapePy and - pre-transformed by accumulated transformation matrix along the object path. + pre-transformed by accumulated transformation matrix along the object path. DocObject: return the document object referenced in subname, if 'matrix' is None. Or, return a tuple (object, matrix) for each 'subname' and 'matrix' is @@ -168,15 +168,15 @@ Return -1 if element visibility is not supported or element not found, 0 if invi - Returns the group the object is in or None if it is not part of a group. - Note that an object can only be in a single group, hence only a single return + Returns the group the object is in or None if it is not part of a group. + Note that an object can only be in a single group, hence only a single return value. - Returns the GeoFeatureGroup, and hence the local coordinate system, the object - is in or None if it is not part of a group. Note that an object can only be + Returns the GeoFeatureGroup, and hence the local coordinate system, the object + is in or None if it is not part of a group. Note that an object can only be in a single group, hence only a single return value. diff --git a/src/App/DocumentObjectPyImp.cpp b/src/App/DocumentObjectPyImp.cpp index af09d7d998..c6e2e32b20 100644 --- a/src/App/DocumentObjectPyImp.cpp +++ b/src/App/DocumentObjectPyImp.cpp @@ -76,7 +76,7 @@ Py::Object DocumentObjectPy::getDocument() const } } -PyObject* DocumentObjectPy::isAttachedToDocument(PyObject *args) +PyObject* DocumentObjectPy::isAttachedToDocument(PyObject* args) { if (!PyArg_ParseTuple(args, "")) { return nullptr; @@ -87,27 +87,52 @@ PyObject* DocumentObjectPy::isAttachedToDocument(PyObject *args) return Py::new_reference_to(Py::Boolean(ok)); } -PyObject* DocumentObjectPy::addProperty(PyObject *args, PyObject *kwd) +PyObject* DocumentObjectPy::addProperty(PyObject* args, PyObject* kwd) { - char *sType,*sName=nullptr,*sGroup=nullptr,*sDoc=nullptr; - short attr=0; + char *sType, *sName = nullptr, *sGroup = nullptr, *sDoc = nullptr; + short attr = 0; std::string sDocStr; PyObject *ro = Py_False, *hd = Py_False; PyObject* enumVals = nullptr; - const std::array kwlist {"type","name","group","doc","attr","read_only","hidden","enum_vals",nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords( - args, kwd, "ss|sethO!O!O", kwlist, &sType, &sName, &sGroup, "utf-8", - &sDoc, &attr, &PyBool_Type, &ro, &PyBool_Type, &hd, &enumVals)) + const std::array kwlist {"type", + "name", + "group", + "doc", + "attr", + "read_only", + "hidden", + "enum_vals", + nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + kwd, + "ss|sethO!O!O", + kwlist, + &sType, + &sName, + &sGroup, + "utf-8", + &sDoc, + &attr, + &PyBool_Type, + &ro, + &PyBool_Type, + &hd, + &enumVals)) { return nullptr; + } if (sDoc) { sDocStr = sDoc; PyMem_Free(sDoc); } - Property *prop = getDocumentObjectPtr()-> - addDynamicProperty(sType,sName,sGroup,sDocStr.c_str(),attr, - Base::asBoolean(ro), Base::asBoolean(hd)); + Property* prop = getDocumentObjectPtr()->addDynamicProperty(sType, + sName, + sGroup, + sDocStr.c_str(), + attr, + Base::asBoolean(ro), + Base::asBoolean(hd)); // enum support auto* propEnum = dynamic_cast(prop); @@ -118,26 +143,28 @@ PyObject* DocumentObjectPy::addProperty(PyObject *args, PyObject *kwd) return Py::new_reference_to(this); } -PyObject* DocumentObjectPy::removeProperty(PyObject *args) +PyObject* DocumentObjectPy::removeProperty(PyObject* args) { - char *sName; - if (!PyArg_ParseTuple(args, "s", &sName)) + char* sName; + if (!PyArg_ParseTuple(args, "s", &sName)) { return nullptr; + } bool ok = getDocumentObjectPtr()->removeDynamicProperty(sName); return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* DocumentObjectPy::supportedProperties(PyObject *args) +PyObject* DocumentObjectPy::supportedProperties(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } std::vector ary; Base::Type::getAllDerivedFrom(App::Property::getClassTypeId(), ary); Py::List res; - for (auto & it : ary) { - Base::BaseClass *data = static_cast(it.createInstance()); + for (auto& it : ary) { + Base::BaseClass* data = static_cast(it.createInstance()); if (data) { delete data; res.append(Py::String(it.getName())); @@ -146,19 +173,21 @@ PyObject* DocumentObjectPy::supportedProperties(PyObject *args) return Py::new_reference_to(res); } -PyObject* DocumentObjectPy::touch(PyObject * args) +PyObject* DocumentObjectPy::touch(PyObject* args) { - char *propName = nullptr; - if (!PyArg_ParseTuple(args, "|s",&propName)) + char* propName = nullptr; + if (!PyArg_ParseTuple(args, "|s", &propName)) { return nullptr; - if(propName) { - if(!propName[0]) { + } + if (propName) { + if (!propName[0]) { getDocumentObjectPtr()->touch(true); Py_Return; } auto prop = getDocumentObjectPtr()->getPropertyByName(propName); - if(!prop) + if (!prop) { throw Py::RuntimeError("Property not found"); + } prop->touch(); Py_Return; } @@ -167,18 +196,20 @@ PyObject* DocumentObjectPy::touch(PyObject * args) Py_Return; } -PyObject* DocumentObjectPy::purgeTouched(PyObject * args) +PyObject* DocumentObjectPy::purgeTouched(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getDocumentObjectPtr()->purgeTouched(); Py_Return; } -PyObject* DocumentObjectPy::enforceRecompute(PyObject * args) +PyObject* DocumentObjectPy::enforceRecompute(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getDocumentObjectPtr()->enforceRecompute(); Py_Return; } @@ -207,13 +238,13 @@ Py::List DocumentObjectPy::getState() const uptodate = false; list.append(Py::String("Restore")); } - if (object->testStatus(App::Expand)){ + if (object->testStatus(App::Expand)) { list.append(Py::String("Expanded")); } - if (object->testStatus(App::PartialObject)){ + if (object->testStatus(App::PartialObject)) { list.append(Py::String("Partial")); } - if (object->testStatus(App::ObjImporting)){ + if (object->testStatus(App::ObjImporting)) { list.append(Py::String("Importing")); } if (uptodate) { @@ -225,7 +256,7 @@ Py::List DocumentObjectPy::getState() const Py::Object DocumentObjectPy::getViewObject() const { try { - PyObject *dict = PySys_GetObject("modules"); + PyObject* dict = PySys_GetObject("modules"); if (!dict) { return Py::None(); } @@ -237,12 +268,13 @@ Py::Object DocumentObjectPy::getViewObject() const } // double-check that the module doesn't have a null pointer - Py::Module module(PyImport_ImportModule("FreeCADGui"),true); + Py::Module module(PyImport_ImportModule("FreeCADGui"), true); if (module.isNull() || !module.hasAttr("getDocument")) { - // in v0.14+, the GUI module can be loaded in console mode (but doesn't have all its document methods) + // in v0.14+, the GUI module can be loaded in console mode (but doesn't have all its + // document methods) return Py::None(); } - if(!getDocumentObjectPtr()->getDocument()) { + if (!getDocumentObjectPtr()->getDocument()) { throw Py::RuntimeError("Object has no document"); } const char* internalName = getDocumentObjectPtr()->getNameInDocument(); @@ -266,7 +298,7 @@ Py::Object DocumentObjectPy::getViewObject() const return Py::None(); } // FreeCADGui is loaded, so there must be wrong something else - throw; // re-throw + throw; // re-throw } } @@ -275,8 +307,9 @@ Py::List DocumentObjectPy::getInList() const Py::List ret; std::vector list = getDocumentObjectPtr()->getInList(); - for (auto It : list) + for (auto It : list) { ret.append(Py::Object(It->getPyObject(), true)); + } return ret; } @@ -287,8 +320,9 @@ Py::List DocumentObjectPy::getInListRecursive() const try { std::vector list = getDocumentObjectPtr()->getInListRecursive(); - for (auto It : list) + for (auto It : list) { ret.append(Py::Object(It->getPyObject(), true)); + } } catch (const Base::Exception& e) { throw Py::IndexError(e.what()); @@ -301,8 +335,9 @@ Py::List DocumentObjectPy::getOutList() const Py::List ret; std::vector list = getDocumentObjectPtr()->getOutList(); - for (auto It : list) + for (auto It : list) { ret.append(Py::Object(It->getPyObject(), true)); + } return ret; } @@ -314,8 +349,9 @@ Py::List DocumentObjectPy::getOutListRecursive() const std::vector list = getDocumentObjectPtr()->getOutListRecursive(); // create the python list for the output - for (auto It : list) + for (auto It : list) { ret.append(Py::Object(It->getPyObject(), true)); + } } catch (const Base::Exception& e) { throw Py::IndexError(e.what()); @@ -324,14 +360,15 @@ Py::List DocumentObjectPy::getOutListRecursive() const return ret; } -PyObject* DocumentObjectPy::setExpression(PyObject * args) +PyObject* DocumentObjectPy::setExpression(PyObject* args) { - char * path = nullptr; - PyObject * expr; - char * comment = nullptr; + char* path = nullptr; + PyObject* expr; + char* comment = nullptr; - if (!PyArg_ParseTuple(args, "sO|s", &path, &expr, &comment)) + if (!PyArg_ParseTuple(args, "sO|s", &path, &expr, &comment)) { return nullptr; + } App::ObjectIdentifier p(ObjectIdentifier::parse(getDocumentObjectPtr(), path)); @@ -340,10 +377,11 @@ PyObject* DocumentObjectPy::setExpression(PyObject * args) Py_Return; } else if (PyUnicode_Check(expr)) { - const char * exprStr = PyUnicode_AsUTF8(expr); + const char* exprStr = PyUnicode_AsUTF8(expr); std::shared_ptr shared_expr(Expression::parse(getDocumentObjectPtr(), exprStr)); - if (shared_expr && comment) + if (shared_expr && comment) { shared_expr->comment = comment; + } getDocumentObjectPtr()->setExpression(p, shared_expr); Py_Return; @@ -352,22 +390,24 @@ PyObject* DocumentObjectPy::setExpression(PyObject * args) throw Py::TypeError("String or None expected."); } -PyObject* DocumentObjectPy::clearExpression(PyObject * args) +PyObject* DocumentObjectPy::clearExpression(PyObject* args) { - char * path = nullptr; - if (!PyArg_ParseTuple(args, "s", &path)) + char* path = nullptr; + if (!PyArg_ParseTuple(args, "s", &path)) { return nullptr; + } App::ObjectIdentifier p(ObjectIdentifier::parse(getDocumentObjectPtr(), path)); getDocumentObjectPtr()->clearExpression(p); Py_Return; } -PyObject* DocumentObjectPy::evalExpression(PyObject *self, PyObject * args) +PyObject* DocumentObjectPy::evalExpression(PyObject* self, PyObject* args) { - const char *expr; - if (!PyArg_ParseTuple(args, "s", &expr)) + const char* expr; + if (!PyArg_ParseTuple(args, "s", &expr)) { return nullptr; + } // HINT: // The standard behaviour of Python for class methods is to always pass the class @@ -385,19 +425,23 @@ PyObject* DocumentObjectPy::evalExpression(PyObject *self, PyObject * args) obj = static_cast(self)->getDocumentObjectPtr(); } - PY_TRY { + PY_TRY + { std::shared_ptr shared_expr(Expression::parse(obj, expr)); - if (shared_expr) + if (shared_expr) { return Py::new_reference_to(shared_expr->getPyValue()); + } Py_Return; - } PY_CATCH + } + PY_CATCH } -PyObject* DocumentObjectPy::recompute(PyObject *args) +PyObject* DocumentObjectPy::recompute(PyObject* args) { - PyObject *recursive = Py_False; - if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &recursive)) + PyObject* recursive = Py_False; + if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &recursive)) { return nullptr; + } try { bool ok = getDocumentObjectPtr()->recomputeFeature(Base::asBoolean(recursive)); @@ -408,10 +452,11 @@ PyObject* DocumentObjectPy::recompute(PyObject *args) } } -PyObject* DocumentObjectPy::isValid(PyObject *args) +PyObject* DocumentObjectPy::isValid(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { bool ok = getDocumentObjectPtr()->isValid(); @@ -422,10 +467,11 @@ PyObject* DocumentObjectPy::isValid(PyObject *args) } } -PyObject* DocumentObjectPy::getStatusString(PyObject *args) +PyObject* DocumentObjectPy::getStatusString(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { Py::String text(getDocumentObjectPtr()->getStatusString()); @@ -436,9 +482,10 @@ PyObject* DocumentObjectPy::getStatusString(PyObject *args) } } -PyObject* DocumentObjectPy::getSubObject(PyObject *args, PyObject *keywds) +PyObject* DocumentObjectPy::getSubObject(PyObject* args, PyObject* keywds) { - enum class ReturnType { + enum class ReturnType + { PyObject = 0, DocObject = 1, DocAndPyObject = 2, @@ -448,19 +495,33 @@ PyObject* DocumentObjectPy::getSubObject(PyObject *args, PyObject *keywds) LinkAndMatrix = 6 }; - PyObject *obj; + PyObject* obj; short retType = 0; - PyObject *pyMat = nullptr; - PyObject *doTransform = Py_True; + PyObject* pyMat = nullptr; + PyObject* doTransform = Py_True; short depth = 0; - static const std::array kwlist {"subname", "retType", "matrix", "transform", "depth", nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords(args, keywds, "O|hO!O!h", kwlist, &obj, &retType, &Base::MatrixPy::Type, - &pyMat, &PyBool_Type, &doTransform, &depth)) { + static const std::array kwlist {"subname", + "retType", + "matrix", + "transform", + "depth", + nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + keywds, + "O|hO!O!h", + kwlist, + &obj, + &retType, + &Base::MatrixPy::Type, + &pyMat, + &PyBool_Type, + &doTransform, + &depth)) { return nullptr; } - if (retType < 0 || static_cast (retType) > kwlist.size()) { + if (retType < 0 || static_cast(retType) > kwlist.size()) { PyErr_SetString(PyExc_ValueError, "invalid retType, can only be integer 0~6"); return nullptr; } @@ -493,12 +554,15 @@ PyObject* DocumentObjectPy::getSubObject(PyObject *args, PyObject *keywds) bool transform = Base::asBoolean(doTransform); - struct SubInfo { - App::DocumentObject *sobj{nullptr}; + struct SubInfo + { + App::DocumentObject* sobj {nullptr}; Py::Object obj; Py::Object pyObj; Base::Matrix4D mat; - explicit SubInfo(const Base::Matrix4D &mat) : mat(mat){} + explicit SubInfo(const Base::Matrix4D& mat) + : mat(mat) + {} }; Base::Matrix4D mat; @@ -506,50 +570,66 @@ PyObject* DocumentObjectPy::getSubObject(PyObject *args, PyObject *keywds) mat = *static_cast(pyMat)->getMatrixPtr(); } - PY_TRY { + PY_TRY + { std::vector ret; - for(const auto &sub : subs) { + for (const auto& sub : subs) { ret.emplace_back(mat); - auto &info = ret.back(); - PyObject *pyObj = nullptr; + auto& info = ret.back(); + PyObject* pyObj = nullptr; - info.sobj = getDocumentObjectPtr()->getSubObject(sub.c_str(), - retEnum != ReturnType::PyObject && - retEnum != ReturnType::DocAndPyObject ? nullptr : &pyObj, - &info.mat, transform, depth); - if (pyObj) + info.sobj = getDocumentObjectPtr()->getSubObject( + sub.c_str(), + retEnum != ReturnType::PyObject && retEnum != ReturnType::DocAndPyObject ? nullptr + : &pyObj, + &info.mat, + transform, + depth); + if (pyObj) { info.pyObj = Py::asObject(pyObj); - if (info.sobj) + } + if (info.sobj) { info.obj = Py::asObject(info.sobj->getPyObject()); + } } - if (ret.empty()) + if (ret.empty()) { Py_Return; + } auto getReturnValue = [retEnum, pyMat](SubInfo& ret) -> Py::Object { - if (retEnum == ReturnType::PyObject) + if (retEnum == ReturnType::PyObject) { return ret.pyObj; - else if (retEnum == ReturnType::DocObject && !pyMat) + } + else if (retEnum == ReturnType::DocObject && !pyMat) { return ret.obj; - else if (!ret.sobj) + } + else if (!ret.sobj) { return Py::None(); - else if (retEnum == ReturnType::Placement) + } + else if (retEnum == ReturnType::Placement) { return Py::Placement(Base::Placement(ret.mat)); - else if (retEnum == ReturnType::Matrix) + } + else if (retEnum == ReturnType::Matrix) { return Py::Matrix(ret.mat); - else if (retEnum == ReturnType::LinkAndPlacement || retEnum == ReturnType::LinkAndMatrix) { + } + else if (retEnum == ReturnType::LinkAndPlacement + || retEnum == ReturnType::LinkAndMatrix) { ret.sobj->getLinkedObject(true, &ret.mat, false); - if (retEnum == ReturnType::LinkAndPlacement) + if (retEnum == ReturnType::LinkAndPlacement) { return Py::Placement(Base::Placement(ret.mat)); - else + } + else { return Py::Matrix(ret.mat); + } } else { Py::Tuple rret(retEnum == ReturnType::DocObject ? 2 : 3); rret.setItem(0, ret.obj); rret.setItem(1, Py::asObject(new Base::MatrixPy(ret.mat))); - if (retEnum != ReturnType::DocObject) + if (retEnum != ReturnType::DocObject) { rret.setItem(2, ret.pyObj); + } return rret; } }; @@ -559,7 +639,7 @@ PyObject* DocumentObjectPy::getSubObject(PyObject *args, PyObject *keywds) } Py::Tuple tuple(ret.size()); - for(size_t i=0; igetSubObjectList(subname)) - res.append(Py::asObject(o->getPyObject())); - return Py::new_reference_to(res); - }PY_CATCH -} - -PyObject* DocumentObjectPy::getSubObjects(PyObject *args) { - int reason = 0; - if (!PyArg_ParseTuple(args, "|i", &reason)) - return nullptr; - - PY_TRY { - auto names = getDocumentObjectPtr()->getSubObjects(reason); - Py::Tuple pyObjs(names.size()); - for(size_t i=0;i kwlist {"recursive","matrix","transform","depth", nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords(args, keywds, "|O!OO!h", kwlist, - &PyBool_Type, &recursive, &pyMat, &PyBool_Type, &transform, &depth)) { + const char* subname; + if (!PyArg_ParseTuple(args, "s", &subname)) { + return nullptr; + } + Py::List res; + PY_TRY + { + for (auto o : getDocumentObjectPtr()->getSubObjectList(subname)) { + res.append(Py::asObject(o->getPyObject())); + } + return Py::new_reference_to(res); + } + PY_CATCH +} + +PyObject* DocumentObjectPy::getSubObjects(PyObject* args) +{ + int reason = 0; + if (!PyArg_ParseTuple(args, "|i", &reason)) { return nullptr; } - PY_TRY { - Base::PyTypeCheck(&pyMat, &Base::MatrixPy::Type, "expect argument 'matrix' to be of type Base.Matrix"); + PY_TRY + { + auto names = getDocumentObjectPtr()->getSubObjects(reason); + Py::Tuple pyObjs(names.size()); + for (size_t i = 0; i < names.size(); ++i) { + pyObjs.setItem(i, Py::String(names[i])); + } + return Py::new_reference_to(pyObjs); + } + PY_CATCH; +} + +PyObject* DocumentObjectPy::getLinkedObject(PyObject* args, PyObject* keywds) +{ + PyObject* recursive = Py_True; + PyObject* pyMat = Py_None; + PyObject* transform = Py_True; + short depth = 0; + static const std::array kwlist {"recursive", + "matrix", + "transform", + "depth", + nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + keywds, + "|O!OO!h", + kwlist, + &PyBool_Type, + &recursive, + &pyMat, + &PyBool_Type, + &transform, + &depth)) { + return nullptr; + } + + PY_TRY + { + Base::PyTypeCheck(&pyMat, + &Base::MatrixPy::Type, + "expect argument 'matrix' to be of type Base.Matrix"); Base::Matrix4D _mat; - Base::Matrix4D *mat = nullptr; + Base::Matrix4D* mat = nullptr; if (pyMat) { _mat = *static_cast(pyMat)->getMatrixPtr(); mat = &_mat; } - auto linked = getDocumentObjectPtr()->getLinkedObject( - Base::asBoolean(recursive), mat, Base::asBoolean(transform), depth); - if (!linked) + auto linked = getDocumentObjectPtr()->getLinkedObject(Base::asBoolean(recursive), + mat, + Base::asBoolean(transform), + depth); + if (!linked) { linked = getDocumentObjectPtr(); - auto pyObj = Py::Object(linked->getPyObject(),true); + } + auto pyObj = Py::Object(linked->getPyObject(), true); if (mat) { Py::Tuple ret(2); - ret.setItem(0,pyObj); - ret.setItem(1,Py::asObject(new Base::MatrixPy(*mat))); + ret.setItem(0, pyObj); + ret.setItem(1, Py::asObject(new Base::MatrixPy(*mat))); return Py::new_reference_to(ret); } @@ -631,44 +739,56 @@ PyObject* DocumentObjectPy::getLinkedObject(PyObject *args, PyObject *keywds) PY_CATCH; } -PyObject* DocumentObjectPy::isElementVisible(PyObject *args) +PyObject* DocumentObjectPy::isElementVisible(PyObject* args) { - char *element = nullptr; - if (!PyArg_ParseTuple(args, "s", &element)) + char* element = nullptr; + if (!PyArg_ParseTuple(args, "s", &element)) { return nullptr; - PY_TRY { + } + PY_TRY + { return Py_BuildValue("h", getDocumentObjectPtr()->isElementVisible(element)); - } PY_CATCH; + } + PY_CATCH; } -PyObject* DocumentObjectPy::setElementVisible(PyObject *args) +PyObject* DocumentObjectPy::setElementVisible(PyObject* args) { - char *element = nullptr; - PyObject *visible = Py_True; - if (!PyArg_ParseTuple(args, "s|O!", &element, &PyBool_Type, &visible)) + char* element = nullptr; + PyObject* visible = Py_True; + if (!PyArg_ParseTuple(args, "s|O!", &element, &PyBool_Type, &visible)) { return nullptr; - PY_TRY { - return Py_BuildValue("h", getDocumentObjectPtr()->setElementVisible(element, Base::asBoolean(visible))); - } PY_CATCH; + } + PY_TRY + { + return Py_BuildValue( + "h", + getDocumentObjectPtr()->setElementVisible(element, Base::asBoolean(visible))); + } + PY_CATCH; } -PyObject* DocumentObjectPy::hasChildElement(PyObject *args) +PyObject* DocumentObjectPy::hasChildElement(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; - PY_TRY { - return Py_BuildValue("O", getDocumentObjectPtr()->hasChildElement()?Py_True:Py_False); - } PY_CATCH; + } + PY_TRY + { + return Py_BuildValue("O", getDocumentObjectPtr()->hasChildElement() ? Py_True : Py_False); + } + PY_CATCH; } -PyObject* DocumentObjectPy::getParentGroup(PyObject *args) +PyObject* DocumentObjectPy::getParentGroup(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { auto grp = GroupExtension::getGroupOfObject(getDocumentObjectPtr()); - if(!grp) { + if (!grp) { Py_INCREF(Py_None); return Py_None; } @@ -679,14 +799,15 @@ PyObject* DocumentObjectPy::getParentGroup(PyObject *args) } } -PyObject* DocumentObjectPy::getParentGeoFeatureGroup(PyObject *args) +PyObject* DocumentObjectPy::getParentGeoFeatureGroup(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { auto grp = GeoFeatureGroupExtension::getGroupOfObject(getDocumentObjectPtr()); - if(!grp) { + if (!grp) { Py_INCREF(Py_None); return Py_None; } @@ -697,14 +818,15 @@ PyObject* DocumentObjectPy::getParentGeoFeatureGroup(PyObject *args) } } -PyObject* DocumentObjectPy::getParent(PyObject *args) +PyObject* DocumentObjectPy::getParent(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { auto grp = getDocumentObjectPtr()->getFirstParent(); - if(!grp) { + if (!grp) { Py_INCREF(Py_None); return Py_None; } @@ -725,15 +847,15 @@ Py::Boolean DocumentObjectPy::getMustExecute() const } } -PyObject* DocumentObjectPy::getPathsByOutList(PyObject *args) +PyObject* DocumentObjectPy::getPathsByOutList(PyObject* args) { PyObject* o; - if (!PyArg_ParseTuple(args, "O!", &DocumentObjectPy::Type, &o)) + if (!PyArg_ParseTuple(args, "O!", &DocumentObjectPy::Type, &o)) { return nullptr; + } try { - DocumentObject* target = static_cast - (o)->getDocumentObjectPtr(); + DocumentObject* target = static_cast(o)->getDocumentObjectPtr(); auto array = getDocumentObjectPtr()->getPathsByOutList(target); Py::List list; for (const auto& it : array) { @@ -766,100 +888,120 @@ PyObject* DocumentObjectPy::getElementMapVersion(PyObject* args) Py::String(getDocumentObjectPtr()->getElementMapVersion(prop, Base::asBoolean(restored)))); } -PyObject *DocumentObjectPy::getCustomAttributes(const char* ) const +PyObject* DocumentObjectPy::getCustomAttributes(const char*) const { - return nullptr; + return nullptr; } -//remove -int DocumentObjectPy::setCustomAttributes(const char* , PyObject *) +// remove +int DocumentObjectPy::setCustomAttributes(const char*, PyObject*) { return 0; } -Py::Int DocumentObjectPy::getID() const { +Py::Int DocumentObjectPy::getID() const +{ return Py::Int(getDocumentObjectPtr()->getID()); } -Py::Boolean DocumentObjectPy::getRemoving() const { +Py::Boolean DocumentObjectPy::getRemoving() const +{ return {getDocumentObjectPtr()->testStatus(ObjectStatus::Remove)}; } -PyObject *DocumentObjectPy::resolve(PyObject *args) +PyObject* DocumentObjectPy::resolve(PyObject* args) { - const char *subname; - if (!PyArg_ParseTuple(args, "s",&subname)) + const char* subname; + if (!PyArg_ParseTuple(args, "s", &subname)) { return nullptr; + } - PY_TRY { + PY_TRY + { std::string elementName; - const char *subElement = nullptr; - App::DocumentObject *parent = nullptr; - auto obj = getDocumentObjectPtr()->resolve(subname,&parent,&elementName,&subElement); + const char* subElement = nullptr; + App::DocumentObject* parent = nullptr; + auto obj = getDocumentObjectPtr()->resolve(subname, &parent, &elementName, &subElement); Py::Tuple ret(4); - ret.setItem(0,obj?Py::Object(obj->getPyObject(),true):Py::None()); - ret.setItem(1,parent?Py::Object(parent->getPyObject(),true):Py::None()); - ret.setItem(2,Py::String(elementName.c_str())); - ret.setItem(3,Py::String(subElement?subElement:"")); + ret.setItem(0, obj ? Py::Object(obj->getPyObject(), true) : Py::None()); + ret.setItem(1, parent ? Py::Object(parent->getPyObject(), true) : Py::None()); + ret.setItem(2, Py::String(elementName.c_str())); + ret.setItem(3, Py::String(subElement ? subElement : "")); return Py::new_reference_to(ret); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject *DocumentObjectPy::resolveSubElement(PyObject *args) +PyObject* DocumentObjectPy::resolveSubElement(PyObject* args) { - const char *subname; - PyObject *append = Py_False; + const char* subname; + PyObject* append = Py_False; int type = 0; - if (!PyArg_ParseTuple(args, "s|O!i",&subname,&PyBool_Type,&append,&type)) + if (!PyArg_ParseTuple(args, "s|O!i", &subname, &PyBool_Type, &append, &type)) { return nullptr; + } - PY_TRY { + PY_TRY + { ElementNamePair elementName; - auto obj = GeoFeature::resolveElement(getDocumentObjectPtr(), subname,elementName, - Base::asBoolean(append), static_cast(type)); + auto obj = GeoFeature::resolveElement(getDocumentObjectPtr(), + subname, + elementName, + Base::asBoolean(append), + static_cast(type)); Py::Tuple ret(3); - ret.setItem(0,obj?Py::Object(obj->getPyObject(),true):Py::None()); - ret.setItem(1,Py::String(elementName.newName)); - ret.setItem(2,Py::String(elementName.oldName)); + ret.setItem(0, obj ? Py::Object(obj->getPyObject(), true) : Py::None()); + ret.setItem(1, Py::String(elementName.newName)); + ret.setItem(2, Py::String(elementName.oldName)); return Py::new_reference_to(ret); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -Py::List DocumentObjectPy::getParents() const { +Py::List DocumentObjectPy::getParents() const +{ Py::List ret; - for(auto &v : getDocumentObjectPtr()->getParents()) - ret.append(Py::TupleN(Py::Object(v.first->getPyObject(),true),Py::String(v.second))); + for (auto& v : getDocumentObjectPtr()->getParents()) { + ret.append(Py::TupleN(Py::Object(v.first->getPyObject(), true), Py::String(v.second))); + } return ret; } -PyObject *DocumentObjectPy::adjustRelativeLinks(PyObject *args) { - PyObject *pyobj; - PyObject *recursive = Py_True; - if (!PyArg_ParseTuple(args, "O!|O",&DocumentObjectPy::Type,&pyobj,&recursive)) +PyObject* DocumentObjectPy::adjustRelativeLinks(PyObject* args) +{ + PyObject* pyobj; + PyObject* recursive = Py_True; + if (!PyArg_ParseTuple(args, "O!|O", &DocumentObjectPy::Type, &pyobj, &recursive)) { return nullptr; - PY_TRY { + } + PY_TRY + { auto obj = static_cast(pyobj)->getDocumentObjectPtr(); auto inList = obj->getInListEx(true); inList.insert(obj); - std::set visited; - return Py::new_reference_to(Py::Boolean( - getDocumentObjectPtr()->adjustRelativeLinks(inList, - Base::asBoolean(recursive) ? &visited : nullptr))); - }PY_CATCH + std::set visited; + return Py::new_reference_to(Py::Boolean(getDocumentObjectPtr()->adjustRelativeLinks( + inList, + Base::asBoolean(recursive) ? &visited : nullptr))); + } + PY_CATCH } -Py::String DocumentObjectPy::getOldLabel() const { +Py::String DocumentObjectPy::getOldLabel() const +{ return {getDocumentObjectPtr()->getOldLabel()}; } -Py::Boolean DocumentObjectPy::getNoTouch() const { +Py::Boolean DocumentObjectPy::getNoTouch() const +{ return {getDocumentObjectPtr()->testStatus(ObjectStatus::NoTouch)}; } -void DocumentObjectPy::setNoTouch(Py::Boolean value) { - getDocumentObjectPtr()->setStatus(ObjectStatus::NoTouch,value.isTrue()); +void DocumentObjectPy::setNoTouch(Py::Boolean value) +{ + getDocumentObjectPtr()->setStatus(ObjectStatus::NoTouch, value.isTrue()); } diff --git a/src/App/DocumentObserver.cpp b/src/App/DocumentObserver.cpp index 896f6c1f38..78b8574302 100644 --- a/src/App/DocumentObserver.cpp +++ b/src/App/DocumentObserver.cpp @@ -57,8 +57,9 @@ DocumentT::~DocumentT() = default; void DocumentT::operator=(const DocumentT& doc) { - if (this == &doc) + if (this == &doc) { return; + } document = doc.document; } @@ -77,7 +78,7 @@ Document* DocumentT::getDocument() const return GetApplication().getDocument(document.c_str()); } -const std::string &DocumentT::getDocumentName() const +const std::string& DocumentT::getDocumentName() const { return document; } @@ -93,12 +94,12 @@ std::string DocumentT::getDocumentPython() const DocumentObjectT::DocumentObjectT() = default; -DocumentObjectT::DocumentObjectT(const DocumentObjectT &other) +DocumentObjectT::DocumentObjectT(const DocumentObjectT& other) { *this = other; } -DocumentObjectT::DocumentObjectT(DocumentObjectT &&other) +DocumentObjectT::DocumentObjectT(DocumentObjectT&& other) { *this = std::move(other); } @@ -115,25 +116,29 @@ DocumentObjectT::DocumentObjectT(const Property* prop) DocumentObjectT::DocumentObjectT(const Document* doc, const std::string& objName) { - if (doc && doc->getName()) + if (doc && doc->getName()) { document = doc->getName(); + } object = objName; } -DocumentObjectT::DocumentObjectT(const char *docName, const char *objName) +DocumentObjectT::DocumentObjectT(const char* docName, const char* objName) { - if(docName) + if (docName) { document = docName; - if(objName) + } + if (objName) { object = objName; + } } DocumentObjectT::~DocumentObjectT() = default; -DocumentObjectT &DocumentObjectT::operator=(const DocumentObjectT& obj) +DocumentObjectT& DocumentObjectT::operator=(const DocumentObjectT& obj) { - if (this == &obj) + if (this == &obj) { return *this; + } object = obj.object; label = obj.label; document = obj.document; @@ -141,10 +146,11 @@ DocumentObjectT &DocumentObjectT::operator=(const DocumentObjectT& obj) return *this; } -DocumentObjectT &DocumentObjectT::operator=(DocumentObjectT&& obj) +DocumentObjectT& DocumentObjectT::operator=(DocumentObjectT&& obj) { - if (this == &obj) + if (this == &obj) { return *this; + } object = std::move(obj.object); label = std::move(obj.label); document = std::move(obj.document); @@ -154,12 +160,13 @@ DocumentObjectT &DocumentObjectT::operator=(DocumentObjectT&& obj) void DocumentObjectT::operator=(const DocumentObject* obj) { - if(!obj || !obj->isAttachedToDocument()) { + if (!obj || !obj->isAttachedToDocument()) { object.clear(); label.clear(); document.clear(); property.clear(); - } else { + } + else { object = obj->getNameInDocument(); label = obj->Label.getValue(); document = obj->getDocument()->getName(); @@ -167,16 +174,16 @@ void DocumentObjectT::operator=(const DocumentObject* obj) } } -void DocumentObjectT::operator=(const Property *prop) { - if(!prop || !prop->hasName() - || !prop->getContainer() - || !prop->getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) - { +void DocumentObjectT::operator=(const Property* prop) +{ + if (!prop || !prop->hasName() || !prop->getContainer() + || !prop->getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { object.clear(); label.clear(); document.clear(); property.clear(); - } else { + } + else { auto obj = static_cast(prop->getContainer()); object = obj->getNameInDocument(); label = obj->Label.getValue(); @@ -185,10 +192,9 @@ void DocumentObjectT::operator=(const Property *prop) { } } -bool DocumentObjectT::operator==(const DocumentObjectT &other) const { - return document == other.document - && object == other.object - && label == other.label +bool DocumentObjectT::operator==(const DocumentObjectT& other) const +{ + return document == other.document && object == other.object && label == other.label && property == other.property; } @@ -219,12 +225,12 @@ DocumentObject* DocumentObjectT::getObject() const return obj; } -const std::string &DocumentObjectT::getObjectName() const +const std::string& DocumentObjectT::getObjectName() const { return object; } -const std::string &DocumentObjectT::getObjectLabel() const +const std::string& DocumentObjectT::getObjectLabel() const { return label; } @@ -236,7 +242,8 @@ std::string DocumentObjectT::getObjectPython() const return str.str(); } -const std::string &DocumentObjectT::getPropertyName() const { +const std::string& DocumentObjectT::getPropertyName() const +{ return property; } @@ -244,15 +251,18 @@ std::string DocumentObjectT::getPropertyPython() const { std::stringstream str; str << getObjectPython(); - if (!property.empty()) + if (!property.empty()) { str << '.' << property; + } return str.str(); } -Property *DocumentObjectT::getProperty() const { +Property* DocumentObjectT::getProperty() const +{ auto obj = getObject(); - if(obj) + if (obj) { return obj->getPropertyByName(property.c_str()); + } return nullptr; } @@ -260,86 +270,95 @@ Property *DocumentObjectT::getProperty() const { SubObjectT::SubObjectT() = default; -SubObjectT::SubObjectT(const SubObjectT &) = default; +SubObjectT::SubObjectT(const SubObjectT&) = default; -SubObjectT::SubObjectT(SubObjectT &&other) - :DocumentObjectT(std::move(other)), subname(std::move(other.subname)) +SubObjectT::SubObjectT(SubObjectT&& other) + : DocumentObjectT(std::move(other)) + , subname(std::move(other.subname)) +{} + +SubObjectT::SubObjectT(const DocumentObject* obj, const char* s) + : DocumentObjectT(obj) + , subname(s ? s : "") +{} + +SubObjectT::SubObjectT(const DocumentObject* obj) + : DocumentObjectT(obj) +{} + +SubObjectT::SubObjectT(const DocumentObjectT& obj, const char* s) + : DocumentObjectT(obj) + , subname(s ? s : "") +{} + +SubObjectT::SubObjectT(const char* docName, const char* objName, const char* s) + : DocumentObjectT(docName, objName) + , subname(s ? s : "") +{} + +bool SubObjectT::operator<(const SubObjectT& other) const { -} - -SubObjectT::SubObjectT(const DocumentObject *obj, const char *s) - :DocumentObjectT(obj),subname(s?s:"") -{ -} - -SubObjectT::SubObjectT(const DocumentObject *obj) - :DocumentObjectT(obj) -{ -} - -SubObjectT::SubObjectT(const DocumentObjectT& obj, const char *s) - :DocumentObjectT(obj),subname(s?s:"") -{ -} - -SubObjectT::SubObjectT(const char *docName, const char *objName, const char *s) - :DocumentObjectT(docName,objName), subname(s?s:"") -{ -} - -bool SubObjectT::operator<(const SubObjectT &other) const { - if(getDocumentName() < other.getDocumentName()) + if (getDocumentName() < other.getDocumentName()) { return true; - if(getDocumentName() > other.getDocumentName()) + } + if (getDocumentName() > other.getDocumentName()) { return false; - if(getObjectName() < other.getObjectName()) + } + if (getObjectName() < other.getObjectName()) { return true; - if(getObjectName() > other.getObjectName()) + } + if (getObjectName() > other.getObjectName()) { return false; - if(getSubName() < other.getSubName()) + } + if (getSubName() < other.getSubName()) { return true; - if(getSubName() > other.getSubName()) + } + if (getSubName() > other.getSubName()) { return false; + } return getPropertyName() < other.getPropertyName(); } -SubObjectT &SubObjectT::operator=(const SubObjectT& other) +SubObjectT& SubObjectT::operator=(const SubObjectT& other) { - if (this == &other) + if (this == &other) { return *this; + } static_cast(*this) = other; subname = other.subname; return *this; } -SubObjectT &SubObjectT::operator=(SubObjectT &&other) +SubObjectT& SubObjectT::operator=(SubObjectT&& other) { - if (this == &other) + if (this == &other) { return *this; + } static_cast(*this) = std::move(other); subname = std::move(other.subname); return *this; } -SubObjectT &SubObjectT::operator=(const DocumentObjectT &other) +SubObjectT& SubObjectT::operator=(const DocumentObjectT& other) { - if (this == &other) + if (this == &other) { return *this; + } static_cast(*this) = other; subname.clear(); return *this; } -SubObjectT &SubObjectT::operator=(const DocumentObject *other) +SubObjectT& SubObjectT::operator=(const DocumentObject* other) { static_cast(*this) = other; subname.clear(); return *this; } -bool SubObjectT::operator==(const SubObjectT &other) const { - return static_cast(*this) == other - && subname == other.subname; +bool SubObjectT::operator==(const SubObjectT& other) const +{ + return static_cast(*this) == other && subname == other.subname; } namespace @@ -430,19 +449,23 @@ SubObjectT App::SubObjectT::normalized(NormalizeOptions options) const return res; } -void SubObjectT::setSubName(const char *s) { - subname = s?s:""; +void SubObjectT::setSubName(const char* s) +{ + subname = s ? s : ""; } -const std::string &SubObjectT::getSubName() const { +const std::string& SubObjectT::getSubName() const +{ return subname; } -std::string SubObjectT::getSubNameNoElement() const { +std::string SubObjectT::getSubNameNoElement() const +{ return Data::noElementName(subname.c_str()); } -const char *SubObjectT::getElementName() const { +const char* SubObjectT::getElementName() const +{ return Data::findElementName(subname.c_str()); } @@ -457,90 +480,107 @@ bool SubObjectT::hasSubElement() const return element && (element[0] != '\0'); } -std::string SubObjectT::getNewElementName() const { +std::string SubObjectT::getNewElementName() const +{ ElementNamePair element; auto obj = getObject(); - if(!obj) + if (!obj) { return {}; - GeoFeature::resolveElement(obj,subname.c_str(),element); + } + GeoFeature::resolveElement(obj, subname.c_str(), element); return std::move(element.newName); } -std::string SubObjectT::getOldElementName(int *index) const { +std::string SubObjectT::getOldElementName(int* index) const +{ ElementNamePair element; auto obj = getObject(); - if(!obj) + if (!obj) { return {}; - GeoFeature::resolveElement(obj,subname.c_str(),element); - if(!index) + } + GeoFeature::resolveElement(obj, subname.c_str(), element); + if (!index) { return std::move(element.oldName); + } std::size_t pos = element.oldName.find_first_of("0123456789"); - if(pos == std::string::npos) + if (pos == std::string::npos) { *index = -1; + } else { - *index = std::atoi(element.oldName.c_str()+pos); + *index = std::atoi(element.oldName.c_str() + pos); element.oldName.resize(pos); } return std::move(element.oldName); } -App::DocumentObject *SubObjectT::getSubObject() const { +App::DocumentObject* SubObjectT::getSubObject() const +{ auto obj = getObject(); - if(obj) + if (obj) { return obj->getSubObject(subname.c_str()); + } return nullptr; } -std::string SubObjectT::getSubObjectPython(bool force) const { - if(!force && subname.empty()) +std::string SubObjectT::getSubObjectPython(bool force) const +{ + if (!force && subname.empty()) { return getObjectPython(); + } std::stringstream str; - str << "(" << getObjectPython() << ",u'" - << Base::Tools::escapedUnicodeFromUtf8(subname.c_str()) << "')"; + str << "(" << getObjectPython() << ",u'" << Base::Tools::escapedUnicodeFromUtf8(subname.c_str()) + << "')"; return str.str(); } -std::vector SubObjectT::getSubObjectList() const { +std::vector SubObjectT::getSubObjectList() const +{ auto obj = getObject(); - if(obj) + if (obj) { return obj->getSubObjectList(subname.c_str()); + } return {}; } -std::string SubObjectT::getObjectFullName(const char *docName) const +std::string SubObjectT::getObjectFullName(const char* docName) const { std::ostringstream ss; if (!docName || getDocumentName() != docName) { ss << getDocumentName(); if (auto doc = getDocument()) { - if (doc->Label.getStrValue() != getDocumentName()) + if (doc->Label.getStrValue() != getDocumentName()) { ss << "(" << doc->Label.getValue() << ")"; + } } ss << "#"; } ss << getObjectName(); - if (!getObjectLabel().empty() && getObjectLabel() != getObjectName()) + if (!getObjectLabel().empty() && getObjectLabel() != getObjectName()) { ss << " (" << getObjectLabel() << ")"; + } return ss.str(); } -std::string SubObjectT::getSubObjectFullName(const char *docName) const +std::string SubObjectT::getSubObjectFullName(const char* docName) const { - if (subname.empty()) + if (subname.empty()) { return getObjectFullName(docName); + } std::ostringstream ss; if (!docName || getDocumentName() != docName) { ss << getDocumentName(); if (auto doc = getDocument()) { - if (doc->Label.getStrValue() != getDocumentName()) + if (doc->Label.getStrValue() != getDocumentName()) { ss << "(" << doc->Label.getValue() << ")"; + } } ss << "#"; } ss << getObjectName() << "." << subname; auto sobj = getSubObject(); - if (sobj && sobj->Label.getStrValue() != sobj->getNameInDocument()) + if (sobj && sobj->Label.getStrValue() != sobj->getNameInDocument()) { ss << " (" << sobj->Label.getValue() << ")"; + } return ss.str(); } @@ -548,10 +588,9 @@ std::string SubObjectT::getSubObjectFullName(const char *docName) const PropertyLinkT::PropertyLinkT() : toPython("None") -{ -} +{} -PropertyLinkT::PropertyLinkT(DocumentObject *obj) +PropertyLinkT::PropertyLinkT(DocumentObject* obj) : PropertyLinkT() { if (obj) { @@ -563,15 +602,16 @@ PropertyLinkT::PropertyLinkT(DocumentObject *obj) } } -PropertyLinkT::PropertyLinkT(DocumentObject *obj, const std::vector& subNames) +PropertyLinkT::PropertyLinkT(DocumentObject* obj, const std::vector& subNames) : PropertyLinkT() { if (obj) { std::ostringstream str; DocumentObjectT objT(obj); str << "(" << objT.getObjectPython() << ",["; - for(const auto& it : subNames) + for (const auto& it : subNames) { str << "'" << it << "',"; + } str << "])"; toPython = str.str(); @@ -585,8 +625,9 @@ PropertyLinkT::PropertyLinkT(const std::vector& objs) std::stringstream str; str << "["; for (std::size_t i = 0; i < objs.size(); i++) { - if (i > 0) + if (i > 0) { str << ", "; + } App::DocumentObject* obj = objs[i]; if (obj) { @@ -602,17 +643,20 @@ PropertyLinkT::PropertyLinkT(const std::vector& objs) } } -PropertyLinkT::PropertyLinkT(const std::vector& objs, const std::vector& subNames) +PropertyLinkT::PropertyLinkT(const std::vector& objs, + const std::vector& subNames) : PropertyLinkT() { if (!objs.empty() && objs.size() == subNames.size()) { std::stringstream str; str << "["; for (std::size_t i = 0; i < subNames.size(); i++) { - if (i>0) + if (i > 0) { str << ",("; - else + } + else { str << "("; + } App::DocumentObject* obj = objs[i]; if (obj) { @@ -639,22 +683,28 @@ std::string PropertyLinkT::getPropertyPython() const // ----------------------------------------------------------------------------- -class DocumentWeakPtrT::Private { +class DocumentWeakPtrT::Private +{ public: - explicit Private(App::Document* doc) : _document(doc) { + explicit Private(App::Document* doc) + : _document(doc) + { if (doc) { - //NOLINTBEGIN - connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(std::bind - (&Private::deletedDocument, this, sp::_1)); - //NOLINTEND + // NOLINTBEGIN + connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect( + std::bind(&Private::deletedDocument, this, sp::_1)); + // NOLINTEND } } - void deletedDocument(const App::Document& doc) { - if (_document == &doc) + void deletedDocument(const App::Document& doc) + { + if (_document == &doc) { reset(); + } } - void reset() { + void reset() + { connectApplicationDeletedDocument.disconnect(); _document = nullptr; } @@ -665,9 +715,8 @@ public: }; DocumentWeakPtrT::DocumentWeakPtrT(App::Document* doc) noexcept - : d(new Private(doc)) -{ -} + : d(new Private(doc)) +{} DocumentWeakPtrT::~DocumentWeakPtrT() = default; @@ -693,56 +742,65 @@ App::Document* DocumentWeakPtrT::operator->() const noexcept // ----------------------------------------------------------------------------- -class DocumentObjectWeakPtrT::Private { +class DocumentObjectWeakPtrT::Private +{ public: - explicit Private(App::DocumentObject* obj) : object(obj) { + explicit Private(App::DocumentObject* obj) + : object(obj) + { set(obj); } - void deletedDocument(const App::Document& doc) { + void deletedDocument(const App::Document& doc) + { // When deleting document then there is no way to undo it if (object && object->getDocument() == &doc) { reset(); } } - void createdObject(const App::DocumentObject& obj) noexcept { + void createdObject(const App::DocumentObject& obj) noexcept + { // When undoing the removal if (object == &obj) { indocument = true; } } - void deletedObject(const App::DocumentObject& obj) noexcept { + void deletedObject(const App::DocumentObject& obj) noexcept + { if (object == &obj) { indocument = false; } } - void reset() { + void reset() + { connectApplicationDeletedDocument.disconnect(); connectDocumentCreatedObject.disconnect(); connectDocumentDeletedObject.disconnect(); object = nullptr; indocument = false; } - void set(App::DocumentObject* obj) { + void set(App::DocumentObject* obj) + { object = obj; if (obj) { - //NOLINTBEGIN + // NOLINTBEGIN indocument = true; - connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(std::bind - (&Private::deletedDocument, this, sp::_1)); + connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect( + std::bind(&Private::deletedDocument, this, sp::_1)); App::Document* doc = obj->getDocument(); - connectDocumentCreatedObject = doc->signalNewObject.connect(std::bind - (&Private::createdObject, this, sp::_1)); - connectDocumentDeletedObject = doc->signalDeletedObject.connect(std::bind - (&Private::deletedObject, this, sp::_1)); - //NOLINTEND + connectDocumentCreatedObject = + doc->signalNewObject.connect(std::bind(&Private::createdObject, this, sp::_1)); + connectDocumentDeletedObject = + doc->signalDeletedObject.connect(std::bind(&Private::deletedObject, this, sp::_1)); + // NOLINTEND } } - App::DocumentObject* get() const noexcept { + App::DocumentObject* get() const noexcept + { return indocument ? object : nullptr; } App::DocumentObject* object; - bool indocument{false}; + bool indocument {false}; using Connection = boost::signals2::scoped_connection; Connection connectApplicationDeletedDocument; Connection connectDocumentCreatedObject; @@ -750,9 +808,8 @@ public: }; DocumentObjectWeakPtrT::DocumentObjectWeakPtrT(App::DocumentObject* obj) - : d(new Private(obj)) -{ -} + : d(new Private(obj)) +{} DocumentObjectWeakPtrT::~DocumentObjectWeakPtrT() = default; @@ -771,7 +828,7 @@ bool DocumentObjectWeakPtrT::expired() const noexcept return !d->indocument; } -DocumentObjectWeakPtrT& DocumentObjectWeakPtrT::operator= (App::DocumentObject* p) +DocumentObjectWeakPtrT& DocumentObjectWeakPtrT::operator=(App::DocumentObject* p) { d->reset(); d->set(p); @@ -788,31 +845,33 @@ App::DocumentObject* DocumentObjectWeakPtrT::operator->() const noexcept return d->get(); } -bool DocumentObjectWeakPtrT::operator== (const DocumentObjectWeakPtrT& p) const noexcept +bool DocumentObjectWeakPtrT::operator==(const DocumentObjectWeakPtrT& p) const noexcept { return d->get() == p.d->get(); } -bool DocumentObjectWeakPtrT::operator!= (const DocumentObjectWeakPtrT& p) const noexcept +bool DocumentObjectWeakPtrT::operator!=(const DocumentObjectWeakPtrT& p) const noexcept { return d->get() != p.d->get(); } // ----------------------------------------------------------------------------- -DocumentObserver::DocumentObserver() : _document(nullptr) +DocumentObserver::DocumentObserver() + : _document(nullptr) { - //NOLINTBEGIN - this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect(std::bind - (&DocumentObserver::slotCreatedDocument, this, sp::_1)); - this->connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(std::bind - (&DocumentObserver::slotDeletedDocument, this, sp::_1)); - this->connectApplicationActivateDocument = App::GetApplication().signalActiveDocument.connect(std::bind - (&DocumentObserver::slotActivateDocument, this, sp::_1)); - //NOLINTEND + // NOLINTBEGIN + this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect( + std::bind(&DocumentObserver::slotCreatedDocument, this, sp::_1)); + this->connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect( + std::bind(&DocumentObserver::slotDeletedDocument, this, sp::_1)); + this->connectApplicationActivateDocument = App::GetApplication().signalActiveDocument.connect( + std::bind(&DocumentObserver::slotActivateDocument, this, sp::_1)); + // NOLINTEND } -DocumentObserver::DocumentObserver(Document* doc) : DocumentObserver() +DocumentObserver::DocumentObserver(Document* doc) + : DocumentObserver() { // Connect to application and given document attachDocument(doc); @@ -838,18 +897,18 @@ void DocumentObserver::attachDocument(Document* doc) detachDocument(); _document = doc; - //NOLINTBEGIN - this->connectDocumentCreatedObject = _document->signalNewObject.connect(std::bind - (&DocumentObserver::slotCreatedObject, this, sp::_1)); - this->connectDocumentDeletedObject = _document->signalDeletedObject.connect(std::bind - (&DocumentObserver::slotDeletedObject, this, sp::_1)); - this->connectDocumentChangedObject = _document->signalChangedObject.connect(std::bind - (&DocumentObserver::slotChangedObject, this, sp::_1, sp::_2)); - this->connectDocumentRecomputedObject = _document->signalRecomputedObject.connect(std::bind - (&DocumentObserver::slotRecomputedObject, this, sp::_1)); - this->connectDocumentRecomputed = _document->signalRecomputed.connect(std::bind - (&DocumentObserver::slotRecomputedDocument, this, sp::_1)); - //NOLINTEND + // NOLINTBEGIN + this->connectDocumentCreatedObject = _document->signalNewObject.connect( + std::bind(&DocumentObserver::slotCreatedObject, this, sp::_1)); + this->connectDocumentDeletedObject = _document->signalDeletedObject.connect( + std::bind(&DocumentObserver::slotDeletedObject, this, sp::_1)); + this->connectDocumentChangedObject = _document->signalChangedObject.connect( + std::bind(&DocumentObserver::slotChangedObject, this, sp::_1, sp::_2)); + this->connectDocumentRecomputedObject = _document->signalRecomputedObject.connect( + std::bind(&DocumentObserver::slotRecomputedObject, this, sp::_1)); + this->connectDocumentRecomputed = _document->signalRecomputed.connect( + std::bind(&DocumentObserver::slotRecomputedDocument, this, sp::_1)); + // NOLINTEND } } @@ -866,36 +925,29 @@ void DocumentObserver::detachDocument() } void DocumentObserver::slotCreatedDocument(const App::Document& /*Doc*/) -{ -} +{} void DocumentObserver::slotDeletedDocument(const App::Document& /*Doc*/) -{ -} +{} void DocumentObserver::slotActivateDocument(const App::Document& /*Doc*/) -{ -} +{} void DocumentObserver::slotCreatedObject(const App::DocumentObject& /*Obj*/) -{ -} +{} void DocumentObserver::slotDeletedObject(const App::DocumentObject& /*Obj*/) -{ -} +{} -void DocumentObserver::slotChangedObject(const App::DocumentObject& /*Obj*/, const App::Property& /*Prop*/) -{ -} +void DocumentObserver::slotChangedObject(const App::DocumentObject& /*Obj*/, + const App::Property& /*Prop*/) +{} void DocumentObserver::slotRecomputedObject(const DocumentObject& /*Obj*/) -{ -} +{} void DocumentObserver::slotRecomputedDocument(const Document& /*doc*/) -{ -} +{} // ----------------------------------------------------------------------------- @@ -925,8 +977,7 @@ void DocumentObjectObserver::removeFromObservation(App::DocumentObject* obj) } void DocumentObjectObserver::slotCreatedDocument(const App::Document&) -{ -} +{} void DocumentObjectObserver::slotDeletedDocument(const App::Document& Doc) { @@ -938,24 +989,22 @@ void DocumentObjectObserver::slotDeletedDocument(const App::Document& Doc) } void DocumentObjectObserver::slotCreatedObject(const App::DocumentObject&) -{ -} +{} void DocumentObjectObserver::slotDeletedObject(const App::DocumentObject& Obj) { - std::set::iterator it = _objects.find - (const_cast(&Obj)); - if (it != _objects.end()) + std::set::iterator it = + _objects.find(const_cast(&Obj)); + if (it != _objects.end()) { _objects.erase(it); - if (_objects.empty()) + } + if (_objects.empty()) { cancelObservation(); + } } -void DocumentObjectObserver::slotChangedObject(const App::DocumentObject&, - const App::Property&) -{ -} +void DocumentObjectObserver::slotChangedObject(const App::DocumentObject&, const App::Property&) +{} void DocumentObjectObserver::cancelObservation() -{ -} +{} diff --git a/src/App/DocumentObserver.h b/src/App/DocumentObserver.h index e9ce51692c..87a8b5c97d 100644 --- a/src/App/DocumentObserver.h +++ b/src/App/DocumentObserver.h @@ -51,7 +51,7 @@ public: /*! Constructor */ DocumentT(); /*! Constructor */ - DocumentT(Document*); // explicit bombs + DocumentT(Document*); // explicit bombs /*! Constructor */ explicit DocumentT(const std::string&); /*! Constructor */ @@ -65,18 +65,20 @@ public: /*! Assignment operator */ void operator=(const std::string&); - bool operator==(const DocumentT &other) const { + bool operator==(const DocumentT& other) const + { return document == other.document; } - bool operator<(const DocumentT &other) const { + bool operator<(const DocumentT& other) const + { return document < other.document; } /*! Get a pointer to the document or 0 if it doesn't exist any more. */ Document* getDocument() const; /*! Get the name of the document. */ - const std::string &getDocumentName() const; + const std::string& getDocumentName() const; /*! Get the document as Python command. */ std::string getDocumentPython() const; @@ -85,9 +87,9 @@ private: }; /** - * The DocumentObjectT class is a helper class to store the names of a document object and its document. - * This can be useful when you cannot rely on that the document or the object still exists when you have to - * access it. + * The DocumentObjectT class is a helper class to store the names of a document object and its + * document. This can be useful when you cannot rely on that the document or the object still exists + * when you have to access it. * * @author Werner Mayer */ @@ -97,23 +99,23 @@ public: /*! Constructor */ DocumentObjectT(); /*! Constructor */ - DocumentObjectT(const DocumentObjectT &); + DocumentObjectT(const DocumentObjectT&); /*! Constructor */ - DocumentObjectT(DocumentObjectT &&); + DocumentObjectT(DocumentObjectT&&); /*! Constructor */ explicit DocumentObjectT(const DocumentObject*); /*! Constructor */ DocumentObjectT(const Document*, const std::string& objName); /*! Constructor */ - DocumentObjectT(const char *docName, const char *objName); + DocumentObjectT(const char* docName, const char* objName); /*! Constructor */ explicit DocumentObjectT(const Property*); /*! Destructor */ ~DocumentObjectT(); /*! Assignment operator */ - DocumentObjectT &operator=(const DocumentObjectT&); + DocumentObjectT& operator=(const DocumentObjectT&); /*! Assignment operator */ - DocumentObjectT &operator=(DocumentObjectT &&); + DocumentObjectT& operator=(DocumentObjectT&&); /*! Assignment operator */ void operator=(const DocumentObject*); /*! Assignment operator */ @@ -124,7 +126,7 @@ public: /*! Get a pointer to the document or 0 if it doesn't exist any more. */ Document* getDocument() const; /*! Get the name of the document. */ - const std::string &getDocumentName() const; + const std::string& getDocumentName() const; /*! Get the document as Python command. */ std::string getDocumentPython() const; /*! Get a pointer to the document object or 0 if it doesn't exist any more. */ @@ -132,16 +134,17 @@ public: /*! Get a pointer to the property or 0 if it doesn't exist any more. */ Property* getProperty() const; /*! Get the name of the document object. */ - const std::string &getObjectName() const; + const std::string& getObjectName() const; /*! Get the label of the document object. */ - const std::string &getObjectLabel() const; + const std::string& getObjectLabel() const; /*! Get the name of the property. */ - const std::string &getPropertyName() const; + const std::string& getPropertyName() const; /*! Get the document object as Python command. */ std::string getObjectPython() const; /*! Get the property as Python command. */ std::string getPropertyPython() const; - /*! Get a pointer to the document or 0 if it doesn't exist any more or the type doesn't match. */ + /*! Get a pointer to the document or 0 if it doesn't exist any more or the type doesn't match. + */ template inline T* getObjectAs() const { @@ -160,72 +163,73 @@ private: std::string property; }; -class AppExport SubObjectT : public DocumentObjectT +class AppExport SubObjectT: public DocumentObjectT { public: /*! Constructor */ SubObjectT(); /*! Constructor */ - SubObjectT(const SubObjectT &); + SubObjectT(const SubObjectT&); /*! Constructor */ - SubObjectT(SubObjectT &&); + SubObjectT(SubObjectT&&); /*! Constructor */ - SubObjectT(const DocumentObjectT & obj, const char *subname); + SubObjectT(const DocumentObjectT& obj, const char* subname); /*! Constructor */ - SubObjectT(const DocumentObject*, const char *subname); + SubObjectT(const DocumentObject*, const char* subname); /*! Constructor */ - SubObjectT(const DocumentObject*);// explicit bombs + SubObjectT(const DocumentObject*); // explicit bombs /*! Constructor */ - SubObjectT(const char *docName, const char *objName, const char *subname); + SubObjectT(const char* docName, const char* objName, const char* subname); /*! Assignment operator */ - SubObjectT &operator=(const SubObjectT&); + SubObjectT& operator=(const SubObjectT&); /*! Assignment operator */ - SubObjectT &operator=(SubObjectT &&); + SubObjectT& operator=(SubObjectT&&); /*! Assignment operator */ - SubObjectT &operator=(const DocumentObjectT&); + SubObjectT& operator=(const DocumentObjectT&); /*! Assignment operator */ - SubObjectT &operator=(const App::DocumentObject*); + SubObjectT& operator=(const App::DocumentObject*); /*! Equality operator */ bool operator==(const SubObjectT&) const; /// Set the subname path to the sub-object - void setSubName(const char *subname); + void setSubName(const char* subname); /// Set the subname path to the sub-object - void setSubName(const std::string &subname) { + void setSubName(const std::string& subname) + { setSubName(subname.c_str()); } /// Return the subname path - const std::string &getSubName() const; + const std::string& getSubName() const; /** Return docname#objname (label) * @param docName: optional document name. The document prefix will only be printed * if it is different then the given 'doc'. */ - std::string getObjectFullName(const char *docName=nullptr) const; + std::string getObjectFullName(const char* docName = nullptr) const; /** Return docname#objname.subname (label) * @param doc: optional document name. The document prefix will only be printed * if it is different then the given 'doc'. */ - std::string getSubObjectFullName(const char *docName=nullptr) const; + std::string getSubObjectFullName(const char* docName = nullptr) const; /// Return the subname path without sub-element std::string getSubNameNoElement() const; /// Return the sub-element (Face, Edge, etc) of the subname path - const char *getElementName() const; + const char* getElementName() const; /// Check if there is any sub object reference bool hasSubObject() const; @@ -239,17 +243,17 @@ public: /** Return the old style sub-element name * @param index: if given, then return the element type, and extract the index */ - std::string getOldElementName(int *index=nullptr) const; + std::string getOldElementName(int* index = nullptr) const; /// Return the sub-object - DocumentObject *getSubObject() const; + DocumentObject* getSubObject() const; /// Return all objects along the subname path - std::vector getSubObjectList() const; + std::vector getSubObjectList() const; - bool operator<(const SubObjectT &other) const; + bool operator<(const SubObjectT& other) const; - std::string getSubObjectPython(bool force=true) const; + std::string getSubObjectPython(bool force = true) const; /// Options used by normalize() enum class NormalizeOption : uint8_t @@ -299,16 +303,17 @@ public: PropertyLinkT(); /*! Constructor */ - explicit PropertyLinkT(DocumentObject *obj); + explicit PropertyLinkT(DocumentObject* obj); /*! Constructor */ - PropertyLinkT(DocumentObject *obj, const std::vector& subNames); + PropertyLinkT(DocumentObject* obj, const std::vector& subNames); /*! Constructor */ explicit PropertyLinkT(const std::vector& objs); /*! Constructor */ - PropertyLinkT(const std::vector& objs, const std::vector& subNames); + PropertyLinkT(const std::vector& objs, + const std::vector& subNames); /*! Get the property as Python command. */ std::string getPropertyPython() const; @@ -379,7 +384,7 @@ public: * \brief operator = * Assignment operator */ - DocumentObjectWeakPtrT& operator= (App::DocumentObject* p); + DocumentObjectWeakPtrT& operator=(App::DocumentObject* p); /*! * \brief operator * * \return pointer to the document object @@ -394,12 +399,12 @@ public: * \brief operator == * \return true if both objects are equal, false otherwise */ - bool operator== (const DocumentObjectWeakPtrT& p) const noexcept; + bool operator==(const DocumentObjectWeakPtrT& p) const noexcept; /*! * \brief operator != * \return true if both objects are inequal, false otherwise */ - bool operator!= (const DocumentObjectWeakPtrT& p) const noexcept; + bool operator!=(const DocumentObjectWeakPtrT& p) const noexcept; /*! Get a pointer to the object or 0 if it doesn't exist any more or the type doesn't match. */ template inline T* get() const noexcept @@ -423,33 +428,37 @@ private: /** * @brief The WeakPtrT class */ -template +template class WeakPtrT { public: - explicit WeakPtrT(T* t) : ptr(t) { - } + explicit WeakPtrT(T* t) + : ptr(t) + {} ~WeakPtrT() = default; /*! * \brief reset * Releases the reference to the managed object. After the call *this manages no object. */ - void reset() { + void reset() + { ptr.reset(); } /*! * \brief expired * \return true if the managed object has already been deleted, false otherwise. */ - bool expired() const { + bool expired() const + { return ptr.expired(); } /*! * \brief operator = * Assignment operator */ - WeakPtrT& operator= (T* p) { + WeakPtrT& operator=(T* p) + { ptr = p; return *this; } @@ -457,28 +466,32 @@ public: * \brief operator -> * \return pointer to the document object */ - T* operator*() const { + T* operator*() const + { return ptr.get(); } /*! * \brief operator -> * \return pointer to the document object */ - T* operator->() const { + T* operator->() const + { return ptr.get(); } /*! * \brief operator == * \return true if both objects are equal, false otherwise */ - bool operator== (const WeakPtrT& p) const { + bool operator==(const WeakPtrT& p) const + { return ptr == p.ptr; } /*! * \brief operator != * \return true if both objects are inequal, false otherwise */ - bool operator!= (const WeakPtrT& p) const { + bool operator!=(const WeakPtrT& p) const + { return ptr != p.ptr; } /*! Get a pointer to the object or 0 if it doesn't exist any more. */ @@ -561,7 +574,7 @@ private: * * @author Werner Mayer */ -class AppExport DocumentObjectObserver : public DocumentObserver +class AppExport DocumentObjectObserver: public DocumentObserver { public: @@ -587,18 +600,18 @@ private: void slotDeletedObject(const App::DocumentObject& Obj) override; /** The property of an observed object has changed */ void slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop) override; - /** This method gets called when all observed objects are deleted or the whole document is deleted. - * This method can be re-implemented to perform an extra step like closing a dialog that observes - * a document. - */ + /** This method gets called when all observed objects are deleted or the whole document is + * deleted. This method can be re-implemented to perform an extra step like closing a dialog + * that observes a document. + */ virtual void cancelObservation(); private: std::set _objects; }; -} //namespace App +} // namespace App ENABLE_BITMASK_OPERATORS(App::SubObjectT::NormalizeOption) -#endif // APP_DOCUMENTOBSERVER_H +#endif // APP_DOCUMENTOBSERVER_H diff --git a/src/App/DocumentObserverPython.cpp b/src/App/DocumentObserverPython.cpp index beb61a1522..f36515dd8a 100644 --- a/src/App/DocumentObserverPython.cpp +++ b/src/App/DocumentObserverPython.cpp @@ -46,9 +46,10 @@ void DocumentObserverPython::addObserver(const Py::Object& obj) void DocumentObserverPython::removeObserver(const Py::Object& obj) { - DocumentObserverPython* obs=nullptr; - for (std::vector::iterator it = - _instances.begin(); it != _instances.end(); ++it) { + DocumentObserverPython* obs = nullptr; + for (std::vector::iterator it = _instances.begin(); + it != _instances.end(); + ++it) { if ((*it)->inst == obj) { obs = *it; _instances.erase(it); @@ -59,33 +60,34 @@ void DocumentObserverPython::removeObserver(const Py::Object& obj) delete obs; } -DocumentObserverPython::DocumentObserverPython(const Py::Object& obj) : inst(obj) +DocumentObserverPython::DocumentObserverPython(const Py::Object& obj) + : inst(obj) { -#define FC_PY_ELEMENT_ARG0(_name1, _name2) do {\ - FC_PY_GetCallable(obj.ptr(), "slot" #_name1, py##_name1.py);\ - if (!py##_name1.py.isNone())\ - py##_name1.slot = App::GetApplication().signal##_name2.connect(\ - std::bind(&DocumentObserverPython::slot##_name1, this));\ - }\ - while(0); +#define FC_PY_ELEMENT_ARG0(_name1, _name2) \ + do { \ + FC_PY_GetCallable(obj.ptr(), "slot" #_name1, py##_name1.py); \ + if (!py##_name1.py.isNone()) \ + py##_name1.slot = App::GetApplication().signal##_name2.connect( \ + std::bind(&DocumentObserverPython::slot##_name1, this)); \ + } while (0); -#define FC_PY_ELEMENT_ARG1(_name1, _name2) do {\ - FC_PY_GetCallable(obj.ptr(), "slot" #_name1, py##_name1.py);\ - if (!py##_name1.py.isNone())\ - py##_name1.slot = App::GetApplication().signal##_name2.connect(\ - std::bind(&DocumentObserverPython::slot##_name1, this, sp::_1));\ - }\ - while(0); +#define FC_PY_ELEMENT_ARG1(_name1, _name2) \ + do { \ + FC_PY_GetCallable(obj.ptr(), "slot" #_name1, py##_name1.py); \ + if (!py##_name1.py.isNone()) \ + py##_name1.slot = App::GetApplication().signal##_name2.connect( \ + std::bind(&DocumentObserverPython::slot##_name1, this, sp::_1)); \ + } while (0); - //NOLINTBEGIN -#define FC_PY_ELEMENT_ARG2(_name1, _name2) do {\ - FC_PY_GetCallable(obj.ptr(), "slot" #_name1, py##_name1.py);\ - if (!py##_name1.py.isNone())\ - py##_name1.slot = App::GetApplication().signal##_name2.connect(\ - std::bind(&DocumentObserverPython::slot##_name1, this, sp::_1, sp::_2));\ - }\ - while(0); + // NOLINTBEGIN +#define FC_PY_ELEMENT_ARG2(_name1, _name2) \ + do { \ + FC_PY_GetCallable(obj.ptr(), "slot" #_name1, py##_name1.py); \ + if (!py##_name1.py.isNone()) \ + py##_name1.slot = App::GetApplication().signal##_name2.connect( \ + std::bind(&DocumentObserverPython::slot##_name1, this, sp::_1, sp::_2)); \ + } while (0); FC_PY_ELEMENT_ARG1(CreatedDocument, NewDocument) FC_PY_ELEMENT_ARG1(DeletedDocument, DeleteDocument) @@ -116,7 +118,7 @@ DocumentObserverPython::DocumentObserverPython(const Py::Object& obj) : inst(obj FC_PY_ELEMENT_ARG2(ChangePropertyEditor, ChangePropertyEditor) FC_PY_ELEMENT_ARG2(BeforeAddingDynamicExtension, BeforeAddingDynamicExtension) FC_PY_ELEMENT_ARG2(AddedDynamicExtension, AddedDynamicExtension) - //NOLINTEND + // NOLINTEND } DocumentObserverPython::~DocumentObserverPython() = default; @@ -127,10 +129,10 @@ void DocumentObserverPython::slotCreatedDocument(const App::Document& Doc) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(Doc).getPyObject())); - Base::pyCall(pyCreatedDocument.ptr(),args.ptr()); + Base::pyCall(pyCreatedDocument.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -141,10 +143,10 @@ void DocumentObserverPython::slotDeletedDocument(const App::Document& Doc) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(Doc).getPyObject())); - Base::pyCall(pyDeletedDocument.ptr(),args.ptr()); + Base::pyCall(pyDeletedDocument.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -155,10 +157,10 @@ void DocumentObserverPython::slotRelabelDocument(const App::Document& Doc) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(Doc).getPyObject())); - Base::pyCall(pyRelabelDocument.ptr(),args.ptr()); + Base::pyCall(pyRelabelDocument.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -169,10 +171,10 @@ void DocumentObserverPython::slotActivateDocument(const App::Document& Doc) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(Doc).getPyObject())); - Base::pyCall(pyActivateDocument.ptr(),args.ptr()); + Base::pyCall(pyActivateDocument.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -183,10 +185,10 @@ void DocumentObserverPython::slotUndoDocument(const App::Document& Doc) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(Doc).getPyObject())); - Base::pyCall(pyUndoDocument.ptr(),args.ptr()); + Base::pyCall(pyUndoDocument.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -198,10 +200,10 @@ void DocumentObserverPython::slotRedoDocument(const App::Document& Doc) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(Doc).getPyObject())); - Base::pyCall(pyRedoDocument.ptr(),args.ptr()); + Base::pyCall(pyRedoDocument.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -213,7 +215,7 @@ void DocumentObserverPython::slotUndo() Base::pyCall(pyUndo.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -225,7 +227,7 @@ void DocumentObserverPython::slotRedo() Base::pyCall(pyRedo.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -236,10 +238,10 @@ void DocumentObserverPython::slotBeforeCloseTransaction(bool abort) try { Py::Tuple args(1); args.setItem(0, Py::Boolean(abort)); - Base::pyCall(pyBeforeCloseTransaction.ptr(),args.ptr()); + Base::pyCall(pyBeforeCloseTransaction.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -250,15 +252,16 @@ void DocumentObserverPython::slotCloseTransaction(bool abort) try { Py::Tuple args(1); args.setItem(0, Py::Boolean(abort)); - Base::pyCall(pyCloseTransaction.ptr(),args.ptr()); + Base::pyCall(pyCloseTransaction.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } -void DocumentObserverPython::slotBeforeChangeDocument(const App::Document& Doc, const App::Property& Prop) +void DocumentObserverPython::slotBeforeChangeDocument(const App::Document& Doc, + const App::Property& Prop) { Base::PyGILStateLocker lock; try { @@ -269,16 +272,17 @@ void DocumentObserverPython::slotBeforeChangeDocument(const App::Document& Doc, const char* prop_name = Doc.getPropertyName(&Prop); if (prop_name) { args.setItem(1, Py::String(prop_name)); - Base::pyCall(pyBeforeChangeDocument.ptr(),args.ptr()); + Base::pyCall(pyBeforeChangeDocument.ptr(), args.ptr()); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } -void DocumentObserverPython::slotChangedDocument(const App::Document& Doc, const App::Property& Prop) +void DocumentObserverPython::slotChangedDocument(const App::Document& Doc, + const App::Property& Prop) { Base::PyGILStateLocker lock; try { @@ -289,11 +293,11 @@ void DocumentObserverPython::slotChangedDocument(const App::Document& Doc, const const char* prop_name = Doc.getPropertyName(&Prop); if (prop_name) { args.setItem(1, Py::String(prop_name)); - Base::pyCall(pyChangedDocument.ptr(),args.ptr()); + Base::pyCall(pyChangedDocument.ptr(), args.ptr()); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -304,10 +308,10 @@ void DocumentObserverPython::slotCreatedObject(const App::DocumentObject& Obj) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(Obj).getPyObject())); - Base::pyCall(pyCreatedObject.ptr(),args.ptr()); + Base::pyCall(pyCreatedObject.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -318,16 +322,16 @@ void DocumentObserverPython::slotDeletedObject(const App::DocumentObject& Obj) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(Obj).getPyObject())); - Base::pyCall(pyDeletedObject.ptr(),args.ptr()); + Base::pyCall(pyDeletedObject.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } void DocumentObserverPython::slotBeforeChangeObject(const App::DocumentObject& Obj, - const App::Property& Prop) + const App::Property& Prop) { Base::PyGILStateLocker lock; try { @@ -338,11 +342,11 @@ void DocumentObserverPython::slotBeforeChangeObject(const App::DocumentObject& O const char* prop_name = Obj.getPropertyName(&Prop); if (prop_name) { args.setItem(1, Py::String(prop_name)); - Base::pyCall(pyBeforeChangeObject.ptr(),args.ptr()); + Base::pyCall(pyBeforeChangeObject.ptr(), args.ptr()); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -359,11 +363,11 @@ void DocumentObserverPython::slotChangedObject(const App::DocumentObject& Obj, const char* prop_name = Obj.getPropertyName(&Prop); if (prop_name) { args.setItem(1, Py::String(prop_name)); - Base::pyCall(pyChangedObject.ptr(),args.ptr()); + Base::pyCall(pyChangedObject.ptr(), args.ptr()); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -374,10 +378,10 @@ void DocumentObserverPython::slotRecomputedObject(const App::DocumentObject& Obj try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(Obj).getPyObject())); - Base::pyCall(pyRecomputedObject.ptr(),args.ptr()); + Base::pyCall(pyRecomputedObject.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -388,10 +392,10 @@ void DocumentObserverPython::slotRecomputedDocument(const App::Document& doc) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(doc).getPyObject())); - Base::pyCall(pyRecomputedDocument.ptr(),args.ptr()); + Base::pyCall(pyRecomputedDocument.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -402,10 +406,10 @@ void DocumentObserverPython::slotBeforeRecomputeDocument(const App::Document& do try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(doc).getPyObject())); - Base::pyCall(pyBeforeRecomputeDocument.ptr(),args.ptr()); + Base::pyCall(pyBeforeRecomputeDocument.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -417,10 +421,10 @@ void DocumentObserverPython::slotOpenTransaction(const App::Document& doc, std:: Py::Tuple args(2); args.setItem(0, Py::asObject(const_cast(doc).getPyObject())); args.setItem(1, Py::String(str)); - Base::pyCall(pyOpenTransaction.ptr(),args.ptr()); + Base::pyCall(pyOpenTransaction.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -431,10 +435,10 @@ void DocumentObserverPython::slotCommitTransaction(const App::Document& doc) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(doc).getPyObject())); - Base::pyCall(pyCommitTransaction.ptr(),args.ptr()); + Base::pyCall(pyCommitTransaction.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -445,10 +449,10 @@ void DocumentObserverPython::slotAbortTransaction(const App::Document& doc) try { Py::Tuple args(1); args.setItem(0, Py::asObject(const_cast(doc).getPyObject())); - Base::pyCall(pyAbortTransaction.ptr(),args.ptr()); + Base::pyCall(pyAbortTransaction.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -465,11 +469,11 @@ void DocumentObserverPython::slotAppendDynamicProperty(const App::Property& Prop const char* prop_name = container->getPropertyName(&Prop); if (prop_name) { args.setItem(1, Py::String(prop_name)); - Base::pyCall(pyAppendDynamicProperty.ptr(),args.ptr()); + Base::pyCall(pyAppendDynamicProperty.ptr(), args.ptr()); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -486,16 +490,17 @@ void DocumentObserverPython::slotRemoveDynamicProperty(const App::Property& Prop const char* prop_name = container->getPropertyName(&Prop); if (prop_name) { args.setItem(1, Py::String(prop_name)); - Base::pyCall(pyRemoveDynamicProperty.ptr(),args.ptr()); + Base::pyCall(pyRemoveDynamicProperty.ptr(), args.ptr()); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } -void DocumentObserverPython::slotChangePropertyEditor(const App::Document &, const App::Property& Prop) +void DocumentObserverPython::slotChangePropertyEditor(const App::Document&, + const App::Property& Prop) { Base::PyGILStateLocker lock; try { @@ -507,72 +512,76 @@ void DocumentObserverPython::slotChangePropertyEditor(const App::Document &, con const char* prop_name = container->getPropertyName(&Prop); if (prop_name) { args.setItem(1, Py::String(prop_name)); - Base::pyCall(pyChangePropertyEditor.ptr(),args.ptr()); + Base::pyCall(pyChangePropertyEditor.ptr(), args.ptr()); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } -void DocumentObserverPython::slotStartSaveDocument(const App::Document& doc, const std::string& file) +void DocumentObserverPython::slotStartSaveDocument(const App::Document& doc, + const std::string& file) { Base::PyGILStateLocker lock; try { Py::Tuple args(2); args.setItem(0, Py::asObject(const_cast(doc).getPyObject())); args.setItem(1, Py::String(file)); - Base::pyCall(pyStartSaveDocument.ptr(),args.ptr()); + Base::pyCall(pyStartSaveDocument.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } -void DocumentObserverPython::slotFinishSaveDocument(const App::Document& doc, const std::string& file) +void DocumentObserverPython::slotFinishSaveDocument(const App::Document& doc, + const std::string& file) { Base::PyGILStateLocker lock; try { Py::Tuple args(2); args.setItem(0, Py::asObject(const_cast(doc).getPyObject())); args.setItem(1, Py::String(file)); - Base::pyCall(pyFinishSaveDocument.ptr(),args.ptr()); + Base::pyCall(pyFinishSaveDocument.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } -void DocumentObserverPython::slotBeforeAddingDynamicExtension(const App::ExtensionContainer& extcont, std::string extension) +void DocumentObserverPython::slotBeforeAddingDynamicExtension( + const App::ExtensionContainer& extcont, + std::string extension) { Base::PyGILStateLocker lock; try { Py::Tuple args(2); args.setItem(0, Py::asObject(const_cast(extcont).getPyObject())); args.setItem(1, Py::String(extension)); - Base::pyCall(pyBeforeAddingDynamicExtension.ptr(),args.ptr()); + Base::pyCall(pyBeforeAddingDynamicExtension.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } -void DocumentObserverPython::slotAddedDynamicExtension(const App::ExtensionContainer& extcont, std::string extension) +void DocumentObserverPython::slotAddedDynamicExtension(const App::ExtensionContainer& extcont, + std::string extension) { Base::PyGILStateLocker lock; try { Py::Tuple args(2); args.setItem(0, Py::asObject(const_cast(extcont).getPyObject())); args.setItem(1, Py::String(extension)); - Base::pyCall(pyAddedDynamicExtension.ptr(),args.ptr()); + Base::pyCall(pyAddedDynamicExtension.ptr(), args.ptr()); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } - diff --git a/src/App/DocumentObserverPython.h b/src/App/DocumentObserverPython.h index ce57626ddf..b0240c6416 100644 --- a/src/App/DocumentObserverPython.h +++ b/src/App/DocumentObserverPython.h @@ -106,7 +106,7 @@ private: /** Called when an object gets a dynamic property removed*/ void slotRemoveDynamicProperty(const App::Property& Prop); /** Called when an object property gets a new editor relevant status like hidden or read only*/ - void slotChangePropertyEditor(const App::Document &Doc, const App::Property& Prop); + void slotChangePropertyEditor(const App::Document& Doc, const App::Property& Prop); /** Called when a document is about to be saved*/ void slotStartSaveDocument(const App::Document&, const std::string&); /** Called when an document has been saved*/ @@ -121,12 +121,14 @@ private: Py::Object inst; static std::vector _instances; - using Connection = struct PythonObject { - boost::signals2::scoped_connection slot; - Py::Object py; - PyObject* ptr() { - return py.ptr(); - } + using Connection = struct PythonObject + { + boost::signals2::scoped_connection slot; + Py::Object py; + PyObject* ptr() + { + return py.ptr(); + } }; Connection pyCreatedDocument; @@ -160,6 +162,6 @@ private: Connection pyAddedDynamicExtension; }; -} //namespace App +} // namespace App -#endif // APP_DOCUMENTOBSERVERPYTHON_H +#endif // APP_DOCUMENTOBSERVERPYTHON_H diff --git a/src/App/DocumentPyImp.cpp b/src/App/DocumentPyImp.cpp index 229ba5d7d7..ea62adb535 100644 --- a/src/App/DocumentPyImp.cpp +++ b/src/App/DocumentPyImp.cpp @@ -41,21 +41,40 @@ using namespace App; -PyObject* DocumentPy::addProperty(PyObject *args, PyObject *kwd) +PyObject* DocumentPy::addProperty(PyObject* args, PyObject* kwd) { - char *sType {nullptr}; - char *sName {nullptr}; - char *sGroup {nullptr}; - char *sDoc {nullptr}; - short attr=0; + char* sType {nullptr}; + char* sName {nullptr}; + char* sGroup {nullptr}; + char* sDoc {nullptr}; + short attr = 0; std::string sDocStr; PyObject *ro = Py_False, *hd = Py_False; PyObject* enumVals = nullptr; - static const std::array kwlist{"type", "name", "group", "doc", "attr", - "read_only", "hidden", "enum_vals", nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords( - args, kwd, "ss|sethO!O!O", kwlist, &sType, &sName, &sGroup, "utf-8", - &sDoc, &attr, &PyBool_Type, &ro, &PyBool_Type, &hd, &enumVals)) { + static const std::array kwlist {"type", + "name", + "group", + "doc", + "attr", + "read_only", + "hidden", + "enum_vals", + nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + kwd, + "ss|sethO!O!O", + kwlist, + &sType, + &sName, + &sGroup, + "utf-8", + &sDoc, + &attr, + &PyBool_Type, + &ro, + &PyBool_Type, + &hd, + &enumVals)) { return nullptr; } @@ -64,9 +83,13 @@ PyObject* DocumentPy::addProperty(PyObject *args, PyObject *kwd) PyMem_Free(sDoc); } - Property *prop = getDocumentPtr()-> - addDynamicProperty(sType,sName,sGroup,sDocStr.c_str(),attr, - Base::asBoolean(ro), Base::asBoolean(hd)); + Property* prop = getDocumentPtr()->addDynamicProperty(sType, + sName, + sGroup, + sDocStr.c_str(), + attr, + Base::asBoolean(ro), + Base::asBoolean(hd)); // enum support auto* propEnum = dynamic_cast(prop); @@ -77,11 +100,12 @@ PyObject* DocumentPy::addProperty(PyObject *args, PyObject *kwd) return Py::new_reference_to(this); } -PyObject* DocumentPy::removeProperty(PyObject *args) +PyObject* DocumentPy::removeProperty(PyObject* args) { - char *sName; - if (!PyArg_ParseTuple(args, "s", &sName)) + char* sName; + if (!PyArg_ParseTuple(args, "s", &sName)) { return nullptr; + } bool ok = getDocumentPtr()->removeDynamicProperty(sName); return Py_BuildValue("O", (ok ? Py_True : Py_False)); @@ -96,17 +120,20 @@ std::string DocumentPy::representation() const return str.str(); } -PyObject* DocumentPy::save(PyObject * args) +PyObject* DocumentPy::save(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { if (!getDocumentPtr()->save()) { PyErr_SetString(PyExc_ValueError, "Object attribute 'FileName' is not set"); return nullptr; } - } PY_CATCH; + } + PY_CATCH; const char* filename = getDocumentPtr()->FileName.getValue(); Base::FileInfo fi(filename); @@ -118,38 +145,45 @@ PyObject* DocumentPy::save(PyObject * args) Py_Return; } -PyObject* DocumentPy::saveAs(PyObject * args) +PyObject* DocumentPy::saveAs(PyObject* args) { char* fn; - if (!PyArg_ParseTuple(args, "et", "utf-8", &fn)) + if (!PyArg_ParseTuple(args, "et", "utf-8", &fn)) { return nullptr; + } std::string utf8Name = fn; PyMem_Free(fn); - PY_TRY { + PY_TRY + { getDocumentPtr()->saveAs(utf8Name.c_str()); Py_Return; - }PY_CATCH + } + PY_CATCH } -PyObject* DocumentPy::saveCopy(PyObject * args) +PyObject* DocumentPy::saveCopy(PyObject* args) { char* fn; - if (!PyArg_ParseTuple(args, "s", &fn)) + if (!PyArg_ParseTuple(args, "s", &fn)) { return nullptr; + } - PY_TRY { + PY_TRY + { getDocumentPtr()->saveCopy(fn); Py_Return; - }PY_CATCH + } + PY_CATCH } -PyObject* DocumentPy::load(PyObject * args) +PyObject* DocumentPy::load(PyObject* args) { - char* filename=nullptr; - if (!PyArg_ParseTuple(args, "s", &filename)) + char* filename = nullptr; + if (!PyArg_ParseTuple(args, "s", &filename)) { return nullptr; + } if (!filename || *filename == '\0') { PyErr_Format(PyExc_ValueError, "Path is empty"); return nullptr; @@ -163,17 +197,19 @@ PyObject* DocumentPy::load(PyObject * args) } try { getDocumentPtr()->restore(); - } catch (...) { + } + catch (...) { PyErr_Format(PyExc_IOError, "Reading from file '%s' failed", filename); return nullptr; } Py_Return; } -PyObject* DocumentPy::restore(PyObject * args) +PyObject* DocumentPy::restore(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } const char* filename = getDocumentPtr()->FileName.getValue(); if (!filename || *filename == '\0') { PyErr_Format(PyExc_ValueError, "Object attribute 'FileName' is not set"); @@ -186,7 +222,8 @@ PyObject* DocumentPy::restore(PyObject * args) } try { getDocumentPtr()->restore(); - } catch (...) { + } + catch (...) { PyErr_Format(PyExc_IOError, "Reading from file '%s' failed", filename); return nullptr; } @@ -195,61 +232,70 @@ PyObject* DocumentPy::restore(PyObject * args) PyObject* DocumentPy::isSaved(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getDocumentPtr()->isSaved(); return Py::new_reference_to(Py::Boolean(ok)); } PyObject* DocumentPy::getProgramVersion(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } const char* version = getDocumentPtr()->getProgramVersion(); return Py::new_reference_to(Py::String(version)); } PyObject* DocumentPy::getFileName(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } const char* fn = getDocumentPtr()->getFileName(); return Py::new_reference_to(Py::String(fn)); } -PyObject* DocumentPy::getUniqueObjectName(PyObject *args) +PyObject* DocumentPy::getUniqueObjectName(PyObject* args) { - char *sName; - if (!PyArg_ParseTuple(args, "s", &sName)) + char* sName; + if (!PyArg_ParseTuple(args, "s", &sName)) { return nullptr; - PY_TRY { - auto newName = getDocumentPtr()->getUniqueObjectName(sName); + } + PY_TRY + { + auto newName = getDocumentPtr()->getUniqueObjectName(sName); return Py::new_reference_to(Py::String(newName)); } PY_CATCH; } -PyObject* DocumentPy::mergeProject(PyObject * args) +PyObject* DocumentPy::mergeProject(PyObject* args) { char* filename; - if (!PyArg_ParseTuple(args, "s", &filename)) + if (!PyArg_ParseTuple(args, "s", &filename)) { return nullptr; + } - PY_TRY { + PY_TRY + { Base::FileInfo fi(filename); Base::ifstream str(fi, std::ios::in | std::ios::binary); App::Document* doc = getDocumentPtr(); MergeDocuments md(doc); md.importObjects(str); Py_Return; - } PY_CATCH; + } + PY_CATCH; } -PyObject* DocumentPy::exportGraphviz(PyObject * args) +PyObject* DocumentPy::exportGraphviz(PyObject* args) { - char* fn=nullptr; - if (!PyArg_ParseTuple(args, "|s",&fn)) + char* fn = nullptr; + if (!PyArg_ParseTuple(args, "|s", &fn)) { return nullptr; + } if (fn) { Base::FileInfo fi(fn); Base::ofstream str(fi); @@ -264,26 +310,36 @@ PyObject* DocumentPy::exportGraphviz(PyObject * args) } } -PyObject* DocumentPy::addObject(PyObject *args, PyObject *kwd) +PyObject* DocumentPy::addObject(PyObject* args, PyObject* kwd) { char *sType, *sName = nullptr, *sViewType = nullptr; - PyObject *obj = nullptr; - PyObject *view = nullptr; - PyObject *attach = Py_False; - static const std::array kwlist{"type", "name", "objProxy", "viewProxy", "attach", "viewType", - nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords(args, kwd, "s|sOOO!s", - kwlist, &sType, &sName, &obj, &view, &PyBool_Type, &attach, &sViewType)) { + PyObject* obj = nullptr; + PyObject* view = nullptr; + PyObject* attach = Py_False; + static const std::array + kwlist {"type", "name", "objProxy", "viewProxy", "attach", "viewType", nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + kwd, + "s|sOOO!s", + kwlist, + &sType, + &sName, + &obj, + &view, + &PyBool_Type, + &attach, + &sViewType)) { return nullptr; } - DocumentObject *pcFtr = nullptr; + DocumentObject* pcFtr = nullptr; if (!obj || !Base::asBoolean(attach)) { - pcFtr = getDocumentPtr()->addObject(sType,sName,true,sViewType); + pcFtr = getDocumentPtr()->addObject(sType, sName, true, sViewType); } else { - Base::Type type = Base::Type::getTypeIfDerivedFrom(sType, DocumentObject::getClassTypeId(), true); + Base::Type type = + Base::Type::getTypeIfDerivedFrom(sType, DocumentObject::getClassTypeId(), true); if (type.isBad()) { std::stringstream str; str << "'" << sType << "' is not a document object type"; @@ -310,7 +366,7 @@ PyObject* DocumentPy::addObject(PyObject *args, PyObject *kwd) pyftr.setAttr("Proxy", pyobj); if (Base::asBoolean(attach)) { - getDocumentPtr()->addObject(pcFtr,sName); + getDocumentPtr()->addObject(pcFtr, sName); try { Py::Callable method(pyobj.getAttr("attach")); @@ -328,10 +384,12 @@ PyObject* DocumentPy::addObject(PyObject *args, PyObject *kwd) // 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) + if (view) { pyvp = Py::Object(view); - if (pyvp.isNone()) + } + 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")); @@ -348,16 +406,17 @@ PyObject* DocumentPy::addObject(PyObject *args, PyObject *kwd) return pcFtr->getPyObject(); } -PyObject* DocumentPy::removeObject(PyObject *args) +PyObject* DocumentPy::removeObject(PyObject* args) { - char *sName; - if (!PyArg_ParseTuple(args, "s",&sName)) + char* sName; + if (!PyArg_ParseTuple(args, "s", &sName)) { return nullptr; + } - DocumentObject *pcFtr = getDocumentPtr()->getObject(sName); + DocumentObject* pcFtr = getDocumentPtr()->getObject(sName); if (pcFtr) { - getDocumentPtr()->removeObject( sName ); + getDocumentPtr()->removeObject(sName); Py_Return; } else { @@ -367,26 +426,29 @@ PyObject* DocumentPy::removeObject(PyObject *args) } } -PyObject* DocumentPy::copyObject(PyObject *args) +PyObject* DocumentPy::copyObject(PyObject* args) { - PyObject *obj, *rec=Py_False, *retAll=Py_False; - if (!PyArg_ParseTuple(args, "O|O!O!",&obj,&PyBool_Type,&rec,&PyBool_Type,&retAll)) + PyObject *obj, *rec = Py_False, *retAll = Py_False; + if (!PyArg_ParseTuple(args, "O|O!O!", &obj, &PyBool_Type, &rec, &PyBool_Type, &retAll)) { return nullptr; + } std::vector objs; bool single = false; if (PySequence_Check(obj)) { Py::Sequence seq(obj); - for (Py_ssize_t i=0;i(seq[i].ptr())->getDocumentObjectPtr()); } } - else if (!PyObject_TypeCheck(obj,&DocumentObjectPy::Type)) { - PyErr_SetString(PyExc_TypeError, + else if (!PyObject_TypeCheck(obj, &DocumentObjectPy::Type)) { + PyErr_SetString( + PyExc_TypeError, "Expect first argument to be either a document object or sequence of document objects"); return nullptr; } @@ -395,64 +457,79 @@ PyObject* DocumentPy::copyObject(PyObject *args) single = true; } - PY_TRY { - auto ret = getDocumentPtr()->copyObject(objs, Base::asBoolean(rec), Base::asBoolean(retAll)); - if (ret.size()==1 && single) + PY_TRY + { + auto ret = + getDocumentPtr()->copyObject(objs, Base::asBoolean(rec), Base::asBoolean(retAll)); + if (ret.size() == 1 && single) { return ret[0]->getPyObject(); + } Py::Tuple tuple(ret.size()); - for (size_t i=0;igetPyObject(),true)); + for (size_t i = 0; i < ret.size(); ++i) { + tuple.setItem(i, Py::Object(ret[i]->getPyObject(), true)); + } return Py::new_reference_to(tuple); - } PY_CATCH + } + PY_CATCH } -PyObject* DocumentPy::importLinks(PyObject *args) +PyObject* DocumentPy::importLinks(PyObject* args) { - PyObject *obj = Py_None; - if (!PyArg_ParseTuple(args, "|O",&obj)) + PyObject* obj = Py_None; + if (!PyArg_ParseTuple(args, "|O", &obj)) { return nullptr; + } std::vector objs; if (PySequence_Check(obj)) { Py::Sequence seq(obj); - for (Py_ssize_t i=0;i(seq[i].ptr())->getDocumentObjectPtr()); } } else { - Base::PyTypeCheck(&obj, &DocumentObjectPy::Type, - "Expect first argument to be either a document object, sequence of document objects or None"); - if (obj) + Base::PyTypeCheck(&obj, + &DocumentObjectPy::Type, + "Expect first argument to be either a document object, sequence of " + "document objects or None"); + if (obj) { objs.push_back(static_cast(obj)->getDocumentObjectPtr()); + } } - if (objs.empty()) + if (objs.empty()) { objs = getDocumentPtr()->getObjects(); + } - PY_TRY { + PY_TRY + { auto ret = getDocumentPtr()->importLinks(objs); Py::Tuple tuple(ret.size()); - for (size_t i=0;igetPyObject(),true)); + for (size_t i = 0; i < ret.size(); ++i) { + tuple.setItem(i, Py::Object(ret[i]->getPyObject(), true)); + } return Py::new_reference_to(tuple); } PY_CATCH } -PyObject* DocumentPy::moveObject(PyObject *args) +PyObject* DocumentPy::moveObject(PyObject* args) { - PyObject *obj, *rec=Py_False; - if (!PyArg_ParseTuple(args, "O!|O!",&(DocumentObjectPy::Type),&obj,&PyBool_Type,&rec)) + PyObject *obj, *rec = Py_False; + if (!PyArg_ParseTuple(args, "O!|O!", &(DocumentObjectPy::Type), &obj, &PyBool_Type, &rec)) { return nullptr; + } DocumentObjectPy* docObj = static_cast(obj); - DocumentObject* move = getDocumentPtr()->moveObject(docObj->getDocumentObjectPtr(), Base::asBoolean(rec)); + DocumentObject* move = + getDocumentPtr()->moveObject(docObj->getDocumentObjectPtr(), Base::asBoolean(rec)); if (move) { return move->getPyObject(); } @@ -462,11 +539,12 @@ PyObject* DocumentPy::moveObject(PyObject *args) } } -PyObject* DocumentPy::openTransaction(PyObject *args) +PyObject* DocumentPy::openTransaction(PyObject* args) { - PyObject *value = nullptr; - if (!PyArg_ParseTuple(args, "|O",&value)) + PyObject* value = nullptr; + if (!PyArg_ParseTuple(args, "|O", &value)) { return nullptr; + } std::string cmd; @@ -485,56 +563,65 @@ PyObject* DocumentPy::openTransaction(PyObject *args) Py_Return; } -PyObject* DocumentPy::abortTransaction(PyObject * args) +PyObject* DocumentPy::abortTransaction(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getDocumentPtr()->abortTransaction(); Py_Return; } -PyObject* DocumentPy::commitTransaction(PyObject * args) +PyObject* DocumentPy::commitTransaction(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getDocumentPtr()->commitTransaction(); Py_Return; } -Py::Boolean DocumentPy::getHasPendingTransaction() const { +Py::Boolean DocumentPy::getHasPendingTransaction() const +{ return {getDocumentPtr()->hasPendingTransaction()}; } -PyObject* DocumentPy::undo(PyObject * args) +PyObject* DocumentPy::undo(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; - if (getDocumentPtr()->getAvailableUndos()) + } + if (getDocumentPtr()->getAvailableUndos()) { getDocumentPtr()->undo(); + } Py_Return; } -PyObject* DocumentPy::redo(PyObject * args) +PyObject* DocumentPy::redo(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; - if (getDocumentPtr()->getAvailableRedos()) + } + if (getDocumentPtr()->getAvailableRedos()) { getDocumentPtr()->redo(); + } Py_Return; } -PyObject* DocumentPy::clearUndos(PyObject * args) +PyObject* DocumentPy::clearUndos(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getDocumentPtr()->clearUndos(); Py_Return; } -PyObject* DocumentPy::clearDocument(PyObject * args) +PyObject* DocumentPy::clearDocument(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getDocumentPtr()->clearDocument(); Py_Return; } @@ -542,52 +629,65 @@ PyObject* DocumentPy::clearDocument(PyObject * args) PyObject* DocumentPy::setClosable(PyObject* args) { PyObject* close; - if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &close)) + if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &close)) { return nullptr; + } getDocumentPtr()->setClosable(Base::asBoolean(close)); Py_Return; } PyObject* DocumentPy::isClosable(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getDocumentPtr()->isClosable(); return Py::new_reference_to(Py::Boolean(ok)); } -PyObject* DocumentPy::recompute(PyObject * args) +PyObject* DocumentPy::recompute(PyObject* args) { - PyObject *pyobjs = Py_None; - PyObject *force = Py_False; - PyObject *checkCycle = Py_False; - if (!PyArg_ParseTuple(args, "|OO!O!",&pyobjs, - &PyBool_Type,&force,&PyBool_Type,&checkCycle)) + PyObject* pyobjs = Py_None; + PyObject* force = Py_False; + PyObject* checkCycle = Py_False; + if (!PyArg_ParseTuple(args, + "|OO!O!", + &pyobjs, + &PyBool_Type, + &force, + &PyBool_Type, + &checkCycle)) { return nullptr; + } - PY_TRY { - std::vector objs; - if (pyobjs!=Py_None) { + PY_TRY + { + std::vector objs; + if (pyobjs != Py_None) { if (!PySequence_Check(pyobjs)) { PyErr_SetString(PyExc_TypeError, "expect input of sequence of document objects"); return nullptr; } Py::Sequence seq(pyobjs); - for (Py_ssize_t i=0;i(seq[i].ptr())->getDocumentObjectPtr()); + objs.push_back( + static_cast(seq[i].ptr())->getDocumentObjectPtr()); } } int options = 0; - if (Base::asBoolean(checkCycle)) + if (Base::asBoolean(checkCycle)) { options = Document::DepNoCycle; + } - int objectCount = getDocumentPtr()->recompute(objs, Base::asBoolean(force), nullptr, options); + int objectCount = + getDocumentPtr()->recompute(objs, Base::asBoolean(force), nullptr, options); // Document::recompute() hides possibly raised Python exceptions by its features // So, check if an error is set and return null if yes @@ -596,40 +696,44 @@ PyObject* DocumentPy::recompute(PyObject * args) } return Py::new_reference_to(Py::Int(objectCount)); - } PY_CATCH; + } + PY_CATCH; } PyObject* DocumentPy::mustExecute(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getDocumentPtr()->mustExecute(); return Py::new_reference_to(Py::Boolean(ok)); } PyObject* DocumentPy::isTouched(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getDocumentPtr()->isTouched(); return Py::new_reference_to(Py::Boolean(ok)); } PyObject* DocumentPy::purgeTouched(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getDocumentPtr()->purgeTouched(); Py_Return; } -PyObject* DocumentPy::getObject(PyObject *args) +PyObject* DocumentPy::getObject(PyObject* args) { DocumentObject* obj = nullptr; do { char* name = nullptr; - if (PyArg_ParseTuple(args, "s", &name)) { + if (PyArg_ParseTuple(args, "s", &name)) { obj = getDocumentPtr()->getObject(name); break; } @@ -643,41 +747,44 @@ PyObject* DocumentPy::getObject(PyObject *args) PyErr_SetString(PyExc_TypeError, "a string or integer is required"); return nullptr; - } - while (false); + } while (false); - if (obj) + if (obj) { return obj->getPyObject(); + } Py_Return; } -PyObject* DocumentPy::getObjectsByLabel(PyObject *args) +PyObject* DocumentPy::getObjectsByLabel(PyObject* args) { - char *sName; - if (!PyArg_ParseTuple(args, "s",&sName)) + char* sName; + if (!PyArg_ParseTuple(args, "s", &sName)) { return nullptr; + } Py::List list; std::string name = sName; std::vector objs = getDocumentPtr()->getObjects(); for (auto obj : objs) { - if (name == obj->Label.getValue()) + if (name == obj->Label.getValue()) { list.append(Py::asObject(obj->getPyObject())); + } } return Py::new_reference_to(list); } -PyObject* DocumentPy::findObjects(PyObject *args, PyObject *kwds) +PyObject* DocumentPy::findObjects(PyObject* args, PyObject* kwds) { const char *sType = "App::DocumentObject", *sName = nullptr, *sLabel = nullptr; - static const std::array kwlist{"Type", "Name", "Label", nullptr}; + static const std::array kwlist {"Type", "Name", "Label", nullptr}; if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "|sss", kwlist, &sType, &sName, &sLabel)) { return nullptr; } - Base::Type type = Base::Type::getTypeIfDerivedFrom(sType, App::DocumentObject::getClassTypeId(), true); + Base::Type type = + Base::Type::getTypeIfDerivedFrom(sType, App::DocumentObject::getClassTypeId(), true); if (type.isBad()) { std::stringstream str; str << "'" << sType << "' is not a document object type"; @@ -694,31 +801,36 @@ PyObject* DocumentPy::findObjects(PyObject *args, PyObject *kwds) return nullptr; } - Py_ssize_t index=0; + Py_ssize_t index = 0; PyObject* list = PyList_New((Py_ssize_t)res.size()); - for (std::vector::const_iterator It = res.begin();It != res.end();++It, index++) + for (std::vector::const_iterator It = res.begin(); It != res.end(); + ++It, index++) { PyList_SetItem(list, index, (*It)->getPyObject()); + } return list; } Py::Object DocumentPy::getActiveObject() const { - DocumentObject *pcFtr = getDocumentPtr()->getActiveObject(); - if (pcFtr) + DocumentObject* pcFtr = getDocumentPtr()->getActiveObject(); + if (pcFtr) { return Py::Object(pcFtr->getPyObject(), true); + } return Py::None(); } -PyObject* DocumentPy::supportedTypes(PyObject *args) +PyObject* DocumentPy::supportedTypes(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } std::vector ary; Base::Type::getAllDerivedFrom(App::DocumentObject::getClassTypeId(), ary); Py::List res; - for (const auto & it : ary) + for (const auto& it : ary) { res.append(Py::String(it.getName())); + } return Py::new_reference_to(res); } @@ -727,9 +839,11 @@ Py::List DocumentPy::getObjects() const std::vector objs = getDocumentPtr()->getObjects(); Py::List res; - for (auto obj : objs) - //Note: Here we must force the Py::Object to own this Python object as getPyObject() increments the counter + for (auto obj : objs) { + // Note: Here we must force the Py::Object to own this Python object as getPyObject() + // increments the counter res.append(Py::Object(obj->getPyObject(), true)); + } return res; } @@ -739,9 +853,11 @@ Py::List DocumentPy::getTopologicalSortedObjects() const std::vector objs = getDocumentPtr()->topologicalSort(); Py::List res; - for (auto obj : objs) - //Note: Here we must force the Py::Object to own this Python object as getPyObject() increments the counter + for (auto obj : objs) { + // Note: Here we must force the Py::Object to own this Python object as getPyObject() + // increments the counter res.append(Py::Object(obj->getPyObject(), true)); + } return res; } @@ -751,9 +867,11 @@ Py::List DocumentPy::getRootObjects() const std::vector objs = getDocumentPtr()->getRootObjects(); Py::List res; - for (auto obj : objs) - //Note: Here we must force the Py::Object to own this Python object as getPyObject() increments the counter + for (auto obj : objs) { + // Note: Here we must force the Py::Object to own this Python object as getPyObject() + // increments the counter res.append(Py::Object(obj->getPyObject(), true)); + } return res; } @@ -763,9 +881,11 @@ Py::List DocumentPy::getRootObjectsIgnoreLinks() const std::vector objs = getDocumentPtr()->getRootObjectsIgnoreLinks(); Py::List res; - for (auto obj : objs) - //Note: Here we must force the Py::Object to own this Python object as getPyObject() increments the counter + for (auto obj : objs) { + // Note: Here we must force the Py::Object to own this Python object as getPyObject() + // increments the counter res.append(Py::Object(obj->getPyObject(), true)); + } return res; } @@ -775,7 +895,7 @@ Py::Int DocumentPy::getUndoMode() const return Py::Int(getDocumentPtr()->getUndoMode()); } -void DocumentPy::setUndoMode(Py::Int arg) +void DocumentPy::setUndoMode(Py::Int arg) { getDocumentPtr()->setUndoMode(arg); } @@ -801,8 +921,9 @@ Py::List DocumentPy::getUndoNames() const std::vector vList = getDocumentPtr()->getAvailableUndoNames(); Py::List res; - for (const auto & It : vList) + for (const auto& It : vList) { res.append(Py::String(It)); + } return res; } @@ -812,13 +933,14 @@ Py::List DocumentPy::getRedoNames() const std::vector vList = getDocumentPtr()->getAvailableRedoNames(); Py::List res; - for (const auto & It : vList) + for (const auto& It : vList) { res.append(Py::String(It)); + } return res; } -Py::String DocumentPy::getDependencyGraph() const +Py::String DocumentPy::getDependencyGraph() const { std::stringstream out; getDocumentPtr()->exportGraphviz(out); @@ -840,11 +962,12 @@ void DocumentPy::setRecomputesFrozen(Py::Boolean arg) getDocumentPtr()->setStatus(Document::Status::SkipRecompute, arg.isTrue()); } -PyObject* DocumentPy::getTempFileName(PyObject *args) +PyObject* DocumentPy::getTempFileName(PyObject* args) { - PyObject *value; - if (!PyArg_ParseTuple(args, "O",&value)) + PyObject* value; + if (!PyArg_ParseTuple(args, "O", &value)) { return nullptr; + } std::string string; if (PyUnicode_Check(value)) { @@ -857,19 +980,20 @@ PyObject* DocumentPy::getTempFileName(PyObject *args) } // search for a temp file name in the document transient directory - Base::FileInfo fileName(Base::FileInfo::getTempFileName - (string.c_str(),getDocumentPtr()->TransientDir.getValue())); + Base::FileInfo fileName( + Base::FileInfo::getTempFileName(string.c_str(), getDocumentPtr()->TransientDir.getValue())); // delete the created file, we need only the name... fileName.deleteFile(); - PyObject *p = PyUnicode_DecodeUTF8(fileName.filePath().c_str(),fileName.filePath().size(),nullptr); + PyObject* p = + PyUnicode_DecodeUTF8(fileName.filePath().c_str(), fileName.filePath().size(), nullptr); if (!p) { throw Base::UnicodeError("UTF8 conversion failure at PropertyString::getPyObject()"); } return p; } -PyObject *DocumentPy::getCustomAttributes(const char* attr) const +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 @@ -877,21 +1001,24 @@ PyObject *DocumentPy::getCustomAttributes(const char* attr) const // 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) + if (prop) { return nullptr; + } if (!this->ob_type->tp_dict) { - if (PyType_Ready(this->ob_type) < 0) + if (PyType_Ready(this->ob_type) < 0) { return nullptr; + } } PyObject* item = PyDict_GetItemString(this->ob_type->tp_dict, attr); - if (item) + if (item) { return nullptr; + } // search for an object with this name DocumentObject* obj = getDocumentPtr()->getObject(attr); return (obj ? obj->getPyObject() : nullptr); } -int DocumentPy::setCustomAttributes(const char* attr, PyObject *) +int DocumentPy::setCustomAttributes(const char* attr, PyObject*) { // Note: Here we want to return only a document object if its // name matches 'attr'. However, it is possible to have an object @@ -899,21 +1026,22 @@ int DocumentPy::setCustomAttributes(const char* attr, PyObject *) // 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) + if (prop) { return 0; + } if (!this->ob_type->tp_dict) { - if (PyType_Ready(this->ob_type) < 0) + if (PyType_Ready(this->ob_type) < 0) { return 0; + } } PyObject* item = PyDict_GetItemString(this->ob_type->tp_dict, attr); - if (item) + if (item) { return 0; + } DocumentObject* obj = getDocumentPtr()->getObject(attr); - if (obj) - { + if (obj) { std::stringstream str; - str << "'Document' object attribute '" << attr - << "' must not be set this way" << std::ends; + str << "'Document' object attribute '" << attr << "' must not be set this way" << std::ends; PyErr_SetString(PyExc_RuntimeError, str.str().c_str()); return -1; } @@ -921,26 +1049,32 @@ int DocumentPy::setCustomAttributes(const char* attr, PyObject *) return 0; } -PyObject* DocumentPy::getLinksTo(PyObject *args) +PyObject* DocumentPy::getLinksTo(PyObject* args) { - PyObject *pyobj = Py_None; + PyObject* pyobj = Py_None; int options = 0; short count = 0; - if (!PyArg_ParseTuple(args, "|Oih", &pyobj,&options, &count)) + if (!PyArg_ParseTuple(args, "|Oih", &pyobj, &options, &count)) { return nullptr; + } - PY_TRY { - Base::PyTypeCheck(&pyobj, &DocumentObjectPy::Type, "Expect the first argument of type document object"); - DocumentObject *obj = nullptr; - if (pyobj) + PY_TRY + { + Base::PyTypeCheck(&pyobj, + &DocumentObjectPy::Type, + "Expect the first argument of type document object"); + DocumentObject* obj = nullptr; + if (pyobj) { obj = static_cast(pyobj)->getDocumentObjectPtr(); + } - std::set links; - getDocumentPtr()->getLinksTo(links,obj,options,count); + std::set links; + getDocumentPtr()->getLinksTo(links, obj, options, count); Py::Tuple ret(links.size()); - int i=0; - for (auto o : links) - ret.setItem(i++,Py::Object(o->getPyObject(),true)); + int i = 0; + for (auto o : links) { + ret.setItem(i++, Py::Object(o->getPyObject(), true)); + } return Py::new_reference_to(ret); } @@ -951,9 +1085,10 @@ Py::List DocumentPy::getInList() const { Py::List ret; auto lists = PropertyXLink::getDocumentInList(getDocumentPtr()); - if (lists.size()==1) { - for (auto doc : lists.begin()->second) + if (lists.size() == 1) { + for (auto doc : lists.begin()->second) { ret.append(Py::Object(doc->getPyObject(), true)); + } } return ret; } @@ -962,24 +1097,30 @@ Py::List DocumentPy::getOutList() const { Py::List ret; auto lists = PropertyXLink::getDocumentOutList(getDocumentPtr()); - if (lists.size()==1) { - for (auto doc : lists.begin()->second) + if (lists.size() == 1) { + for (auto doc : lists.begin()->second) { ret.append(Py::Object(doc->getPyObject(), true)); + } } return ret; } -PyObject *DocumentPy::getDependentDocuments(PyObject *args) { - PyObject *sort = Py_True; - if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &sort)) +PyObject* DocumentPy::getDependentDocuments(PyObject* args) +{ + PyObject* sort = Py_True; + if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &sort)) { return nullptr; - PY_TRY { + } + PY_TRY + { auto docs = getDocumentPtr()->getDependentDocuments(Base::asBoolean(sort)); Py::List ret; - for (auto doc : docs) + for (auto doc : docs) { ret.append(Py::Object(doc->getPyObject(), true)); + } return Py::new_reference_to(ret); - } PY_CATCH; + } + PY_CATCH; } Py::Boolean DocumentPy::getRestoring() const diff --git a/src/App/DynamicProperty.cpp b/src/App/DynamicProperty.cpp index cc21764ada..f79ecd5650 100644 --- a/src/App/DynamicProperty.cpp +++ b/src/App/DynamicProperty.cpp @@ -33,7 +33,7 @@ #include "PropertyContainer.h" -FC_LOG_LEVEL_INIT("Property",true,true) +FC_LOG_LEVEL_INIT("Property", true, true) using namespace App; @@ -46,65 +46,75 @@ DynamicProperty::~DynamicProperty() clear(); } -void DynamicProperty::clear() { - auto &index = props.get<0>(); - for(auto &v : index) +void DynamicProperty::clear() +{ + auto& index = props.get<0>(); + for (auto& v : index) { delete v.property; + } index.clear(); } -void DynamicProperty::getPropertyList(std::vector &List) const +void DynamicProperty::getPropertyList(std::vector& List) const { - for (auto &v : props.get<0>()) + for (auto& v : props.get<0>()) { List.push_back(v.property); + } } -void DynamicProperty::getPropertyNamedList(std::vector > &List) const +void DynamicProperty::getPropertyNamedList( + std::vector>& List) const { - for (auto &v : props.get<0>()) - List.emplace_back(v.getName(),v.property); + for (auto& v : props.get<0>()) { + List.emplace_back(v.getName(), v.property); + } } -void DynamicProperty::getPropertyMap(std::map &Map) const +void DynamicProperty::getPropertyMap(std::map& Map) const { - for (auto &v : props.get<0>()) + for (auto& v : props.get<0>()) { Map[v.name] = v.property; + } } -Property *DynamicProperty::getDynamicPropertyByName(const char* name) const +Property* DynamicProperty::getDynamicPropertyByName(const char* name) const { - auto &index = props.get<0>(); + auto& index = props.get<0>(); auto it = index.find(name); - if (it != index.end()) + if (it != index.end()) { return it->property; + } return nullptr; } std::vector DynamicProperty::getDynamicPropertyNames() const { std::vector names; - auto &index = props.get<0>(); + auto& index = props.get<0>(); names.reserve(index.size()); - for(auto &v : index) + for (auto& v : index) { names.push_back(v.name); + } return names; } short DynamicProperty::getPropertyType(const Property* prop) const { - return prop?prop->getType():0; + return prop ? prop->getType() : 0; } -short DynamicProperty::getPropertyType(const char *name) const +short DynamicProperty::getPropertyType(const char* name) const { - auto &index = props.get<0>(); + auto& index = props.get<0>(); auto it = index.find(name); if (it != index.end()) { short attr = it->attr; - if (it->hidden) + if (it->hidden) { attr |= Prop_Hidden; - if (it->readonly) + } + if (it->readonly) { attr |= Prop_ReadOnly; + } return attr; } return 0; @@ -112,92 +122,113 @@ short DynamicProperty::getPropertyType(const char *name) const const char* DynamicProperty::getPropertyGroup(const Property* prop) const { - auto &index = props.get<1>(); + auto& index = props.get<1>(); auto it = index.find(const_cast(prop)); - if(it!=index.end()) + if (it != index.end()) { return it->group.c_str(); + } return nullptr; } -const char* DynamicProperty::getPropertyGroup(const char *name) const +const char* DynamicProperty::getPropertyGroup(const char* name) const { - auto &index = props.get<0>(); + auto& index = props.get<0>(); auto it = index.find(name); - if (it != index.end()) + if (it != index.end()) { return it->group.c_str(); + } return nullptr; } const char* DynamicProperty::getPropertyDocumentation(const Property* prop) const { - auto &index = props.get<1>(); + auto& index = props.get<1>(); auto it = index.find(const_cast(prop)); - if(it!=index.end()) + if (it != index.end()) { return it->doc.c_str(); + } return nullptr; } -const char* DynamicProperty::getPropertyDocumentation(const char *name) const +const char* DynamicProperty::getPropertyDocumentation(const char* name) const { - auto &index = props.get<0>(); + auto& index = props.get<0>(); auto it = index.find(name); - if (it != index.end()) + if (it != index.end()) { return it->doc.c_str(); + } return nullptr; } -Property* DynamicProperty::addDynamicProperty(PropertyContainer &pc, const char* type, - const char* name, const char* group, const char* doc, short attr, bool ro, bool hidden) +Property* DynamicProperty::addDynamicProperty(PropertyContainer& pc, + const char* type, + const char* name, + const char* group, + const char* doc, + short attr, + bool ro, + bool hidden) { - if(!type) + if (!type) { type = ""; + } std::string _name; - static ParameterGrp::handle hGrp = GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Document"); - if(hGrp->GetBool("AutoNameDynamicProperty",false)) { - if(!name || !name[0]) + static ParameterGrp::handle hGrp = + GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document"); + if (hGrp->GetBool("AutoNameDynamicProperty", false)) { + if (!name || !name[0]) { name = type; - _name = getUniquePropertyName(pc,name); - if(_name != name) { - FC_WARN(pc.getFullName() << " rename dynamic property from '" - << name << "' to '" << _name << "'"); + } + _name = getUniquePropertyName(pc, name); + if (_name != name) { + FC_WARN(pc.getFullName() + << " rename dynamic property from '" << name << "' to '" << _name << "'"); } name = _name.c_str(); - } else if(!name) - name = ""; // setting a bad name to trigger exception + } + else if (!name) { + name = ""; // setting a bad name to trigger exception + } auto prop = pc.getPropertyByName(name); - if(prop && prop->getContainer()==&pc) - FC_THROWM(Base::NameError, "Property " << pc.getFullName() << '.' << name << " already exists"); + if (prop && prop->getContainer() == &pc) { + FC_THROWM(Base::NameError, + "Property " << pc.getFullName() << '.' << name << " already exists"); + } - if(Base::Tools::getIdentifier(name) != name) + if (Base::Tools::getIdentifier(name) != name) { FC_THROWM(Base::NameError, "Invalid property name '" << name << "'"); + } - Base::Type propType = Base::Type::getTypeIfDerivedFrom(type, App::Property::getClassTypeId(), true); + Base::Type propType = + Base::Type::getTypeIfDerivedFrom(type, App::Property::getClassTypeId(), true); if (propType.isBad()) { - FC_THROWM(Base::TypeError, "Invalid type " - << type << " for property " << pc.getFullName() << '.' << name); + FC_THROWM(Base::TypeError, + "Invalid type " << type << " for property " << pc.getFullName() << '.' << name); } void* propInstance = propType.createInstance(); if (!propInstance) { - FC_THROWM(Base::RuntimeError, "Failed to create property " - << pc.getFullName() << '.' << name << " of type " << type); + FC_THROWM(Base::RuntimeError, + "Failed to create property " << pc.getFullName() << '.' << name << " of type " + << type); } Property* pcProperty = static_cast(propInstance); - auto res = props.get<0>().emplace(pcProperty,name, nullptr, group, doc, attr, ro, hidden); + auto res = props.get<0>().emplace(pcProperty, name, nullptr, group, doc, attr, ro, hidden); pcProperty->setContainer(&pc); pcProperty->myName = res.first->name.c_str(); - if(ro) + if (ro) { attr |= Prop_ReadOnly; - if(hidden) + } + if (hidden) { attr |= Prop_Hidden; + } pcProperty->syncType(attr); pcProperty->StatusBits.set((size_t)Property::PropDynamic); @@ -207,21 +238,29 @@ Property* DynamicProperty::addDynamicProperty(PropertyContainer &pc, const char* return pcProperty; } -bool DynamicProperty::addProperty(Property *prop) +bool DynamicProperty::addProperty(Property* prop) { - if(!prop || !prop->hasName()) + if (!prop || !prop->hasName()) { return false; - auto &index = props.get<0>(); - if(index.count(prop->getName())) + } + auto& index = props.get<0>(); + if (index.count(prop->getName())) { return false; - index.emplace(prop,std::string(),prop->getName(), - prop->getGroup(),prop->getDocumentation(),prop->getType(),false,false); + } + index.emplace(prop, + std::string(), + prop->getName(), + prop->getGroup(), + prop->getDocumentation(), + prop->getType(), + false, + false); return true; } -bool DynamicProperty::removeProperty(const Property *prop) +bool DynamicProperty::removeProperty(const Property* prop) { - auto &index = props.get<1>(); + auto& index = props.get<1>(); auto it = index.find(const_cast(prop)); if (it != index.end()) { index.erase(it); @@ -232,14 +271,16 @@ bool DynamicProperty::removeProperty(const Property *prop) bool DynamicProperty::removeDynamicProperty(const char* name) { - auto &index = props.get<0>(); + auto& index = props.get<0>(); auto it = index.find(name); if (it != index.end()) { - if(it->property->testStatus(Property::LockDynamic)) + if (it->property->testStatus(Property::LockDynamic)) { throw Base::RuntimeError("property is locked"); - else if(!it->property->testStatus(Property::PropDynamic)) + } + else if (!it->property->testStatus(Property::PropDynamic)) { throw Base::RuntimeError("property is not dynamic"); - Property *prop = it->property; + } + Property* prop = it->property; GetApplication().signalRemoveDynamicProperty(*prop); // Handle possible recursive calls of removeDynamicProperty @@ -255,12 +296,12 @@ bool DynamicProperty::removeDynamicProperty(const char* name) return false; } -std::string DynamicProperty::getUniquePropertyName(PropertyContainer &pc, const char *Name) const +std::string DynamicProperty::getUniquePropertyName(PropertyContainer& pc, const char* Name) const { std::string CleanName = Base::Tools::getIdentifier(Name); // name in use? - std::map objectProps; + std::map objectProps; pc.getPropertyMap(objectProps); auto pos = objectProps.find(CleanName); @@ -271,38 +312,42 @@ std::string DynamicProperty::getUniquePropertyName(PropertyContainer &pc, const else { std::vector names; names.reserve(objectProps.size()); - for (pos = objectProps.begin();pos != objectProps.end();++pos) { + for (pos = objectProps.begin(); pos != objectProps.end(); ++pos) { names.push_back(pos->first); } return Base::Tools::getUniqueName(CleanName, names); } } -void DynamicProperty::save(const Property *prop, Base::Writer &writer) const +void DynamicProperty::save(const Property* prop, Base::Writer& writer) const { - auto &index = props.get<1>(); + auto& index = props.get<1>(); auto it = index.find(const_cast(prop)); - if(it != index.end()) { - auto &data = *it; + if (it != index.end()) { + auto& data = *it; writer.Stream() << "\" group=\"" << Base::Persistence::encodeAttribute(data.group) << "\" doc=\"" << Base::Persistence::encodeAttribute(data.doc) - << "\" attr=\"" << data.attr << "\" ro=\"" << data.readonly - << "\" hide=\"" << data.hidden; + << "\" attr=\"" << data.attr << "\" ro=\"" << data.readonly << "\" hide=\"" + << data.hidden; } } -Property *DynamicProperty::restore(PropertyContainer &pc, - const char *PropName, const char *TypeName, Base::XMLReader &reader) +Property* DynamicProperty::restore(PropertyContainer& pc, + const char* PropName, + const char* TypeName, + Base::XMLReader& reader) { - if (!reader.hasAttribute("group")) + if (!reader.hasAttribute("group")) { return nullptr; + } short attribute = 0; bool readonly = false, hidden = false; - const char *group=nullptr, *doc=nullptr, *attr=nullptr, *ro=nullptr, *hide=nullptr; + const char *group = nullptr, *doc = nullptr, *attr = nullptr, *ro = nullptr, *hide = nullptr; group = reader.getAttribute("group"); - if (reader.hasAttribute("doc")) + if (reader.hasAttribute("doc")) { doc = reader.getAttribute("doc"); + } if (reader.hasAttribute("attr")) { attr = reader.getAttribute("attr"); if (attr) { @@ -312,42 +357,54 @@ Property *DynamicProperty::restore(PropertyContainer &pc, } if (reader.hasAttribute("ro")) { ro = reader.getAttribute("ro"); - if (ro) readonly = (ro[0]-48) != 0; + if (ro) { + readonly = (ro[0] - 48) != 0; + } } if (reader.hasAttribute("hide")) { hide = reader.getAttribute("hide"); - if (hide) hidden = (hide[0]-48) != 0; + if (hide) { + hidden = (hide[0] - 48) != 0; + } } - return addDynamicProperty(pc,TypeName, PropName, group, doc, attribute, readonly, hidden); + return addDynamicProperty(pc, TypeName, PropName, group, doc, attribute, readonly, hidden); } -DynamicProperty::PropData DynamicProperty::getDynamicPropertyData(const Property *prop) const +DynamicProperty::PropData DynamicProperty::getDynamicPropertyData(const Property* prop) const { - auto &index = props.get<1>(); + auto& index = props.get<1>(); auto it = index.find(const_cast(prop)); - if(it != index.end()) + if (it != index.end()) { return *it; + } return {}; } -bool DynamicProperty::changeDynamicProperty(const Property *prop, const char *group, const char *doc) { - auto &index = props.get<1>(); +bool DynamicProperty::changeDynamicProperty(const Property* prop, + const char* group, + const char* doc) +{ + auto& index = props.get<1>(); auto it = index.find(const_cast(prop)); - if (it == index.end()) + if (it == index.end()) { return false; - if(group) + } + if (group) { it->group = group; - if(doc) + } + if (doc) { it->doc = doc; + } return true; } -const char *DynamicProperty::getPropertyName(const Property *prop) const +const char* DynamicProperty::getPropertyName(const Property* prop) const { - auto &index = props.get<1>(); + auto& index = props.get<1>(); auto it = index.find(const_cast(prop)); - if(it != index.end()) + if (it != index.end()) { return it->getName(); + } return nullptr; } diff --git a/src/App/DynamicProperty.h b/src/App/DynamicProperty.h index a292f74c8e..6a2caf1d11 100644 --- a/src/App/DynamicProperty.h +++ b/src/App/DynamicProperty.h @@ -35,11 +35,12 @@ #include -namespace Base { +namespace Base +{ class Writer; class XMLReader; class XMLWriter; -} +} // namespace Base namespace App { @@ -48,15 +49,24 @@ class PropertyContainer; namespace bmi = boost::multi_index; -struct CStringHasher { - inline std::size_t operator()(const char *s) const { - if(!s) return 0; - return boost::hash_range(s,s+std::strlen(s)); +struct CStringHasher +{ + inline std::size_t operator()(const char* s) const + { + if (!s) { + return 0; + } + return boost::hash_range(s, s + std::strlen(s)); } - inline bool operator()(const char *a, const char *b) const { - if(!a) return !b; - if(!b) return false; - return std::strcmp(a,b)==0; + inline bool operator()(const char* a, const char* b) const + { + if (!a) { + return !b; + } + if (!b) { + return false; + } + return std::strcmp(a, b) == 0; } }; @@ -73,13 +83,13 @@ public: /** @name Access properties */ //@{ /// Get all properties of the class (including parent) - void getPropertyList(std::vector &List) const; + void getPropertyList(std::vector& List) const; /// get all properties with their names - void getPropertyNamedList(std::vector > &List) const; + void getPropertyNamedList(std::vector>& List) const; /// Get all properties of the class (including parent) - void getPropertyMap(std::map &Map) const; + void getPropertyMap(std::map& Map) const; /// Find a dynamic property by its name - Property *getDynamicPropertyByName(const char* name) const; + Property* getDynamicPropertyByName(const char* name) const; /*! Add a dynamic property of the type @a type and with the name @a name. @a Group gives the grouping name which appears in the property editor and @@ -97,22 +107,28 @@ public: addDynamicProperty(..., ..., "Base","blah", Prop_None, true, true); @endcode */ - Property* addDynamicProperty(PropertyContainer &pc, const char* type, const char* name=nullptr, const char* group=nullptr, - const char* doc=nullptr, short attr=0, bool ro=false, bool hidden=false); + Property* addDynamicProperty(PropertyContainer& pc, + const char* type, + const char* name = nullptr, + const char* group = nullptr, + const char* doc = nullptr, + short attr = 0, + bool ro = false, + bool hidden = false); /** Add a pre-existing property * * The property is not treated as dynamic, and will not trigger signal. * * @return Return false if there is a property exist with the same name. */ - bool addProperty(Property *prop); + bool addProperty(Property* prop); /*! - Removes a dynamic property by name. Returns true if the property is part of the container, otherwise - false is returned. + Removes a dynamic property by name. Returns true if the property is part of the container, + otherwise false is returned. */ bool removeDynamicProperty(const char* name); /// Remove pre-existing property, which will not be deleted. - bool removeProperty(const Property *prop); + bool removeProperty(const Property* prop); /// Get a list of all dynamic properties. std::vector getDynamicPropertyNames() const; /// Get the name of a property @@ -124,72 +140,86 @@ public: /// Get the attributes of a property short getPropertyType(const Property* prop) const; /// Get the attributes of a named property - short getPropertyType(const char *name) const; + short getPropertyType(const char* name) const; /// Get the group name of a property const char* getPropertyGroup(const Property* prop) const; /// Get the group name of a named property - const char* getPropertyGroup(const char *name) const; + const char* getPropertyGroup(const char* name) const; /// Get the documentation of a property const char* getPropertyDocumentation(const Property* prop) const; /// Get the documentation of a named property - const char* getPropertyDocumentation(const char *name) const; + const char* getPropertyDocumentation(const char* name) const; //@} /// Remove all properties void clear(); /// Get property count - size_t size() const { return props.size(); } + size_t size() const + { + return props.size(); + } - void save(const Property *prop, Base::Writer &writer) const; + void save(const Property* prop, Base::Writer& writer) const; - Property *restore(PropertyContainer &pc, - const char *PropName, const char *TypeName, Base::XMLReader &reader); + Property* restore(PropertyContainer& pc, + const char* PropName, + const char* TypeName, + Base::XMLReader& reader); - struct PropData { + struct PropData + { Property* property; std::string name; - const char *pName; + const char* pName; mutable std::string group; mutable std::string doc; short attr; bool readonly; bool hidden; - PropData(Property *prop=nullptr, std::string &&n=std::string(), const char *pn=nullptr, - const char *g=nullptr, const char *d=nullptr, short a=0, bool ro=false, bool h=false) - :property(prop),name(std::move(n)),pName(pn) - ,group(g?g:""),doc(d?d:""),attr(a),readonly(ro),hidden(h) + PropData(Property* prop = nullptr, + std::string&& n = std::string(), + const char* pn = nullptr, + const char* g = nullptr, + const char* d = nullptr, + short a = 0, + bool ro = false, + bool h = false) + : property(prop) + , name(std::move(n)) + , pName(pn) + , group(g ? g : "") + , doc(d ? d : "") + , attr(a) + , readonly(ro) + , hidden(h) {} - const char *getName() const { - return pName?pName:name.c_str(); + const char* getName() const + { + return pName ? pName : name.c_str(); } }; PropData getDynamicPropertyData(const Property* prop) const; - bool changeDynamicProperty(const Property *prop, const char *group, const char *doc); + bool changeDynamicProperty(const Property* prop, const char* group, const char* doc); private: - std::string getUniquePropertyName(PropertyContainer &pc, const char *Name) const; + std::string getUniquePropertyName(PropertyContainer& pc, const char* Name) const; private: bmi::multi_index_container< PropData, bmi::indexed_by< - bmi::hashed_unique< - bmi::const_mem_fun, - CStringHasher, - CStringHasher - >, - bmi::hashed_unique< - bmi::member - > - > - > props; + bmi::hashed_unique, + CStringHasher, + CStringHasher>, + bmi::hashed_unique>>> + props; }; -} // namespace App +} // namespace App -#endif // APP_DYNAMICPROPERTY_H +#endif // APP_DYNAMICPROPERTY_H diff --git a/src/App/ElementMap.cpp b/src/App/ElementMap.cpp index 4a2545e388..9e69c434be 100644 --- a/src/App/ElementMap.cpp +++ b/src/App/ElementMap.cpp @@ -18,7 +18,7 @@ #include -FC_LOG_LEVEL_INIT("ElementMap", true, 2);// NOLINT +FC_LOG_LEVEL_INIT("ElementMap", true, 2); // NOLINT namespace Data { @@ -104,7 +104,8 @@ void ElementMap::beforeSave(const ::App::StringHasherRef& hasherRef) const } } -void ElementMap::save(std::ostream& stream, int index, +void ElementMap::save(std::ostream& stream, + int index, const std::map& childMapSet, const std::map& postfixMap) const { @@ -121,7 +122,7 @@ void ElementMap::save(std::ostream& stream, int index, if (child.elementMap) { auto it = childMapSet.find(child.elementMap.get()); if (it == childMapSet.end() || it->second == 0) { - FC_ERR("Invalid child element map");// NOLINT + FC_ERR("Invalid child element map"); // NOLINT } else { mapIndex = it->second; @@ -240,7 +241,7 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream int count = 0; std::string tmp; if (!(stream >> id >> tmp >> count) || tmp != "PostfixCount") { - FC_THROWM(Base::RuntimeError, msg);// NOLINT + FC_THROWM(Base::RuntimeError, msg); // NOLINT } auto& map = _idToElementMap[id]; @@ -258,7 +259,7 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream std::vector childMaps; count = 0; if (!(stream >> tmp >> count) || tmp != "MapCount" || count == 0) { - FC_THROWM(Base::RuntimeError, msg);// NOLINT + FC_THROWM(Base::RuntimeError, msg); // NOLINT } childMaps.reserve(count - 1); for (int i = 0; i < count - 1; ++i) { @@ -269,7 +270,8 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream return restore(hasherRef, stream, childMaps, postfixes); } -ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream& stream, +ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, + std::istream& stream, std::vector& childMaps, const std::vector& postfixes) { @@ -281,14 +283,14 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream int typeCount = 0; unsigned id = 0; if (!(stream >> tmp >> index >> id >> typeCount) || tmp != "ElementMap") { - FC_THROWM(Base::RuntimeError, msg);// NOLINT + FC_THROWM(Base::RuntimeError, msg); // NOLINT } auto& map = _idToElementMap[id]; if (map) { while (tmp != "EndMap") { if (!std::getline(stream, tmp)) { - FC_THROWM(Base::RuntimeError, "unexpected end of child element map");// NOLINT + FC_THROWM(Base::RuntimeError, "unexpected end of child element map"); // NOLINT } } return map; @@ -303,12 +305,12 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream for (int i = 0; i < typeCount; ++i) { int outerCount = 0; if (!(stream >> tmp)) { - FC_THROWM(Base::RuntimeError, "missing element type");// NOLINT + FC_THROWM(Base::RuntimeError, "missing element type"); // NOLINT } IndexedName idx(tmp.c_str(), 1); if (!(stream >> tmp >> outerCount) || tmp != "ChildCount") { - FC_THROWM(Base::RuntimeError, "missing element child count");// NOLINT + FC_THROWM(Base::RuntimeError, "missing element child count"); // NOLINT } auto& indices = this->indexedNames[idx.getType()]; @@ -319,16 +321,16 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream long tag = 0; int mapIndex = 0; if (!(stream >> cIndex >> offset >> count >> tag >> mapIndex >> tmp)) { - FC_THROWM(Base::RuntimeError, "Invalid element child");// NOLINT + FC_THROWM(Base::RuntimeError, "Invalid element child"); // NOLINT } if (cIndex < 0) { - FC_THROWM(Base::RuntimeError, "Invalid element child index");// NOLINT + FC_THROWM(Base::RuntimeError, "Invalid element child index"); // NOLINT } if (offset < 0) { - FC_THROWM(Base::RuntimeError, "Invalid element child offset");// NOLINT + FC_THROWM(Base::RuntimeError, "Invalid element child offset"); // NOLINT } if (mapIndex >= index || mapIndex < 0 || mapIndex > (int)childMaps.size()) { - FC_THROWM(Base::RuntimeError, "Invalid element child map index");// NOLINT + FC_THROWM(Base::RuntimeError, "Invalid element child map index"); // NOLINT } auto& child = indices.children[cIndex + offset + count]; child.indexedName = IndexedName::fromConst(idx.getType(), cIndex); @@ -346,7 +348,7 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream this->childElementSize += child.count; if (!(stream >> tmp)) { - FC_THROWM(Base::RuntimeError, "Invalid element child string id");// NOLINT + FC_THROWM(Base::RuntimeError, "Invalid element child string id"); // NOLINT } tokens.clear(); @@ -371,7 +373,7 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream } if (!(stream >> tmp >> outerCount) || tmp != "NameCount") { - FC_THROWM(Base::RuntimeError, "missing element name outerCount");// NOLINT + FC_THROWM(Base::RuntimeError, "missing element name outerCount"); // NOLINT } boost::io::ios_flags_saver ifs(stream); @@ -384,7 +386,7 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream int innerCount = 0; while (true) { if (!(stream >> tmp)) { - FC_THROWM(Base::RuntimeError, "Failed to read element name");// NOLINT + FC_THROWM(Base::RuntimeError, "Failed to read element name"); // NOLINT } if (tmp == "0") { break; @@ -396,7 +398,7 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream tokens.clear(); boost::split(tokens, tmp, boost::is_any_of(".")); if (tokens.size() < 2) { - FC_THROWM(Base::RuntimeError, "Invalid element entry");// NOLINT + FC_THROWM(Base::RuntimeError, "Invalid element entry"); // NOLINT } int offset = 1; @@ -406,12 +408,12 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream switch (tokens[0][0]) { case ':': { if (tokens.size() < 3) { - FC_THROWM(Base::RuntimeError, "Invalid element entry");// NOLINT + FC_THROWM(Base::RuntimeError, "Invalid element entry"); // NOLINT } ++offset; long elementNameIndex = strtol(tokens[0].c_str() + 1, nullptr, hexBase); if (elementNameIndex <= 0 || elementNameIndex > (int)postfixes.size()) { - FC_THROWM(Base::RuntimeError, "Invalid element name index");// NOLINT + FC_THROWM(Base::RuntimeError, "Invalid element name index"); // NOLINT } long elementIndex = strtol(tokens[1].c_str(), nullptr, hexBase); ref->name = MappedName( @@ -427,7 +429,7 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream ref->name = MappedName(tokens[0].c_str() + 1); break; default: - FC_THROWM(Base::RuntimeError, "Invalid element name marker");// NOLINT + FC_THROWM(Base::RuntimeError, "Invalid element name marker"); // NOLINT } if (tokens[offset] != "0") { @@ -473,31 +475,34 @@ ElementMapPtr ElementMap::restore(::App::StringHasherRef hasherRef, std::istream } } if (hasherWarn) { - FC_WARN(hasherWarn);// NOLINT + FC_WARN(hasherWarn); // NOLINT } if (hasherIDWarn) { - FC_WARN(hasherIDWarn);// NOLINT + FC_WARN(hasherIDWarn); // NOLINT } if (postfixWarn) { - FC_WARN(postfixWarn);// NOLINT + FC_WARN(postfixWarn); // NOLINT } if (childSIDWarn) { - FC_WARN(childSIDWarn);// NOLINT + FC_WARN(childSIDWarn); // NOLINT } if (!(stream >> tmp) || tmp != "EndMap") { - FC_THROWM(Base::RuntimeError, "unexpected end of child element map");// NOLINT + FC_THROWM(Base::RuntimeError, "unexpected end of child element map"); // NOLINT } return shared_from_this(); } -MappedName ElementMap::addName(MappedName& name, const IndexedName& idx, const ElementIDRefs& sids, - bool overwrite, IndexedName* existing) +MappedName ElementMap::addName(MappedName& name, + const IndexedName& idx, + const ElementIDRefs& sids, + bool overwrite, + IndexedName* existing) { if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) { if (name.find("#") >= 0 && name.findTagInElementName() < 0) { - FC_ERR("missing tag postfix " << name);// NOLINT + FC_ERR("missing tag postfix " << name); // NOLINT } } while (true) { @@ -505,14 +510,14 @@ MappedName ElementMap::addName(MappedName& name, const IndexedName& idx, const E erase(idx); } auto ret = mappedNames.insert(std::make_pair(name, idx)); - if (ret.second) { // element just inserted did not exist yet in the map - ret.first->first.compact();// FIXME see MappedName.cpp + if (ret.second) { // element just inserted did not exist yet in the map + ret.first->first.compact(); // FIXME see MappedName.cpp mappedRef(idx).append(ret.first->first, sids); - FC_TRACE(idx << " -> " << name);// NOLINT + FC_TRACE(idx << " -> " << name); // NOLINT return ret.first->first; } if (ret.first->second == idx) { - FC_TRACE("duplicate " << idx << " -> " << name);// NOLINT + FC_TRACE("duplicate " << idx << " -> " << name); // NOLINT return ret.first->first; } if (!overwrite) { @@ -526,7 +531,8 @@ MappedName ElementMap::addName(MappedName& name, const IndexedName& idx, const E }; } -void ElementMap::addPostfix(const QByteArray& postfix, std::map& postfixMap, +void ElementMap::addPostfix(const QByteArray& postfix, + std::map& postfixMap, std::vector& postfixes) { if (postfix.isEmpty()) { @@ -539,8 +545,11 @@ void ElementMap::addPostfix(const QByteArray& postfix, std::map } } -MappedName ElementMap::setElementName(const IndexedName& element, const MappedName& name, - long masterTag, const ElementIDRefs* sid, bool overwrite) +MappedName ElementMap::setElementName(const IndexedName& element, + const MappedName& name, + long masterTag, + const ElementIDRefs* sid, + bool overwrite) { if (!element) { throw Base::ValueError("Invalid input"); @@ -553,13 +562,13 @@ MappedName ElementMap::setElementName(const IndexedName& element, const MappedNa for (int i = 0, count = name.size(); i < count; ++i) { char check = name[i]; if (check == '.' || (std::isspace((int)check) != 0)) { - FC_THROWM(Base::RuntimeError, "Illegal character in mapped name: " << name);// NOLINT + FC_THROWM(Base::RuntimeError, "Illegal character in mapped name: " << name); // NOLINT } } for (const char* readChar = element.getType(); *readChar != 0; ++readChar) { char check = *readChar; if (check == '.' || (std::isspace((int)check) != 0)) { - FC_THROWM(Base::RuntimeError,// NOLINT + FC_THROWM(Base::RuntimeError, // NOLINT "Illegal character in element name: " << element); } } @@ -586,7 +595,7 @@ MappedName ElementMap::setElementName(const IndexedName& element, const MappedNa } const int maxAttempts {100}; if (++i == maxAttempts) { - FC_ERR("unresolved duplicate element mapping '"// NOLINT + FC_ERR("unresolved duplicate element mapping '" // NOLINT << name << ' ' << element << '/' << existing); return name; } @@ -602,9 +611,14 @@ MappedName ElementMap::setElementName(const IndexedName& element, const MappedNa } // try to hash element name while preserving the source tag -void ElementMap::encodeElementName(char element_type, MappedName& name, std::ostringstream& ss, - ElementIDRefs* sids, long masterTag, const char* postfix, - long tag, bool forceTag) const +void ElementMap::encodeElementName(char element_type, + MappedName& name, + std::ostringstream& ss, + ElementIDRefs* sids, + long masterTag, + const char* postfix, + long tag, + bool forceTag) const { if (postfix && (postfix[0] != 0)) { if (!boost::starts_with(postfix, ELEMENT_MAP_PREFIX)) { @@ -715,26 +729,30 @@ MappedName ElementMap::dehashElementName(const MappedName& name) const auto sid = this->hasher->getID(id); if (!sid) { if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_TRACE)) { - FC_WARN("failed to find hash id " << id);// NOLINT + FC_WARN("failed to find hash id " << id); // NOLINT } else { - FC_LOG("failed to find hash id " << id);// NOLINT + FC_LOG("failed to find hash id " << id); // NOLINT } return name; } if (sid.isHashed()) { - FC_LOG("cannot de-hash id " << id);// NOLINT + FC_LOG("cannot de-hash id " << id); // NOLINT return name; } MappedName ret(sid); -// sid.toString());// FIXME .toString() was missing in original function. is this correct? - FC_TRACE("de-hash " << name << " -> " << ret);// NOLINT + // sid.toString());// FIXME .toString() was missing in original function. is this + // correct? + FC_TRACE("de-hash " << name << " -> " << ret); // NOLINT return ret; } -MappedName ElementMap::renameDuplicateElement(int index, const IndexedName& element, - const IndexedName& element2, const MappedName& name, - ElementIDRefs& sids, long masterTag) const +MappedName ElementMap::renameDuplicateElement(int index, + const IndexedName& element, + const IndexedName& element2, + const MappedName& name, + ElementIDRefs& sids, + long masterTag) const { int idx {0}; #ifdef FC_DEBUG @@ -751,7 +769,7 @@ MappedName ElementMap::renameDuplicateElement(int index, const IndexedName& elem MappedName renamed(name); encodeElementName(element.getType()[0], renamed, ss, &sids, masterTag); if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) { - FC_WARN("duplicate element mapping '"// NOLINT + FC_WARN("duplicate element mapping '" // NOLINT << name << " -> " << renamed << ' ' << element << '/' << element2); } return renamed; @@ -1008,13 +1026,20 @@ void ElementMap::hashChildMaps(long masterTag) .findTagInElementName(&tag, &len, nullptr, nullptr, false, false); // TODO: What is this 10? if (pos > 10) { - MappedName postfix = hashElementName( - MappedName::fromRawData(child.postfix.constData(), pos), child.sids); + MappedName postfix = + hashElementName(MappedName::fromRawData(child.postfix.constData(), pos), + child.sids); ss.str(""); ss << MAPPED_CHILD_ELEMENTS_PREFIX << postfix; MappedName tmp; - encodeElementName( - child.indexedName[0], tmp, ss, nullptr, masterTag, nullptr, child.tag, true); + encodeElementName(child.indexedName[0], + tmp, + ss, + nullptr, + masterTag, + nullptr, + child.tag, + true); this->childElements.remove(child.postfix); child.postfix = tmp.toBytes(); this->childElements[child.postfix].childMap = &child; @@ -1152,7 +1177,7 @@ void ElementMap::addChildElements(long masterTag, const std::vectorchildMap) { - FC_ERR("duplicate mapped child element");// NOLINT + FC_ERR("duplicate mapped child element"); // NOLINT continue; } } auto& indices = this->indexedNames[child.indexedName.getType()]; - auto res = indices.children.emplace( - child.indexedName.getIndex() + child.offset + child.count, child); + auto res = + indices.children.emplace(child.indexedName.getIndex() + child.offset + child.count, + child); if (!res.second) { if (!entry->childMap) { this->childElements.remove(tmp.toBytes()); } - FC_ERR("duplicate mapped child element");// NOLINT + FC_ERR("duplicate mapped child element"); // NOLINT continue; } @@ -1293,7 +1324,9 @@ std::vector ElementMap::getAll() const return ret; } -long ElementMap::getElementHistory(const MappedName& name, long masterTag, MappedName* original, +long ElementMap::getElementHistory(const MappedName& name, + long masterTag, + MappedName* original, std::vector* history) const { long tag = 0; @@ -1321,7 +1354,7 @@ long ElementMap::getElementHistory(const MappedName& name, long masterTag, Mappe while (true) { if ((len == 0) || len > pos) { - FC_WARN("invalid name length " << name);// NOLINT + FC_WARN("invalid name length " << name); // NOLINT return 0; } bool deHashed = false; @@ -1440,4 +1473,4 @@ void ElementMap::traceElement(const MappedName& name, long masterTag, TraceCallb } -}// Namespace Data +} // Namespace Data diff --git a/src/App/ElementMap.h b/src/App/ElementMap.h index 1902210ef9..29c7c2ab9a 100644 --- a/src/App/ElementMap.h +++ b/src/App/ElementMap.h @@ -46,17 +46,17 @@ class ElementMap; using ElementMapPtr = std::shared_ptr; /** Element trace callback - * - * The callback has the following call signature - * (const std::string &name, size_t offset, long encodedTag, long tag) -> bool - * - * @param name: the current element name. - * @param offset: the offset skipping the encoded element name for the next iteration. - * @param encodedTag: the tag encoded inside the current element, which is usually the tag - * of the previous step in the shape history. - * @param tag: the tag of the current shape element. - * - * @sa traceElement() + * + * The callback has the following call signature + * (const std::string &name, size_t offset, long encodedTag, long tag) -> bool + * + * @param name: the current element name. + * @param offset: the offset skipping the encoded element name for the next iteration. + * @param encodedTag: the tag encoded inside the current element, which is usually the tag + * of the previous step in the shape history. + * @param tag: the tag of the current shape element. + * + * @sa traceElement() */ typedef std::function TraceCallback; @@ -68,13 +68,14 @@ typedef std::function TraceCallback; * possibly a recursive elementmap * `mappedNames` maps a MappedName to a specific IndexedName. */ -class AppExport ElementMap: public std::enable_shared_from_this //TODO can remove shared_from_this? +class AppExport ElementMap + : public std::enable_shared_from_this // TODO can remove shared_from_this? { public: /** Default constructor: hooks internal functions to \c signalSaveDocument and * \c signalStartRestoreDocument. This is related to the save and restore process * of the map. - */ + */ ElementMap(); /** Ensures that naming is properly assigned. It then marks as "used" all the StringID @@ -82,14 +83,14 @@ public: * as a parameter. Finally do this recursively for all childEelementMaps as well. * * @param hasherRef where all the StringID needed to build the map are stored. - */ + */ // FIXME this should be made part of \c save, to achieve symmetry with the restore method void beforeSave(const ::App::StringHasherRef& hasherRef) const; /** Serialize this map. Calls \c collectChildMaps to get \c childMapSet and * \c postfixMap, then calls the other (private) save function with those parameters. * @param stream: serialized stream - */ + */ void save(std::ostream& stream) const; /** Deserialize and restore this map. This function restores \c childMaps and @@ -97,7 +98,7 @@ public: * parameters. * @param hasherRef: where all the StringIDs are stored * @param stream: stream to deserialize - */ + */ ElementMapPtr restore(::App::StringHasherRef hasherRef, std::istream& stream); @@ -196,9 +197,10 @@ public: std::vector getAll() const; - long getElementHistory(const MappedName & name, + long getElementHistory(const MappedName& name, long masterTag, - MappedName *original=nullptr, std::vector *history=nullptr) const; + MappedName* original = nullptr, + std::vector* history = nullptr) const; /** Iterate through the history of the give element name with a given callback * @@ -214,8 +216,10 @@ private: * @param stream: serialized stream * @param childMapSet: where all child element maps are stored * @param postfixMap. where all postfixes are stored - */ - void save(std::ostream& stream, int index, const std::map& childMapSet, + */ + void save(std::ostream& stream, + int index, + const std::map& childMapSet, const std::map& postfixMap) const; /** Deserialize and restore this map. @@ -223,8 +227,9 @@ private: * @param stream: stream to deserialize * @param childMaps: where all child element maps are stored * @param postfixes. where all postfixes are stored - */ - ElementMapPtr restore(::App::StringHasherRef hasherRef, std::istream& stream, + */ + ElementMapPtr restore(::App::StringHasherRef hasherRef, + std::istream& stream, std::vector& childMaps, const std::vector& postfixes); @@ -237,20 +242,27 @@ private: * associated with another indexedName, set \c existing to that indexedname * @return the name just added, or an empty name if it wasn't added. */ - MappedName addName(MappedName& name, const IndexedName& idx, const ElementIDRefs& sids, - bool overwrite, IndexedName* existing); + MappedName addName(MappedName& name, + const IndexedName& idx, + const ElementIDRefs& sids, + bool overwrite, + IndexedName* existing); /** Utility function that adds \c postfix to \c postfixMap, and to \c postfixes * if it was not present in the map. - */ - static void addPostfix(const QByteArray& postfix, std::map& postfixMap, + */ + static void addPostfix(const QByteArray& postfix, + std::map& postfixMap, std::vector& postfixes); /* Note: the original proc passed `ComplexGeoData& master` for getting the `Tag`, * now it just passes `long masterTag`.*/ - MappedName renameDuplicateElement(int index, const IndexedName& element, - const IndexedName& element2, const MappedName& name, - ElementIDRefs& sids, long masterTag) const; + MappedName renameDuplicateElement(int index, + const IndexedName& element, + const IndexedName& element2, + const MappedName& name, + ElementIDRefs& sids, + long masterTag) const; /** Convenience method to hash the main element name * @@ -263,7 +275,7 @@ private: /// Reverse hashElementName() MappedName dehashElementName(const MappedName& name) const; - //FIXME duplicate code? as in copy/paste + // FIXME duplicate code? as in copy/paste const MappedNameRef* findMappedRef(const IndexedName& idx) const; MappedNameRef* findMappedRef(const IndexedName& idx); @@ -313,6 +325,6 @@ public: }; -}// namespace Data +} // namespace Data -#endif// DATA_ELEMENTMAP_H +#endif // DATA_ELEMENTMAP_H diff --git a/src/App/ElementNamingUtils.cpp b/src/App/ElementNamingUtils.cpp index 2b6e59d4d8..8d17603219 100644 --- a/src/App/ElementNamingUtils.cpp +++ b/src/App/ElementNamingUtils.cpp @@ -4,96 +4,119 @@ #include -const char *Data::isMappedElement(const char *name) { - if(name && boost::starts_with(name, ELEMENT_MAP_PREFIX)) +const char* Data::isMappedElement(const char* name) +{ + if (name && boost::starts_with(name, ELEMENT_MAP_PREFIX)) { return name + ELEMENT_MAP_PREFIX_SIZE; + } return nullptr; } -std::string Data::newElementName(const char *name) { - if(!name) +std::string Data::newElementName(const char* name) +{ + if (!name) { return {}; - const char *dot = strrchr(name,'.'); - if(!dot || dot==name) + } + const char* dot = strrchr(name, '.'); + if (!dot || dot == name) { return name; - const char *c = dot-1; - for(;c!=name;--c) { - if(*c == '.') { + } + const char* c = dot - 1; + for (; c != name; --c) { + if (*c == '.') { ++c; break; } } - if(isMappedElement(c)) - return std::string(name,dot-name); + if (isMappedElement(c)) { + return std::string(name, dot - name); + } return name; } -std::string Data::oldElementName(const char *name) { - if(!name) +std::string Data::oldElementName(const char* name) +{ + if (!name) { return {}; - const char *dot = strrchr(name,'.'); - if(!dot || dot==name) + } + const char* dot = strrchr(name, '.'); + if (!dot || dot == name) { return name; - const char *c = dot-1; - for(;c!=name;--c) { - if(*c == '.') { + } + const char* c = dot - 1; + for (; c != name; --c) { + if (*c == '.') { ++c; break; } } - if(isMappedElement(c)) - return std::string(name,c-name)+(dot+1); + if (isMappedElement(c)) { + return std::string(name, c - name) + (dot + 1); + } return name; } -std::string Data::noElementName(const char *name) { - if(!name) +std::string Data::noElementName(const char* name) +{ + if (!name) { return {}; + } auto element = findElementName(name); - if(element) - return std::string(name,element-name); + if (element) { + return std::string(name, element - name); + } return name; } -const char *Data::findElementName(const char *subname) { +const char* Data::findElementName(const char* subname) +{ // skip leading dots - while(subname && subname[0] == '.') + while (subname && subname[0] == '.') { ++subname; - if(!subname || !subname[0] || isMappedElement(subname)) + } + if (!subname || !subname[0] || isMappedElement(subname)) { return subname; - const char *dot = strrchr(subname,'.'); - if(!dot) + } + const char* dot = strrchr(subname, '.'); + if (!dot) { return subname; - const char *element = dot+1; - if(dot==subname || isMappedElement(element)) + } + const char* element = dot + 1; + if (dot == subname || isMappedElement(element)) { return element; - for(--dot;dot!=subname;--dot) { - if(*dot == '.') { + } + for (--dot; dot != subname; --dot) { + if (*dot == '.') { ++dot; break; } } - if(isMappedElement(dot)) + if (isMappedElement(dot)) { return dot; + } return element; } -bool Data::hasMissingElement(const char *subname) { - if(!subname) +bool Data::hasMissingElement(const char* subname) +{ + if (!subname) { return false; - auto dot = strrchr(subname,'.'); - if(dot) - subname = dot+1; + } + auto dot = strrchr(subname, '.'); + if (dot) { + subname = dot + 1; + } return boost::starts_with(subname, MISSING_PREFIX); } -const char *Data::hasMappedElementName(const char *subname) { +const char* Data::hasMappedElementName(const char* subname) +{ return isMappedElement(findElementName(subname)); } -const std::string Data::indexSuffix(int index, const char *label) +const std::string Data::indexSuffix(int index, const char* label) { - if ( index < 2 ) { // Don't add a suffix for item #1, begin appending at 2 + if (index < 2) { // Don't add a suffix for item #1, begin appending at 2 return {""}; } std::string name(label); diff --git a/src/App/ElementNamingUtils.h b/src/App/ElementNamingUtils.h index cedc2c1342..3ed66ecedd 100644 --- a/src/App/ElementNamingUtils.h +++ b/src/App/ElementNamingUtils.h @@ -18,10 +18,10 @@ struct ElementNamePair ElementNamePair() = default; - ElementNamePair(std::string newNameStr, std::string oldNameStr) : - newName(std::move(newNameStr)), oldName(std::move(oldNameStr)) - { - } + ElementNamePair(std::string newNameStr, std::string oldNameStr) + : newName(std::move(newNameStr)) + , oldName(std::move(oldNameStr)) + {} bool operator==(const ElementNamePair& other) const { @@ -34,7 +34,7 @@ struct ElementNamePair } }; -} +} // namespace App // clang-format off namespace Data @@ -101,4 +101,4 @@ AppExport const std::string indexSuffix(int index, const char *label=ELEMENT_MAP } // namespace Data // clang-format on -#endif // ELEMENT_NAMING_UTILS_H +#endif // ELEMENT_NAMING_UTILS_H diff --git a/src/App/Enumeration.cpp b/src/App/Enumeration.cpp index 69d3027495..595292f0a1 100644 --- a/src/App/Enumeration.cpp +++ b/src/App/Enumeration.cpp @@ -22,8 +22,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif #include @@ -32,17 +32,23 @@ using namespace App; -namespace { -struct StringCopy : public Enumeration::Object { - explicit StringCopy(const char* str) : d(str) { - } - const char* data() const override { +namespace +{ +struct StringCopy: public Enumeration::Object +{ + explicit StringCopy(const char* str) + : d(str) + {} + const char* data() const override + { return d.data(); } - bool isEqual(const char* str) const override { + bool isEqual(const char* str) const override + { return d == str; } - bool isCustom() const override { + bool isCustom() const override + { return true; } @@ -50,43 +56,47 @@ private: std::string d; }; -struct StringView : public Enumeration::Object { - explicit StringView(const char* str) : d(str) { - } - const char* data() const override { +struct StringView: public Enumeration::Object +{ + explicit StringView(const char* str) + : d(str) + {} + const char* data() const override + { return d.data(); } - bool isEqual(const char* str) const override { + bool isEqual(const char* str) const override + { return d == str; } - bool isCustom() const override { + bool isCustom() const override + { return false; } private: std::string_view d; }; -} +} // namespace Enumeration::Enumeration() : _index(0) -{ -} +{} -Enumeration::Enumeration(const Enumeration &other) +Enumeration::Enumeration(const Enumeration& other) { enumArray = other.enumArray; _index = other._index; } -Enumeration::Enumeration(const char *valStr) +Enumeration::Enumeration(const char* valStr) : _index(0) { enumArray.push_back(std::make_shared(valStr)); setValue(valStr); } -Enumeration::Enumeration(const char **list, const char *valStr) +Enumeration::Enumeration(const char** list, const char* valStr) : _index(0) { while (list && *list) { @@ -101,14 +111,15 @@ Enumeration::~Enumeration() enumArray.clear(); } -void Enumeration::setEnums(const char **plEnums) +void Enumeration::setEnums(const char** plEnums) { std::string oldValue; bool preserve = (isValid() && plEnums != nullptr); if (preserve) { const char* str = getCStr(); - if (str) + if (str) { oldValue = str; + } } enumArray.clear(); @@ -118,14 +129,15 @@ void Enumeration::setEnums(const char **plEnums) } // set _index - if (_index < 0) + if (_index < 0) { _index = 0; + } if (preserve) { setValue(oldValue); } } -void Enumeration::setEnums(const std::vector &values) +void Enumeration::setEnums(const std::vector& values) { if (values.empty()) { setEnums(nullptr); @@ -136,24 +148,26 @@ void Enumeration::setEnums(const std::vector &values) bool preserve = isValid(); if (preserve) { const char* str = getCStr(); - if (str) + if (str) { oldValue = str; + } } enumArray.clear(); - for (const auto & it : values) { + for (const auto& it : values) { enumArray.push_back(std::make_shared(it.c_str())); } // set _index - if (_index < 0) + if (_index < 0) { _index = 0; + } if (preserve) { setValue(oldValue); } } -void Enumeration::setValue(const char *value) +void Enumeration::setValue(const char* value) { _index = 0; for (std::size_t i = 0; i < enumArray.size(); i++) { @@ -168,41 +182,45 @@ void Enumeration::setValue(long value, bool checkRange) { if (value >= 0 && value < countItems()) { _index = value; - } else { + } + else { if (checkRange) { throw Base::ValueError("Out of range"); - } else { + } + else { _index = value; } } } -bool Enumeration::isValue(const char *value) const +bool Enumeration::isValue(const char* value) const { int i = getInt(); if (i == -1) { return false; - } else { + } + else { return enumArray[i]->isEqual(value); } } -bool Enumeration::contains(const char *value) const +bool Enumeration::contains(const char* value) const { if (!isValid()) { return false; } for (const auto& it : enumArray) { - if (it->isEqual(value)) + if (it->isEqual(value)) { return true; + } } return false; } -const char * Enumeration::getCStr() const +const char* Enumeration::getCStr() const { if (!isValid() || _index < 0 || _index >= countItems()) { return nullptr; @@ -223,8 +241,9 @@ int Enumeration::getInt() const std::vector Enumeration::getEnumVector() const { std::vector list; - for (const auto& it : enumArray) + for (const auto& it : enumArray) { list.emplace_back(it->data()); + } return list; } @@ -241,24 +260,27 @@ bool Enumeration::isValid() const int Enumeration::maxValue() const { int num = -1; - if (!enumArray.empty()) + if (!enumArray.empty()) { num = static_cast(enumArray.size()) - 1; + } return num; } bool Enumeration::isCustom() const { for (const auto& it : enumArray) { - if (it->isCustom()) + if (it->isCustom()) { return true; + } } return false; } -Enumeration & Enumeration::operator=(const Enumeration &other) +Enumeration& Enumeration::operator=(const Enumeration& other) { - if (this == &other) + if (this == &other) { return *this; + } enumArray = other.enumArray; _index = other._index; @@ -266,23 +288,26 @@ Enumeration & Enumeration::operator=(const Enumeration &other) return *this; } -bool Enumeration::operator==(const Enumeration &other) const +bool Enumeration::operator==(const Enumeration& other) const { if (_index != other._index || enumArray.size() != other.enumArray.size()) { return false; } for (size_t i = 0; i < enumArray.size(); ++i) { - if (enumArray[i]->data() == other.enumArray[i]->data()) + if (enumArray[i]->data() == other.enumArray[i]->data()) { continue; - if (!enumArray[i]->data() || !other.enumArray[i]->data()) + } + if (!enumArray[i]->data() || !other.enumArray[i]->data()) { return false; - if (!enumArray[i]->isEqual(other.enumArray[i]->data())) + } + if (!enumArray[i]->isEqual(other.enumArray[i]->data())) { return false; + } } return true; } -bool Enumeration::operator==(const char *other) const +bool Enumeration::operator==(const char* other) const { if (!getCStr()) { return false; diff --git a/src/App/Enumeration.h b/src/App/Enumeration.h index 64320ac9b4..60fe063287 100644 --- a/src/App/Enumeration.h +++ b/src/App/Enumeration.h @@ -31,162 +31,166 @@ namespace App { - /// A bidirectional string-integer mapping - /*! - * This is mainly intended for two purposes: working around the difficulty - * in C++ of sharing enumerations between different source files, - * namespaces, etc. and as the data type stored by App::PropertyEnumeration - * - * Internally, Enumeration maintains - * -# Either a const pointer to an array of C-style strings, or a vector - * of C++ std::strings - * -# An integer index into that array/vector representing the string - * representing the instance's value. - * - * If built with FC_DEBUG defined, some boundaries of passed in pointers - * will be checked. Otherwise, the caller has the responsibility of - * checking the limits of given indices. - * - * \todo Implement lazy copy - */ - class AppExport Enumeration +/// A bidirectional string-integer mapping +/*! + * This is mainly intended for two purposes: working around the difficulty + * in C++ of sharing enumerations between different source files, + * namespaces, etc. and as the data type stored by App::PropertyEnumeration + * + * Internally, Enumeration maintains + * -# Either a const pointer to an array of C-style strings, or a vector + * of C++ std::strings + * -# An integer index into that array/vector representing the string + * representing the instance's value. + * + * If built with FC_DEBUG defined, some boundaries of passed in pointers + * will be checked. Otherwise, the caller has the responsibility of + * checking the limits of given indices. + * + * \todo Implement lazy copy + */ +class AppExport Enumeration +{ +public: + class Object { public: - class Object { - public: - virtual ~Object() = default; - virtual const char* data() const = 0; - virtual bool isEqual(const char*) const = 0; - virtual bool isCustom() const = 0; - }; + virtual ~Object() = default; + virtual const char* data() const = 0; + virtual bool isEqual(const char*) const = 0; + virtual bool isCustom() const = 0; + }; - public: - /// Constructs an empty Enumeration object - Enumeration(); +public: + /// Constructs an empty Enumeration object + Enumeration(); - /// Standard copy constructor - Enumeration(const Enumeration& other); + /// Standard copy constructor + Enumeration(const Enumeration& other); - /// Constructs an Enumeration with a single element - explicit Enumeration(const char *valStr); + /// Constructs an Enumeration with a single element + explicit Enumeration(const char* valStr); - /// Constructs an Enumeration using val within list - Enumeration(const char **list, const char *valStr); + /// Constructs an Enumeration using val within list + Enumeration(const char** list, const char* valStr); - /// Standard destructor - ~Enumeration(); + /// Standard destructor + ~Enumeration(); - /** Sets the enumeration string list - * The list is a NULL terminated array of pointers to const - * char* strings. - * \code - * const char enums[] = {"Black","White","Other",NULL} - * \endcode - * - * If Enumeration was already valid, will attempt to preserve - * the string-representation value of the Enumeration - * - * Enumeration does not take ownership of the passed object - */ - void setEnums(const char **plEnums); + /** Sets the enumeration string list + * The list is a NULL terminated array of pointers to const + * char* strings. + * \code + * const char enums[] = {"Black","White","Other",NULL} + * \endcode + * + * If Enumeration was already valid, will attempt to preserve + * the string-representation value of the Enumeration + * + * Enumeration does not take ownership of the passed object + */ + void setEnums(const char** plEnums); - /// Set all enum values as vector of strings - /*! - * This method causes the Enumeration to dynamically allocate - * it's own array of C Strings, which will be deleted by the - * destructor or subsequent calls to setEnums(). So, it is - * important to make sure the Enumeration stays in scope as - * long as values returned by getCStr are in use. - * - * If Enumeration was already valid, will attempt to preserve - * the string-representation value of the Enumeration - */ - void setEnums(const std::vector &values); + /// Set all enum values as vector of strings + /*! + * This method causes the Enumeration to dynamically allocate + * it's own array of C Strings, which will be deleted by the + * destructor or subsequent calls to setEnums(). So, it is + * important to make sure the Enumeration stays in scope as + * long as values returned by getCStr are in use. + * + * If Enumeration was already valid, will attempt to preserve + * the string-representation value of the Enumeration + */ + void setEnums(const std::vector& values); - /// Set the enum using a C string - void setValue(const char *value); + /// Set the enum using a C string + void setValue(const char* value); - /// Overload of setValue(const char *value) - void setValue(const std::string &value) {setValue(value.c_str());} + /// Overload of setValue(const char *value) + void setValue(const std::string& value) + { + setValue(value.c_str()); + } - /// Set the enum using a long - /*! - * if checkRange is set to true, throws Base::ValueError when - * values are set out of range - * - * Checks for boundaries via assert() - */ - void setValue(long value, bool checkRange = false); + /// Set the enum using a long + /*! + * if checkRange is set to true, throws Base::ValueError when + * values are set out of range + * + * Checks for boundaries via assert() + */ + void setValue(long value, bool checkRange = false); - /// Checks if the property is set to a certain string value - bool isValue(const char *value) const; + /// Checks if the property is set to a certain string value + bool isValue(const char* value) const; - /// Checks if a string is included in the enumeration - bool contains(const char *value) const; + /// Checks if a string is included in the enumeration + bool contains(const char* value) const; - /// Return the value as C string - /*! - * Returns NULL if the enumeration is invalid. - */ - const char * getCStr() const; + /// Return the value as C string + /*! + * Returns NULL if the enumeration is invalid. + */ + const char* getCStr() const; - /// Return value as integer - /*! - * Returns -1 if the Enumeration isn't valid - */ - int getInt() const; + /// Return value as integer + /*! + * Returns -1 if the Enumeration isn't valid + */ + int getInt() const; - /// get all possible enum values as vector of strings - std::vector getEnumVector() const; + /// get all possible enum values as vector of strings + std::vector getEnumVector() const; - /// returns true if the enum list is non-empty, false otherwise - bool hasEnums() const; + /// returns true if the enum list is non-empty, false otherwise + bool hasEnums() const; - /// Returns true if the instance is in a usable state - bool isValid() const; + /// Returns true if the instance is in a usable state + bool isValid() const; - /// Returns the highest usable integer value for this enum - /*! - * Returns -1 if the enumeration is not valid according to isValid() - */ - int maxValue() const; + /// Returns the highest usable integer value for this enum + /*! + * Returns -1 if the enumeration is not valid according to isValid() + */ + int maxValue() const; - /// Returns true if any of the items is a user-defined string - bool isCustom() const; + /// Returns true if any of the items is a user-defined string + bool isCustom() const; - /// Assignment operator - Enumeration & operator=(const Enumeration &other); + /// Assignment operator + Enumeration& operator=(const Enumeration& other); - /// true iff our string representation matches other's - /*! - * Returns false if either Enumeration is not valid. - */ - bool operator==(const Enumeration &other) const; + /// true iff our string representation matches other's + /*! + * Returns false if either Enumeration is not valid. + */ + bool operator==(const Enumeration& other) const; - /// true iff our string representation matches other - /*! - * Returns false if Enumeration is not valid. - */ - bool operator==(const char *other) const; - protected: + /// true iff our string representation matches other + /*! + * Returns false if Enumeration is not valid. + */ + bool operator==(const char* other) const; - /// Number of items - int countItems() const; +protected: + /// Number of items + int countItems() const; - private: - /// Handle to C Strings of possible enumeration values - using ObjectPtr = std::shared_ptr; - std::vector enumArray; +private: + /// Handle to C Strings of possible enumeration values + using ObjectPtr = std::shared_ptr; + std::vector enumArray; - /// Integer value of the enumeration - /*! - * This serves as an index into enumArray to get the string - * representation. - */ - int _index; + /// Integer value of the enumeration + /*! + * This serves as an index into enumArray to get the string + * representation. + */ + int _index; - friend class PropertyEnumeration; - }; // class Enumeration -} // namespace App + friend class PropertyEnumeration; +}; // class Enumeration +} // namespace App -#endif // #ifndef BASE_ENUMERATION_H +#endif // #ifndef BASE_ENUMERATION_H diff --git a/src/App/Extension.cpp b/src/App/Extension.cpp index 8fa6ecc0a1..51ba5fff7c 100644 --- a/src/App/Extension.cpp +++ b/src/App/Extension.cpp @@ -24,7 +24,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include @@ -39,167 +39,201 @@ * PropertyData in the extension chain, there is no parent property data. */ EXTENSION_TYPESYSTEM_SOURCE_P(App::Extension) -const App::PropertyData * App::Extension::extensionGetPropertyDataPtr(){return &propertyData;} -const App::PropertyData & App::Extension::extensionGetPropertyData() const{return propertyData;} +const App::PropertyData* App::Extension::extensionGetPropertyDataPtr() +{ + return &propertyData; +} +const App::PropertyData& App::Extension::extensionGetPropertyData() const +{ + return propertyData; +} App::PropertyData App::Extension::propertyData; -void App::Extension::init(){ +void App::Extension::init() +{ assert(Extension::classTypeId == Base::Type::badType() && "don't init() twice!"); /* Set up entry in the type system. */ - Extension::classTypeId = Base::Type::createType(Base::Type::badType(), "App::Extension", - Extension::create); + Extension::classTypeId = + Base::Type::createType(Base::Type::badType(), "App::Extension", Extension::create); } using namespace App; Extension::~Extension() { - if (!ExtensionPythonObject.is(Py::_None())){ + if (!ExtensionPythonObject.is(Py::_None())) { // Remark: The API of Py::Object has been changed to set whether the wrapper owns the passed - // Python object or not. In the constructor we forced the wrapper to own the object so we need - // not to dec'ref the Python object any more. - // But we must still invalidate the Python object because it need not to be - // destructed right now because the interpreter can own several references to it. + // Python object or not. In the constructor we forced the wrapper to own the object so we + // need not to dec'ref the Python object any more. But we must still invalidate the Python + // object because it need not to be destructed right now because the interpreter can own + // several references to it. Base::PyObjectBase* obj = static_cast(ExtensionPythonObject.ptr()); // Call before decrementing the reference counter, otherwise a heap error can occur obj->setInvalid(); } } -void Extension::initExtensionType(Base::Type type) { +void Extension::initExtensionType(Base::Type type) +{ m_extensionType = type; - if (m_extensionType.isBad()) + if (m_extensionType.isBad()) { throw Base::RuntimeError("Extension: Extension type not set"); + } } -void Extension::initExtension(ExtensionContainer* obj) { - if (m_extensionType.isBad()) +void Extension::initExtension(ExtensionContainer* obj) +{ + if (m_extensionType.isBad()) { throw Base::RuntimeError("Extension: Extension type not set"); + } - //all properties are initialised without PropertyContainer father. Now that we know it we can - //finally finish the property initialisation + // all properties are initialised without PropertyContainer father. Now that we know it we can + // finally finish the property initialisation std::vector list; extensionGetPropertyData().getPropertyList(this, list); - for(Property* prop : list) + for (Property* prop : list) { prop->setContainer(obj); + } m_base = obj; - m_base->registerExtension( m_extensionType, this ); + m_base->registerExtension(m_extensionType, this); } -PyObject* Extension::getExtensionPyObject() { +PyObject* Extension::getExtensionPyObject() +{ - if (ExtensionPythonObject.is(Py::_None())){ + if (ExtensionPythonObject.is(Py::_None())) { // ref counter is set to 1 auto grp = new ExtensionPy(this); - ExtensionPythonObject = Py::Object(grp,true); + ExtensionPythonObject = Py::Object(grp, true); } return Py::new_reference_to(ExtensionPythonObject); } -std::string Extension::name() const { +std::string Extension::name() const +{ - if (m_extensionType.isBad()) + if (m_extensionType.isBad()) { throw Base::RuntimeError("Extension::name: Extension type not set"); + } std::string temp(m_extensionType.getName()); std::string::size_type pos = temp.find_last_of(':'); - if (pos != std::string::npos) - return temp.substr(pos+1); + if (pos != std::string::npos) { + return temp.substr(pos + 1); + } return {}; } -Property* Extension::extensionGetPropertyByName(const char* name) const { +Property* Extension::extensionGetPropertyByName(const char* name) const +{ return extensionGetPropertyData().getPropertyByName(this, name); } -short int Extension::extensionGetPropertyType(const Property* prop) const { +short int Extension::extensionGetPropertyType(const Property* prop) const +{ return extensionGetPropertyData().getType(this, prop); } -short int Extension::extensionGetPropertyType(const char* name) const { +short int Extension::extensionGetPropertyType(const char* name) const +{ return extensionGetPropertyData().getType(this, name); } -const char* Extension::extensionGetPropertyName(const Property* prop) const { +const char* Extension::extensionGetPropertyName(const Property* prop) const +{ - return extensionGetPropertyData().getName(this,prop); + return extensionGetPropertyData().getName(this, prop); } -const char* Extension::extensionGetPropertyGroup(const Property* prop) const { +const char* Extension::extensionGetPropertyGroup(const Property* prop) const +{ - return extensionGetPropertyData().getGroup(this,prop); + return extensionGetPropertyData().getGroup(this, prop); } -const char* Extension::extensionGetPropertyGroup(const char* name) const { +const char* Extension::extensionGetPropertyGroup(const char* name) const +{ - return extensionGetPropertyData().getGroup(this,name); + return extensionGetPropertyData().getGroup(this, name); } -const char* Extension::extensionGetPropertyDocumentation(const Property* prop) const { +const char* Extension::extensionGetPropertyDocumentation(const Property* prop) const +{ return extensionGetPropertyData().getDocumentation(this, prop); } -const char* Extension::extensionGetPropertyDocumentation(const char* name) const { +const char* Extension::extensionGetPropertyDocumentation(const char* name) const +{ return extensionGetPropertyData().getDocumentation(this, name); } -void Extension::extensionGetPropertyList(std::vector< Property* >& List) const { +void Extension::extensionGetPropertyList(std::vector& List) const +{ extensionGetPropertyData().getPropertyList(this, List); } -void Extension::extensionGetPropertyMap(std::map< std::string, Property* >& Map) const { +void Extension::extensionGetPropertyMap(std::map& Map) const +{ extensionGetPropertyData().getPropertyMap(this, Map); } -void Extension::initExtensionSubclass(Base::Type& toInit, const char* ClassName, const char* ParentName, - Base::Type::instantiationMethod method) { +void Extension::initExtensionSubclass(Base::Type& toInit, + const char* ClassName, + const char* ParentName, + Base::Type::instantiationMethod method) +{ // don't init twice! assert(toInit == Base::Type::badType()); // get the parent class Base::Type parentType(Base::Type::fromName(ParentName)); // forgot init parent! - assert(parentType != Base::Type::badType() ); + assert(parentType != Base::Type::badType()); // create the new type toInit = Base::Type::createType(parentType, ClassName, method); } -bool Extension::extensionHandleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName) +bool Extension::extensionHandleChangedPropertyName(Base::XMLReader& reader, + const char* TypeName, + const char* PropName) { - (void) reader; - (void) TypeName; - (void) PropName; + (void)reader; + (void)TypeName; + (void)PropName; return false; }; -bool Extension::extensionHandleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, Property * prop) +bool Extension::extensionHandleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + Property* prop) { - (void) reader; - (void) TypeName; - (void) prop; + (void)reader; + (void)TypeName; + (void)prop; return false; }; -namespace App { +namespace App +{ EXTENSION_PROPERTY_SOURCE_TEMPLATE(App::ExtensionPython, App::ExtensionPython::Inherited) // explicit template instantiation template class AppExport ExtensionPythonT; -} +} // namespace App diff --git a/src/App/ExtensionContainer.cpp b/src/App/ExtensionContainer.cpp index 6702621ff9..2fd642990d 100644 --- a/src/App/ExtensionContainer.cpp +++ b/src/App/ExtensionContainer.cpp @@ -38,23 +38,28 @@ TYPESYSTEM_SOURCE(App::ExtensionContainer, App::PropertyContainer) ExtensionContainer::ExtensionContainer() = default; -ExtensionContainer::~ExtensionContainer() { +ExtensionContainer::~ExtensionContainer() +{ - //we need to delete all dynamically added extensions - for(const auto& entry : _extensions) { - if(entry.second->isPythonExtension()) + // we need to delete all dynamically added extensions + for (const auto& entry : _extensions) { + if (entry.second->isPythonExtension()) { delete entry.second; + } } } -void ExtensionContainer::registerExtension(Base::Type extension, Extension* ext) { - if(ext->getExtendedContainer() != this) - throw Base::ValueError("ExtensionContainer::registerExtension: Extension has not this as base object"); +void ExtensionContainer::registerExtension(Base::Type extension, Extension* ext) +{ + if (ext->getExtendedContainer() != this) { + throw Base::ValueError( + "ExtensionContainer::registerExtension: Extension has not this as base object"); + } - //no duplicate extensions (including base classes) - if(hasExtension(extension)) { - for(const auto& entry : _extensions) { - if(entry.first == extension || entry.first.isDerivedFrom(extension)) { + // no duplicate extensions (including base classes) + if (hasExtension(extension)) { + for (const auto& entry : _extensions) { + if (entry.first == extension || entry.first.isDerivedFrom(extension)) { _extensions.erase(entry.first); break; } @@ -64,275 +69,325 @@ void ExtensionContainer::registerExtension(Base::Type extension, Extension* ext) _extensions[extension] = ext; } -bool ExtensionContainer::hasExtension(Base::Type t, bool derived) const { +bool ExtensionContainer::hasExtension(Base::Type t, bool derived) const +{ - //check for the exact type + // check for the exact type bool found = _extensions.find(t) != _extensions.end(); - if(!found && derived) { - //and for types derived from it, as they can be cast to the extension - for(const auto& entry : _extensions) { - if(entry.first.isDerivedFrom(t)) + if (!found && derived) { + // and for types derived from it, as they can be cast to the extension + for (const auto& entry : _extensions) { + if (entry.first.isDerivedFrom(t)) { return true; + } } return false; } return found; } -bool ExtensionContainer::hasExtension(const std::string& name) const { +bool ExtensionContainer::hasExtension(const std::string& name) const +{ - //and for types derived from it, as they can be cast to the extension - for(const auto& entry : _extensions) { - if(entry.second->name() == name) + // and for types derived from it, as they can be cast to the extension + for (const auto& entry : _extensions) { + if (entry.second->name() == name) { return true; + } } return false; } -Extension* ExtensionContainer::getExtension(Base::Type t, bool derived, bool no_except) const { +Extension* ExtensionContainer::getExtension(Base::Type t, bool derived, bool no_except) const +{ auto result = _extensions.find(t); - if((result == _extensions.end()) && derived) { - //we need to check for derived types - for(const auto& entry : _extensions) { - if(entry.first.isDerivedFrom(t)) + if ((result == _extensions.end()) && derived) { + // we need to check for derived types + for (const auto& entry : _extensions) { + if (entry.first.isDerivedFrom(t)) { return entry.second; + } } - if(no_except) + if (no_except) { return nullptr; - //if we arrive here we don't have anything matching - throw Base::TypeError("ExtensionContainer::getExtension: No extension of given type available"); + } + // if we arrive here we don't have anything matching + throw Base::TypeError( + "ExtensionContainer::getExtension: No extension of given type available"); } else if (result != _extensions.end()) { return result->second; } else { - if(no_except) + if (no_except) { return nullptr; - //if we arrive here we don't have anything matching - throw Base::TypeError("ExtensionContainer::getExtension: No extension of given type available"); + } + // if we arrive here we don't have anything matching + throw Base::TypeError( + "ExtensionContainer::getExtension: No extension of given type available"); } } -bool ExtensionContainer::hasExtensions() const { +bool ExtensionContainer::hasExtensions() const +{ return !_extensions.empty(); } -Extension* ExtensionContainer::getExtension(const std::string& name) const { +Extension* ExtensionContainer::getExtension(const std::string& name) const +{ - //and for types derived from it, as they can be cast to the extension - for(const auto& entry : _extensions) { - if(entry.second->name() == name) + // and for types derived from it, as they can be cast to the extension + for (const auto& entry : _extensions) { + if (entry.second->name() == name) { return entry.second; + } } return nullptr; } -std::vector< Extension* > ExtensionContainer::getExtensionsDerivedFrom(Base::Type type) const { +std::vector ExtensionContainer::getExtensionsDerivedFrom(Base::Type type) const +{ std::vector vec; - //and for types derived from it, as they can be cast to the extension - for(const auto& entry : _extensions) { - if(entry.first.isDerivedFrom(type)) + // and for types derived from it, as they can be cast to the extension + for (const auto& entry : _extensions) { + if (entry.first.isDerivedFrom(type)) { vec.push_back(entry.second); + } } return vec; } -void ExtensionContainer::getPropertyList(std::vector< Property* >& List) const { +void ExtensionContainer::getPropertyList(std::vector& List) const +{ App::PropertyContainer::getPropertyList(List); - for(const auto& entry : _extensions) + for (const auto& entry : _extensions) { entry.second->extensionGetPropertyList(List); + } } -void ExtensionContainer::getPropertyMap(std::map< std::string, Property* >& Map) const { +void ExtensionContainer::getPropertyMap(std::map& Map) const +{ App::PropertyContainer::getPropertyMap(Map); - for(const auto& entry : _extensions) + for (const auto& entry : _extensions) { entry.second->extensionGetPropertyMap(Map); + } } -Property* ExtensionContainer::getPropertyByName(const char* name) const { +Property* ExtensionContainer::getPropertyByName(const char* name) const +{ auto prop = App::PropertyContainer::getPropertyByName(name); - if(prop) + if (prop) { return prop; + } - for(const auto& entry : _extensions) { + for (const auto& entry : _extensions) { auto prop = entry.second->extensionGetPropertyByName(name); - if(prop) + if (prop) { return prop; + } } return nullptr; } -short int ExtensionContainer::getPropertyType(const Property* prop) const { +short int ExtensionContainer::getPropertyType(const Property* prop) const +{ short int res = App::PropertyContainer::getPropertyType(prop); - if(res != 0) + if (res != 0) { return res; + } - for(const auto& entry : _extensions) { + for (const auto& entry : _extensions) { res = entry.second->extensionGetPropertyType(prop); - if(res != 0) + if (res != 0) { return res; + } } return 0; } -short int ExtensionContainer::getPropertyType(const char* name) const { +short int ExtensionContainer::getPropertyType(const char* name) const +{ short int res = App::PropertyContainer::getPropertyType(name); - if(res != 0) + if (res != 0) { return res; + } - for(const auto& entry : _extensions) { + for (const auto& entry : _extensions) { res = entry.second->extensionGetPropertyType(name); - if(res != 0) + if (res != 0) { return res; + } } return 0; } -const char* ExtensionContainer::getPropertyName(const Property* prop) const { +const char* ExtensionContainer::getPropertyName(const Property* prop) const +{ const char* res = App::PropertyContainer::getPropertyName(prop); - if (res) + if (res) { return res; + } for (const auto& entry : _extensions) { res = entry.second->extensionGetPropertyName(prop); - if (res) + if (res) { return res; + } } return nullptr; } -const char* ExtensionContainer::getPropertyGroup(const Property* prop) const { +const char* ExtensionContainer::getPropertyGroup(const Property* prop) const +{ const char* res = App::PropertyContainer::getPropertyGroup(prop); - if (res) + if (res) { return res; + } for (const auto& entry : _extensions) { res = entry.second->extensionGetPropertyGroup(prop); - if (res) + if (res) { return res; + } } return nullptr; } -const char* ExtensionContainer::getPropertyGroup(const char* name) const { +const char* ExtensionContainer::getPropertyGroup(const char* name) const +{ const char* res = App::PropertyContainer::getPropertyGroup(name); - if (res) + if (res) { return res; + } for (const auto& entry : _extensions) { res = entry.second->extensionGetPropertyGroup(name); - if (res) + if (res) { return res; + } } return nullptr; } -const char* ExtensionContainer::getPropertyDocumentation(const Property* prop) const { +const char* ExtensionContainer::getPropertyDocumentation(const Property* prop) const +{ const char* res = App::PropertyContainer::getPropertyDocumentation(prop); - if (res) + if (res) { return res; + } for (const auto& entry : _extensions) { res = entry.second->extensionGetPropertyDocumentation(prop); - if (res) + if (res) { return res; + } } return nullptr; } -const char* ExtensionContainer::getPropertyDocumentation(const char* name) const { +const char* ExtensionContainer::getPropertyDocumentation(const char* name) const +{ const char* res = App::PropertyContainer::getPropertyDocumentation(name); - if (res) + if (res) { return res; + } - for(const auto& entry : _extensions) { + for (const auto& entry : _extensions) { res = entry.second->extensionGetPropertyDocumentation(name); - if (res) + if (res) { return res; + } } return nullptr; } -void ExtensionContainer::onChanged(const Property* prop) { +void ExtensionContainer::onChanged(const Property* prop) +{ - //inform all extensions about changed property. This includes all properties from the - //extended object (this) as well as all extension properties - for(const auto& entry : _extensions) + // inform all extensions about changed property. This includes all properties from the + // extended object (this) as well as all extension properties + for (const auto& entry : _extensions) { entry.second->extensionOnChanged(prop); + } App::PropertyContainer::onChanged(prop); } -void ExtensionContainer::Save(Base::Writer& writer) const { +void ExtensionContainer::Save(Base::Writer& writer) const +{ - //Note: save extensions must be called first to ensure that the extension element is always the - // very first inside the object element. This is needed since extension element works together with - // an object attribute, and if another element would be read first the object attributes would be - // cleared. + // Note: save extensions must be called first to ensure that the extension element is always the + // very first inside the object element. This is needed since extension element works + // together with an object attribute, and if another element would be read first the + // object attributes would be cleared. saveExtensions(writer); App::PropertyContainer::Save(writer); } -void ExtensionContainer::Restore(Base::XMLReader& reader) { +void ExtensionContainer::Restore(Base::XMLReader& reader) +{ - //restore dynamic extensions. - //Note 1: The extension element must be read first, before all other object elements. That is - // needed as the element works together with an object element attribute, which would be - // cleared if another attribute is read first - //Note 2: This must happen before the py object of this container is used, as only in the - // pyobject constructor the extension methods are added to the container. + // restore dynamic extensions. + // Note 1: The extension element must be read first, before all other object elements. That is + // needed as the element works together with an object element attribute, which would be + // cleared if another attribute is read first + // Note 2: This must happen before the py object of this container is used, as only in the + // pyobject constructor the extension methods are added to the container. restoreExtensions(reader); App::PropertyContainer::Restore(reader); } -void ExtensionContainer::saveExtensions(Base::Writer& writer) const { +void ExtensionContainer::saveExtensions(Base::Writer& writer) const +{ - //we don't save anything if there are no dynamic extensions - if(!hasExtensions()) + // we don't save anything if there are no dynamic extensions + if (!hasExtensions()) { return; + } - //save dynamic extensions - writer.incInd(); // indentation for 'Extensions' - writer.Stream() << writer.ind() << "" << std::endl; - for(const auto& entry : _extensions) { + // save dynamic extensions + writer.incInd(); // indentation for 'Extensions' + writer.Stream() << writer.ind() << "" + << std::endl; + for (const auto& entry : _extensions) { auto ext = entry.second; - writer.incInd(); // indentation for 'Extension name' + writer.incInd(); // indentation for 'Extension name' writer.Stream() << writer.ind() << "getExtensionTypeId().getName() <<"\"" - << " name=\"" << ext->name() << "\">" << std::endl; - writer.incInd(); // indentation for the actual Extension + << " type=\"" << ext->getExtensionTypeId().getName() << "\"" + << " name=\"" << ext->name() << "\">" << std::endl; + writer.incInd(); // indentation for the actual Extension try { // We must make sure to handle all exceptions accordingly so that // the project file doesn't get invalidated. In the error case this // means to proceed instead of aborting the write operation. ext->extensionSave(writer); } - catch (const Base::Exception &e) { + catch (const Base::Exception& e) { Base::Console().Error("%s\n", e.what()); } - catch (const std::exception &e) { + catch (const std::exception& e) { Base::Console().Error("%s\n", e.what()); } catch (const char* e) { @@ -340,47 +395,51 @@ void ExtensionContainer::saveExtensions(Base::Writer& writer) const { } #ifndef FC_DEBUG catch (...) { - Base::Console().Error("ExtensionContainer::Save: Unknown C++ exception thrown. Try to continue...\n"); + Base::Console().Error( + "ExtensionContainer::Save: Unknown C++ exception thrown. Try to continue...\n"); } #endif - writer.decInd(); // indentation for the actual extension + writer.decInd(); // indentation for the actual extension writer.Stream() << writer.ind() << "" << std::endl; - writer.decInd(); // indentation for 'Extension name' + writer.decInd(); // indentation for 'Extension name' } writer.Stream() << writer.ind() << "" << std::endl; writer.decInd(); } -void ExtensionContainer::restoreExtensions(Base::XMLReader& reader) { +void ExtensionContainer::restoreExtensions(Base::XMLReader& reader) +{ - //Dynamic extensions are optional (also because they are introduced late into the document format) - //and hence it is possible that the element does not exist. As we cannot check for the existence of - //an element a object attribute is set if extensions are available. Here we check that - //attribute, and only if it exists the extensions element will be available. - if(!reader.hasAttribute("Extensions")) + // Dynamic extensions are optional (also because they are introduced late into the document + // format) and hence it is possible that the element does not exist. As we cannot check for the + // existence of an element a object attribute is set if extensions are available. Here we check + // that attribute, and only if it exists the extensions element will be available. + if (!reader.hasAttribute("Extensions")) { return; + } reader.readElement("Extensions"); int Cnt = reader.getAttributeAsInteger("Count"); - for (int i=0 ;i(extension.createInstance()); - //check if this really is a python extension! + // check if this really is a python extension! if (!ext->isPythonExtension()) { delete ext; std::stringstream str; @@ -390,16 +449,17 @@ void ExtensionContainer::restoreExtensions(Base::XMLReader& reader) { ext->initExtension(this); } - if (ext && strcmp(ext->getExtensionTypeId().getName(), Type) == 0) + if (ext && strcmp(ext->getExtensionTypeId().getName(), Type) == 0) { ext->extensionRestore(reader); + } } catch (const Base::XMLParseException&) { - throw; // re-throw + throw; // re-throw } - catch (const Base::Exception &e) { + catch (const Base::Exception& e) { Base::Console().Error("%s\n", e.what()); } - catch (const std::exception &e) { + catch (const std::exception& e) { Base::Console().Error("%s\n", e.what()); } catch (const char* e) { @@ -416,29 +476,35 @@ void ExtensionContainer::restoreExtensions(Base::XMLReader& reader) { reader.readEndElement("Extensions"); } -void ExtensionContainer::handleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName) +void ExtensionContainer::handleChangedPropertyName(Base::XMLReader& reader, + const char* TypeName, + const char* PropName) { - //inform all extensions about changed property name. This includes all properties from the - //extended object (this) as well as all extension properties - for(const auto& entry : _extensions) { + // inform all extensions about changed property name. This includes all properties from the + // extended object (this) as well as all extension properties + for (const auto& entry : _extensions) { bool handled = entry.second->extensionHandleChangedPropertyName(reader, TypeName, PropName); - if(handled) - return; // one property change needs only be handled once + if (handled) { + return; // one property change needs only be handled once + } } PropertyContainer::handleChangedPropertyName(reader, TypeName, PropName); } -void ExtensionContainer::handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, Property * prop) +void ExtensionContainer::handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + Property* prop) { - //inform all extensions about changed property type. This includes all properties from the - //extended object (this) as well as all extension properties - for(const auto& entry : _extensions) { + // inform all extensions about changed property type. This includes all properties from the + // extended object (this) as well as all extension properties + for (const auto& entry : _extensions) { bool handled = entry.second->extensionHandleChangedPropertyType(reader, TypeName, prop); - if(handled) - return; // one property change needs only be handled once + if (handled) { + return; // one property change needs only be handled once + } } PropertyContainer::handleChangedPropertyType(reader, TypeName, prop); diff --git a/src/App/ExtensionContainer.h b/src/App/ExtensionContainer.h index 7ff7091a3c..9ef6999b12 100644 --- a/src/App/ExtensionContainer.h +++ b/src/App/ExtensionContainer.h @@ -27,7 +27,8 @@ #include "PropertyContainer.h" -namespace App { +namespace App +{ class Extension; /** @@ -49,14 +50,14 @@ class Extension; * - Extensions can be added from c++ and python, even from both together * * The interoperability with python is highly important, as in FreeCAD all functionality should be - * as easily accessible from python as from c++. To ensure this, and as already noted, extensions can - * be added to a object from python. However, this means that it is not clear from the c++ object type - * if an extension was added or not. If added from c++ it becomes clear in the type due to the use of - * multiple inheritance. If added from python it is a runtime extension and not visible from type. - * Hence querying existing extensions of an object and accessing its methods works not by type - * casting but by the interface provided in ExtensionContainer. The default workflow is to query if - * an extension exists and then get the extension object. No matter if added from python or c++ this - * interface works always the same. + * as easily accessible from python as from c++. To ensure this, and as already noted, extensions + * can be added to a object from python. However, this means that it is not clear from the c++ + * object type if an extension was added or not. If added from c++ it becomes clear in the type due + * to the use of multiple inheritance. If added from python it is a runtime extension and not + * visible from type. Hence querying existing extensions of an object and accessing its methods + * works not by type casting but by the interface provided in ExtensionContainer. The default + * workflow is to query if an extension exists and then get the extension object. No matter if added + * from python or c++ this interface works always the same. * @code * if (object->hasExtension(GroupExtension::getClassTypeId())) { * App::GroupExtension* group = object->getExtensionByType(); @@ -77,8 +78,8 @@ class Extension; * * Here is a working example: * @code - * class AppExport Part : public App::DocumentObject, public App::FirstExtension, public App::SecondExtension { - * PROPERTY_HEADER_WITH_EXTENSIONS(App::Part); + * class AppExport Part : public App::DocumentObject, public App::FirstExtension, public + * App::SecondExtension { PROPERTY_HEADER_WITH_EXTENSIONS(App::Part); * }; * PROPERTY_SOURCE_WITH_EXTENSIONS(App::Part, App::DocumentObject) * Part::Part(void) { @@ -88,9 +89,9 @@ class Extension; * @endcode * * From python adding an extension is easier, it must be simply registered to a document object - * at object initialisation like done with properties. Note that the special python extension objects - * need to be added, not the c++ objects. Normally the only difference in name is the additional - * "Python" at the end of the extension name. + * at object initialisation like done with properties. Note that the special python extension + * objects need to be added, not the c++ objects. Normally the only difference in name is the + * additional "Python" at the end of the extension name. * @code{.py} * class Test(): * __init(self)__: @@ -99,86 +100,98 @@ class Extension; * @endcode * * Extensions can provide methods that should be overridden by the extended object for customisation - * of the extension behaviour. In c++ this is as simple as overriding the provided virtual functions. - * In python a class method must be provided which has the same name as the method to override. This - * method must not necessarily be in the object that is extended, it must be in the object which is - * provided to the "registerExtension" call as second argument. This second argument is used as a - * proxy and enqueired if the method to override exists in this proxy before calling it. + * of the extension behaviour. In c++ this is as simple as overriding the provided virtual + * functions. In python a class method must be provided which has the same name as the method to + * override. This method must not necessarily be in the object that is extended, it must be in the + * object which is provided to the "registerExtension" call as second argument. This second argument + * is used as a proxy and enqueired if the method to override exists in this proxy before calling + * it. * * For information on howto create extension see the documentation of Extension */ -class AppExport ExtensionContainer : public App::PropertyContainer +class AppExport ExtensionContainer: public App::PropertyContainer { TYPESYSTEM_HEADER_WITH_OVERRIDE(); public: - using ExtensionIterator = std::map::iterator; ExtensionContainer(); ~ExtensionContainer() override; void registerExtension(Base::Type extension, App::Extension* ext); - //returns first of type (or derived from if set to true) and throws otherwise - bool hasExtension(Base::Type, bool derived=true) const; - //this version does not check derived classes + // returns first of type (or derived from if set to true) and throws otherwise + bool hasExtension(Base::Type, bool derived = true) const; + // this version does not check derived classes bool hasExtension(const std::string& name) const; bool hasExtensions() const; - App::Extension* getExtension(Base::Type, bool derived = true, bool no_except=false) const; - //this version does not check derived classes + App::Extension* getExtension(Base::Type, bool derived = true, bool no_except = false) const; + // this version does not check derived classes App::Extension* getExtension(const std::string& name) const; // this version checks for derived types and doesn't throw template - ExtensionT* getExtension() const { - return static_cast(getExtension(ExtensionT::getExtensionClassTypeId(), true, true)); + ExtensionT* getExtension() const + { + return static_cast( + getExtension(ExtensionT::getExtensionClassTypeId(), true, true)); } - //returns first of type (or derived from) and throws otherwise + // returns first of type (or derived from) and throws otherwise template - ExtensionT* getExtensionByType(bool no_except=false, bool derived=true) const { - return static_cast(getExtension(ExtensionT::getExtensionClassTypeId(),derived,no_except)); + ExtensionT* getExtensionByType(bool no_except = false, bool derived = true) const + { + return static_cast( + getExtension(ExtensionT::getExtensionClassTypeId(), derived, no_except)); } - //get all extensions which have the given base class + // get all extensions which have the given base class std::vector getExtensionsDerivedFrom(Base::Type type) const; template - std::vector getExtensionsDerivedFromType() const { + std::vector getExtensionsDerivedFromType() const + { std::vector typevec; - for(const auto& entry : _extensions) { - if(entry.first.isDerivedFrom(ExtensionT::getExtensionClassTypeId())) + for (const auto& entry : _extensions) { + if (entry.first.isDerivedFrom(ExtensionT::getExtensionClassTypeId())) { typevec.push_back(static_cast(entry.second)); + } } return typevec; } - ExtensionIterator extensionBegin() {return _extensions.begin();} - ExtensionIterator extensionEnd() {return _extensions.end();} + ExtensionIterator extensionBegin() + { + return _extensions.begin(); + } + ExtensionIterator extensionEnd() + { + return _extensions.end(); + } /** @name Access properties */ //@{ /// find a property by its name - Property *getPropertyByName(const char* name) const override; + Property* getPropertyByName(const char* name) const override; /// get the name of a property const char* getPropertyName(const Property* prop) const override; /// get all properties of the class (including properties of the parent) - void getPropertyMap(std::map &Map) const override; + void getPropertyMap(std::map& Map) const override; /// get all properties of the class (including properties of the parent) - void getPropertyList(std::vector &List) const override; + void getPropertyList(std::vector& List) const override; /// get the Type of a Property short getPropertyType(const Property* prop) const override; /// get the Type of a named Property - short getPropertyType(const char *name) const override; + short getPropertyType(const char* name) const override; /// get the Group of a Property const char* getPropertyGroup(const Property* prop) const override; /// get the Group of a named Property - const char* getPropertyGroup(const char *name) const override; + const char* getPropertyGroup(const char* name) const override; /// get the Group of a Property const char* getPropertyDocumentation(const Property* prop) const override; /// get the Group of a named Property - const char* getPropertyDocumentation(const char *name) const override; + const char* getPropertyDocumentation(const char* name) const override; //@} void onChanged(const Property*) override; @@ -186,43 +199,50 @@ public: void Save(Base::Writer& writer) const override; void Restore(Base::XMLReader& reader) override; - //those methods save/restore the dynamic extensions without handling properties, which is something - //done by the default Save/Restore methods. + // those methods save/restore the dynamic extensions without handling properties, which is + // something done by the default Save/Restore methods. void saveExtensions(Base::Writer& writer) const; void restoreExtensions(Base::XMLReader& reader); - /** Extends the rules for handling property name changed, so that extensions are given an opportunity to handle it. - * If an extension handles a change, neither the rest of the extensions, nor the container itself get to handle it. + /** Extends the rules for handling property name changed, so that extensions are given an + * opportunity to handle it. If an extension handles a change, neither the rest of the + * extensions, nor the container itself get to handle it. * * Extensions get their extensionHandleChangedPropertyName() called. * - * If no extension handles the request, then the containers handleChangedPropertyName() is called. + * If no extension handles the request, then the containers handleChangedPropertyName() is + * called. */ - void handleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName) override; - /** Extends the rules for handling property type changed, so that extensions are given an opportunity to handle it. - * If an extension handles a change, neither the rest of the extensions, nor the container itself get to handle it. + void handleChangedPropertyName(Base::XMLReader& reader, + const char* TypeName, + const char* PropName) override; + /** Extends the rules for handling property type changed, so that extensions are given an + * opportunity to handle it. If an extension handles a change, neither the rest of the + * extensions, nor the container itself get to handle it. * * Extensions get their extensionHandleChangedPropertyType() called. * - * If no extension handles the request, then the containers handleChangedPropertyType() is called. + * If no extension handles the request, then the containers handleChangedPropertyType() is + * called. */ - void handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, Property * prop) override; + void handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + Property* prop) override; private: - //stored extensions + // stored extensions std::map _extensions; }; -#define PROPERTY_HEADER_WITH_EXTENSIONS(_class_) \ - PROPERTY_HEADER_WITH_OVERRIDE(_class) +#define PROPERTY_HEADER_WITH_EXTENSIONS(_class_) PROPERTY_HEADER_WITH_OVERRIDE(_class) /// We make sure that the PropertyData of the container is not connected to the one of the extension -#define PROPERTY_SOURCE_WITH_EXTENSIONS(_class_, _parentclass_) \ +#define PROPERTY_SOURCE_WITH_EXTENSIONS(_class_, _parentclass_) \ PROPERTY_SOURCE(_class_, _parentclass_) -#define PROPERTY_SOURCE_ABSTRACT_WITH_EXTENSIONS(_class_, _parentclass_) \ +#define PROPERTY_SOURCE_ABSTRACT_WITH_EXTENSIONS(_class_, _parentclass_) \ PROPERTY_SOURCE_ABSTRACT(_class_, _parentclass_) -} //App +} // namespace App -#endif // APP_EXTENSIONCONTAINER_H +#endif // APP_EXTENSIONCONTAINER_H diff --git a/src/App/ExtensionContainerPy.xml b/src/App/ExtensionContainerPy.xml index 2497c3dda1..da86226dc5 100644 --- a/src/App/ExtensionContainerPy.xml +++ b/src/App/ExtensionContainerPy.xml @@ -1,13 +1,13 @@  - diff --git a/src/App/ExtensionContainerPyImp.cpp b/src/App/ExtensionContainerPyImp.cpp index 3a22b9c906..0202d0a0b9 100644 --- a/src/App/ExtensionContainerPyImp.cpp +++ b/src/App/ExtensionContainerPyImp.cpp @@ -24,7 +24,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include "Application.h" @@ -41,22 +41,24 @@ std::string ExtensionContainerPy::representation() const return {""}; } -int ExtensionContainerPy::initialization() { +int ExtensionContainerPy::initialization() +{ if (!this->ob_type->tp_dict) { - if (PyType_Ready(this->ob_type) < 0) + if (PyType_Ready(this->ob_type) < 0) { return 0; + } } ExtensionContainer::ExtensionIterator it = this->getExtensionContainerPtr()->extensionBegin(); - for(; it != this->getExtensionContainerPtr()->extensionEnd(); ++it) { + for (; it != this->getExtensionContainerPtr()->extensionEnd(); ++it) { // The PyTypeObject is shared by all instances of this type and therefore // we have to add new methods only once. PyObject* obj = (*it).second->getExtensionPyObject(); PyMethodDef* meth = obj->ob_type->tp_methods; - PyTypeObject *type = this->ob_type; - PyObject *dict = type->tp_dict; + PyTypeObject* type = this->ob_type; + PyObject* dict = type->tp_dict; // make sure to do the initialization only once if (meth->ml_name) { @@ -67,12 +69,14 @@ int ExtensionContainerPy::initialization() { // to an instance Py_INCREF(dict); while (meth->ml_name) { - PyObject *func; + PyObject* func; func = PyCFunction_New(meth, 0); - if (!func) + if (!func) { break; - if (PyDict_SetItemString(dict, meth->ml_name, func) < 0) + } + if (PyDict_SetItemString(dict, meth->ml_name, func) < 0) { break; + } Py_DECREF(func); ++meth; } @@ -86,20 +90,22 @@ int ExtensionContainerPy::initialization() { return 1; } -int ExtensionContainerPy::finalization() { -/* - //we need to delete all added python extensions, as we are the owner! - ExtensionContainer::ExtensionIterator it = this->getExtensionContainerPtr()->extensionBegin(); - for(; it != this->getExtensionContainerPtr()->extensionEnd(); ++it) { - if((*it).second->isPythonExtension()) - delete (*it).second; - }*/ +int ExtensionContainerPy::finalization() +{ + /* + //we need to delete all added python extensions, as we are the owner! + ExtensionContainer::ExtensionIterator it = + this->getExtensionContainerPtr()->extensionBegin(); for(; it != + this->getExtensionContainerPtr()->extensionEnd(); ++it) { + if((*it).second->isPythonExtension()) + delete (*it).second; + }*/ return 1; } -PyObject* ExtensionContainerPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +PyObject* ExtensionContainerPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper { - // create a new instance of @self.export.Name@ and the Twin object + // create a new instance of @self.export.Name@ and the Twin object return nullptr; } @@ -109,7 +115,7 @@ int ExtensionContainerPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/) return 0; } -PyObject *ExtensionContainerPy::getCustomAttributes(const char* attr) const +PyObject* ExtensionContainerPy::getCustomAttributes(const char* attr) const { if (Base::streq(attr, "__dict__")) { PyObject* dict = PyDict_New(); @@ -119,12 +125,13 @@ PyObject *ExtensionContainerPy::getCustomAttributes(const char* attr) const Py_DECREF(props); } - ExtensionContainer::ExtensionIterator it = this->getExtensionContainerPtr()->extensionBegin(); + ExtensionContainer::ExtensionIterator it = + this->getExtensionContainerPtr()->extensionBegin(); for (; it != this->getExtensionContainerPtr()->extensionEnd(); ++it) { // The PyTypeObject is shared by all instances of this type and therefore // we have to add new methods only once. PyObject* obj = (*it).second->getExtensionPyObject(); - PyTypeObject *tp = Py_TYPE(obj); + PyTypeObject* tp = Py_TYPE(obj); if (tp && tp->tp_dict) { Py_XINCREF(tp->tp_dict); PyDict_Merge(dict, tp->tp_dict, 0); @@ -139,13 +146,13 @@ PyObject *ExtensionContainerPy::getCustomAttributes(const char* attr) const // Py_FindMethod is successful then a PyCFunction_New instance is returned // with the PyObject pointer of the extension to make sure the method will // be called for the correct instance. - PyObject *func = nullptr; + PyObject* func = nullptr; ExtensionContainer::ExtensionIterator it = this->getExtensionContainerPtr()->extensionBegin(); for (; it != this->getExtensionContainerPtr()->extensionEnd(); ++it) { // The PyTypeObject is shared by all instances of this type and therefore // we have to add new methods only once. PyObject* obj = (*it).second->getExtensionPyObject(); - PyObject *nameobj = PyUnicode_FromString(attr); + PyObject* nameobj = PyUnicode_FromString(attr); func = PyObject_GenericGetAttr(obj, nameobj); Py_DECREF(nameobj); Py_DECREF(obj); @@ -153,33 +160,36 @@ PyObject *ExtensionContainerPy::getCustomAttributes(const char* attr) const PyCFunctionObject* cfunc = reinterpret_cast(func); // OK, that's what we wanted - if (cfunc->m_self == obj) + if (cfunc->m_self == obj) { break; + } // otherwise cleanup the result again Py_DECREF(func); func = nullptr; } - PyErr_Clear(); // clear the error set inside Py_FindMethod + PyErr_Clear(); // clear the error set inside Py_FindMethod } return func; } -int ExtensionContainerPy::setCustomAttributes(const char* /*attr*/, PyObject * /*obj*/) +int ExtensionContainerPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { return 0; } -PyObject* ExtensionContainerPy::hasExtension(PyObject *args) { +PyObject* ExtensionContainerPy::hasExtension(PyObject* args) +{ - char *type; - PyObject *deriv = Py_True; - if (!PyArg_ParseTuple(args, "s|O!", &type, &PyBool_Type, &deriv)) + char* type; + PyObject* deriv = Py_True; + if (!PyArg_ParseTuple(args, "s|O!", &type, &PyBool_Type, &deriv)) { return nullptr; + } - //get the extension type asked for + // get the extension type asked for bool derived = Base::asBoolean(deriv); - Base::Type extension = Base::Type::fromName(type); + 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; @@ -194,30 +204,34 @@ PyObject* ExtensionContainerPy::hasExtension(PyObject *args) { return PyBool_FromLong(val ? 1 : 0); } -PyObject* ExtensionContainerPy::addExtension(PyObject *args) { +PyObject* ExtensionContainerPy::addExtension(PyObject* args) +{ - char *typeId; + char* typeId; PyObject* proxy = nullptr; - if (!PyArg_ParseTuple(args, "s|O", &typeId, &proxy)) + if (!PyArg_ParseTuple(args, "s|O", &typeId, &proxy)) { return nullptr; + } if (proxy) { - PyErr_SetString(PyExc_DeprecationWarning, "Second argument is deprecated. It is ignored and will be removed in future versions. " - "The default Python feature proxy is used for extension method overrides."); + PyErr_SetString( + PyExc_DeprecationWarning, + "Second argument is deprecated. It is ignored and will be removed in future versions. " + "The default Python feature proxy is used for extension method overrides."); PyErr_Print(); } - //get the extension type asked for - Base::Type extension = Base::Type::fromName(typeId); + // 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::TypeError(str.str()); } - //register the extension + // register the extension App::Extension* ext = static_cast(extension.createInstance()); - //check if this really is a python extension! + // check if this really is a python extension! if (!ext->isPythonExtension()) { delete ext; std::stringstream str; @@ -232,8 +246,8 @@ PyObject* ExtensionContainerPy::addExtension(PyObject *args) { // we have to add new methods only once. PyObject* obj = ext->getExtensionPyObject(); PyMethodDef* meth = obj->ob_type->tp_methods; - PyTypeObject *type = this->ob_type; - PyObject *dict = type->tp_dict; + PyTypeObject* type = this->ob_type; + PyObject* dict = type->tp_dict; // make sure to do the initialization only once if (meth->ml_name) { @@ -244,12 +258,14 @@ PyObject* ExtensionContainerPy::addExtension(PyObject *args) { // to an instance Py_INCREF(dict); while (meth->ml_name) { - PyObject *func; + PyObject* func; func = PyCFunction_New(meth, 0); - if (!func) + if (!func) { break; - if (PyDict_SetItemString(dict, meth->ml_name, func) < 0) + } + if (PyDict_SetItemString(dict, meth->ml_name, func) < 0) { break; + } Py_DECREF(func); ++meth; } @@ -259,8 +275,8 @@ PyObject* ExtensionContainerPy::addExtension(PyObject *args) { } Py_DECREF(obj); - - //throw the appropriate event + + // throw the appropriate event GetApplication().signalAddedDynamicExtension(*getExtensionContainerPtr(), typeId); Py_Return; diff --git a/src/App/ExtensionPy.xml b/src/App/ExtensionPy.xml index a499639e37..7551ad1e21 100644 --- a/src/App/ExtensionPy.xml +++ b/src/App/ExtensionPy.xml @@ -1,13 +1,13 @@  - diff --git a/src/App/ExtensionPyImp.cpp b/src/App/ExtensionPyImp.cpp index b57bcb73a2..23a1cf2b74 100644 --- a/src/App/ExtensionPyImp.cpp +++ b/src/App/ExtensionPyImp.cpp @@ -37,12 +37,12 @@ std::string ExtensionPy::representation() const return {""}; } -PyObject *ExtensionPy::getCustomAttributes(const char* /*attr*/) const +PyObject* ExtensionPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } -int ExtensionPy::setCustomAttributes(const char* /*attr*/, PyObject * /*obj*/) +int ExtensionPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { return 0; } diff --git a/src/App/ExtensionPython.h b/src/App/ExtensionPython.h index b6672f15d7..6ba59bd548 100644 --- a/src/App/ExtensionPython.h +++ b/src/App/ExtensionPython.h @@ -28,21 +28,23 @@ #include "Extension.h" #include "PropertyPythonObject.h" -namespace App { +namespace App +{ /** * Generic Python extension class which allows every extension derived * class to behave as a Python extension -- simply by subclassing. */ -template -class ExtensionPythonT : public ExtensionT //NOLINT +template +class ExtensionPythonT: public ExtensionT // NOLINT { EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::ExtensionPythonT); public: using Inherited = ExtensionT; - ExtensionPythonT() { + ExtensionPythonT() + { ExtensionT::m_isPythonExtension = true; ExtensionT::initExtensionType(ExtensionPythonT::getExtensionClassTypeId()); } @@ -50,73 +52,72 @@ public: ExtensionPythonT(const ExtensionPythonT&) = delete; ExtensionPythonT(ExtensionPythonT&&) = delete; - ExtensionPythonT& operator= (const ExtensionPythonT&) = delete; - ExtensionPythonT& operator= (ExtensionPythonT&&) = delete; + ExtensionPythonT& operator=(const ExtensionPythonT&) = delete; + ExtensionPythonT& operator=(ExtensionPythonT&&) = delete; }; using ExtensionPython = ExtensionPythonT; // Helper macros to define python extensions -#define EXTENSION_PROXY_FIRST(function) \ - Base::PyGILStateLocker lock;\ - Py::Object result;\ - try {\ - Property* proxy = this->getExtendedContainer()->getPropertyByName("Proxy");\ - if (proxy && proxy->is()) {\ - Py::Object feature = static_cast(proxy)->getValue();\ - if (feature.hasAttr(std::string("function"))) {\ - if (feature.hasAttr("__object__")) {\ +#define EXTENSION_PROXY_FIRST(function) \ + Base::PyGILStateLocker lock; \ + Py::Object result; \ + try { \ + Property* proxy = this->getExtendedContainer()->getPropertyByName("Proxy"); \ + if (proxy && proxy->is()) { \ + Py::Object feature = static_cast(proxy)->getValue(); \ + if (feature.hasAttr(std::string("function"))) { \ + if (feature.hasAttr("__object__")) { \ Py::Callable method(feature.getAttr(std::string("function"))); +#define EXTENSION_PROXY_SECOND(function) \ + result = method.apply(args); \ + } \ + else \ + { \ + Py::Callable method(feature.getAttr(std::string("function"))); - -#define EXTENSION_PROXY_SECOND(function)\ - result = method.apply(args);\ - }\ - else {\ - Py::Callable method(feature.getAttr(std::string("function"))); - -#define EXTENSION_PROXY_THIRD()\ - result = method.apply(args);\ - }\ - }\ - }\ - }\ - catch (Py::Exception&) {\ - Base::PyException e;\ - e.ReportException();\ +#define EXTENSION_PROXY_THIRD() \ + result = method.apply(args); \ + } \ + } \ + } \ + } \ + catch (Py::Exception&) \ + { \ + Base::PyException e; \ + e.ReportException(); \ } -#define EXTENSION_PROXY_NOARG(function)\ - EXTENSION_PROXY_FIRST(function) \ - Py::Tuple args;\ - EXTENSION_PROXY_SECOND(function) \ - Py::Tuple args(1);\ - args.setItem(0, Py::Object(this->getExtensionPyObject(), true));\ +#define EXTENSION_PROXY_NOARG(function) \ + EXTENSION_PROXY_FIRST(function) \ + Py::Tuple args; \ + EXTENSION_PROXY_SECOND(function) \ + Py::Tuple args(1); \ + args.setItem(0, Py::Object(this->getExtensionPyObject(), true)); \ EXTENSION_PROXY_THIRD() -#define EXTENSION_PROXY_ONEARG(function, arg)\ - EXTENSION_PROXY_FIRST(function) \ - Py::Tuple args;\ - args.setItem(0, arg); \ - EXTENSION_PROXY_SECOND(function) \ - Py::Tuple args(2);\ - args.setItem(0, Py::Object(this->getExtensionPyObject(), true));\ - args.setItem(1, arg); \ +#define EXTENSION_PROXY_ONEARG(function, arg) \ + EXTENSION_PROXY_FIRST(function) \ + Py::Tuple args; \ + args.setItem(0, arg); \ + EXTENSION_PROXY_SECOND(function) \ + Py::Tuple args(2); \ + args.setItem(0, Py::Object(this->getExtensionPyObject(), true)); \ + args.setItem(1, arg); \ EXTENSION_PROXY_THIRD() -#define EXTENSION_PYTHON_OVERRIDE_VOID_NOARGS(function)\ - virtual void function() override {\ - EXTENSION_PROXY_NOARGS(function)\ +#define EXTENSION_PYTHON_OVERRIDE_VOID_NOARGS(function) \ + virtual void function() override { EXTENSION_PROXY_NOARGS(function) }; + +#define EXTENSION_PYTHON_OVERRIDE_OBJECT_NOARGS(function) \ + virtual PyObject* function() override \ + { \ + EXTENSION_PROXY_NOARGS(function) \ + return res.ptr(); \ }; -#define EXTENSION_PYTHON_OVERRIDE_OBJECT_NOARGS(function)\ - virtual PyObject* function() override {\ - EXTENSION_PROXY_NOARGS(function)\ - return res.ptr();\ - }; +} // namespace App -} //App - -#endif // APP_EXTENSIONPYTHON_H +#endif // APP_EXTENSIONPYTHON_H diff --git a/src/App/FeatureCustom.h b/src/App/FeatureCustom.h index 3b1873d3fe..7dd377b18e 100644 --- a/src/App/FeatureCustom.h +++ b/src/App/FeatureCustom.h @@ -21,7 +21,6 @@ ***************************************************************************/ - #ifndef APP_FEATURECUSTOM_H #define APP_FEATURECUSTOM_H @@ -41,8 +40,8 @@ class Property; * it has no support for in Python written feature classes. * @author Werner Mayer */ -template -class FeatureCustomT : public FeatureT //NOLINT +template +class FeatureCustomT: public FeatureT // NOLINT { PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureCustomT); @@ -53,46 +52,55 @@ public: /** @name methods override DocumentObject */ //@{ - short mustExecute() const override { + short mustExecute() const override + { return FeatureT::mustExecute(); } /// recalculate the Feature - DocumentObjectExecReturn *execute() override { + DocumentObjectExecReturn* execute() override + { return FeatureT::execute(); } /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return FeatureT::getViewProviderName(); } - PyObject *getPyObject() override { + PyObject* getPyObject() override + { return FeatureT::getPyObject(); } - void setPyObject(PyObject *obj) override { + void setPyObject(PyObject* obj) override + { FeatureT::setPyObject(obj); } protected: - void onBeforeChange(const Property* prop) override { + void onBeforeChange(const Property* prop) override + { FeatureT::onBeforeChange(prop); } - void onChanged(const Property* prop) override { + void onChanged(const Property* prop) override + { FeatureT::onChanged(prop); } - void onDocumentRestored() override { + void onDocumentRestored() override + { FeatureT::onDocumentRestored(); } - void onSettingDocument() override { + void onSettingDocument() override + { FeatureT::onSettingDocument(); } public: FeatureCustomT(const FeatureCustomT&) = delete; FeatureCustomT(FeatureCustomT&&) = delete; - FeatureCustomT& operator= (const FeatureCustomT&) = delete; - FeatureCustomT& operator= (FeatureCustomT&&) = delete; + FeatureCustomT& operator=(const FeatureCustomT&) = delete; + FeatureCustomT& operator=(FeatureCustomT&&) = delete; }; -} //namespace App +} // namespace App -#endif // APP_FEATURECUSTOM_H +#endif // APP_FEATURECUSTOM_H diff --git a/src/App/FeaturePython.cpp b/src/App/FeaturePython.cpp index fa9c7018e9..fdb7640821 100644 --- a/src/App/FeaturePython.cpp +++ b/src/App/FeaturePython.cpp @@ -23,7 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include @@ -39,8 +39,7 @@ using namespace App; FeaturePythonImp::FeaturePythonImp(App::DocumentObject* o) : object(o) -{ -} +{} FeaturePythonImp::~FeaturePythonImp() { @@ -56,7 +55,8 @@ FeaturePythonImp::~FeaturePythonImp() } } -void FeaturePythonImp::init(PyObject *pyobj) { +void FeaturePythonImp::init(PyObject* pyobj) +{ Base::PyGILStateLocker lock; has__object__ = !!PyObject_HasAttrString(pyobj, "__object__"); @@ -66,11 +66,11 @@ void FeaturePythonImp::init(PyObject *pyobj) { FC_PY_FEATURE_PYTHON } -#define FC_PY_CALL_CHECK(_name) _FC_PY_CALL_CHECK(_name,return(false)) +#define FC_PY_CALL_CHECK(_name) _FC_PY_CALL_CHECK(_name, return (false)) /*! - Calls the execute() method of the Python feature class. If the Python feature class doesn't have an execute() - method or if it returns False this method also return false and true otherwise. + Calls the execute() method of the Python feature class. If the Python feature class doesn't have an + execute() method or if it returns False this method also return false and true otherwise. */ bool FeaturePythonImp::execute() { @@ -79,16 +79,18 @@ bool FeaturePythonImp::execute() try { if (has__object__) { Py::Object res = Base::pyCall(py_execute.ptr()); - if (res.isBoolean() && !res.isTrue()) + if (res.isBoolean() && !res.isTrue()) { return false; + } return true; } else { Py::Tuple args(1); args.setItem(0, Py::Object(object->getPyObject(), true)); - Py::Object res = Base::pyCall(py_execute.ptr(),args.ptr()); - if (res.isBoolean() && !res.isTrue()) + Py::Object res = Base::pyCall(py_execute.ptr(), args.ptr()); + if (res.isBoolean() && !res.isTrue()) { return false; + } return true; } } @@ -97,7 +99,7 @@ bool FeaturePythonImp::execute() PyErr_Clear(); return false; } - Base::PyException::ThrowException(); // extract the Python error text + Base::PyException::ThrowException(); // extract the Python error text } return false; @@ -115,12 +117,12 @@ bool FeaturePythonImp::mustExecute() const else { Py::Tuple args(1); args.setItem(0, Py::Object(object->getPyObject(), true)); - Py::Object res(Base::pyCall(py_mustExecute.ptr(),args.ptr())); + Py::Object res(Base::pyCall(py_mustExecute.ptr(), args.ptr())); return res.isTrue(); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } return false; @@ -129,54 +131,58 @@ bool FeaturePythonImp::mustExecute() const void FeaturePythonImp::onBeforeChange(const Property* prop) { - if (py_onBeforeChange.isNone()) + if (py_onBeforeChange.isNone()) { return; + } // Run the execute method of the proxy object. Base::PyGILStateLocker lock; try { - const char *prop_name = object->getPropertyName(prop); - if (!prop_name) + const char* prop_name = object->getPropertyName(prop); + if (!prop_name) { return; + } if (has__object__) { Py::Tuple args(1); args.setItem(0, Py::String(prop_name)); - Base::pyCall(py_onBeforeChange.ptr(),args.ptr()); + Base::pyCall(py_onBeforeChange.ptr(), args.ptr()); } else { Py::Tuple args(2); args.setItem(0, Py::Object(object->getPyObject(), true)); args.setItem(1, Py::String(prop_name)); - Base::pyCall(py_onBeforeChange.ptr(),args.ptr()); + Base::pyCall(py_onBeforeChange.ptr(), args.ptr()); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } -bool FeaturePythonImp::onBeforeChangeLabel(std::string &newLabel) +bool FeaturePythonImp::onBeforeChangeLabel(std::string& newLabel) { - if(py_onBeforeChangeLabel.isNone()) + if (py_onBeforeChangeLabel.isNone()) { return false; + } // Run the execute method of the proxy object. Base::PyGILStateLocker lock; try { Py::Tuple args(2); args.setItem(0, Py::Object(object->getPyObject(), true)); - args.setItem(1,Py::String(newLabel)); - Py::Object ret(Base::pyCall(py_onBeforeChangeLabel.ptr(),args.ptr())); - if(!ret.isNone()) { - if(!ret.isString()) + args.setItem(1, Py::String(newLabel)); + Py::Object ret(Base::pyCall(py_onBeforeChangeLabel.ptr(), args.ptr())); + if (!ret.isNone()) { + if (!ret.isString()) { throw Py::TypeError("onBeforeChangeLabel expects to return a string"); + } newLabel = ret.as_string(); return true; } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } return false; @@ -184,35 +190,37 @@ bool FeaturePythonImp::onBeforeChangeLabel(std::string &newLabel) void FeaturePythonImp::onChanged(const Property* prop) { - if (py_onChanged.isNone()) + if (py_onChanged.isNone()) { return; + } // Run the execute method of the proxy object. Base::PyGILStateLocker lock; try { - const char *prop_name = object->getPropertyName(prop); - if (!prop_name) + const char* prop_name = object->getPropertyName(prop); + if (!prop_name) { return; + } if (has__object__) { Py::Tuple args(1); args.setItem(0, Py::String(prop_name)); - Base::pyCall(py_onChanged.ptr(),args.ptr()); + Base::pyCall(py_onChanged.ptr(), args.ptr()); } else { Py::Tuple args(2); args.setItem(0, Py::Object(object->getPyObject(), true)); args.setItem(1, Py::String(prop_name)); - Base::pyCall(py_onChanged.ptr(),args.ptr()); + Base::pyCall(py_onChanged.ptr(), args.ptr()); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } void FeaturePythonImp::onDocumentRestored() { - _FC_PY_CALL_CHECK(onDocumentRestored,return); + _FC_PY_CALL_CHECK(onDocumentRestored, return); // Run the execute method of the proxy object. Base::PyGILStateLocker lock; @@ -223,11 +231,11 @@ void FeaturePythonImp::onDocumentRestored() else { Py::Tuple args(1); args.setItem(0, Py::Object(object->getPyObject(), true)); - Base::pyCall(py_onDocumentRestored.ptr(),args.ptr()); + Base::pyCall(py_onDocumentRestored.ptr(), args.ptr()); } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } @@ -249,57 +257,71 @@ void FeaturePythonImp::unsetupObject() } } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } } -bool FeaturePythonImp::getSubObject(DocumentObject *&ret, const char *subname, - PyObject **pyObj, Base::Matrix4D *_mat, bool transform, int depth) const +bool FeaturePythonImp::getSubObject(DocumentObject*& ret, + const char* subname, + PyObject** pyObj, + Base::Matrix4D* _mat, + bool transform, + int depth) const { FC_PY_CALL_CHECK(getSubObject); Base::PyGILStateLocker lock; try { Py::Tuple args(6); args.setItem(0, Py::Object(object->getPyObject(), true)); - if(!subname) subname = ""; - args.setItem(1,Py::String(subname)); - args.setItem(2,Py::Int(pyObj?2:1)); - Base::MatrixPy *pyMat = new Base::MatrixPy(new Base::Matrix4D); - if(_mat) *pyMat->getMatrixPtr() = *_mat; - args.setItem(3,Py::asObject(pyMat)); - args.setItem(4,Py::Boolean(transform)); - args.setItem(5,Py::Int(depth)); + if (!subname) { + subname = ""; + } + args.setItem(1, Py::String(subname)); + args.setItem(2, Py::Int(pyObj ? 2 : 1)); + Base::MatrixPy* pyMat = new Base::MatrixPy(new Base::Matrix4D); + if (_mat) { + *pyMat->getMatrixPtr() = *_mat; + } + args.setItem(3, Py::asObject(pyMat)); + args.setItem(4, Py::Boolean(transform)); + args.setItem(5, Py::Int(depth)); - Py::Object res(Base::pyCall(py_getSubObject.ptr(),args.ptr())); - if(res.isNone()) { + Py::Object res(Base::pyCall(py_getSubObject.ptr(), args.ptr())); + if (res.isNone()) { ret = nullptr; return true; } - if(!res.isTrue()) + if (!res.isTrue()) { return false; - if(!res.isSequence()) + } + if (!res.isSequence()) { throw Py::TypeError("getSubObject expects return type of tuple"); + } Py::Sequence seq(res); - if(seq.length() < 2 || - (!seq.getItem(0).isNone() && - !PyObject_TypeCheck(seq.getItem(0).ptr(),&DocumentObjectPy::Type)) || - !PyObject_TypeCheck(seq.getItem(1).ptr(),&Base::MatrixPy::Type)) - { + if (seq.length() < 2 + || (!seq.getItem(0).isNone() + && !PyObject_TypeCheck(seq.getItem(0).ptr(), &DocumentObjectPy::Type)) + || !PyObject_TypeCheck(seq.getItem(1).ptr(), &Base::MatrixPy::Type)) { throw Py::TypeError("getSubObject expects return type of (obj,matrix,pyobj)"); } - if(_mat) + if (_mat) { *_mat = *static_cast(seq.getItem(1).ptr())->getMatrixPtr(); - if(pyObj) { - if(seq.length()>2) - *pyObj = Py::new_reference_to(seq.getItem(2)); - else - *pyObj = Py::new_reference_to(Py::None()); } - if(seq.getItem(0).isNone()) + if (pyObj) { + if (seq.length() > 2) { + *pyObj = Py::new_reference_to(seq.getItem(2)); + } + else { + *pyObj = Py::new_reference_to(Py::None()); + } + } + if (seq.getItem(0).isNone()) { ret = nullptr; - else + } + else { ret = static_cast(seq.getItem(0).ptr())->getDocumentObjectPtr(); + } return true; } catch (Py::Exception&) { @@ -307,30 +329,34 @@ bool FeaturePythonImp::getSubObject(DocumentObject *&ret, const char *subname, PyErr_Clear(); return false; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); ret = nullptr; return true; } } -bool FeaturePythonImp::getSubObjects(std::vector &ret, int reason) const { +bool FeaturePythonImp::getSubObjects(std::vector& ret, int reason) const +{ FC_PY_CALL_CHECK(getSubObjects); Base::PyGILStateLocker lock; try { Py::Tuple args(2); args.setItem(0, Py::Object(object->getPyObject(), true)); args.setItem(1, Py::Int(reason)); - Py::Object res(Base::pyCall(py_getSubObjects.ptr(),args.ptr())); - if(!res.isTrue()) + Py::Object res(Base::pyCall(py_getSubObjects.ptr(), args.ptr())); + if (!res.isTrue()) { return true; - if(!res.isSequence()) + } + if (!res.isSequence()) { throw Py::TypeError("getSubObjects expects return type of tuple"); + } Py::Sequence seq(res); - for(Py_ssize_t i=0;i &ret, int reason) PyErr_Clear(); return false; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); return true; } } -bool FeaturePythonImp::getLinkedObject(DocumentObject *&ret, bool recurse, - Base::Matrix4D *_mat, bool transform, int depth) const +bool FeaturePythonImp::getLinkedObject(DocumentObject*& ret, + bool recurse, + Base::Matrix4D* _mat, + bool transform, + int depth) const { FC_PY_CALL_CHECK(getLinkedObject); Base::PyGILStateLocker lock; try { Py::Tuple args(5); args.setItem(0, Py::Object(object->getPyObject(), true)); - args.setItem(1,Py::Boolean(recurse)); - Base::MatrixPy *pyMat = new Base::MatrixPy(new Base::Matrix4D); - if(_mat) *pyMat->getMatrixPtr() = *_mat; - args.setItem(2,Py::asObject(pyMat)); - args.setItem(3,Py::Boolean(transform)); - args.setItem(4,Py::Int(depth)); + args.setItem(1, Py::Boolean(recurse)); + Base::MatrixPy* pyMat = new Base::MatrixPy(new Base::Matrix4D); + if (_mat) { + *pyMat->getMatrixPtr() = *_mat; + } + args.setItem(2, Py::asObject(pyMat)); + args.setItem(3, Py::Boolean(transform)); + args.setItem(4, Py::Int(depth)); - Py::Object res(Base::pyCall(py_getLinkedObject.ptr(),args.ptr())); - if(!res.isTrue()) { + Py::Object res(Base::pyCall(py_getLinkedObject.ptr(), args.ptr())); + if (!res.isTrue()) { ret = object; return true; } - if(!res.isSequence()) - throw Py::TypeError("getLinkedObject expects return type of (object,matrix)"); - Py::Sequence seq(res); - if(seq.length() != 2 || - (!seq.getItem(0).isNone() && - !PyObject_TypeCheck(seq.getItem(0).ptr(),&DocumentObjectPy::Type)) || - !PyObject_TypeCheck(seq.getItem(1).ptr(),&Base::MatrixPy::Type)) - { + if (!res.isSequence()) { throw Py::TypeError("getLinkedObject expects return type of (object,matrix)"); } - if(_mat) + Py::Sequence seq(res); + if (seq.length() != 2 + || (!seq.getItem(0).isNone() + && !PyObject_TypeCheck(seq.getItem(0).ptr(), &DocumentObjectPy::Type)) + || !PyObject_TypeCheck(seq.getItem(1).ptr(), &Base::MatrixPy::Type)) { + throw Py::TypeError("getLinkedObject expects return type of (object,matrix)"); + } + if (_mat) { *_mat = *static_cast(seq.getItem(1).ptr())->getMatrixPtr(); - if(seq.getItem(0).isNone()) + } + if (seq.getItem(0).isNone()) { ret = object; - else + } + else { ret = static_cast(seq.getItem(0).ptr())->getDocumentObjectPtr(); + } return true; } catch (Py::Exception&) { @@ -389,28 +423,27 @@ bool FeaturePythonImp::getLinkedObject(DocumentObject *&ret, bool recurse, PyErr_Clear(); return false; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); ret = nullptr; return true; } } -PyObject *FeaturePythonImp::getPyObject() +PyObject* FeaturePythonImp::getPyObject() { // ref counter is set to 1 return new FeaturePythonPyT(object); } -FeaturePythonImp::ValueT -FeaturePythonImp::hasChildElement() const +FeaturePythonImp::ValueT FeaturePythonImp::hasChildElement() const { - _FC_PY_CALL_CHECK(hasChildElement,return(NotImplemented)); + _FC_PY_CALL_CHECK(hasChildElement, return (NotImplemented)); Base::PyGILStateLocker lock; try { Py::Tuple args(1); args.setItem(0, Py::Object(object->getPyObject(), true)); - Py::Boolean ok(Base::pyCall(py_hasChildElement.ptr(),args.ptr())); + Py::Boolean ok(Base::pyCall(py_hasChildElement.ptr(), args.ptr())); return static_cast(ok) ? Accepted : Rejected; } catch (Py::Exception&) { @@ -419,48 +452,50 @@ FeaturePythonImp::hasChildElement() const return NotImplemented; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); return Rejected; } } -int FeaturePythonImp::isElementVisible(const char *element) const { - _FC_PY_CALL_CHECK(isElementVisible,return(-2)); +int FeaturePythonImp::isElementVisible(const char* element) const +{ + _FC_PY_CALL_CHECK(isElementVisible, return (-2)); Base::PyGILStateLocker lock; try { Py::Tuple args(2); args.setItem(0, Py::Object(object->getPyObject(), true)); - args.setItem(1,Py::String(element?element:"")); - return Py::Int(Base::pyCall(py_isElementVisible.ptr(),args.ptr())); + args.setItem(1, Py::String(element ? element : "")); + return Py::Int(Base::pyCall(py_isElementVisible.ptr(), args.ptr())); } catch (Py::Exception&) { if (PyErr_ExceptionMatches(PyExc_NotImplementedError)) { PyErr_Clear(); return -2; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); return -1; } } -int FeaturePythonImp::setElementVisible(const char *element, bool visible) { - _FC_PY_CALL_CHECK(setElementVisible,return(-2)); +int FeaturePythonImp::setElementVisible(const char* element, bool visible) +{ + _FC_PY_CALL_CHECK(setElementVisible, return (-2)); Base::PyGILStateLocker lock; try { Py::Tuple args(3); args.setItem(0, Py::Object(object->getPyObject(), true)); - args.setItem(1,Py::String(element?element:"")); - args.setItem(2,Py::Boolean(visible)); - return Py::Int(Base::pyCall(py_setElementVisible.ptr(),args.ptr())); + args.setItem(1, Py::String(element ? element : "")); + args.setItem(2, Py::Boolean(visible)); + return Py::Int(Base::pyCall(py_setElementVisible.ptr(), args.ptr())); } catch (Py::Exception&) { if (PyErr_ExceptionMatches(PyExc_NotImplementedError)) { PyErr_Clear(); return -2; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); return -1; } @@ -468,30 +503,29 @@ int FeaturePythonImp::setElementVisible(const char *element, bool visible) { std::string FeaturePythonImp::getViewProviderName() { - _FC_PY_CALL_CHECK(getViewProviderName,return(std::string())); + _FC_PY_CALL_CHECK(getViewProviderName, return (std::string())); Base::PyGILStateLocker lock; try { Py::TupleN args(Py::Object(object->getPyObject(), true)); - Py::String ret(Base::pyCall(py_getViewProviderName.ptr(),args.ptr())); + Py::String ret(Base::pyCall(py_getViewProviderName.ptr(), args.ptr())); return ret.as_string(); } catch (Py::Exception&) { - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } return {}; } -FeaturePythonImp::ValueT -FeaturePythonImp::canLinkProperties() const +FeaturePythonImp::ValueT FeaturePythonImp::canLinkProperties() const { - _FC_PY_CALL_CHECK(canLinkProperties,return(NotImplemented)); + _FC_PY_CALL_CHECK(canLinkProperties, return (NotImplemented)); Base::PyGILStateLocker lock; try { Py::Tuple args(1); args.setItem(0, Py::Object(object->getPyObject(), true)); - Py::Boolean ok(Base::pyCall(py_canLinkProperties.ptr(),args.ptr())); + Py::Boolean ok(Base::pyCall(py_canLinkProperties.ptr(), args.ptr())); return ok ? Accepted : Rejected; } catch (Py::Exception&) { @@ -499,21 +533,20 @@ FeaturePythonImp::canLinkProperties() const PyErr_Clear(); return NotImplemented; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); return Rejected; } } -FeaturePythonImp::ValueT -FeaturePythonImp::allowDuplicateLabel() const +FeaturePythonImp::ValueT FeaturePythonImp::allowDuplicateLabel() const { - _FC_PY_CALL_CHECK(allowDuplicateLabel,return(NotImplemented)); + _FC_PY_CALL_CHECK(allowDuplicateLabel, return (NotImplemented)); Base::PyGILStateLocker lock; try { Py::Tuple args(1); args.setItem(0, Py::Object(object->getPyObject(), true)); - Py::Boolean ok(Base::pyCall(py_allowDuplicateLabel.ptr(),args.ptr())); + Py::Boolean ok(Base::pyCall(py_allowDuplicateLabel.ptr(), args.ptr())); return ok ? Accepted : Rejected; } catch (Py::Exception&) { @@ -522,19 +555,20 @@ FeaturePythonImp::allowDuplicateLabel() const return NotImplemented; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); return Rejected; } } -int FeaturePythonImp::canLoadPartial() const { - _FC_PY_CALL_CHECK(canLoadPartial,return(-1)); +int FeaturePythonImp::canLoadPartial() const +{ + _FC_PY_CALL_CHECK(canLoadPartial, return (-1)); Base::PyGILStateLocker lock; try { Py::Tuple args(1); args.setItem(0, Py::Object(object->getPyObject(), true)); - Py::Int ret(Base::pyCall(py_canLoadPartial.ptr(),args.ptr())); + Py::Int ret(Base::pyCall(py_canLoadPartial.ptr(), args.ptr())); return ret; } catch (Py::Exception&) { @@ -542,28 +576,28 @@ int FeaturePythonImp::canLoadPartial() const { PyErr_Clear(); return -1; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); return 0; } } -FeaturePythonImp::ValueT -FeaturePythonImp::redirectSubName(std::ostringstream &ss, - App::DocumentObject *topParent, - App::DocumentObject *child) const +FeaturePythonImp::ValueT FeaturePythonImp::redirectSubName(std::ostringstream& ss, + App::DocumentObject* topParent, + App::DocumentObject* child) const { - _FC_PY_CALL_CHECK(redirectSubName,return(NotImplemented)); + _FC_PY_CALL_CHECK(redirectSubName, return (NotImplemented)); Base::PyGILStateLocker lock; try { Py::Tuple args(4); args.setItem(0, Py::Object(object->getPyObject(), true)); - args.setItem(1,Py::String(ss.str())); - args.setItem(2,topParent?Py::Object(topParent->getPyObject(),true):Py::Object()); - args.setItem(3,child?Py::Object(child->getPyObject(),true):Py::Object()); - Py::Object ret(Base::pyCall(py_redirectSubName.ptr(),args.ptr())); - if (ret.isNone()) + args.setItem(1, Py::String(ss.str())); + args.setItem(2, topParent ? Py::Object(topParent->getPyObject(), true) : Py::Object()); + args.setItem(3, child ? Py::Object(child->getPyObject(), true) : Py::Object()); + Py::Object ret(Base::pyCall(py_redirectSubName.ptr(), args.ptr())); + if (ret.isNone()) { return Rejected; + } ss.str(""); ss << ret.as_string(); return Accepted; @@ -574,20 +608,20 @@ FeaturePythonImp::redirectSubName(std::ostringstream &ss, return NotImplemented; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); return Rejected; } } -bool FeaturePythonImp::editProperty(const char *name) +bool FeaturePythonImp::editProperty(const char* name) { - _FC_PY_CALL_CHECK(editProperty,return false); + _FC_PY_CALL_CHECK(editProperty, return false); Base::PyGILStateLocker lock; try { Py::Tuple args(1); args.setItem(0, Py::String(name)); - Py::Object ret(Base::pyCall(py_editProperty.ptr(),args.ptr())); + Py::Object ret(Base::pyCall(py_editProperty.ptr(), args.ptr())); return ret.isTrue(); } catch (Py::Exception&) { @@ -596,7 +630,7 @@ bool FeaturePythonImp::editProperty(const char *name) return false; } - Base::PyException e; // extract the Python error text + Base::PyException e; // extract the Python error text e.ReportException(); } return false; @@ -604,29 +638,37 @@ bool FeaturePythonImp::editProperty(const char *name) // --------------------------------------------------------- -namespace App { +namespace App +{ PROPERTY_SOURCE_TEMPLATE(App::FeaturePython, App::DocumentObject) -template<> const char* App::FeaturePython::getViewProviderName() const { +template<> +const char* App::FeaturePython::getViewProviderName() const +{ return "Gui::ViewProviderFeaturePython"; } -template<> PyObject* App::FeaturePython::getPyObject() { +template<> +PyObject* App::FeaturePython::getPyObject() +{ if (PythonObject.is(Py::_None())) { // ref counter is set to 1 - PythonObject = Py::Object(new FeaturePythonPyT(this),true); + PythonObject = Py::Object(new FeaturePythonPyT(this), true); } return Py::new_reference_to(PythonObject); } // explicit template instantiation template class AppExport FeaturePythonT; -} +} // namespace App // --------------------------------------------------------- -namespace App { +namespace App +{ PROPERTY_SOURCE_TEMPLATE(App::GeometryPython, App::GeoFeature) -template<> const char* App::GeometryPython::getViewProviderName() const { +template<> +const char* App::GeometryPython::getViewProviderName() const +{ return "Gui::ViewProviderGeometryPython"; } // explicit template instantiation template class AppExport FeaturePythonT; -} +} // namespace App diff --git a/src/App/FeaturePython.h b/src/App/FeaturePython.h index d57747bfbb..c9208e3b95 100644 --- a/src/App/FeaturePython.h +++ b/src/App/FeaturePython.h @@ -21,7 +21,6 @@ ***************************************************************************/ - #ifndef APP_FEATUREPYTHON_H #define APP_FEATUREPYTHON_H @@ -38,10 +37,11 @@ class Property; class AppExport FeaturePythonImp { public: - enum ValueT { - NotImplemented = 0, // not handled - Accepted = 1, // handled and accepted - Rejected = 2 // handled and rejected + enum ValueT + { + NotImplemented = 0, // not handled + Accepted = 1, // handled and accepted + Rejected = 2 // handled and rejected }; explicit FeaturePythonImp(App::DocumentObject*); @@ -50,93 +50,95 @@ public: bool execute(); bool mustExecute() const; void onBeforeChange(const Property* prop); - bool onBeforeChangeLabel(std::string &newLabel); + bool onBeforeChangeLabel(std::string& newLabel); void onChanged(const Property* prop); void onDocumentRestored(); void unsetupObject(); std::string getViewProviderName(); - PyObject *getPyObject(); + PyObject* getPyObject(); - bool getSubObject(App::DocumentObject *&ret, const char *subname, PyObject **pyObj, - Base::Matrix4D *mat, bool transform, int depth) const; + bool getSubObject(App::DocumentObject*& ret, + const char* subname, + PyObject** pyObj, + Base::Matrix4D* mat, + bool transform, + int depth) const; - bool getSubObjects(std::vector &ret, int reason) const; + bool getSubObjects(std::vector& ret, int reason) const; - bool getLinkedObject(App::DocumentObject *&ret, bool recurse, - Base::Matrix4D *mat, bool transform, int depth) const; + bool getLinkedObject(App::DocumentObject*& ret, + bool recurse, + Base::Matrix4D* mat, + bool transform, + int depth) const; ValueT canLinkProperties() const; ValueT allowDuplicateLabel() const; - ValueT redirectSubName(std::ostringstream &ss, - App::DocumentObject *topParent, - App::DocumentObject *child) const; + ValueT redirectSubName(std::ostringstream& ss, + App::DocumentObject* topParent, + App::DocumentObject* child) const; int canLoadPartial() const; /// return true to activate tree view group object handling ValueT hasChildElement() const; /// Get sub-element visibility - int isElementVisible(const char *) const; + int isElementVisible(const char*) const; /// Set sub-element visibility - int setElementVisible(const char *, bool); + int setElementVisible(const char*, bool); - bool editProperty(const char *propName); + bool editProperty(const char* propName); private: App::DocumentObject* object; - bool has__object__{false}; + bool has__object__ {false}; -#define FC_PY_FEATURE_PYTHON \ - FC_PY_ELEMENT(execute)\ - FC_PY_ELEMENT(mustExecute)\ - FC_PY_ELEMENT(onBeforeChange)\ - FC_PY_ELEMENT(onBeforeChangeLabel)\ - FC_PY_ELEMENT(onChanged)\ - FC_PY_ELEMENT(onDocumentRestored)\ - FC_PY_ELEMENT(unsetupObject)\ - FC_PY_ELEMENT(getViewProviderName)\ - FC_PY_ELEMENT(getSubObject)\ - FC_PY_ELEMENT(getSubObjects)\ - FC_PY_ELEMENT(getLinkedObject)\ - FC_PY_ELEMENT(canLinkProperties)\ - FC_PY_ELEMENT(allowDuplicateLabel)\ - FC_PY_ELEMENT(redirectSubName)\ - FC_PY_ELEMENT(canLoadPartial)\ - FC_PY_ELEMENT(hasChildElement)\ - FC_PY_ELEMENT(isElementVisible)\ - FC_PY_ELEMENT(setElementVisible)\ - FC_PY_ELEMENT(editProperty)\ +#define FC_PY_FEATURE_PYTHON \ + FC_PY_ELEMENT(execute) \ + FC_PY_ELEMENT(mustExecute) \ + FC_PY_ELEMENT(onBeforeChange) \ + FC_PY_ELEMENT(onBeforeChangeLabel) \ + FC_PY_ELEMENT(onChanged) \ + FC_PY_ELEMENT(onDocumentRestored) \ + FC_PY_ELEMENT(unsetupObject) \ + FC_PY_ELEMENT(getViewProviderName) \ + FC_PY_ELEMENT(getSubObject) \ + FC_PY_ELEMENT(getSubObjects) \ + FC_PY_ELEMENT(getLinkedObject) \ + FC_PY_ELEMENT(canLinkProperties) \ + FC_PY_ELEMENT(allowDuplicateLabel) \ + FC_PY_ELEMENT(redirectSubName) \ + FC_PY_ELEMENT(canLoadPartial) \ + FC_PY_ELEMENT(hasChildElement) \ + FC_PY_ELEMENT(isElementVisible) \ + FC_PY_ELEMENT(setElementVisible) \ + FC_PY_ELEMENT(editProperty) -#define FC_PY_ELEMENT_DEFINE(_name) \ - Py::Object py_##_name; +#define FC_PY_ELEMENT_DEFINE(_name) Py::Object py_##_name; -#define FC_PY_ELEMENT_INIT(_name) \ - FC_PY_GetCallable(pyobj,#_name,py_##_name);\ - if(!py_##_name.isNone()) {\ - PyObject *pyRecursive = PyObject_GetAttrString(pyobj, \ - "__allow_recursive_" #_name);\ - if(!pyRecursive) {\ - PyErr_Clear();\ - _Flags.set(FlagAllowRecursive_##_name, false);\ - }else{\ - _Flags.set(FlagAllowRecursive_##_name, PyObject_IsTrue(pyRecursive));\ - Py_DECREF(pyRecursive);\ - }\ +#define FC_PY_ELEMENT_INIT(_name) \ + FC_PY_GetCallable(pyobj, #_name, py_##_name); \ + if (!py_##_name.isNone()) { \ + PyObject* pyRecursive = PyObject_GetAttrString(pyobj, "__allow_recursive_" #_name); \ + if (!pyRecursive) { \ + PyErr_Clear(); \ + _Flags.set(FlagAllowRecursive_##_name, false); \ + } \ + else { \ + _Flags.set(FlagAllowRecursive_##_name, PyObject_IsTrue(pyRecursive)); \ + Py_DECREF(pyRecursive); \ + } \ } -#define FC_PY_ELEMENT_FLAG(_name) \ - FlagCalling_##_name,\ - FlagAllowRecursive_##_name, +#define FC_PY_ELEMENT_FLAG(_name) FlagCalling_##_name, FlagAllowRecursive_##_name, -#define _FC_PY_CALL_CHECK(_name,_ret) \ - if((!_Flags.test(FlagAllowRecursive_##_name) \ - && _Flags.test(FlagCalling_##_name)) \ - || py_##_name.isNone()) \ - {\ - _ret;\ - }\ +#define _FC_PY_CALL_CHECK(_name, _ret) \ + if ((!_Flags.test(FlagAllowRecursive_##_name) && _Flags.test(FlagCalling_##_name)) \ + || py_##_name.isNone()) { \ + _ret; \ + } \ Base::BitsetLocker guard(_Flags, FlagCalling_##_name); #undef FC_PY_ELEMENT @@ -147,16 +149,16 @@ private: #undef FC_PY_ELEMENT #define FC_PY_ELEMENT(_name) FC_PY_ELEMENT_FLAG(_name) - enum Flag { - FC_PY_FEATURE_PYTHON - FlagMax, + enum Flag + { + FC_PY_FEATURE_PYTHON FlagMax, }; using Flags = std::bitset; mutable Flags _Flags; public: - void init(PyObject *pyobj); + void init(PyObject* pyobj); }; /** @@ -164,185 +166,226 @@ public: * derived class as Python feature -- simply by subclassing. * @author Werner Mayer */ -template -class FeaturePythonT : public FeatureT +template +class FeaturePythonT: public FeatureT { PROPERTY_HEADER_WITH_OVERRIDE(App::FeaturePythonT); public: - FeaturePythonT() { - ADD_PROPERTY(Proxy,(Py::Object())); + FeaturePythonT() + { + ADD_PROPERTY(Proxy, (Py::Object())); // cannot move this to the initializer list to avoid warning imp = new FeaturePythonImp(this); } - ~FeaturePythonT() override { + ~FeaturePythonT() override + { delete imp; } /** @name methods override DocumentObject */ //@{ - short mustExecute() const override { - if (this->isTouched()) + short mustExecute() const override + { + if (this->isTouched()) { return 1; + } auto ret = FeatureT::mustExecute(); - if(ret) return ret; - return imp->mustExecute()?1:0; + if (ret) { + return ret; + } + return imp->mustExecute() ? 1 : 0; } /// recalculate the Feature - DocumentObjectExecReturn *execute() override { + DocumentObjectExecReturn* execute() override + { try { bool handled = imp->execute(); - if (!handled) + if (!handled) { return FeatureT::execute(); + } } catch (const Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what()); } return DocumentObject::StdReturn; } - const char* getViewProviderNameOverride() const override { + const char* getViewProviderNameOverride() const override + { viewProviderName = imp->getViewProviderName(); - if(!viewProviderName.empty()) + if (!viewProviderName.empty()) { return viewProviderName.c_str(); + } return FeatureT::getViewProviderNameOverride(); } /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return FeatureT::getViewProviderName(); } - App::DocumentObject *getSubObject(const char *subname, PyObject **pyObj, - Base::Matrix4D *mat, bool transform, int depth) const override + App::DocumentObject* getSubObject(const char* subname, + PyObject** pyObj, + Base::Matrix4D* mat, + bool transform, + int depth) const override { - App::DocumentObject *ret = nullptr; - if(imp->getSubObject(ret,subname,pyObj,mat,transform,depth)) + App::DocumentObject* ret = nullptr; + if (imp->getSubObject(ret, subname, pyObj, mat, transform, depth)) { return ret; - return FeatureT::getSubObject(subname,pyObj,mat,transform,depth); + } + return FeatureT::getSubObject(subname, pyObj, mat, transform, depth); } - std::vector getSubObjects(int reason=0) const override { + std::vector getSubObjects(int reason = 0) const override + { std::vector ret; - if(imp->getSubObjects(ret,reason)) + if (imp->getSubObjects(ret, reason)) { return ret; + } return FeatureT::getSubObjects(reason); } - App::DocumentObject *getLinkedObject(bool recurse, - Base::Matrix4D *mat, bool transform, int depth) const override + App::DocumentObject* + getLinkedObject(bool recurse, Base::Matrix4D* mat, bool transform, int depth) const override { - App::DocumentObject *ret = nullptr; - if(imp->getLinkedObject(ret,recurse,mat,transform,depth)) + App::DocumentObject* ret = nullptr; + if (imp->getLinkedObject(ret, recurse, mat, transform, depth)) { return ret; - return FeatureT::getLinkedObject(recurse,mat,transform,depth); + } + return FeatureT::getLinkedObject(recurse, mat, transform, depth); } /// return true to activate tree view group object handling - bool hasChildElement() const override { + bool hasChildElement() const override + { switch (imp->hasChildElement()) { - case FeaturePythonImp::Accepted: - return true; - case FeaturePythonImp::Rejected: - return false; - default: - return FeatureT::hasChildElement(); + case FeaturePythonImp::Accepted: + return true; + case FeaturePythonImp::Rejected: + return false; + default: + return FeatureT::hasChildElement(); } } /// Get sub-element visibility - int isElementVisible(const char *element) const override { + int isElementVisible(const char* element) const override + { int ret = imp->isElementVisible(element); - if(ret == -2) + if (ret == -2) { return FeatureT::isElementVisible(element); + } return ret; } /// Set sub-element visibility - int setElementVisible(const char *element, bool visible) override { - int ret = imp->setElementVisible(element,visible); - if(ret == -2) - return FeatureT::setElementVisible(element,visible); + int setElementVisible(const char* element, bool visible) override + { + int ret = imp->setElementVisible(element, visible); + if (ret == -2) { + return FeatureT::setElementVisible(element, visible); + } return ret; } - bool canLinkProperties() const override { - switch (imp->canLinkProperties()) { - case FeaturePythonImp::Accepted: - return true; - case FeaturePythonImp::Rejected: - return false; - default: - return FeatureT::canLinkProperties(); - } - } - - bool allowDuplicateLabel() const override { - switch (imp->allowDuplicateLabel()) { - case FeaturePythonImp::Accepted: - return true; - case FeaturePythonImp::Rejected: - return false; - default: - return FeatureT::allowDuplicateLabel(); - } - } - - bool redirectSubName(std::ostringstream &ss, - App::DocumentObject *topParent, App::DocumentObject *child) const override + bool canLinkProperties() const override { - switch (imp->redirectSubName(ss,topParent,child)) { - case FeaturePythonImp::Accepted: - return true; - case FeaturePythonImp::Rejected: - return false; - default: - return FeatureT::redirectSubName(ss, topParent, child); + switch (imp->canLinkProperties()) { + case FeaturePythonImp::Accepted: + return true; + case FeaturePythonImp::Rejected: + return false; + default: + return FeatureT::canLinkProperties(); } } - int canLoadPartial() const override { + bool allowDuplicateLabel() const override + { + switch (imp->allowDuplicateLabel()) { + case FeaturePythonImp::Accepted: + return true; + case FeaturePythonImp::Rejected: + return false; + default: + return FeatureT::allowDuplicateLabel(); + } + } + + bool redirectSubName(std::ostringstream& ss, + App::DocumentObject* topParent, + App::DocumentObject* child) const override + { + switch (imp->redirectSubName(ss, topParent, child)) { + case FeaturePythonImp::Accepted: + return true; + case FeaturePythonImp::Rejected: + return false; + default: + return FeatureT::redirectSubName(ss, topParent, child); + } + } + + int canLoadPartial() const override + { int ret = imp->canLoadPartial(); - if(ret>=0) + if (ret >= 0) { return ret; + } return FeatureT::canLoadPartial(); } - void editProperty(const char *propName) override { - if (!imp->editProperty(propName)) + void editProperty(const char* propName) override + { + if (!imp->editProperty(propName)) { FeatureT::editProperty(propName); + } } - PyObject *getPyObject() override { + PyObject* getPyObject() override + { if (FeatureT::PythonObject.is(Py::_None())) { // ref counter is set to 1 - FeatureT::PythonObject = Py::Object(imp->getPyObject(),true); + FeatureT::PythonObject = Py::Object(imp->getPyObject(), true); } return Py::new_reference_to(FeatureT::PythonObject); } - void setPyObject(PyObject *obj) override { - if (obj) + void setPyObject(PyObject* obj) override + { + if (obj) { FeatureT::PythonObject = obj; - else + } + else { FeatureT::PythonObject = Py::None(); + } } protected: - void onBeforeChange(const Property* prop) override { + void onBeforeChange(const Property* prop) override + { FeatureT::onBeforeChange(prop); imp->onBeforeChange(prop); } - void onBeforeChangeLabel(std::string &newLabel) override{ - if(!imp->onBeforeChangeLabel(newLabel)) + void onBeforeChangeLabel(std::string& newLabel) override + { + if (!imp->onBeforeChangeLabel(newLabel)) { FeatureT::onBeforeChangeLabel(newLabel); + } } - void onChanged(const Property* prop) override { - if(prop == &Proxy) + void onChanged(const Property* prop) override + { + if (prop == &Proxy) { imp->init(Proxy.getValue().ptr()); + } imp->onChanged(prop); FeatureT::onChanged(prop); } - void onDocumentRestored() override { + void onDocumentRestored() override + { imp->onDocumentRestored(); FeatureT::onDocumentRestored(); } - void unsetupObject() override { + void unsetupObject() override + { imp->unsetupObject(); FeatureT::unsetupObject(); } @@ -350,8 +393,8 @@ protected: public: FeaturePythonT(const FeaturePythonT&) = delete; FeaturePythonT(FeaturePythonT&&) = delete; - FeaturePythonT& operator= (const FeaturePythonT&) = delete; - FeaturePythonT& operator= (FeaturePythonT&&) = delete; + FeaturePythonT& operator=(const FeaturePythonT&) = delete; + FeaturePythonT& operator=(FeaturePythonT&&) = delete; private: FeaturePythonImp* imp; @@ -360,9 +403,9 @@ private: }; // Special Feature-Python classes -using FeaturePython = FeaturePythonT; -using GeometryPython = FeaturePythonT; +using FeaturePython = FeaturePythonT; +using GeometryPython = FeaturePythonT; -} //namespace App +} // namespace App -#endif // APP_FEATUREPYTHON_H +#endif // APP_FEATUREPYTHON_H diff --git a/src/App/FreeCADTest.py b/src/App/FreeCADTest.py index e74c5dd559..8f97014893 100644 --- a/src/App/FreeCADTest.py +++ b/src/App/FreeCADTest.py @@ -1,25 +1,25 @@ -#*************************************************************************** -#* Copyright (c) 2002 Jürgen Riegel * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Lesser General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2002 Jürgen Riegel * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ # FreeCAD test module # @@ -27,8 +27,7 @@ # (if existing) the test function of the modules - -Log ("FreeCAD test running...\n\n") +Log("FreeCAD test running...\n\n") import sys @@ -39,6 +38,6 @@ testCase = FreeCAD.ConfigGet("TestCase") testResult = TestApp.TestText(testCase) -Log ("FreeCAD test done\n") +Log("FreeCAD test done\n") sys.exit(0 if testResult.wasSuccessful() else 1) diff --git a/src/App/GeoFeatureGroupExtension.cpp b/src/App/GeoFeatureGroupExtension.cpp index 70ecdb4678..6da11bf098 100644 --- a/src/App/GeoFeatureGroupExtension.cpp +++ b/src/App/GeoFeatureGroupExtension.cpp @@ -52,24 +52,28 @@ GeoFeatureGroupExtension::GeoFeatureGroupExtension() GeoFeatureGroupExtension::~GeoFeatureGroupExtension() = default; -void GeoFeatureGroupExtension::initExtension(ExtensionContainer* obj) { +void GeoFeatureGroupExtension::initExtension(ExtensionContainer* obj) +{ - if(!obj->isDerivedFrom(App::GeoFeature::getClassTypeId())) + if (!obj->isDerivedFrom(App::GeoFeature::getClassTypeId())) { throw Base::RuntimeError("GeoFeatureGroupExtension can only be applied to GeoFeatures"); + } App::GroupExtension::initExtension(obj); } -PropertyPlacement& GeoFeatureGroupExtension::placement() { +PropertyPlacement& GeoFeatureGroupExtension::placement() +{ - if(!getExtendedContainer()) + if (!getExtendedContainer()) { throw Base::RuntimeError("GeoFeatureGroupExtension was not applied to GeoFeature"); + } return static_cast(getExtendedContainer())->Placement; } -void GeoFeatureGroupExtension::transformPlacement(const Base::Placement &transform) +void GeoFeatureGroupExtension::transformPlacement(const Base::Placement& transform) { // NOTE: Keep in sync with APP::GeoFeature Base::Placement plm = this->placement().getValue(); @@ -79,25 +83,29 @@ void GeoFeatureGroupExtension::transformPlacement(const Base::Placement &transfo DocumentObject* GeoFeatureGroupExtension::getGroupOfObject(const DocumentObject* obj) { - if(!obj) + if (!obj) { return nullptr; + } - //we will find origins, but not origin features - if(obj->isDerivedFrom(App::OriginFeature::getClassTypeId())) + // we will find origins, but not origin features + if (obj->isDerivedFrom(App::OriginFeature::getClassTypeId())) { return OriginGroupExtension::getGroupOfObject(obj); + } - //compared to GroupExtension we do return here all GeoFeatureGroups including all extensions derived from it - //like OriginGroup. That is needed as we use this function to get all local coordinate systems. Also there - //is no reason to distinguish between GeoFeatuerGroups, there is only between group/geofeaturegroup + // compared to GroupExtension we do return here all GeoFeatureGroups including all extensions + // derived from it like OriginGroup. That is needed as we use this function to get all local + // coordinate systems. Also there is no reason to distinguish between GeoFeatuerGroups, there is + // only between group/geofeaturegroup auto list = obj->getInList(); for (auto inObj : list) { - //There is a chance that a derived geofeaturegroup links with a local link and hence is not - //the parent group even though it links to the object. We use hasObject as one and only truth - //if it has the object within the group + // There is a chance that a derived geofeaturegroup links with a local link and hence is not + // the parent group even though it links to the object. We use hasObject as one and only + // truth if it has the object within the group auto group = inObj->getExtensionByType(true); - if(group && group->hasObject(obj)) + if (group && group->hasObject(obj)) { return inObj; + } } return nullptr; @@ -115,8 +123,9 @@ Base::Placement GeoFeatureGroupExtension::globalGroupPlacement() } -Base::Placement GeoFeatureGroupExtension::recursiveGroupPlacement(GeoFeatureGroupExtension* group, - std::unordered_set& history) +Base::Placement GeoFeatureGroupExtension::recursiveGroupPlacement( + GeoFeatureGroupExtension* group, + std::unordered_set& history) { history.insert(this); @@ -135,25 +144,29 @@ Base::Placement GeoFeatureGroupExtension::recursiveGroupPlacement(GeoFeatureGrou return group->placement().getValue(); } -std::vector GeoFeatureGroupExtension::addObjects(std::vector objects) { +std::vector +GeoFeatureGroupExtension::addObjects(std::vector objects) +{ std::vector grp = Group.getValues(); std::vector ret; - for(auto object : objects) { + for (auto object : objects) { - if(!allowObject(object)) + if (!allowObject(object)) { continue; + } - //cross CoordinateSystem links are not allowed, so we need to move the whole link group + // cross CoordinateSystem links are not allowed, so we need to move the whole link group std::vector links = getCSRelevantLinks(object); links.push_back(object); - for( auto obj : links) { - //only one geofeaturegroup per object. - auto *group = App::GeoFeatureGroupExtension::getGroupOfObject(obj); - if(group && group != getExtendedObject()) + for (auto obj : links) { + // only one geofeaturegroup per object. + auto* group = App::GeoFeatureGroupExtension::getGroupOfObject(obj); + if (group && group != getExtendedObject()) { group->getExtensionByType()->removeObject(obj); + } if (!hasObject(obj)) { grp.push_back(obj); @@ -166,61 +179,68 @@ std::vector GeoFeatureGroupExtension::addObjects(std::vector GeoFeatureGroupExtension::removeObjects(std::vector objects) { +std::vector +GeoFeatureGroupExtension::removeObjects(std::vector objects) +{ std::vector removed; std::vector grp = Group.getValues(); - for(auto object : objects) { - //cross CoordinateSystem links are not allowed, so we need to remove the whole link group - std::vector< DocumentObject* > links = getCSRelevantLinks(object); + for (auto object : objects) { + // cross CoordinateSystem links are not allowed, so we need to remove the whole link group + std::vector links = getCSRelevantLinks(object); links.push_back(object); - //remove all links out of group - for(auto link : links) { + // remove all links out of group + for (auto link : links) { auto end = std::remove(grp.begin(), grp.end(), link); - if(end != grp.end()) { + if (end != grp.end()) { grp.erase(end, grp.end()); removed.push_back(link); } } } - if(!removed.empty()) + if (!removed.empty()) { Group.setValues(grp); + } return removed; } -void GeoFeatureGroupExtension::extensionOnChanged(const Property* p) { +void GeoFeatureGroupExtension::extensionOnChanged(const Property* p) +{ - //objects are only allowed in a single GeoFeatureGroup - if(p == &Group && !Group.testStatus(Property::User3)) { + // objects are only allowed in a single GeoFeatureGroup + if (p == &Group && !Group.testStatus(Property::User3)) { - if((!getExtendedObject()->isRestoring() - || getExtendedObject()->getDocument()->testStatus(Document::Importing)) + if ((!getExtendedObject()->isRestoring() + || getExtendedObject()->getDocument()->testStatus(Document::Importing)) && !getExtendedObject()->getDocument()->isPerformingTransaction()) { bool error = false; auto corrected = Group.getValues(); - for(auto obj : Group.getValues()) { + for (auto obj : Group.getValues()) { - //we have already set the obj into the group, so in a case of multiple groups getGroupOfObject - //would return anyone of it and hence it is possible that we miss an error. We need a custom check + // we have already set the obj into the group, so in a case of multiple groups + // getGroupOfObject would return anyone of it and hence it is possible that we miss + // an error. We need a custom check auto list = obj->getInList(); for (auto in : list) { - if(in == getExtendedObject()) + if (in == getExtendedObject()) { continue; + } auto parent = in->getExtensionByType(true); - if(parent && parent->hasObject(obj)) { + if (parent && parent->hasObject(obj)) { error = true; - corrected.erase(std::remove(corrected.begin(), corrected.end(), obj), corrected.end()); + corrected.erase(std::remove(corrected.begin(), corrected.end(), obj), + corrected.end()); } } } - //if an error was found we need to correct the values and inform the user - if(error) { + // if an error was found we need to correct the values and inform the user + if (error) { Base::ObjectStatusLocker guard(Property::User3, &Group); Group.setValues(corrected); throw Base::RuntimeError("Object can only be in a single GeoFeatureGroup"); @@ -232,99 +252,119 @@ void GeoFeatureGroupExtension::extensionOnChanged(const Property* p) { } -std::vector< DocumentObject* > GeoFeatureGroupExtension::getScopedObjectsFromLinks(const DocumentObject* obj, LinkScope scope) { +std::vector +GeoFeatureGroupExtension::getScopedObjectsFromLinks(const DocumentObject* obj, LinkScope scope) +{ - if(!obj) + if (!obj) { return {}; + } - //we get all linked objects. We can't use outList() as this includes the links from expressions - std::vector< App::DocumentObject* > result; + // we get all linked objects. We can't use outList() as this includes the links from expressions + std::vector result; std::vector list; obj->getPropertyList(list); - for(App::Property* prop : list) { + for (App::Property* prop : list) { auto vec = getScopedObjectsFromLink(prop, scope); result.insert(result.end(), vec.begin(), vec.end()); } - //clear all null objects and duplicates + // clear all null objects and duplicates std::sort(result.begin(), result.end()); result.erase(std::unique(result.begin(), result.end()), result.end()); return result; } -std::vector< DocumentObject* > GeoFeatureGroupExtension::getScopedObjectsFromLink(App::Property* prop, LinkScope scope) { +std::vector GeoFeatureGroupExtension::getScopedObjectsFromLink(App::Property* prop, + LinkScope scope) +{ - if(!prop) + if (!prop) { return {}; + } - std::vector< App::DocumentObject* > result; + std::vector result; auto link = Base::freecad_dynamic_cast(prop); - if(link && link->getScope()==scope) + if (link && link->getScope() == scope) { link->getLinks(result); + } return result; } void GeoFeatureGroupExtension::getCSOutList(const App::DocumentObject* obj, - std::vector< DocumentObject* >& vec) { + std::vector& vec) +{ - if(!obj) + if (!obj) { return; + } - //we get all relevant linked objects. We can't use outList() as this includes the links from expressions, - //also we only want links with scope Local + // we get all relevant linked objects. We can't use outList() as this includes the links from + // expressions, also we only want links with scope Local auto result = getScopedObjectsFromLinks(obj, LinkScope::Local); - //we remove all links to origin features and origins, they belong to a CS too and can't be moved - result.erase(std::remove_if(result.begin(), result.end(), [](App::DocumentObject* obj)->bool { - return (obj->isDerivedFrom(App::OriginFeature::getClassTypeId()) || - obj->isDerivedFrom(App::Origin::getClassTypeId())); - }), result.end()); + // we remove all links to origin features and origins, they belong to a CS too and can't be + // moved + result.erase(std::remove_if(result.begin(), + result.end(), + [](App::DocumentObject* obj) -> bool { + return (obj->isDerivedFrom(App::OriginFeature::getClassTypeId()) + || obj->isDerivedFrom(App::Origin::getClassTypeId())); + }), + result.end()); vec.insert(vec.end(), result.begin(), result.end()); - //post process the vector + // post process the vector std::sort(vec.begin(), vec.end()); vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); } void GeoFeatureGroupExtension::getCSInList(const DocumentObject* obj, - std::vector< DocumentObject* >& vec) { + std::vector& vec) +{ - if(!obj) + if (!obj) { return; - - //search the inlist for objects that have non-expression links to us - for(App::DocumentObject* parent : obj->getInList()) { - - //not interested in other groups (and here we mean all groups, normal ones and geofeaturegroup) - if(parent->hasExtension(App::GroupExtension::getExtensionClassTypeId())) - continue; - - //check if the link is real Local scope one or if it is a expression one (could also be both, so it is not - //enough to check the expressions) - auto res = getScopedObjectsFromLinks(parent, LinkScope::Local); - if(std::find(res.begin(), res.end(), obj) != res.end()) - vec.push_back(parent); } - //clear all duplicates + // search the inlist for objects that have non-expression links to us + for (App::DocumentObject* parent : obj->getInList()) { + + // not interested in other groups (and here we mean all groups, normal ones and + // geofeaturegroup) + if (parent->hasExtension(App::GroupExtension::getExtensionClassTypeId())) { + continue; + } + + // check if the link is real Local scope one or if it is a expression one (could also be + // both, so it is not enough to check the expressions) + auto res = getScopedObjectsFromLinks(parent, LinkScope::Local); + if (std::find(res.begin(), res.end(), obj) != res.end()) { + vec.push_back(parent); + } + } + + // clear all duplicates std::sort(vec.begin(), vec.end()); vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); } -std::vector< DocumentObject* > GeoFeatureGroupExtension::getCSRelevantLinks(const DocumentObject* obj) { +std::vector GeoFeatureGroupExtension::getCSRelevantLinks(const DocumentObject* obj) +{ - if(!obj) + if (!obj) { return {}; + } - //get all out links + // get all out links std::vector vec; recursiveCSRelevantLinks(obj, vec); - //post process the list after we added many things + // post process the list after we added many things std::sort(vec.begin(), vec.end()); vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); vec.erase(std::remove(vec.begin(), vec.end(), obj), vec.end()); @@ -333,53 +373,63 @@ std::vector< DocumentObject* > GeoFeatureGroupExtension::getCSRelevantLinks(cons } void GeoFeatureGroupExtension::recursiveCSRelevantLinks(const DocumentObject* obj, - std::vector< DocumentObject* >& vec) { + std::vector& vec) +{ - if(!obj) + if (!obj) { return; + } - std::vector< DocumentObject* > links; + std::vector links; getCSOutList(obj, links); getCSInList(obj, links); - //go on traversing the graph in all directions! - for(auto o : links) { - if(!o || o == obj || std::find(vec.begin(), vec.end(), o) != vec.end()) + // go on traversing the graph in all directions! + for (auto o : links) { + if (!o || o == obj || std::find(vec.begin(), vec.end(), o) != vec.end()) { continue; + } vec.push_back(o); recursiveCSRelevantLinks(o, vec); } } -bool GeoFeatureGroupExtension::extensionGetSubObject(DocumentObject *&ret, const char *subname, - PyObject **pyObj, Base::Matrix4D *mat, bool transform, int depth) const +bool GeoFeatureGroupExtension::extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject** pyObj, + Base::Matrix4D* mat, + bool transform, + int depth) const { ret = nullptr; - const char *dot; - if(!subname || *subname==0) { + const char* dot; + if (!subname || *subname == 0) { auto obj = dynamic_cast(getExtendedContainer()); ret = const_cast(obj); - if(mat && transform) + if (mat && transform) { *mat *= const_cast(this)->placement().getValue().toMatrix(); - }else if((dot=strchr(subname,'.'))) { - if(subname[0]!='$') - ret = Group.findUsingMap(std::string(subname,dot)); - else{ - std::string name = std::string(subname+1,dot); - for(auto child : Group.getValues()) { - if(name == child->Label.getStrValue()){ + } + } + else if ((dot = strchr(subname, '.'))) { + if (subname[0] != '$') { + ret = Group.findUsingMap(std::string(subname, dot)); + } + else { + std::string name = std::string(subname + 1, dot); + for (auto child : Group.getValues()) { + if (name == child->Label.getStrValue()) { ret = child; break; } } } - if(ret) { - if(dot) ++dot; - if(dot && *dot - && !ret->hasExtension(App::LinkBaseExtension::getExtensionClassTypeId()) - && !ret->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId())) - { + if (ret) { + if (dot) { + ++dot; + } + if (dot && *dot && !ret->hasExtension(App::LinkBaseExtension::getExtensionClassTypeId()) + && !ret->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId())) { // Consider this // Body // | -- Pad @@ -391,33 +441,37 @@ bool GeoFeatureGroupExtension::extensionGetSubObject(DocumentObject *&ret, const // getSubObject(Pad,"Sketch.") as this will transform Sketch // using Pad's placement. // - const char *next = strchr(dot,'.'); - if(next) { - App::DocumentObject *nret=nullptr; - extensionGetSubObject(nret,dot,pyObj,mat,transform,depth+1); - if(nret) { + const char* next = strchr(dot, '.'); + if (next) { + App::DocumentObject* nret = nullptr; + extensionGetSubObject(nret, dot, pyObj, mat, transform, depth + 1); + if (nret) { ret = nret; return true; } } } - if(mat && transform) - *mat *= const_cast(this)->placement().getValue().toMatrix(); - ret = ret->getSubObject(dot?dot:"",pyObj,mat,true,depth+1); + if (mat && transform) { + *mat *= + const_cast(this)->placement().getValue().toMatrix(); + } + ret = ret->getSubObject(dot ? dot : "", pyObj, mat, true, depth + 1); } } return true; } -bool GeoFeatureGroupExtension::areLinksValid(const DocumentObject* obj) { +bool GeoFeatureGroupExtension::areLinksValid(const DocumentObject* obj) +{ - if(!obj) + if (!obj) { return true; + } std::vector list; obj->getPropertyList(list); - for(App::Property* prop : list) { - if(!isLinkValid(prop)) { + for (App::Property* prop : list) { + if (!isLinkValid(prop)) { return false; } } @@ -425,65 +479,79 @@ bool GeoFeatureGroupExtension::areLinksValid(const DocumentObject* obj) { return true; } -bool GeoFeatureGroupExtension::isLinkValid(App::Property* prop) { +bool GeoFeatureGroupExtension::isLinkValid(App::Property* prop) +{ - if(!prop) + if (!prop) { return true; + } - //get the object that holds the property - if(!prop->getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) - return true; //this link comes not from a document object, scopes are meaningless + // get the object that holds the property + if (!prop->getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + return true; // this link comes not from a document object, scopes are meaningless + } auto obj = static_cast(prop->getContainer()); - //no cross CS link for local links. + // no cross CS link for local links. auto result = getScopedObjectsFromLink(prop, LinkScope::Local); auto group = getGroupOfObject(obj); - for(auto link : result) { - if(getGroupOfObject(link) != group) + for (auto link : result) { + if (getGroupOfObject(link) != group) { return false; + } } - //for links with scope SubGroup we need to check if all features are part of subgroups - if(obj->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId())) { + // for links with scope SubGroup we need to check if all features are part of subgroups + if (obj->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId())) { result = getScopedObjectsFromLink(prop, LinkScope::Child); auto groupExt = obj->getExtensionByType(); - for(auto link : result) { - if(!groupExt->hasObject(link, true)) + for (auto link : result) { + if (!groupExt->hasObject(link, true)) { return false; + } } } return true; } -void GeoFeatureGroupExtension::getInvalidLinkObjects(const DocumentObject* obj, std::vector< DocumentObject* >& vec) { +void GeoFeatureGroupExtension::getInvalidLinkObjects(const DocumentObject* obj, + std::vector& vec) +{ - if(!obj) + if (!obj) { return; - - //no cross CS link for local links. - auto result = getScopedObjectsFromLinks(obj, LinkScope::Local); - auto group = obj->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId()) ? obj : getGroupOfObject(obj); - for(auto link : result) { - if(getGroupOfObject(link) != group) - vec.push_back(link); } - //for links with scope SubGroup we need to check if all features are part of subgroups - if(group) { + // no cross CS link for local links. + auto result = getScopedObjectsFromLinks(obj, LinkScope::Local); + auto group = obj->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId()) + ? obj + : getGroupOfObject(obj); + for (auto link : result) { + if (getGroupOfObject(link) != group) { + vec.push_back(link); + } + } + + // for links with scope SubGroup we need to check if all features are part of subgroups + if (group) { result = getScopedObjectsFromLinks(obj, LinkScope::Child); auto groupExt = group->getExtensionByType(); - for(auto link : result) { - if(!groupExt->hasObject(link, true)) + for (auto link : result) { + if (!groupExt->hasObject(link, true)) { vec.push_back(link); + } } } } -bool GeoFeatureGroupExtension::extensionGetSubObjects(std::vector &ret, int) const { - for(auto obj : Group.getValues()) { - if(obj && obj->isAttachedToDocument() && !obj->testStatus(ObjectStatus::GeoExcluded)) - ret.push_back(std::string(obj->getNameInDocument())+'.'); +bool GeoFeatureGroupExtension::extensionGetSubObjects(std::vector& ret, int) const +{ + for (auto obj : Group.getValues()) { + if (obj && obj->isAttachedToDocument() && !obj->testStatus(ObjectStatus::GeoExcluded)) { + ret.push_back(std::string(obj->getNameInDocument()) + '.'); + } } return true; } @@ -491,9 +559,11 @@ bool GeoFeatureGroupExtension::extensionGetSubObjects(std::vector & // Python feature --------------------------------------------------------- -namespace App { -EXTENSION_PROPERTY_SOURCE_TEMPLATE(App::GeoFeatureGroupExtensionPython, App::GeoFeatureGroupExtension) +namespace App +{ +EXTENSION_PROPERTY_SOURCE_TEMPLATE(App::GeoFeatureGroupExtensionPython, + App::GeoFeatureGroupExtension) // explicit template instantiation template class AppExport ExtensionPythonT>; -} +} // namespace App diff --git a/src/App/GeoFeatureGroupExtension.h b/src/App/GeoFeatureGroupExtension.h index bd3dadb624..411f27b65e 100644 --- a/src/App/GeoFeatureGroupExtension.h +++ b/src/App/GeoFeatureGroupExtension.h @@ -35,21 +35,23 @@ namespace App { /** - * @brief The base class for placeable group of DocumentObjects. It represents a local coordnate system + * @brief The base class for placeable group of DocumentObjects. It represents a local coordnate + * system * - * This class is the FreeCAD way of representing local coordinate systems. It groups its children beneath - * it and transforms them all with the GeoFeatureGroup placement. A few important properties: - * - Every child that belongs to the CS must be in the Group property. Even if a sketch is part of a pad, - * it must be in the Group property of the same GeoFeatureGroup as pad. This also holds for normal - * GroupExtensions. They can be added to a GeoFeatureGroup, but all objects that the group holds must - * also be added to the GeoFeatureGroup + * This class is the FreeCAD way of representing local coordinate systems. It groups its children + * beneath it and transforms them all with the GeoFeatureGroup placement. A few important + * properties: + * - Every child that belongs to the CS must be in the Group property. Even if a sketch is part of a + * pad, it must be in the Group property of the same GeoFeatureGroup as pad. This also holds for + * normal GroupExtensions. They can be added to a GeoFeatureGroup, but all objects that the group + * holds must also be added to the GeoFeatureGroup * - Objects can be only in a single GeoFeatureGroup. It is not allowed to have a document object in * multiple GeoFeatureGroups - * - PropertyLinks between different GeoFeatureGroups are forbidden. There are special link properties - * that allow such cross-CS links. + * - PropertyLinks between different GeoFeatureGroups are forbidden. There are special link + * properties that allow such cross-CS links. * - Expressions can cross GeoFeatureGroup borders */ -class AppExport GeoFeatureGroupExtension : public App::GroupExtension +class AppExport GeoFeatureGroupExtension: public App::GroupExtension { using inherited = App::GroupExtension; EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::GeoFeatureGroupExtension); @@ -65,7 +67,7 @@ public: * features. * @param transform (input). */ - virtual void transformPlacement(const Base::Placement &transform); + virtual void transformPlacement(const Base::Placement& transform); /// Constructor GeoFeatureGroupExtension(); @@ -84,65 +86,77 @@ public: * @brief Calculates the global placement of this group * * The returned placement describes the transformation from the global reference coordinate - * system to the local coordinate system of this geo feature group. If this group has a no parent - * GeoFeatureGroup the returned placement is the one of this group. For multiple stacked + * system to the local coordinate system of this geo feature group. If this group has a no + * parent GeoFeatureGroup the returned placement is the one of this group. For multiple stacked * GeoFeatureGroups the returned Placement is the combination of all parent placements including * the one of this group. - * @return Base::Placement The transformation from global reference system to the groups local system + * @return Base::Placement The transformation from global reference system to the groups local + * system */ Base::Placement globalGroupPlacement(); /// Returns true if the given DocumentObject is DocumentObjectGroup but not GeoFeatureGroup - static bool isNonGeoGroup(const DocumentObject* obj) { - return obj->hasExtension(GroupExtension::getExtensionClassTypeId()) && - !obj->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId()); + static bool isNonGeoGroup(const DocumentObject* obj) + { + return obj->hasExtension(GroupExtension::getExtensionClassTypeId()) + && !obj->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId()); } - bool extensionGetSubObject(DocumentObject *&ret, const char *subname, PyObject **pyObj, - Base::Matrix4D *mat, bool transform, int depth) const override; + bool extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject** pyObj, + Base::Matrix4D* mat, + bool transform, + int depth) const override; - bool extensionGetSubObjects(std::vector &ret, int reason) const override; + bool extensionGetSubObjects(std::vector& ret, int reason) const override; - std::vector< DocumentObject* > addObjects(std::vector< DocumentObject* > obj) override; - std::vector< DocumentObject* > removeObjects(std::vector< DocumentObject* > obj) override; + std::vector addObjects(std::vector obj) override; + std::vector removeObjects(std::vector obj) override; - /// Collects all links that are relevant for the coordinate system, meaning all recursive links to - /// obj and from obj excluding expressions and stopping the recursion at other geofeaturegroups. - /// The result is the combination of CSOutList and CSInList. + /// Collects all links that are relevant for the coordinate system, meaning all recursive links + /// to obj and from obj excluding expressions and stopping the recursion at other + /// geofeaturegroups. The result is the combination of CSOutList and CSInList. static std::vector getCSRelevantLinks(const App::DocumentObject* obj); - /// Checks if the links of the given object comply with all GeoFeatureGroup requirements, that means - /// if normal links are only within the parent GeoFeatureGroup. + /// Checks if the links of the given object comply with all GeoFeatureGroup requirements, that + /// means if normal links are only within the parent GeoFeatureGroup. static bool areLinksValid(const App::DocumentObject* obj); /// Checks if the given link complies with all GeoFeatureGroup requirements, that means /// if normal links are only within the parent GeoFeatureGroup. static bool isLinkValid(App::Property* link); - //Returns all objects that are wrongly linked from this object, meaning which are out of scope of the - //links of obj - static void getInvalidLinkObjects(const App::DocumentObject* obj, std::vector& vec); + // Returns all objects that are wrongly linked from this object, meaning which are out of scope + // of the links of obj + static void getInvalidLinkObjects(const App::DocumentObject* obj, + std::vector& vec); private: - Base::Placement recursiveGroupPlacement(GeoFeatureGroupExtension* group, std::unordered_set& history); - static std::vector getScopedObjectsFromLinks(const App::DocumentObject*, LinkScope scope = LinkScope::Local); - static std::vector getScopedObjectsFromLink(App::Property*, LinkScope scope = LinkScope::Local); + Base::Placement recursiveGroupPlacement(GeoFeatureGroupExtension* group, + std::unordered_set& history); + static std::vector + getScopedObjectsFromLinks(const App::DocumentObject*, LinkScope scope = LinkScope::Local); + static std::vector + getScopedObjectsFromLink(App::Property*, LinkScope scope = LinkScope::Local); - /// Collects GeoFeatureGroup relevant objects that are linked from the given one. That means all linked objects - /// except GeoFeatureGroups. Expressions links are ignored. Only local scope links are considered. There is no - /// recursion. An exception is thrown when there are dependency loops. - static void getCSOutList(const App::DocumentObject* obj, std::vector& vec); + /// Collects GeoFeatureGroup relevant objects that are linked from the given one. That means all + /// linked objects except GeoFeatureGroups. Expressions links are ignored. Only local scope + /// links are considered. There is no recursion. An exception is thrown when there are + /// dependency loops. + static void getCSOutList(const App::DocumentObject* obj, + std::vector& vec); /// Collects GeoFeatureGroup relevant objects that link to the given one. That means all objects - /// except GeoFeatureGroups. Expression links are ignored. Only local scope links are relevant, and - /// there is no recursion. An exception is thrown when there are dependency loops. + /// except GeoFeatureGroups. Expression links are ignored. Only local scope links are relevant, + /// and there is no recursion. An exception is thrown when there are dependency loops. static void getCSInList(const App::DocumentObject* obj, std::vector& vec); static void recursiveCSRelevantLinks(const App::DocumentObject* obj, std::vector& vec); - }; -using GeoFeatureGroupExtensionPython = ExtensionPythonT>; +using GeoFeatureGroupExtensionPython = + ExtensionPythonT>; -} //namespace App +} // namespace App -#endif // APP_GeoFeatureGroup_H +#endif // APP_GeoFeatureGroup_H diff --git a/src/App/GeoFeatureGroupExtensionPyImp.cpp b/src/App/GeoFeatureGroupExtensionPyImp.cpp index 6a27200f32..48660bb41e 100644 --- a/src/App/GeoFeatureGroupExtensionPyImp.cpp +++ b/src/App/GeoFeatureGroupExtensionPyImp.cpp @@ -36,7 +36,7 @@ std::string GeoFeatureGroupExtensionPy::representation() const return {""}; } -PyObject *GeoFeatureGroupExtensionPy::getCustomAttributes(const char* /*attr*/) const +PyObject* GeoFeatureGroupExtensionPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } @@ -45,5 +45,3 @@ int GeoFeatureGroupExtensionPy::setCustomAttributes(const char* /*attr*/, PyObje { return 0; } - - diff --git a/src/App/GeoFeaturePyImp.cpp b/src/App/GeoFeaturePyImp.cpp index 1792f225b9..2d78e69867 100644 --- a/src/App/GeoFeaturePyImp.cpp +++ b/src/App/GeoFeaturePyImp.cpp @@ -37,16 +37,18 @@ std::string GeoFeaturePy::representation() const return {""}; } -PyObject* GeoFeaturePy::getPaths(PyObject * /*args*/) +PyObject* GeoFeaturePy::getPaths(PyObject* /*args*/) { PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented"); return nullptr; } -PyObject* GeoFeaturePy::getGlobalPlacement(PyObject * args) { +PyObject* GeoFeaturePy::getGlobalPlacement(PyObject* args) +{ - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { Base::Placement p = static_cast(getDocumentObjectPtr())->globalPlacement(); @@ -57,7 +59,8 @@ PyObject* GeoFeaturePy::getGlobalPlacement(PyObject * args) { } } -PyObject* GeoFeaturePy::getGlobalPlacementOf(PyObject * args) { +PyObject* GeoFeaturePy::getGlobalPlacementOf(PyObject* args) +{ PyObject* pyTargetObj {nullptr}; PyObject* pyRootObj {nullptr}; @@ -78,10 +81,11 @@ PyObject* GeoFeaturePy::getGlobalPlacementOf(PyObject * args) { } } -PyObject* GeoFeaturePy::getPropertyNameOfGeometry(PyObject * args) +PyObject* GeoFeaturePy::getPropertyNameOfGeometry(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } GeoFeature* object = this->getGeoFeaturePtr(); const PropertyComplexGeoData* prop = object->getPropertyOfGeometry(); @@ -92,10 +96,11 @@ PyObject* GeoFeaturePy::getPropertyNameOfGeometry(PyObject * args) return Py::new_reference_to(Py::None()); } -PyObject* GeoFeaturePy::getPropertyOfGeometry(PyObject * args) +PyObject* GeoFeaturePy::getPropertyOfGeometry(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } GeoFeature* object = this->getGeoFeaturePtr(); const PropertyComplexGeoData* prop = object->getPropertyOfGeometry(); @@ -105,7 +110,7 @@ PyObject* GeoFeaturePy::getPropertyOfGeometry(PyObject * args) return Py::new_reference_to(Py::None()); } -PyObject *GeoFeaturePy::getCustomAttributes(const char* /*attr*/) const +PyObject* GeoFeaturePy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } @@ -115,7 +120,8 @@ int GeoFeaturePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) return 0; } -Py::String GeoFeaturePy::getElementMapVersion() const { - return Py::String(getGeoFeaturePtr()->getElementMapVersion( - getGeoFeaturePtr()->getPropertyOfGeometry())); +Py::String GeoFeaturePy::getElementMapVersion() const +{ + return Py::String( + getGeoFeaturePtr()->getElementMapVersion(getGeoFeaturePtr()->getPropertyOfGeometry())); } diff --git a/src/App/Graphviz.cpp b/src/App/Graphviz.cpp index 567dc0728a..ec74cf5f68 100644 --- a/src/App/Graphviz.cpp +++ b/src/App/Graphviz.cpp @@ -38,21 +38,22 @@ using namespace App; using namespace boost; -void Document::writeDependencyGraphViz(std::ostream &out) +void Document::writeDependencyGraphViz(std::ostream& out) { // // caching vertex to DocObject - //std::map VertexMap; - //for(std::map::const_iterator It1= _DepConMap.begin();It1 != _DepConMap.end(); ++It1) + // std::map VertexMap; + // for(std::map::const_iterator It1= _DepConMap.begin();It1 != + // _DepConMap.end(); ++It1) // VertexMap[It1->second] = It1->first; out << "digraph G {" << std::endl; out << "\tordering=out;" << std::endl; out << "\tnode [shape = box];" << std::endl; - for (const auto &It : d->objectMap) { + for (const auto& It : d->objectMap) { out << "\t" << It.first << ";" << std::endl; std::vector OutList = It.second->getOutList(); - for (const auto &It2 : OutList) { + for (const auto& It2 : OutList) { if (It2) { out << "\t" << It.first << "->" << It2->getNameInDocument() << ";" << std::endl; } @@ -75,14 +76,19 @@ void Document::exportGraphviz(std::ostream& out) const { /* Type defs for a graph with graphviz attributes */ using GraphvizAttributes = std::map; - using Graph = boost::subgraph< adjacency_list, - property >, - property - > > > > >; + using Graph = boost::subgraph, + property>, + property>>>>>; /** * @brief The GraphCreator class @@ -91,18 +97,25 @@ void Document::exportGraphviz(std::ostream& out) const * */ - class GraphCreator { + class GraphCreator + { public: - - explicit GraphCreator(struct DocumentP* _d) : d(_d), seed(std::random_device()()), distribution(0,255) { + explicit GraphCreator(struct DocumentP* _d) + : d(_d) + , seed(std::random_device()()) + , distribution(0, 255) + { build(); } - const Graph & getGraph() const { return DepList; } + const Graph& getGraph() const + { + return DepList; + } private: - - void build() { + void build() + { // Set attribute(s) for main graph get_property(DepList, graph_graph_attribute)["compound"] = "true"; @@ -119,7 +132,8 @@ void Document::exportGraphviz(std::ostream& out) const * @return A string */ - std::string getId(const DocumentObject * docObj) { + std::string getId(const DocumentObject* docObj) + { std::string id; if (docObj->isAttachedToDocument()) { auto doc = docObj->getDocument(); @@ -136,25 +150,32 @@ void Document::exportGraphviz(std::ostream& out) const * @return A string */ - std::string getId(const ObjectIdentifier & path) { - DocumentObject * docObj = path.getDocumentObject(); - if (!docObj) + std::string getId(const ObjectIdentifier& path) + { + DocumentObject* docObj = path.getDocumentObject(); + if (!docObj) { return {}; + } - return std::string((docObj)->getDocument()->getName()) + "#" + docObj->getNameInDocument() + "." + path.getPropertyName() + path.getSubPathStr(); + return std::string((docObj)->getDocument()->getName()) + "#" + + docObj->getNameInDocument() + "." + path.getPropertyName() + path.getSubPathStr(); } - std::string getClusterName(const DocumentObject * docObj) const { + std::string getClusterName(const DocumentObject* docObj) const + { return std::string("cluster") + docObj->getNameInDocument(); } - void setGraphLabel(Graph& g, const DocumentObject* obj) const { + void setGraphLabel(Graph& g, const DocumentObject* obj) const + { std::string name(obj->getNameInDocument()); std::string label(obj->Label.getValue()); - if (name == label) + if (name == label) { get_property(g, graph_graph_attribute)["label"] = name; - else + } + else { get_property(g, graph_graph_attribute)["label"] = name + "\n(" + label + ")"; + } } /** @@ -162,7 +183,8 @@ void Document::exportGraphviz(std::ostream& out) const * @param obj DocumentObject */ - void setGraphAttributes(const DocumentObject * obj) { + void setGraphAttributes(const DocumentObject* obj) + { assert(GraphList.find(obj) != GraphList.end()); get_property(*GraphList[obj], graph_name) = getClusterName(obj); @@ -179,7 +201,8 @@ void Document::exportGraphviz(std::ostream& out) const * @param name Name of node */ - void setPropertyVertexAttributes(Graph & g, Vertex vertex, const std::string & name) { + void setPropertyVertexAttributes(Graph& g, Vertex vertex, const std::string& name) + { get(vertex_attribute, g)[vertex]["label"] = name; get(vertex_attribute, g)[vertex]["shape"] = "box"; get(vertex_attribute, g)[vertex]["style"] = "dashed"; @@ -187,13 +210,15 @@ void Document::exportGraphviz(std::ostream& out) const } /** - * @brief addExpressionSubgraphIfNeeded Add a subgraph to the main graph if it is needed, i.e. there are defined at least one - * expression in the document object, or other objects are referencing properties in it. + * @brief addExpressionSubgraphIfNeeded Add a subgraph to the main graph if it is needed, + * i.e. there are defined at least one expression in the document object, or other objects + * are referencing properties in it. * @param obj DocumentObject to assess. * @param CSSubgraphs Boolean if the GeoFeatureGroups are created as subgraphs */ - void addExpressionSubgraphIfNeeded(DocumentObject * obj, bool CSsubgraphs) { + void addExpressionSubgraphIfNeeded(DocumentObject* obj, bool CSsubgraphs) + { auto expressions = obj->ExpressionEngine.getExpressions(); @@ -205,8 +230,9 @@ void Document::exportGraphviz(std::ostream& out) const auto group = GeoFeatureGroupExtension::getGroupOfObject(obj); if (group) { auto it = GraphList.find(group); - if (it != GraphList.end()) + if (it != GraphList.end()) { graph = it->second; + } } } @@ -216,16 +242,18 @@ void Document::exportGraphviz(std::ostream& out) const setGraphAttributes(obj); } - // Create subgraphs for all document objects that it depends on; it will depend on some property there - for (const auto &expr : expressions) { + // Create subgraphs for all document objects that it depends on; it will depend on + // some property there + for (const auto& expr : expressions) { std::map deps; expr.second->getIdentifiers(deps); - for (const auto &dep : deps) { - if (dep.second) + for (const auto& dep : deps) { + if (dep.second) { continue; - DocumentObject * o = dep.first.getDocumentObject(); + } + DocumentObject* o = dep.first.getDocumentObject(); // Doesn't exist already? if (o && !GraphList[o]) { @@ -249,38 +277,48 @@ void Document::exportGraphviz(std::ostream& out) const } /** - * @brief add Add @docObj to the graph, including all expressions (and dependencies) it includes. + * @brief add Add @docObj to the graph, including all expressions (and dependencies) it + * includes. * @param docObj The document object to add. * @param name Name of node. */ - void add(DocumentObject *docObj, const std::string &name, const std::string &label, bool CSSubgraphs) + void add(DocumentObject* docObj, + const std::string& name, + const std::string& label, + bool CSSubgraphs) { - //don't add objects twice - if (std::find(objects.begin(), objects.end(), docObj) != objects.end()) + // don't add objects twice + if (std::find(objects.begin(), objects.end(), docObj) != objects.end()) { return; + } - //find the correct graph to add the vertex to. Check first expression graphs, afterwards - //the parent CS and origin graphs - Graph *sgraph = GraphList[docObj]; + // find the correct graph to add the vertex to. Check first expression graphs, + // afterwards the parent CS and origin graphs + Graph* sgraph = GraphList[docObj]; if (CSSubgraphs) { if (!sgraph) { auto group = GeoFeatureGroupExtension::getGroupOfObject(docObj); if (group) { - if (docObj->isDerivedFrom(App::OriginFeature::getClassTypeId())) - sgraph = GraphList[group->getExtensionByType()->Origin.getValue()]; - else + if (docObj->isDerivedFrom(App::OriginFeature::getClassTypeId())) { + sgraph = GraphList[group->getExtensionByType() + ->Origin.getValue()]; + } + else { sgraph = GraphList[group]; + } } } if (!sgraph) { - if (docObj->isDerivedFrom(OriginFeature::getClassTypeId())) - sgraph = GraphList[static_cast(docObj)->getOrigin()]; + if (docObj->isDerivedFrom(OriginFeature::getClassTypeId())) { + sgraph = GraphList[static_cast(docObj)->getOrigin()]; + } } } - if (!sgraph) + if (!sgraph) { sgraph = &DepList; + } // Keep a list of all added document objects. objects.insert(docObj); @@ -294,21 +332,25 @@ void Document::exportGraphviz(std::ostream& out) const get(vertex_attribute, *sgraph)[LocalVertexList[getId(docObj)]]["style"] = "filled"; get(vertex_attribute, *sgraph)[LocalVertexList[getId(docObj)]]["shape"] = "Mrecord"; // Set node label - if (name == label) + if (name == label) { get(vertex_attribute, *sgraph)[LocalVertexList[getId(docObj)]]["label"] = name; - else - get(vertex_attribute, *sgraph)[LocalVertexList[getId(docObj)]]["label"] = name + "\n(" + label + ")"; + } + else { + get(vertex_attribute, *sgraph)[LocalVertexList[getId(docObj)]]["label"] = + name + "\n(" + label + ")"; + } } else { get(vertex_attribute, *sgraph)[LocalVertexList[getId(docObj)]]["style"] = "invis"; - get(vertex_attribute, *sgraph)[LocalVertexList[getId(docObj)]]["fixedsize"] = "true"; + get(vertex_attribute, *sgraph)[LocalVertexList[getId(docObj)]]["fixedsize"] = + "true"; get(vertex_attribute, *sgraph)[LocalVertexList[getId(docObj)]]["width"] = "0"; get(vertex_attribute, *sgraph)[LocalVertexList[getId(docObj)]]["height"] = "0"; } // Add expressions and its dependencies - auto expressions{docObj->ExpressionEngine.getExpressions()}; - for (const auto &expr : expressions) { + auto expressions {docObj->ExpressionEngine.getExpressions()}; + for (const auto& expr : expressions) { auto found = std::as_const(GlobalVertexList).find(getId(expr.first)); if (found == GlobalVertexList.end()) { int vid = LocalVertexList[getId(expr.first)] = add_vertex(*sgraph); @@ -318,63 +360,70 @@ void Document::exportGraphviz(std::ostream& out) const } // Add all dependencies - for (const auto &expression : expressions) { + for (const auto& expression : expressions) { // Get dependencies std::map deps; expression.second->getIdentifiers(deps); - // Create subgraphs for all documentobjects that it depends on; it will depend on some property there - for (const auto &dep : deps) { + // Create subgraphs for all documentobjects that it depends on; it will depend on + // some property there + for (const auto& dep : deps) { if (dep.second) { continue; } - DocumentObject *depObjDoc = dep.first.getDocumentObject(); + DocumentObject* depObjDoc = dep.first.getDocumentObject(); auto found = GlobalVertexList.find(getId(dep.first)); if (found == GlobalVertexList.end()) { - Graph *depSgraph = GraphList[depObjDoc] ? GraphList[depObjDoc] : &DepList; + Graph* depSgraph = GraphList[depObjDoc] ? GraphList[depObjDoc] : &DepList; LocalVertexList[getId(dep.first)] = add_vertex(*depSgraph); GlobalVertexList[getId(dep.first)] = vertex_no++; - setPropertyVertexAttributes(*depSgraph, LocalVertexList[getId(dep.first)], dep.first.getPropertyName() + dep.first.getSubPathStr()); + setPropertyVertexAttributes(*depSgraph, + LocalVertexList[getId(dep.first)], + dep.first.getPropertyName() + + dep.first.getSubPathStr()); } } } } - void recursiveCSSubgraphs(DocumentObject* cs, DocumentObject* parent) { + void recursiveCSSubgraphs(DocumentObject* cs, DocumentObject* parent) + { auto graph = parent ? GraphList[parent] : &DepList; // check if the value for the key 'parent' is null - if (!graph) + if (!graph) { return; + } auto& sub = graph->create_subgraph(); GraphList[cs] = ⊂ get_property(sub, graph_name) = getClusterName(cs); - //build random color string + // build random color string std::stringstream stream; - stream << "#" << std::setfill('0') << std::setw(2)<< std::hex << distribution(seed) - << std::setfill('0') << std::setw(2)<< std::hex << distribution(seed) - << std::setfill('0') << std::setw(2)<< std::hex << distribution(seed) << 80; + stream << "#" << std::setfill('0') << std::setw(2) << std::hex << distribution(seed) + << std::setfill('0') << std::setw(2) << std::hex << distribution(seed) + << std::setfill('0') << std::setw(2) << std::hex << distribution(seed) << 80; std::string result(stream.str()); get_property(sub, graph_graph_attribute)["bgcolor"] = result; get_property(sub, graph_graph_attribute)["style"] = "rounded,filled"; setGraphLabel(sub, cs); - for(auto obj : cs->getOutList()) { + for (auto obj : cs->getOutList()) { if (obj->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId())) { // in case of dependencies loops check if obj is already part of the // map to avoid infinite recursions auto it = GraphList.find(obj); - if (it == GraphList.end()) + if (it == GraphList.end()) { recursiveCSSubgraphs(obj, cs); + } } } - //setup the origin if available - if(cs->hasExtension(App::OriginGroupExtension::getExtensionClassTypeId())) { + // setup the origin if available + if (cs->hasExtension(App::OriginGroupExtension::getExtensionClassTypeId())) { auto origin = cs->getExtensionByType()->Origin.getValue(); if (!origin) { std::cerr << "Origin feature not found" << std::endl; @@ -388,67 +437,80 @@ void Document::exportGraphviz(std::ostream& out) const } } - void addSubgraphs() { + void addSubgraphs() + { - ParameterGrp::handle depGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/DependencyGraph"); + ParameterGrp::handle depGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/DependencyGraph"); bool CSSubgraphs = depGrp->GetBool("GeoFeatureSubgraphs", true); - if(CSSubgraphs) { - //first build up the coordinate system subgraphs + if (CSSubgraphs) { + // first build up the coordinate system subgraphs for (auto objectIt : d->objectArray) { - // ignore groups inside other groups, these will be processed in one of the next recursive calls. - // App::Origin now has the GeoFeatureGroupExtension but it should not move its - // group symbol outside its parent - if (!objectIt->isDerivedFrom(Origin::getClassTypeId()) && - objectIt->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId()) && - GeoFeatureGroupExtension::getGroupOfObject(objectIt) == nullptr) - { + // ignore groups inside other groups, these will be processed in one of the next + // recursive calls. App::Origin now has the GeoFeatureGroupExtension but it + // should not move its group symbol outside its parent + if (!objectIt->isDerivedFrom(Origin::getClassTypeId()) + && objectIt->hasExtension( + GeoFeatureGroupExtension::getExtensionClassTypeId()) + && GeoFeatureGroupExtension::getGroupOfObject(objectIt) == nullptr) { recursiveCSSubgraphs(objectIt, nullptr); } } } // Internal document objects - for (const auto & It : d->objectMap) + for (const auto& It : d->objectMap) { addExpressionSubgraphIfNeeded(It.second, CSSubgraphs); + } // Add external document objects - for (const auto & it : d->objectMap) { + for (const auto& it : d->objectMap) { std::vector OutList = it.second->getOutList(); for (auto obj : OutList) { if (obj) { - std::map::const_iterator item = GlobalVertexList.find(getId(obj)); + std::map::const_iterator item = + GlobalVertexList.find(getId(obj)); - if (item == GlobalVertexList.end()) + if (item == GlobalVertexList.end()) { addExpressionSubgraphIfNeeded(obj, CSSubgraphs); + } } } } - } // Filling up the adjacency List - void buildAdjacencyList() { + void buildAdjacencyList() + { - ParameterGrp::handle depGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/DependencyGraph"); + ParameterGrp::handle depGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/DependencyGraph"); bool CSSubgraphs = depGrp->GetBool("GeoFeatureSubgraphs", true); // Add internal document objects - for (const auto & It : d->objectMap) - add(It.second, It.second->getNameInDocument(), It.second->Label.getValue(), CSSubgraphs); + for (const auto& It : d->objectMap) { + add(It.second, + It.second->getNameInDocument(), + It.second->Label.getValue(), + CSSubgraphs); + } // Add external document objects - for (const auto & It : d->objectMap) { + for (const auto& It : d->objectMap) { std::vector OutList = It.second->getOutList(); for (auto obj : OutList) { if (obj) { - std::map::const_iterator item = GlobalVertexList.find(getId(obj)); + std::map::const_iterator item = + GlobalVertexList.find(getId(obj)); if (item == GlobalVertexList.end()) { if (obj->isAttachedToDocument()) { add(obj, - std::string(obj->getDocument()->getName()) + "#" + obj->getNameInDocument(), - std::string(obj->getDocument()->getName()) + "#" + obj->Label.getValue(), + std::string(obj->getDocument()->getName()) + "#" + + obj->getNameInDocument(), + std::string(obj->getDocument()->getName()) + "#" + + obj->Label.getValue(), CSSubgraphs); } } @@ -457,31 +519,37 @@ void Document::exportGraphviz(std::ostream& out) const } } - void addEdges() { + void addEdges() + { // Get edge properties for main graph - const boost::property_map::type& edgeAttrMap = boost::get(boost::edge_attribute, DepList); + const boost::property_map::type& edgeAttrMap = + boost::get(boost::edge_attribute, DepList); // Track edges between document objects connected by expression dependencies - std::set > existingEdges; + std::set> existingEdges; // Add edges between properties - for (const auto &docObj : objects) { + for (const auto& docObj : objects) { // Add expressions and its dependencies auto expressions = docObj->ExpressionEngine.getExpressions(); - for (const auto &expr : expressions) { + for (const auto& expr : expressions) { std::map deps; expr.second->getIdentifiers(deps); - // Create subgraphs for all documentobjects that it depends on; it will depend on some property there - for (const auto &dep : deps) { - if (dep.second) + // Create subgraphs for all documentobjects that it depends on; it will depend + // on some property there + for (const auto& dep : deps) { + if (dep.second) { continue; - DocumentObject * depObjDoc = dep.first.getDocumentObject(); + } + DocumentObject* depObjDoc = dep.first.getDocumentObject(); Edge edge; bool inserted; - tie(edge, inserted) = add_edge(GlobalVertexList[getId(expr.first)], GlobalVertexList[getId(dep.first)], DepList); + tie(edge, inserted) = add_edge(GlobalVertexList[getId(expr.first)], + GlobalVertexList[getId(dep.first)], + DepList); // Add this edge to the set of all expression generated edges existingEdges.insert(std::make_pair(docObj, depObjDoc)); @@ -493,54 +561,69 @@ void Document::exportGraphviz(std::ostream& out) const } } - ParameterGrp::handle depGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/DependencyGraph"); + ParameterGrp::handle depGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/DependencyGraph"); bool omitGeoFeatureGroups = depGrp->GetBool("GeoFeatureSubgraphs", true); // Add edges between document objects - for (const auto & It : d->objectMap) { + for (const auto& It : d->objectMap) { - if(omitGeoFeatureGroups && It.second->isDerivedFrom(Origin::getClassTypeId())) { + if (omitGeoFeatureGroups && It.second->isDerivedFrom(Origin::getClassTypeId())) { continue; } std::map dups; std::vector OutList = It.second->getOutList(); - const DocumentObject * docObj = It.second; - const bool docObj_is_group = docObj->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId()); + const DocumentObject* docObj = It.second; + const bool docObj_is_group = + docObj->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId()); for (auto obj : OutList) { if (obj) { - if(omitGeoFeatureGroups && docObj_is_group && GeoFeatureGroupExtension::getGroupOfObject(obj) == docObj) { + if (omitGeoFeatureGroups && docObj_is_group + && GeoFeatureGroupExtension::getGroupOfObject(obj) == docObj) { continue; } // Count duplicate edges - bool inserted = edge(GlobalVertexList[getId(docObj)], GlobalVertexList[getId(obj)], DepList).second; + bool inserted = edge(GlobalVertexList[getId(docObj)], + GlobalVertexList[getId(obj)], + DepList) + .second; if (inserted) { dups[obj]++; continue; } // Skip edge if an expression edge already exists - if (existingEdges.find(std::make_pair(docObj, obj)) != existingEdges.end()) + if (existingEdges.find(std::make_pair(docObj, obj)) + != existingEdges.end()) { continue; + } // Add edge Edge edge; - tie(edge, inserted) = add_edge(GlobalVertexList[getId(docObj)], GlobalVertexList[getId(obj)], DepList); + tie(edge, inserted) = add_edge(GlobalVertexList[getId(docObj)], + GlobalVertexList[getId(obj)], + DepList); // Set properties to make arrows go between subgraphs if needed - if (GraphList[docObj]) + if (GraphList[docObj]) { edgeAttrMap[edge]["ltail"] = getClusterName(docObj); - if (GraphList[obj]) + } + if (GraphList[obj]) { edgeAttrMap[edge]["lhead"] = getClusterName(obj); + } } } // Set labels for duplicate edges - for (const auto & dup : dups) { - Edge e(edge(GlobalVertexList[getId(It.second)], GlobalVertexList[getId(dup.first)], DepList).first); + for (const auto& dup : dups) { + Edge e(edge(GlobalVertexList[getId(It.second)], + GlobalVertexList[getId(dup.first)], + DepList) + .first); std::stringstream s; s << " " << (dup.second + 1) << "x"; edgeAttrMap[e]["label"] = s.str(); @@ -550,10 +633,11 @@ void Document::exportGraphviz(std::ostream& out) const using EdgeMap = std::unordered_multimap; - void removeEdges(EdgeMap & in_edges, - EdgeMap & out_edges, - std::pair i_pair, - std::function select_vertex) { + void removeEdges(EdgeMap& in_edges, + EdgeMap& out_edges, + std::pair i_pair, + std::function select_vertex) + { auto i = i_pair.first; while (i != i_pair.second) { @@ -562,10 +646,12 @@ void Document::exportGraphviz(std::ostream& out) const auto in_i = in_i_pair.first; while (in_i != in_i_pair.second) { - if (in_i->second == i->second) + if (in_i->second == i->second) { in_i = in_edges.erase(in_i); - else + } + else { ++in_i; + } } // Remove node from out_edges @@ -574,12 +660,13 @@ void Document::exportGraphviz(std::ostream& out) const } #if defined(__clang__) -#elif defined (__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#elif defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif - void markCycles() { + void markCycles() + { bool changed = true; std::unordered_set in_use; EdgeMap in_edges; @@ -588,8 +675,9 @@ void Document::exportGraphviz(std::ostream& out) const // Add all vertices to the in_use set graph_traits::vertex_iterator vi, vi_end; tie(vi, vi_end) = vertices(DepList); - for (; vi != vi_end; ++vi) + for (; vi != vi_end; ++vi) { in_use.insert(*vi); + } // Add all edges to the in_edges and out_edges multimaps graph_traits::edge_iterator ei, ei_end; @@ -616,21 +704,26 @@ void Document::exportGraphviz(std::ostream& out) const auto i_in_deg_pair = in_edges.equal_range(*uvi); auto i_out_deg_pair = out_edges.equal_range(*uvi); - if (i_in_deg_pair.first == in_edges.end() && i_out_deg_pair.first == out_edges.end()) { + if (i_in_deg_pair.first == in_edges.end() + && i_out_deg_pair.first == out_edges.end()) { uvi = in_use.erase(uvi); continue; } // Remove out edges of nodes that don't have a single edge in if (i_in_deg_pair.first == in_edges.end()) { - removeEdges(in_edges, out_edges, i_out_deg_pair, [&](Edge e) { return target(e, DepList); }); + removeEdges(in_edges, out_edges, i_out_deg_pair, [&](Edge e) { + return target(e, DepList); + }); changed = true; i_out_deg_pair = out_edges.equal_range(*uvi); } // Remove in edges of nodes that don't have a single edge out if (i_out_deg_pair.first == out_edges.end()) { - removeEdges(out_edges, in_edges, i_in_deg_pair, [&](Edge e) { return source(e, DepList); }); + removeEdges(out_edges, in_edges, i_in_deg_pair, [&](Edge e) { + return source(e, DepList); + }); changed = true; } @@ -639,41 +732,48 @@ void Document::exportGraphviz(std::ostream& out) const } // Update colors in graph - const boost::property_map::type& edgeAttrMap = boost::get(boost::edge_attribute, DepList); - for (auto ei : out_edges) + const boost::property_map::type& edgeAttrMap = + boost::get(boost::edge_attribute, DepList); + for (auto ei : out_edges) { edgeAttrMap[ei.second]["color"] = "red"; + } } #if defined(__clang__) -#elif defined (__GNUC__) -# pragma GCC diagnostic pop +#elif defined(__GNUC__) +#pragma GCC diagnostic pop #endif - void markOutOfScopeLinks() { - const boost::property_map::type& edgeAttrMap = boost::get(boost::edge_attribute, DepList); + void markOutOfScopeLinks() + { + const boost::property_map::type& edgeAttrMap = + boost::get(boost::edge_attribute, DepList); - for( auto obj : objects) { + for (auto obj : objects) { std::vector invalids; GeoFeatureGroupExtension::getInvalidLinkObjects(obj, invalids); - //isLinkValid returns true for non-link properties - for(auto linkedObj : invalids) { + // isLinkValid returns true for non-link properties + for (auto linkedObj : invalids) { - auto res = edge(GlobalVertexList[getId(obj)], GlobalVertexList[getId(linkedObj)], DepList); - if(res.second) + auto res = edge(GlobalVertexList[getId(obj)], + GlobalVertexList[getId(linkedObj)], + DepList); + if (res.second) { edgeAttrMap[res.first]["color"] = "orange"; + } } } } const struct DocumentP* d; Graph DepList; - int vertex_no{0}; + int vertex_no {0}; std::map LocalVertexList; std::map GlobalVertexList; std::set objects; std::map GraphList; - //random color generation + // random color generation std::mt19937 seed; std::uniform_int_distribution distribution; }; diff --git a/src/App/GroupExtension.cpp b/src/App/GroupExtension.cpp index 7e47743846..6e017b82f9 100644 --- a/src/App/GroupExtension.cpp +++ b/src/App/GroupExtension.cpp @@ -35,21 +35,29 @@ namespace sp = std::placeholders; EXTENSION_PROPERTY_SOURCE(App::GroupExtension, App::DocumentObjectExtension) -namespace App { +namespace App +{ EXTENSION_PROPERTY_SOURCE_TEMPLATE(App::GroupExtensionPython, App::GroupExtension) // explicit template instantiation template class AppExport ExtensionPythonT>; -} +} // namespace App GroupExtension::GroupExtension() { initExtensionType(GroupExtension::getExtensionClassTypeId()); - - EXTENSION_ADD_PROPERTY_TYPE(Group,(nullptr),"Base",(App::PropertyType)(Prop_None),"List of referenced objects"); - EXTENSION_ADD_PROPERTY_TYPE(_GroupTouched, (false), "Base", - PropertyType(Prop_Hidden|Prop_Transient),0); + EXTENSION_ADD_PROPERTY_TYPE(Group, + (nullptr), + "Base", + (App::PropertyType)(Prop_None), + "List of referenced objects"); + + EXTENSION_ADD_PROPERTY_TYPE(_GroupTouched, + (false), + "Base", + PropertyType(Prop_Hidden | Prop_Transient), + 0); } GroupExtension::~GroupExtension() = default; @@ -57,7 +65,7 @@ GroupExtension::~GroupExtension() = default; DocumentObject* GroupExtension::addObject(const char* sType, const char* pObjectName) { DocumentObject* obj = getExtendedObject()->getDocument()->addObject(sType, pObjectName); - if(!allowObject(obj)) { + if (!allowObject(obj)) { getExtendedObject()->getDocument()->removeObject(obj->getNameInDocument()); return nullptr; } @@ -71,47 +79,55 @@ std::vector GroupExtension::addObject(DocumentObject* obj) return addObjects(vec); } -std::vector< DocumentObject* > GroupExtension::addObjects(std::vector< DocumentObject* > objs) { - +std::vector GroupExtension::addObjects(std::vector objs) +{ + std::vector added; std::vector grp = Group.getValues(); - for(auto obj : objs) { - - if(!allowObject(obj)) + for (auto obj : objs) { + + if (!allowObject(obj)) { continue; - - if (hasObject(obj)) + } + + if (hasObject(obj)) { continue; - - //only one group per object. Note that it is allowed to be in a group and geofeaturegroup. However, - //getGroupOfObject() returns only normal groups, no GeoFeatureGroups. Hence this works. - auto *group = App::GroupExtension::getGroupOfObject(obj); - if(group && group != getExtendedObject()) + } + + // only one group per object. Note that it is allowed to be in a group and geofeaturegroup. + // However, getGroupOfObject() returns only normal groups, no GeoFeatureGroups. Hence this + // works. + auto* group = App::GroupExtension::getGroupOfObject(obj); + if (group && group != getExtendedObject()) { group->getExtensionByType()->removeObject(obj); - - //if we are in a geofeaturegroup we need to ensure the object is too + } + + // if we are in a geofeaturegroup we need to ensure the object is too auto geogrp = GeoFeatureGroupExtension::getGroupOfObject(getExtendedObject()); auto objgrp = GeoFeatureGroupExtension::getGroupOfObject(obj); - if( geogrp != objgrp ) { - //what to do depends on if we are in geofeature group or not - if(geogrp) + if (geogrp != objgrp) { + // what to do depends on if we are in geofeature group or not + if (geogrp) { geogrp->getExtensionByType()->addObject(obj); - else + } + else { objgrp->getExtensionByType()->removeObject(obj); + } } - + grp.push_back(obj); added.push_back(obj); } - + Group.setValues(grp); - + return added; } -std::vector< DocumentObject* > GroupExtension::setObjects(std::vector< DocumentObject* > obj) { +std::vector GroupExtension::setObjects(std::vector obj) +{ - Group.setValues(std::vector< DocumentObject* > ()); + Group.setValues(std::vector()); return addObjects(obj); } @@ -121,26 +137,27 @@ std::vector GroupExtension::removeObject(DocumentObject* obj) return removeObjects(vec); } -std::vector< DocumentObject* > GroupExtension::removeObjects(std::vector< DocumentObject* > objs) { +std::vector GroupExtension::removeObjects(std::vector objs) +{ - const std::vector & grp = Group.getValues(); + const std::vector& grp = Group.getValues(); std::vector newGrp = grp; std::vector removed; std::vector::iterator end = newGrp.end(); - for(auto obj : objs) { - auto res = std::remove(newGrp.begin(), end, obj); - if(res != end) { - end = res; - removed.push_back(obj); - } + for (auto obj : objs) { + auto res = std::remove(newGrp.begin(), end, obj); + if (res != end) { + end = res; + removed.push_back(obj); + } } - + newGrp.erase(end, newGrp.end()); if (grp.size() != newGrp.size()) { - Group.setValues (newGrp); + Group.setValues(newGrp); } - + return removed; } @@ -150,7 +167,7 @@ void GroupExtension::removeObjectsFromDocument() // Remove the objects step by step because it can happen // that an object is part of several groups and thus a // double destruction could be possible - const std::vector & grp = Group.getValues(); + const std::vector& grp = Group.getValues(); removeObjectFromDocument(grp.front()); } } @@ -158,12 +175,14 @@ void GroupExtension::removeObjectsFromDocument() void GroupExtension::removeObjectFromDocument(DocumentObject* obj) { // check that object is not invalid - if (!obj || !obj->isAttachedToDocument()) + if (!obj || !obj->isAttachedToDocument()) { return; + } // remove all children if (obj->hasExtension(GroupExtension::getExtensionClassTypeId())) { - GroupExtension *grp = static_cast(obj->getExtension(GroupExtension::getExtensionClassTypeId())); + GroupExtension* grp = static_cast( + obj->getExtension(GroupExtension::getExtensionClassTypeId())); // recursive call to remove all subgroups grp->removeObjectsFromDocument(); @@ -172,11 +191,12 @@ void GroupExtension::removeObjectFromDocument(DocumentObject* obj) getExtendedObject()->getDocument()->removeObject(obj->getNameInDocument()); } -DocumentObject *GroupExtension::getObject(const char *Name) const +DocumentObject* GroupExtension::getObject(const char* Name) const { DocumentObject* obj = getExtendedObject()->getDocument()->getObject(Name); - if (obj && hasObject(obj)) + if (obj && hasObject(obj)) { return obj; + } return nullptr; } @@ -190,22 +210,24 @@ bool GroupExtension::hasObject(const DocumentObject* obj, bool recursive) const const std::vector& grp = Group.getValues(); for (auto child : grp) { - if (!child) + if (!child) { continue; + } if (child == obj) { return true; } else if (child == getExtendedObject()) { - throw Base::RuntimeError("Cyclic dependencies detected: Search cannot be performed"); + throw Base::RuntimeError( + "Cyclic dependencies detected: Search cannot be performed"); } - else if ( recursive && child->hasExtension(GroupExtension::getExtensionClassTypeId()) ) { - App::GroupExtension *subGroup = static_cast ( - child->getExtension(GroupExtension::getExtensionClassTypeId())); + else if (recursive && child->hasExtension(GroupExtension::getExtensionClassTypeId())) { + App::GroupExtension* subGroup = static_cast( + child->getExtension(GroupExtension::getExtensionClassTypeId())); std::vector history; history.push_back(this); - if (subGroup->recursiveHasObject (obj, subGroup, history)) { + if (subGroup->recursiveHasObject(obj, subGroup, history)) { return true; } } @@ -219,31 +241,36 @@ bool GroupExtension::hasObject(const DocumentObject* obj, bool recursive) const } } -bool GroupExtension::recursiveHasObject(const DocumentObject* obj, const GroupExtension* group, - std::vector< const GroupExtension* > history) const { +bool GroupExtension::recursiveHasObject(const DocumentObject* obj, + const GroupExtension* group, + std::vector history) const +{ - //the purpose is to prevent infinite recursion when groups form a cyclic graph. To do this - //we store every group we processed on the current leave of the tree, and if we reach an - //already processed group we know that it not really is a tree but a cycle. + // the purpose is to prevent infinite recursion when groups form a cyclic graph. To do this + // we store every group we processed on the current leave of the tree, and if we reach an + // already processed group we know that it not really is a tree but a cycle. history.push_back(this); - //we use hasObject with out recursion to allow override in derived classes - if(group->hasObject(obj, false)) + // we use hasObject with out recursion to allow override in derived classes + if (group->hasObject(obj, false)) { return true; + } - //we checked for the searched object already with hasObject and did not find it, now we need to - //do the same for all subgroups + // we checked for the searched object already with hasObject and did not find it, now we need to + // do the same for all subgroups for (auto child : group->Group.getValues()) { - if(!child) + if (!child) { continue; + } - if ( child->hasExtension(GroupExtension::getExtensionClassTypeId()) ) { + if (child->hasExtension(GroupExtension::getExtensionClassTypeId())) { auto ext = child->getExtensionByType(); - + if (std::find(history.begin(), history.end(), ext) != history.end()) { - throw Base::RuntimeError("Cyclic dependencies detected: Search cannot be performed"); + throw Base::RuntimeError( + "Cyclic dependencies detected: Search cannot be performed"); } if (recursiveHasObject(obj, ext, history)) { @@ -259,7 +286,7 @@ bool GroupExtension::isChildOf(const GroupExtension* group, bool recursive) cons return group->hasObject(getExtendedObject(), recursive); } -const std::vector &GroupExtension::getObjects() const +const std::vector& GroupExtension::getObjects() const { return Group.getValues(); } @@ -269,8 +296,9 @@ std::vector GroupExtension::getObjectsOfType(const Base::Type& std::vector type; const std::vector& grp = Group.getValues(); for (auto it : grp) { - if (it->getTypeId().isDerivedFrom(typeId)) + if (it->getTypeId().isDerivedFrom(typeId)) { type.push_back(it); + } } return type; @@ -278,11 +306,12 @@ std::vector GroupExtension::getObjectsOfType(const Base::Type& int GroupExtension::countObjectsOfType(const Base::Type& typeId) const { - int type=0; + int type = 0; const std::vector& grp = Group.getValues(); for (auto it : grp) { - if ( it->getTypeId().isDerivedFrom(typeId)) + if (it->getTypeId().isDerivedFrom(typeId)) { type++; + } } return type; @@ -290,57 +319,63 @@ int GroupExtension::countObjectsOfType(const Base::Type& typeId) const DocumentObject* GroupExtension::getGroupOfObject(const DocumentObject* obj) { - //note that we return here only Groups, but nothing derived from it, e.g. no GeoFeatureGroups. - //That is important as there are clear differences between groups/geofeature groups (e.g. an object - //can be in only one group, and only one geofeaturegroup, however, it can be in both at the same time) + // note that we return here only Groups, but nothing derived from it, e.g. no GeoFeatureGroups. + // That is important as there are clear differences between groups/geofeature groups (e.g. an + // object can be in only one group, and only one geofeaturegroup, however, it can be in both at + // the same time) for (auto o : obj->getInList()) { - if (o->hasExtension(App::GroupExtension::getExtensionClassTypeId(), false)) + if (o->hasExtension(App::GroupExtension::getExtensionClassTypeId(), false)) { return o; - if (o->hasExtension(App::GroupExtensionPython::getExtensionClassTypeId(), false)) + } + if (o->hasExtension(App::GroupExtensionPython::getExtensionClassTypeId(), false)) { return o; + } } return nullptr; } -PyObject* GroupExtension::getExtensionPyObject() { +PyObject* GroupExtension::getExtensionPyObject() +{ - if (ExtensionPythonObject.is(Py::_None())){ + if (ExtensionPythonObject.is(Py::_None())) { // ref counter is set to 1 auto grp = new GroupExtensionPy(this); - ExtensionPythonObject = Py::Object(grp,true); + ExtensionPythonObject = Py::Object(grp, true); } return Py::new_reference_to(ExtensionPythonObject); } -void GroupExtension::extensionOnChanged(const Property* p) { +void GroupExtension::extensionOnChanged(const Property* p) +{ + + // objects are only allowed in a single group. Note that this check must only be done for normal + // groups, not any derived classes + if ((this->getExtensionTypeId() == GroupExtension::getExtensionClassTypeId()) && p == &Group + && !Group.testStatus(Property::User3)) { + if (!getExtendedObject()->isRestoring() + && !getExtendedObject()->getDocument()->isPerformingTransaction()) { - //objects are only allowed in a single group. Note that this check must only be done for normal - //groups, not any derived classes - if((this->getExtensionTypeId() == GroupExtension::getExtensionClassTypeId()) - && p == &Group && !Group.testStatus(Property::User3)) - { - if(!getExtendedObject()->isRestoring() && - !getExtendedObject()->getDocument()->isPerformingTransaction()) { - bool error = false; auto corrected = Group.getValues(); - for(auto obj : Group.getValues()) { + for (auto obj : Group.getValues()) { - //we have already set the obj into the group, so in a case of multiple groups getGroupOfObject - //would return anyone of it and hence it is possible that we miss an error. We need a custom check + // we have already set the obj into the group, so in a case of multiple groups + // getGroupOfObject would return anyone of it and hence it is possible that we miss + // an error. We need a custom check auto list = obj->getInList(); for (auto in : list) { - if(in->hasExtension(App::GroupExtension::getExtensionClassTypeId(), false) && - in != getExtendedObject()) { + if (in->hasExtension(App::GroupExtension::getExtensionClassTypeId(), false) + && in != getExtendedObject()) { error = true; - corrected.erase(std::remove(corrected.begin(), corrected.end(), obj), corrected.end()); + corrected.erase(std::remove(corrected.begin(), corrected.end(), obj), + corrected.end()); } } } - //if an error was found we need to correct the values and inform the user - if(error) { + // if an error was found we need to correct the values and inform the user + if (error) { Base::ObjectStatusLocker guard(Property::User3, &Group); Group.setValues(corrected); throw Base::RuntimeError("Object can only be in a single Group"); @@ -348,14 +383,14 @@ void GroupExtension::extensionOnChanged(const Property* p) { } } - if(p == &Group) { + if (p == &Group) { _Conns.clear(); - for(auto obj : Group.getValue()) { - if(obj && obj->isAttachedToDocument()) { - //NOLINTBEGIN - _Conns[obj] = obj->signalChanged.connect(std::bind( - &GroupExtension::slotChildChanged,this,sp::_1, sp::_2)); - //NOLINTEND + for (auto obj : Group.getValue()) { + if (obj && obj->isAttachedToDocument()) { + // NOLINTBEGIN + _Conns[obj] = obj->signalChanged.connect( + std::bind(&GroupExtension::slotChildChanged, this, sp::_1, sp::_2)); + // NOLINTEND } } } @@ -363,71 +398,87 @@ void GroupExtension::extensionOnChanged(const Property* p) { App::Extension::extensionOnChanged(p); } -void GroupExtension::slotChildChanged(const DocumentObject &obj, const Property &prop) { - if(&prop == &obj.Visibility) +void GroupExtension::slotChildChanged(const DocumentObject& obj, const Property& prop) +{ + if (&prop == &obj.Visibility) { _GroupTouched.touch(); + } } -bool GroupExtension::extensionGetSubObject(DocumentObject *&ret, const char *subname, - PyObject **pyObj, Base::Matrix4D *mat, bool /*transform*/, int depth) const +bool GroupExtension::extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject** pyObj, + Base::Matrix4D* mat, + bool /*transform*/, + int depth) const { - const char *dot; - if(!subname || *subname==0) { + const char* dot; + if (!subname || *subname == 0) { auto obj = Base::freecad_dynamic_cast(getExtendedContainer()); ret = const_cast(obj); return true; } - dot=strchr(subname,'.'); - if(!dot) + dot = strchr(subname, '.'); + if (!dot) { return false; - if(subname[0]!='$') - ret = Group.findUsingMap(std::string(subname,dot)); - else{ - std::string name = std::string(subname+1,dot); - for(auto child : Group.getValues()) { - if(name == child->Label.getStrValue()){ + } + if (subname[0] != '$') { + ret = Group.findUsingMap(std::string(subname, dot)); + } + else { + std::string name = std::string(subname + 1, dot); + for (auto child : Group.getValues()) { + if (name == child->Label.getStrValue()) { ret = child; break; } } } - if(!ret) + if (!ret) { return false; - return ret->getSubObject(dot+1,pyObj,mat,true,depth+1); + } + return ret->getSubObject(dot + 1, pyObj, mat, true, depth + 1); } -bool GroupExtension::extensionGetSubObjects(std::vector &ret, int) const { - for(auto obj : Group.getValues()) { - if(obj && obj->isAttachedToDocument()) - ret.push_back(std::string(obj->getNameInDocument())+'.'); +bool GroupExtension::extensionGetSubObjects(std::vector& ret, int) const +{ + for (auto obj : Group.getValues()) { + if (obj && obj->isAttachedToDocument()) { + ret.push_back(std::string(obj->getNameInDocument()) + '.'); + } } return true; } -App::DocumentObjectExecReturn *GroupExtension::extensionExecute() { +App::DocumentObjectExecReturn* GroupExtension::extensionExecute() +{ // This touch property is for propagating changes to upper group _GroupTouched.touch(); return inherited::extensionExecute(); } -std::vector GroupExtension::getAllChildren() const { +std::vector GroupExtension::getAllChildren() const +{ std::vector res; std::set rset; - getAllChildren(res,rset); + getAllChildren(res, rset); return res; } -void GroupExtension::getAllChildren(std::vector &res, - std::set &rset) const +void GroupExtension::getAllChildren(std::vector& res, + std::set& rset) const { - for(auto obj : Group.getValues()) { - if(!obj || !obj->isAttachedToDocument()) + for (auto obj : Group.getValues()) { + if (!obj || !obj->isAttachedToDocument()) { continue; - if(!rset.insert(obj).second) + } + if (!rset.insert(obj).second) { continue; + } res.push_back(obj); - auto ext = obj->getExtensionByType(true,false); - if(ext) - ext->getAllChildren(res,rset); + auto ext = obj->getExtensionByType(true, false); + if (ext) { + ext->getAllChildren(res, rset); + } } } diff --git a/src/App/GroupExtension.h b/src/App/GroupExtension.h index 810ff0d410..4130023d23 100644 --- a/src/App/GroupExtension.h +++ b/src/App/GroupExtension.h @@ -35,7 +35,7 @@ namespace App class DocumentObjectGroup; class GroupExtensionPy; -class AppExport GroupExtension : public DocumentObjectExtension +class AppExport GroupExtension: public DocumentObjectExtension { EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::GroupExtension); using inherited = DocumentObjectExtension; @@ -50,22 +50,25 @@ public: /** Adds an object of \a sType with \a pObjectName to the document this group belongs to and * append it to this group as well. */ - virtual DocumentObject *addObject(const char* sType, const char* pObjectName); + virtual DocumentObject* addObject(const char* sType, const char* pObjectName); /* Adds the object \a obj to this group. Returns all objects that have been added. */ virtual std::vector addObject(DocumentObject* obj); /* Adds the objects \a objs to this group. Returns all objects that have been added. */ virtual std::vector addObjects(std::vector obj); - + /* Sets the objects in this group. Everything contained already will be removed first */ - virtual std::vector< DocumentObject* > setObjects(std::vector< DocumentObject* > obj); - + virtual std::vector setObjects(std::vector obj); + /*override this function if you want only special objects */ - virtual bool allowObject(DocumentObject* ) {return true;} - + virtual bool allowObject(DocumentObject*) + { + return true; + } + /** Removes an object from this group. Returns all objects that have been removed. */ virtual std::vector removeObject(DocumentObject* obj); @@ -75,16 +78,19 @@ public: /** Removes all children objects from this group and the document. */ virtual void removeObjectsFromDocument(); - /** Returns the object of this group with \a Name. If the group doesn't have such an object 0 is returned. - * @note This method might return 0 even if the document this group belongs to contains an object with this name. + /** Returns the object of this group with \a Name. If the group doesn't have such an object 0 is + * returned. + * @note This method might return 0 even if the document this group belongs to contains an + * object with this name. */ - DocumentObject *getObject(const char* Name) const; + DocumentObject* getObject(const char* Name) const; /** * Checks whether the object \a obj is part of this group. * @param obj the object to check for. - * @param recursive if true check also if the obj is child of some sub group (default is false). + * @param recursive if true check also if the obj is child of some sub group (default is + * false). */ - virtual bool hasObject(const DocumentObject* obj, bool recursive=false) const; + virtual bool hasObject(const DocumentObject* obj, bool recursive = false) const; /** * Checks whether this group object is a child (or sub-child if enabled) * of the given group object. @@ -92,7 +98,7 @@ public: bool isChildOf(const GroupExtension* group, bool recursive = true) const; /** Returns a list of all objects this group does have. */ - const std::vector &getObjects() const; + const std::vector& getObjects() const; /** Returns a list of all objects of \a typeId this group does have. */ std::vector getObjectsOfType(const Base::Type& typeId) const; @@ -100,36 +106,44 @@ public: */ int countObjectsOfType(const Base::Type& typeId) const; /** Returns the object group of the document which the given object \a obj is part of. - * In case this object is not part of a group 0 is returned. - * @note This only returns objects that are normal groups, not any special derived type - * like GeoFeatureGroups or OriginGroups. To retrieve those please use their appropriate functions + * In case this object is not part of a group 0 is returned. + * @note This only returns objects that are normal groups, not any special derived type + * like GeoFeatureGroups or OriginGroups. To retrieve those please use their appropriate + * functions */ static DocumentObject* getGroupOfObject(const DocumentObject* obj); //@} - + PyObject* getExtensionPyObject() override; void extensionOnChanged(const Property* p) override; - bool extensionGetSubObject(DocumentObject *&ret, const char *subname, - PyObject **pyObj, Base::Matrix4D *mat, bool transform, int depth) const override; + bool extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject** pyObj, + Base::Matrix4D* mat, + bool transform, + int depth) const override; - bool extensionGetSubObjects(std::vector &ret, int reason) const override; + bool extensionGetSubObjects(std::vector& ret, int reason) const override; - App::DocumentObjectExecReturn *extensionExecute() override; + App::DocumentObjectExecReturn* extensionExecute() override; std::vector getAllChildren() const; - void getAllChildren(std::vector &, std::set &) const; - + void getAllChildren(std::vector&, std::set&) const; + /// Properties PropertyLinkList Group; PropertyBool _GroupTouched; private: void removeObjectFromDocument(DocumentObject*); - // This function stores the already searched objects to prevent infinite recursion in case of a cyclic group graph - // It throws an exception of type Base::RuntimeError if a cyclic dependency is detected. - bool recursiveHasObject(const DocumentObject* obj, const GroupExtension* group, std::vector history) const; + // This function stores the already searched objects to prevent infinite recursion in case of a + // cyclic group graph It throws an exception of type Base::RuntimeError if a cyclic dependency + // is detected. + bool recursiveHasObject(const DocumentObject* obj, + const GroupExtension* group, + std::vector history) const; // for tracking children visibility void slotChildChanged(const App::DocumentObject&, const App::Property&); @@ -138,32 +152,35 @@ private: template -class GroupExtensionPythonT : public ExtensionT { - +class GroupExtensionPythonT: public ExtensionT +{ + public: - GroupExtensionPythonT() = default; ~GroupExtensionPythonT() override = default; - - //override the documentobjectextension functions to make them available in python - bool allowObject(DocumentObject* obj) override { + + // override the documentobjectextension functions to make them available in python + bool allowObject(DocumentObject* obj) override + { Base::PyGILStateLocker locker; Py::Object pyobj = Py::asObject(obj->getPyObject()); EXTENSION_PROXY_ONEARG(allowObject, pyobj); - - if(result.isNone()) + + if (result.isNone()) { return ExtensionT::allowObject(obj); - - if(result.isBoolean()) + } + + if (result.isBoolean()) { return result.isTrue(); - + } + return false; }; }; using GroupExtensionPython = ExtensionPythonT>; -} //namespace App +} // namespace App -#endif // APP_GROUPEXTENSION_H +#endif // APP_GROUPEXTENSION_H diff --git a/src/App/GroupExtensionPy.xml b/src/App/GroupExtensionPy.xml index 5576a43407..5860051f67 100644 --- a/src/App/GroupExtensionPy.xml +++ b/src/App/GroupExtensionPy.xml @@ -1,13 +1,13 @@ - diff --git a/src/App/GroupExtensionPyImp.cpp b/src/App/GroupExtensionPyImp.cpp index 5b2b118d3d..a13fbd7f65 100644 --- a/src/App/GroupExtensionPyImp.cpp +++ b/src/App/GroupExtensionPyImp.cpp @@ -39,14 +39,15 @@ std::string GroupExtensionPy::representation() const return {""}; } -PyObject* GroupExtensionPy::newObject(PyObject *args) +PyObject* GroupExtensionPy::newObject(PyObject* args) { - char *sType,*sName=nullptr; - if (!PyArg_ParseTuple(args, "s|s", &sType,&sName)) + char *sType, *sName = nullptr; + if (!PyArg_ParseTuple(args, "s|s", &sType, &sName)) { return nullptr; + } - DocumentObject *object = getGroupExtensionPtr()->addObject(sType, sName); - if ( object ) { + DocumentObject* object = getGroupExtensionPtr()->addObject(sType, sName); + if (object) { return object->getPyObject(); } else { @@ -55,20 +56,24 @@ PyObject* GroupExtensionPy::newObject(PyObject *args) } } -PyObject* GroupExtensionPy::addObject(PyObject *args) +PyObject* GroupExtensionPy::addObject(PyObject* args) { - PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) + PyObject* object; + if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) { return nullptr; + } DocumentObjectPy* docObj = static_cast(object); - if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->isAttachedToDocument()) { + if (!docObj->getDocumentObjectPtr() + || !docObj->getDocumentObjectPtr()->isAttachedToDocument()) { PyErr_SetString(Base::PyExc_FC_GeneralError, "Cannot add an invalid object"); return nullptr; } - - if (docObj->getDocumentObjectPtr()->getDocument() != getGroupExtensionPtr()->getExtendedObject()->getDocument()) { - PyErr_SetString(Base::PyExc_FC_GeneralError, "Cannot add an object from another document to this group"); + + if (docObj->getDocumentObjectPtr()->getDocument() + != getGroupExtensionPtr()->getExtendedObject()->getDocument()) { + PyErr_SetString(Base::PyExc_FC_GeneralError, + "Cannot add an object from another document to this group"); return nullptr; } if (docObj->getDocumentObjectPtr() == this->getGroupExtensionPtr()->getExtendedObject()) { @@ -76,110 +81,123 @@ PyObject* GroupExtensionPy::addObject(PyObject *args) return nullptr; } if (docObj->getDocumentObjectPtr()->hasExtension(GroupExtension::getExtensionClassTypeId())) { - App::GroupExtension* docGrp = docObj->getDocumentObjectPtr()->getExtensionByType(); + App::GroupExtension* docGrp = + docObj->getDocumentObjectPtr()->getExtensionByType(); if (docGrp->hasObject(getGroupExtensionPtr()->getExtendedObject())) { - PyErr_SetString(Base::PyExc_FC_GeneralError, "Cannot add a group object to a child group"); + PyErr_SetString(Base::PyExc_FC_GeneralError, + "Cannot add a group object to a child group"); return nullptr; } } GroupExtension* grp = getGroupExtensionPtr(); - auto vec = grp->addObject(docObj->getDocumentObjectPtr()); + auto vec = grp->addObject(docObj->getDocumentObjectPtr()); Py::List list; - for (App::DocumentObject* obj : vec) + for (App::DocumentObject* obj : vec) { list.append(Py::asObject(obj->getPyObject())); + } return Py::new_reference_to(list); } -PyObject* GroupExtensionPy::addObjects(PyObject *args) { - - PyObject *object; - if (!PyArg_ParseTuple(args, "O", &object)) - return nullptr; - - if (PyTuple_Check(object) || PyList_Check(object)) { - Py::Sequence list(object); - Py::Sequence::size_type size = list.size(); - std::vector values; - values.resize(size); - - for (Py::Sequence::size_type i = 0; i < size; i++) { - Py::Object item = list[i]; - if (!PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) { - std::string error = std::string("type in list must be 'DocumentObject', not "); - error += (*item)->ob_type->tp_name; - throw Base::TypeError(error); - } - - values[i] = static_cast(*item)->getDocumentObjectPtr(); - } - - GroupExtension* grp = getGroupExtensionPtr(); - auto vec = grp->addObjects(values); - Py::List result; - for (App::DocumentObject* obj : vec) - result.append(Py::asObject(obj->getPyObject())); - - return Py::new_reference_to(result); - } - - std::string error = std::string("type must be list of 'DocumentObject', not "); - error += object->ob_type->tp_name; - throw Base::TypeError(error); -} - -PyObject* GroupExtensionPy::setObjects(PyObject *args) { - - PyObject *object; - if (!PyArg_ParseTuple(args, "O", &object)) - return nullptr; - - if (PyTuple_Check(object) || PyList_Check(object)) { - Py::Sequence list(object); - Py::Sequence::size_type size = list.size(); - std::vector values; - values.resize(size); - - for (Py::Sequence::size_type i = 0; i < size; i++) { - Py::Object item = list[i]; - if (!PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) { - std::string error = std::string("type in list must be 'DocumentObject', not "); - error += (*item)->ob_type->tp_name; - throw Base::TypeError(error); - } - - values[i] = static_cast(*item)->getDocumentObjectPtr(); - } - - GroupExtension* grp = getGroupExtensionPtr(); - auto vec = grp->setObjects(values); - Py::List result; - for (App::DocumentObject* obj : vec) - result.append(Py::asObject(obj->getPyObject())); - - return Py::new_reference_to(result); - } - - std::string error = std::string("type must be list of 'DocumentObject', not "); - error += object->ob_type->tp_name; - throw Base::TypeError(error); -} - -PyObject* GroupExtensionPy::removeObject(PyObject *args) +PyObject* GroupExtensionPy::addObjects(PyObject* args) { - PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) + + PyObject* object; + if (!PyArg_ParseTuple(args, "O", &object)) { return nullptr; + } + + if (PyTuple_Check(object) || PyList_Check(object)) { + Py::Sequence list(object); + Py::Sequence::size_type size = list.size(); + std::vector values; + values.resize(size); + + for (Py::Sequence::size_type i = 0; i < size; i++) { + Py::Object item = list[i]; + if (!PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) { + std::string error = std::string("type in list must be 'DocumentObject', not "); + error += (*item)->ob_type->tp_name; + throw Base::TypeError(error); + } + + values[i] = static_cast(*item)->getDocumentObjectPtr(); + } + + GroupExtension* grp = getGroupExtensionPtr(); + auto vec = grp->addObjects(values); + Py::List result; + for (App::DocumentObject* obj : vec) { + result.append(Py::asObject(obj->getPyObject())); + } + + return Py::new_reference_to(result); + } + + std::string error = std::string("type must be list of 'DocumentObject', not "); + error += object->ob_type->tp_name; + throw Base::TypeError(error); +} + +PyObject* GroupExtensionPy::setObjects(PyObject* args) +{ + + PyObject* object; + if (!PyArg_ParseTuple(args, "O", &object)) { + return nullptr; + } + + if (PyTuple_Check(object) || PyList_Check(object)) { + Py::Sequence list(object); + Py::Sequence::size_type size = list.size(); + std::vector values; + values.resize(size); + + for (Py::Sequence::size_type i = 0; i < size; i++) { + Py::Object item = list[i]; + if (!PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) { + std::string error = std::string("type in list must be 'DocumentObject', not "); + error += (*item)->ob_type->tp_name; + throw Base::TypeError(error); + } + + values[i] = static_cast(*item)->getDocumentObjectPtr(); + } + + GroupExtension* grp = getGroupExtensionPtr(); + auto vec = grp->setObjects(values); + Py::List result; + for (App::DocumentObject* obj : vec) { + result.append(Py::asObject(obj->getPyObject())); + } + + return Py::new_reference_to(result); + } + + std::string error = std::string("type must be list of 'DocumentObject', not "); + error += object->ob_type->tp_name; + throw Base::TypeError(error); +} + +PyObject* GroupExtensionPy::removeObject(PyObject* args) +{ + PyObject* object; + if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) { + return nullptr; + } DocumentObjectPy* docObj = static_cast(object); - if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->isAttachedToDocument()) { + if (!docObj->getDocumentObjectPtr() + || !docObj->getDocumentObjectPtr()->isAttachedToDocument()) { PyErr_SetString(Base::PyExc_FC_GeneralError, "Cannot remove an invalid object"); return nullptr; } - if (docObj->getDocumentObjectPtr()->getDocument() != getGroupExtensionPtr()->getExtendedObject()->getDocument()) { - PyErr_SetString(Base::PyExc_FC_GeneralError, "Cannot remove an object from another document from this group"); + if (docObj->getDocumentObjectPtr()->getDocument() + != getGroupExtensionPtr()->getExtendedObject()->getDocument()) { + PyErr_SetString(Base::PyExc_FC_GeneralError, + "Cannot remove an object from another document from this group"); return nullptr; } @@ -187,18 +205,21 @@ PyObject* GroupExtensionPy::removeObject(PyObject *args) auto vec = grp->removeObject(docObj->getDocumentObjectPtr()); Py::List list; - for (App::DocumentObject* obj : vec) + for (App::DocumentObject* obj : vec) { list.append(Py::asObject(obj->getPyObject())); + } return Py::new_reference_to(list); } -PyObject* GroupExtensionPy::removeObjects(PyObject *args) { +PyObject* GroupExtensionPy::removeObjects(PyObject* args) +{ - PyObject *object; - if (!PyArg_ParseTuple(args, "O", &object)) + PyObject* object; + if (!PyArg_ParseTuple(args, "O", &object)) { return nullptr; - + } + if (PyTuple_Check(object) || PyList_Check(object)) { Py::Sequence list(object); Py::Sequence::size_type size = list.size(); @@ -217,10 +238,11 @@ PyObject* GroupExtensionPy::removeObjects(PyObject *args) { } GroupExtension* grp = getGroupExtensionPtr(); - auto vec = grp->removeObjects(values); + auto vec = grp->removeObjects(values); Py::List result; - for (App::DocumentObject* obj : vec) + for (App::DocumentObject* obj : vec) { result.append(Py::asObject(obj->getPyObject())); + } return Py::new_reference_to(result); } @@ -230,44 +252,56 @@ PyObject* GroupExtensionPy::removeObjects(PyObject *args) { throw Base::TypeError(error); } -PyObject* GroupExtensionPy::removeObjectsFromDocument(PyObject *args) +PyObject* GroupExtensionPy::removeObjectsFromDocument(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getGroupExtensionPtr()->removeObjectsFromDocument(); Py_Return; } -PyObject* GroupExtensionPy::getObject(PyObject *args) +PyObject* GroupExtensionPy::getObject(PyObject* args) { char* pcName; - if (!PyArg_ParseTuple(args, "s", &pcName)) + if (!PyArg_ParseTuple(args, "s", &pcName)) { return nullptr; + } DocumentObject* obj = getGroupExtensionPtr()->getObject(pcName); - if ( obj ) { + if (obj) { return obj->getPyObject(); - } else { + } + else { Py_Return; } } -PyObject* GroupExtensionPy::hasObject(PyObject *args) +PyObject* GroupExtensionPy::hasObject(PyObject* args) { - PyObject *object; - PyObject *recursivePy = Py_False; - if (!PyArg_ParseTuple(args, "O!|O!", &(DocumentObjectPy::Type), &object, &PyBool_Type, &recursivePy)) + PyObject* object; + PyObject* recursivePy = Py_False; + if (!PyArg_ParseTuple(args, + "O!|O!", + &(DocumentObjectPy::Type), + &object, + &PyBool_Type, + &recursivePy)) { return nullptr; + } DocumentObjectPy* docObj = static_cast(object); bool recursive = Base::asBoolean(recursivePy); - if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->isAttachedToDocument()) { + if (!docObj->getDocumentObjectPtr() + || !docObj->getDocumentObjectPtr()->isAttachedToDocument()) { PyErr_SetString(Base::PyExc_FC_GeneralError, "Cannot check an invalid object"); return nullptr; } - if (docObj->getDocumentObjectPtr()->getDocument() != getGroupExtensionPtr()->getExtendedObject()->getDocument()) { - PyErr_SetString(Base::PyExc_FC_GeneralError, "Cannot check an object from another document with this group"); + if (docObj->getDocumentObjectPtr()->getDocument() + != getGroupExtensionPtr()->getExtendedObject()->getDocument()) { + PyErr_SetString(Base::PyExc_FC_GeneralError, + "Cannot check an object from another document with this group"); return nullptr; } @@ -275,7 +309,7 @@ PyObject* GroupExtensionPy::hasObject(PyObject *args) return PyBool_FromLong(v ? 1 : 0); } -PyObject *GroupExtensionPy::getCustomAttributes(const char* /*attr*/) const +PyObject* GroupExtensionPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } diff --git a/src/App/ImagePlane.cpp b/src/App/ImagePlane.cpp index 9d8b8133ba..120575871e 100644 --- a/src/App/ImagePlane.cpp +++ b/src/App/ImagePlane.cpp @@ -32,9 +32,9 @@ PROPERTY_SOURCE(Image::ImagePlane, App::GeoFeature) ImagePlane::ImagePlane() { - ADD_PROPERTY_TYPE( ImageFile,(nullptr) , "ImagePlane",App::Prop_None,"File of the image"); - ADD_PROPERTY_TYPE( XSize, (100), "ImagePlane",App::Prop_None,"Size of a pixel in X"); - ADD_PROPERTY_TYPE( YSize, (100), "ImagePlane",App::Prop_None,"Size of a pixel in Y"); + ADD_PROPERTY_TYPE(ImageFile, (nullptr), "ImagePlane", App::Prop_None, "File of the image"); + ADD_PROPERTY_TYPE(XSize, (100), "ImagePlane", App::Prop_None, "Size of a pixel in X"); + ADD_PROPERTY_TYPE(YSize, (100), "ImagePlane", App::Prop_None, "Size of a pixel in Y"); } int ImagePlane::getXSizeInPixel() diff --git a/src/App/ImagePlane.h b/src/App/ImagePlane.h index 4afffe1d9c..ff57e2c844 100644 --- a/src/App/ImagePlane.h +++ b/src/App/ImagePlane.h @@ -30,7 +30,7 @@ namespace Image { -class AppExport ImagePlane : public App::GeoFeature +class AppExport ImagePlane: public App::GeoFeature { PROPERTY_HEADER_WITH_OVERRIDE(Image::ImagePlane); @@ -40,24 +40,25 @@ public: ~ImagePlane() override = default; App::PropertyFileIncluded ImageFile; - App::PropertyLength XSize; - App::PropertyLength YSize; + App::PropertyLength XSize; + App::PropertyLength YSize; int getXSizeInPixel(); int getYSizeInPixel(); void setXSizeInPixel(int); void setYSizeInPixel(int); - double XPixelsPerMeter{1000.0}; - double YPixelsPerMeter{1000.0}; + double XPixelsPerMeter {1000.0}; + double YPixelsPerMeter {1000.0}; /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderImagePlane"; } }; -} //namespace Image +} // namespace Image -#endif // App_ImagePlane_H +#endif // App_ImagePlane_H diff --git a/src/App/IndexedName.cpp b/src/App/IndexedName.cpp index ebe9bf2ddb..86fd2234b6 100644 --- a/src/App/IndexedName.cpp +++ b/src/App/IndexedName.cpp @@ -26,8 +26,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif #include "IndexedName.h" @@ -37,17 +37,17 @@ using namespace Data; /// Check whether the input character is an underscore or an ASCII letter a-Z or A-Z inline bool isInvalidChar(char test) { - return test != '_' && (test < 'a' || test > 'z' ) && (test < 'A' || test > 'Z'); + return test != '_' && (test < 'a' || test > 'z') && (test < 'A' || test > 'Z'); } /// Get the integer suffix of name. Returns a tuple of (suffix, suffixPosition). Calling code -/// should check to ensure that suffixPosition is not equal to nameLength (in which case there was no -/// suffix). +/// should check to ensure that suffixPosition is not equal to nameLength (in which case there was +/// no suffix). /// /// \param name The name to check /// \param nameLength The length of the string in name /// \returns An integer pair of the suffix itself and the position of that suffix in name -std::pair getIntegerSuffix(const char *name, int nameLength) +std::pair getIntegerSuffix(const char* name, int nameLength) { int suffixPosition {nameLength - 1}; @@ -68,11 +68,10 @@ std::pair getIntegerSuffix(const char *name, int nameLength) return std::make_pair(suffix, suffixPosition); } -void IndexedName::set( - const char* name, - int length, - const std::vector& allowedNames, - bool allowOthers) +void IndexedName::set(const char* name, + int length, + const std::vector& allowedNames, + bool allowOthers) { // Storage for names that we weren't given external storage for static std::unordered_set NameSet; @@ -90,22 +89,22 @@ void IndexedName::set( // underscore. If any other character appears, reject the entire string. // When we support C++20 we can use std::span<> to eliminate the clang-tidy warning // NOLINTNEXTLINE cppcoreguidelines-pro-bounds-pointer-arithmetic - if (std::any_of(name, name+suffixPosition, isInvalidChar)) { + if (std::any_of(name, name + suffixPosition, isInvalidChar)) { this->type = ""; return; } - // If a list of allowedNames was provided, see if our set name matches one of those allowedNames: if it - // does, reference that memory location and return. - for (const auto *typeName : allowedNames) { + // If a list of allowedNames was provided, see if our set name matches one of those + // allowedNames: if it does, reference that memory location and return. + for (const auto* typeName : allowedNames) { if (std::strncmp(name, typeName, suffixPosition) == 0) { this->type = typeName; return; } } - // If the type was NOT in the list of allowedNames, but the caller has set the allowOthers flag to - // true, then add the new type to the static NameSet (if it is not already there). + // If the type was NOT in the list of allowedNames, but the caller has set the allowOthers flag + // to true, then add the new type to the static NameSet (if it is not already there). if (allowOthers) { auto res = NameSet.insert(ByteArray(QByteArray::fromRawData(name, suffixPosition))); if (res.second /*The insert succeeded (the type was new)*/) { diff --git a/src/App/IndexedName.h b/src/App/IndexedName.h index 7b152a2506..c2504cbaa3 100644 --- a/src/App/IndexedName.h +++ b/src/App/IndexedName.h @@ -40,21 +40,21 @@ namespace Data { -/// The IndexedName class provides a very memory-efficient data structure to hold a name and an index -/// value, and to perform various comparisons and validations of those values. The name must only -/// consist of upper- and lower-case ASCII characters and the underscore ('_') character. The index -/// must be a positive integer. The string representation of this IndexedName is the name followed by -/// the index, with no spaces between: an IndexedName may be constructed from this string. For -/// example "EDGE1" or "FACE345" might be the names of elements that use an IndexedName. If there is -/// then an "EDGE2", only a pointer to the original stored name "EDGE" is retained. +/// The IndexedName class provides a very memory-efficient data structure to hold a name and an +/// index value, and to perform various comparisons and validations of those values. The name must +/// only consist of upper- and lower-case ASCII characters and the underscore ('_') character. The +/// index must be a positive integer. The string representation of this IndexedName is the name +/// followed by the index, with no spaces between: an IndexedName may be constructed from this +/// string. For example "EDGE1" or "FACE345" might be the names of elements that use an IndexedName. +/// If there is then an "EDGE2", only a pointer to the original stored name "EDGE" is retained. /// /// The memory efficiency of the class comes from re-using the same character storage for names that /// match, while retaining their differing indices. This is achieved by either using user-provided /// const char * names (provided as a list of typeNames and presumed to never be deallocated), or by /// maintaining an internal list of names that have been used before, and can be re-used later. -class AppExport IndexedName { +class AppExport IndexedName +{ public: - /// Construct from a name and an optional index. If the name contains an index it is read, but /// is used as the index *only* if _index parameter is unset. If the _index parameter is given /// it overrides any trailing integer in the name. Index must be positive, and name must contain @@ -64,7 +64,7 @@ public: /// \param name The new name - ASCII letters and underscores only, with optional integer suffix. /// This memory will be copied into a new internal storage location and need not be persistent. /// \param _index The new index - if provided, it overrides any suffix provided by name - explicit IndexedName(const char *name = nullptr, int _index = 0) + explicit IndexedName(const char* name = nullptr, int _index = 0) : index(0) { assert(_index >= 0); @@ -93,9 +93,11 @@ public: /// \param allowOthers Whether a name not in allowedTypeNames is permitted. If true (the /// default) then a name not in allowedTypeNames is added to a static internal storage vector /// so that it can be re-used later without additional memory allocation. - IndexedName(const char *name, - const std::vector & allowedTypeNames, - bool allowOthers=true) : type(""), index(0) + IndexedName(const char* name, + const std::vector& allowedTypeNames, + bool allowOthers = true) + : type("") + , index(0) { set(name, -1, allowedTypeNames, allowOthers); } @@ -105,7 +107,9 @@ public: /// is made. /// /// \param data The QByteArray to copy the data from - explicit IndexedName(const QByteArray & data) : type(""), index(0) + explicit IndexedName(const QByteArray& data) + : type("") + , index(0) { set(data.constData(), data.size()); } @@ -117,8 +121,9 @@ public: /// \param name The name of the object. This memory is NOT copied and must be persistent. /// \param index A positive, non-zero integer /// \return An IndexedName with the given name and index, re-using the existing memory for name - static IndexedName fromConst(const char *name, int index) { - assert (index >= 0); + static IndexedName fromConst(const char* name, int index) + { + assert(index >= 0); IndexedName res; res.type = name; res.index = index; @@ -130,7 +135,7 @@ public: /// /// \param buffer A (possibly non-empty) string buffer to append the name to. /// \return A const char pointer to the name we appended to the buffer. - const char * appendToStringBuffer(std::string & buffer) const + const char* appendToStringBuffer(std::string& buffer) const { // Note! buffer is not cleared on purpose. std::size_t offset = buffer.size(); @@ -153,7 +158,7 @@ public: /// An indexedName is represented as the simple concatenation of the name and its index, e.g. /// "EDGE1" or "FACE42". - friend std::ostream & operator<<(std::ostream & stream, const IndexedName & indexedName) + friend std::ostream& operator<<(std::ostream& stream, const IndexedName& indexedName) { stream << indexedName.type; if (indexedName.index > 0) { @@ -163,15 +168,14 @@ public: } /// True only if both the name and index compare exactly equal. - bool operator==(const IndexedName & other) const + bool operator==(const IndexedName& other) const { return this->index == other.index - && (this->type == other.type - || std::strcmp(this->type, other.type)==0); + && (this->type == other.type || std::strcmp(this->type, other.type) == 0); } /// Increments the index by the given offset. Does not affect the text part of the name. - IndexedName & operator+=(int offset) + IndexedName& operator+=(int offset) { this->index += offset; assert(this->index >= 0); @@ -179,7 +183,7 @@ public: } /// Pre-increment operator: increases the index of this element by one. - IndexedName & operator++() + IndexedName& operator++() { ++this->index; return *this; @@ -187,7 +191,7 @@ public: /// Pre-decrement operator: decreases the index of this element by one. Must not make the index /// negative (only checked when compiled in debug mode). - IndexedName & operator--() + IndexedName& operator--() { --this->index; assert(this->index >= 0); @@ -195,13 +199,13 @@ public: } /// True if either the name or the index compare not equal. - bool operator!=(const IndexedName & other) const + bool operator!=(const IndexedName& other) const { return !(this->operator==(other)); } /// Equivalent to C++20's operator <=> - int compare(const IndexedName & other) const + int compare(const IndexedName& other) const { int res = std::strcmp(this->type, other.type); if (res != 0) { @@ -218,7 +222,7 @@ public: /// Provided to enable sorting operations: the comparison is first lexicographical for the text /// element of the names, then numerical for the indices. - bool operator<(const IndexedName & other) const + bool operator<(const IndexedName& other) const { return compare(other) < 0; } @@ -235,25 +239,41 @@ public: } /// Get a pointer to text part of the name - does NOT make a copy, returns direct memory access - const char * getType() const { return this->type; } + const char* getType() const + { + return this->type; + } /// Get the numerical part of the name - int getIndex() const { return this->index; } + int getIndex() const + { + return this->index; + } /// Set the numerical part of the name (note that there is no equivalent function to allow /// changing the text part of the name, which is immutable once created). /// /// \param input The new index. Must be a positive non-zero integer - void setIndex(int input) { assert(input>=0); this->index = input; } + void setIndex(int input) + { + assert(input >= 0); + this->index = input; + } /// A name is considered "null" if its text component is an empty string. // When we support C++20 we can use std::span<> to eliminate the clang-tidy warning // NOLINTNEXTLINE cppcoreguidelines-pro-bounds-pointer-arithmetic - bool isNull() const { return this->type[0] == '\0'; } + bool isNull() const + { + return this->type[0] == '\0'; + } /// Boolean conversion provides the opposite of isNull(), yielding true when the text part of /// the name is NOT the empty string. - explicit operator bool() const { return !isNull(); } + explicit operator bool() const + { + return !isNull(); + } protected: /// Apply the IndexedName rules and either store the characters of a new type or a reference to @@ -268,13 +288,13 @@ protected: /// \param allowOthers If true (the default), then if name is not in allowedNames it is allowed, /// and it is added to internal storage (making a copy of the name if this is its first /// occurrence). - void set(const char *name, + void set(const char* name, int length = -1, - const std::vector & allowedNames = {}, + const std::vector& allowedNames = {}, bool allowOthers = true); private: - const char * type; + const char* type; int index; }; @@ -285,13 +305,13 @@ private: struct ByteArray { explicit ByteArray(QByteArray other) - :bytes(std::move(other)) + : bytes(std::move(other)) {} ByteArray(const ByteArray& other) = default; ByteArray(ByteArray&& other) noexcept - :bytes(std::move(other.bytes)) + : bytes(std::move(other.bytes)) {} ~ByteArray() = default; @@ -304,17 +324,19 @@ struct ByteArray bytes = copy; } - bool operator==(const ByteArray& other) const { + bool operator==(const ByteArray& other) const + { return bytes == other.bytes; } - ByteArray &operator=(const ByteArray & other) { + ByteArray& operator=(const ByteArray& other) + { bytes.clear(); bytes.append(other.bytes.constData(), other.bytes.size()); return *this; } - ByteArray &operator= (ByteArray&& other) noexcept + ByteArray& operator=(ByteArray&& other) noexcept { bytes = std::move(other.bytes); return *this; @@ -337,6 +359,6 @@ struct ByteArrayHasher } }; -} +} // namespace Data -#endif // APP_INDEXEDNAME_H +#endif // APP_INDEXEDNAME_H diff --git a/src/App/InventorObject.cpp b/src/App/InventorObject.cpp index eded2a6f57..255baee052 100644 --- a/src/App/InventorObject.cpp +++ b/src/App/InventorObject.cpp @@ -32,10 +32,10 @@ using namespace App; PROPERTY_SOURCE(App::InventorObject, App::GeoFeature) -InventorObject::InventorObject() +InventorObject::InventorObject() { - ADD_PROPERTY_TYPE(Buffer,(""),"",Prop_None,"String buffer with a scene graph"); - ADD_PROPERTY_TYPE(FileName,(""),"",Prop_None,"Path to an Inventor file"); + ADD_PROPERTY_TYPE(Buffer, (""), "", Prop_None, "String buffer with a scene graph"); + ADD_PROPERTY_TYPE(FileName, (""), "", Prop_None, "Path to an Inventor file"); } InventorObject::~InventorObject() = default; @@ -45,11 +45,11 @@ short InventorObject::mustExecute() const return 0; } -PyObject *InventorObject::getPyObject() +PyObject* InventorObject::getPyObject() { - if (PythonObject.is(Py::_None())){ + if (PythonObject.is(Py::_None())) { // ref counter is set to 1 - PythonObject = Py::Object(new DocumentObjectPy(this),true); + PythonObject = Py::Object(new DocumentObjectPy(this), true); } - return Py::new_reference_to(PythonObject); + return Py::new_reference_to(PythonObject); } diff --git a/src/App/InventorObject.h b/src/App/InventorObject.h index af0c9825ac..3fe6d7d770 100644 --- a/src/App/InventorObject.h +++ b/src/App/InventorObject.h @@ -31,7 +31,7 @@ namespace App { -class AppExport InventorObject : public GeoFeature +class AppExport InventorObject: public GeoFeature { PROPERTY_HEADER_WITH_OVERRIDE(App::InventorObject); @@ -41,20 +41,22 @@ public: ~InventorObject() override; /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderInventorObject"; } - DocumentObjectExecReturn *execute() override { + DocumentObjectExecReturn* execute() override + { return DocumentObject::StdReturn; } short mustExecute() const override; - PyObject *getPyObject() override; + PyObject* getPyObject() override; PropertyString Buffer; PropertyString FileName; }; -} //namespace App +} // namespace App -#endif // APP_INVENTOROBJECT_H +#endif // APP_INVENTOROBJECT_H diff --git a/src/App/License.h b/src/App/License.h index b16c2b7252..a07e72274d 100644 --- a/src/App/License.h +++ b/src/App/License.h @@ -75,6 +75,6 @@ int constexpr findLicense(const char* identifier) } return -1; } -}// namespace App +} // namespace App -#endif// APP_LICENSE_H +#endif // APP_LICENSE_H diff --git a/src/App/MappedElement.cpp b/src/App/MappedElement.cpp index 137c0e8883..7b69e35c70 100644 --- a/src/App/MappedElement.cpp +++ b/src/App/MappedElement.cpp @@ -24,8 +24,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif #include "DocumentObject.h" @@ -164,9 +164,12 @@ bool ElementNameComparator::operator()(const MappedName& leftName, return leftName.size() < rightName.size(); } -HistoryItem::HistoryItem(App::DocumentObject *obj, const Data::MappedName &name) - :obj(obj),tag(0),element(name) +HistoryItem::HistoryItem(App::DocumentObject* obj, const Data::MappedName& name) + : obj(obj) + , tag(0) + , element(name) { - if(obj) + if (obj) { tag = obj->getID(); + } } diff --git a/src/App/MappedElement.h b/src/App/MappedElement.h index 8c49016686..4880354592 100644 --- a/src/App/MappedElement.h +++ b/src/App/MappedElement.h @@ -46,13 +46,13 @@ struct AppExport MappedElement MappedElement() = default; MappedElement(const IndexedName& idx, MappedName n) - : index(idx), - name(std::move(n)) + : index(idx) + , name(std::move(n)) {} MappedElement(MappedName n, const IndexedName& idx) - : index(idx), - name(std::move(n)) + : index(idx) + , name(std::move(n)) {} ~MappedElement() = default; @@ -60,8 +60,8 @@ struct AppExport MappedElement MappedElement(const MappedElement& other) = default; MappedElement(MappedElement&& other) noexcept - : index(other.index), - name(std::move(other.name)) + : index(other.index) + , name(std::move(other.name)) {} MappedElement& operator=(MappedElement&& other) noexcept @@ -99,16 +99,18 @@ struct AppExport MappedElement } }; -struct AppExport HistoryItem { - App::DocumentObject *obj; +struct AppExport HistoryItem +{ + App::DocumentObject* obj; long tag; Data::MappedName element; Data::IndexedName index; std::vector intermediates; - HistoryItem(App::DocumentObject *obj, const Data::MappedName &name); + HistoryItem(App::DocumentObject* obj, const Data::MappedName& name); }; -struct AppExport ElementNameComparator { +struct AppExport ElementNameComparator +{ /** Comparison function to make topo name more stable * * The sorting decomposes the name into either of the following two forms @@ -121,10 +123,10 @@ struct AppExport ElementNameComparator { * The reason for this is to prevent names with bigger digits (which usually means * they come later in history) from coming earlier when sorting. */ - bool operator()(const MappedName & leftName, const MappedName & rightName) const; + bool operator()(const MappedName& leftName, const MappedName& rightName) const; }; -}// namespace Data +} // namespace Data -#endif// APP_MAPPED_ELEMENT_H +#endif // APP_MAPPED_ELEMENT_H diff --git a/src/App/MappedName.cpp b/src/App/MappedName.cpp index 968bfd4850..2f00e75335 100644 --- a/src/App/MappedName.cpp +++ b/src/App/MappedName.cpp @@ -23,7 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include "MappedName.h" @@ -34,13 +34,15 @@ #include -FC_LOG_LEVEL_INIT("MappedName", true, 2);// NOLINT +FC_LOG_LEVEL_INIT("MappedName", true, 2); // NOLINT -namespace Data { +namespace Data +{ void MappedName::compact() const { - auto self = const_cast(this); //FIXME this is a workaround for a single call in ElementMap::addName() + auto self = const_cast( + this); // FIXME this is a workaround for a single call in ElementMap::addName() if (this->raw) { self->data = QByteArray(self->data.constData(), self->data.size()); @@ -49,8 +51,12 @@ void MappedName::compact() const } -int MappedName::findTagInElementName(long* tagOut, int* lenOut, std::string* postfixOut, - char* typeOut, bool negative, bool recursive) const +int MappedName::findTagInElementName(long* tagOut, + int* lenOut, + std::string* postfixOut, + char* typeOut, + bool negative, + bool recursive) const { bool hex = true; int pos = this->rfind(POSTFIX_TAG); @@ -61,7 +67,7 @@ int MappedName::findTagInElementName(long* tagOut, int* lenOut, std::string* pos // | // pos - if(pos < 0) { + if (pos < 0) { pos = this->rfind(POSTFIX_DECIMAL_TAG); if (pos < 0) { return -1; @@ -77,7 +83,7 @@ int MappedName::findTagInElementName(long* tagOut, int* lenOut, std::string* pos char eof = 0; int size {0}; - const char * nameAsChars = this->toConstString(offset, size); + const char* nameAsChars = this->toConstString(offset, size); // check if the number followed by the tagPosfix is negative bool isNegative = (nameAsChars[0] == '-'); @@ -89,7 +95,8 @@ int MappedName::findTagInElementName(long* tagOut, int* lenOut, std::string* pos if (!hex) { // no hex is an older version of the encoding scheme iss >> _tag >> sep; - } else { + } + else { // The purpose of tagOut postfixOut is to encode one model operation. The // 'tagOut' field is used to record the own object ID of that model shape, // and the 'lenOut' field indicates the length of the operation codes @@ -148,13 +155,13 @@ int MappedName::findTagInElementName(long* tagOut, int* lenOut, std::string* pos } if (hex) { - if (pos-_len < 0) { + if (pos - _len < 0) { return -1; } if ((_len != 0) && recursive && (tagOut || lenOut)) { // in case of recursive tagOut postfixOut (used by hierarchy element // map), look for any embedded tagOut postfixOut - int next = MappedName::fromRawData(*this, pos-_len, _len).rfind(POSTFIX_TAG); + int next = MappedName::fromRawData(*this, pos - _len, _len).rfind(POSTFIX_TAG); if (next >= 0) { next += pos - _len; // #94;:G0;XTR;:H19:8,F;:H1a,F;BND:-1:0;:H1b:10,F @@ -174,7 +181,7 @@ int MappedName::findTagInElementName(long* tagOut, int* lenOut, std::string* pos .find(ELEMENT_MAP_PREFIX); } if (end >= 0) { - end += next+1; + end += next + 1; // #94;:G0;XTR;:H19:8,F;:H1a,F;BND:-1:0;:H1b:10,F // ^ // | @@ -183,7 +190,8 @@ int MappedName::findTagInElementName(long* tagOut, int* lenOut, std::string* pos // #94;:G0;XTR;:H19:8,F;:H1a,F;BND:-1:0;:H1b:10,F // | | // -- lenOut -- - } else { + } + else { _len = 0; } } @@ -196,28 +204,28 @@ int MappedName::findTagInElementName(long* tagOut, int* lenOut, std::string* pos // ----------- lenOut ----------- _len = pos - _len; } - if(typeOut) { + if (typeOut) { *typeOut = tp; } - if(tagOut) { + if (tagOut) { if (_tag == 0 && recursive) { return MappedName(*this, 0, _len) .findTagInElementName(tagOut, lenOut, postfixOut, typeOut, negative); } - if(_tag>0 || negative) { + if (_tag > 0 || negative) { *tagOut = _tag; } else { *tagOut = -_tag; } } - if(lenOut) { + if (lenOut) { *lenOut = _len; } - if(postfixOut) { + if (postfixOut) { *postfixOut = this->toString(pos); } return pos; } -} +} // namespace Data diff --git a/src/App/MappedName.h b/src/App/MappedName.h index 93c79682b6..b7df053cc4 100644 --- a/src/App/MappedName.h +++ b/src/App/MappedName.h @@ -415,7 +415,7 @@ public: } - if (startPosition < other.data.size())// if starting inside data + if (startPosition < other.data.size()) // if starting inside data { int count = size; // make sure count doesn't exceed data size and end up in postfix @@ -436,7 +436,7 @@ public: startPosition = 0; size -= count; } - else// else starting inside postfix + else // else starting inside postfix { startPosition -= other.data.size(); } @@ -879,7 +879,8 @@ public: return false; } return startsWith( - QByteArray::fromRawData(searchTarget, static_cast(qstrlen(searchTarget))), offset); + QByteArray::fromRawData(searchTarget, static_cast(qstrlen(searchTarget))), + offset); } /// Returns true if this MappedName starts with the search target. If there is a postfix, only @@ -902,15 +903,18 @@ public: /// \param lenOut: optional pointer to receive the length field after the tagOut field. /// This gives the length of the previous hashed element name starting /// from the beginning of the give element name. - /// \param postfixOut: optional pointer to receive the postfixOut starting at the found tagOut field. - /// \param typeOut: optional pointer to receive the element typeOut character - /// \param negative: return negative tagOut as it is. If disabled, then always return positive tagOut. + /// \param postfixOut: optional pointer to receive the postfixOut starting at the found tagOut + /// field. \param typeOut: optional pointer to receive the element typeOut character \param + /// negative: return negative tagOut as it is. If disabled, then always return positive tagOut. /// Negative tagOut is sometimes used for element disambiguation. /// \param recursive: recursively find the last non-zero tagOut /// /// \return Return the end position of the tagOut field, or return -1 if not found. - int findTagInElementName(long* tagOut = nullptr, int* lenOut = nullptr, std::string* postfixOut = nullptr, - char* typeOut = nullptr, bool negative = false, + int findTagInElementName(long* tagOut = nullptr, + int* lenOut = nullptr, + std::string* postfixOut = nullptr, + char* typeOut = nullptr, + bool negative = false, bool recursive = true) const; /// Get a hash for this MappedName @@ -1043,7 +1047,7 @@ struct MappedNameRef // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) -}// namespace Data +} // namespace Data -#endif// APP_MAPPED_NAME_H +#endif // APP_MAPPED_NAME_H diff --git a/src/App/MaterialObject.cpp b/src/App/MaterialObject.cpp index 60c4f2ee1e..da866b7835 100644 --- a/src/App/MaterialObject.cpp +++ b/src/App/MaterialObject.cpp @@ -33,20 +33,22 @@ PROPERTY_SOURCE(App::MaterialObject, App::DocumentObject) MaterialObject::MaterialObject() { - ADD_PROPERTY_TYPE(Material,(),"Material",Prop_None,"Material key/value map"); - + ADD_PROPERTY_TYPE(Material, (), "Material", Prop_None, "Material key/value map"); } // Python feature --------------------------------------------------------- -namespace App { +namespace App +{ /// @cond DOXERR PROPERTY_SOURCE_TEMPLATE(App::MaterialObjectPython, App::MaterialObject) -template<> const char* App::MaterialObjectPython::getViewProviderName() const { +template<> +const char* App::MaterialObjectPython::getViewProviderName() const +{ return "Gui::ViewProviderMaterialObjectPython"; } /// @endcond // explicit template instantiation template class AppExport FeaturePythonT; -} +} // namespace App diff --git a/src/App/MaterialObject.h b/src/App/MaterialObject.h index 177a35764e..ad0fed4c06 100644 --- a/src/App/MaterialObject.h +++ b/src/App/MaterialObject.h @@ -31,7 +31,7 @@ namespace App { -class AppExport MaterialObject : public DocumentObject +class AppExport MaterialObject: public DocumentObject { PROPERTY_HEADER_WITH_OVERRIDE(App::MaterialObject); @@ -43,16 +43,16 @@ public: /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderMaterialObject"; } - }; using MaterialObjectPython = App::FeaturePythonT; -} //namespace App +} // namespace App -#endif // APP_MaterialObject_H +#endif // APP_MaterialObject_H diff --git a/src/App/MeasureManager.cpp b/src/App/MeasureManager.cpp index 825cbc63a9..d6b4c07a81 100644 --- a/src/App/MeasureManager.cpp +++ b/src/App/MeasureManager.cpp @@ -28,179 +28,208 @@ #include "MeasureManager.h" -namespace App { +namespace App +{ - std::vector MeasureManager::_mMeasureHandlers; - std::vector MeasureManager::_mMeasureTypes; +std::vector MeasureManager::_mMeasureHandlers; +std::vector MeasureManager::_mMeasureTypes; - MeasureManager::MeasureManager() - { - // Constructor implementation +MeasureManager::MeasureManager() +{ + // Constructor implementation +} + + +void MeasureManager::addMeasureHandler(const char* module, MeasureTypeMethod typeCb) +{ + _mMeasureHandlers.emplace_back(MeasureHandler {module, typeCb}); +} + +bool MeasureManager::hasMeasureHandler(const char* module) +{ + for (MeasureHandler& handler : _mMeasureHandlers) { + if (strcmp(handler.module.c_str(), module) == 0) { + return true; + } + } + return false; +} + +MeasureHandler MeasureManager::getMeasureHandler(const char* module) +{ + for (MeasureHandler handler : _mMeasureHandlers) { + if (!strcmp(handler.module.c_str(), module)) { + return handler; + } } + MeasureHandler empty; + return empty; +} - void MeasureManager::addMeasureHandler(const char* module, MeasureTypeMethod typeCb) { - _mMeasureHandlers.emplace_back(MeasureHandler{module, typeCb}); +MeasureHandler MeasureManager::getMeasureHandler(const App::MeasureSelectionItem& selectionItem) +{ + auto objT = selectionItem.object; + + // Resolve App::Link + App::DocumentObject* sub = objT.getSubObject(); + if (sub->isDerivedFrom()) { + auto link = static_cast(sub); + sub = link->getLinkedObject(true); } - bool MeasureManager::hasMeasureHandler(const char* module) { - for(MeasureHandler& handler : _mMeasureHandlers) { - if (strcmp(handler.module.c_str(), module) == 0) { - return true; + const char* className = sub->getTypeId().getName(); + std::string mod = Base::Type::getModuleName(className); + + return getMeasureHandler(mod.c_str()); +} + +MeasureElementType +MeasureManager::getMeasureElementType(const App::MeasureSelectionItem& selectionItem) +{ + auto handler = getMeasureHandler(selectionItem); + if (handler.module.empty()) { + return App::MeasureElementType::INVALID; + } + + auto objT = selectionItem.object; + return handler.typeCb(objT.getObject(), objT.getSubName().c_str()); +} + +void MeasureManager::addMeasureType(MeasureType* measureType) +{ + _mMeasureTypes.push_back(measureType); +} + +void MeasureManager::addMeasureType(std::string id, + std::string label, + std::string measureObj, + MeasureValidateMethod validatorCb, + MeasurePrioritizeMethod prioritizeCb) +{ + MeasureType* mType = + new MeasureType {id, label, measureObj, validatorCb, prioritizeCb, false, nullptr}; + _mMeasureTypes.push_back(mType); +} + +void MeasureManager::addMeasureType(const char* id, + const char* label, + const char* measureObj, + MeasureValidateMethod validatorCb, + MeasurePrioritizeMethod prioritizeCb) +{ + addMeasureType(std::string(id), + std::string(label), + std::string(measureObj), + validatorCb, + prioritizeCb); +} + +const std::vector MeasureManager::getMeasureTypes() +{ + return _mMeasureTypes; +} + + +Py::Tuple MeasureManager::getSelectionPy(const App::MeasureSelection& selection) +{ + // Convert selection to python list + Py::Tuple selectionPy(selection.size()); + + int i = 0; + for (auto it : selection) { + + Py::Dict sel; + sel.setItem("object", Py::asObject(it.object.getObject()->getPyObject())); + sel.setItem("subName", Py::String(it.object.getSubName())); + sel.setItem("pickedPoint", Py::asObject(new Base::VectorPy(it.pickedPoint))); + + selectionPy.setItem(i, sel); + + i++; + } + return selectionPy; +} + + +std::vector MeasureManager::getValidMeasureTypes(App::MeasureSelection selection, + std::string mode) +{ + Base::PyGILStateLocker lock; + + // Convert selection to python list + Py::Tuple selectionPy = getSelectionPy(selection); + + // Store valid measure types + std::vector validTypes; + std::pair(); + + + // Loop through measure types and check if they work with given selection + for (App::MeasureType* mType : getMeasureTypes()) { + + if (mode != "" && mType->label != mode) { + continue; + } + + + if (mType->isPython) { + // Parse Python measure types + auto measurePyClass = Py::Object(mType->pythonClass); + + Py::Tuple args(1); + args.setItem(0, selectionPy); + + Py::Object isValid; + try { + isValid = measurePyClass.callMemberFunction(std::string("isValidSelection"), args); + } + catch (const Py::Exception&) { + Base::PyException e; + e.ReportException(); + isValid = Py::False(); + } + + if (isValid.as_bool()) { + + // Check priority + Py::Object isPriority; + try { + isPriority = measurePyClass.callMemberFunction("isPrioritySelection", args); + } + catch (const Py::Exception&) { + Base::PyException e; + e.ReportException(); + isPriority = Py::False(); + } + + if (isPriority.as_bool()) { + validTypes.insert(validTypes.begin(), mType); + } + else { + validTypes.push_back(mType); + } } } - return false; - } + else { + // Parse c++ measure types - MeasureHandler MeasureManager::getMeasureHandler(const char* module) { - for(MeasureHandler handler : _mMeasureHandlers) { - if (!strcmp(handler.module.c_str(), module)) { - return handler; - } - } - - MeasureHandler empty; - return empty; - } - - MeasureHandler MeasureManager::getMeasureHandler(const App::MeasureSelectionItem& selectionItem) { - auto objT = selectionItem.object; - - // Resolve App::Link - App::DocumentObject* sub = objT.getSubObject(); - if (sub->isDerivedFrom()) { - auto link = static_cast(sub); - sub = link->getLinkedObject(true); - } - - const char* className = sub->getTypeId().getName(); - std::string mod = Base::Type::getModuleName(className); - - return getMeasureHandler(mod.c_str()); - } - - MeasureElementType MeasureManager::getMeasureElementType(const App::MeasureSelectionItem& selectionItem) { - auto handler = getMeasureHandler(selectionItem); - if (handler.module.empty()) { - return App::MeasureElementType::INVALID; - } - - auto objT = selectionItem.object; - return handler.typeCb(objT.getObject(), objT.getSubName().c_str()); - } - - void MeasureManager::addMeasureType(MeasureType* measureType) { - _mMeasureTypes.push_back(measureType); - } - - void MeasureManager::addMeasureType(std::string id, std::string label, std::string measureObj, MeasureValidateMethod validatorCb, MeasurePrioritizeMethod prioritizeCb) { - MeasureType* mType = new MeasureType{id, label, measureObj, validatorCb, prioritizeCb, false, nullptr}; - _mMeasureTypes.push_back(mType); - } - - void MeasureManager::addMeasureType(const char* id, const char* label, const char* measureObj, MeasureValidateMethod validatorCb, MeasurePrioritizeMethod prioritizeCb) { - addMeasureType(std::string(id), std::string(label), std::string(measureObj), validatorCb, prioritizeCb); - } - - const std::vector MeasureManager::getMeasureTypes() { - return _mMeasureTypes; - } - - - Py::Tuple MeasureManager::getSelectionPy(const App::MeasureSelection& selection) { - // Convert selection to python list - Py::Tuple selectionPy(selection.size()); - - int i = 0; - for (auto it : selection) { - - Py::Dict sel; - sel.setItem("object", Py::asObject(it.object.getObject()->getPyObject())); - sel.setItem("subName", Py::String(it.object.getSubName())); - sel.setItem("pickedPoint", Py::asObject(new Base::VectorPy(it.pickedPoint))); - - selectionPy.setItem(i, sel); - - i++; - } - return selectionPy; - } - - - std::vector MeasureManager::getValidMeasureTypes(App::MeasureSelection selection, std::string mode) { - Base::PyGILStateLocker lock; - - // Convert selection to python list - Py::Tuple selectionPy = getSelectionPy(selection); - - // Store valid measure types - std::vector validTypes; - std::pair(); - - - // Loop through measure types and check if they work with given selection - for (App::MeasureType* mType : getMeasureTypes()){ - - if (mode != "" && mType->label != mode) { + if (mType->validatorCb && !mType->validatorCb(selection)) { continue; } - - if (mType->isPython) { - // Parse Python measure types - auto measurePyClass = Py::Object(mType->pythonClass); - - Py::Tuple args(1); - args.setItem(0, selectionPy); - - Py::Object isValid; - try { - isValid = measurePyClass.callMemberFunction(std::string("isValidSelection"), args); - } catch (const Py::Exception&) { - Base::PyException e; - e.ReportException(); - isValid = Py::False(); - } - - if (isValid.as_bool()) { - - // Check priority - Py::Object isPriority; - try { - isPriority = measurePyClass.callMemberFunction("isPrioritySelection", args); - } catch (const Py::Exception&) { - Base::PyException e; - e.ReportException(); - isPriority = Py::False(); - } - - if (isPriority.as_bool()) { - validTypes.insert(validTypes.begin(), mType); - } else { - validTypes.push_back(mType); - } - } - } else { - // Parse c++ measure types - - if (mType->validatorCb && !mType->validatorCb(selection)) { - continue; - } - - // Check if the measurement type prioritizes the given selection - if (mType->prioritizeCb && mType->prioritizeCb(selection)) { - validTypes.insert(validTypes.begin(), mType); - } else { - validTypes.push_back(mType); - } - + // Check if the measurement type prioritizes the given selection + if (mType->prioritizeCb && mType->prioritizeCb(selection)) { + validTypes.insert(validTypes.begin(), mType); + } + else { + validTypes.push_back(mType); } } - - return validTypes; } + return validTypes; +} - -} // namespace App +} // namespace App diff --git a/src/App/MeasureManager.h b/src/App/MeasureManager.h index 303bdd1390..66379c21a4 100644 --- a/src/App/MeasureManager.h +++ b/src/App/MeasureManager.h @@ -36,24 +36,27 @@ #include -namespace App { +namespace App +{ // Add your class methods and member variables here -enum class MeasureElementType { +enum class MeasureElementType +{ INVALID, POINT, LINE, LINESEGMENT, CIRCLE, ARC, - CURVE, // Has a length but no radius or axis + CURVE, // Has a length but no radius or axis PLANE, CYLINDER, Volume, }; -struct MeasureSelectionItem { +struct MeasureSelectionItem +{ App::SubObjectT object; Base::Vector3d pickedPoint; }; @@ -62,9 +65,10 @@ struct MeasureSelectionItem { using MeasureSelection = std::vector; using MeasureValidateMethod = std::function; using MeasurePrioritizeMethod = std::function; -using MeasureTypeMethod = std::function; +using MeasureTypeMethod = std::function; -struct MeasureType { +struct MeasureType +{ std::string identifier; std::string label; std::string measureObject; @@ -72,21 +76,24 @@ struct MeasureType { // Checks if the measurement works with a given selection MeasureValidateMethod validatorCb; - // Allows to prioritize this over other measurement types when the measurement type is picked implicitly from the selection. - // Gets called only when validatorCb returned true for the given selection + // Allows to prioritize this over other measurement types when the measurement type is picked + // implicitly from the selection. Gets called only when validatorCb returned true for the given + // selection MeasurePrioritizeMethod prioritizeCb; bool isPython; PyObject* pythonClass; }; -struct MeasureHandler { +struct MeasureHandler +{ std::string module; MeasureTypeMethod typeCb; }; -class AppExport MeasureManager { +class AppExport MeasureManager +{ public: MeasureManager(); @@ -96,11 +103,20 @@ public: static MeasureHandler getMeasureHandler(const App::MeasureSelectionItem& selectionItem); static MeasureElementType getMeasureElementType(const App::MeasureSelectionItem& selectionItem); static void addMeasureType(MeasureType* measureType); - static void addMeasureType(std::string id, std::string label, std::string measureObj, MeasureValidateMethod validatorCb, MeasurePrioritizeMethod prioritizeCb); - static void addMeasureType(const char* id, const char* label, const char* measureObj, MeasureValidateMethod validatorCb, MeasurePrioritizeMethod prioritizeCb); + static void addMeasureType(std::string id, + std::string label, + std::string measureObj, + MeasureValidateMethod validatorCb, + MeasurePrioritizeMethod prioritizeCb); + static void addMeasureType(const char* id, + const char* label, + const char* measureObj, + MeasureValidateMethod validatorCb, + MeasurePrioritizeMethod prioritizeCb); static const std::vector getMeasureTypes(); static Py::Tuple getSelectionPy(const App::MeasureSelection& selection); - static std::vector getValidMeasureTypes(App::MeasureSelection selection, std::string mode); + static std::vector getValidMeasureTypes(App::MeasureSelection selection, + std::string mode); private: @@ -109,6 +125,6 @@ private: }; -} // namespace App +} // namespace App -#endif // MEASUREMANAGER_H +#endif // MEASUREMANAGER_H diff --git a/src/App/MeasureManagerPyImp.cpp b/src/App/MeasureManagerPyImp.cpp index be7854b98e..bcb5d08a65 100644 --- a/src/App/MeasureManagerPyImp.cpp +++ b/src/App/MeasureManagerPyImp.cpp @@ -47,17 +47,17 @@ int MeasureManagerPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj* } -PyObject* MeasureManagerPy::addMeasureType(PyObject *args) +PyObject* MeasureManagerPy::addMeasureType(PyObject* args) { - PyObject *pyobj = Py_None; + PyObject* pyobj = Py_None; char *id, *label; - if (!PyArg_ParseTuple(args, "ssO", &id, &label, &pyobj)) + if (!PyArg_ParseTuple(args, "ssO", &id, &label, &pyobj)) { return nullptr; + } MeasureManager::addMeasureType( - new App::MeasureType{id, label, "", nullptr, nullptr, true, pyobj} - ); + new App::MeasureType {id, label, "", nullptr, nullptr, true, pyobj}); Py_Return; } @@ -66,7 +66,7 @@ PyObject* MeasureManagerPy::addMeasureType(PyObject *args) PyObject* MeasureManagerPy::getMeasureTypes() { Py::List types; - for (auto & it : MeasureManager::getMeasureTypes()) { + for (auto& it : MeasureManager::getMeasureTypes()) { Py::Tuple type(3); type.setItem(0, Py::String(it->identifier)); type.setItem(1, Py::String(it->label)); diff --git a/src/App/MergeDocuments.cpp b/src/App/MergeDocuments.cpp index 10453b163f..fafcab3cc6 100644 --- a/src/App/MergeDocuments.cpp +++ b/src/App/MergeDocuments.cpp @@ -22,7 +22,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include @@ -36,13 +36,17 @@ using namespace App; namespace sp = std::placeholders; -namespace App { +namespace App +{ -class XMLMergeReader : public Base::XMLReader +class XMLMergeReader: public Base::XMLReader { public: - XMLMergeReader(std::map& name, const char* FileName, std::istream& str) - : Base::XMLReader(FileName, str), nameMap(name) + XMLMergeReader(std::map& name, + const char* FileName, + std::istream& str) + : Base::XMLReader(FileName, str) + , nameMap(name) {} void addName(const char* s1, const char* s2) override @@ -52,34 +56,35 @@ public: const char* getName(const char* name) const override { std::map::const_iterator it = nameMap.find(name); - if (it != nameMap.end()) + if (it != nameMap.end()) { return it->second.c_str(); - else + } + else { return name; + } } bool doNameMapping() const override { return true; } + protected: - - private: std::map& nameMap; using PropertyTag = std::pair; std::stack propertyStack; }; -} +} // namespace App MergeDocuments::MergeDocuments(App::Document* doc) : appdoc(doc) { - //NOLINTBEGIN - connectExport = doc->signalExportObjects.connect - (std::bind(&MergeDocuments::exportObject, this, sp::_1, sp::_2)); - connectImport = doc->signalImportObjects.connect - (std::bind(&MergeDocuments::importObject, this, sp::_1, sp::_2)); - //NOLINTEND + // NOLINTBEGIN + connectExport = doc->signalExportObjects.connect( + std::bind(&MergeDocuments::exportObject, this, sp::_1, sp::_2)); + connectImport = doc->signalImportObjects.connect( + std::bind(&MergeDocuments::importObject, this, sp::_1, sp::_2)); + // NOLINTEND QCoreApplication* app = QCoreApplication::instance(); if (app && app->inherits("QApplication")) { @@ -93,17 +98,16 @@ MergeDocuments::~MergeDocuments() connectImport.disconnect(); } -unsigned int MergeDocuments::getMemSize () const +unsigned int MergeDocuments::getMemSize() const { return 0; } -std::vector -MergeDocuments::importObjects(std::istream& input) +std::vector MergeDocuments::importObjects(std::istream& input) { this->nameMap.clear(); this->stream = new zipios::ZipInputStream(input); - XMLMergeReader reader(this->nameMap,"", *stream); + XMLMergeReader reader(this->nameMap, "", *stream); reader.setVerbose(isVerbose()); std::vector objs = appdoc->importObjects(reader); @@ -113,20 +117,20 @@ MergeDocuments::importObjects(std::istream& input) return objs; } -void MergeDocuments::importObject(const std::vector& o, Base::XMLReader & r) +void MergeDocuments::importObject(const std::vector& o, Base::XMLReader& r) { objects = o; Restore(r); r.readFiles(*this->stream); } -void MergeDocuments::exportObject(const std::vector& o, Base::Writer & w) +void MergeDocuments::exportObject(const std::vector& o, Base::Writer& w) { objects = o; Save(w); } -void MergeDocuments::Save (Base::Writer & w) const +void MergeDocuments::Save(Base::Writer& w) const { // Save view provider stuff if (guiup) { @@ -134,7 +138,7 @@ void MergeDocuments::Save (Base::Writer & w) const } } -void MergeDocuments::Restore(Base::XMLReader &r) +void MergeDocuments::Restore(Base::XMLReader& r) { // Restore view provider stuff if (guiup) { @@ -142,13 +146,13 @@ void MergeDocuments::Restore(Base::XMLReader &r) } } -void MergeDocuments::SaveDocFile (Base::Writer & w) const +void MergeDocuments::SaveDocFile(Base::Writer& w) const { // Save view provider stuff appdoc->signalExportViewObjects(this->objects, w); } -void MergeDocuments::RestoreDocFile(Base::Reader & r) +void MergeDocuments::RestoreDocFile(Base::Reader& r) { // Restore view provider stuff appdoc->signalImportViewObjects(this->objects, r, this->nameMap); diff --git a/src/App/MergeDocuments.h b/src/App/MergeDocuments.h index f1cd31ec97..faab10179a 100644 --- a/src/App/MergeDocuments.h +++ b/src/App/MergeDocuments.h @@ -27,36 +27,47 @@ #include #include -namespace zipios { +namespace zipios +{ class ZipInputStream; } -namespace App { +namespace App +{ class Document; class DocumentObject; -class AppExport MergeDocuments : public Base::Persistence +class AppExport MergeDocuments: public Base::Persistence { public: explicit MergeDocuments(App::Document* doc); ~MergeDocuments() override; - bool isVerbose() const { return verbose; } - void setVerbose(bool on) { verbose = on; } - unsigned int getMemSize () const override; + bool isVerbose() const + { + return verbose; + } + void setVerbose(bool on) + { + verbose = on; + } + unsigned int getMemSize() const override; std::vector importObjects(std::istream&); - void importObject(const std::vector& o, Base::XMLReader & r); - void exportObject(const std::vector& o, Base::Writer & w); - void Save (Base::Writer & w) const override; - void Restore(Base::XMLReader &r) override; - void SaveDocFile (Base::Writer & w) const override; - void RestoreDocFile(Base::Reader & r) override; + void importObject(const std::vector& o, Base::XMLReader& r); + void exportObject(const std::vector& o, Base::Writer& w); + void Save(Base::Writer& w) const override; + void Restore(Base::XMLReader& r) override; + void SaveDocFile(Base::Writer& w) const override; + void RestoreDocFile(Base::Reader& r) override; - const std::map &getNameMap() const {return nameMap;} + const std::map& getNameMap() const + { + return nameMap; + } private: - bool guiup{false}; - bool verbose{true}; - zipios::ZipInputStream* stream{nullptr}; - App::Document* appdoc{nullptr}; + bool guiup {false}; + bool verbose {true}; + zipios::ZipInputStream* stream {nullptr}; + App::Document* appdoc {nullptr}; std::vector objects; std::map nameMap; using Connection = boost::signals2::connection; @@ -64,6 +75,6 @@ private: Connection connectImport; }; -} // namespace App +} // namespace App -#endif // APP_MERGEDOCUMENTS_H +#endif // APP_MERGEDOCUMENTS_H diff --git a/src/App/Metadata.cpp b/src/App/Metadata.cpp index 1a70438e23..4e9df6f5fe 100644 --- a/src/App/Metadata.cpp +++ b/src/App/Metadata.cpp @@ -1,31 +1,31 @@ /************************************************************************** -* * -* Copyright (c) 2021-2023 FreeCAD Project Association * -* * -* This file is part of FreeCAD. * -* * -* FreeCAD is free software: you can redistribute it and/or modify it * -* under the terms of the GNU Lesser General Public License as * -* published by the Free Software Foundation, either version 2.1 of the * -* License, or (at your option) any later version. * -* * -* FreeCAD is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * -* Lesser General Public License for more details. * -* * -* You should have received a copy of the GNU Lesser General Public * -* License along with FreeCAD. If not, see * -* . * -* * -***************************************************************************/ + * * + * Copyright (c) 2021-2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include +#include +#include +#include #endif #include @@ -93,7 +93,7 @@ class XMLErrorHandler: public HandlerBase throw Base::XMLBaseException(message.str()); } }; -}// namespace MetadataInternal +} // namespace MetadataInternal Metadata::Metadata(const fs::path& metadataFile) : _dom(nullptr) @@ -130,10 +130,9 @@ Metadata::Metadata(const DOMNode* domNode, int format) App::Metadata::Metadata(const std::string& rawData) : _dom(nullptr) { - MemBufInputSource buffer( - reinterpret_cast(rawData.c_str()), - rawData.size(), - "raw data (in memory)"); + MemBufInputSource buffer(reinterpret_cast(rawData.c_str()), + rawData.size(), + "raw data (in memory)"); loadFromInputSource(buffer); } @@ -294,7 +293,7 @@ XERCES_CPP_NAMESPACE::DOMElement* Metadata::dom() const void Metadata::setName(const std::string& name) { - std::string invalidCharacters = "/\\?%*:|\"<>";// Should cover all OSes + std::string invalidCharacters = "/\\?%*:|\"<>"; // Should cover all OSes if (_name.find_first_of(invalidCharacters) != std::string::npos) { throw Base::RuntimeError("Name cannot contain any of: " + invalidCharacters); } @@ -534,7 +533,8 @@ void Metadata::clearFile() } -DOMElement* appendSimpleXMLNode(DOMElement* baseNode, const std::string& nodeName, +DOMElement* appendSimpleXMLNode(DOMElement* baseNode, + const std::string& nodeName, const std::string& nodeContents) { // For convenience (and brevity of final output) don't create nodes that don't have contents @@ -665,8 +665,9 @@ bool Metadata::satisfies(const Meta::Dependency& dep) if (dep.package != _name) { return false; } - // The "condition" attribute allows an expression to enable or disable this dependency check: it must contain a valid - // FreeCAD Expression. If it evaluates to false, this dependency is bypassed (e.g. this function returns false). + // The "condition" attribute allows an expression to enable or disable this dependency check: it + // must contain a valid FreeCAD Expression. If it evaluates to false, this dependency is + // bypassed (e.g. this function returns false). if (!dep.condition.empty()) { auto injectedString = dep.condition; std::map replacements; @@ -938,11 +939,11 @@ void Metadata::parseVersion1(const DOMNode* startNode) _icon = fs::path(StrXUTF8(element->getTextContent()).str); } else if (tagString == "content") { - parseContentNodeVersion1(element);// Recursive call + parseContentNodeVersion1(element); // Recursive call } else { - // If none of this node's nodeChildren have nodeChildren of their own, it is a simple element and we - // can handle it as a GenericMetadata object + // If none of this node's nodeChildren have nodeChildren of their own, it is a simple + // element and we can handle it as a GenericMetadata object auto nodeChildren = element->getChildNodes(); bool hasGrandchildren = false; for (XMLSize_t j = 0; j < nodeChildren->getLength() && !hasGrandchildren; ++j) { @@ -970,15 +971,15 @@ void Metadata::parseContentNodeVersion1(const DOMElement* contentNode) } Meta::Contact::Contact(std::string name, std::string email) - : name(std::move(name)), - email(std::move(email)) + : name(std::move(name)) + , email(std::move(email)) { // This has to be provided manually since we have another constructor } Meta::Contact::Contact(const XERCES_CPP_NAMESPACE::DOMElement* elem) { - if (!elem){ + if (!elem) { return; } auto emailAttribute = elem->getAttribute(XUTF8Str("email").unicodeForm()); @@ -992,15 +993,15 @@ bool App::Meta::Contact::operator==(const Contact& rhs) const } Meta::License::License(std::string name, fs::path file) - : name(std::move(name)), - file(std::move(file)) + : name(std::move(name)) + , file(std::move(file)) { // This has to be provided manually since we have another constructor } Meta::License::License(const XERCES_CPP_NAMESPACE::DOMElement* elem) { - if (!elem){ + if (!elem) { return; } auto fileAttribute = elem->getAttribute(XUTF8Str("file").unicodeForm()); @@ -1016,13 +1017,13 @@ bool App::Meta::License::operator==(const License& rhs) const } App::Meta::Url::Url() - : location(""), - type(App::Meta::UrlType::website) + : location("") + , type(App::Meta::UrlType::website) {} Meta::Url::Url(std::string location, UrlType type) - : location(std::move(location)), - type(type) + : location(std::move(location)) + , type(type) { // This has to be provided manually since we have another constructor } @@ -1070,14 +1071,14 @@ bool App::Meta::Url::operator==(const Url& rhs) const } App::Meta::Dependency::Dependency() - : optional(false), - dependencyType(App::Meta::DependencyType::automatic) + : optional(false) + , dependencyType(App::Meta::DependencyType::automatic) {} App::Meta::Dependency::Dependency(std::string pkg) - : package(std::move(pkg)), - optional(false), - dependencyType(App::Meta::DependencyType::automatic) + : package(std::move(pkg)) + , optional(false) + , dependencyType(App::Meta::DependencyType::automatic) {} Meta::Dependency::Dependency(const XERCES_CPP_NAMESPACE::DOMElement* elem) @@ -1090,7 +1091,7 @@ Meta::Dependency::Dependency(const XERCES_CPP_NAMESPACE::DOMElement* elem) condition = StrXUTF8(elem->getAttribute(XUTF8Str("condition").unicodeForm())).str; std::string opt_string = StrXUTF8(elem->getAttribute(XUTF8Str("optional").unicodeForm())).str; if (opt_string == "true" - || opt_string == "True") {// Support Python capitalization in this one case... + || opt_string == "True") { // Support Python capitalization in this one case... optional = true; } else { @@ -1128,10 +1129,10 @@ bool App::Meta::Dependency::operator==(const Dependency& rhs) const Meta::Version::Version() = default; Meta::Version::Version(int major, int minor, int patch, std::string suffix) - : major(major), - minor(minor), - patch(patch), - suffix(std::move(suffix)) + : major(major) + , minor(minor) + , patch(patch) + , suffix(std::move(suffix)) {} Meta::Version::Version(const std::string& versionString) @@ -1207,8 +1208,8 @@ Meta::GenericMetadata::GenericMetadata(const XERCES_CPP_NAMESPACE::DOMElement* e contents = StrXUTF8(elem->getTextContent()).str; for (XMLSize_t i = 0; i < elem->getAttributes()->getLength(); ++i) { auto attr = elem->getAttributes()->item(i); - attributes.insert( - std::make_pair(StrXUTF8(attr->getNodeName()).str, StrXUTF8(attr->getTextContent()).str)); + attributes.insert(std::make_pair(StrXUTF8(attr->getNodeName()).str, + StrXUTF8(attr->getTextContent()).str)); } } diff --git a/src/App/Metadata.h b/src/App/Metadata.h index ff30828ce4..fa5f14717c 100644 --- a/src/App/Metadata.h +++ b/src/App/Metadata.h @@ -1,24 +1,24 @@ /************************************************************************** -* * -* Copyright (c) 2021-2023 FreeCAD Project Association * -* * -* This file is part of FreeCAD. * -* * -* FreeCAD is free software: you can redistribute it and/or modify it * -* under the terms of the GNU Lesser General Public License as * -* published by the Free Software Foundation, either version 2.1 of the * -* License, or (at your option) any later version. * -* * -* FreeCAD is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * -* Lesser General Public License for more details. * -* * -* You should have received a copy of the GNU Lesser General Public * -* License along with FreeCAD. If not, see * -* . * -* * -***************************************************************************/ + * * + * Copyright (c) 2021-2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ #ifndef BASE_METADATAREADER_H #define BASE_METADATAREADER_H @@ -43,32 +43,36 @@ namespace Meta { /** - * \struct Contact - * \brief A person or company representing a point of contact for the package (either author or maintainer). - */ -struct AppExport Contact { + * \struct Contact + * \brief A person or company representing a point of contact for the package (either author or + * maintainer). + */ +struct AppExport Contact +{ Contact() = default; - Contact(std::string name, std::string email); + Contact(std::string name, std::string email); explicit Contact(const XERCES_CPP_NAMESPACE::DOMElement* elem); - std::string name; //< Contact name - required - std::string email;//< Contact email - may be optional + std::string name; //< Contact name - required + std::string email; //< Contact email - may be optional bool operator==(const Contact& rhs) const; }; /** - * \struct License - * \brief A license that covers some or all of this package. - * - * Many licenses also require the inclusion of the complete license text, specified in this struct - * using the "file" member. - */ -struct AppExport License { + * \struct License + * \brief A license that covers some or all of this package. + * + * Many licenses also require the inclusion of the complete license text, specified in this struct + * using the "file" member. + */ +struct AppExport License +{ License() = default; License(std::string name, boost::filesystem::path file); explicit License(const XERCES_CPP_NAMESPACE::DOMElement* elem); - std::string name;//< Short name of license, e.g. "LGPL2", "MIT", "Mozilla Public License", etc. + std::string + name; //< Short name of license, e.g. "LGPL2", "MIT", "Mozilla Public License", etc. boost::filesystem::path - file;//< Optional path to the license file, relative to the XML file's location + file; //< Optional path to the license file, relative to the XML file's location bool operator==(const License& rhs) const; }; @@ -83,32 +87,35 @@ enum class UrlType }; /** - * \struct Url - * \brief A URL, including type information (e.g. website, repository, or bugtracker, in package.xml) - */ -struct AppExport Url { + * \struct Url + * \brief A URL, including type information (e.g. website, repository, or bugtracker, in + * package.xml) + */ +struct AppExport Url +{ Url(); Url(std::string location, UrlType type); explicit Url(const XERCES_CPP_NAMESPACE::DOMElement* elem); - std::string location;//< The actual URL, including protocol - UrlType type; //< What kind of URL this is - std::string branch; //< If it's a repository, which branch to use + std::string location; //< The actual URL, including protocol + UrlType type; //< What kind of URL this is + std::string branch; //< If it's a repository, which branch to use bool operator==(const Url& rhs) const; }; /** - * \struct Version - * A semantic version structure providing comparison operators and conversion to and from std::string - */ -struct AppExport Version { + * \struct Version + * A semantic version structure providing comparison operators and conversion to and from + * std::string + */ +struct AppExport Version +{ Version(); - explicit Version(int major, int minor = 0, int patch = 0, - std::string suffix = std::string()); + explicit Version(int major, int minor = 0, int patch = 0, std::string suffix = std::string()); explicit Version(const std::string& semanticString); - int major{}; - int minor{}; - int patch{}; + int major {}; + int minor {}; + int patch {}; std::string suffix; std::string str() const; @@ -122,9 +129,9 @@ struct AppExport Version { }; /** - * \enum DependencyType - * The type of dependency. - */ + * \enum DependencyType + * The type of dependency. + */ enum class DependencyType { automatic, @@ -134,81 +141,83 @@ enum class DependencyType }; /** - * \struct Dependency - * \brief Another package that this package depends on, conflicts with, or replaces - */ -struct AppExport Dependency { + * \struct Dependency + * \brief Another package that this package depends on, conflicts with, or replaces + */ +struct AppExport Dependency +{ Dependency(); - explicit Dependency(std::string pkg); + explicit Dependency(std::string pkg); explicit Dependency(const XERCES_CPP_NAMESPACE::DOMElement* elem); - std::string - package;//< Required: must exactly match the contents of the "name" element in the referenced package's package.xml file. - std::string - version_lt;//< Optional: The dependency to the package is restricted to versions less than the stated version number. - std::string - version_lte;//< Optional: The dependency to the package is restricted to versions less or equal than the stated version number. - std::string - version_eq;//< Optional: The dependency to the package is restricted to a version equal than the stated version number. - std::string - version_gte;//< Optional: The dependency to the package is restricted to versions greater or equal than the stated version number. - std::string - version_gt;//< Optional: The dependency to the package is restricted to versions greater than the stated version number. - std::string condition; //< Optional: Conditional expression as documented in REP149. - bool optional; //< Optional: Whether this dependency is considered "optional" - DependencyType dependencyType;//< Optional: defaults to "automatic" + std::string package; //< Required: must exactly match the contents of the "name" element in the + //referenced package's package.xml file. + std::string version_lt; //< Optional: The dependency to the package is restricted to versions + //less than the stated version number. + std::string version_lte; //< Optional: The dependency to the package is restricted to versions + //less or equal than the stated version number. + std::string version_eq; //< Optional: The dependency to the package is restricted to a version + //equal than the stated version number. + std::string version_gte; //< Optional: The dependency to the package is restricted to versions + //greater or equal than the stated version number. + std::string version_gt; //< Optional: The dependency to the package is restricted to versions + //greater than the stated version number. + std::string condition; //< Optional: Conditional expression as documented in REP149. + bool optional; //< Optional: Whether this dependency is considered "optional" + DependencyType dependencyType; //< Optional: defaults to "automatic" bool operator==(const Dependency& rhs) const; }; /** - * \struct GenericMetadata - * A structure to hold unrecognized single-level metadata. - * - * Most unrecognized metadata is simple: when parsing the XML, if the parser finds a tag it - * does not recognize, and that tag has no children, it is parsed into this data structure - * for convenient access by client code. - */ -struct AppExport GenericMetadata { + * \struct GenericMetadata + * A structure to hold unrecognized single-level metadata. + * + * Most unrecognized metadata is simple: when parsing the XML, if the parser finds a tag it + * does not recognize, and that tag has no children, it is parsed into this data structure + * for convenient access by client code. + */ +struct AppExport GenericMetadata +{ GenericMetadata() = default; explicit GenericMetadata(const XERCES_CPP_NAMESPACE::DOMElement* elem); - explicit GenericMetadata(std::string contents); - std::string contents; //< The contents of the tag - std::map attributes;//< The XML attributes of the tag + explicit GenericMetadata(std::string contents); + std::string contents; //< The contents of the tag + std::map attributes; //< The XML attributes of the tag }; -}// namespace Meta +} // namespace Meta /** - * \class Metadata - * \brief Reads data from a metadata file. - * - * The metadata format is based on https://ros.org/reps/rep-0149.html, modified for FreeCAD - * use. Full format documentation is available at the FreeCAD Wiki: - * https://wiki.freecad.org/Package_Metadata - */ + * \class Metadata + * \brief Reads data from a metadata file. + * + * The metadata format is based on https://ros.org/reps/rep-0149.html, modified for FreeCAD + * use. Full format documentation is available at the FreeCAD Wiki: + * https://wiki.freecad.org/Package_Metadata + */ class AppExport Metadata { public: Metadata(); /** - * Read the data from a file on disk - * - * This constructor takes a path to an XML file and loads the XML from that file as - * metadata. - */ + * Read the data from a file on disk + * + * This constructor takes a path to an XML file and loads the XML from that file as + * metadata. + */ explicit Metadata(const boost::filesystem::path& metadataFile); /** - * Construct a Metadata object from a DOM node. - * - * This node may have any tag name: it is only accessed via its children, which are - * expected to follow the standard Metadata format for the contents of the element. - */ + * Construct a Metadata object from a DOM node. + * + * This node may have any tag name: it is only accessed via its children, which are + * expected to follow the standard Metadata format for the contents of the element. + */ Metadata(const XERCES_CPP_NAMESPACE::DOMNode* domNode, int format); /** - * Treat the incoming rawData as metadata to be parsed. - */ + * Treat the incoming rawData as metadata to be parsed. + */ explicit Metadata(const std::string& rawData); ~Metadata(); @@ -218,69 +227,69 @@ public: // Recognized Metadata ////////////////////////////////////////////////////////////// - std::string name() const; //< A short name for this package, often used as a menu entry. - std::string type() const; //< The type for this package. - Meta::Version version() const;//< Version string in semantic triplet format, e.g. "1.2.3". + std::string name() const; //< A short name for this package, often used as a menu entry. + std::string type() const; //< The type for this package. + Meta::Version version() const; //< Version string in semantic triplet format, e.g. "1.2.3". std::string date() - const;//< Date string -- currently arbitrary (when C++20 is well-supported we can revisit) - std::string description() const;//< Text-only description of the package. No markup. + const; //< Date string -- currently arbitrary (when C++20 is well-supported we can revisit) + std::string description() const; //< Text-only description of the package. No markup. std::vector - maintainer() const;//< Must be at least one, and must specify an email address. + maintainer() const; //< Must be at least one, and must specify an email address. std::vector - license() const;//< Must be at least one, and most licenses require including a license file. - std::vector url() - const;//< Any number of URLs may be specified, but at least one repository URL must be included at the package level. + license() const; //< Must be at least one, and most licenses require including a license file. + std::vector url() const; //< Any number of URLs may be specified, but at least one + //repository URL must be included at the package level. std::vector - author() const;//< Any number of authors may be specified, and email addresses are optional. + author() const; //< Any number of authors may be specified, and email addresses are optional. std::vector - depend() const;//< Zero or more packages this package requires prior to use. + depend() const; //< Zero or more packages this package requires prior to use. std::vector - conflict() const;//< Zero of more packages this package conflicts with. + conflict() const; //< Zero of more packages this package conflicts with. std::vector - replace() const;//< Zero or more packages this package is intended to replace. - std::vector tag() const;//< Zero or more text tags related to this package. - boost::filesystem::path icon() const;//< Path to an icon file. + replace() const; //< Zero or more packages this package is intended to replace. + std::vector tag() const; //< Zero or more text tags related to this package. + boost::filesystem::path icon() const; //< Path to an icon file. std::string - classname() const;//< Recognized for convenience -- generally only used by Workbenches. + classname() const; //< Recognized for convenience -- generally only used by Workbenches. boost::filesystem::path - subdirectory() const;//< Optional, override the default subdirectory name for this item. + subdirectory() const; //< Optional, override the default subdirectory name for this item. std::vector - file() const;//< Arbitrary files associated with this package or content item. - Meta::Version freecadmin() const;//< The minimum FreeCAD version. - Meta::Version freecadmax() const;//< The maximum FreeCAD version. - Meta::Version pythonmin() const; //< The minimum Python version. + file() const; //< Arbitrary files associated with this package or content item. + Meta::Version freecadmin() const; //< The minimum FreeCAD version. + Meta::Version freecadmax() const; //< The maximum FreeCAD version. + Meta::Version pythonmin() const; //< The minimum Python version. /** - * Access the metadata for the content elements of this package - * - * In addition to the overall package metadata, this class reads in metadata contained in a - * element. Each entry in the content element is an element representing some - * type of package content (e.g. add-on, macro, theme, etc.). This class places no restriction - * on the types, it is up to client code to place requirements on the metadata included - * here. - * - * For example, themes might be specified: - * - * - * High Contrast - * - * - */ + * Access the metadata for the content elements of this package + * + * In addition to the overall package metadata, this class reads in metadata contained in a + * element. Each entry in the content element is an element representing some + * type of package content (e.g. add-on, macro, theme, etc.). This class places no restriction + * on the types, it is up to client code to place requirements on the metadata included + * here. + * + * For example, themes might be specified: + * + * + * High Contrast + * + * + */ std::multimap content() const; /** - * Convenience accessor for unrecognized simple metadata. - * - * If the XML parser encounters tags that it does not recognize, and those tags have - * no children, a GenericMetadata object is created. Those objects can be accessed using - * operator[], which returns a (potentially empty) vector containing all instances of the - * given tag. It cannot be used to *create* a new tag, however. See addGenericMetadata(). - */ + * Convenience accessor for unrecognized simple metadata. + * + * If the XML parser encounters tags that it does not recognize, and those tags have + * no children, a GenericMetadata object is created. Those objects can be accessed using + * operator[], which returns a (potentially empty) vector containing all instances of the + * given tag. It cannot be used to *create* a new tag, however. See addGenericMetadata(). + */ std::vector operator[](const std::string& tag) const; /** - * Directly access the DOM tree to support unrecognized multi-level metadata - */ + * Directly access the DOM tree to support unrecognized multi-level metadata + */ XERCES_CPP_NAMESPACE::DOMElement* dom() const; @@ -333,19 +342,19 @@ public: void clearFile(); /** - * Write the metadata to an XML file - */ + * Write the metadata to an XML file + */ void write(const boost::filesystem::path& file) const; /** - * Determine whether this package satisfies the given dependency - */ + * Determine whether this package satisfies the given dependency + */ bool satisfies(const Meta::Dependency&); /** - * Determine whether the current metadata specifies support for the currently-running version of FreeCAD. - * Does not interrogate content items, which must be queried individually. - */ + * Determine whether the current metadata specifies support for the currently-running version of + * FreeCAD. Does not interrogate content items, which must be queried individually. + */ bool supportsCurrentFreeCAD() const; private: @@ -384,6 +393,6 @@ private: void appendToElement(XERCES_CPP_NAMESPACE::DOMElement* root) const; }; -}// namespace App +} // namespace App #endif diff --git a/src/App/MetadataPyImp.cpp b/src/App/MetadataPyImp.cpp index a2241a0e6e..953f2799dc 100644 --- a/src/App/MetadataPyImp.cpp +++ b/src/App/MetadataPyImp.cpp @@ -1,24 +1,24 @@ /************************************************************************** -* * -* Copyright (c) 2022 FreeCAD Project Association * -* * -* This file is part of FreeCAD. * -* * -* FreeCAD is free software: you can redistribute it and/or modify it * -* under the terms of the GNU Lesser General Public License as * -* published by the Free Software Foundation, either version 2.1 of the * -* License, or (at your option) any later version. * -* * -* FreeCAD is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * -* Lesser General Public License for more details. * -* * -* You should have received a copy of the GNU Lesser General Public * -* License along with FreeCAD. If not, see * -* . * -* * -**************************************************************************/ + * * + * Copyright (c) 2022 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + **************************************************************************/ #include "PreCompiled.h" @@ -55,13 +55,13 @@ std::string MetadataPy::representation() const return str.str(); } -PyObject *MetadataPy::PyMake(struct _typeobject *, PyObject *, PyObject *)// Python wrapper +PyObject* MetadataPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper { return new MetadataPy(nullptr); } // constructor method -int MetadataPy::PyInit(PyObject *args, PyObject * /*kwd*/) +int MetadataPy::PyInit(PyObject* args, PyObject* /*kwd*/) { if (PyArg_ParseTuple(args, "")) { setTwinPointer(new Metadata()); @@ -75,9 +75,8 @@ int MetadataPy::PyInit(PyObject *args, PyObject * /*kwd*/) try { // NB: This is making a copy of the buffer for simplicity, but that shouldn't be // necessary. Use either a string_view or a span to avoid the copy in the future. - auto md = new Metadata( - std::string(static_cast(dataBuffer.buf), dataBuffer.len) - ); + auto md = + new Metadata(std::string(static_cast(dataBuffer.buf), dataBuffer.len)); setTwinPointer(md); return 0; } @@ -89,7 +88,7 @@ int MetadataPy::PyInit(PyObject *args, PyObject * /*kwd*/) // Main class constructor -- takes a file path, loads the metadata from it PyErr_Clear(); - char *filename; + char* filename; if (PyArg_ParseTuple(args, "et", "utf-8", &filename)) { try { std::string utf8Name = std::string(filename); @@ -99,19 +98,19 @@ int MetadataPy::PyInit(PyObject *args, PyObject * /*kwd*/) setTwinPointer(md); return 0; } - catch (const Base::XMLBaseException &e) { + catch (const Base::XMLBaseException& e) { e.setPyException(); return -1; } - catch (const XMLException &toCatch) { - char *message = XMLString::transcode(toCatch.getMessage()); + catch (const XMLException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); std::string what = message; XMLString::release(&message); PyErr_SetString(Base::PyExc_FC_XMLBaseException, what.c_str()); return -1; } - catch (const DOMException &toCatch) { - char *message = XMLString::transcode(toCatch.getMessage()); + catch (const DOMException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); std::string what = message; XMLString::release(&message); PyErr_SetString(Base::PyExc_FC_XMLBaseException, what.c_str()); @@ -125,14 +124,15 @@ int MetadataPy::PyInit(PyObject *args, PyObject * /*kwd*/) // Copy constructor PyErr_Clear(); - PyObject *o; + PyObject* o; if (PyArg_ParseTuple(args, "O!", &(App::MetadataPy::Type), &o)) { - App::Metadata *a = static_cast(o)->getMetadataPtr(); + App::Metadata* a = static_cast(o)->getMetadataPtr(); setTwinPointer(new Metadata(*a)); return 0; } - PyErr_SetString(Base::PyExc_FC_GeneralError, "metadata object or path to metadata file expected"); + PyErr_SetString(Base::PyExc_FC_GeneralError, + "metadata object or path to metadata file expected"); return -1; } @@ -143,14 +143,16 @@ Py::Object MetadataPy::getName() const void MetadataPy::setName(Py::Object args) { - const char *name = nullptr; + const char* name = nullptr; if (!PyArg_Parse(args.ptr(), "z", &name)) { throw Py::Exception(); } - if (name) + if (name) { getMetadataPtr()->setName(name); - else + } + else { getMetadataPtr()->setName(""); + } } Py::Object MetadataPy::getVersion() const @@ -160,13 +162,16 @@ Py::Object MetadataPy::getVersion() const void MetadataPy::setVersion(Py::Object args) { - const char *name = nullptr; - if (!PyArg_Parse(args.ptr(), "z", &name)) + const char* name = nullptr; + if (!PyArg_Parse(args.ptr(), "z", &name)) { throw Py::Exception(); - if (name && name[0] != '\0') + } + if (name && name[0] != '\0') { getMetadataPtr()->setVersion(App::Meta::Version(std::string(name))); - else + } + else { getMetadataPtr()->setVersion(App::Meta::Version()); + } } Py::Object MetadataPy::getDate() const @@ -176,12 +181,16 @@ Py::Object MetadataPy::getDate() const void MetadataPy::setDate(Py::Object args) { - const char *date = nullptr; - if (!PyArg_Parse(args.ptr(), "z", &date)) + const char* date = nullptr; + if (!PyArg_Parse(args.ptr(), "z", &date)) { throw Py::Exception(); - if (date) getMetadataPtr()->setDate(date); - else + } + if (date) { + getMetadataPtr()->setDate(date); + } + else { getMetadataPtr()->setDate(""); + } } Py::Object MetadataPy::getDescription() const @@ -191,9 +200,10 @@ Py::Object MetadataPy::getDescription() const void MetadataPy::setDescription(Py::Object args) { - const char *description = nullptr; - if (!PyArg_Parse(args.ptr(), "s", &description)) + const char* description = nullptr; + if (!PyArg_Parse(args.ptr(), "s", &description)) { throw Py::Exception(); + } getMetadataPtr()->setDescription(description); } @@ -204,9 +214,10 @@ Py::Object MetadataPy::getType() const void MetadataPy::setType(Py::Object args) { - const char *type = nullptr; - if (!PyArg_Parse(args.ptr(), "s", &type)) + const char* type = nullptr; + if (!PyArg_Parse(args.ptr(), "s", &type)) { throw Py::Exception(); + } getMetadataPtr()->setType(type); } @@ -214,7 +225,7 @@ Py::Object MetadataPy::getMaintainer() const { auto maintainers = getMetadataPtr()->maintainer(); Py::List pyMaintainers; - for (const auto &m : maintainers) { + for (const auto& m : maintainers) { Py::Dict pyMaintainer; pyMaintainer["name"] = Py::String(m.name); pyMaintainer["email"] = Py::String(m.email); @@ -225,13 +236,14 @@ Py::Object MetadataPy::getMaintainer() const void MetadataPy::setMaintainer(Py::Object args) { - PyObject *list = nullptr; - if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) + PyObject* list = nullptr; + if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) { throw Py::Exception(); + } getMetadataPtr()->clearMaintainer(); Py::List maintainers(list); - for (const auto &m : maintainers) { + for (const auto& m : maintainers) { Py::Dict pyMaintainer(m); std::string name = pyMaintainer["name"].str(); std::string email = pyMaintainer["email"].str(); @@ -239,23 +251,25 @@ void MetadataPy::setMaintainer(Py::Object args) } } -PyObject *MetadataPy::addMaintainer(PyObject *args) +PyObject* MetadataPy::addMaintainer(PyObject* args) { - const char *name = nullptr; - const char *email = nullptr; - if (!PyArg_ParseTuple(args, "ss", &name, &email)) + const char* name = nullptr; + const char* email = nullptr; + if (!PyArg_ParseTuple(args, "ss", &name, &email)) { throw Py::Exception(); + } getMetadataPtr()->addMaintainer(App::Meta::Contact(name, email)); Py_INCREF(Py_None); return Py_None; } -PyObject *MetadataPy::removeMaintainer(PyObject *args) +PyObject* MetadataPy::removeMaintainer(PyObject* args) { - const char *name = nullptr; - const char *email = nullptr; - if (!PyArg_ParseTuple(args, "ss", &name, &email)) + const char* name = nullptr; + const char* email = nullptr; + if (!PyArg_ParseTuple(args, "ss", &name, &email)) { throw Py::Exception(); + } getMetadataPtr()->removeMaintainer(App::Meta::Contact(name, email)); Py_INCREF(Py_None); return Py_None; @@ -266,7 +280,7 @@ Py::Object MetadataPy::getAuthor() const { auto authors = getMetadataPtr()->author(); Py::List pyAuthors; - for (const auto &a : authors) { + for (const auto& a : authors) { Py::Dict pyAuthor; pyAuthor["name"] = Py::String(a.name); pyAuthor["email"] = Py::String(a.email); @@ -277,13 +291,14 @@ Py::Object MetadataPy::getAuthor() const void MetadataPy::setAuthor(Py::Object args) { - PyObject *list = nullptr; - if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) + PyObject* list = nullptr; + if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) { throw Py::Exception(); + } getMetadataPtr()->clearAuthor(); Py::List authors(list); - for (const auto &a : authors) { + for (const auto& a : authors) { Py::Dict pyAuthor(a); std::string name = pyAuthor["name"].str(); std::string email = pyAuthor["email"].str(); @@ -291,23 +306,25 @@ void MetadataPy::setAuthor(Py::Object args) } } -PyObject *MetadataPy::addAuthor(PyObject *args) +PyObject* MetadataPy::addAuthor(PyObject* args) { - const char *name = nullptr; - const char *email = nullptr; - if (!PyArg_ParseTuple(args, "ss", &name, &email)) + const char* name = nullptr; + const char* email = nullptr; + if (!PyArg_ParseTuple(args, "ss", &name, &email)) { throw Py::Exception(); + } getMetadataPtr()->addAuthor(App::Meta::Contact(name, email)); Py_INCREF(Py_None); return Py_None; } -PyObject *MetadataPy::removeAuthor(PyObject *args) +PyObject* MetadataPy::removeAuthor(PyObject* args) { - const char *name = nullptr; - const char *email = nullptr; - if (!PyArg_ParseTuple(args, "ss", &name, &email)) + const char* name = nullptr; + const char* email = nullptr; + if (!PyArg_ParseTuple(args, "ss", &name, &email)) { throw Py::Exception(); + } getMetadataPtr()->removeAuthor(App::Meta::Contact(name, email)); Py_INCREF(Py_None); return Py_None; @@ -317,7 +334,7 @@ Py::Object MetadataPy::getLicense() const { auto licenses = getMetadataPtr()->license(); Py::List pyLicenses; - for (const auto &lic : licenses) { + for (const auto& lic : licenses) { Py::Dict pyLicense; pyLicense["name"] = Py::String(lic.name); pyLicense["file"] = Py::String(lic.file.string()); @@ -328,13 +345,14 @@ Py::Object MetadataPy::getLicense() const void MetadataPy::setLicense(Py::Object args) { - PyObject *list = nullptr; - if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) + PyObject* list = nullptr; + if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) { throw Py::Exception(); + } getMetadataPtr()->clearLicense(); Py::List licenses(list); - for (const auto &l : licenses) { + for (const auto& l : licenses) { Py::Dict pyLicense(l); std::string name = pyLicense["name"].str(); std::string path = pyLicense["file"].str(); @@ -342,23 +360,25 @@ void MetadataPy::setLicense(Py::Object args) } } -PyObject *MetadataPy::addLicense(PyObject *args) +PyObject* MetadataPy::addLicense(PyObject* args) { - const char *shortCode = nullptr; - const char *path = nullptr; - if (!PyArg_ParseTuple(args, "ss", &shortCode, &path)) + const char* shortCode = nullptr; + const char* path = nullptr; + if (!PyArg_ParseTuple(args, "ss", &shortCode, &path)) { throw Py::Exception(); + } getMetadataPtr()->addLicense(App::Meta::License(shortCode, path)); Py_INCREF(Py_None); return Py_None; } -PyObject *MetadataPy::removeLicense(PyObject *args) +PyObject* MetadataPy::removeLicense(PyObject* args) { - const char *shortCode = nullptr; - const char *path = nullptr; - if (!PyArg_ParseTuple(args, "ss", &shortCode, &path)) + const char* shortCode = nullptr; + const char* path = nullptr; + if (!PyArg_ParseTuple(args, "ss", &shortCode, &path)) { throw Py::Exception(); + } getMetadataPtr()->removeLicense(App::Meta::License(shortCode, path)); Py_INCREF(Py_None); return Py_None; @@ -368,20 +388,35 @@ Py::Object MetadataPy::getUrls() const { auto urls = getMetadataPtr()->url(); Py::List pyUrls; - for (const auto &url : urls) { + for (const auto& url : urls) { Py::Dict pyUrl; pyUrl["location"] = Py::String(url.location); switch (url.type) { - case Meta::UrlType::website: pyUrl["type"] = Py::String("website"); break; - case Meta::UrlType::repository: pyUrl["type"] = Py::String("repository"); break; - case Meta::UrlType::bugtracker: pyUrl["type"] = Py::String("bugtracker"); break; - case Meta::UrlType::readme: pyUrl["type"] = Py::String("readme"); break; - case Meta::UrlType::documentation: pyUrl["type"] = Py::String("documentation"); break; - case Meta::UrlType::discussion: pyUrl["type"] = Py::String("discussion"); break; - default: pyUrl["type"] = Py::String("unknown"); break; + case Meta::UrlType::website: + pyUrl["type"] = Py::String("website"); + break; + case Meta::UrlType::repository: + pyUrl["type"] = Py::String("repository"); + break; + case Meta::UrlType::bugtracker: + pyUrl["type"] = Py::String("bugtracker"); + break; + case Meta::UrlType::readme: + pyUrl["type"] = Py::String("readme"); + break; + case Meta::UrlType::documentation: + pyUrl["type"] = Py::String("documentation"); + break; + case Meta::UrlType::discussion: + pyUrl["type"] = Py::String("discussion"); + break; + default: + pyUrl["type"] = Py::String("unknown"); + break; } - if (url.type == Meta::UrlType::repository) + if (url.type == Meta::UrlType::repository) { pyUrl["branch"] = Py::String(url.branch); + } pyUrls.append(pyUrl); } return pyUrls; @@ -389,13 +424,14 @@ Py::Object MetadataPy::getUrls() const void MetadataPy::setUrls(Py::Object args) { - PyObject *list = nullptr; - if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) + PyObject* list = nullptr; + if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) { throw Py::Exception(); + } getMetadataPtr()->clearUrl(); Py::List urls(list); - for (const auto &url : urls) { + for (const auto& url : urls) { Py::Dict pyUrl(url); std::string location = pyUrl["location"].str(); std::string typeAsString = pyUrl["type"].str(); @@ -431,52 +467,60 @@ void MetadataPy::setUrls(Py::Object args) App::Meta::Url urlFromStrings(const char* urlTypeCharStar, const char* link, const char* branch) { std::string urlTypeString(urlTypeCharStar); - App::Meta::UrlType urlType{App::Meta::UrlType::documentation}; - if (urlTypeString == "repository") + App::Meta::UrlType urlType {App::Meta::UrlType::documentation}; + if (urlTypeString == "repository") { urlType = App::Meta::UrlType::repository; - else if (urlTypeString == "bugtracker") + } + else if (urlTypeString == "bugtracker") { urlType = App::Meta::UrlType::bugtracker; - else if (urlTypeString == "documentation") + } + else if (urlTypeString == "documentation") { urlType = App::Meta::UrlType::documentation; - else if (urlTypeString == "readme") + } + else if (urlTypeString == "readme") { urlType = App::Meta::UrlType::readme; - else if (urlTypeString == "website") + } + else if (urlTypeString == "website") { urlType = App::Meta::UrlType::website; + } App::Meta::Url url(link, urlType); - if (urlType == App::Meta::UrlType::repository) + if (urlType == App::Meta::UrlType::repository) { url.branch = std::string(branch); + } return url; } -PyObject *MetadataPy::addUrl(PyObject *args) +PyObject* MetadataPy::addUrl(PyObject* args) { - const char *urlTypeCharStar = nullptr; - const char *link = nullptr; - const char *branch = nullptr; - if (!PyArg_ParseTuple(args, "ss|s", &urlTypeCharStar, &link, &branch)) + const char* urlTypeCharStar = nullptr; + const char* link = nullptr; + const char* branch = nullptr; + if (!PyArg_ParseTuple(args, "ss|s", &urlTypeCharStar, &link, &branch)) { throw Py::Exception(); + } getMetadataPtr()->addUrl(urlFromStrings(urlTypeCharStar, link, branch)); Py_INCREF(Py_None); return Py_None; } -PyObject *MetadataPy::removeUrl(PyObject *args) +PyObject* MetadataPy::removeUrl(PyObject* args) { - const char *urlTypeCharStar = nullptr; - const char *link = nullptr; - const char *branch = nullptr; - if (!PyArg_ParseTuple(args, "ss|s", &urlTypeCharStar, &link, &branch)) + const char* urlTypeCharStar = nullptr; + const char* link = nullptr; + const char* branch = nullptr; + if (!PyArg_ParseTuple(args, "ss|s", &urlTypeCharStar, &link, &branch)) { throw Py::Exception(); + } getMetadataPtr()->removeUrl(urlFromStrings(urlTypeCharStar, link, branch)); Py_INCREF(Py_None); return Py_None; } -Py::Object dependencyToPyObject(const Meta::Dependency &d) +Py::Object dependencyToPyObject(const Meta::Dependency& d) { Py::Dict pyDependency; pyDependency["package"] = Py::String(d.package); @@ -489,7 +533,7 @@ Py::Object dependencyToPyObject(const Meta::Dependency &d) pyDependency["optional"] = Py::Boolean(d.optional); switch (d.dependencyType) { case App::Meta::DependencyType::automatic: - pyDependency["type"] = Py::String ("automatic"); + pyDependency["type"] = Py::String("automatic"); break; case App::Meta::DependencyType::addon: pyDependency["type"] = Py::String("addon"); @@ -504,34 +548,45 @@ Py::Object dependencyToPyObject(const Meta::Dependency &d) return pyDependency; } -Meta::Dependency pyObjectToDependency(const Py::Object &d) +Meta::Dependency pyObjectToDependency(const Py::Object& d) { Py::Dict pyDependency(d); Meta::Dependency result; result.package = pyDependency["package"].str(); - if (pyDependency.hasKey("version_lt")) + if (pyDependency.hasKey("version_lt")) { result.version_lt = pyDependency["version_lt"].str(); - if (pyDependency.hasKey("version_lte")) + } + if (pyDependency.hasKey("version_lte")) { result.version_lte = pyDependency["version_lte"].str(); - if (pyDependency.hasKey("version_eq")) + } + if (pyDependency.hasKey("version_eq")) { result.version_eq = pyDependency["version_eq"].str(); - if (pyDependency.hasKey("version_gt")) + } + if (pyDependency.hasKey("version_gt")) { result.version_gt = pyDependency["version_gt"].str(); - if (pyDependency.hasKey("version_gte")) + } + if (pyDependency.hasKey("version_gte")) { result.version_gte = pyDependency["version_gte"].str(); - if (pyDependency.hasKey("condition")) + } + if (pyDependency.hasKey("condition")) { result.condition = pyDependency["condition"].str(); - if (pyDependency.hasKey("optional")) + } + if (pyDependency.hasKey("optional")) { result.optional = Py::Boolean(pyDependency["optional"]).as_bool(); + } if (pyDependency.hasKey("type")) { - if (pyDependency["type"].str() == Py::String("automatic")) + if (pyDependency["type"].str() == Py::String("automatic")) { result.dependencyType = App::Meta::DependencyType::automatic; - else if (pyDependency["type"].str() == Py::String("internal")) + } + else if (pyDependency["type"].str() == Py::String("internal")) { result.dependencyType = App::Meta::DependencyType::internal; - else if (pyDependency["type"].str() == Py::String("addon")) + } + else if (pyDependency["type"].str() == Py::String("addon")) { result.dependencyType = App::Meta::DependencyType::addon; - else if (pyDependency["type"].str() == Py::String("python")) + } + else if (pyDependency["type"].str() == Py::String("python")) { result.dependencyType = App::Meta::DependencyType::python; + } } return result; } @@ -540,7 +595,7 @@ Py::Object MetadataPy::getDepend() const { auto dependencies = getMetadataPtr()->depend(); Py::List pyDependencies; - for (const auto &d : dependencies) { + for (const auto& d : dependencies) { pyDependencies.append(dependencyToPyObject(d)); } return pyDependencies; @@ -548,34 +603,37 @@ Py::Object MetadataPy::getDepend() const void MetadataPy::setDepend(Py::Object args) { - PyObject *list = nullptr; - if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) + PyObject* list = nullptr; + if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) { throw Py::Exception(); + } getMetadataPtr()->clearDepend(); Py::List deps(list); - for (const auto &dep : deps) { + for (const auto& dep : deps) { Py::Dict pyDep(dep); getMetadataPtr()->addDepend(pyObjectToDependency(pyDep)); } } -PyObject *MetadataPy::addDepend(PyObject *args) +PyObject* MetadataPy::addDepend(PyObject* args) { - PyObject *dictionary = nullptr; - if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) + PyObject* dictionary = nullptr; + if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) { throw Py::Exception(); + } Py::Dict pyDep(dictionary); getMetadataPtr()->addDepend(pyObjectToDependency(pyDep)); Py_INCREF(Py_None); return Py_None; } -PyObject *MetadataPy::removeDepend(PyObject *args) +PyObject* MetadataPy::removeDepend(PyObject* args) { - PyObject *dictionary = nullptr; - if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) + PyObject* dictionary = nullptr; + if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) { throw Py::Exception(); + } Py::Dict pyDep(dictionary); getMetadataPtr()->removeDepend(pyObjectToDependency(pyDep)); Py_INCREF(Py_None); @@ -586,7 +644,7 @@ Py::Object MetadataPy::getConflict() const { auto dependencies = getMetadataPtr()->conflict(); Py::List pyDependencies; - for (const auto &d : dependencies) { + for (const auto& d : dependencies) { pyDependencies.append(dependencyToPyObject(d)); } return pyDependencies; @@ -594,34 +652,37 @@ Py::Object MetadataPy::getConflict() const void MetadataPy::setConflict(Py::Object args) { - PyObject *list = nullptr; - if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) + PyObject* list = nullptr; + if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) { throw Py::Exception(); + } getMetadataPtr()->clearConflict(); Py::List deps(list); - for (const auto &dep : deps) { + for (const auto& dep : deps) { Py::Dict pyDep(dep); getMetadataPtr()->addConflict(pyObjectToDependency(pyDep)); } } -PyObject *MetadataPy::addConflict(PyObject *args) +PyObject* MetadataPy::addConflict(PyObject* args) { - PyObject *dictionary = nullptr; - if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) + PyObject* dictionary = nullptr; + if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) { throw Py::Exception(); + } Py::Dict pyDep(dictionary); getMetadataPtr()->addConflict(pyObjectToDependency(pyDep)); Py_INCREF(Py_None); return Py_None; } -PyObject *MetadataPy::removeConflict(PyObject *args) +PyObject* MetadataPy::removeConflict(PyObject* args) { - PyObject *dictionary = nullptr; - if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) + PyObject* dictionary = nullptr; + if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) { throw Py::Exception(); + } Py::Dict pyDep(dictionary); getMetadataPtr()->removeConflict(pyObjectToDependency(pyDep)); Py_INCREF(Py_None); @@ -632,7 +693,7 @@ Py::Object MetadataPy::getReplace() const { auto dependencies = getMetadataPtr()->replace(); Py::List pyDependencies; - for (const auto &d : dependencies) { + for (const auto& d : dependencies) { pyDependencies.append(dependencyToPyObject(d)); } return pyDependencies; @@ -640,34 +701,37 @@ Py::Object MetadataPy::getReplace() const void MetadataPy::setReplace(Py::Object args) { - PyObject *list = nullptr; - if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) + PyObject* list = nullptr; + if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) { throw Py::Exception(); + } getMetadataPtr()->clearReplace(); Py::List deps(list); - for (const auto &dep : deps) { + for (const auto& dep : deps) { Py::Dict pyDep(dep); getMetadataPtr()->addReplace(pyObjectToDependency(pyDep)); } } -PyObject *MetadataPy::addReplace(PyObject *args) +PyObject* MetadataPy::addReplace(PyObject* args) { - PyObject *dictionary = nullptr; - if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) + PyObject* dictionary = nullptr; + if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) { throw Py::Exception(); + } Py::Dict pyDep(dictionary); getMetadataPtr()->addReplace(pyObjectToDependency(pyDep)); Py_INCREF(Py_None); return Py_None; } -PyObject *MetadataPy::removeReplace(PyObject *args) +PyObject* MetadataPy::removeReplace(PyObject* args) { - PyObject *dictionary = nullptr; - if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) + PyObject* dictionary = nullptr; + if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dictionary)) { throw Py::Exception(); + } Py::Dict pyDep(dictionary); getMetadataPtr()->removeReplace(pyObjectToDependency(pyDep)); Py_INCREF(Py_None); @@ -680,7 +744,7 @@ Py::Object MetadataPy::getTag() const { auto tags = getMetadataPtr()->tag(); Py::List pyTags; - for (const auto &t : tags) { + for (const auto& t : tags) { pyTags.append(Py::String(t)); } return pyTags; @@ -688,33 +752,36 @@ Py::Object MetadataPy::getTag() const void MetadataPy::setTag(Py::Object args) { - PyObject *list = nullptr; - if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) + PyObject* list = nullptr; + if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) { throw Py::Exception(); + } getMetadataPtr()->clearTag(); Py::List tags(list); - for (const auto &tag : tags) { + for (const auto& tag : tags) { Py::String pyTag(tag); getMetadataPtr()->addTag(pyTag.as_std_string()); } } -PyObject *MetadataPy::addTag(PyObject *args) +PyObject* MetadataPy::addTag(PyObject* args) { - const char *tag = nullptr; - if (!PyArg_ParseTuple(args, "s", &tag)) + const char* tag = nullptr; + if (!PyArg_ParseTuple(args, "s", &tag)) { throw Py::Exception(); + } getMetadataPtr()->addTag(tag); Py_INCREF(Py_None); return Py_None; } -PyObject *MetadataPy::removeTag(PyObject *args) +PyObject* MetadataPy::removeTag(PyObject* args) { - const char *tag = nullptr; - if (!PyArg_ParseTuple(args, "s", &tag)) + const char* tag = nullptr; + if (!PyArg_ParseTuple(args, "s", &tag)) { throw Py::Exception(); + } getMetadataPtr()->removeTag(tag); Py_INCREF(Py_None); return Py_None; @@ -727,9 +794,10 @@ Py::Object MetadataPy::getIcon() const void MetadataPy::setIcon(Py::Object args) { - const char *name; - if (!PyArg_Parse(args.ptr(), "s", &name)) + const char* name; + if (!PyArg_Parse(args.ptr(), "s", &name)) { throw Py::Exception(); + } getMetadataPtr()->setIcon(name); } @@ -740,9 +808,10 @@ Py::Object MetadataPy::getClassname() const void MetadataPy::setClassname(Py::Object args) { - const char *name; - if (!PyArg_Parse(args.ptr(), "s", &name)) + const char* name; + if (!PyArg_Parse(args.ptr(), "s", &name)) { throw Py::Exception(); + } getMetadataPtr()->setClassname(name); } @@ -753,9 +822,10 @@ Py::Object MetadataPy::getSubdirectory() const void MetadataPy::setSubdirectory(Py::Object args) { - const char *name; - if (!PyArg_Parse(args.ptr(), "s", &name)) + const char* name; + if (!PyArg_Parse(args.ptr(), "s", &name)) { throw Py::Exception(); + } getMetadataPtr()->setSubdirectory(name); } @@ -763,7 +833,7 @@ Py::Object MetadataPy::getFile() const { auto files = getMetadataPtr()->file(); Py::List pyFiles; - for (const auto &f : files) { + for (const auto& f : files) { pyFiles.append(Py::String(f.string())); } return pyFiles; @@ -771,33 +841,36 @@ Py::Object MetadataPy::getFile() const void MetadataPy::setFile(Py::Object args) { - PyObject *list = nullptr; - if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) + PyObject* list = nullptr; + if (!PyArg_Parse(args.ptr(), "O!", &PyList_Type, &list)) { throw Py::Exception(); + } getMetadataPtr()->clearTag(); Py::List files(list); - for (const auto &file : files) { + for (const auto& file : files) { Py::String pyFile(file); getMetadataPtr()->addFile(pyFile.as_std_string()); } } -PyObject *MetadataPy::addFile(PyObject *args) +PyObject* MetadataPy::addFile(PyObject* args) { - const char *file = nullptr; - if (!PyArg_ParseTuple(args, "s", &file)) + const char* file = nullptr; + if (!PyArg_ParseTuple(args, "s", &file)) { throw Py::Exception(); + } getMetadataPtr()->addFile(file); Py_INCREF(Py_None); return Py_None; } -PyObject *MetadataPy::removeFile(PyObject *args) +PyObject* MetadataPy::removeFile(PyObject* args) { - const char *file = nullptr; - if (!PyArg_ParseTuple(args, "s", &file)) + const char* file = nullptr; + if (!PyArg_ParseTuple(args, "s", &file)) { throw Py::Exception(); + } getMetadataPtr()->removeFile(file); Py_INCREF(Py_None); return Py_None; @@ -808,16 +881,16 @@ Py::Object MetadataPy::getContent() const { auto content = getMetadataPtr()->content(); std::set keys; - for (const auto &item : content) { + for (const auto& item : content) { keys.insert(item.first); } // For the Python, we'll use a dictionary of lists to store the content components: Py::Dict pyContent; - for (const auto &key : keys) { + for (const auto& key : keys) { Py::List pyContentForKey; auto elements = content.equal_range(key); - for (auto &element = elements.first; element != elements.second; ++element) { + for (auto& element = elements.first; element != elements.second; ++element) { auto contentMetadataItem = new MetadataPy(new Metadata(element->second)); pyContentForKey.append(Py::asObject(contentMetadataItem)); } @@ -828,36 +901,37 @@ Py::Object MetadataPy::getContent() const void MetadataPy::setContent(Py::Object arg) { - PyObject *obj = nullptr; - if (!PyArg_Parse(arg.ptr(), "O!", &PyList_Type, &obj)) + PyObject* obj = nullptr; + if (!PyArg_Parse(arg.ptr(), "O!", &PyList_Type, &obj)) { throw Py::Exception(); + } getMetadataPtr()->clearContent(); Py::Dict outerDict(obj); - for (const auto &pyContentType : outerDict) { + for (const auto& pyContentType : outerDict) { auto contentType = Py::String(pyContentType.first).as_std_string(); auto contentList = Py::List(pyContentType.second); for (const auto& contentItem : contentList) { - auto item = static_cast(contentItem.ptr()); + auto item = static_cast(contentItem.ptr()); getMetadataPtr()->addContentItem(contentType, *(item->getMetadataPtr())); } } - } -PyObject *MetadataPy::getGenericMetadata(PyObject *args) +PyObject* MetadataPy::getGenericMetadata(PyObject* args) { - const char *name; - if (!PyArg_ParseTuple(args, "s", &name)) + const char* name; + if (!PyArg_ParseTuple(args, "s", &name)) { return nullptr; + } auto gm = (*getMetadataPtr())[name]; Py::List pyGenericMetadata; - for (const auto &item : gm) { + for (const auto& item : gm) { Py::Dict pyItem; pyItem["contents"] = Py::String(item.contents); Py::Dict pyAttributes; - for (const auto &attribute : item.attributes) { + for (const auto& attribute : item.attributes) { pyAttributes[attribute.first] = Py::String(attribute.second); } pyItem["attributes"] = pyAttributes; @@ -873,14 +947,17 @@ Py::Object MetadataPy::getFreeCADMin() const void MetadataPy::setFreeCADMin(Py::Object args) { - char *version = nullptr; - PyObject *p = args.ptr(); - if (!PyArg_Parse(p, "z", &version)) + char* version = nullptr; + PyObject* p = args.ptr(); + if (!PyArg_Parse(p, "z", &version)) { throw Py::Exception(); - if (version) + } + if (version) { getMetadataPtr()->setFreeCADMin(App::Meta::Version(version)); - else + } + else { getMetadataPtr()->setFreeCADMin(App::Meta::Version()); + } } Py::Object MetadataPy::getFreeCADMax() const @@ -890,15 +967,18 @@ Py::Object MetadataPy::getFreeCADMax() const void MetadataPy::setFreeCADMax(Py::Object args) { - char *version = nullptr; - PyObject *p = args.ptr(); - if (!PyArg_Parse(p, "z", &version)) + char* version = nullptr; + PyObject* p = args.ptr(); + if (!PyArg_Parse(p, "z", &version)) { throw Py::Exception(); + } - if (version) + if (version) { getMetadataPtr()->setFreeCADMax(App::Meta::Version(version)); - else + } + else { getMetadataPtr()->setFreeCADMax(App::Meta::Version()); + } } Py::Object MetadataPy::getPythonMin() const @@ -908,30 +988,39 @@ Py::Object MetadataPy::getPythonMin() const void MetadataPy::setPythonMin(Py::Object args) { - char *version = nullptr; - PyObject *p = args.ptr(); - if (!PyArg_Parse(p, "z", &version)) throw Py::Exception(); - if (version) getMetadataPtr()->setPythonMin(App::Meta::Version(version)); - else + char* version = nullptr; + PyObject* p = args.ptr(); + if (!PyArg_Parse(p, "z", &version)) { + throw Py::Exception(); + } + if (version) { + getMetadataPtr()->setPythonMin(App::Meta::Version(version)); + } + else { getMetadataPtr()->setPythonMin(App::Meta::Version()); + } } -PyObject *MetadataPy::getFirstSupportedFreeCADVersion(PyObject *p) +PyObject* MetadataPy::getFirstSupportedFreeCADVersion(PyObject* p) { - if (!PyArg_ParseTuple(p, "")) + if (!PyArg_ParseTuple(p, "")) { return nullptr; + } // Short-circuit: if the toplevel sets a version, then the lower-levels are overridden - if (getMetadataPtr()->freecadmin() != App::Meta::Version()) + if (getMetadataPtr()->freecadmin() != App::Meta::Version()) { return Py::new_reference_to(Py::String(getMetadataPtr()->freecadmin().str())); + } auto content = getMetadataPtr()->content(); auto result = App::Meta::Version(); - for (const auto &item : content) { + for (const auto& item : content) { auto minVersion = item.second.freecadmin(); - if (minVersion != App::Meta::Version()) - if (result == App::Meta::Version() || minVersion < result) + if (minVersion != App::Meta::Version()) { + if (result == App::Meta::Version() || minVersion < result) { result = minVersion; + } + } } if (result != App::Meta::Version()) { return Py::new_reference_to(Py::String(result.str())); @@ -942,22 +1031,26 @@ PyObject *MetadataPy::getFirstSupportedFreeCADVersion(PyObject *p) } } -PyObject *MetadataPy::getLastSupportedFreeCADVersion(PyObject *p) +PyObject* MetadataPy::getLastSupportedFreeCADVersion(PyObject* p) { - if (!PyArg_ParseTuple(p, "")) + if (!PyArg_ParseTuple(p, "")) { return nullptr; + } // Short-circuit: if the toplevel sets a version, then the lower-levels are overridden - if (getMetadataPtr()->freecadmax() != App::Meta::Version()) + if (getMetadataPtr()->freecadmax() != App::Meta::Version()) { return Py::new_reference_to(Py::String(getMetadataPtr()->freecadmax().str())); + } auto content = getMetadataPtr()->content(); auto result = App::Meta::Version(); - for (const auto &item : content) { + for (const auto& item : content) { auto maxVersion = item.second.freecadmax(); - if (maxVersion != App::Meta::Version()) - if (result == App::Meta::Version() || maxVersion > result) + if (maxVersion != App::Meta::Version()) { + if (result == App::Meta::Version() || maxVersion > result) { result = maxVersion; + } + } } if (result != App::Meta::Version()) { return Py::new_reference_to(Py::String(result.str())); @@ -968,10 +1061,11 @@ PyObject *MetadataPy::getLastSupportedFreeCADVersion(PyObject *p) } } -PyObject *MetadataPy::supportsCurrentFreeCAD(PyObject *p) +PyObject* MetadataPy::supportsCurrentFreeCAD(PyObject* p) { - if (!PyArg_ParseTuple(p, "")) + if (!PyArg_ParseTuple(p, "")) { return nullptr; + } bool result = getMetadataPtr()->supportsCurrentFreeCAD(); return Py::new_reference_to(Py::Boolean(result)); @@ -979,28 +1073,32 @@ PyObject *MetadataPy::supportsCurrentFreeCAD(PyObject *p) PyObject* MetadataPy::addContentItem(PyObject* arg) { - char *contentType = nullptr; - PyObject *contentItem = nullptr; - if (!PyArg_ParseTuple(arg, "sO!", &contentType, &(App::MetadataPy::Type), &contentItem)) + char* contentType = nullptr; + PyObject* contentItem = nullptr; + if (!PyArg_ParseTuple(arg, "sO!", &contentType, &(App::MetadataPy::Type), &contentItem)) { return nullptr; + } - if (!contentItem || !contentType) + if (!contentItem || !contentType) { return nullptr; - auto item = static_cast(contentItem); + } + auto item = static_cast(contentItem); getMetadataPtr()->addContentItem(contentType, *(item->getMetadataPtr())); Py_INCREF(Py_None); return Py_None; } -PyObject *MetadataPy::removeContentItem(PyObject *arg) +PyObject* MetadataPy::removeContentItem(PyObject* arg) { - char *contentType = nullptr; - char *contentName = nullptr; - if (!PyArg_ParseTuple(arg, "ss", &contentType, &contentName)) + char* contentType = nullptr; + char* contentName = nullptr; + if (!PyArg_ParseTuple(arg, "ss", &contentType, &contentName)) { return nullptr; - if (contentType && contentName) + } + if (contentType && contentName) { getMetadataPtr()->removeContentItem(contentType, contentName); + } Py_INCREF(Py_None); return Py_None; @@ -1008,9 +1106,10 @@ PyObject *MetadataPy::removeContentItem(PyObject *arg) PyObject* MetadataPy::write(PyObject* args) { - char *filename = nullptr; - if (!PyArg_ParseTuple(args, "s", &filename)) + char* filename = nullptr; + if (!PyArg_ParseTuple(args, "s", &filename)) { return nullptr; + } getMetadataPtr()->write(filename); Py_INCREF(Py_None); @@ -1018,12 +1117,12 @@ PyObject* MetadataPy::write(PyObject* args) } -PyObject *MetadataPy::getCustomAttributes(const char * /*attr*/) const +PyObject* MetadataPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } -int MetadataPy::setCustomAttributes(const char * /*attr*/, PyObject * /*obj*/) +int MetadataPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { return 0; } diff --git a/src/App/Origin.cpp b/src/App/Origin.cpp index a79951669a..afc3c13492 100644 --- a/src/App/Origin.cpp +++ b/src/App/Origin.cpp @@ -24,7 +24,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include @@ -36,7 +36,7 @@ #ifndef M_PI -# define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif using namespace App; @@ -44,100 +44,116 @@ using namespace App; PROPERTY_SOURCE(App::Origin, App::DocumentObject) -Origin::Origin() : extension(this) { - ADD_PROPERTY_TYPE ( OriginFeatures, (nullptr), 0, App::Prop_Hidden, - "Axis and baseplanes controlled by the origin" ); +Origin::Origin() + : extension(this) +{ + ADD_PROPERTY_TYPE(OriginFeatures, + (nullptr), + 0, + App::Prop_Hidden, + "Axis and baseplanes controlled by the origin"); - setStatus(App::NoAutoExpand,true); + setStatus(App::NoAutoExpand, true); extension.initExtension(this); } Origin::~Origin() = default; -App::OriginFeature *Origin::getOriginFeature( const char *role) const { - const auto & features = OriginFeatures.getValues (); - auto featIt = std::find_if (features.begin(), features.end(), - [role] (App::DocumentObject *obj) { - return obj->isDerivedFrom ( App::OriginFeature::getClassTypeId () ) && - strcmp (static_cast(obj)->Role.getValue(), role) == 0; - } ); +App::OriginFeature* Origin::getOriginFeature(const char* role) const +{ + const auto& features = OriginFeatures.getValues(); + auto featIt = std::find_if(features.begin(), features.end(), [role](App::DocumentObject* obj) { + return obj->isDerivedFrom(App::OriginFeature::getClassTypeId()) + && strcmp(static_cast(obj)->Role.getValue(), role) == 0; + }); if (featIt != features.end()) { - return static_cast(*featIt); - } else { + return static_cast(*featIt); + } + else { std::stringstream err; - err << "Origin \"" << getFullName () << "\" doesn't contain feature with role \"" - << role << '"'; - throw Base::RuntimeError ( err.str().c_str () ); + err << "Origin \"" << getFullName() << "\" doesn't contain feature with role \"" << role + << '"'; + throw Base::RuntimeError(err.str().c_str()); } } -App::Line *Origin::getAxis( const char *role ) const { - App::OriginFeature *feat = getOriginFeature (role); - if ( feat->isDerivedFrom(App::Line::getClassTypeId () ) ) { - return static_cast (feat); - } else { +App::Line* Origin::getAxis(const char* role) const +{ + App::OriginFeature* feat = getOriginFeature(role); + if (feat->isDerivedFrom(App::Line::getClassTypeId())) { + return static_cast(feat); + } + else { std::stringstream err; - err << "Origin \"" << getFullName () << "\" contains bad Axis object for role \"" - << role << '"'; - throw Base::RuntimeError ( err.str().c_str () ); + err << "Origin \"" << getFullName() << "\" contains bad Axis object for role \"" << role + << '"'; + throw Base::RuntimeError(err.str().c_str()); } } -App::Plane *Origin::getPlane( const char *role ) const { - App::OriginFeature *feat = getOriginFeature (role); - if ( feat->isDerivedFrom(App::Plane::getClassTypeId () ) ) { - return static_cast (feat); - } else { +App::Plane* Origin::getPlane(const char* role) const +{ + App::OriginFeature* feat = getOriginFeature(role); + if (feat->isDerivedFrom(App::Plane::getClassTypeId())) { + return static_cast(feat); + } + else { std::stringstream err; - err << "Origin \"" << getFullName () << "\" contains bad Plane object for role \"" - << role << '"'; - throw Base::RuntimeError ( err.str().c_str () ); + err << "Origin \"" << getFullName() << "\" contains bad Plane object for role \"" << role + << '"'; + throw Base::RuntimeError(err.str().c_str()); } } -bool Origin::hasObject (const DocumentObject *obj) const { - const auto & features = OriginFeatures.getValues (); - return std::find (features.begin(), features.end(), obj) != features.end (); +bool Origin::hasObject(const DocumentObject* obj) const +{ + const auto& features = OriginFeatures.getValues(); + return std::find(features.begin(), features.end(), obj) != features.end(); } -short Origin::mustExecute() const { - if (OriginFeatures.isTouched ()) { +short Origin::mustExecute() const +{ + if (OriginFeatures.isTouched()) { return 1; - } else { + } + else { return DocumentObject::mustExecute(); } } -App::DocumentObjectExecReturn *Origin::execute() { - try { // try to find all base axis and planes in the origin - for (const char* role: AxisRoles) { - App::Line *axis = getAxis (role); +App::DocumentObjectExecReturn* Origin::execute() +{ + try { // try to find all base axis and planes in the origin + for (const char* role : AxisRoles) { + App::Line* axis = getAxis(role); assert(axis); (void)axis; } - for (const char* role: PlaneRoles) { - App::Plane *plane = getPlane (role); + for (const char* role : PlaneRoles) { + App::Plane* plane = getPlane(role); assert(plane); (void)plane; } - } catch (const Base::Exception &ex) { - setError (); - return new App::DocumentObjectExecReturn ( ex.what () ); + } + catch (const Base::Exception& ex) { + setError(); + return new App::DocumentObjectExecReturn(ex.what()); } - return DocumentObject::execute (); + return DocumentObject::execute(); } -void Origin::setupObject () { - const static struct { +void Origin::setupObject() +{ + const static struct + { const Base::Type type; - const char *role; - const QString label; + const char* role; + const QString label; Base::Rotation rot; - } - setupData [] = { + } setupData[] = { // clang-format off {App::Line::getClassTypeId(), AxisRoles[0], tr("X-axis"), Base::Rotation()}, {App::Line::getClassTypeId(), AxisRoles[1], tr("Y-axis"), Base::Rotation(Base::Vector3d(1,1,1), M_PI*2/3)}, @@ -148,39 +164,40 @@ void Origin::setupObject () { // clang-format on }; - App::Document *doc = getDocument (); + App::Document* doc = getDocument(); - std::vector links; - for (auto data: setupData) { - std::string objName = doc->getUniqueObjectName ( data.role ); - App::DocumentObject *featureObj = doc->addObject ( data.type.getName(), objName.c_str () ); + std::vector links; + for (auto data : setupData) { + std::string objName = doc->getUniqueObjectName(data.role); + App::DocumentObject* featureObj = doc->addObject(data.type.getName(), objName.c_str()); - assert ( featureObj && featureObj->isDerivedFrom ( App::OriginFeature::getClassTypeId () ) ); + assert(featureObj && featureObj->isDerivedFrom(App::OriginFeature::getClassTypeId())); - QByteArray byteArray = data.label.toUtf8(); + QByteArray byteArray = data.label.toUtf8(); featureObj->Label.setValue(byteArray.constData()); - App::OriginFeature *feature = static_cast ( featureObj ); - feature->Placement.setValue ( Base::Placement ( Base::Vector3d (), data.rot ) ); - feature->Role.setValue ( data.role ); + App::OriginFeature* feature = static_cast(featureObj); + feature->Placement.setValue(Base::Placement(Base::Vector3d(), data.rot)); + feature->Role.setValue(data.role); - links.push_back (feature); + links.push_back(feature); } - OriginFeatures.setValues (links); + OriginFeatures.setValues(links); } -void Origin::unsetupObject () { - const auto &objsLnk = OriginFeatures.getValues (); +void Origin::unsetupObject() +{ + const auto& objsLnk = OriginFeatures.getValues(); // Copy to set to assert we won't call methode more then one time for each object - std::set objs (objsLnk.begin(), objsLnk.end()); + std::set objs(objsLnk.begin(), objsLnk.end()); // Remove all controlled objects - for (auto obj: objs ) { + for (auto obj : objs) { // Check that previous deletes wasn't inderectly removed one of our objects - const auto &objsLnk = OriginFeatures.getValues (); - if ( std::find(objsLnk.begin(), objsLnk.end(), obj) != objsLnk.end()) { - if ( ! obj->isRemoving() ) { - obj->getDocument()->removeObject (obj->getNameInDocument()); + const auto& objsLnk = OriginFeatures.getValues(); + if (std::find(objsLnk.begin(), objsLnk.end(), obj) != objsLnk.end()) { + if (!obj->isRemoving()) { + obj->getDocument()->removeObject(obj->getNameInDocument()); } } } @@ -194,19 +211,25 @@ Origin::OriginExtension::OriginExtension(Origin* obj) Group.setStatus(Property::Transient, true); } -void Origin::OriginExtension::initExtension(ExtensionContainer* obj) { +void Origin::OriginExtension::initExtension(ExtensionContainer* obj) +{ App::GroupExtension::initExtension(obj); } -bool Origin::OriginExtension::extensionGetSubObject(DocumentObject *&ret, const char *subname, - PyObject **pyobj, Base::Matrix4D *mat, bool, int depth) const { +bool Origin::OriginExtension::extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject** pyobj, + Base::Matrix4D* mat, + bool, + int depth) const +{ if (!subname || subname[0] == '\0') { return false; } // mapping of object name to role name std::string name(subname); - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { if (name.rfind(Origin::AxisRoles[i], 0) == 0) { name = Origin::AxisRoles[i]; break; @@ -219,14 +242,17 @@ bool Origin::OriginExtension::extensionGetSubObject(DocumentObject *&ret, const try { ret = obj->getOriginFeature(name.c_str()); - if (!ret) + if (!ret) { return false; - const char *dot = strchr(subname, '.'); - if (dot) - subname = dot+1; - else + } + const char* dot = strchr(subname, '.'); + if (dot) { + subname = dot + 1; + } + else { subname = ""; - ret = ret->getSubObject(subname, pyobj, mat, true, depth+1); + } + ret = ret->getSubObject(subname, pyobj, mat, true, depth + 1); return true; } catch (const Base::Exception& e) { diff --git a/src/App/Origin.h b/src/App/Origin.h index ff4d1372aa..0f7f2110e4 100644 --- a/src/App/Origin.h +++ b/src/App/Origin.h @@ -35,7 +35,7 @@ namespace App /** Base class of all geometric document objects. */ -class AppExport Origin : public App::DocumentObject +class AppExport Origin: public App::DocumentObject { PROPERTY_HEADER_WITH_OVERRIDE(App::Origin); Q_DECLARE_TR_FUNCTIONS(App::Origin) @@ -46,7 +46,8 @@ public: ~Origin() override; /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderOrigin"; } @@ -56,58 +57,67 @@ public: */ ///@{ // returns X axis - App::Line *getX () const { - return getAxis (AxisRoles[0]); + App::Line* getX() const + { + return getAxis(AxisRoles[0]); } // returns Y axis - App::Line *getY () const { - return getAxis (AxisRoles[1]); + App::Line* getY() const + { + return getAxis(AxisRoles[1]); } // returns Z axis - App::Line *getZ () const { - return getAxis (AxisRoles[2]); + App::Line* getZ() const + { + return getAxis(AxisRoles[2]); } // returns XY plane - App::Plane *getXY () const { - return getPlane (PlaneRoles[0]); + App::Plane* getXY() const + { + return getPlane(PlaneRoles[0]); } // returns XZ plane - App::Plane *getXZ () const { - return getPlane (PlaneRoles[1]); + App::Plane* getXZ() const + { + return getPlane(PlaneRoles[1]); } // returns YZ plane - App::Plane *getYZ () const { - return getPlane (PlaneRoles[2]); + App::Plane* getYZ() const + { + return getPlane(PlaneRoles[2]); } /// Returns all axis objects to iterate on them - std::vector axes() const { - return { getX(), getY(), getZ() }; + std::vector axes() const + { + return {getX(), getY(), getZ()}; } /// Returns all base planes objects to iterate on them - std::vector planes() const { - return { getXY(), getXZ(), getYZ() }; + std::vector planes() const + { + return {getXY(), getXZ(), getYZ()}; } /// Returns all controlled objects (both planes and axis) to iterate on them - std::vector baseObjects() const { - return { getX(), getY(), getZ(), getXY(), getXZ(), getYZ() }; + std::vector baseObjects() const + { + return {getX(), getY(), getZ(), getXY(), getXZ(), getYZ()}; } /// Returns an axis by it's name - App::OriginFeature *getOriginFeature( const char* role ) const; + App::OriginFeature* getOriginFeature(const char* role) const; /// Returns an axis by it's name - App::Line *getAxis( const char* role ) const; + App::Line* getAxis(const char* role) const; /// Returns an axis by it's name - App::Plane *getPlane( const char* role ) const; + App::Plane* getPlane(const char* role) const; ///@} /// Returns true if the given object is part of the origin - bool hasObject (const DocumentObject *obj) const; + bool hasObject(const DocumentObject* obj) const; /// Returns the default bounding box of the origin (use this if you confused what should be s ) // TODO Delete me if not really needed (2015-09-01, Fat-Zer) @@ -126,27 +136,33 @@ public: protected: /// Checks integrity of the Origin - App::DocumentObjectExecReturn *execute() override; + App::DocumentObjectExecReturn* execute() override; /// Creates all corresponding Axes and Planes objects for the origin if they aren't linked yet - void setupObject () override; + void setupObject() override; /// Removes all planes and axis if they are still linked to the document - void unsetupObject () override; + void unsetupObject() override; private: struct SetupData; - void setupOriginFeature (App::PropertyLink &featProp, const SetupData &data); + void setupOriginFeature(App::PropertyLink& featProp, const SetupData& data); - class OriginExtension : public GeoFeatureGroupExtension { + class OriginExtension: public GeoFeatureGroupExtension + { Origin* obj; + public: explicit OriginExtension(Origin* obj); void initExtension(ExtensionContainer* obj) override; - bool extensionGetSubObject(DocumentObject *&ret, const char *subname, - PyObject **, Base::Matrix4D *, bool, int) const override; + bool extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject**, + Base::Matrix4D*, + bool, + int) const override; }; OriginExtension extension; }; -} //namespace App +} // namespace App -#endif // APP_Origin_H +#endif // APP_Origin_H diff --git a/src/App/OriginFeature.cpp b/src/App/OriginFeature.cpp index 2171207687..a3b79e000c 100644 --- a/src/App/OriginFeature.cpp +++ b/src/App/OriginFeature.cpp @@ -35,7 +35,7 @@ PROPERTY_SOURCE(App::Line, App::OriginFeature) OriginFeature::OriginFeature() { - ADD_PROPERTY_TYPE ( Role, (""), 0, App::Prop_ReadOnly, "Role of the feature in the Origin" ) ; + ADD_PROPERTY_TYPE(Role, (""), 0, App::Prop_ReadOnly, "Role of the feature in the Origin"); // Set placement to read-only Placement.setStatus(Property::Hidden, true); @@ -43,18 +43,20 @@ OriginFeature::OriginFeature() OriginFeature::~OriginFeature() = default; -Origin * OriginFeature::getOrigin () { - App::Document *doc = getDocument(); - auto origins = doc->getObjectsOfType ( App::Origin::getClassTypeId() ); +Origin* OriginFeature::getOrigin() +{ + App::Document* doc = getDocument(); + auto origins = doc->getObjectsOfType(App::Origin::getClassTypeId()); - auto originIt= std::find_if (origins.begin(), origins.end(), [this] (DocumentObject *origin) { - assert ( origin->isDerivedFrom ( App::Origin::getClassTypeId() ) ); - return static_cast (origin)->hasObject (this); - } ); + auto originIt = std::find_if(origins.begin(), origins.end(), [this](DocumentObject* origin) { + assert(origin->isDerivedFrom(App::Origin::getClassTypeId())); + return static_cast(origin)->hasObject(this); + }); if (originIt == origins.end()) { return nullptr; - } else { - assert ( (*originIt)->isDerivedFrom ( App::Origin::getClassTypeId() ) ); - return static_cast (*originIt); + } + else { + assert((*originIt)->isDerivedFrom(App::Origin::getClassTypeId())); + return static_cast(*originIt); } } diff --git a/src/App/OriginFeature.h b/src/App/OriginFeature.h index e8dc7fa22d..f499da900f 100644 --- a/src/App/OriginFeature.h +++ b/src/App/OriginFeature.h @@ -36,6 +36,7 @@ class Origin; class AppExport OriginFeature: public App::GeoFeature { PROPERTY_HEADER_WITH_OVERRIDE(App::OriginFeature); + public: /// additional information about the feature usage (e.g. "BasePlane-XY" or "Axis-X" in a Origin) PropertyString Role; @@ -45,25 +46,31 @@ public: ~OriginFeature() override; /// Finds the origin object this plane belongs to - App::Origin *getOrigin (); + App::Origin* getOrigin(); }; -class AppExport Plane: public App::OriginFeature { +class AppExport Plane: public App::OriginFeature +{ PROPERTY_HEADER_WITH_OVERRIDE(App::OriginFeature); + public: - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderPlane"; } }; -class AppExport Line: public App::OriginFeature { +class AppExport Line: public App::OriginFeature +{ PROPERTY_HEADER_WITH_OVERRIDE(App::OriginFeature); + public: - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderLine"; } }; -} //namespace App +} // namespace App #endif /* end of include guard: ORIGINFEATURE_H */ diff --git a/src/App/OriginGroupExtension.cpp b/src/App/OriginGroupExtension.cpp index 077c0e262f..ed7ad3547b 100644 --- a/src/App/OriginGroupExtension.cpp +++ b/src/App/OriginGroupExtension.cpp @@ -38,139 +38,172 @@ using namespace App; EXTENSION_PROPERTY_SOURCE(App::OriginGroupExtension, App::GeoFeatureGroupExtension) -OriginGroupExtension::OriginGroupExtension () { +OriginGroupExtension::OriginGroupExtension() +{ initExtensionType(OriginGroupExtension::getExtensionClassTypeId()); - EXTENSION_ADD_PROPERTY_TYPE ( Origin, (nullptr), 0, App::Prop_Hidden, "Origin linked to the group" ); + EXTENSION_ADD_PROPERTY_TYPE(Origin, + (nullptr), + 0, + App::Prop_Hidden, + "Origin linked to the group"); Origin.setScope(LinkScope::Child); } -OriginGroupExtension::~OriginGroupExtension () = default; +OriginGroupExtension::~OriginGroupExtension() = default; -App::Origin *OriginGroupExtension::getOrigin () const { - App::DocumentObject *originObj = Origin.getValue (); +App::Origin* OriginGroupExtension::getOrigin() const +{ + App::DocumentObject* originObj = Origin.getValue(); - if ( !originObj ) { + if (!originObj) { std::stringstream err; - err << "Can't find Origin for \"" << getExtendedObject()->getFullName () << "\""; - throw Base::RuntimeError ( err.str().c_str () ); - - } else if (! originObj->isDerivedFrom ( App::Origin::getClassTypeId() ) ) { + err << "Can't find Origin for \"" << getExtendedObject()->getFullName() << "\""; + throw Base::RuntimeError(err.str().c_str()); + } + else if (!originObj->isDerivedFrom(App::Origin::getClassTypeId())) { std::stringstream err; - err << "Bad object \"" << originObj->getFullName () << "\"(" << originObj->getTypeId().getName() - << ") linked to the Origin of \"" << getExtendedObject()->getFullName () << "\""; - throw Base::RuntimeError ( err.str().c_str () ); - } else { - return static_cast ( originObj ); + err << "Bad object \"" << originObj->getFullName() << "\"(" + << originObj->getTypeId().getName() << ") linked to the Origin of \"" + << getExtendedObject()->getFullName() << "\""; + throw Base::RuntimeError(err.str().c_str()); + } + else { + return static_cast(originObj); } } -bool OriginGroupExtension::extensionGetSubObject(DocumentObject *&ret, const char *subname, - PyObject **pyObj, Base::Matrix4D *mat, bool transform, int depth) const +bool OriginGroupExtension::extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject** pyObj, + Base::Matrix4D* mat, + bool transform, + int depth) const { - App::DocumentObject *originObj = Origin.getValue (); - const char *dot; - if(originObj && originObj->isAttachedToDocument() && - subname && (dot=strchr(subname,'.'))) - { + App::DocumentObject* originObj = Origin.getValue(); + const char* dot; + if (originObj && originObj->isAttachedToDocument() && subname && (dot = strchr(subname, '.'))) { bool found; - if(subname[0] == '$') - found = std::string(subname+1,dot)==originObj->Label.getValue(); - else - found = std::string(subname,dot)==originObj->getNameInDocument(); - if(found) { - if(mat && transform) + if (subname[0] == '$') { + found = std::string(subname + 1, dot) == originObj->Label.getValue(); + } + else { + found = std::string(subname, dot) == originObj->getNameInDocument(); + } + if (found) { + if (mat && transform) { *mat *= const_cast(this)->placement().getValue().toMatrix(); - ret = originObj->getSubObject(dot+1,pyObj,mat,true,depth+1); + } + ret = originObj->getSubObject(dot + 1, pyObj, mat, true, depth + 1); return true; } } - return GeoFeatureGroupExtension::extensionGetSubObject(ret,subname,pyObj,mat,transform,depth); + return GeoFeatureGroupExtension::extensionGetSubObject(ret, + subname, + pyObj, + mat, + transform, + depth); } -App::DocumentObject *OriginGroupExtension::getGroupOfObject (const DocumentObject* obj) { +App::DocumentObject* OriginGroupExtension::getGroupOfObject(const DocumentObject* obj) +{ - if(!obj) + if (!obj) { return nullptr; + } bool isOriginFeature = obj->isDerivedFrom(App::OriginFeature::getClassTypeId()); auto list = obj->getInList(); for (auto o : list) { - if(o->hasExtension(App::OriginGroupExtension::getExtensionClassTypeId())) + if (o->hasExtension(App::OriginGroupExtension::getExtensionClassTypeId())) { return o; + } else if (isOriginFeature && o->isDerivedFrom(App::Origin::getClassTypeId())) { auto result = getGroupOfObject(o); - if(result) + if (result) { return result; + } } } return nullptr; } -short OriginGroupExtension::extensionMustExecute() { - if (Origin.isTouched ()) { +short OriginGroupExtension::extensionMustExecute() +{ + if (Origin.isTouched()) { return 1; - } else { + } + else { return GeoFeatureGroupExtension::extensionMustExecute(); } } -App::DocumentObjectExecReturn *OriginGroupExtension::extensionExecute() { - try { // try to find all base axis and planes in the origin - getOrigin (); - } catch (const Base::Exception &ex) { - //getExtendedObject()->setError (); - return new App::DocumentObjectExecReturn ( ex.what () ); +App::DocumentObjectExecReturn* OriginGroupExtension::extensionExecute() +{ + try { // try to find all base axis and planes in the origin + getOrigin(); + } + catch (const Base::Exception& ex) { + // getExtendedObject()->setError (); + return new App::DocumentObjectExecReturn(ex.what()); } - return GeoFeatureGroupExtension::extensionExecute (); + return GeoFeatureGroupExtension::extensionExecute(); } -App::DocumentObject *OriginGroupExtension::getLocalizedOrigin(App::Document *doc) { - App::DocumentObject *originObject = doc->addObject ( "App::Origin", "Origin" ); +App::DocumentObject* OriginGroupExtension::getLocalizedOrigin(App::Document* doc) +{ + App::DocumentObject* originObject = doc->addObject("App::Origin", "Origin"); QByteArray byteArray = tr("Origin").toUtf8(); originObject->Label.setValue(byteArray.constData()); return originObject; } -void OriginGroupExtension::onExtendedSetupObject () { - App::Document *doc = getExtendedObject()->getDocument (); +void OriginGroupExtension::onExtendedSetupObject() +{ + App::Document* doc = getExtendedObject()->getDocument(); - App::DocumentObject *originObj = getLocalizedOrigin(doc); + App::DocumentObject* originObj = getLocalizedOrigin(doc); - assert ( originObj && originObj->isDerivedFrom ( App::Origin::getClassTypeId () ) ); - Origin.setValue (originObj); + assert(originObj && originObj->isDerivedFrom(App::Origin::getClassTypeId())); + Origin.setValue(originObj); - GeoFeatureGroupExtension::onExtendedSetupObject (); + GeoFeatureGroupExtension::onExtendedSetupObject(); } -void OriginGroupExtension::onExtendedUnsetupObject () { - App::DocumentObject *origin = Origin.getValue (); - if (origin && !origin->isRemoving ()) { - origin->getDocument ()->removeObject (origin->getNameInDocument()); +void OriginGroupExtension::onExtendedUnsetupObject() +{ + App::DocumentObject* origin = Origin.getValue(); + if (origin && !origin->isRemoving()) { + origin->getDocument()->removeObject(origin->getNameInDocument()); } - GeoFeatureGroupExtension::onExtendedUnsetupObject (); + GeoFeatureGroupExtension::onExtendedUnsetupObject(); } -void OriginGroupExtension::extensionOnChanged(const Property* p) { - if(p == &Origin) { - App::DocumentObject *owner = getExtendedObject(); - App::DocumentObject *origin = Origin.getValue(); +void OriginGroupExtension::extensionOnChanged(const Property* p) +{ + if (p == &Origin) { + App::DocumentObject* owner = getExtendedObject(); + App::DocumentObject* origin = Origin.getValue(); // Document::Importing indicates the object is being imported (i.e. // copied). So check the Origin ownership here to prevent copy without // dependency if (origin && owner && owner->getDocument() - && owner->getDocument()->testStatus(Document::Importing)) { + && owner->getDocument()->testStatus(Document::Importing)) { for (auto o : origin->getInList()) { - if(o != owner && o->hasExtension(App::OriginGroupExtension::getExtensionClassTypeId())) { - App::Document *document = owner->getDocument(); - // Temporarily reset 'Restoring' status to allow document to auto label new objects - Base::ObjectStatusLocker guard( - Document::Restoring, document, false); + if (o != owner + && o->hasExtension(App::OriginGroupExtension::getExtensionClassTypeId())) { + App::Document* document = owner->getDocument(); + // Temporarily reset 'Restoring' status to allow document to auto label new + // objects + Base::ObjectStatusLocker guard(Document::Restoring, + document, + false); Origin.setValue(getLocalizedOrigin(document)); FC_WARN("Reset origin in " << owner->getFullName()); return; @@ -183,83 +216,99 @@ void OriginGroupExtension::extensionOnChanged(const Property* p) { void OriginGroupExtension::relinkToOrigin(App::DocumentObject* obj) { - //we get all links and replace the origin objects if needed (subnames need not to change, they - //would stay the same) - std::vector< App::DocumentObject* > result; + // we get all links and replace the origin objects if needed (subnames need not to change, they + // would stay the same) + std::vector result; std::vector list; obj->getPropertyList(list); - for(App::Property* prop : list) { - if(prop->isDerivedFrom()) { + for (App::Property* prop : list) { + if (prop->isDerivedFrom()) { auto p = static_cast(prop); - if(!p->getValue() || !p->getValue()->isDerivedFrom(App::OriginFeature::getClassTypeId())) + if (!p->getValue() + || !p->getValue()->isDerivedFrom(App::OriginFeature::getClassTypeId())) { continue; + } - p->setValue(getOrigin()->getOriginFeature(static_cast(p->getValue())->Role.getValue())); + p->setValue(getOrigin()->getOriginFeature( + static_cast(p->getValue())->Role.getValue())); } - else if(prop->isDerivedFrom()) { + else if (prop->isDerivedFrom()) { auto p = static_cast(prop); auto vec = p->getValues(); std::vector result; bool changed = false; - for(App::DocumentObject* o : vec) { - if(!o || !o->isDerivedFrom(App::OriginFeature::getClassTypeId())) + for (App::DocumentObject* o : vec) { + if (!o || !o->isDerivedFrom(App::OriginFeature::getClassTypeId())) { result.push_back(o); + } else { - result.push_back(getOrigin()->getOriginFeature(static_cast(o)->Role.getValue())); + result.push_back(getOrigin()->getOriginFeature( + static_cast(o)->Role.getValue())); changed = true; } } - if(changed) + if (changed) { static_cast(prop)->setValues(result); + } } - else if(prop->isDerivedFrom()) { + else if (prop->isDerivedFrom()) { auto p = static_cast(prop); - if(!p->getValue() || !p->getValue()->isDerivedFrom(App::OriginFeature::getClassTypeId())) + if (!p->getValue() + || !p->getValue()->isDerivedFrom(App::OriginFeature::getClassTypeId())) { continue; + } std::vector subValues = p->getSubValues(); - p->setValue(getOrigin()->getOriginFeature(static_cast(p->getValue())->Role.getValue()), subValues); + p->setValue(getOrigin()->getOriginFeature( + static_cast(p->getValue())->Role.getValue()), + subValues); } - else if(prop->isDerivedFrom()) { + else if (prop->isDerivedFrom()) { auto p = static_cast(prop); auto vec = p->getSubListValues(); bool changed = false; - for(auto &v : vec) { - if(v.first && v.first->isDerivedFrom(App::OriginFeature::getClassTypeId())) { - v.first = getOrigin()->getOriginFeature(static_cast(v.first)->Role.getValue()); + for (auto& v : vec) { + if (v.first && v.first->isDerivedFrom(App::OriginFeature::getClassTypeId())) { + v.first = getOrigin()->getOriginFeature( + static_cast(v.first)->Role.getValue()); changed = true; } } - if(changed) + if (changed) { p->setSubListValues(vec); + } } } } -std::vector< DocumentObject* > OriginGroupExtension::addObjects(std::vector objs) { +std::vector OriginGroupExtension::addObjects(std::vector objs) +{ - for(auto obj : objs) + for (auto obj : objs) { relinkToOrigin(obj); + } return App::GeoFeatureGroupExtension::addObjects(objs); } -bool OriginGroupExtension::hasObject(const DocumentObject* obj, bool recursive) const { +bool OriginGroupExtension::hasObject(const DocumentObject* obj, bool recursive) const +{ - if(Origin.getValue() && (obj == getOrigin() || getOrigin()->hasObject(obj))) + if (Origin.getValue() && (obj == getOrigin() || getOrigin()->hasObject(obj))) { return true; + } return App::GroupExtension::hasObject(obj, recursive); } - // Python feature --------------------------------------------------------- -namespace App { +namespace App +{ EXTENSION_PROPERTY_SOURCE_TEMPLATE(App::OriginGroupExtensionPython, App::OriginGroupExtension) // explicit template instantiation template class AppExport ExtensionPythonT>; -} +} // namespace App diff --git a/src/App/OriginGroupExtension.h b/src/App/OriginGroupExtension.h index 58a0341c98..779c67d783 100644 --- a/src/App/OriginGroupExtension.h +++ b/src/App/OriginGroupExtension.h @@ -26,26 +26,28 @@ #include "GeoFeatureGroupExtension.h" #include "QCoreApplication" -namespace App { +namespace App +{ class Origin; /** * Represents an abstract placeable group of objects with an associated Origin */ -class AppExport OriginGroupExtension : public App::GeoFeatureGroupExtension +class AppExport OriginGroupExtension: public App::GeoFeatureGroupExtension { EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::OriginGroupExtension); Q_DECLARE_TR_FUNCTIONS(App::OriginGroupExtension) public: - OriginGroupExtension (); - ~OriginGroupExtension () override; + OriginGroupExtension(); + ~OriginGroupExtension() override; /// Returns the origin link or throws an exception - App::Origin *getOrigin () const; + App::Origin* getOrigin() const; /// returns the type name of the ViewProvider - virtual const char* getViewProviderName () const { + virtual const char* getViewProviderName() const + { return "Gui::ViewProviderOriginGroup"; } @@ -54,10 +56,10 @@ public: * In case this object is not part of any geoFeatureGroup, 0 is returned. * @param obj the object to search for */ - static DocumentObject* getGroupOfObject (const DocumentObject* obj); + static DocumentObject* getGroupOfObject(const DocumentObject* obj); /// Returns true on changing OriginFeature set - short extensionMustExecute () override; + short extensionMustExecute() override; /// Origin linked to the group PropertyLink Origin; @@ -68,26 +70,30 @@ public: std::vector addObjects(std::vector obj) override; bool hasObject(const DocumentObject* obj, bool recursive = false) const override; - bool extensionGetSubObject(DocumentObject *&ret, const char *subname, PyObject **pyObj, - Base::Matrix4D *mat, bool transform, int depth) const override; + bool extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject** pyObj, + Base::Matrix4D* mat, + bool transform, + int depth) const override; void extensionOnChanged(const Property* p) override; protected: /// Checks integrity of the Origin - App::DocumentObjectExecReturn *extensionExecute () override; + App::DocumentObjectExecReturn* extensionExecute() override; /// Creates the corresponding Origin object - void onExtendedSetupObject () override; + void onExtendedSetupObject() override; /// Removes all planes and axis if they are still linked to the document - void onExtendedUnsetupObject () override; + void onExtendedUnsetupObject() override; private: /// Creates a localized Origin object - App::DocumentObject *getLocalizedOrigin(App::Document *doc); + App::DocumentObject* getLocalizedOrigin(App::Document* doc); }; using OriginGroupExtensionPython = ExtensionPythonT>; -} /* App */ +} // namespace App #endif /* end of include guard: ORIGINGROUP_H_QHTU73IF */ diff --git a/src/App/OriginGroupExtensionPy.xml b/src/App/OriginGroupExtensionPy.xml index 8a44fa579d..2b66cdf7f5 100644 --- a/src/App/OriginGroupExtensionPy.xml +++ b/src/App/OriginGroupExtensionPy.xml @@ -16,4 +16,3 @@ - diff --git a/src/App/OriginGroupExtensionPyImp.cpp b/src/App/OriginGroupExtensionPyImp.cpp index a7fc7c3870..f4021550ce 100644 --- a/src/App/OriginGroupExtensionPyImp.cpp +++ b/src/App/OriginGroupExtensionPyImp.cpp @@ -35,7 +35,7 @@ std::string OriginGroupExtensionPy::representation() const return {""}; } -PyObject *OriginGroupExtensionPy::getCustomAttributes(const char* /*attr*/) const +PyObject* OriginGroupExtensionPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } @@ -44,5 +44,3 @@ int OriginGroupExtensionPy::setCustomAttributes(const char* /*attr*/, PyObject* { return 0; } - - diff --git a/src/App/Part.cpp b/src/App/Part.cpp index 07e80a78ee..68feeaa88b 100644 --- a/src/App/Part.cpp +++ b/src/App/Part.cpp @@ -42,7 +42,7 @@ PROPERTY_SOURCE_WITH_EXTENSIONS(App::Part, App::GeoFeature) Part::Part() { - ADD_PROPERTY(Type,("")); + ADD_PROPERTY(Type, ("")); ADD_PROPERTY_TYPE(Material, (nullptr), 0, App::Prop_None, "The Material for this Part"); ADD_PROPERTY_TYPE(Meta, (), 0, App::Prop_None, "Map with additional meta information"); @@ -62,22 +62,25 @@ Part::Part() Part::~Part() = default; -static App::Part *_getPartOfObject(const DocumentObject *obj, - std::set *objset) +static App::Part* _getPartOfObject(const DocumentObject* obj, + std::set* objset) { // as a Part is a geofeaturegroup it must directly link to all // objects it contains, even if they are in additional groups etc. // But we still must call 'hasObject()' to exclude link brought in by // expressions. for (auto inObj : obj->getInList()) { - if (objset && !objset->insert(inObj).second) + if (objset && !objset->insert(inObj).second) { continue; + } auto group = inObj->getExtensionByType(true); - if(group && group->hasObject(obj)) { - if(inObj->isDerivedFrom(App::Part::getClassTypeId())) + if (group && group->hasObject(obj)) { + if (inObj->isDerivedFrom(App::Part::getClassTypeId())) { return static_cast(inObj); - else if (objset) + } + else if (objset) { return _getPartOfObject(inObj, objset); + } // Only one parent geofeature group per object, so break break; } @@ -86,35 +89,41 @@ static App::Part *_getPartOfObject(const DocumentObject *obj, return nullptr; } -App::Part *Part::getPartOfObject (const DocumentObject* obj, bool recursive) { - if (!recursive) +App::Part* Part::getPartOfObject(const DocumentObject* obj, bool recursive) +{ + if (!recursive) { return _getPartOfObject(obj, nullptr); - std::set objset; + } + std::set objset; objset.insert(obj); return _getPartOfObject(obj, &objset); } -PyObject *Part::getPyObject() +PyObject* Part::getPyObject() { - if (PythonObject.is(Py::_None())){ + if (PythonObject.is(Py::_None())) { // ref counter is set to 1 - PythonObject = Py::Object(new PartPy(this),true); + PythonObject = Py::Object(new PartPy(this), true); } return Py::new_reference_to(PythonObject); } -void Part::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop) +void Part::handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) { // Migrate Material from App::PropertyMap to App::PropertyLink if (!strcmp(TypeName, "App::PropertyMap")) { App::PropertyMap oldvalue; oldvalue.Restore(reader); if (oldvalue.getSize()) { - auto oldprop = static_cast(addDynamicProperty("App::PropertyMap", "Material_old", "Base")); + auto oldprop = static_cast( + addDynamicProperty("App::PropertyMap", "Material_old", "Base")); oldprop->setValues(oldvalue.getValues()); } - } else { + } + else { App::GeoFeature::handleChangedPropertyType(reader, TypeName, prop); } } @@ -124,21 +133,21 @@ void Part::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeNa // Not quite sure yet making Part derivable in Python is good Idea! // JR 2014 -//namespace App { +// namespace App { ///// @cond DOXERR -//PROPERTY_SOURCE_TEMPLATE(App::PartPython, App::Part) -//template<> const char* App::PartPython::getViewProviderName(void) const { -// return "Gui::ViewProviderPartPython"; -//} -//template<> PyObject* App::PartPython::getPyObject(void) { -// if (PythonObject.is(Py::_None())) { -// // ref counter is set to 1 -// PythonObject = Py::Object(new FeaturePythonPyT(this),true); -// } -// return Py::new_reference_to(PythonObject); -//} +// PROPERTY_SOURCE_TEMPLATE(App::PartPython, App::Part) +// template<> const char* App::PartPython::getViewProviderName(void) const { +// return "Gui::ViewProviderPartPython"; +// } +// template<> PyObject* App::PartPython::getPyObject(void) { +// if (PythonObject.is(Py::_None())) { +// // ref counter is set to 1 +// PythonObject = Py::Object(new FeaturePythonPyT(this),true); +// } +// return Py::new_reference_to(PythonObject); +// } ///// @endcond // //// explicit template instantiation -//template class AppExport FeaturePythonT; -//} +// template class AppExport FeaturePythonT; +// } diff --git a/src/App/Part.h b/src/App/Part.h index a40212fd72..312f20b518 100644 --- a/src/App/Part.h +++ b/src/App/Part.h @@ -35,7 +35,7 @@ namespace App /** Base class of all geometric document objects. */ -class AppExport Part : public App::GeoFeature, public App::OriginGroupExtension +class AppExport Part: public App::GeoFeature, public App::OriginGroupExtension { PROPERTY_HEADER_WITH_EXTENSIONS(App::Part); @@ -44,26 +44,26 @@ public: PropertyString Type; /** @name base properties of all Assembly Items - * These properties correspond mostly to the meta information - * in the App::Document class - */ + * These properties correspond mostly to the meta information + * in the App::Document class + */ //@{ /// Id e.g. Part number - App::PropertyString Id; + App::PropertyString Id; /// unique identifier of the Item - App::PropertyUUID Uid; + App::PropertyUUID Uid; /// material descriptions - App::PropertyLink Material; + App::PropertyLink Material; /// Meta descriptions - App::PropertyMap Meta; + App::PropertyMap Meta; /** License string - * Holds the short license string for the Item, e.g. CC-BY - * for the Creative Commons license suit. - */ - App::PropertyString License; + * Holds the short license string for the Item, e.g. CC-BY + * for the Creative Commons license suit. + */ + App::PropertyString License; /// License description/contract URL - App::PropertyString LicenseURL; + App::PropertyString LicenseURL; //@} /** @name Visual properties */ @@ -80,12 +80,15 @@ public: ~Part() override; /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderPart"; } - void handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop) override; + void handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) override; /** * Returns the part which contains this object. @@ -93,14 +96,14 @@ public: * @param obj the object to search for * @param recursive: whether to recursively find any grand parent Part container */ - static App::Part* getPartOfObject (const DocumentObject* obj, bool recursive=true); + static App::Part* getPartOfObject(const DocumentObject* obj, bool recursive = true); - PyObject *getPyObject() override; + PyObject* getPyObject() override; }; -//using PartPython = App::FeaturePythonT; +// using PartPython = App::FeaturePythonT; -} //namespace App +} // namespace App -#endif // APP_Part_H +#endif // APP_Part_H diff --git a/src/App/PartPyImp.cpp b/src/App/PartPyImp.cpp index e595a18c82..ddfba84183 100644 --- a/src/App/PartPyImp.cpp +++ b/src/App/PartPyImp.cpp @@ -35,7 +35,7 @@ std::string PartPy::representation() const return {""}; } -PyObject *PartPy::getCustomAttributes(const char* /*attr*/) const +PyObject* PartPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } @@ -44,4 +44,3 @@ int PartPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { return 0; } - diff --git a/src/App/Path.cpp b/src/App/Path.cpp index 39773c0892..0665a316b6 100644 --- a/src/App/Path.cpp +++ b/src/App/Path.cpp @@ -28,7 +28,6 @@ using namespace App; -Path::Path(const std::vector &PathVector) - : _PathVector(PathVector) -{ -} +Path::Path(const std::vector& PathVector) + : _PathVector(PathVector) +{} diff --git a/src/App/Path.h b/src/App/Path.h index eb77a65af9..f40eab4f83 100644 --- a/src/App/Path.h +++ b/src/App/Path.h @@ -36,21 +36,22 @@ namespace App class AppExport Path { protected: - std::vector _PathVector; + std::vector _PathVector; public: /// Constructor Path() = default; - explicit Path(const std::vector & PathVector); + explicit Path(const std::vector& PathVector); virtual ~Path() = default; - const std::vector & getVector() const { + const std::vector& getVector() const + { return _PathVector; } }; -} //namespace App +} // namespace App -#endif // APP_Path_H +#endif // APP_Path_H diff --git a/src/App/Placement.cpp b/src/App/Placement.cpp index 6a47e88c8f..b3c0dabf2a 100644 --- a/src/App/Placement.cpp +++ b/src/App/Placement.cpp @@ -42,16 +42,14 @@ Placement::Placement() = default; Placement::~Placement() = default; - // Python feature --------------------------------------------------------- -namespace App { +namespace App +{ PROPERTY_SOURCE_TEMPLATE(App::PlacementPython, App::Placement) -template<> const char* App::PlacementPython::getViewProviderName() const { - return "Gui::ViewProviderPlacementPython"; +template<> +const char* App::PlacementPython::getViewProviderName() const +{ + return "Gui::ViewProviderPlacementPython"; } template class AppExport FeaturePythonT; -} - - - - +} // namespace App diff --git a/src/App/Placement.h b/src/App/Placement.h index 39b18f9920..fc1ebf07fe 100644 --- a/src/App/Placement.h +++ b/src/App/Placement.h @@ -37,21 +37,20 @@ class AppExport Placement: public App::GeoFeature PROPERTY_HEADER_WITH_OVERRIDE(App::Placement); public: - /// Constructor - Placement(); - ~Placement() override; - - /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { - return "Gui::ViewProviderPlacement"; - } - + /// Constructor + Placement(); + ~Placement() override; + /// returns the type name of the ViewProvider + const char* getViewProviderName() const override + { + return "Gui::ViewProviderPlacement"; + } }; using PlacementPython = App::FeaturePythonT; -} //namespace App +} // namespace App #endif diff --git a/src/App/PreCompiled.cpp b/src/App/PreCompiled.cpp index cd345efad8..7b200a1bf2 100644 --- a/src/App/PreCompiled.cpp +++ b/src/App/PreCompiled.cpp @@ -22,4 +22,3 @@ #include "PreCompiled.h" - diff --git a/src/App/PreCompiled.h b/src/App/PreCompiled.h index b421ee048b..57cafc2a35 100644 --- a/src/App/PreCompiled.h +++ b/src/App/PreCompiled.h @@ -27,12 +27,13 @@ // point at which warnings of overly long specifiers disabled #ifdef _MSC_VER -#pragma warning( disable : 4251 ) -#pragma warning( disable : 4273 ) -#pragma warning( disable : 4275 ) -#pragma warning( disable : 4482 ) // nonstandard extension used: enum 'App::ObjectStatus' used in qualified name -#pragma warning( disable : 4503 ) -#pragma warning( disable : 4786 ) // specifier longer then 255 chars +#pragma warning(disable : 4251) +#pragma warning(disable : 4273) +#pragma warning(disable : 4275) +#pragma warning(disable : 4482) // nonstandard extension used: enum 'App::ObjectStatus' used in + // qualified name +#pragma warning(disable : 4503) +#pragma warning(disable : 4786) // specifier longer then 255 chars #endif #ifdef FC_OS_WIN32 @@ -52,15 +53,15 @@ #include #ifdef FC_OS_WIN32 -# include -# include -# include +#include +#include +#include #endif #if defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) -# include -# include -# include +#include +#include +#include #endif // Streams @@ -100,6 +101,6 @@ #include #include -#endif //_PreComp_ +#endif //_PreComp_ -#endif // APP_PRECOMPILED_H +#endif // APP_PRECOMPILED_H diff --git a/src/App/ProgramOptionsUtilities.h b/src/App/ProgramOptionsUtilities.h index 8024cf3a90..cba3bcaf0b 100644 --- a/src/App/ProgramOptionsUtilities.h +++ b/src/App/ProgramOptionsUtilities.h @@ -1,25 +1,25 @@ /*************************************************************************** -* Copyright (c) 2002 Jürgen Riegel * -* * -* This file is part of the FreeCAD CAx development system. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU Library General Public License (LGPL) * -* as published by the Free Software Foundation; either version 2 of * -* the License, or (at your option) any later version. * -* for detail see the LICENCE text file. * -* * -* FreeCAD is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU Library General Public License for more details. * -* * -* You should have received a copy of the GNU Library General Public * -* License along with FreeCAD; if not, write to the Free Software * -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -* USA * -* * -***************************************************************************/ + * Copyright (c) 2002 Jürgen Riegel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License (LGPL) * + * as published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * for detail see the LICENCE text file. * + * * + * FreeCAD is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with FreeCAD; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * + * USA * + * * + ***************************************************************************/ #ifndef PROGRAMOPTIONSUTILITIES_H #define PROGRAMOPTIONSUTILITIES_H @@ -28,12 +28,13 @@ #include #include -namespace App::Util{ +namespace App::Util +{ std::pair customSyntax(std::string_view strIn) { - if(strIn.size() < 2) { - return{}; + if (strIn.size() < 2) { + return {}; } char leadChr {strIn[0]}; @@ -53,7 +54,7 @@ std::pair customSyntax(std::string_view strIn) } #endif - if(rest == "widgetcount"){ + if (rest == "widgetcount") { return {rest, ""}; } @@ -73,11 +74,11 @@ std::pair customSyntax(std::string_view strIn) "title", "visual"}; - if(std::find(knowns.begin(), knowns.end(), rest) != knowns.end()) { + if (std::find(knowns.begin(), knowns.end(), rest) != knowns.end()) { return {rest, "null"}; } return {}; } -} // namespace -#endif// PROGRAMOPTIONSUTILITIES_H +} // namespace App::Util +#endif // PROGRAMOPTIONSUTILITIES_H diff --git a/src/App/ProjectFile.cpp b/src/App/ProjectFile.cpp index 28269368bc..03dbac3df1 100644 --- a/src/App/ProjectFile.cpp +++ b/src/App/ProjectFile.cpp @@ -64,12 +64,13 @@ XERCES_CPP_NAMESPACE_USE #endif using namespace App; -namespace { +namespace +{ class DocumentMetadata { public: explicit DocumentMetadata(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* xmlDocument) - : xmlDocument{xmlDocument} + : xmlDocument {xmlDocument} {} ProjectFile::Metadata getMetadata() const @@ -103,11 +104,13 @@ public: private: void readProgramVersion() { - if (DOMNodeList* nodes = xmlDocument->getElementsByTagName(XStr("Document").unicodeForm())) { + if (DOMNodeList* nodes = + xmlDocument->getElementsByTagName(XStr("Document").unicodeForm())) { for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMNode* nameAttr = node->getAttributes()->getNamedItem(XStr("ProgramVersion").unicodeForm()); + DOMNode* nameAttr = + node->getAttributes()->getNamedItem(XStr("ProgramVersion").unicodeForm()); if (nameAttr) { std::string value = StrX(nameAttr->getNodeValue()).c_str(); metadata.programVersion = value; @@ -163,12 +166,14 @@ private: static std::string readValue(DOMNode* node) { if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - if (DOMElement* child = static_cast(node)->getFirstElementChild()) { // NOLINT - if (DOMNode* nameAttr = child->getAttributes()->getNamedItem(XStr("value").unicodeForm())) { - std::string value = StrX(nameAttr->getNodeValue()).c_str(); - return value; - } - } + if (DOMElement* child = + static_cast(node)->getFirstElementChild()) { // NOLINT + if (DOMNode* nameAttr = + child->getAttributes()->getNamedItem(XStr("value").unicodeForm())) { + std::string value = StrX(nameAttr->getNodeValue()).c_str(); + return value; + } + } } return {}; @@ -178,7 +183,7 @@ private: XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* xmlDocument; ProjectFile::Metadata metadata; }; -} +} // namespace ProjectFile::ProjectFile() : xmlDocument(nullptr) @@ -259,8 +264,8 @@ std::list ProjectFile::getObjects() const for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMNodeList* objectList = - static_cast(node)->getElementsByTagName(XStr("Object").unicodeForm()); // NOLINT + DOMNodeList* objectList = static_cast(node)->getElementsByTagName( + XStr("Object").unicodeForm()); // NOLINT for (XMLSize_t j = 0; j < objectList->getLength(); j++) { DOMNode* objectNode = objectList->item(j); DOMNode* typeAttr = @@ -291,8 +296,8 @@ std::list ProjectFile::getObjectsOfType(const Base::Type& typeId) c for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMNodeList* objectList = - static_cast(node)->getElementsByTagName(XStr("Object").unicodeForm()); // NOLINT + DOMNodeList* objectList = static_cast(node)->getElementsByTagName( + XStr("Object").unicodeForm()); // NOLINT for (XMLSize_t j = 0; j < objectList->getLength(); j++) { DOMNode* objectNode = objectList->item(j); DOMNode* typeAttr = @@ -311,9 +316,7 @@ std::list ProjectFile::getObjectsOfType(const Base::Type& typeId) c return names; } -bool ProjectFile::restoreObject(const std::string& name, - App::PropertyContainer* obj, - bool verbose) +bool ProjectFile::restoreObject(const std::string& name, App::PropertyContainer* obj, bool verbose) { Base::FileInfo fi(stdFile); Base::ifstream file(fi, std::ios::in | std::ios::binary); @@ -367,8 +370,8 @@ Base::Type ProjectFile::getTypeId(const std::string& name) const for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMNodeList* objectList = - static_cast(node)->getElementsByTagName(XStr("Object").unicodeForm()); // NOLINT + DOMNodeList* objectList = static_cast(node)->getElementsByTagName( + XStr("Object").unicodeForm()); // NOLINT for (XMLSize_t j = 0; j < objectList->getLength(); j++) { DOMNode* objectNode = objectList->item(j); DOMNode* typeAttr = @@ -388,8 +391,7 @@ Base::Type ProjectFile::getTypeId(const std::string& name) const return Base::Type::badType(); } -std::list -ProjectFile::getPropertyFiles(const std::string& name) const +std::list ProjectFile::getPropertyFiles(const std::string& name) const { // // @@ -409,8 +411,8 @@ ProjectFile::getPropertyFiles(const std::string& name) const for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMNodeList* objectList = - static_cast(node)->getElementsByTagName(XStr("Object").unicodeForm()); // NOLINT + DOMNodeList* objectList = static_cast(node)->getElementsByTagName( + XStr("Object").unicodeForm()); // NOLINT for (XMLSize_t j = 0; j < objectList->getLength(); j++) { DOMNode* objectNode = objectList->item(j); DOMNode* nameAttr = @@ -488,8 +490,8 @@ std::list ProjectFile::getInputFiles(const std::string& name) const for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMNodeList* objectList = - static_cast(node)->getElementsByTagName(XStr("Object").unicodeForm()); // NOLINT + DOMNodeList* objectList = static_cast(node)->getElementsByTagName( + XStr("Object").unicodeForm()); // NOLINT for (XMLSize_t j = 0; j < objectList->getLength(); j++) { DOMNode* objectNode = objectList->item(j); DOMNode* nameAttr = @@ -646,8 +648,7 @@ std::string ProjectFile::replaceInputFiles(const std::map& props) +std::string ProjectFile::replacePropertyFiles(const std::map& props) { // create a new zip file with the name '.' std::string uuid = Base::Uuid::createUuid(); diff --git a/src/App/ProjectFile.h b/src/App/ProjectFile.h index 597ccc72c8..b9086c8d12 100644 --- a/src/App/ProjectFile.h +++ b/src/App/ProjectFile.h @@ -35,7 +35,12 @@ #ifndef XERCES_CPP_NAMESPACE_BEGIN #define XERCES_CPP_NAMESPACE_QUALIFIER using namespace XERCES_CPP_NAMESPACE; -namespace XERCES_CPP_NAMESPACE { class DOMNode; class DOMElement; class DOMDocument; } +namespace XERCES_CPP_NAMESPACE +{ +class DOMNode; +class DOMElement; +class DOMDocument; +} // namespace XERCES_CPP_NAMESPACE #else XERCES_CPP_NAMESPACE_BEGIN class DOMDocument; @@ -210,6 +215,6 @@ private: }; -} // namespace APP +} // namespace App #endif // APP_PROJECTFILE_H diff --git a/src/App/Range.cpp b/src/App/Range.cpp index 83bcc9d3b5..22d243dcf7 100644 --- a/src/App/Range.cpp +++ b/src/App/Range.cpp @@ -40,7 +40,8 @@ using namespace App; const int App::CellAddress::MAX_ROWS = 16384; const int App::CellAddress::MAX_COLUMNS = 26 * 26 + 26; -namespace App { +namespace App +{ // From a given cell address the '$' must be at within the first // few characters bool maybeAbsolute(std::string_view address) @@ -50,9 +51,9 @@ bool maybeAbsolute(std::string_view address) address = address.substr(0, MAX_COLUMNS_LETTERS + 1); return address.find("$") != std::string_view::npos; } -} +} // namespace App -Range::Range(const char * range, bool normalize) +Range::Range(const char* range, bool normalize) { std::string from; std::string to; @@ -97,7 +98,7 @@ Range::Range(int _row_begin, int _col_begin, int _row_end, int _col_end, bool no col_curr = col_begin; } -Range::Range(const CellAddress &from, const CellAddress &to, bool normalize) +Range::Range(const CellAddress& from, const CellAddress& to, bool normalize) : row_begin(from.row()) , col_begin(from.col()) , row_end(to.row()) @@ -128,8 +129,9 @@ bool Range::next() return true; } if (col_curr < col_end) { - if (row_curr == row_end + 1) + if (row_curr == row_end + 1) { return false; + } row_curr = row_begin; ++col_curr; return true; @@ -138,14 +140,14 @@ bool Range::next() } /** - * @brief Decode a row specification into a 0-based integer. - * - * @param rowstr Row specified as a string, with "1" being the first row. - * - * @returns The row. - */ + * @brief Decode a row specification into a 0-based integer. + * + * @param rowstr Row specified as a string, with "1" being the first row. + * + * @returns The row. + */ -int App::decodeRow(const std::string &rowstr, bool silent) +int App::decodeRow(const std::string& rowstr, bool silent) { int row = validRow(rowstr); @@ -159,10 +161,11 @@ int App::decodeRow(const std::string &rowstr, bool silent) /** * Assumes well-formed input. A through ZZZ. 0-based output */ -int columnStringToNum(const std::string &colstr) { +int columnStringToNum(const std::string& colstr) +{ double out {0}; int pos {0}; - for (auto chr = colstr.crbegin(); chr != colstr.crend(); chr++){ + for (auto chr = colstr.crbegin(); chr != colstr.crend(); chr++) { out += (*chr - 'A' + 1) * std::pow(26, pos++); } @@ -170,15 +173,15 @@ int columnStringToNum(const std::string &colstr) { } /** - * @brief Decode a column name string into a 0-based integer. - * - * @param colstr input string. - * - * @returns The column. - * - */ + * @brief Decode a column name string into a 0-based integer. + * + * @param colstr input string. + * + * @returns The column. + * + */ -int App::decodeColumn( const std::string &colstr, bool silent ) +int App::decodeColumn(const std::string& colstr, bool silent) { if (validColumn(colstr)) { return columnStringToNum(colstr); @@ -192,19 +195,19 @@ int App::decodeColumn( const std::string &colstr, bool silent ) } /** - * @brief Determine whether a row specification is valid or not. - * - * @param rowstr Row specified as a string, with "1" being the first row. - * - * @returns 0 or positive on success, -1 on error. - */ + * @brief Determine whether a row specification is valid or not. + * + * @param rowstr Row specified as a string, with "1" being the first row. + * + * @returns 0 or positive on success, -1 on error. + */ -int App::validRow(const std::string &rowstr) +int App::validRow(const std::string& rowstr) { - char * end; + char* end; int i = strtol(rowstr.c_str(), &end, 10); - if (i <=0 || i > CellAddress::MAX_ROWS || *end) { + if (i <= 0 || i > CellAddress::MAX_ROWS || *end) { return -1; } @@ -212,30 +215,30 @@ int App::validRow(const std::string &rowstr) } /** - * @brief Determine if a string is a valid column specification. - * - * @param colstr input string. - * - * @returns true if valid, false if not. - * - */ + * @brief Determine if a string is a valid column specification. + * + * @param colstr input string. + * + * @returns true if valid, false if not. + * + */ -bool App::validColumn( const std::string &colstr ) +bool App::validColumn(const std::string& colstr) { return boost::regex_match(colstr, boost::regex("[A-Z]{1,3}")); } /** - * @brief Convert a string address into integer \a row and \a column. - * row and col are 0-based. - * - * This function will throw an exception if the specified \a address is invalid. - * - * @param strAddress Address to parse. - * - */ + * @brief Convert a string address into integer \a row and \a column. + * row and col are 0-based. + * + * This function will throw an exception if the specified \a address is invalid. + * + * @param strAddress Address to parse. + * + */ -App::CellAddress App::stringToAddress(const char * strAddress, bool silent) +App::CellAddress App::stringToAddress(const char* strAddress, bool silent) { assert(strAddress); @@ -243,24 +246,24 @@ App::CellAddress App::stringToAddress(const char * strAddress, bool silent) boost::cmatch cm; if (boost::regex_match(strAddress, cm, e)) { - bool absCol = (cm[1].first[0]=='$'); - std::string r,c; + bool absCol = (cm[1].first[0] == '$'); + std::string r, c; if (absCol) { - c = std::string(cm[1].first+1,cm[1].second); + c = std::string(cm[1].first + 1, cm[1].second); } else { - c = std::string(cm[1].first,cm[1].second); + c = std::string(cm[1].first, cm[1].second); } - bool absRow = (cm[2].first[0]=='$'); + bool absRow = (cm[2].first[0] == '$'); if (absRow) { - r = std::string(cm[2].first+1,cm[2].second); + r = std::string(cm[2].first + 1, cm[2].second); } else { - r = std::string(cm[2].first,cm[2].second); + r = std::string(cm[2].first, cm[2].second); } - return CellAddress(decodeRow(r,silent), decodeColumn(c,silent), absRow, absCol); + return CellAddress(decodeRow(r, silent), decodeColumn(c, silent), absRow, absCol); } else if (silent) { return CellAddress(); @@ -270,10 +273,10 @@ App::CellAddress App::stringToAddress(const char * strAddress, bool silent) } /** - * @brief Convert given \a cell address into its string representation. - * - * @returns Address given as a string. - */ + * @brief Convert given \a cell address into its string representation. + * + * @returns Address given as a string. + */ std::string App::CellAddress::toString(Cell cell) const { @@ -311,7 +314,8 @@ std::string App::CellAddress::toString(Cell cell) const * If the passed string is a valid and absolute cell address it will be assigned to this instance. * \return True if it's an absolute cell address and false otherwise */ -bool App::CellAddress::parseAbsoluteAddress(const char *address) { +bool App::CellAddress::parseAbsoluteAddress(const char* address) +{ if (maybeAbsolute(address)) { CellAddress addr = stringToAddress(address, true); if (addr.isValid()) { @@ -321,4 +325,3 @@ bool App::CellAddress::parseAbsoluteAddress(const char *address) { } return false; } - diff --git a/src/App/Range.h b/src/App/Range.h index 57b2f2ca8a..d30dce59df 100644 --- a/src/App/Range.h +++ b/src/App/Range.h @@ -29,19 +29,22 @@ #include #endif -namespace App { +namespace App +{ struct CellAddress; -AppExport CellAddress stringToAddress(const char *strAddress, bool silent=false); -AppExport int decodeColumn(const std::string &colstr, bool silent=false); -AppExport int decodeRow(const std::string &rowstr, bool silent=false); -AppExport bool validColumn(const std::string &colstr); -AppExport int validRow(const std::string &rowstr); +AppExport CellAddress stringToAddress(const char* strAddress, bool silent = false); +AppExport int decodeColumn(const std::string& colstr, bool silent = false); +AppExport int decodeRow(const std::string& rowstr, bool silent = false); +AppExport bool validColumn(const std::string& colstr); +AppExport int validRow(const std::string& rowstr); -struct AppExport CellAddress { +struct AppExport CellAddress +{ // See call of ENABLE_BITMASK_OPERATORS - enum class Cell { + enum class Cell + { Absolute = 1, ShowRow = 2, ShowColumn = 4, @@ -49,41 +52,79 @@ struct AppExport CellAddress { ShowFull = Absolute | ShowRow | ShowColumn }; - explicit CellAddress(int row = -1, int col = -1, bool absRow=false, bool absCol=false) - : _row(row), _col(col), _absRow(absRow), _absCol(absCol) - { } + explicit CellAddress(int row = -1, int col = -1, bool absRow = false, bool absCol = false) + : _row(row) + , _col(col) + , _absRow(absRow) + , _absCol(absCol) + {} - explicit CellAddress(const char * address) { + explicit CellAddress(const char* address) + { *this = stringToAddress(address); } - explicit CellAddress(const std::string & address) { + explicit CellAddress(const std::string& address) + { *this = stringToAddress(address.c_str()); } - bool parseAbsoluteAddress(const char *txt); + bool parseAbsoluteAddress(const char* txt); - inline int row() const { return _row; } + inline int row() const + { + return _row; + } - inline int col() const { return _col; } + inline int col() const + { + return _col; + } - void setRow(int r, bool clip=false) { _row = (clip && r>=MAX_ROWS) ? MAX_ROWS-1 : r; } + void setRow(int r, bool clip = false) + { + _row = (clip && r >= MAX_ROWS) ? MAX_ROWS - 1 : r; + } - void setCol(int c, bool clip=false) { _col = (clip && c>=MAX_COLUMNS) ? MAX_COLUMNS-1 : c; } + void setCol(int c, bool clip = false) + { + _col = (clip && c >= MAX_COLUMNS) ? MAX_COLUMNS - 1 : c; + } - inline bool operator<(const CellAddress & other) const { return asInt() < other.asInt(); } + inline bool operator<(const CellAddress& other) const + { + return asInt() < other.asInt(); + } - inline bool operator>(const CellAddress & other) const { return asInt() > other.asInt(); } + inline bool operator>(const CellAddress& other) const + { + return asInt() > other.asInt(); + } - inline bool operator==(const CellAddress & other) const { return asInt() == other.asInt(); } + inline bool operator==(const CellAddress& other) const + { + return asInt() == other.asInt(); + } - inline bool operator!=(const CellAddress & other) const { return asInt() != other.asInt(); } + inline bool operator!=(const CellAddress& other) const + { + return asInt() != other.asInt(); + } - inline bool isValid() { return (row() >=0 && row() < MAX_ROWS && col() >= 0 && col() < MAX_COLUMNS); } + inline bool isValid() + { + return (row() >= 0 && row() < MAX_ROWS && col() >= 0 && col() < MAX_COLUMNS); + } - inline bool isAbsoluteRow() const { return _absRow; } + inline bool isAbsoluteRow() const + { + return _absRow; + } - inline bool isAbsoluteCol() const { return _absCol; } + inline bool isAbsoluteCol() const + { + return _absCol; + } std::string toString(Cell = Cell::ShowFull) const; @@ -94,8 +135,10 @@ struct AppExport CellAddress { static const int MAX_COLUMNS; protected: - - inline unsigned int asInt() const { return ((_row << 16) | _col); } + inline unsigned int asInt() const + { + return ((_row << 16) | _col); + } short _row; short _col; @@ -115,13 +158,14 @@ protected: * */ -class AppExport Range { +class AppExport Range +{ public: - explicit Range(const char *range, bool normalize=false); + explicit Range(const char* range, bool normalize = false); - Range(int _row_begin, int _col_begin, int _row_end, int _col_end, bool normalize=false); + Range(int _row_begin, int _col_begin, int _row_end, int _col_end, bool normalize = false); - Range(const CellAddress & from, const CellAddress & to, bool normalize=false); + Range(const CellAddress& from, const CellAddress& to, bool normalize = false); bool next(); @@ -129,49 +173,87 @@ public: void normalize(); /** Current row */ - inline int row() const { return row_curr; } - - /** Current column */ - inline int column() const { return col_curr; } - - /** Row count */ - inline int rowCount() const { return row_end - row_begin + 1; } - - /** Column count */ - inline int colCount() const { return col_end - col_begin + 1; } - - /** Position of start of range */ - inline CellAddress from() const { return CellAddress(row_begin, col_begin); } - - /** Position of end of range */ - inline CellAddress to() const { return CellAddress(row_end, col_end); } - - /** Start of range as a string */ - inline std::string fromCellString() const { return CellAddress(row_begin, col_begin).toString(); } - - /** End of range as a string */ - inline std::string toCellString() const { return CellAddress(row_end, col_end).toString(); } - - /** Current cell as a string */ - inline std::string address() const { return CellAddress(row_curr, col_curr).toString(); } - - /** The raneg as a string */ - inline std::string rangeString() const { - return CellAddress(row_begin, col_begin).toString() + ":" + CellAddress(row_end, col_end).toString(); + inline int row() const + { + return row_curr; } - CellAddress operator*() const { return CellAddress(row_curr, col_curr); } + /** Current column */ + inline int column() const + { + return col_curr; + } - inline bool operator<(const Range & other) const { - if(from() < other.from()) + /** Row count */ + inline int rowCount() const + { + return row_end - row_begin + 1; + } + + /** Column count */ + inline int colCount() const + { + return col_end - col_begin + 1; + } + + /** Position of start of range */ + inline CellAddress from() const + { + return CellAddress(row_begin, col_begin); + } + + /** Position of end of range */ + inline CellAddress to() const + { + return CellAddress(row_end, col_end); + } + + /** Start of range as a string */ + inline std::string fromCellString() const + { + return CellAddress(row_begin, col_begin).toString(); + } + + /** End of range as a string */ + inline std::string toCellString() const + { + return CellAddress(row_end, col_end).toString(); + } + + /** Current cell as a string */ + inline std::string address() const + { + return CellAddress(row_curr, col_curr).toString(); + } + + /** The raneg as a string */ + inline std::string rangeString() const + { + return CellAddress(row_begin, col_begin).toString() + ":" + + CellAddress(row_end, col_end).toString(); + } + + CellAddress operator*() const + { + return CellAddress(row_curr, col_curr); + } + + inline bool operator<(const Range& other) const + { + if (from() < other.from()) { return true; - if(from() > other.from()) + } + if (from() > other.from()) { return false; + } return to() < other.to(); } /** Number of elements in range */ - inline int size() const { return (row_end - row_begin + 1) * (col_end - col_begin + 1); } + inline int size() const + { + return (row_end - row_begin + 1) * (col_end - col_begin + 1); + } private: int row_curr, col_curr; @@ -179,8 +261,8 @@ private: int row_end, col_end; }; -} +} // namespace App ENABLE_BITMASK_OPERATORS(App::CellAddress::Cell) -#endif // RANGE_H +#endif // RANGE_H diff --git a/src/App/Resources/translations/App_hr.ts b/src/App/Resources/translations/App_hr.ts index 65cef49df0..a52952ced2 100644 --- a/src/App/Resources/translations/App_hr.ts +++ b/src/App/Resources/translations/App_hr.ts @@ -7,7 +7,7 @@ Stores the last user choice of whether to apply CopyOnChange setup to all links that reference the same configurable object - Pamti posljednji izbor korisnika o tome treba li primijeniti postavljanje CopyOnChange + Pamti posljednji izbor korisnika o tome treba li primijeniti postavljanje CopyOnChange na sve veze koje referenciraju isti konfigurabilni objekt diff --git a/src/App/Resources/translations/App_tr.ts b/src/App/Resources/translations/App_tr.ts index 449fc8c945..8376aad26c 100644 --- a/src/App/Resources/translations/App_tr.ts +++ b/src/App/Resources/translations/App_tr.ts @@ -7,7 +7,7 @@ Stores the last user choice of whether to apply CopyOnChange setup to all links that reference the same configurable object - Aynı yapılandırılabilir nesneye baÅŸvuran tüm baÄŸlantılara CopyOnChange kurulumunun uygulanıp + Aynı yapılandırılabilir nesneye baÅŸvuran tüm baÄŸlantılara CopyOnChange kurulumunun uygulanıp uygulanmayacağına iliÅŸkin son kullanıcı seçimini saklar diff --git a/src/App/SafeMode.cpp b/src/App/SafeMode.cpp index 63fbd7cd90..72a065b5c5 100644 --- a/src/App/SafeMode.cpp +++ b/src/App/SafeMode.cpp @@ -30,9 +30,10 @@ #include "SafeMode.h" -static QTemporaryDir * tempDir = nullptr; +static QTemporaryDir* tempDir = nullptr; -static bool _createTemporaryBaseDir() { +static bool _createTemporaryBaseDir() +{ tempDir = new QTemporaryDir(); if (!tempDir->isValid()) { delete tempDir; @@ -43,7 +44,7 @@ static bool _createTemporaryBaseDir() { static void _replaceDirs() { - auto &config = App::GetApplication().Config(); + auto& config = App::GetApplication().Config(); auto const temp_base = tempDir->path().toStdString(); auto const dirs = { @@ -70,10 +71,12 @@ void SafeMode::StartSafeMode() } } -bool SafeMode::SafeModeEnabled() { +bool SafeMode::SafeModeEnabled() +{ return tempDir; } -void SafeMode::Destruct() { +void SafeMode::Destruct() +{ delete tempDir; } diff --git a/src/App/SafeMode.h b/src/App/SafeMode.h index 95a3749c3d..e2353d0e4a 100644 --- a/src/App/SafeMode.h +++ b/src/App/SafeMode.h @@ -23,8 +23,9 @@ #pragma once -namespace SafeMode { - AppExport bool SafeModeEnabled(); - AppExport void StartSafeMode(); - AppExport void Destruct(); -}; +namespace SafeMode +{ +AppExport bool SafeModeEnabled(); +AppExport void StartSafeMode(); +AppExport void Destruct(); +}; // namespace SafeMode diff --git a/src/App/StringHasher.cpp b/src/App/StringHasher.cpp index dd8960f93c..7cdc892dd1 100644 --- a/src/App/StringHasher.cpp +++ b/src/App/StringHasher.cpp @@ -210,7 +210,7 @@ void StringHasher::compact() pendings.pop_front(); // Try to erase the map entry for this StringID if (_hashes->right.erase(sid.value()) == 0U) { - continue;// If nothing was erased, there's nothing more to do + continue; // If nothing was erased, there's nothing more to do } sid._sid->_hasher = nullptr; sid._sid->unref(); @@ -403,10 +403,10 @@ StringIDRef StringHasher::getID(const Data::MappedName& name, const QVector 0) {// If the data had an index + if (res.id > 0) { // If the data had an index if (res.index != 0) { indexed.setIndex(res.index); - newStringID._data.resize(newStringID._data.lastIndexOf(':')+1); + newStringID._data.resize(newStringID._data.lastIndexOf(':') + 1); } int offset = newStringID.isPostfixEncoded() ? 1 : 0; // Search for the SID with that index @@ -612,7 +612,7 @@ void StringHasher::RestoreDocFile(Base::Reader& reader) void StringHasher::restoreStreamNew(std::istream& stream, std::size_t count) { - Base::TextInputStream asciiStream (stream); + Base::TextInputStream asciiStream(stream); _hashes->clear(); std::string content; boost::io::ios_flags_saver ifs(stream); @@ -708,8 +708,9 @@ void StringHasher::restoreStreamNew(std::istream& stream, std::size_t count) FC_THROWM(Base::RuntimeError, "Missing string prefix id"); } d._data = d._sids[offset]._sid->toString(0).c_str(); - if (d.isPrefixIDIndex()) + if (d.isPrefixIDIndex()) { d._data += ":"; + } } else { stream >> content; @@ -777,7 +778,7 @@ size_t StringHasher::count() const { size_t count = 0; for (auto& hasher : _hashes->right) { - if (hasher.second->isMarked() || hasher.second->isPersistent() ) { + if (hasher.second->isMarked() || hasher.second->isPersistent()) { ++count; } } @@ -808,8 +809,9 @@ void StringHasher::Restore(Base::XMLReader& reader) std::size_t count = reader.getAttributeAsUnsigned("count"); if (newTag) { try { - restoreStreamNew(reader.beginCharStream(), count); - } catch (const Base::Exception &e) { + restoreStreamNew(reader.beginCharStream(), count); + } + catch (const Base::Exception& e) { e.ReportException(); FC_ERR("Failed to restore string table: full-document recompute strongly recommended."); } diff --git a/src/App/StringHasher.h b/src/App/StringHasher.h index 1b65b34795..bc4491d02b 100644 --- a/src/App/StringHasher.h +++ b/src/App/StringHasher.h @@ -76,7 +76,7 @@ using StringHasherRef = Base::Reference; */ class AppExport StringID: public Base::BaseClass, public Base::Handled { - TYPESYSTEM_HEADER_WITH_OVERRIDE();// NOLINT + TYPESYSTEM_HEADER_WITH_OVERRIDE(); // NOLINT public: /// Flag of the stored string data @@ -119,15 +119,15 @@ public: * User code is not supposed to create StringID directly, but through StringHasher::getID() */ StringID(long id, QByteArray data, const Flags& flags = Flag::None) - : _id(id), - _data(std::move(data)), - _flags(flags) + : _id(id) + , _data(std::move(data)) + , _flags(flags) {} /// Constructs an empty StringID StringID() - : _id(0), - _flags(Flag::None) + : _id(0) + , _flags(Flag::None) {} StringID(const StringID& other) = delete; @@ -327,8 +327,8 @@ public: /// Default construction results in an empty StringIDRef object: it will evaluate to boolean /// "false" if queried. StringIDRef() - : _sid(nullptr), - _index(0) + : _sid(nullptr) + , _index(0) {} /// Standard construction from a heap-allocated StringID. This reference-counting class manages @@ -337,8 +337,8 @@ public: /// \param stringID A pointer to a StringID allocated with "new" /// \param index (optional) An index value to store along with the StringID. Defaults to zero. StringIDRef(StringID* stringID, int index = 0) - : _sid(stringID), - _index(index) + : _sid(stringID) + , _index(index) { if (_sid) { _sid->ref(); @@ -347,8 +347,8 @@ public: /// Copy construction results in an incremented reference count for the stored StringID StringIDRef(const StringIDRef& other) - : _sid(other._sid), - _index(other._index) + : _sid(other._sid) + , _index(other._index) { if (_sid) { _sid->ref(); @@ -358,15 +358,15 @@ public: /// Move construction does NOT increase the reference count of the StringID (instead, it /// invalidates the pointer in the moved object). StringIDRef(StringIDRef&& other) noexcept - : _sid(other._sid), - _index(other._index) + : _sid(other._sid) + , _index(other._index) { other._sid = nullptr; } StringIDRef(const StringIDRef& other, int index) - : _sid(other._sid), - _index(index) + : _sid(other._sid) + , _index(index) { if (_sid) { _sid->ref(); @@ -582,12 +582,12 @@ public: bool isMarked() const { - return _sid && _sid->isMarked();// NOLINT + return _sid && _sid->isMarked(); // NOLINT } bool isFromSameHasher(const StringHasherRef& hasher) const { - return _sid && _sid->isFromSameHasher(hasher);// NOLINT + return _sid && _sid->isFromSameHasher(hasher); // NOLINT } StringHasherRef getHasher() const @@ -633,7 +633,7 @@ private: class AppExport StringHasher: public Base::Persistence, public Base::Handled { - TYPESYSTEM_HEADER_WITH_OVERRIDE();// NOLINT + TYPESYSTEM_HEADER_WITH_OVERRIDE(); // NOLINT public: StringHasher(); @@ -778,10 +778,11 @@ protected: void restoreStreamNew(std::istream& stream, std::size_t count); private: - std::unique_ptr _hashes;///< Bidirectional map of StringID and its index (a long int). + std::unique_ptr + _hashes; ///< Bidirectional map of StringID and its index (a long int). mutable std::string _filename; }; -}// namespace App +} // namespace App ENABLE_BITMASK_OPERATORS(App::StringID::Flag) ENABLE_BITMASK_OPERATORS(App::StringHasher::Option) @@ -828,6 +829,6 @@ inline void StringID::setPersistent(bool enable) { _flags.setFlag(Flag::Persistent, enable); } -}// namespace App +} // namespace App -#endif// APP_STRING_ID_H +#endif // APP_STRING_ID_H diff --git a/src/App/StringHasherPy.xml b/src/App/StringHasherPy.xml index d7df2b0e25..ff7d8e1dbf 100644 --- a/src/App/StringHasherPy.xml +++ b/src/App/StringHasherPy.xml @@ -1,13 +1,13 @@ - @@ -25,7 +25,7 @@ If the input is text, return a StringID object that is unique within this hasher StringID object is reference counted. The hasher may only save hash ID's that are used. If the input is an integer, then the hasher will try to find the StringID object stored -with the same integer value. +with the same integer value. base64: indicate if the input 'txt' is base64 encoded binary data @@ -68,4 +68,3 @@ base64: indicate if the input 'txt' is base64 encoded binary data - diff --git a/src/App/StringHasherPyImp.cpp b/src/App/StringHasherPyImp.cpp index cae36bce9f..4581bf5fed 100644 --- a/src/App/StringHasherPyImp.cpp +++ b/src/App/StringHasherPyImp.cpp @@ -1,24 +1,24 @@ /**************************************************************************** -* Copyright (c) 2018 Zheng Lei (realthunder) * -* * -* This file is part of the FreeCAD CAx development system. * -* * -* This library is free software; you can redistribute it and/or * -* modify it under the terms of the GNU Library General Public * -* License as published by the Free Software Foundation; either * -* version 2 of the License, or (at your option) any later version. * -* * -* This library is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU Library General Public License for more details. * -* * -* You should have received a copy of the GNU Library General Public * -* License along with this library; see the file COPYING.LIB. If not, * -* write to the Free Software Foundation, Inc., 59 Temple Place, * -* Suite 330, Boston, MA 02111-1307, USA * -* * -****************************************************************************/ + * Copyright (c) 2018 Zheng Lei (realthunder) * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ****************************************************************************/ #include "PreCompiled.h" @@ -38,7 +38,7 @@ std::string StringHasherPy::representation() const return str.str(); } -PyObject *StringHasherPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +PyObject* StringHasherPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper { return new StringHasherPy(new StringHasher); } @@ -46,7 +46,7 @@ PyObject *StringHasherPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // constructor method int StringHasherPy::PyInit(PyObject* args, PyObject* kwds) { - static const std::array kwlist {nullptr}; + static const std::array kwlist {nullptr}; if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "", kwlist)) { return -1; } @@ -55,9 +55,9 @@ int StringHasherPy::PyInit(PyObject* args, PyObject* kwds) } -PyObject* StringHasherPy::isSame(PyObject *args) +PyObject* StringHasherPy::isSame(PyObject* args) { - PyObject *other; + PyObject* other; if (!PyArg_ParseTuple(args, "O!", &StringHasherPy::Type, &other)) { return nullptr; } @@ -65,16 +65,17 @@ PyObject* StringHasherPy::isSame(PyObject *args) auto otherHasher = static_cast(other)->getStringHasherPtr(); bool same = getStringHasherPtr() == otherHasher; - return PyBool_FromLong(same ? 1 : 0); + return PyBool_FromLong(same ? 1 : 0); } -PyObject* StringHasherPy::getID(PyObject *args) +PyObject* StringHasherPy::getID(PyObject* args) { long id; int index = 0; if (PyArg_ParseTuple(args, "l|i", &id, &index)) { if (id > 0) { - PY_TRY { + PY_TRY + { auto sid = getStringHasherPtr()->getID(id, index); if (!sid) { Py_Return; @@ -91,19 +92,20 @@ PyObject* StringHasherPy::getID(PyObject *args) } PyErr_Clear(); - PyObject *value = nullptr; - PyObject *base64 = Py_False; + PyObject* value = nullptr; + PyObject* base64 = Py_False; if (PyArg_ParseTuple(args, "O!|O!", &PyUnicode_Type, &value, &PyBool_Type, &base64)) { - PY_TRY { + PY_TRY + { std::string txt = PyUnicode_AsUTF8(value); QByteArray data; StringIDRef sid; if (PyObject_IsTrue(base64)) { - data = QByteArray::fromBase64(QByteArray::fromRawData(txt.c_str(),txt.size())); - sid = getStringHasherPtr()->getID(data,true); + data = QByteArray::fromBase64(QByteArray::fromRawData(txt.c_str(), txt.size())); + sid = getStringHasherPtr()->getID(data, true); } else { - sid = getStringHasherPtr()->getID(txt.c_str(),txt.size()); + sid = getStringHasherPtr()->getID(txt.c_str(), txt.size()); } return sid.getPyObject(); @@ -111,8 +113,9 @@ PyObject* StringHasherPy::getID(PyObject *args) PY_CATCH; } - PyErr_SetString(PyExc_TypeError, "Positive integer and optional integer or " - "string and optional boolean is required"); + PyErr_SetString(PyExc_TypeError, + "Positive integer and optional integer or " + "string and optional boolean is required"); return nullptr; } @@ -149,14 +152,14 @@ void StringHasherPy::setThreshold(Py::Long value) Py::Dict StringHasherPy::getTable() const { Py::Dict dict; - for (const auto &v : getStringHasherPtr()->getIDMap()) { + for (const auto& v : getStringHasherPtr()->getIDMap()) { dict.setItem(Py::Long(v.first), Py::String(v.second.dataToText())); } return dict; } -PyObject *StringHasherPy::getCustomAttributes(const char* /*attr*/) const +PyObject* StringHasherPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } diff --git a/src/App/StringIDPy.xml b/src/App/StringIDPy.xml index eb43002f40..de77d7c97a 100644 --- a/src/App/StringIDPy.xml +++ b/src/App/StringIDPy.xml @@ -1,13 +1,13 @@ - @@ -62,4 +62,3 @@ - diff --git a/src/App/StringIDPyImp.cpp b/src/App/StringIDPyImp.cpp index 549b71f1c8..d81b2f29df 100644 --- a/src/App/StringIDPyImp.cpp +++ b/src/App/StringIDPyImp.cpp @@ -1,24 +1,24 @@ /*************************************************************************** -* Copyright (c) 2018 Zheng Lei (realthunder) * -* * -* This file is part of the FreeCAD CAx development system. * -* * -* This library is free software; you can redistribute it and/or * -* modify it under the terms of the GNU Library General Public * -* License as published by the Free Software Foundation; either * -* version 2 of the License, or (at your option) any later version. * -* * -* This library is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU Library General Public License for more details. * -* * -* You should have received a copy of the GNU Library General Public * -* License along with this library; see the file COPYING.LIB. If not, * -* write to the Free Software Foundation, Inc., 59 Temple Place, * -* Suite 330, Boston, MA 02111-1307, USA * -* * -****************************************************************************/ + * Copyright (c) 2018 Zheng Lei (realthunder) * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ****************************************************************************/ #include "PreCompiled.h" @@ -35,16 +35,16 @@ std::string StringIDPy::representation() const return getStringIDPtr()->toString(this->_index); } -PyObject* StringIDPy::isSame(PyObject *args) +PyObject* StringIDPy::isSame(PyObject* args) { - PyObject *other = nullptr; + PyObject* other = nullptr; if (!PyArg_ParseTuple(args, "O!", &StringIDPy::Type, &other)) { return nullptr; } - auto *otherPy = static_cast(other); - bool same = (otherPy->getStringIDPtr() == this->getStringIDPtr()) - && (otherPy->_index == this->_index); + auto* otherPy = static_cast(other); + bool same = + (otherPy->getStringIDPtr() == this->getStringIDPtr()) && (otherPy->_index == this->_index); return PyBool_FromLong(same ? 1 : 0); } @@ -57,7 +57,7 @@ Py::Long StringIDPy::getValue() const Py::List StringIDPy::getRelated() const { Py::List list; - for (const auto &id : getStringIDPtr()->relatedIDs()) { + for (const auto& id : getStringIDPtr()->relatedIDs()) { list.append(Py::Long(id.value())); } @@ -89,7 +89,7 @@ void StringIDPy::setIndex(Py::Long index) this->_index = index; } -PyObject *StringIDPy::getCustomAttributes(const char* /*attr*/) const +PyObject* StringIDPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } diff --git a/src/App/SuppressibleExtension.cpp b/src/App/SuppressibleExtension.cpp index 9c2348f8be..5add18392b 100644 --- a/src/App/SuppressibleExtension.cpp +++ b/src/App/SuppressibleExtension.cpp @@ -29,7 +29,8 @@ #include "SuppressibleExtensionPy.h" -namespace App { +namespace App +{ EXTENSION_PROPERTY_SOURCE(App::SuppressibleExtension, App::DocumentObjectExtension) @@ -43,19 +44,24 @@ template class AppExport ExtensionPythonT -class SuppressibleExtensionPythonT : public ExtensionT { +class SuppressibleExtensionPythonT: public ExtensionT +{ public: - SuppressibleExtensionPythonT() = default; ~SuppressibleExtensionPythonT() override = default; }; -using SuppressibleExtensionPython = ExtensionPythonT>; +using SuppressibleExtensionPython = + ExtensionPythonT>; -} //namespace App +} // namespace App -#endif // SUPPRESSIBLEEXTENSION_H +#endif // SUPPRESSIBLEEXTENSION_H diff --git a/src/App/SuppressibleExtensionPyImp.cpp b/src/App/SuppressibleExtensionPyImp.cpp index 3a2c99a117..d6e4053f8a 100644 --- a/src/App/SuppressibleExtensionPyImp.cpp +++ b/src/App/SuppressibleExtensionPyImp.cpp @@ -38,7 +38,7 @@ std::string SuppressibleExtensionPy::representation() const return {""}; } -PyObject *SuppressibleExtensionPy::getCustomAttributes(const char* /*attr*/) const +PyObject* SuppressibleExtensionPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } diff --git a/src/App/TextDocument.cpp b/src/App/TextDocument.cpp index 24cb355e3b..7d3d30d0bf 100644 --- a/src/App/TextDocument.cpp +++ b/src/App/TextDocument.cpp @@ -33,17 +33,17 @@ PROPERTY_SOURCE(App::TextDocument, App::DocumentObject) TextDocument::TextDocument() { - ADD_PROPERTY_TYPE( - Text, (""), 0, App::Prop_Hidden, - "Content of the document."); + ADD_PROPERTY_TYPE(Text, (""), 0, App::Prop_Hidden, "Content of the document."); } void TextDocument::onChanged(const Property* prop) { - if (prop == &Text) + if (prop == &Text) { textChanged(); - else if (prop == &Label) + } + else if (prop == &Label) { labelChanged(); + } DocumentObject::onChanged(prop); } @@ -52,12 +52,12 @@ const char* TextDocument::getViewProviderName() const return "Gui::ViewProviderTextDocument"; } -boost::signals2::connection TextDocument::connectText(const TextSlot &sub) +boost::signals2::connection TextDocument::connectText(const TextSlot& sub) { return textChanged.connect(sub); } -boost::signals2::connection TextDocument::connectLabel(const TextSlot &sub) +boost::signals2::connection TextDocument::connectLabel(const TextSlot& sub) { return labelChanged.connect(sub); } diff --git a/src/App/TextDocument.h b/src/App/TextDocument.h index 702313eb3f..fb47592198 100644 --- a/src/App/TextDocument.h +++ b/src/App/TextDocument.h @@ -31,10 +31,12 @@ namespace App { -class AppExport TextDocument : public App::DocumentObject { +class AppExport TextDocument: public App::DocumentObject +{ PROPERTY_HEADER_WITH_OVERRIDE(App::TextDocument); + public: - using TextSignal = boost::signals2::signal; + using TextSignal = boost::signals2::signal; using TextSlot = TextSignal::slot_type; PropertyString Text; @@ -45,15 +47,15 @@ public: void onChanged(const Property* prop) override; const char* getViewProviderName() const override; - boost::signals2::connection connectText(const TextSlot &sub); - boost::signals2::connection connectLabel(const TextSlot &sub); + boost::signals2::connection connectText(const TextSlot& sub); + boost::signals2::connection connectLabel(const TextSlot& sub); private: TextSignal textChanged; TextSignal labelChanged; }; -} +} // namespace App #endif diff --git a/src/App/TransactionalObject.cpp b/src/App/TransactionalObject.cpp index 2e4bf944e2..5e9340dddd 100644 --- a/src/App/TransactionalObject.cpp +++ b/src/App/TransactionalObject.cpp @@ -46,8 +46,7 @@ const char* TransactionalObject::detachFromDocument() return ""; } -void TransactionalObject::onBeforeChangeProperty(Document *doc, const Property *prop) +void TransactionalObject::onBeforeChangeProperty(Document* doc, const Property* prop) { doc->onBeforeChangeProperty(this, prop); } - diff --git a/src/App/TransactionalObject.h b/src/App/TransactionalObject.h index 97d47be216..dd4c86fdef 100644 --- a/src/App/TransactionalObject.h +++ b/src/App/TransactionalObject.h @@ -34,7 +34,7 @@ class TransactionObject; /** Base class of transactional objects */ -class AppExport TransactionalObject : public App::ExtensionContainer +class AppExport TransactionalObject: public App::ExtensionContainer { PROPERTY_HEADER_WITH_OVERRIDE(App::TransactionalObject); @@ -44,11 +44,12 @@ public: ~TransactionalObject() override; virtual bool isAttachedToDocument() const; virtual const char* detachFromDocument(); + protected: - void onBeforeChangeProperty(Document *doc, const Property *prop); + void onBeforeChangeProperty(Document* doc, const Property* prop); }; -} //namespace App +} // namespace App -#endif // APP_TRANSACTIONALOBJECT_H +#endif // APP_TRANSACTIONALOBJECT_H diff --git a/src/App/Transactions.cpp b/src/App/Transactions.cpp index 5100c3992c..ebf1c47fe7 100644 --- a/src/App/Transactions.cpp +++ b/src/App/Transactions.cpp @@ -25,7 +25,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include @@ -39,7 +39,7 @@ #include "Property.h" -FC_LOG_LEVEL_INIT("App",true,true) +FC_LOG_LEVEL_INIT("App", true, true) using namespace App; using namespace std; @@ -51,7 +51,9 @@ TYPESYSTEM_SOURCE(App::Transaction, Base::Persistence) Transaction::Transaction(int id) { - if(!id) id = getNewID(); + if (!id) { + id = getNewID(); + } transID = id; } @@ -61,8 +63,8 @@ Transaction::Transaction(int id) */ Transaction::~Transaction() { - auto &index = _Objects.get<0>(); - for (const auto & It : index) { + auto& index = _Objects.get<0>(); + for (const auto& It : index) { if (It.second->status == TransactionObject::New) { // If an object has been removed from the document the transaction // status is 'New'. The 'pcNameInDocument' member serves as criterion @@ -97,29 +99,32 @@ Transaction::~Transaction() static std::atomic _TransactionID; -int Transaction::getNewID() { +int Transaction::getNewID() +{ int id = ++_TransactionID; - if(id) + if (id) { return id; + } // wrap around? really? return ++_TransactionID; } -int Transaction::getLastID() { +int Transaction::getLastID() +{ return _TransactionID; } -unsigned int Transaction::getMemSize () const +unsigned int Transaction::getMemSize() const { return 0; } -void Transaction::Save (Base::Writer &/*writer*/) const +void Transaction::Save(Base::Writer& /*writer*/) const { assert(0); } -void Transaction::Restore(Base::XMLReader &/*reader*/) +void Transaction::Restore(Base::XMLReader& /*reader*/) { assert(0); } @@ -134,18 +139,17 @@ bool Transaction::isEmpty() const return _Objects.empty(); } -bool Transaction::hasObject(const TransactionalObject *Obj) const +bool Transaction::hasObject(const TransactionalObject* Obj) const { return !!_Objects.get<1>().count(Obj); } -void Transaction::addOrRemoveProperty(TransactionalObject *Obj, - const Property* pcProp, bool add) +void Transaction::addOrRemoveProperty(TransactionalObject* Obj, const Property* pcProp, bool add) { - auto &index = _Objects.get<1>(); + auto& index = _Objects.get<1>(); auto pos = index.find(Obj); - TransactionObject *To; + TransactionObject* To; if (pos != index.end()) { To = pos->second; @@ -153,44 +157,49 @@ void Transaction::addOrRemoveProperty(TransactionalObject *Obj, else { To = TransactionFactory::instance().createTransaction(Obj->getTypeId()); To->status = TransactionObject::Chn; - index.emplace(Obj,To); + index.emplace(Obj, To); } - To->addOrRemoveProperty(pcProp,add); + To->addOrRemoveProperty(pcProp, add); } //************************************************************************** // separator for other implementation aspects -void Transaction::apply(Document &Doc, bool forward) +void Transaction::apply(Document& Doc, bool forward) { std::string errMsg; try { - auto &index = _Objects.get<0>(); - for(auto &info : index) + auto& index = _Objects.get<0>(); + for (auto& info : index) { info.second->applyDel(Doc, const_cast(info.first)); - for(auto &info : index) + } + for (auto& info : index) { info.second->applyNew(Doc, const_cast(info.first)); - for(auto &info : index) + } + for (auto& info : index) { info.second->applyChn(Doc, const_cast(info.first), forward); - }catch(Base::Exception &e) { + } + } + catch (Base::Exception& e) { e.ReportException(); errMsg = e.what(); - }catch(std::exception &e) { + } + catch (std::exception& e) { errMsg = e.what(); - }catch(...) { + } + catch (...) { errMsg = "Unknown exception"; } - if(!errMsg.empty()) { - FC_ERR("Exception on " << (forward?"redo":"undo") << " '" - << Name << "':" << errMsg); + if (!errMsg.empty()) { + FC_ERR("Exception on " << (forward ? "redo" : "undo") << " '" << Name << "':" << errMsg); } } -void Transaction::addObjectNew(TransactionalObject *Obj) +void Transaction::addObjectNew(TransactionalObject* Obj) { - auto &index = _Objects.get<1>(); + auto& index = _Objects.get<1>(); auto pos = index.find(Obj); if (pos != index.end()) { if (pos->second->status == TransactionObject::Del) { @@ -205,21 +214,21 @@ void Transaction::addObjectNew(TransactionalObject *Obj) pos->second->status = TransactionObject::New; pos->second->_NameInDocument = Obj->detachFromDocument(); // move item at the end to make sure the order of removal is kept - auto &seq = _Objects.get<0>(); - seq.relocate(seq.end(),_Objects.project<0>(pos)); + auto& seq = _Objects.get<0>(); + seq.relocate(seq.end(), _Objects.project<0>(pos)); } } else { - TransactionObject *To = TransactionFactory::instance().createTransaction(Obj->getTypeId()); + TransactionObject* To = TransactionFactory::instance().createTransaction(Obj->getTypeId()); To->status = TransactionObject::New; To->_NameInDocument = Obj->detachFromDocument(); - index.emplace(Obj,To); + index.emplace(Obj, To); } } -void Transaction::addObjectDel(const TransactionalObject *Obj) +void Transaction::addObjectDel(const TransactionalObject* Obj) { - auto &index = _Objects.get<1>(); + auto& index = _Objects.get<1>(); auto pos = index.find(Obj); // is it created in this transaction ? @@ -232,18 +241,18 @@ void Transaction::addObjectDel(const TransactionalObject *Obj) pos->second->status = TransactionObject::Del; } else { - TransactionObject *To = TransactionFactory::instance().createTransaction(Obj->getTypeId()); + TransactionObject* To = TransactionFactory::instance().createTransaction(Obj->getTypeId()); To->status = TransactionObject::Del; - index.emplace(Obj,To); + index.emplace(Obj, To); } } -void Transaction::addObjectChange(const TransactionalObject *Obj, const Property *Prop) +void Transaction::addObjectChange(const TransactionalObject* Obj, const Property* Prop) { - auto &index = _Objects.get<1>(); + auto& index = _Objects.get<1>(); auto pos = index.find(Obj); - TransactionObject *To; + TransactionObject* To; if (pos != index.end()) { To = pos->second; @@ -251,7 +260,7 @@ void Transaction::addObjectChange(const TransactionalObject *Obj, const Property else { To = TransactionFactory::instance().createTransaction(Obj->getTypeId()); To->status = TransactionObject::Chn; - index.emplace(Obj,To); + index.emplace(Obj, To); } To->setProperty(Prop); @@ -280,27 +289,26 @@ TransactionObject::TransactionObject() = default; */ TransactionObject::~TransactionObject() { - for(auto &v : _PropChangeMap) + for (auto& v : _PropChangeMap) { delete v.second.property; + } } -void TransactionObject::applyDel(Document & /*Doc*/, TransactionalObject * /*pcObj*/) -{ -} +void TransactionObject::applyDel(Document& /*Doc*/, TransactionalObject* /*pcObj*/) +{} -void TransactionObject::applyNew(Document & /*Doc*/, TransactionalObject * /*pcObj*/) -{ -} +void TransactionObject::applyNew(Document& /*Doc*/, TransactionalObject* /*pcObj*/) +{} -void TransactionObject::applyChn(Document & /*Doc*/, TransactionalObject *pcObj, bool /* Forward */) +void TransactionObject::applyChn(Document& /*Doc*/, TransactionalObject* pcObj, bool /* Forward */) { if (status == New || status == Chn) { // Property change order is not preserved, as it is recursive in nature - for(auto &v : _PropChangeMap) { - auto &data = v.second; + for (auto& v : _PropChangeMap) { + auto& data = v.second; auto prop = const_cast(data.propertyOrig); - if(!data.property) { + if (!data.property) { // here means we are undoing/redoing and property add operation pcObj->removeDynamicProperty(v.second.name.c_str()); continue; @@ -310,9 +318,10 @@ void TransactionObject::applyChn(Document & /*Doc*/, TransactionalObject *pcObj, // been destroies. We must prepare for the case where user removed // a dynamic property but does not recordered as transaction. auto name = pcObj->getPropertyName(prop); - if(!name || (!data.name.empty() && data.name != name) || data.propertyType != prop->getTypeId()) { + if (!name || (!data.name.empty() && data.name != name) + || data.propertyType != prop->getTypeId()) { // Here means the original property is not found, probably removed - if(data.name.empty()) { + if (data.name.empty()) { // not a dynamic property, nothing to do continue; } @@ -322,14 +331,18 @@ void TransactionObject::applyChn(Document & /*Doc*/, TransactionalObject *pcObj, // a new property, the property key inside redo stack will not // match. So we search by name first. prop = pcObj->getDynamicPropertyByName(data.name.c_str()); - if(!prop) { + if (!prop) { // Still not found, re-create the property - prop = pcObj->addDynamicProperty( - data.propertyType.getName(), - data.name.c_str(), data.group.c_str(), data.doc.c_str(), - data.attr, data.readonly, data.hidden); - if(!prop) + prop = pcObj->addDynamicProperty(data.propertyType.getName(), + data.name.c_str(), + data.group.c_str(), + data.doc.c_str(), + data.attr, + data.readonly, + data.hidden); + if (!prop) { continue; + } prop->setStatusValue(data.property->getStatus()); } } @@ -349,22 +362,25 @@ void TransactionObject::applyChn(Document & /*Doc*/, TransactionalObject *pcObj, // } try { prop->Paste(*data.property); - } catch (Base::Exception &e) { + } + catch (Base::Exception& e) { e.ReportException(); FC_ERR("exception while restoring " << prop->getFullName() << ": " << e.what()); - } catch (std::exception &e) { + } + catch (std::exception& e) { FC_ERR("exception while restoring " << prop->getFullName() << ": " << e.what()); - } catch (...) - {} + } + catch (...) { + } } } } void TransactionObject::setProperty(const Property* pcProp) { - auto &data = _PropChangeMap[pcProp->getID()]; - if(!data.property && data.name.empty()) { - static_cast(data) = + auto& data = _PropChangeMap[pcProp->getID()]; + if (!data.property && data.name.empty()) { + static_cast(data) = pcProp->getContainer()->getDynamicPropertyData(pcProp); data.propertyOrig = pcProp; data.property = pcProp->Copy(); @@ -376,27 +392,29 @@ void TransactionObject::setProperty(const Property* pcProp) void TransactionObject::addOrRemoveProperty(const Property* pcProp, bool add) { (void)add; - if(!pcProp || !pcProp->getContainer()) + if (!pcProp || !pcProp->getContainer()) { return; + } - auto &data = _PropChangeMap[pcProp->getID()]; - if(!data.name.empty()) { - if(!add && !data.property) { + auto& data = _PropChangeMap[pcProp->getID()]; + if (!data.name.empty()) { + if (!add && !data.property) { // this means add and remove the same property inside a single // transaction, so they cancel each other out. _PropChangeMap.erase(pcProp->getID()); } return; } - if(data.property) { + if (data.property) { delete data.property; data.property = nullptr; } data.propertyOrig = pcProp; - static_cast(data) = + static_cast(data) = pcProp->getContainer()->getDynamicPropertyData(pcProp); - if(add) + if (add) { data.property = nullptr; + } else { data.property = pcProp->Copy(); data.propertyType = pcProp->getTypeId(); @@ -404,17 +422,17 @@ void TransactionObject::addOrRemoveProperty(const Property* pcProp, bool add) } } -unsigned int TransactionObject::getMemSize () const +unsigned int TransactionObject::getMemSize() const { return 0; } -void TransactionObject::Save (Base::Writer &/*writer*/) const +void TransactionObject::Save(Base::Writer& /*writer*/) const { assert(0); } -void TransactionObject::Restore(Base::XMLReader &/*reader*/) +void TransactionObject::Restore(Base::XMLReader& /*reader*/) { assert(0); } @@ -441,18 +459,19 @@ TransactionDocumentObject::TransactionDocumentObject() = default; */ TransactionDocumentObject::~TransactionDocumentObject() = default; -void TransactionDocumentObject::applyDel(Document &Doc, TransactionalObject *pcObj) +void TransactionDocumentObject::applyDel(Document& Doc, TransactionalObject* pcObj) { if (status == Del) { DocumentObject* obj = static_cast(pcObj); #ifndef USE_OLD_DAG - //Make sure the backlinks of all linked objects are updated. As the links of the removed - //object are never set to [] they also do not remove the backlink. But as they are - //not in the document anymore we need to remove them anyway to ensure a correct graph + // Make sure the backlinks of all linked objects are updated. As the links of the removed + // object are never set to [] they also do not remove the backlink. But as they are + // not in the document anymore we need to remove them anyway to ensure a correct graph auto list = obj->getOutList(); - for (auto link : list) + for (auto link : list) { link->_removeBackLink(obj); + } #endif // simply filling in the saved object @@ -460,17 +479,18 @@ void TransactionDocumentObject::applyDel(Document &Doc, TransactionalObject *pcO } } -void TransactionDocumentObject::applyNew(Document &Doc, TransactionalObject *pcObj) +void TransactionDocumentObject::applyNew(Document& Doc, TransactionalObject* pcObj) { if (status == New) { DocumentObject* obj = static_cast(pcObj); Doc._addObject(obj, _NameInDocument.c_str()); #ifndef USE_OLD_DAG - //make sure the backlinks of all linked objects are updated + // make sure the backlinks of all linked objects are updated auto list = obj->getOutList(); - for (auto link : list) + for (auto link : list) { link->_addBackLink(obj); + } #endif } } @@ -484,8 +504,9 @@ App::TransactionFactory* App::TransactionFactory::self = nullptr; TransactionFactory& TransactionFactory::instance() { - if (!self) + if (!self) { self = new TransactionFactory; + } return *self; } @@ -495,7 +516,7 @@ void TransactionFactory::destruct() self = nullptr; } -void TransactionFactory::addProducer (const Base::Type& type, Base::AbstractProducer *producer) +void TransactionFactory::addProducer(const Base::Type& type, Base::AbstractProducer* producer) { producers[type] = producer; } @@ -503,7 +524,7 @@ void TransactionFactory::addProducer (const Base::Type& type, Base::AbstractProd /** * Creates a transaction object for the given type id. */ -TransactionObject* TransactionFactory::createTransaction (const Base::Type& type) const +TransactionObject* TransactionFactory::createTransaction(const Base::Type& type) const { std::map::const_iterator it; for (it = producers.begin(); it != producers.end(); ++it) { diff --git a/src/App/Transactions.h b/src/App/Transactions.h index 93bc592c6e..494f59d162 100644 --- a/src/App/Transactions.h +++ b/src/App/Transactions.h @@ -42,7 +42,7 @@ class TransactionalObject; /** Represents a atomic transaction of the document */ -class AppExport Transaction : public Base::Persistence +class AppExport Transaction: public Base::Persistence { TYPESYSTEM_HEADER_WITH_OVERRIDE(); @@ -60,15 +60,15 @@ public: ~Transaction() override; /// apply the content to the document - void apply(Document &Doc,bool forward); + void apply(Document& Doc, bool forward); // the utf-8 name of the transaction std::string Name; - unsigned int getMemSize () const override; - void Save (Base::Writer &writer) const override; + unsigned int getMemSize() const override; + void Save(Base::Writer& writer) const override; /// This method is used to restore properties from an XML document. - void Restore(Base::XMLReader &reader) override; + void Restore(Base::XMLReader& reader) override; /// Return the transaction ID int getID() const; @@ -80,12 +80,12 @@ public: /// Returns true if the transaction list is empty; otherwise returns false. bool isEmpty() const; /// check if this object is used in a transaction - bool hasObject(const TransactionalObject *Obj) const; - void addOrRemoveProperty(TransactionalObject *Obj, const Property* pcProp, bool add); + bool hasObject(const TransactionalObject* Obj) const; + void addOrRemoveProperty(TransactionalObject* Obj, const Property* pcProp, bool add); - void addObjectNew(TransactionalObject *Obj); - void addObjectDel(const TransactionalObject *Obj); - void addObjectChange(const TransactionalObject *Obj, const Property *Prop); + void addObjectNew(TransactionalObject* Obj); + void addObjectDel(const TransactionalObject* Obj); + void addObjectChange(const TransactionalObject* Obj, const Property* Prop); private: int transID; @@ -94,16 +94,13 @@ private: Info, bmi::indexed_by< bmi::sequenced<>, - bmi::hashed_unique< - bmi::member - > - > - > _Objects; + bmi::hashed_unique>>> + _Objects; }; /** Represents an entry for an object in a Transaction */ -class AppExport TransactionObject : public Base::Persistence +class AppExport TransactionObject: public Base::Persistence { TYPESYSTEM_HEADER_WITH_OVERRIDE(); @@ -113,26 +110,32 @@ public: /// Destruction ~TransactionObject() override; - virtual void applyNew(Document &Doc, TransactionalObject *pcObj); - virtual void applyDel(Document &Doc, TransactionalObject *pcObj); - virtual void applyChn(Document &Doc, TransactionalObject *pcObj, bool Forward); + virtual void applyNew(Document& Doc, TransactionalObject* pcObj); + virtual void applyDel(Document& Doc, TransactionalObject* pcObj); + virtual void applyChn(Document& Doc, TransactionalObject* pcObj, bool Forward); void setProperty(const Property* pcProp); void addOrRemoveProperty(const Property* pcProp, bool add); - unsigned int getMemSize () const override; - void Save (Base::Writer &writer) const override; + unsigned int getMemSize() const override; + void Save(Base::Writer& writer) const override; /// This method is used to restore properties from an XML document. - void Restore(Base::XMLReader &reader) override; + void Restore(Base::XMLReader& reader) override; friend class Transaction; protected: - enum Status {New,Del,Chn} status{New}; + enum Status + { + New, + Del, + Chn + } status {New}; - struct PropData : DynamicProperty::PropData { + struct PropData: DynamicProperty::PropData + { Base::Type propertyType; - const Property *propertyOrig = nullptr; + const Property* propertyOrig = nullptr; }; std::unordered_map _PropChangeMap; @@ -141,7 +144,7 @@ protected: /** Represents an entry for a document object in a transaction */ -class AppExport TransactionDocumentObject : public TransactionObject +class AppExport TransactionDocumentObject: public TransactionObject { TYPESYSTEM_HEADER_WITH_OVERRIDE(); @@ -151,18 +154,18 @@ public: /// Destruction ~TransactionDocumentObject() override; - void applyNew(Document &Doc, TransactionalObject *pcObj) override; - void applyDel(Document &Doc, TransactionalObject *pcObj) override; + void applyNew(Document& Doc, TransactionalObject* pcObj) override; + void applyDel(Document& Doc, TransactionalObject* pcObj) override; }; class AppExport TransactionFactory { public: static TransactionFactory& instance(); - static void destruct (); + static void destruct(); - TransactionObject* createTransaction (const Base::Type& type) const; - void addProducer (const Base::Type& type, Base::AbstractProducer *producer); + TransactionObject* createTransaction(const Base::Type& type) const; + void addProducer(const Base::Type& type, Base::AbstractProducer* producer); private: static TransactionFactory* self; @@ -172,27 +175,26 @@ private: ~TransactionFactory() = default; }; -template -class TransactionProducer : public Base::AbstractProducer +template +class TransactionProducer: public Base::AbstractProducer { public: - explicit TransactionProducer (const Base::Type& type) + explicit TransactionProducer(const Base::Type& type) { TransactionFactory::instance().addProducer(type, this); } - ~TransactionProducer () override = default; + ~TransactionProducer() override = default; /** * Creates an instance of the specified transaction object. */ - void* Produce () const override + void* Produce() const override { return (new CLASS); } }; -} //namespace App - -#endif // APP_TRANSACTION_H +} // namespace App +#endif // APP_TRANSACTION_H diff --git a/src/App/VRMLObject.cpp b/src/App/VRMLObject.cpp index 8dd6ae1f2c..6844fd9327 100644 --- a/src/App/VRMLObject.cpp +++ b/src/App/VRMLObject.cpp @@ -40,11 +40,17 @@ PROPERTY_SOURCE(App::VRMLObject, App::GeoFeature) VRMLObject::VRMLObject() { - ADD_PROPERTY_TYPE(VrmlFile,(nullptr),"",Prop_None,"Included file with the VRML definition"); - ADD_PROPERTY_TYPE(Urls,(""),"",static_cast(Prop_ReadOnly|Prop_Output|Prop_Transient), - "Resource files loaded by the VRML file"); - ADD_PROPERTY_TYPE(Resources,(""),"",static_cast(Prop_ReadOnly|Prop_Output), - "Resource files loaded by the VRML file"); + ADD_PROPERTY_TYPE(VrmlFile, (nullptr), "", Prop_None, "Included file with the VRML definition"); + ADD_PROPERTY_TYPE(Urls, + (""), + "", + static_cast(Prop_ReadOnly | Prop_Output | Prop_Transient), + "Resource files loaded by the VRML file"); + ADD_PROPERTY_TYPE(Resources, + (""), + "", + static_cast(Prop_ReadOnly | Prop_Output), + "Resource files loaded by the VRML file"); Urls.setSize(0); Resources.setSize(0); } @@ -82,16 +88,17 @@ void VRMLObject::onChanged(const App::Property* prop) GeoFeature::onChanged(prop); } -PyObject *VRMLObject::getPyObject() +PyObject* VRMLObject::getPyObject() { - if (PythonObject.is(Py::_None())){ + if (PythonObject.is(Py::_None())) { // ref counter is set to 1 - PythonObject = Py::Object(new DocumentObjectPy(this),true); + PythonObject = Py::Object(new DocumentObjectPy(this), true); } - return Py::new_reference_to(PythonObject); + return Py::new_reference_to(PythonObject); } -std::string VRMLObject::getRelativePath(const std::string& prefix, const std::string& resource) const +std::string VRMLObject::getRelativePath(const std::string& prefix, + const std::string& resource) const { std::string str; std::string intname = this->getNameInDocument(); @@ -136,38 +143,38 @@ void VRMLObject::makeDirectories(const std::string& path, const std::string& sub if (!fi.createDirectory()) { break; } - pos = subdir.find('/', pos+1); + pos = subdir.find('/', pos + 1); } } -void VRMLObject::Save (Base::Writer &writer) const +void VRMLObject::Save(Base::Writer& writer) const { App::GeoFeature::Save(writer); // save also the inline files if there const std::vector& urls = Resources.getValues(); - for (const auto & url : urls) { + for (const auto& url : urls) { writer.addFile(url.c_str(), this); } this->indexSave = 0; } -void VRMLObject::Restore(Base::XMLReader &reader) +void VRMLObject::Restore(Base::XMLReader& reader) { App::GeoFeature::Restore(reader); Urls.setSize(Resources.getSize()); // restore also the inline files if there const std::vector& urls = Resources.getValues(); - for(const auto & url : urls) { + for (const auto& url : urls) { reader.addFile(url.c_str(), this); } this->indexRestore = 0; } -void VRMLObject::SaveDocFile (Base::Writer &writer) const +void VRMLObject::SaveDocFile(Base::Writer& writer) const { // store the inline files of the VRML file if (this->indexSave < Urls.getSize()) { @@ -192,7 +199,7 @@ void VRMLObject::SaveDocFile (Base::Writer &writer) const } } -bool VRMLObject::restoreTextureFinished(Base::Reader &reader) +bool VRMLObject::restoreTextureFinished(Base::Reader& reader) { Base::StateLocker locker(restoreData, true); if (this->indexRestore < Resources.getSize()) { @@ -228,7 +235,7 @@ void VRMLObject::reloadFile() this->vrmlPath = fi.dirPath(); } -void VRMLObject::RestoreDocFile(Base::Reader &reader) +void VRMLObject::RestoreDocFile(Base::Reader& reader) { if (restoreTextureFinished(reader)) { reloadFile(); diff --git a/src/App/VRMLObject.h b/src/App/VRMLObject.h index f2f8abf2d4..23474ce47e 100644 --- a/src/App/VRMLObject.h +++ b/src/App/VRMLObject.h @@ -31,7 +31,7 @@ namespace App { -class AppExport VRMLObject : public GeoFeature +class AppExport VRMLObject: public GeoFeature { PROPERTY_HEADER_WITH_OVERRIDE(App::VRMLObject); @@ -40,24 +40,26 @@ public: VRMLObject(); /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "Gui::ViewProviderVRMLObject"; } - DocumentObjectExecReturn *execute() override { + DocumentObjectExecReturn* execute() override + { return DocumentObject::StdReturn; } short mustExecute() const override; - PyObject *getPyObject() override; - void Save (Base::Writer &writer) const override; - void Restore(Base::XMLReader &reader) override; - void SaveDocFile (Base::Writer &writer) const override; - void RestoreDocFile(Base::Reader &reader) override; + PyObject* getPyObject() override; + void Save(Base::Writer& writer) const override; + void Restore(Base::XMLReader& reader) override; + void SaveDocFile(Base::Writer& writer) const override; + void RestoreDocFile(Base::Reader& reader) override; - //NOLINTBEGIN + // NOLINTBEGIN PropertyFileIncluded VrmlFile; PropertyStringList Urls; PropertyStringList Resources; - //NOLINTEND + // NOLINTEND protected: void onChanged(const App::Property*) override; @@ -66,7 +68,7 @@ private: std::string getRelativePath(const std::string& prefix, const std::string& resource) const; static std::string fixRelativePath(const std::string& name, const std::string& resource); static void makeDirectories(const std::string& path, const std::string& subdir); - bool restoreTextureFinished(Base::Reader &reader); + bool restoreTextureFinished(Base::Reader& reader); void reloadFile(); private: @@ -76,7 +78,7 @@ private: mutable bool restoreData {false}; }; -} //namespace App +} // namespace App -#endif // APP_INVENTOROBJECT_H +#endif // APP_INVENTOROBJECT_H diff --git a/src/App/VarSet.cpp b/src/App/VarSet.cpp index a8ea0fe5a3..c02ba03430 100644 --- a/src/App/VarSet.cpp +++ b/src/App/VarSet.cpp @@ -37,4 +37,3 @@ const char* VarSet::getViewProviderName() const { return "Gui::ViewProviderVarSet"; } - diff --git a/src/App/VarSet.h b/src/App/VarSet.h index 9d55ca680a..e83edb2ba0 100644 --- a/src/App/VarSet.h +++ b/src/App/VarSet.h @@ -29,18 +29,17 @@ namespace App { /** A DocumentObject class with the purpose to store variables -*/ -class AppExport VarSet : public App::DocumentObject + */ +class AppExport VarSet: public App::DocumentObject { PROPERTY_HEADER_WITH_OVERRIDE(App::VarSet); - -public: +public: VarSet() = default; ~VarSet() override = default; const char* getViewProviderName() const override; }; -} +} // namespace App #endif diff --git a/src/App/core-app.dox b/src/App/core-app.dox index be3f806d40..1a5f38b0e9 100644 --- a/src/App/core-app.dox +++ b/src/App/core-app.dox @@ -13,4 +13,3 @@ */ - diff --git a/src/App/private/DocumentP.h b/src/App/private/DocumentP.h index f3930a442d..b0098f1715 100644 --- a/src/App/private/DocumentP.h +++ b/src/App/private/DocumentP.h @@ -24,7 +24,7 @@ #define APP_DOCUMENTP_H #ifdef _MSC_VER -#pragma warning( disable : 4834 ) +#pragma warning(disable : 4834) #endif #include @@ -38,22 +38,23 @@ // using VertexProperty = boost::property; -using DependencyList = boost::adjacency_list < -boost::vecS, // class OutEdgeListS : a Sequence or an AssociativeContainer -boost::vecS, // class VertexListS : a Sequence or a RandomAccessContainer -boost::directedS, // class DirectedS : This is a directed graph -boost::no_property, // class VertexProperty: -boost::no_property, // class EdgeProperty: -boost::no_property, // class GraphProperty: -boost::listS // class EdgeListS: ->; +using DependencyList = boost::adjacency_list< + boost::vecS, // class OutEdgeListS : a Sequence or an AssociativeContainer + boost::vecS, // class VertexListS : a Sequence or a RandomAccessContainer + boost::directedS, // class DirectedS : This is a directed graph + boost::no_property, // class VertexProperty: + boost::no_property, // class EdgeProperty: + boost::no_property, // class GraphProperty: + boost::listS // class EdgeListS: + >; using Traits = boost::graph_traits; using Vertex = Traits::vertex_descriptor; -using Edge = Traits::edge_descriptor; -using Node = std::vector ; -using Path = std::vector ; +using Edge = Traits::edge_descriptor; +using Node = std::vector; +using Path = std::vector; -namespace App { +namespace App +{ using HasherMap = boost::bimap; class Transaction; @@ -69,12 +70,12 @@ struct DocumentP std::vector pendingRemove; long lastObjectId; DocumentObject* activeObject; - Transaction *activeUndoTransaction; + Transaction* activeUndoTransaction; // pointer to the python class Py::Object DocumentPythonObject; int iTransactionMode; bool rollback; - bool undoing; ///< document in the middle of undo or redo + bool undoing; ///< document in the middle of undo or redo bool committing; bool opentransaction; std::bitset<32> StatusBits; @@ -87,66 +88,77 @@ struct DocumentP DependencyList DepList; std::map VertexObjectList; std::map vertexMap; -#endif //USE_OLD_DAG - std::multimap > _RecomputeLog; +#endif // USE_OLD_DAG + std::multimap> + _RecomputeLog; StringHasherRef Hasher; DocumentP(); - void addRecomputeLog(const char *why, App::DocumentObject *obj) { + void addRecomputeLog(const char* why, App::DocumentObject* obj) + { addRecomputeLog(new DocumentObjectExecReturn(why, obj)); } - void addRecomputeLog(const std::string &why, App::DocumentObject *obj) { + void addRecomputeLog(const std::string& why, App::DocumentObject* obj) + { addRecomputeLog(new DocumentObjectExecReturn(why, obj)); } - void addRecomputeLog(DocumentObjectExecReturn *returnCode) { - if(!returnCode->Which) { + void addRecomputeLog(DocumentObjectExecReturn* returnCode) + { + if (!returnCode->Which) { delete returnCode; return; } - _RecomputeLog.emplace(returnCode->Which, std::unique_ptr(returnCode)); + _RecomputeLog.emplace(returnCode->Which, + std::unique_ptr(returnCode)); returnCode->Which->setStatus(ObjectStatus::Error, true); } - void clearRecomputeLog(const App::DocumentObject *obj=nullptr) { - if(!obj) + void clearRecomputeLog(const App::DocumentObject* obj = nullptr) + { + if (!obj) { _RecomputeLog.clear(); - else + } + else { _RecomputeLog.erase(obj); + } } - void clearDocument() { + void clearDocument() + { objectArray.clear(); - for(auto &v : objectMap) { + for (auto& v : objectMap) { v.second->setStatus(ObjectStatus::Destroy, true); - delete(v.second); + delete (v.second); v.second = nullptr; } objectMap.clear(); objectIdMap.clear(); } - const char *findRecomputeLog(const App::DocumentObject *obj) { + const char* findRecomputeLog(const App::DocumentObject* obj) + { auto range = _RecomputeLog.equal_range(obj); - if(range.first == range.second) + if (range.first == range.second) { return nullptr; + } return (--range.second)->second->Why.c_str(); } - static - void findAllPathsAt(const std::vector &all_nodes, size_t id, - std::vector &all_paths, Path tmp); + static void findAllPathsAt(const std::vector& all_nodes, + size_t id, + std::vector& all_paths, + Path tmp); std::vector topologicalSort(const std::vector& objects) const; - std::vector - static partialTopologicalSort(const std::vector& objects); + static std::vector partialTopologicalSort( + const std::vector& objects); static void checkStringHasher(const Base::XMLReader& reader); }; -} // namespace App +} // namespace App -#endif // APP_DOCUMENTP_H +#endif // APP_DOCUMENTP_H