diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 6ab625095d..0fc1cf62a2 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -453,7 +453,7 @@ void Application::renameDocument(const char *OldName, const char *NewName) throw Base::RuntimeError("Renaming document internal name is no longer allowed!"); } -Document* Application::newDocument(const char * Name, const char * UserName, bool createView, bool tempDoc) +Document* Application::newDocument(const char * Name, const char * UserName, DocumentCreateFlags CreateFlags) { auto getNameAndLabel = [this](const char * Name, const char * UserName) -> std::tuple { bool defaultName = (!Name || Name[0] == '\0'); @@ -487,10 +487,10 @@ Document* Application::newDocument(const char * Name, const char * UserName, boo auto tuple = getNameAndLabel(Name, UserName); std::string name = std::get<0>(tuple); std::string userName = std::get<1>(tuple); - name = getUniqueDocumentName(name.c_str(), tempDoc); + name = getUniqueDocumentName(name.c_str(), CreateFlags.temporary); // return the temporary document if it exists - if (tempDoc) { + if (CreateFlags.temporary) { auto it = DocMap.find(name); if (it != DocMap.end() && it->second->testStatus(Document::TempDoc)) return it->second; @@ -498,7 +498,7 @@ Document* Application::newDocument(const char * Name, const char * UserName, boo // create the FreeCAD document std::unique_ptr newDoc(new Document(name.c_str())); - newDoc->setStatus(Document::TempDoc, tempDoc); + newDoc->setStatus(Document::TempDoc, CreateFlags.temporary); auto oldActiveDoc = _pActiveDoc; auto doc = newDoc.release(); // now owned by the Application @@ -539,13 +539,13 @@ Document* Application::newDocument(const char * Name, const char * UserName, boo Py::Module("FreeCAD").setAttr(std::string("ActiveDocument"), active); } - signalNewDocument(*_pActiveDoc, createView); + signalNewDocument(*_pActiveDoc, CreateFlags.createView); // set the UserName after notifying all observers _pActiveDoc->Label.setValue(userName); // set the old document active again if the new is temporary - if (tempDoc && oldActiveDoc) + if (CreateFlags.temporary && oldActiveDoc) setActiveDocument(oldActiveDoc); return doc; @@ -701,9 +701,9 @@ public: } }; -Document* Application::openDocument(const char * FileName, bool createView) { +Document* Application::openDocument(const char * FileName, DocumentCreateFlags createFlags) { std::vector filenames(1,FileName); - auto docs = openDocuments(filenames, nullptr, nullptr, nullptr, createView); + auto docs = openDocuments(filenames, nullptr, nullptr, nullptr, createFlags); if(!docs.empty()) return docs.front(); return nullptr; @@ -748,7 +748,7 @@ std::vector Application::openDocuments(const std::vector const std::vector *paths, const std::vector *labels, std::vector *errs, - bool createView) + DocumentCreateFlags createFlags) { std::vector res(filenames.size(), nullptr); if (filenames.empty()) @@ -812,7 +812,7 @@ std::vector Application::openDocuments(const std::vector label = (*labels)[count].c_str(); } - auto doc = openDocumentPrivate(path, name.c_str(), label, isMainDoc, createView, std::move(objNames)); + auto doc = openDocumentPrivate(path, name.c_str(), label, isMainDoc, createFlags, std::move(objNames)); FC_DURATION_PLUS(timing.d1,t1); if (doc) { timings[doc].d1 += timing.d1; @@ -951,7 +951,7 @@ std::vector Application::openDocuments(const std::vector Document* Application::openDocumentPrivate(const char * FileName, const char *propFileName, const char *label, - bool isMainDoc, bool createView, + bool isMainDoc, DocumentCreateFlags createFlags, std::vector &&objNames) { FileInfo File(FileName); @@ -1022,8 +1022,8 @@ Document* Application::openDocumentPrivate(const char * FileName, // to only contain valid ASCII characters but the user name will be kept. if(!label) label = name.c_str(); - Document* newDoc = newDocument(name.c_str(),label,isMainDoc && createView); + Document* newDoc = newDocument(name.c_str(), label, createFlags); newDoc->FileName.setValue(propFileName==FileName?File.filePath():propFileName); try { diff --git a/src/App/Application.h b/src/App/Application.h index e2a32adefe..a2be53861b 100644 --- a/src/App/Application.h +++ b/src/App/Application.h @@ -69,6 +69,10 @@ enum class MessageOption { Throw, /**< Throw an exception. */ }; +struct DocumentCreateFlags { + bool createView {true}; + bool temporary {false}; +}; /** The Application * The root of the whole application @@ -94,13 +98,13 @@ public: * the user and stored in the App::Document::Name property. */ App::Document* newDocument(const char * Name=nullptr, const char * UserName=nullptr, - bool createView=true, bool tempDoc=false); + DocumentCreateFlags CreateFlags=DocumentCreateFlags()); /// Closes the document \a name and removes it from the application. bool closeDocument(const char* name); /// find a unique document name std::string getUniqueDocumentName(const char *Name, bool tempDoc=false) const; /// Open an existing document from a file - App::Document* openDocument(const char * FileName=nullptr, bool createView=true); + App::Document* openDocument(const char * FileName=nullptr, DocumentCreateFlags createFlags = DocumentCreateFlags{}); /** Open multiple documents * * @param filenames: input file names @@ -122,7 +126,7 @@ public: const std::vector *paths=nullptr, const std::vector *labels=nullptr, std::vector *errs=nullptr, - bool createView = true); + DocumentCreateFlags createFlags = DocumentCreateFlags{}); /// Retrieve the active document App::Document* getActiveDocument() const; /// Retrieve a named document @@ -486,7 +490,7 @@ protected: /// open single document only App::Document* openDocumentPrivate(const char * FileName, const char *propFileName, - const char *label, bool isMainDoc, bool createView, std::vector &&objNames); + const char *label, bool isMainDoc, DocumentCreateFlags createFlags, std::vector &&objNames); /// Helper class for App::Document to signal on close/abort transaction class AppExport TransactionSignaller { diff --git a/src/App/ApplicationPy.cpp b/src/App/ApplicationPy.cpp index 7303d7e56c..33ad33c5ad 100644 --- a/src/App/ApplicationPy.cpp +++ b/src/App/ApplicationPy.cpp @@ -149,12 +149,13 @@ PyMethodDef Application::Methods[] = { {"openDocument", reinterpret_cast(reinterpret_cast(Application::sOpenDocument)), METH_VARARGS | METH_KEYWORDS, - "openDocument(filepath,hidden=False) -> object\n" + "openDocument(filepath,hidden=False,temporary=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."}, + "hidden: whether to hide document 3D view.\n" + "temporary: whether to hide document in the tree view."}, // {"saveDocument", (PyCFunction) Application::sSaveDocument, METH_VARARGS, // "saveDocument(string) -- Save the document to a file."}, // {"saveDocumentAs", (PyCFunction) Application::sSaveDocumentAs, METH_VARARGS}, @@ -339,23 +340,30 @@ PyObject* Application::sOpenDocument(PyObject* /*self*/, PyObject* args, PyObjec { char* Name; PyObject* hidden = Py_False; - static const std::array kwlist {"name", "hidden", nullptr}; + PyObject* temporary = Py_False; + static const std::array kwlist {"name", "hidden", "temporary", nullptr}; if (!Base::Wrapped_ParseTupleAndKeywords(args, kwd, - "et|O!", + "et|O!O!", kwlist, "utf-8", &Name, &PyBool_Type, - &hidden)) { + &hidden, + &PyBool_Type, + &temporary)) { return nullptr; } std::string EncodedName = std::string(Name); PyMem_Free(Name); try { + DocumentCreateFlags createFlags; + createFlags.createView = !Base::asBoolean(hidden); + createFlags.temporary = Base::asBoolean(temporary); + // return new document return (GetApplication() - .openDocument(EncodedName.c_str(), !Base::asBoolean(hidden)) + .openDocument(EncodedName.c_str(), createFlags) ->getPyObject()); } catch (const Base::Exception& e) { @@ -393,11 +401,13 @@ PyObject* Application::sNewDocument(PyObject* /*self*/, PyObject* args, PyObject PY_TRY { + DocumentCreateFlags createFlags; + createFlags.createView = !Base::asBoolean(hidden); + createFlags.temporary = Base::asBoolean(temp); + App::Document* doc = GetApplication().newDocument(docName, usrName, - !Base::asBoolean(hidden), - Base::asBoolean(temp)); - PyMem_Free(docName); + createFlags); PyMem_Free(usrName); return doc->getPyObject(); } diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index dec82e9aa0..383c6c87d2 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -2562,7 +2562,9 @@ App::Document* Application::reopen(App::Document* doc) } for (auto& file : docs) { - App::GetApplication().openDocument(file.c_str(), false); + App::DocumentCreateFlags createFlags; + createFlags.createView = false; + App::GetApplication().openDocument(file.c_str(), createFlags); } } diff --git a/src/Mod/Import/App/ImportOCAF2.cpp b/src/Mod/Import/App/ImportOCAF2.cpp index d4446afc4c..1cabfbb9f6 100644 --- a/src/Mod/Import/App/ImportOCAF2.cpp +++ b/src/Mod/Import/App/ImportOCAF2.cpp @@ -411,7 +411,10 @@ App::Document* ImportOCAF2::getDocument(App::Document* doc, TDF_Label label) return doc; } - auto newDoc = App::GetApplication().newDocument(name.c_str(), name.c_str(), false); + App::DocumentCreateFlags createFlags; + createFlags.createView = false; + auto newDoc = App::GetApplication().newDocument(name.c_str(), name.c_str(), createFlags); + std::ostringstream ss; Base::FileInfo fi(doc->FileName.getValue()); std::string path = fi.dirPath(); diff --git a/src/Mod/PartDesign/App/ShapeBinder.cpp b/src/Mod/PartDesign/App/ShapeBinder.cpp index 4bb358f3cb..895473d183 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.cpp +++ b/src/Mod/PartDesign/App/ShapeBinder.cpp @@ -597,8 +597,11 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) { recomputeCopy = true; clearCopiedObjects(); - auto tmpDoc = App::GetApplication().newDocument( - "_tmp_binder", nullptr, false, true); + App::DocumentCreateFlags createFlags; + createFlags.createView = false; + createFlags.temporary = true; + + auto tmpDoc = App::GetApplication().newDocument("_tmp_binder", nullptr, createFlags); tmpDoc->setUndoMode(0); auto objs = tmpDoc->copyObject({ obj }, true, true); if (!objs.empty()) { @@ -618,21 +621,21 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) { std::vector props; getPropertyList(props); // lambda for copying values of copy-on-change properties - const auto copyPropertyValues = [this, &recomputeCopy, &props, copied](const bool to_support) { + const auto copyPropertyValues = [this, &recomputeCopy, &props, copied](const bool to_support) { for (auto prop : props) { if (!App::LinkBaseExtension::isCopyOnChangeProperty(this, *prop)) continue; - // we only copy read-only and output properties from support to binder - if (!to_support && !(prop->testStatus(App::Property::Output) && prop->testStatus(App::Property::ReadOnly))) - continue; + // we only copy read-only and output properties from support to binder + if (!to_support && !(prop->testStatus(App::Property::Output) && prop->testStatus(App::Property::ReadOnly))) + continue; auto p = copied->getPropertyByName(prop->getName()); if (p && p->getContainer() == copied && p->getTypeId() == prop->getTypeId() && !p->isSame(*prop)) { recomputeCopy = true; - auto* const from = to_support ? prop : p; - auto* const to = to_support ? p : prop; + auto* const from = to_support ? prop : p; + auto* const to = to_support ? p : prop; std::unique_ptr pcopy(from->Copy()); to->Paste(*pcopy);