Revert "Address the poor performance of the existing unique-name generation (#17944)"
This reverts commit 83202d8ad6.
# Conflicts:
# src/Base/Tools.cpp
# src/Base/Tools.h
This commit is contained in:
committed by
Yorik van Havre
parent
844d88fb7a
commit
a2c980f7d6
@@ -450,16 +450,41 @@ 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 * proposedName, const char * proposedLabel, bool createView, bool tempDoc)
|
||||
Document* Application::newDocument(const char * Name, const char * UserName, bool createView, bool tempDoc)
|
||||
{
|
||||
std::string name;
|
||||
bool useDefaultName = (!proposedName || proposedName[0] == '\0');
|
||||
// get a valid name anyway!
|
||||
if (useDefaultName) {
|
||||
proposedName = "Unnamed";
|
||||
}
|
||||
auto getNameAndLabel = [this](const char * Name, const char * UserName) -> std::tuple<std::string, std::string> {
|
||||
bool defaultName = (!Name || Name[0] == '\0');
|
||||
|
||||
name = getUniqueDocumentName(proposedName, tempDoc);
|
||||
// get a valid name anyway!
|
||||
if (defaultName) {
|
||||
Name = "Unnamed";
|
||||
}
|
||||
|
||||
std::string userName;
|
||||
if (UserName && UserName[0] != '\0') {
|
||||
userName = UserName;
|
||||
}
|
||||
else {
|
||||
userName = defaultName ? QObject::tr("Unnamed").toStdString() : Name;
|
||||
|
||||
std::vector<std::string> names;
|
||||
names.reserve(DocMap.size());
|
||||
for (const auto& pos : DocMap) {
|
||||
names.emplace_back(pos.second->Label.getValue());
|
||||
}
|
||||
|
||||
if (!names.empty()) {
|
||||
userName = Base::Tools::getUniqueName(userName, names);
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_tuple(std::string(Name), userName);
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
// return the temporary document if it exists
|
||||
if (tempDoc) {
|
||||
@@ -468,65 +493,53 @@ Document* Application::newDocument(const char * proposedName, const char * propo
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// Determine the document's Label
|
||||
std::string label;
|
||||
if (proposedLabel && proposedLabel[0] != '\0') {
|
||||
label = proposedLabel;
|
||||
}
|
||||
else {
|
||||
label = useDefaultName ? QObject::tr("Unnamed").toStdString() : proposedName;
|
||||
|
||||
if (!DocMap.empty()) {
|
||||
// The assumption here is that there are not many documents and
|
||||
// documents are rarely created so the cost
|
||||
// of building this manager each time is inconsequential
|
||||
Base::UniqueNameManager names;
|
||||
for (const auto& pos : DocMap) {
|
||||
names.addExactName(pos.second->Label.getValue());
|
||||
}
|
||||
|
||||
label = names.makeUniqueName(label);
|
||||
}
|
||||
}
|
||||
// create the FreeCAD document
|
||||
Document* doc = new Document(name.c_str());
|
||||
doc->setStatus(Document::TempDoc, tempDoc);
|
||||
std::unique_ptr<Document> newDoc(new Document(name.c_str()));
|
||||
newDoc->setStatus(Document::TempDoc, tempDoc);
|
||||
|
||||
auto oldActiveDoc = _pActiveDoc;
|
||||
auto doc = newDoc.release(); // now owned by the Application
|
||||
|
||||
// add the document to the internal list
|
||||
DocMap[name] = doc;
|
||||
_pActiveDoc = doc;
|
||||
|
||||
//NOLINTBEGIN
|
||||
// clang-format off
|
||||
// connect the signals to the application for the new document
|
||||
doc->signalBeforeChange.connect(std::bind(&App::Application::slotBeforeChangeDocument, this, sp::_1, sp::_2));
|
||||
doc->signalChanged.connect(std::bind(&App::Application::slotChangedDocument, this, sp::_1, sp::_2));
|
||||
doc->signalNewObject.connect(std::bind(&App::Application::slotNewObject, this, sp::_1));
|
||||
doc->signalDeletedObject.connect(std::bind(&App::Application::slotDeletedObject, this, sp::_1));
|
||||
doc->signalBeforeChangeObject.connect(std::bind(&App::Application::slotBeforeChangeObject, this, sp::_1, sp::_2));
|
||||
doc->signalChangedObject.connect(std::bind(&App::Application::slotChangedObject, this, sp::_1, sp::_2));
|
||||
doc->signalRelabelObject.connect(std::bind(&App::Application::slotRelabelObject, this, sp::_1));
|
||||
doc->signalActivatedObject.connect(std::bind(&App::Application::slotActivatedObject, this, sp::_1));
|
||||
doc->signalUndo.connect(std::bind(&App::Application::slotUndoDocument, this, sp::_1));
|
||||
doc->signalRedo.connect(std::bind(&App::Application::slotRedoDocument, this, sp::_1));
|
||||
doc->signalRecomputedObject.connect(std::bind(&App::Application::slotRecomputedObject, this, sp::_1));
|
||||
doc->signalRecomputed.connect(std::bind(&App::Application::slotRecomputed, this, sp::_1));
|
||||
doc->signalBeforeRecompute.connect(std::bind(&App::Application::slotBeforeRecompute, this, sp::_1));
|
||||
doc->signalOpenTransaction.connect(std::bind(&App::Application::slotOpenTransaction, this, sp::_1, sp::_2));
|
||||
doc->signalCommitTransaction.connect(std::bind(&App::Application::slotCommitTransaction, this, sp::_1));
|
||||
doc->signalAbortTransaction.connect(std::bind(&App::Application::slotAbortTransaction, this, sp::_1));
|
||||
doc->signalStartSave.connect(std::bind(&App::Application::slotStartSaveDocument, this, sp::_1, sp::_2));
|
||||
doc->signalFinishSave.connect(std::bind(&App::Application::slotFinishSaveDocument, this, sp::_1, sp::_2));
|
||||
doc->signalChangePropertyEditor.connect(std::bind(&App::Application::slotChangePropertyEditor, this, sp::_1, sp::_2));
|
||||
_pActiveDoc->signalBeforeChange.connect(std::bind(&App::Application::slotBeforeChangeDocument, this, sp::_1, sp::_2));
|
||||
_pActiveDoc->signalChanged.connect(std::bind(&App::Application::slotChangedDocument, this, sp::_1, sp::_2));
|
||||
_pActiveDoc->signalNewObject.connect(std::bind(&App::Application::slotNewObject, this, sp::_1));
|
||||
_pActiveDoc->signalDeletedObject.connect(std::bind(&App::Application::slotDeletedObject, this, sp::_1));
|
||||
_pActiveDoc->signalBeforeChangeObject.connect(std::bind(&App::Application::slotBeforeChangeObject, this, sp::_1, sp::_2));
|
||||
_pActiveDoc->signalChangedObject.connect(std::bind(&App::Application::slotChangedObject, this, sp::_1, sp::_2));
|
||||
_pActiveDoc->signalRelabelObject.connect(std::bind(&App::Application::slotRelabelObject, this, sp::_1));
|
||||
_pActiveDoc->signalActivatedObject.connect(std::bind(&App::Application::slotActivatedObject, this, sp::_1));
|
||||
_pActiveDoc->signalUndo.connect(std::bind(&App::Application::slotUndoDocument, this, sp::_1));
|
||||
_pActiveDoc->signalRedo.connect(std::bind(&App::Application::slotRedoDocument, this, sp::_1));
|
||||
_pActiveDoc->signalRecomputedObject.connect(std::bind(&App::Application::slotRecomputedObject, this, sp::_1));
|
||||
_pActiveDoc->signalRecomputed.connect(std::bind(&App::Application::slotRecomputed, this, sp::_1));
|
||||
_pActiveDoc->signalBeforeRecompute.connect(std::bind(&App::Application::slotBeforeRecompute, this, sp::_1));
|
||||
_pActiveDoc->signalOpenTransaction.connect(std::bind(&App::Application::slotOpenTransaction, this, sp::_1, sp::_2));
|
||||
_pActiveDoc->signalCommitTransaction.connect(std::bind(&App::Application::slotCommitTransaction, this, sp::_1));
|
||||
_pActiveDoc->signalAbortTransaction.connect(std::bind(&App::Application::slotAbortTransaction, this, sp::_1));
|
||||
_pActiveDoc->signalStartSave.connect(std::bind(&App::Application::slotStartSaveDocument, this, sp::_1, sp::_2));
|
||||
_pActiveDoc->signalFinishSave.connect(std::bind(&App::Application::slotFinishSaveDocument, this, sp::_1, sp::_2));
|
||||
_pActiveDoc->signalChangePropertyEditor.connect(std::bind(&App::Application::slotChangePropertyEditor, this, sp::_1, sp::_2));
|
||||
// clang-format on
|
||||
//NOLINTEND
|
||||
|
||||
// (temporarily) make this the active document for the upcoming notifications.
|
||||
// Signal NewDocument rather than ActiveDocument
|
||||
auto oldActiveDoc = _pActiveDoc;
|
||||
setActiveDocumentNoSignal(doc);
|
||||
signalNewDocument(*doc, createView);
|
||||
// make sure that the active document is set in case no GUI is up
|
||||
{
|
||||
Base::PyGILStateLocker lock;
|
||||
Py::Object active(_pActiveDoc->getPyObject(), true);
|
||||
Py::Module("FreeCAD").setAttr(std::string("ActiveDocument"), active);
|
||||
}
|
||||
|
||||
doc->Label.setValue(label);
|
||||
signalNewDocument(*_pActiveDoc, 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)
|
||||
@@ -616,17 +629,13 @@ std::string Application::getUniqueDocumentName(const char *Name, bool tempDoc) c
|
||||
return CleanName;
|
||||
}
|
||||
else {
|
||||
// The assumption here is that there are not many documents and
|
||||
// documents are rarely created so the cost
|
||||
// of building this manager each time is inconsequential
|
||||
Base::UniqueNameManager names;
|
||||
for (const auto& pos : DocMap) {
|
||||
if (!tempDoc || !pos.second->testStatus(Document::TempDoc)) {
|
||||
names.addExactName(pos.first);
|
||||
}
|
||||
std::vector<std::string> names;
|
||||
names.reserve(DocMap.size());
|
||||
for (pos = DocMap.begin(); pos != DocMap.end(); ++pos) {
|
||||
if (!tempDoc || !pos->second->testStatus(Document::TempDoc))
|
||||
names.push_back(pos->first);
|
||||
}
|
||||
|
||||
return names.makeUniqueName(CleanName);
|
||||
return Base::Tools::getUniqueName(CleanName, names);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1044,14 +1053,6 @@ Document* Application::getActiveDocument() const
|
||||
}
|
||||
|
||||
void Application::setActiveDocument(Document* pDoc)
|
||||
{
|
||||
setActiveDocumentNoSignal(pDoc);
|
||||
|
||||
if (pDoc)
|
||||
signalActiveDocument(*pDoc);
|
||||
}
|
||||
|
||||
void Application::setActiveDocumentNoSignal(Document* pDoc)
|
||||
{
|
||||
_pActiveDoc = pDoc;
|
||||
|
||||
@@ -1059,15 +1060,18 @@ void Application::setActiveDocumentNoSignal(Document* pDoc)
|
||||
if (pDoc) {
|
||||
Base::PyGILStateLocker lock;
|
||||
Py::Object active(pDoc->getPyObject(), true);
|
||||
Py::Module("FreeCAD").setAttr(std::string("ActiveDocument"), active);
|
||||
Py::Module("FreeCAD").setAttr(std::string("ActiveDocument"),active);
|
||||
}
|
||||
else {
|
||||
Base::PyGILStateLocker lock;
|
||||
Py::Module("FreeCAD").setAttr(std::string("ActiveDocument"), Py::None());
|
||||
Py::Module("FreeCAD").setAttr(std::string("ActiveDocument"),Py::None());
|
||||
}
|
||||
|
||||
if (pDoc)
|
||||
signalActiveDocument(*pDoc);
|
||||
}
|
||||
|
||||
void Application::setActiveDocument(const char* Name)
|
||||
void Application::setActiveDocument(const char *Name)
|
||||
{
|
||||
// If no active document is set, resort to a default.
|
||||
if (*Name == '\0') {
|
||||
|
||||
Reference in New Issue
Block a user