From a95667f06bf8aae0e466a3f5e8c19e7a17c8ce8c Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Thu, 24 Oct 2024 18:55:02 +0200 Subject: [PATCH 01/12] Fix issue #5225: All modified 'DEF' fields are reset to their initial values when the simulation is reset. The world modified flag is only set when the simulation time is 0 and there is a change between any of the initial and modified values in the'DEF' fields. --- src/webots/nodes/utils/WbWorld.cpp | 15 ++-- src/webots/nodes/utils/WbWorld.hpp | 3 + src/webots/scene_tree/WbFieldEditor.cpp | 7 +- src/webots/scene_tree/WbNodeEditor.cpp | 105 ++++++++++++++++++++++++ src/webots/scene_tree/WbNodeEditor.hpp | 14 ++++ 5 files changed, 138 insertions(+), 6 deletions(-) diff --git a/src/webots/nodes/utils/WbWorld.cpp b/src/webots/nodes/utils/WbWorld.cpp index d7f886c4234..f8f49f93bb0 100644 --- a/src/webots/nodes/utils/WbWorld.cpp +++ b/src/webots/nodes/utils/WbWorld.cpp @@ -227,15 +227,20 @@ bool WbWorld::needSaving() const { void WbWorld::setModifiedFromSceneTree() { if (!mIsModifiedFromSceneTree) { mIsModifiedFromSceneTree = true; - setModified(); + } + if (isModifiedFromSceneTreeRestarted) { + mIsModifiedFromSceneTree = false; + isModifiedFromSceneTreeRestarted = false; } } +void WbWorld::resetModifiedFromSceneTree() { + mIsModifiedFromSceneTree = false; + isModifiedFromSceneTreeRestarted = true; +} + void WbWorld::setModified(bool isModified) { - if (mIsModified != isModified) { - mIsModified = isModified; - emit modificationChanged(isModified); - } + emit checkDefDiff(); } bool WbWorld::saveAs(const QString &fileName) { diff --git a/src/webots/nodes/utils/WbWorld.hpp b/src/webots/nodes/utils/WbWorld.hpp index f84d4054152..2a2a45de854 100644 --- a/src/webots/nodes/utils/WbWorld.hpp +++ b/src/webots/nodes/utils/WbWorld.hpp @@ -158,12 +158,14 @@ class WbWorld : public QObject { void robotAdded(WbRobot *robot); void robotRemoved(WbRobot *robot); void resetRequested(bool restartControllers); + void checkDefDiff(); public slots: void awake(); void updateVideoRecordingStatus(int status) { mIsVideoRecording = (status == WB_SUPERVISOR_MOVIE_RECORDING || status == WB_SUPERVISOR_MOVIE_SAVING); } + void resetModifiedFromSceneTree(); protected: // collecting contact and immersion geometries @@ -199,6 +201,7 @@ protected slots: bool mIsLoading; bool mIsCleaning; bool mIsVideoRecording; + bool isModifiedFromSceneTreeRestarted = false; void checkPresenceOfMandatoryNodes(); WbNode *findTopLevelNode(const QString &modelName, int preferredPosition) const; diff --git a/src/webots/scene_tree/WbFieldEditor.cpp b/src/webots/scene_tree/WbFieldEditor.cpp index 1d72afafb74..9ab51d2b2bf 100644 --- a/src/webots/scene_tree/WbFieldEditor.cpp +++ b/src/webots/scene_tree/WbFieldEditor.cpp @@ -89,7 +89,12 @@ WbFieldEditor::WbFieldEditor(QWidget *parent) : WbNodePane *const nodePane = new WbNodePane(this); const WbNodeEditor *nodeEditor = nodePane->nodeEditor(); connect(nodeEditor, &WbNodeEditor::dictionaryUpdateRequested, this, &WbFieldEditor::dictionaryUpdateRequested); - + connect(nodeEditor, &WbNodeEditor::defNameChanged, WbActionManager::instance()->action(WbAction::SAVE_WORLD), &QAction::setEnabled); + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD), &QAction::setEnabled, nodeEditor, &WbNodeEditor::resetDefNamesToInitial); + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), &QAction::setEnabled, nodeEditor, &WbNodeEditor::resetDefNamesToInitial); + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD), &QAction::triggered, nodeEditor, &WbNodeEditor::switchInitialCurrentDef); + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), &QAction::triggered, nodeEditor, &WbNodeEditor::switchInitialCurrentDef); + connect(WbActionManager::instance()->action(WbAction::RELOAD_WORLD), &QAction::triggered, nodeEditor, &WbNodeEditor::startTimer); // create editors mEditors.insert(WB_NO_FIELD, new WbEmptyEditor(this)); mEditors.insert(WB_SF_BOOL, new WbBoolEditor(this)); diff --git a/src/webots/scene_tree/WbNodeEditor.cpp b/src/webots/scene_tree/WbNodeEditor.cpp index 1950c6e5dbb..1d68deafbf7 100644 --- a/src/webots/scene_tree/WbNodeEditor.cpp +++ b/src/webots/scene_tree/WbNodeEditor.cpp @@ -33,6 +33,8 @@ #include "WbViewpoint.hpp" #include "WbVrmlNodeUtilities.hpp" #include "WbWorldInfo.hpp" +#include "WbWorld.hpp" +#include "WbActionManager.hpp" #include #include @@ -42,6 +44,7 @@ #include #include #include +#include WbNodeEditor::WbNodeEditor(QWidget *parent) : WbValueEditor(parent), @@ -52,6 +55,7 @@ WbNodeEditor::WbNodeEditor(QWidget *parent) : mNbTriangles(new QLabel(this)), mStackedWidget(new QStackedWidget(this)), mMessageBox(false), + worldCheckTimer(new QTimer(this)), mShowResizeHandlesLabel(new QLabel(tr("3D tools:"), this)), mShowResizeHandlesCheckBox(new QCheckBox(tr("show resize handles"), this)) { mShowResizeHandlesCheckBox->setChecked(false); @@ -87,6 +91,25 @@ WbNodeEditor::WbNodeEditor(QWidget *parent) : connect(mPrintUrl, &QPushButton::pressed, this, &WbNodeEditor::printUrl); connect(mShowResizeHandlesCheckBox, &QAbstractButton::toggled, WbSelection::instance(), &WbSelection::showResizeManipulatorFromSceneTree, Qt::UniqueConnection); + connect(worldCheckTimer, &QTimer::timeout, this, &WbNodeEditor::tryConnectToWorld); + worldCheckTimer->start(500); +} + +void WbNodeEditor::tryConnectToWorld() { + world = WbWorld::instance(); + state = WbSimulationState::instance(); + if (oldWorld != world) { + connect(world, &WbWorld::checkDefDiff, this, &WbNodeEditor::resetDefNamesToInitial); + connect(this, &WbNodeEditor::resetModifiedFromSceneTree, world, &WbWorld::resetModifiedFromSceneTree); + oldWorld = const_cast(world); + mInitialCurrentDefMap.clear(); + worldCheckTimer->stop(); + } +} + +void WbNodeEditor::startTimer(){ + disconnect(world, &WbWorld::checkDefDiff, this, &WbNodeEditor::resetDefNamesToInitial); + worldCheckTimer->start(500); } void WbNodeEditor::printUrl() { @@ -131,6 +154,9 @@ void WbNodeEditor::edit(bool copyOriginalValue) { mShowResizeHandlesCheckBox->setChecked(g->isResizeManipulatorAttached()); } } + + if (mNode && !mInitialCurrentDefMap.contains(mNode)) + mInitialCurrentDefMap[mNode] = QPair(mNode->defName(), QString()); } update(); @@ -198,6 +224,13 @@ void WbNodeEditor::apply() { QString newDef = mDefEdit->text(); const QString &previousDef = mNode->defName(); + QString initialDef = mInitialCurrentDefMap.value(mNode).first; // Access the first QString (initial DEF) + mInitialCurrentDefMap[mNode].second = newDef; + + bool hasStarted = state->hasStarted(); + if (!hasStarted) + this->compareInitialCurrentDef(); + if (newDef == previousDef) return; @@ -259,3 +292,75 @@ void WbNodeEditor::apply() { if (dictionaryUpdateRequest) emit dictionaryUpdateRequested(); } + +void WbNodeEditor::compareInitialCurrentDef() { + if (!mInitialCurrentDefMap.isEmpty()) { + bool foundDifference = false; + // Iterate through the QMap + for (auto it = mInitialCurrentDefMap.constBegin(); it != mInitialCurrentDefMap.constEnd(); ++it) { + const QString &initialDef = it.value().first; // First QString (initial) + const QString ¤tDef = it.value().second; // Second QString (current) + + // Compare the two QStrings + if (initialDef != currentDef) { + foundDifference = true; // Mark that a difference is found + break; + } + } + if (foundDifference) + emit defNameChanged(true); // Emit true if any difference is found + else + { + emit resetModifiedFromSceneTree(); + emit defNameChanged(false); // Emit false if no differences were found + } + } + else + emit defNameChanged(false); // If all QStrings are the same, return false +} + +void WbNodeEditor::resetDefNamesToInitial() { + // Check if the map is empty + if (mInitialCurrentDefMap.isEmpty()) { + emit defNameChanged(false); + return; + } + + // Iterate through the map and reset each node's DEF name to its initial value + for (auto it = mInitialCurrentDefMap.begin(); it != mInitialCurrentDefMap.end(); ++it) { + WbNode *node = it.key(); + const QString &initialDef = it.value().first; // Access initial DEF name + + // Only reset if node exists and the current DEF differs from the initial one + if (node && node->defName() != initialDef) + node->setDefName(initialDef); // Set the DEF name back to the initial one + } + + update(); + + emit defNameChanged(false); + emit resetModifiedFromSceneTree(); +} + +void WbNodeEditor::switchInitialCurrentDef() { + // Check if the map is empty + if (mInitialCurrentDefMap.isEmpty()) { + emit defNameChanged(false); + return; + } + + // Iterate through the map and switch the initial DEF to the current one + for (auto it = mInitialCurrentDefMap.begin(); it != mInitialCurrentDefMap.end(); ++it) { + WbNode *node = it.key(); + QString &initialDef = it.value().first; // Reference to initial DEF name + const QString ¤tDef = node->defName(); // Get the current DEF name of the node + + // Switch the initial DEF to the current DEF + if (node && initialDef != currentDef) + initialDef = currentDef; // Update the initial DEF with the current one + } + + update(); + + emit defNameChanged(false); +} diff --git a/src/webots/scene_tree/WbNodeEditor.hpp b/src/webots/scene_tree/WbNodeEditor.hpp index 8c1932a1b40..50fef6b1b78 100644 --- a/src/webots/scene_tree/WbNodeEditor.hpp +++ b/src/webots/scene_tree/WbNodeEditor.hpp @@ -20,6 +20,8 @@ // #include "WbValueEditor.hpp" +#include "WbWorld.hpp" +#include "WbSimulationState.hpp" class WbFieldLineEdit; class WbNode; @@ -47,10 +49,15 @@ class WbNodeEditor : public WbValueEditor { signals: void dictionaryUpdateRequested(); + void defNameChanged(bool changed); + void resetModifiedFromSceneTree(); public slots: void apply() override; void cleanValue() override; + void resetDefNamesToInitial(); + void switchInitialCurrentDef(); + void startTimer(); protected: enum PaneType { DEF_PANE, EMPTY_PANE }; @@ -63,6 +70,11 @@ public slots: QLabel *mNbTriangles; QStackedWidget *mStackedWidget; bool mMessageBox; + QMap> mInitialCurrentDefMap; + QTimer *worldCheckTimer; + const WbWorld *world = nullptr; + WbWorld *oldWorld = nullptr; + WbSimulationState *state = nullptr; // actions buttons QLabel *mShowResizeHandlesLabel; @@ -71,6 +83,8 @@ public slots: void setTransformActionVisibile(bool visible); void takeKeyboardFocus() override {} void printUrl(); + void tryConnectToWorld(); + void compareInitialCurrentDef(); }; #endif From 73742f30c2166597bbd0653d12893a54a9ee7607 Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Fri, 25 Oct 2024 09:53:11 +0200 Subject: [PATCH 02/12] Fix source code test --- src/webots/nodes/utils/WbWorld.cpp | 5 ++--- src/webots/scene_tree/WbNodeEditor.cpp | 11 ++++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/webots/nodes/utils/WbWorld.cpp b/src/webots/nodes/utils/WbWorld.cpp index f8f49f93bb0..98d02be047b 100644 --- a/src/webots/nodes/utils/WbWorld.cpp +++ b/src/webots/nodes/utils/WbWorld.cpp @@ -225,9 +225,8 @@ bool WbWorld::needSaving() const { } void WbWorld::setModifiedFromSceneTree() { - if (!mIsModifiedFromSceneTree) { - mIsModifiedFromSceneTree = true; - } + mIsModifiedFromSceneTree = true; +s if (isModifiedFromSceneTreeRestarted) { mIsModifiedFromSceneTree = false; isModifiedFromSceneTreeRestarted = false; diff --git a/src/webots/scene_tree/WbNodeEditor.cpp b/src/webots/scene_tree/WbNodeEditor.cpp index 1d68deafbf7..d71dd2c32cb 100644 --- a/src/webots/scene_tree/WbNodeEditor.cpp +++ b/src/webots/scene_tree/WbNodeEditor.cpp @@ -224,7 +224,6 @@ void WbNodeEditor::apply() { QString newDef = mDefEdit->text(); const QString &previousDef = mNode->defName(); - QString initialDef = mInitialCurrentDefMap.value(mNode).first; // Access the first QString (initial DEF) mInitialCurrentDefMap[mNode].second = newDef; bool hasStarted = state->hasStarted(); @@ -351,13 +350,15 @@ void WbNodeEditor::switchInitialCurrentDef() { // Iterate through the map and switch the initial DEF to the current one for (auto it = mInitialCurrentDefMap.begin(); it != mInitialCurrentDefMap.end(); ++it) { - WbNode *node = it.key(); + const WbNode *node = it.key(); QString &initialDef = it.value().first; // Reference to initial DEF name - const QString ¤tDef = node->defName(); // Get the current DEF name of the node // Switch the initial DEF to the current DEF - if (node && initialDef != currentDef) - initialDef = currentDef; // Update the initial DEF with the current one + if (node) { + const QString ¤tDef = node->defName(); // Get the current DEF name of the node + if (initialDef != currentDef) + initialDef = currentDef; // Update the initial DEF with the current one + } } update(); From bb014cb8fac2297d7623d65b79fb2c94c8eb6b66 Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Fri, 25 Oct 2024 10:07:22 +0200 Subject: [PATCH 03/12] Fix source code test --- src/webots/scene_tree/WbNodeEditor.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/webots/scene_tree/WbNodeEditor.cpp b/src/webots/scene_tree/WbNodeEditor.cpp index d71dd2c32cb..a471cc3dbe8 100644 --- a/src/webots/scene_tree/WbNodeEditor.cpp +++ b/src/webots/scene_tree/WbNodeEditor.cpp @@ -356,8 +356,7 @@ void WbNodeEditor::switchInitialCurrentDef() { // Switch the initial DEF to the current DEF if (node) { const QString ¤tDef = node->defName(); // Get the current DEF name of the node - if (initialDef != currentDef) - initialDef = currentDef; // Update the initial DEF with the current one + initialDef = currentDef; // Update the initial DEF with the current one } } From 0451546c4ad6b7de30a6c61b1a29f54f93f0af44 Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Fri, 25 Oct 2024 10:21:10 +0200 Subject: [PATCH 04/12] Fix source code test --- src/webots/nodes/utils/WbWorld.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webots/nodes/utils/WbWorld.cpp b/src/webots/nodes/utils/WbWorld.cpp index 98d02be047b..63f2afed9a0 100644 --- a/src/webots/nodes/utils/WbWorld.cpp +++ b/src/webots/nodes/utils/WbWorld.cpp @@ -226,7 +226,7 @@ bool WbWorld::needSaving() const { void WbWorld::setModifiedFromSceneTree() { mIsModifiedFromSceneTree = true; -s + if (isModifiedFromSceneTreeRestarted) { mIsModifiedFromSceneTree = false; isModifiedFromSceneTreeRestarted = false; From bcb3a60ddcf7393b56f7a8e2aaaeaaf8148f7b9a Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Fri, 25 Oct 2024 10:38:35 +0200 Subject: [PATCH 05/12] Fix source code test --- src/webots/scene_tree/WbNodeEditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webots/scene_tree/WbNodeEditor.cpp b/src/webots/scene_tree/WbNodeEditor.cpp index a471cc3dbe8..b3f372d2475 100644 --- a/src/webots/scene_tree/WbNodeEditor.cpp +++ b/src/webots/scene_tree/WbNodeEditor.cpp @@ -351,10 +351,10 @@ void WbNodeEditor::switchInitialCurrentDef() { // Iterate through the map and switch the initial DEF to the current one for (auto it = mInitialCurrentDefMap.begin(); it != mInitialCurrentDefMap.end(); ++it) { const WbNode *node = it.key(); - QString &initialDef = it.value().first; // Reference to initial DEF name // Switch the initial DEF to the current DEF if (node) { + QString &initialDef = it.value().first; // Reference to initial DEF name const QString ¤tDef = node->defName(); // Get the current DEF name of the node initialDef = currentDef; // Update the initial DEF with the current one } From 7018f893b62fbf1645f688dda1500b2aa1baefc2 Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Fri, 25 Oct 2024 10:48:30 +0200 Subject: [PATCH 06/12] Fix source code test --- src/webots/scene_tree/WbFieldEditor.cpp | 108 +++++++++++++++--------- 1 file changed, 70 insertions(+), 38 deletions(-) diff --git a/src/webots/scene_tree/WbFieldEditor.cpp b/src/webots/scene_tree/WbFieldEditor.cpp index 9ab51d2b2bf..2e177799328 100644 --- a/src/webots/scene_tree/WbFieldEditor.cpp +++ b/src/webots/scene_tree/WbFieldEditor.cpp @@ -74,27 +74,36 @@ protected slots: static QSize gMinimumSizeOffset = QSize(0, 0); -WbFieldEditor::WbFieldEditor(QWidget *parent) : - QWidget(parent), - mNode(NULL), - mField(NULL), - mItem(-1), - mNodeItem(NULL), - mIsValidItemIndex(false) { +WbFieldEditor::WbFieldEditor(QWidget *parent) + : QWidget(parent), mNode(NULL), mField(NULL), mItem(-1), mNodeItem(NULL), + mIsValidItemIndex(false) { setObjectName("fieldEditorGroupBox"); WbExtendedStringEditor *const stringEditor = new WbExtendedStringEditor(this); - connect(stringEditor, &WbExtendedStringEditor::editRequested, this, &WbFieldEditor::editRequested); + connect(stringEditor, &WbExtendedStringEditor::editRequested, this, + &WbFieldEditor::editRequested); WbNodePane *const nodePane = new WbNodePane(this); const WbNodeEditor *nodeEditor = nodePane->nodeEditor(); - connect(nodeEditor, &WbNodeEditor::dictionaryUpdateRequested, this, &WbFieldEditor::dictionaryUpdateRequested); - connect(nodeEditor, &WbNodeEditor::defNameChanged, WbActionManager::instance()->action(WbAction::SAVE_WORLD), &QAction::setEnabled); - connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD), &QAction::setEnabled, nodeEditor, &WbNodeEditor::resetDefNamesToInitial); - connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), &QAction::setEnabled, nodeEditor, &WbNodeEditor::resetDefNamesToInitial); - connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD), &QAction::triggered, nodeEditor, &WbNodeEditor::switchInitialCurrentDef); - connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), &QAction::triggered, nodeEditor, &WbNodeEditor::switchInitialCurrentDef); - connect(WbActionManager::instance()->action(WbAction::RELOAD_WORLD), &QAction::triggered, nodeEditor, &WbNodeEditor::startTimer); + connect(nodeEditor, &WbNodeEditor::dictionaryUpdateRequested, this, + &WbFieldEditor::dictionaryUpdateRequested); + connect(nodeEditor, &WbNodeEditor::defNameChanged, + WbActionManager::instance()->action(WbAction::SAVE_WORLD), + &QAction::setEnabled); + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD), + &QAction::setEnabled, nodeEditor, + &WbNodeEditor::resetDefNamesToInitial); + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), + &QAction::setEnabled, nodeEditor, + &WbNodeEditor::resetDefNamesToInitial); + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD), + &QAction::triggered, nodeEditor, + &WbNodeEditor::switchInitialCurrentDef); + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), + &QAction::triggered, nodeEditor, + &WbNodeEditor::switchInitialCurrentDef); + connect(WbActionManager::instance()->action(WbAction::RELOAD_WORLD), + &QAction::triggered, nodeEditor, &WbNodeEditor::startTimer); // create editors mEditors.insert(WB_NO_FIELD, new WbEmptyEditor(this)); mEditors.insert(WB_SF_BOOL, new WbBoolEditor(this)); @@ -116,11 +125,14 @@ WbFieldEditor::WbFieldEditor(QWidget *parent) : foreach (WbValueEditor *editor, mEditors) { mStackedLayout->addWidget(editor); // trigger 3D view update after field value change - connect(editor, &WbValueEditor::valueChanged, this, &WbFieldEditor::valueChanged); + connect(editor, &WbValueEditor::valueChanged, this, + &WbFieldEditor::valueChanged); } mStackedLayout->addWidget(mExternProtoEditor); - connect(nodePane->nodeEditor(), &WbValueEditor::valueChanged, this, &WbFieldEditor::valueChanged); - connect(WbApplication::instance(), &WbApplication::worldLoadCompleted, this, &WbFieldEditor::refreshExternProtoEditor); + connect(nodePane->nodeEditor(), &WbValueEditor::valueChanged, this, + &WbFieldEditor::valueChanged); + connect(WbApplication::instance(), &WbApplication::worldLoadCompleted, this, + &WbFieldEditor::refreshExternProtoEditor); mTitleLabel = new QLabel(this); mTitleLabel->setObjectName("titleLabel"); @@ -140,15 +152,15 @@ WbFieldEditor::WbFieldEditor(QWidget *parent) : setCurrentWidget(0); } -WbFieldEditor::~WbFieldEditor() { -} +WbFieldEditor::~WbFieldEditor() {} WbValueEditor *WbFieldEditor::currentEditor() const { return static_cast(mStackedLayout->currentWidget()); } void WbFieldEditor::refreshExternProtoEditor() { - WbExternProtoEditor *editor = dynamic_cast(mExternProtoEditor); + WbExternProtoEditor *editor = + dynamic_cast(mExternProtoEditor); if (currentEditor() == editor) editor->updateContents(); } @@ -182,9 +194,11 @@ void WbFieldEditor::updateTitle() { if (mField->type() == WB_MF_NODE && mItem != -1) title = nodeAsTitle(static_cast(value)->item(mItem)); else if (mField->type() == WB_SF_NODE) - title = mField->name() + " " + nodeAsTitle(static_cast(value)->value()); + title = mField->name() + " " + + nodeAsTitle(static_cast(value)->value()); else { - const WbMultipleValue *multipleValue = dynamic_cast(value); + const WbMultipleValue *multipleValue = + dynamic_cast(value); if (multipleValue) { if (mItem == -1) { int size = multipleValue->size(); @@ -194,7 +208,10 @@ void WbFieldEditor::updateTitle() { title = QString("%1 (%2 %3)").arg(mField->name()).arg(size).arg(type); } else - title = QString("%1 (%3 #%2)").arg(mField->name()).arg(mItem + 1).arg(WbValue::typeToShortName(value->singleType())); + title = QString("%1 (%3 #%2)") + .arg(mField->name()) + .arg(mItem + 1) + .arg(WbValue::typeToShortName(value->singleType())); } else title = QString("%1 (%2)").arg(mField->name(), value->shortTypeName()); } @@ -208,10 +225,12 @@ void WbFieldEditor::editExternProto() { WbValueEditor *current = currentEditor(); current->applyIfNeeded(); current->stopEditing(); - disconnect(current, &WbValueEditor::valueInvalidated, this, &WbFieldEditor::invalidateValue); + disconnect(current, &WbValueEditor::valueInvalidated, this, + &WbFieldEditor::invalidateValue); // enable extern proto - WbExternProtoEditor *editor = dynamic_cast(mExternProtoEditor); + WbExternProtoEditor *editor = + dynamic_cast(mExternProtoEditor); if (editor) { editor->updateContents(); setCurrentWidget(mExternProtoEditor); @@ -219,7 +238,8 @@ void WbFieldEditor::editExternProto() { } void WbFieldEditor::editField(WbNode *node, WbField *field, int item) { - disconnect(this, &WbFieldEditor::valueChanged, this, &WbFieldEditor::updateResetButton); + disconnect(this, &WbFieldEditor::valueChanged, this, + &WbFieldEditor::updateResetButton); if (node == mNode && field == mField && item == mItem) { if (field || node) updateValue(false); @@ -236,11 +256,14 @@ void WbFieldEditor::editField(WbNode *node, WbField *field, int item) { WbValueEditor *editor = currentEditor(); editor->applyIfNeeded(); editor->stopEditing(); - disconnect(editor, &WbValueEditor::valueInvalidated, this, &WbFieldEditor::invalidateValue); + disconnect(editor, &WbValueEditor::valueInvalidated, this, + &WbFieldEditor::invalidateValue); if (field == NULL && node == NULL) { invalidateValue(); - WbActionManager::instance()->action(WbAction::RESET_VALUE)->setEnabled(false); + WbActionManager::instance() + ->action(WbAction::RESET_VALUE) + ->setEnabled(false); return; } @@ -250,8 +273,9 @@ void WbFieldEditor::editField(WbNode *node, WbField *field, int item) { assert(field); WbActionManager::instance() - ->action(WbAction::RESET_VALUE) - ->setEnabled(!((field->isMultiple() && mIsValidItemIndex) || mField->isDefault())); + ->action(WbAction::RESET_VALUE) + ->setEnabled( + !((field->isMultiple() && mIsValidItemIndex) || mField->isDefault())); if (field->isMultiple() && !mIsValidItemIndex) { setCurrentWidget(0); @@ -259,7 +283,8 @@ void WbFieldEditor::editField(WbNode *node, WbField *field, int item) { } // check if the selected item is a Solid node - const QList &v = mEditors.values(field->value()->singleType()); + const QList &v = + mEditors.values(field->value()->singleType()); const bool editingSolid = dynamic_cast(mNodeItem) != NULL; if (v.size() == 1) editor = v.at(0); @@ -268,8 +293,10 @@ void WbFieldEditor::editField(WbNode *node, WbField *field, int item) { editor->edit(node, field, item); setCurrentWidget(editor); - connect(editor, &WbValueEditor::valueInvalidated, this, &WbFieldEditor::invalidateValue); - connect(this, &WbFieldEditor::valueChanged, this, &WbFieldEditor::updateResetButton); + connect(editor, &WbValueEditor::valueInvalidated, this, + &WbFieldEditor::invalidateValue); + connect(this, &WbFieldEditor::valueChanged, this, + &WbFieldEditor::updateResetButton); } void WbFieldEditor::invalidateValue() { @@ -285,9 +312,14 @@ void WbFieldEditor::resetFocus() { } void WbFieldEditor::updateResetButton() { - const WbMultipleValue *const multipleValue = dynamic_cast(mField->value()); - bool enabled = !((multipleValue && (mItem >= 0) && (mItem < multipleValue->size())) || mField->isDefault()); - WbActionManager::instance()->action(WbAction::RESET_VALUE)->setEnabled(enabled); + const WbMultipleValue *const multipleValue = + dynamic_cast(mField->value()); + bool enabled = + !((multipleValue && (mItem >= 0) && (mItem < multipleValue->size())) || + mField->isDefault()); + WbActionManager::instance() + ->action(WbAction::RESET_VALUE) + ->setEnabled(enabled); } void WbFieldEditor::updateValue(bool copyOriginalValue) { @@ -333,4 +365,4 @@ void WbFieldEditor::setCurrentWidget(int index) { void WbFieldEditor::setCurrentWidget(WbValueEditor *editor) { mStackedLayout->setCurrentWidget(editor); -} +} \ No newline at end of file From 9ff852bd2c16b475b3c143611db29597c0926696 Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Fri, 25 Oct 2024 11:18:49 +0200 Subject: [PATCH 07/12] Fix source code issue --- src/webots/scene_tree/WbFieldEditor.cpp | 106 +++++++++--------------- 1 file changed, 40 insertions(+), 66 deletions(-) diff --git a/src/webots/scene_tree/WbFieldEditor.cpp b/src/webots/scene_tree/WbFieldEditor.cpp index 2e177799328..7570318fa6e 100644 --- a/src/webots/scene_tree/WbFieldEditor.cpp +++ b/src/webots/scene_tree/WbFieldEditor.cpp @@ -74,41 +74,38 @@ protected slots: static QSize gMinimumSizeOffset = QSize(0, 0); -WbFieldEditor::WbFieldEditor(QWidget *parent) - : QWidget(parent), mNode(NULL), mField(NULL), mItem(-1), mNodeItem(NULL), - mIsValidItemIndex(false) { +WbFieldEditor::WbFieldEditor(QWidget *parent) : + QWidget(parent), + mNode(NULL), + mField(NULL), + mItem(-1), + mNodeItem(NULL), + mIsValidItemIndex(false) { setObjectName("fieldEditorGroupBox"); WbExtendedStringEditor *const stringEditor = new WbExtendedStringEditor(this); - connect(stringEditor, &WbExtendedStringEditor::editRequested, this, - &WbFieldEditor::editRequested); + connect(stringEditor, &WbExtendedStringEditor::editRequested, this, &WbFieldEditor::editRequested); WbNodePane *const nodePane = new WbNodePane(this); const WbNodeEditor *nodeEditor = nodePane->nodeEditor(); - connect(nodeEditor, &WbNodeEditor::dictionaryUpdateRequested, this, - &WbFieldEditor::dictionaryUpdateRequested); - connect(nodeEditor, &WbNodeEditor::defNameChanged, - WbActionManager::instance()->action(WbAction::SAVE_WORLD), + connect(nodeEditor, &WbNodeEditor::dictionaryUpdateRequested, this, &WbFieldEditor::dictionaryUpdateRequested); + connect(nodeEditor, &WbNodeEditor::defNameChanged, WbActionManager::instance()->action(WbAction::SAVE_WORLD), &QAction::setEnabled); - connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD), - &QAction::setEnabled, nodeEditor, + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD), &QAction::setEnabled, nodeEditor, &WbNodeEditor::resetDefNamesToInitial); - connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), - &QAction::setEnabled, nodeEditor, + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), &QAction::setEnabled, nodeEditor, &WbNodeEditor::resetDefNamesToInitial); - connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD), - &QAction::triggered, nodeEditor, + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD), &QAction::triggered, nodeEditor, &WbNodeEditor::switchInitialCurrentDef); - connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), - &QAction::triggered, nodeEditor, + connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), &QAction::triggered, nodeEditor, &WbNodeEditor::switchInitialCurrentDef); - connect(WbActionManager::instance()->action(WbAction::RELOAD_WORLD), - &QAction::triggered, nodeEditor, &WbNodeEditor::startTimer); + connect(WbActionManager::instance()->action(WbAction::RELOAD_WORLD), &QAction::triggered, nodeEditor, + &WbNodeEditor::startTimer); // create editors mEditors.insert(WB_NO_FIELD, new WbEmptyEditor(this)); mEditors.insert(WB_SF_BOOL, new WbBoolEditor(this)); mEditors.insert(WB_SF_STRING, stringEditor); - mEditors.insert(WB_SF_INT32, new WbIntEditor(this)); + mEditors.insert(WB_SF_INT32, new WbIntEditor(this));c mEditors.insert(WB_SF_FLOAT, new WbDoubleEditor(this)); mEditors.insert(WB_SF_VEC2F, new WbVector2Editor(this)); mEditors.insert(WB_SF_VEC3F, new WbVector3Editor(this)); @@ -125,14 +122,11 @@ WbFieldEditor::WbFieldEditor(QWidget *parent) foreach (WbValueEditor *editor, mEditors) { mStackedLayout->addWidget(editor); // trigger 3D view update after field value change - connect(editor, &WbValueEditor::valueChanged, this, - &WbFieldEditor::valueChanged); + connect(editor, &WbValueEditor::valueChanged, this, &WbFieldEditor::valueChanged); } mStackedLayout->addWidget(mExternProtoEditor); - connect(nodePane->nodeEditor(), &WbValueEditor::valueChanged, this, - &WbFieldEditor::valueChanged); - connect(WbApplication::instance(), &WbApplication::worldLoadCompleted, this, - &WbFieldEditor::refreshExternProtoEditor); + connect(nodePane->nodeEditor(), &WbValueEditor::valueChanged, this, &WbFieldEditor::valueChanged); + connect(WbApplication::instance(), &WbApplication::worldLoadCompleted, this, &WbFieldEditor::refreshExternProtoEditor); mTitleLabel = new QLabel(this); mTitleLabel->setObjectName("titleLabel"); @@ -152,15 +146,15 @@ WbFieldEditor::WbFieldEditor(QWidget *parent) setCurrentWidget(0); } -WbFieldEditor::~WbFieldEditor() {} +WbFieldEditor::~WbFieldEditor() { +} WbValueEditor *WbFieldEditor::currentEditor() const { return static_cast(mStackedLayout->currentWidget()); } void WbFieldEditor::refreshExternProtoEditor() { - WbExternProtoEditor *editor = - dynamic_cast(mExternProtoEditor); + WbExternProtoEditor *editor = dynamic_cast(mExternProtoEditor); if (currentEditor() == editor) editor->updateContents(); } @@ -194,11 +188,9 @@ void WbFieldEditor::updateTitle() { if (mField->type() == WB_MF_NODE && mItem != -1) title = nodeAsTitle(static_cast(value)->item(mItem)); else if (mField->type() == WB_SF_NODE) - title = mField->name() + " " + - nodeAsTitle(static_cast(value)->value()); + title = mField->name() + " " + nodeAsTitle(static_cast(value)->value()); else { - const WbMultipleValue *multipleValue = - dynamic_cast(value); + const WbMultipleValue *multipleValue = dynamic_cast(value); if (multipleValue) { if (mItem == -1) { int size = multipleValue->size(); @@ -208,10 +200,7 @@ void WbFieldEditor::updateTitle() { title = QString("%1 (%2 %3)").arg(mField->name()).arg(size).arg(type); } else - title = QString("%1 (%3 #%2)") - .arg(mField->name()) - .arg(mItem + 1) - .arg(WbValue::typeToShortName(value->singleType())); + title = QString("%1 (%3 #%2)").arg(mField->name()).arg(mItem + 1).arg(WbValue::typeToShortName(value->singleType())); } else title = QString("%1 (%2)").arg(mField->name(), value->shortTypeName()); } @@ -225,12 +214,10 @@ void WbFieldEditor::editExternProto() { WbValueEditor *current = currentEditor(); current->applyIfNeeded(); current->stopEditing(); - disconnect(current, &WbValueEditor::valueInvalidated, this, - &WbFieldEditor::invalidateValue); + disconnect(current, &WbValueEditor::valueInvalidated, this, &WbFieldEditor::invalidateValue); // enable extern proto - WbExternProtoEditor *editor = - dynamic_cast(mExternProtoEditor); + WbExternProtoEditor *editor = dynamic_cast(mExternProtoEditor); if (editor) { editor->updateContents(); setCurrentWidget(mExternProtoEditor); @@ -238,8 +225,7 @@ void WbFieldEditor::editExternProto() { } void WbFieldEditor::editField(WbNode *node, WbField *field, int item) { - disconnect(this, &WbFieldEditor::valueChanged, this, - &WbFieldEditor::updateResetButton); + disconnect(this, &WbFieldEditor::valueChanged, this, &WbFieldEditor::updateResetButton); if (node == mNode && field == mField && item == mItem) { if (field || node) updateValue(false); @@ -256,14 +242,11 @@ void WbFieldEditor::editField(WbNode *node, WbField *field, int item) { WbValueEditor *editor = currentEditor(); editor->applyIfNeeded(); editor->stopEditing(); - disconnect(editor, &WbValueEditor::valueInvalidated, this, - &WbFieldEditor::invalidateValue); + disconnect(editor, &WbValueEditor::valueInvalidated, this, &WbFieldEditor::invalidateValue); if (field == NULL && node == NULL) { invalidateValue(); - WbActionManager::instance() - ->action(WbAction::RESET_VALUE) - ->setEnabled(false); + WbActionManager::instance()->action(WbAction::RESET_VALUE)->setEnabled(false); return; } @@ -273,9 +256,8 @@ void WbFieldEditor::editField(WbNode *node, WbField *field, int item) { assert(field); WbActionManager::instance() - ->action(WbAction::RESET_VALUE) - ->setEnabled( - !((field->isMultiple() && mIsValidItemIndex) || mField->isDefault())); + ->action(WbAction::RESET_VALUE) + ->setEnabled(!((field->isMultiple() && mIsValidItemIndex) || mField->isDefault())); if (field->isMultiple() && !mIsValidItemIndex) { setCurrentWidget(0); @@ -283,8 +265,7 @@ void WbFieldEditor::editField(WbNode *node, WbField *field, int item) { } // check if the selected item is a Solid node - const QList &v = - mEditors.values(field->value()->singleType()); + const QList &v = mEditors.values(field->value()->singleType()); const bool editingSolid = dynamic_cast(mNodeItem) != NULL; if (v.size() == 1) editor = v.at(0); @@ -293,10 +274,8 @@ void WbFieldEditor::editField(WbNode *node, WbField *field, int item) { editor->edit(node, field, item); setCurrentWidget(editor); - connect(editor, &WbValueEditor::valueInvalidated, this, - &WbFieldEditor::invalidateValue); - connect(this, &WbFieldEditor::valueChanged, this, - &WbFieldEditor::updateResetButton); + connect(editor, &WbValueEditor::valueInvalidated, this, &WbFieldEditor::invalidateValue); + connect(this, &WbFieldEditor::valueChanged, this, &WbFieldEditor::updateResetButton); } void WbFieldEditor::invalidateValue() { @@ -312,14 +291,9 @@ void WbFieldEditor::resetFocus() { } void WbFieldEditor::updateResetButton() { - const WbMultipleValue *const multipleValue = - dynamic_cast(mField->value()); - bool enabled = - !((multipleValue && (mItem >= 0) && (mItem < multipleValue->size())) || - mField->isDefault()); - WbActionManager::instance() - ->action(WbAction::RESET_VALUE) - ->setEnabled(enabled); + const WbMultipleValue *const multipleValue = dynamic_cast(mField->value()); + bool enabled = !((multipleValue && (mItem >= 0) && (mItem < multipleValue->size())) || mField->isDefault()); + WbActionManager::instance()->action(WbAction::RESET_VALUE)->setEnabled(enabled); } void WbFieldEditor::updateValue(bool copyOriginalValue) { @@ -365,4 +339,4 @@ void WbFieldEditor::setCurrentWidget(int index) { void WbFieldEditor::setCurrentWidget(WbValueEditor *editor) { mStackedLayout->setCurrentWidget(editor); -} \ No newline at end of file +} From 08fa88a0cdb00f3b93edda3c7d1a3f2cdc61ea64 Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Fri, 25 Oct 2024 11:29:13 +0200 Subject: [PATCH 08/12] Fix source code issue --- src/webots/scene_tree/WbFieldEditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webots/scene_tree/WbFieldEditor.cpp b/src/webots/scene_tree/WbFieldEditor.cpp index 7570318fa6e..765f4a10f7f 100644 --- a/src/webots/scene_tree/WbFieldEditor.cpp +++ b/src/webots/scene_tree/WbFieldEditor.cpp @@ -105,7 +105,7 @@ WbFieldEditor::WbFieldEditor(QWidget *parent) : mEditors.insert(WB_NO_FIELD, new WbEmptyEditor(this)); mEditors.insert(WB_SF_BOOL, new WbBoolEditor(this)); mEditors.insert(WB_SF_STRING, stringEditor); - mEditors.insert(WB_SF_INT32, new WbIntEditor(this));c + mEditors.insert(WB_SF_INT32, new WbIntEditor(this)); mEditors.insert(WB_SF_FLOAT, new WbDoubleEditor(this)); mEditors.insert(WB_SF_VEC2F, new WbVector2Editor(this)); mEditors.insert(WB_SF_VEC3F, new WbVector3Editor(this)); From 9ac3a802cc726cca48c2b30f444dda9f7daf34c4 Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Fri, 25 Oct 2024 12:00:08 +0200 Subject: [PATCH 09/12] Fix source code issue --- src/webots/scene_tree/WbNodeEditor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webots/scene_tree/WbNodeEditor.hpp b/src/webots/scene_tree/WbNodeEditor.hpp index 50fef6b1b78..b9671eaed08 100644 --- a/src/webots/scene_tree/WbNodeEditor.hpp +++ b/src/webots/scene_tree/WbNodeEditor.hpp @@ -19,9 +19,9 @@ // Description: editor for editing a WbSFNode or a WbMFNode item // +#include "WbSimulationState.hpp" #include "WbValueEditor.hpp" #include "WbWorld.hpp" -#include "WbSimulationState.hpp" class WbFieldLineEdit; class WbNode; From 7e630c6a0516056ed2564f9f435f28979303836b Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Fri, 25 Oct 2024 12:11:48 +0200 Subject: [PATCH 10/12] Fix source code issue --- src/webots/scene_tree/WbNodeEditor.cpp | 154 ++++++++++++++----------- 1 file changed, 88 insertions(+), 66 deletions(-) diff --git a/src/webots/scene_tree/WbNodeEditor.cpp b/src/webots/scene_tree/WbNodeEditor.cpp index b3f372d2475..e8b0c4b2850 100644 --- a/src/webots/scene_tree/WbNodeEditor.cpp +++ b/src/webots/scene_tree/WbNodeEditor.cpp @@ -14,6 +14,7 @@ #include "WbNodeEditor.hpp" +#include "WbActionManager.hpp" #include "WbBaseNode.hpp" #include "WbField.hpp" #include "WbFieldLineEdit.hpp" @@ -32,11 +33,11 @@ #include "WbTransform.hpp" #include "WbViewpoint.hpp" #include "WbVrmlNodeUtilities.hpp" -#include "WbWorldInfo.hpp" #include "WbWorld.hpp" -#include "WbActionManager.hpp" +#include "WbWorldInfo.hpp" #include +#include #include #include #include @@ -44,20 +45,16 @@ #include #include #include -#include -WbNodeEditor::WbNodeEditor(QWidget *parent) : - WbValueEditor(parent), - mNode(NULL), - mDefEdit(new WbFieldLineEdit(this)), - mUseCount(new QLabel(this)), - mPrintUrl(new QPushButton("Print EXTERNPROTO", this)), - mNbTriangles(new QLabel(this)), - mStackedWidget(new QStackedWidget(this)), - mMessageBox(false), - worldCheckTimer(new QTimer(this)), - mShowResizeHandlesLabel(new QLabel(tr("3D tools:"), this)), - mShowResizeHandlesCheckBox(new QCheckBox(tr("show resize handles"), this)) { +WbNodeEditor::WbNodeEditor(QWidget *parent) + : WbValueEditor(parent), mNode(NULL), mDefEdit(new WbFieldLineEdit(this)), + mUseCount(new QLabel(this)), + mPrintUrl(new QPushButton("Print EXTERNPROTO", this)), + mNbTriangles(new QLabel(this)), mStackedWidget(new QStackedWidget(this)), + mMessageBox(false), worldCheckTimer(new QTimer(this)), + mShowResizeHandlesLabel(new QLabel(tr("3D tools:"), this)), + mShowResizeHandlesCheckBox( + new QCheckBox(tr("show resize handles"), this)) { mShowResizeHandlesCheckBox->setChecked(false); QWidget *nodePane = new QWidget(this); nodePane->setObjectName("NodeEditorBackground"); @@ -83,15 +80,19 @@ WbNodeEditor::WbNodeEditor(QWidget *parent) : // Main layout mStackedWidget->addWidget(nodePane); - mStackedWidget->addWidget(new QWidget(this)); // empty pane + mStackedWidget->addWidget(new QWidget(this)); // empty pane mLayout->addWidget(mStackedWidget, 1, 1); - connect(mDefEdit, &WbFieldLineEdit::returnPressed, this, &WbNodeEditor::apply); + connect(mDefEdit, &WbFieldLineEdit::returnPressed, this, + &WbNodeEditor::apply); connect(mDefEdit, &WbFieldLineEdit::focusLeft, this, &WbNodeEditor::apply); connect(mPrintUrl, &QPushButton::pressed, this, &WbNodeEditor::printUrl); - connect(mShowResizeHandlesCheckBox, &QAbstractButton::toggled, WbSelection::instance(), - &WbSelection::showResizeManipulatorFromSceneTree, Qt::UniqueConnection); - connect(worldCheckTimer, &QTimer::timeout, this, &WbNodeEditor::tryConnectToWorld); + connect(mShowResizeHandlesCheckBox, &QAbstractButton::toggled, + WbSelection::instance(), + &WbSelection::showResizeManipulatorFromSceneTree, + Qt::UniqueConnection); + connect(worldCheckTimer, &QTimer::timeout, this, + &WbNodeEditor::tryConnectToWorld); worldCheckTimer->start(500); } @@ -99,16 +100,19 @@ void WbNodeEditor::tryConnectToWorld() { world = WbWorld::instance(); state = WbSimulationState::instance(); if (oldWorld != world) { - connect(world, &WbWorld::checkDefDiff, this, &WbNodeEditor::resetDefNamesToInitial); - connect(this, &WbNodeEditor::resetModifiedFromSceneTree, world, &WbWorld::resetModifiedFromSceneTree); - oldWorld = const_cast(world); + connect(world, &WbWorld::checkDefDiff, this, + &WbNodeEditor::resetDefNamesToInitial); + connect(this, &WbNodeEditor::resetModifiedFromSceneTree, world, + &WbWorld::resetModifiedFromSceneTree); + oldWorld = const_cast(world); mInitialCurrentDefMap.clear(); worldCheckTimer->stop(); } } -void WbNodeEditor::startTimer(){ - disconnect(world, &WbWorld::checkDefDiff, this, &WbNodeEditor::resetDefNamesToInitial); +void WbNodeEditor::startTimer() { + disconnect(world, &WbWorld::checkDefDiff, this, + &WbNodeEditor::resetDefNamesToInitial); worldCheckTimer->start(500); } @@ -116,7 +120,9 @@ void WbNodeEditor::printUrl() { if (!mNode->isProtoInstance()) return; - WbLog::info(tr("EXTERNPROTO \"%1\"").arg(WbProtoManager::instance()->externProtoUrl(mNode, true))); + WbLog::info( + tr("EXTERNPROTO \"%1\"") + .arg(WbProtoManager::instance()->externProtoUrl(mNode, true))); } void WbNodeEditor::recursiveBlockSignals(bool block) { @@ -151,12 +157,14 @@ void WbNodeEditor::edit(bool copyOriginalValue) { if (handlesAvailable) { const WbGeometry *g = dynamic_cast(baseNode); if (g) - mShowResizeHandlesCheckBox->setChecked(g->isResizeManipulatorAttached()); + mShowResizeHandlesCheckBox->setChecked( + g->isResizeManipulatorAttached()); } } if (mNode && !mInitialCurrentDefMap.contains(mNode)) - mInitialCurrentDefMap[mNode] = QPair(mNode->defName(), QString()); + mInitialCurrentDefMap[mNode] = + QPair(mNode->defName(), QString()); } update(); @@ -187,11 +195,14 @@ void WbNodeEditor::update() { if (mNode->defName().isEmpty()) mUseCount->clear(); else - mUseCount->setText(tr("USE count: %1").arg(mNode->useCount())); // TODO: is this the final implementation? + mUseCount->setText( + tr("USE count: %1").arg(mNode->useCount())); // TODO: is this the + // final implementation? if (mNode->isProtoInstance()) { mPrintUrl->setVisible(true); - mPrintUrl->setToolTip(WbProtoManager::instance()->externProtoUrl(mNode, true)); + mPrintUrl->setToolTip( + WbProtoManager::instance()->externProtoUrl(mNode, true)); } else mPrintUrl->setVisible(false); } else @@ -199,19 +210,19 @@ void WbNodeEditor::update() { const WbGeometry *node = dynamic_cast(mNode); if (node && !node->isUseNode()) { - const int maxTriangleNumberToCastShadows = node->maxIndexNumberToCastShadows() / 3; + const int maxTriangleNumberToCastShadows = + node->maxIndexNumberToCastShadows() / 3; int triangleCount = node->triangleCount(); if (triangleCount > maxTriangleNumberToCastShadows) - mNbTriangles->setText(tr("Triangle count: %1 (no shadow)").arg(triangleCount)); + mNbTriangles->setText( + tr("Triangle count: %1 (no shadow)").arg(triangleCount)); else mNbTriangles->setText(tr("Triangle count: %1").arg(triangleCount)); } else mNbTriangles->clear(); } -void WbNodeEditor::resetFocus() { - mDefEdit->clearFocus(); -} +void WbNodeEditor::resetFocus() { mDefEdit->clearFocus(); } void WbNodeEditor::apply() { if (!mNode || mStackedWidget->currentIndex() == EMPTY_PANE) @@ -224,7 +235,7 @@ void WbNodeEditor::apply() { QString newDef = mDefEdit->text(); const QString &previousDef = mNode->defName(); - mInitialCurrentDefMap[mNode].second = newDef; + mInitialCurrentDefMap[mNode].second = newDef; bool hasStarted = state->hasStarted(); if (!hasStarted) @@ -237,8 +248,10 @@ void WbNodeEditor::apply() { mDefEdit->blockSignals(true); if (newDef.isEmpty() && mNode->useCount() > 0) { - WbMessageBox::warning(tr("This DEF cannot be cleared because some USE nodes depend on it."), this); - mDefEdit->setText(previousDef); // restore + WbMessageBox::warning( + tr("This DEF cannot be cleared because some USE nodes depend on it."), + this); + mDefEdit->setText(previousDef); // restore mDefEdit->blockSignals(false); return; } @@ -248,29 +261,35 @@ void WbNodeEditor::apply() { // check if the new DEF name is not already used by subsequent USE nodes bool defOverlap = false; bool useOverlap = false; - dictionaryUpdateRequest = - WbVrmlNodeUtilities::hasASubsequentUseOrDefNode(mNode, newDef, previousDef, useOverlap, defOverlap); + dictionaryUpdateRequest = WbVrmlNodeUtilities::hasASubsequentUseOrDefNode( + mNode, newDef, previousDef, useOverlap, defOverlap); if (dictionaryUpdateRequest) { mMessageBox = true; QString message; if (defOverlap && useOverlap) { - message = tr("This DEF string is already used by subsequent USE and DEF nodes. " - "Applying this change will modify all the USE nodes referring to previous node with same DEF name " - "and USE nodes referring to the selected node. \n" - "Do you want to continue?"); + message = tr( + "This DEF string is already used by subsequent USE and DEF nodes. " + "Applying this change will modify all the USE nodes referring to " + "previous node with same DEF name " + "and USE nodes referring to the selected node. \n" + "Do you want to continue?"); } else if (defOverlap) { message = tr("This DEF string is already used by subsequent DEF nodes. " - "Applying this change will turn USE nodes of the selected node into copies of subsequent DEF node.\n" + "Applying this change will turn USE nodes of the selected " + "node into copies of subsequent DEF node.\n" "Do you want to continue?"); } else { - message = tr("This DEF string is already referred to by subsequent USE nodes. " - "Applying this change will turn them into copies of the selected node.\n" - "Do you want to continue?"); + message = tr( + "This DEF string is already referred to by subsequent USE nodes. " + "Applying this change will turn them into copies of the selected " + "node.\n" + "Do you want to continue?"); } mMessageBox = false; - if (WbMessageBox::question(message, this, tr("DEF name change")) == QMessageBox::Cancel) { + if (WbMessageBox::question(message, this, tr("DEF name change")) == + QMessageBox::Cancel) { mDefEdit->setText(previousDef); mDefEdit->blockSignals(false); return; @@ -296,25 +315,24 @@ void WbNodeEditor::compareInitialCurrentDef() { if (!mInitialCurrentDefMap.isEmpty()) { bool foundDifference = false; // Iterate through the QMap - for (auto it = mInitialCurrentDefMap.constBegin(); it != mInitialCurrentDefMap.constEnd(); ++it) { + for (auto it = mInitialCurrentDefMap.constBegin(); + it != mInitialCurrentDefMap.constEnd(); ++it) { const QString &initialDef = it.value().first; // First QString (initial) const QString ¤tDef = it.value().second; // Second QString (current) // Compare the two QStrings if (initialDef != currentDef) { - foundDifference = true; // Mark that a difference is found + foundDifference = true; // Mark that a difference is found break; } } if (foundDifference) - emit defNameChanged(true); // Emit true if any difference is found - else - { + emit defNameChanged(true); // Emit true if any difference is found + else { emit resetModifiedFromSceneTree(); - emit defNameChanged(false); // Emit false if no differences were found + emit defNameChanged(false); // Emit false if no differences were found } - } - else + } else emit defNameChanged(false); // If all QStrings are the same, return false } @@ -326,13 +344,15 @@ void WbNodeEditor::resetDefNamesToInitial() { } // Iterate through the map and reset each node's DEF name to its initial value - for (auto it = mInitialCurrentDefMap.begin(); it != mInitialCurrentDefMap.end(); ++it) { + for (auto it = mInitialCurrentDefMap.begin(); + it != mInitialCurrentDefMap.end(); ++it) { WbNode *node = it.key(); - const QString &initialDef = it.value().first; // Access initial DEF name + const QString &initialDef = it.value().first; // Access initial DEF name - // Only reset if node exists and the current DEF differs from the initial one + // Only reset if node exists and the current DEF differs from the initial + // one if (node && node->defName() != initialDef) - node->setDefName(initialDef); // Set the DEF name back to the initial one + node->setDefName(initialDef); // Set the DEF name back to the initial one } update(); @@ -349,18 +369,20 @@ void WbNodeEditor::switchInitialCurrentDef() { } // Iterate through the map and switch the initial DEF to the current one - for (auto it = mInitialCurrentDefMap.begin(); it != mInitialCurrentDefMap.end(); ++it) { + for (auto it = mInitialCurrentDefMap.begin(); + it != mInitialCurrentDefMap.end(); ++it) { const WbNode *node = it.key(); // Switch the initial DEF to the current DEF if (node) { - QString &initialDef = it.value().first; // Reference to initial DEF name - const QString ¤tDef = node->defName(); // Get the current DEF name of the node - initialDef = currentDef; // Update the initial DEF with the current one + QString &initialDef = it.value().first; // Reference to initial DEF name + const QString ¤tDef = + node->defName(); // Get the current DEF name of the node + initialDef = currentDef; // Update the initial DEF with the current one } } update(); emit defNameChanged(false); -} +} \ No newline at end of file From 98d7b9d9684c74803033cb791f8f77a45d9a320b Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Fri, 25 Oct 2024 14:44:36 +0200 Subject: [PATCH 11/12] Fix source code issue --- src/webots/scene_tree/WbNodeEditor.cpp | 142 ++++++++++--------------- 1 file changed, 59 insertions(+), 83 deletions(-) diff --git a/src/webots/scene_tree/WbNodeEditor.cpp b/src/webots/scene_tree/WbNodeEditor.cpp index e8b0c4b2850..898e20d2cf0 100644 --- a/src/webots/scene_tree/WbNodeEditor.cpp +++ b/src/webots/scene_tree/WbNodeEditor.cpp @@ -46,15 +46,18 @@ #include #include -WbNodeEditor::WbNodeEditor(QWidget *parent) - : WbValueEditor(parent), mNode(NULL), mDefEdit(new WbFieldLineEdit(this)), - mUseCount(new QLabel(this)), - mPrintUrl(new QPushButton("Print EXTERNPROTO", this)), - mNbTriangles(new QLabel(this)), mStackedWidget(new QStackedWidget(this)), - mMessageBox(false), worldCheckTimer(new QTimer(this)), - mShowResizeHandlesLabel(new QLabel(tr("3D tools:"), this)), - mShowResizeHandlesCheckBox( - new QCheckBox(tr("show resize handles"), this)) { +WbNodeEditor::WbNodeEditor(QWidget *parent) : + WbValueEditor(parent), + mNode(NULL), + mDefEdit(new WbFieldLineEdit(this)), + mUseCount(new QLabel(this)), + mPrintUrl(new QPushButton("Print EXTERNPROTO", this)), + mNbTriangles(new QLabel(this)), + mStackedWidget(new QStackedWidget(this)), + mMessageBox(false), + worldCheckTimer(new QTimer(this)), + mShowResizeHandlesLabel(new QLabel(tr("3D tools:"), this)), + mShowResizeHandlesCheckBox(new QCheckBox(tr("show resize handles"), this)) { mShowResizeHandlesCheckBox->setChecked(false); QWidget *nodePane = new QWidget(this); nodePane->setObjectName("NodeEditorBackground"); @@ -80,19 +83,15 @@ WbNodeEditor::WbNodeEditor(QWidget *parent) // Main layout mStackedWidget->addWidget(nodePane); - mStackedWidget->addWidget(new QWidget(this)); // empty pane + mStackedWidget->addWidget(new QWidget(this)); // empty pane mLayout->addWidget(mStackedWidget, 1, 1); - connect(mDefEdit, &WbFieldLineEdit::returnPressed, this, - &WbNodeEditor::apply); + connect(mDefEdit, &WbFieldLineEdit::returnPressed, this, &WbNodeEditor::apply); connect(mDefEdit, &WbFieldLineEdit::focusLeft, this, &WbNodeEditor::apply); connect(mPrintUrl, &QPushButton::pressed, this, &WbNodeEditor::printUrl); - connect(mShowResizeHandlesCheckBox, &QAbstractButton::toggled, - WbSelection::instance(), - &WbSelection::showResizeManipulatorFromSceneTree, - Qt::UniqueConnection); - connect(worldCheckTimer, &QTimer::timeout, this, - &WbNodeEditor::tryConnectToWorld); + connect(mShowResizeHandlesCheckBox, &QAbstractButton::toggled, WbSelection::instance(), + &WbSelection::showResizeManipulatorFromSceneTree, Qt::UniqueConnection); + connect(worldCheckTimer, &QTimer::timeout, this, &WbNodeEditor::tryConnectToWorld); worldCheckTimer->start(500); } @@ -100,10 +99,8 @@ void WbNodeEditor::tryConnectToWorld() { world = WbWorld::instance(); state = WbSimulationState::instance(); if (oldWorld != world) { - connect(world, &WbWorld::checkDefDiff, this, - &WbNodeEditor::resetDefNamesToInitial); - connect(this, &WbNodeEditor::resetModifiedFromSceneTree, world, - &WbWorld::resetModifiedFromSceneTree); + connect(world, &WbWorld::checkDefDiff, this, &WbNodeEditor::resetDefNamesToInitial); + connect(this, &WbNodeEditor::resetModifiedFromSceneTree, world, &WbWorld::resetModifiedFromSceneTree); oldWorld = const_cast(world); mInitialCurrentDefMap.clear(); worldCheckTimer->stop(); @@ -111,8 +108,7 @@ void WbNodeEditor::tryConnectToWorld() { } void WbNodeEditor::startTimer() { - disconnect(world, &WbWorld::checkDefDiff, this, - &WbNodeEditor::resetDefNamesToInitial); + disconnect(world, &WbWorld::checkDefDiff, this, &WbNodeEditor::resetDefNamesToInitial); worldCheckTimer->start(500); } @@ -120,9 +116,7 @@ void WbNodeEditor::printUrl() { if (!mNode->isProtoInstance()) return; - WbLog::info( - tr("EXTERNPROTO \"%1\"") - .arg(WbProtoManager::instance()->externProtoUrl(mNode, true))); + WbLog::info(tr("EXTERNPROTO \"%1\"").arg(WbProtoManager::instance()->externProtoUrl(mNode, true))); } void WbNodeEditor::recursiveBlockSignals(bool block) { @@ -157,14 +151,12 @@ void WbNodeEditor::edit(bool copyOriginalValue) { if (handlesAvailable) { const WbGeometry *g = dynamic_cast(baseNode); if (g) - mShowResizeHandlesCheckBox->setChecked( - g->isResizeManipulatorAttached()); + mShowResizeHandlesCheckBox->setChecked(g->isResizeManipulatorAttached()); } } if (mNode && !mInitialCurrentDefMap.contains(mNode)) - mInitialCurrentDefMap[mNode] = - QPair(mNode->defName(), QString()); + mInitialCurrentDefMap[mNode] = QPair(mNode->defName(), QString()); } update(); @@ -195,14 +187,11 @@ void WbNodeEditor::update() { if (mNode->defName().isEmpty()) mUseCount->clear(); else - mUseCount->setText( - tr("USE count: %1").arg(mNode->useCount())); // TODO: is this the - // final implementation? + mUseCount->setText(tr("USE count: %1").arg(mNode->useCount())); // TODO: is this the final implementation? if (mNode->isProtoInstance()) { mPrintUrl->setVisible(true); - mPrintUrl->setToolTip( - WbProtoManager::instance()->externProtoUrl(mNode, true)); + mPrintUrl->setToolTip(WbProtoManager::instance()->externProtoUrl(mNode, true)); } else mPrintUrl->setVisible(false); } else @@ -210,19 +199,19 @@ void WbNodeEditor::update() { const WbGeometry *node = dynamic_cast(mNode); if (node && !node->isUseNode()) { - const int maxTriangleNumberToCastShadows = - node->maxIndexNumberToCastShadows() / 3; + const int maxTriangleNumberToCastShadows = node->maxIndexNumberToCastShadows() / 3; int triangleCount = node->triangleCount(); if (triangleCount > maxTriangleNumberToCastShadows) - mNbTriangles->setText( - tr("Triangle count: %1 (no shadow)").arg(triangleCount)); + mNbTriangles->setText(tr("Triangle count: %1 (no shadow)").arg(triangleCount)); else mNbTriangles->setText(tr("Triangle count: %1").arg(triangleCount)); } else mNbTriangles->clear(); } -void WbNodeEditor::resetFocus() { mDefEdit->clearFocus(); } +void WbNodeEditor::resetFocus() { + mDefEdit->clearFocus(); +} void WbNodeEditor::apply() { if (!mNode || mStackedWidget->currentIndex() == EMPTY_PANE) @@ -248,10 +237,8 @@ void WbNodeEditor::apply() { mDefEdit->blockSignals(true); if (newDef.isEmpty() && mNode->useCount() > 0) { - WbMessageBox::warning( - tr("This DEF cannot be cleared because some USE nodes depend on it."), - this); - mDefEdit->setText(previousDef); // restore + WbMessageBox::warning(tr("This DEF cannot be cleared because some USE nodes depend on it."), this); + mDefEdit->setText(previousDef); // restore mDefEdit->blockSignals(false); return; } @@ -261,35 +248,29 @@ void WbNodeEditor::apply() { // check if the new DEF name is not already used by subsequent USE nodes bool defOverlap = false; bool useOverlap = false; - dictionaryUpdateRequest = WbVrmlNodeUtilities::hasASubsequentUseOrDefNode( - mNode, newDef, previousDef, useOverlap, defOverlap); + dictionaryUpdateRequest = + WbVrmlNodeUtilities::hasASubsequentUseOrDefNode(mNode, newDef, previousDef, useOverlap, defOverlap); if (dictionaryUpdateRequest) { mMessageBox = true; QString message; if (defOverlap && useOverlap) { - message = tr( - "This DEF string is already used by subsequent USE and DEF nodes. " - "Applying this change will modify all the USE nodes referring to " - "previous node with same DEF name " - "and USE nodes referring to the selected node. \n" - "Do you want to continue?"); + message = tr("This DEF string is already used by subsequent USE and DEF nodes. " + "Applying this change will modify all the USE nodes referring to previous node with same DEF name " + "and USE nodes referring to the selected node. \n" + "Do you want to continue?"); } else if (defOverlap) { message = tr("This DEF string is already used by subsequent DEF nodes. " - "Applying this change will turn USE nodes of the selected " - "node into copies of subsequent DEF node.\n" + "Applying this change will turn USE nodes of the selected node into copies of subsequent DEF node.\n" "Do you want to continue?"); } else { - message = tr( - "This DEF string is already referred to by subsequent USE nodes. " - "Applying this change will turn them into copies of the selected " - "node.\n" - "Do you want to continue?"); + message = tr("This DEF string is already referred to by subsequent USE nodes. " + "Applying this change will turn them into copies of the selected node.\n" + "Do you want to continue?"); } mMessageBox = false; - if (WbMessageBox::question(message, this, tr("DEF name change")) == - QMessageBox::Cancel) { + if (WbMessageBox::question(message, this, tr("DEF name change")) == QMessageBox::Cancel) { mDefEdit->setText(previousDef); mDefEdit->blockSignals(false); return; @@ -315,25 +296,24 @@ void WbNodeEditor::compareInitialCurrentDef() { if (!mInitialCurrentDefMap.isEmpty()) { bool foundDifference = false; // Iterate through the QMap - for (auto it = mInitialCurrentDefMap.constBegin(); - it != mInitialCurrentDefMap.constEnd(); ++it) { - const QString &initialDef = it.value().first; // First QString (initial) - const QString ¤tDef = it.value().second; // Second QString (current) + for (auto it = mInitialCurrentDefMap.constBegin(); it != mInitialCurrentDefMap.constEnd(); ++it) { + const QString &initialDef = it.value().first; // First QString (initial) + const QString ¤tDef = it.value().second; // Second QString (current) // Compare the two QStrings if (initialDef != currentDef) { - foundDifference = true; // Mark that a difference is found + foundDifference = true; // Mark that a difference is found break; } } if (foundDifference) - emit defNameChanged(true); // Emit true if any difference is found + emit defNameChanged(true); // Emit true if any difference is found else { emit resetModifiedFromSceneTree(); - emit defNameChanged(false); // Emit false if no differences were found + emit defNameChanged(false); // Emit false if no differences were found } } else - emit defNameChanged(false); // If all QStrings are the same, return false + emit defNameChanged(false); // If all QStrings are the same, return false } void WbNodeEditor::resetDefNamesToInitial() { @@ -344,15 +324,13 @@ void WbNodeEditor::resetDefNamesToInitial() { } // Iterate through the map and reset each node's DEF name to its initial value - for (auto it = mInitialCurrentDefMap.begin(); - it != mInitialCurrentDefMap.end(); ++it) { + for (auto it = mInitialCurrentDefMap.begin(); it != mInitialCurrentDefMap.end(); ++it) { WbNode *node = it.key(); - const QString &initialDef = it.value().first; // Access initial DEF name + const QString &initialDef = it.value().first; // Access initial DEF name - // Only reset if node exists and the current DEF differs from the initial - // one + // Only reset if node exists and the current DEF differs from the initial one if (node && node->defName() != initialDef) - node->setDefName(initialDef); // Set the DEF name back to the initial one + node->setDefName(initialDef); // Set the DEF name back to the initial one } update(); @@ -369,20 +347,18 @@ void WbNodeEditor::switchInitialCurrentDef() { } // Iterate through the map and switch the initial DEF to the current one - for (auto it = mInitialCurrentDefMap.begin(); - it != mInitialCurrentDefMap.end(); ++it) { + for (auto it = mInitialCurrentDefMap.begin(); it != mInitialCurrentDefMap.end(); ++it) { const WbNode *node = it.key(); // Switch the initial DEF to the current DEF if (node) { - QString &initialDef = it.value().first; // Reference to initial DEF name - const QString ¤tDef = - node->defName(); // Get the current DEF name of the node - initialDef = currentDef; // Update the initial DEF with the current one + QString &initialDef = it.value().first; // Reference to initial DEF name + const QString ¤tDef = node->defName(); // Get the current DEF name of the node + initialDef = currentDef; // Update the initial DEF with the current one } } update(); emit defNameChanged(false); -} \ No newline at end of file +} From 7238bcbf8cadbd70703cbd8e1e066d75882ac84d Mon Sep 17 00:00:00 2001 From: MNikoliCC Date: Mon, 28 Oct 2024 16:40:46 +0100 Subject: [PATCH 12/12] Remove Timer, Implement Singleton Pattern in 'WbNodeEditor', Emit A New Signal When The 'world' Instance Is Created --- src/webots/gui/WbMainWindow.cpp | 5 +++++ src/webots/gui/WbMainWindow.hpp | 1 + src/webots/scene_tree/WbFieldEditor.cpp | 4 +--- src/webots/scene_tree/WbNodeEditor.cpp | 28 +++++++++++-------------- src/webots/scene_tree/WbNodeEditor.hpp | 9 ++++---- src/webots/scene_tree/WbNodePane.cpp | 2 +- 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/webots/gui/WbMainWindow.cpp b/src/webots/gui/WbMainWindow.cpp index 91638c2a306..f4dabfbda85 100644 --- a/src/webots/gui/WbMainWindow.cpp +++ b/src/webots/gui/WbMainWindow.cpp @@ -38,6 +38,7 @@ #include "WbNewProjectWizard.hpp" #include "WbNewProtoWizard.hpp" #include "WbNewWorldWizard.hpp" +#include "WbNodeEditor.hpp" #include "WbNodeOperations.hpp" #include "WbNodeUtilities.hpp" #include "WbOdeDebugger.hpp" @@ -1343,6 +1344,10 @@ void WbMainWindow::updateAfterWorldLoading(bool reloading, bool firstLoad) { if (world->fileName() != WbProject::newWorldPath()) mRecentFiles->makeRecent(world->fileName()); + connect(this, &WbMainWindow::worldCreated, WbNodeEditor::instance(), &WbNodeEditor::tryConnectToWorld); + emit worldCreated(); + disconnect(this, &WbMainWindow::worldCreated, WbNodeEditor::instance(), &WbNodeEditor::tryConnectToWorld); + mSimulationView->setWorld(WbSimulationWorld::instance()); // update 'view' menu diff --git a/src/webots/gui/WbMainWindow.hpp b/src/webots/gui/WbMainWindow.hpp index fe7f2a88660..cfff58e8699 100644 --- a/src/webots/gui/WbMainWindow.hpp +++ b/src/webots/gui/WbMainWindow.hpp @@ -74,6 +74,7 @@ class WbMainWindow : public QMainWindow { signals: void restartRequested(); void splashScreenCloseRequested(); + void worldCreated(); public slots: void loadDifferentWorld(const QString &fileName); diff --git a/src/webots/scene_tree/WbFieldEditor.cpp b/src/webots/scene_tree/WbFieldEditor.cpp index 765f4a10f7f..97e924af7c0 100644 --- a/src/webots/scene_tree/WbFieldEditor.cpp +++ b/src/webots/scene_tree/WbFieldEditor.cpp @@ -87,7 +87,7 @@ WbFieldEditor::WbFieldEditor(QWidget *parent) : connect(stringEditor, &WbExtendedStringEditor::editRequested, this, &WbFieldEditor::editRequested); WbNodePane *const nodePane = new WbNodePane(this); - const WbNodeEditor *nodeEditor = nodePane->nodeEditor(); + const WbNodeEditor *nodeEditor = WbNodeEditor::instance(nodePane); connect(nodeEditor, &WbNodeEditor::dictionaryUpdateRequested, this, &WbFieldEditor::dictionaryUpdateRequested); connect(nodeEditor, &WbNodeEditor::defNameChanged, WbActionManager::instance()->action(WbAction::SAVE_WORLD), &QAction::setEnabled); @@ -99,8 +99,6 @@ WbFieldEditor::WbFieldEditor(QWidget *parent) : &WbNodeEditor::switchInitialCurrentDef); connect(WbActionManager::instance()->action(WbAction::SAVE_WORLD_AS), &QAction::triggered, nodeEditor, &WbNodeEditor::switchInitialCurrentDef); - connect(WbActionManager::instance()->action(WbAction::RELOAD_WORLD), &QAction::triggered, nodeEditor, - &WbNodeEditor::startTimer); // create editors mEditors.insert(WB_NO_FIELD, new WbEmptyEditor(this)); mEditors.insert(WB_SF_BOOL, new WbBoolEditor(this)); diff --git a/src/webots/scene_tree/WbNodeEditor.cpp b/src/webots/scene_tree/WbNodeEditor.cpp index 898e20d2cf0..1dbbe07ba44 100644 --- a/src/webots/scene_tree/WbNodeEditor.cpp +++ b/src/webots/scene_tree/WbNodeEditor.cpp @@ -46,6 +46,14 @@ #include #include +WbNodeEditor *WbNodeEditor::cInstance = nullptr; + +WbNodeEditor *WbNodeEditor::instance(QWidget *parent) { + if (!cInstance) + cInstance = new WbNodeEditor(parent); + return cInstance; +} + WbNodeEditor::WbNodeEditor(QWidget *parent) : WbValueEditor(parent), mNode(NULL), @@ -55,7 +63,6 @@ WbNodeEditor::WbNodeEditor(QWidget *parent) : mNbTriangles(new QLabel(this)), mStackedWidget(new QStackedWidget(this)), mMessageBox(false), - worldCheckTimer(new QTimer(this)), mShowResizeHandlesLabel(new QLabel(tr("3D tools:"), this)), mShowResizeHandlesCheckBox(new QCheckBox(tr("show resize handles"), this)) { mShowResizeHandlesCheckBox->setChecked(false); @@ -91,25 +98,14 @@ WbNodeEditor::WbNodeEditor(QWidget *parent) : connect(mPrintUrl, &QPushButton::pressed, this, &WbNodeEditor::printUrl); connect(mShowResizeHandlesCheckBox, &QAbstractButton::toggled, WbSelection::instance(), &WbSelection::showResizeManipulatorFromSceneTree, Qt::UniqueConnection); - connect(worldCheckTimer, &QTimer::timeout, this, &WbNodeEditor::tryConnectToWorld); - worldCheckTimer->start(500); + state = WbSimulationState::instance(); } void WbNodeEditor::tryConnectToWorld() { world = WbWorld::instance(); - state = WbSimulationState::instance(); - if (oldWorld != world) { - connect(world, &WbWorld::checkDefDiff, this, &WbNodeEditor::resetDefNamesToInitial); - connect(this, &WbNodeEditor::resetModifiedFromSceneTree, world, &WbWorld::resetModifiedFromSceneTree); - oldWorld = const_cast(world); - mInitialCurrentDefMap.clear(); - worldCheckTimer->stop(); - } -} - -void WbNodeEditor::startTimer() { - disconnect(world, &WbWorld::checkDefDiff, this, &WbNodeEditor::resetDefNamesToInitial); - worldCheckTimer->start(500); + connect(world, &WbWorld::checkDefDiff, this, &WbNodeEditor::resetDefNamesToInitial); + connect(this, &WbNodeEditor::resetModifiedFromSceneTree, world, &WbWorld::resetModifiedFromSceneTree); + mInitialCurrentDefMap.clear(); } void WbNodeEditor::printUrl() { diff --git a/src/webots/scene_tree/WbNodeEditor.hpp b/src/webots/scene_tree/WbNodeEditor.hpp index b9671eaed08..a4e781f4b2c 100644 --- a/src/webots/scene_tree/WbNodeEditor.hpp +++ b/src/webots/scene_tree/WbNodeEditor.hpp @@ -35,7 +35,7 @@ class WbNodeEditor : public WbValueEditor { Q_OBJECT public: - explicit WbNodeEditor(QWidget *parent = NULL); + static WbNodeEditor *instance(QWidget *parent = nullptr); void recursiveBlockSignals(bool block) override; @@ -57,7 +57,7 @@ public slots: void cleanValue() override; void resetDefNamesToInitial(); void switchInitialCurrentDef(); - void startTimer(); + void tryConnectToWorld(); protected: enum PaneType { DEF_PANE, EMPTY_PANE }; @@ -71,19 +71,18 @@ public slots: QStackedWidget *mStackedWidget; bool mMessageBox; QMap> mInitialCurrentDefMap; - QTimer *worldCheckTimer; const WbWorld *world = nullptr; - WbWorld *oldWorld = nullptr; WbSimulationState *state = nullptr; + static WbNodeEditor *cInstance; // actions buttons QLabel *mShowResizeHandlesLabel; QCheckBox *mShowResizeHandlesCheckBox; + explicit WbNodeEditor(QWidget *parent = nullptr); void setTransformActionVisibile(bool visible); void takeKeyboardFocus() override {} void printUrl(); - void tryConnectToWorld(); void compareInitialCurrentDef(); }; diff --git a/src/webots/scene_tree/WbNodePane.cpp b/src/webots/scene_tree/WbNodePane.cpp index acc58332b58..4ed05d0d10f 100644 --- a/src/webots/scene_tree/WbNodePane.cpp +++ b/src/webots/scene_tree/WbNodePane.cpp @@ -33,7 +33,7 @@ static const QStringList cTabNames = QStringList() << "Node" WbNodePane::WbNodePane(QWidget *parent) : WbValueEditor(parent), mTabs(new QTabWidget(this)), - mNodeEditor(new WbNodeEditor()), + mNodeEditor(WbNodeEditor::instance()), mPhysicsViewer(new WbPhysicsViewer()), mPositionViewer(new WbPositionViewer()), mVelocityViewer(new WbVelocityViewer()),