From 3286722b6a28ebf42d2ab517b5390608f3846214 Mon Sep 17 00:00:00 2001 From: AlexandreS <32449369+AlexandreSi@users.noreply.github.com> Date: Thu, 13 Jul 2023 17:09:00 +0200 Subject: [PATCH] Enable search and replace in For each object events and Javascript events (#5477) --- Core/GDCore/Events/Builtin/ForEachEvent.cpp | 2 +- Core/GDCore/Events/Builtin/ForEachEvent.h | 10 ++- Core/GDCore/Events/Event.h | 8 ++ Core/GDCore/IDE/Events/EventsRefactorer.cpp | 78 +++++++++++++++---- GDJS/GDJS/Events/Builtin/JsCodeEvent.h | 6 ++ .../EventsTree/Renderers/WhileEvent.js | 5 +- 6 files changed, 86 insertions(+), 23 deletions(-) diff --git a/Core/GDCore/Events/Builtin/ForEachEvent.cpp b/Core/GDCore/Events/Builtin/ForEachEvent.cpp index 6628bc7aa5bc..9fbde064c219 100644 --- a/Core/GDCore/Events/Builtin/ForEachEvent.cpp +++ b/Core/GDCore/Events/Builtin/ForEachEvent.cpp @@ -15,7 +15,7 @@ using namespace std; namespace gd { ForEachEvent::ForEachEvent() - : BaseEvent(), objectsToPick(""), objectsToPickSelected(false) {} + : BaseEvent(), objectsToPick("") {} vector ForEachEvent::GetAllConditionsVectors() { vector allConditions; diff --git a/Core/GDCore/Events/Builtin/ForEachEvent.h b/Core/GDCore/Events/Builtin/ForEachEvent.h index 07b0b3bef353..4089d9c9c542 100644 --- a/Core/GDCore/Events/Builtin/ForEachEvent.h +++ b/Core/GDCore/Events/Builtin/ForEachEvent.h @@ -6,6 +6,8 @@ #ifndef FOREACHEVENT_H #define FOREACHEVENT_H +#include + #include "GDCore/Events/Event.h" #include "GDCore/Events/EventsList.h" namespace gd { @@ -62,13 +64,17 @@ class GD_CORE_API ForEachEvent : public gd::BaseEvent { virtual void UnserializeFrom(gd::Project& project, const SerializerElement& element); + std::vector GetAllObjectExpressions() { + std::vector allObjectExpressions; + allObjectExpressions.push_back(&objectsToPick); + return allObjectExpressions; + } + private: gd::Expression objectsToPick; gd::InstructionsList conditions; gd::InstructionsList actions; gd::EventsList events; - - bool objectsToPickSelected; }; } // namespace gd diff --git a/Core/GDCore/Events/Event.h b/Core/GDCore/Events/Event.h index 1f470d37f8c0..128c2b7423da 100644 --- a/Core/GDCore/Events/Event.h +++ b/Core/GDCore/Events/Event.h @@ -282,6 +282,14 @@ class GD_CORE_API BaseEvent { */ bool IsFolded() const { return folded; } + /** + * \brief Return a list of all objects linked to the event. + */ + virtual std::vector GetAllObjectExpressions() { + std::vector allObjectExpressions; + return allObjectExpressions; + } + ///@} std::weak_ptr diff --git a/Core/GDCore/IDE/Events/EventsRefactorer.cpp b/Core/GDCore/IDE/Events/EventsRefactorer.cpp index 779774e0c0ad..eddb6105cf72 100644 --- a/Core/GDCore/IDE/Events/EventsRefactorer.cpp +++ b/Core/GDCore/IDE/Events/EventsRefactorer.cpp @@ -555,6 +555,22 @@ void EventsRefactorer::RemoveObjectInEvents(const gd::Platform& platform, } } +gd::String ReplaceAllOccurrencesCaseInsensitive(gd::String context, + const gd::String& from, + const gd::String& to) { + size_t lookHere = 0; + size_t foundHere; + size_t fromSize = from.size(); + size_t toSize = to.size(); + while ((foundHere = context.FindCaseInsensitive(from, lookHere)) != + gd::String::npos) { + context.replace(foundHere, fromSize, to); + lookHere = foundHere + toSize; + } + + return context; +} + std::vector EventsRefactorer::ReplaceStringInEvents( gd::ObjectsContainer& project, gd::ObjectsContainer& layout, @@ -570,6 +586,32 @@ std::vector EventsRefactorer::ReplaceStringInEvents( for (std::size_t i = 0; i < events.size(); ++i) { bool eventModified = false; + + std::vector allObjectExpressions = + events[i].GetAllObjectExpressions(); + for (std::size_t j = 0; j < allObjectExpressions.size(); ++j) { + gd::String newExpressionPlainString = + matchCase ? allObjectExpressions[j]->GetPlainString().FindAndReplace( + toReplace, newString, true) + : ReplaceAllOccurrencesCaseInsensitive( + allObjectExpressions[j]->GetPlainString(), + toReplace, + newString); + + if (newExpressionPlainString != + allObjectExpressions[j]->GetPlainString()) { + *allObjectExpressions[j] = gd::Expression(newExpressionPlainString); + + if (!eventModified) { + modifiedEvents.push_back(EventsSearchResult( + std::weak_ptr(events.GetEventSmartPtr(i)), + &events, + i)); + eventModified = true; + } + } + } + if (inConditions) { vector conditionsVectors = events[i].GetAllConditionsVectors(); @@ -642,22 +684,6 @@ std::vector EventsRefactorer::ReplaceStringInEvents( return modifiedEvents; } -gd::String ReplaceAllOccurrencesCaseInsensitive(gd::String context, - gd::String from, - const gd::String& to) { - size_t lookHere = 0; - size_t foundHere; - size_t fromSize = from.size(); - size_t toSize = to.size(); - while ((foundHere = context.FindCaseInsensitive(from, lookHere)) != - gd::String::npos) { - context.replace(foundHere, fromSize, to); - lookHere = foundHere + toSize; - } - - return context; -} - bool EventsRefactorer::ReplaceStringInActions(gd::ObjectsContainer& project, gd::ObjectsContainer& layout, gd::InstructionsList& actions, @@ -789,6 +815,24 @@ vector EventsRefactorer::SearchInEvents( for (std::size_t i = 0; i < events.size(); ++i) { bool eventAddedInResults = false; + std::vector allObjectExpressions = + events[i].GetAllObjectExpressions(); + for (std::size_t j = 0; j < allObjectExpressions.size(); ++j) { + size_t foundPosition = + matchCase + ? allObjectExpressions[j]->GetPlainString().find(search) + : allObjectExpressions[j]->GetPlainString().FindCaseInsensitive( + search); + + if (foundPosition != gd::String::npos && !eventAddedInResults) { + results.push_back(EventsSearchResult( + std::weak_ptr(events.GetEventSmartPtr(i)), + &events, + i)); + eventAddedInResults = true; + } + } + if (inConditions) { vector conditionsVectors = events[i].GetAllConditionsVectors(); @@ -803,6 +847,7 @@ vector EventsRefactorer::SearchInEvents( std::weak_ptr(events.GetEventSmartPtr(i)), &events, i)); + eventAddedInResults = true; } } } @@ -820,6 +865,7 @@ vector EventsRefactorer::SearchInEvents( std::weak_ptr(events.GetEventSmartPtr(i)), &events, i)); + eventAddedInResults = true; } } } diff --git a/GDJS/GDJS/Events/Builtin/JsCodeEvent.h b/GDJS/GDJS/Events/Builtin/JsCodeEvent.h index 75b499102b19..439c00337d58 100644 --- a/GDJS/GDJS/Events/Builtin/JsCodeEvent.h +++ b/GDJS/GDJS/Events/Builtin/JsCodeEvent.h @@ -50,6 +50,12 @@ class JsCodeEvent : public gd::BaseEvent { bool IsEventsSheetExpanded() const { return eventsSheetExpanded; } void SetEventsSheetExpanded(bool enable) { eventsSheetExpanded = enable; }; + std::vector GetAllObjectExpressions() { + std::vector allObjectExpressions; + allObjectExpressions.push_back(¶meterObjects); + return allObjectExpressions; + } + private: void Init(const JsCodeEvent& event); diff --git a/newIDE/app/src/EventsSheet/EventsTree/Renderers/WhileEvent.js b/newIDE/app/src/EventsSheet/EventsTree/Renderers/WhileEvent.js index 4fea9ca6ead7..696965c48479 100644 --- a/newIDE/app/src/EventsSheet/EventsTree/Renderers/WhileEvent.js +++ b/newIDE/app/src/EventsSheet/EventsTree/Renderers/WhileEvent.js @@ -27,10 +27,7 @@ const styles = { }, }; -export default class ForEachEvent extends React.Component< - EventRendererProps, - * -> { +export default class WhileEvent extends React.Component { render() { var whileEvent = gd.asWhileEvent(this.props.event);