Skip to content

Commit 4c42a41

Browse files
authored
Fix Crash when deleting a folder outside of Overload and trying to expand it afterwards#725 (#729)
1 parent e29f595 commit 4c42a41

1 file changed

Lines changed: 51 additions & 1 deletion

File tree

Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <OvUI/Widgets/Buttons/Button.h>
4040
#include <OvUI/Widgets/Layout/Group.h>
4141
#include <OvUI/Widgets/Texts/TextClickable.h>
42+
#include <OvUI/Widgets/Texts/TextColored.h>
4243
#include <OvUI/Widgets/Visual/Image.h>
4344
#include <OvUI/Widgets/Visual/Separator.h>
4445

@@ -135,6 +136,15 @@ namespace
135136
return !relativePath.empty() && *relativePath.begin() != "..";
136137
}
137138

139+
bool ValidateFolderPath(const std::filesystem::path& p_path, const std::string& p_actionName)
140+
{
141+
if (std::filesystem::exists(p_path) && std::filesystem::is_directory(p_path))
142+
return true;
143+
144+
OVLOG_ERROR(std::format("Cannot perform '{}' because the target folder was deleted externally", p_actionName));
145+
return false;
146+
}
147+
138148
class TexturePreview : public OvUI::Plugins::IPlugin
139149
{
140150
private:
@@ -185,6 +195,13 @@ namespace
185195
nameEditor.selectAllOnClick = true;
186196

187197
renameMenu.ClickedEvent +=[this, &nameEditor] {
198+
// Check if the item still exists before allowing rename
199+
if (!std::filesystem::exists(filePath))
200+
{
201+
OVLOG_ERROR("Cannot rename this item because it was deleted externally");
202+
return;
203+
}
204+
188205
nameEditor.content = filePath.stem().string();
189206

190207
if (!std::filesystem::is_directory(filePath))
@@ -198,6 +215,12 @@ namespace
198215

199216
nameEditor.EnterPressedEvent += [this](std::string p_newName)
200217
{
218+
if (!std::filesystem::exists(filePath))
219+
{
220+
OVLOG_ERROR("Cannot complete rename because the item was deleted externally");
221+
return;
222+
}
223+
201224
if (!std::filesystem::is_directory(filePath))
202225
{
203226
p_newName += filePath.extension().string();
@@ -257,6 +280,9 @@ namespace
257280

258281
void CreateNewShader(const std::string& p_shaderName, std::optional<const std::string_view> p_type)
259282
{
283+
if (!ValidateFolderPath(filePath, "Create shader"))
284+
return;
285+
260286
const auto finalPath = FindAvailableFilePath(filePath / (p_shaderName + ".ovfx"));
261287

262288
if (p_type.has_value())
@@ -296,6 +322,9 @@ namespace
296322
std::optional<std::function<void(OvCore::Resources::Material&)>> p_setupCallback
297323
)
298324
{
325+
if (!ValidateFolderPath(filePath, "Create material"))
326+
return;
327+
299328
OvCore::Resources::Material material;
300329

301330
if (p_type.has_value())
@@ -342,6 +371,8 @@ namespace
342371
auto& showInExplorer = CreateWidget<OvUI::Widgets::Menu::MenuItem>("Show in explorer");
343372
showInExplorer.ClickedEvent += [this]
344373
{
374+
if (!ValidateFolderPath(filePath, "Show in explorer"))
375+
return;
345376
OvTools::Utils::SystemCalls::ShowInExplorer(filePath.string());
346377
};
347378

@@ -350,6 +381,9 @@ namespace
350381
auto& importAssetHere = CreateWidget<OvUI::Widgets::Menu::MenuItem>("Import Here...");
351382
importAssetHere.ClickedEvent += [this]
352383
{
384+
if (!ValidateFolderPath(filePath, "Import"))
385+
return;
386+
353387
if (EDITOR_EXEC(ImportAssetAtLocation(filePath.string())))
354388
{
355389
OvUI::Widgets::Layout::TreeNode* pluginOwner = reinterpret_cast<OvUI::Widgets::Layout::TreeNode*>(userData);
@@ -412,13 +446,17 @@ namespace
412446
createAtmosphereMaterialMenu.ClickedEvent += [&createAtmosphereMaterial] { createAtmosphereMaterial.content = ""; };
413447

414448
createFolder.EnterPressedEvent += [this](std::string newFolderName) {
449+
if (!ValidateFolderPath(filePath, "Create folder"))
450+
return;
415451
const auto finalPath = FindAvailableFilePath(filePath / newFolderName);
416452
std::filesystem::create_directory(finalPath);
417453
ItemAddedEvent.Invoke(finalPath);
418454
Close();
419455
};
420456

421457
createScene.EnterPressedEvent += [this](std::string newSceneName) {
458+
if (!ValidateFolderPath(filePath, "Create scene"))
459+
return;
422460
const auto finalPath = FindAvailableFilePath(filePath / (newSceneName + ".ovscene"));
423461

424462
auto emptyScene = OvCore::SceneSystem::Scene{};
@@ -432,6 +470,8 @@ namespace
432470
};
433471

434472
createPartialShader.EnterPressedEvent += [this](std::string newShaderName) {
473+
if (!ValidateFolderPath(filePath, "Create shader"))
474+
return;
435475
const auto finalPath = FindAvailableFilePath(filePath / (newShaderName + ".ovfxh"));
436476

437477
{
@@ -443,6 +483,8 @@ namespace
443483
};
444484

445485
createScript.EnterPressedEvent += [this](std::string p_newName) {
486+
if (!ValidateFolderPath(filePath, "Create script"))
487+
return;
446488
std::erase_if(p_newName, [](char c) {
447489
return std::find(kAllowedFilenameChars.begin(), kAllowedFilenameChars.end(), c) == kAllowedFilenameChars.end();
448490
});
@@ -507,8 +549,9 @@ namespace
507549
{
508550
EDITOR_EXEC(PropagateFolderDestruction(filePath.string()));
509551
std::filesystem::remove_all(filePath);
510-
DestroyedEvent.Invoke(filePath);
511552
}
553+
554+
DestroyedEvent.Invoke(filePath);
512555
}
513556
}
514557

@@ -1045,6 +1088,13 @@ void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNod
10451088
treeNode.OpenedEvent += [this, &treeNode, path, p_isEngineItem] {
10461089
treeNode.RemoveAllWidgets();
10471090
std::filesystem::path updatedPath = std::filesystem::path{path}.parent_path() / treeNode.name;
1091+
1092+
if (!std::filesystem::exists(updatedPath) || !std::filesystem::is_directory(updatedPath))
1093+
{
1094+
OVLOG_ERROR("Folder was deleted externally: " + updatedPath.string());
1095+
return;
1096+
}
1097+
10481098
ParseFolder(treeNode, std::filesystem::directory_entry(updatedPath), p_isEngineItem);
10491099
};
10501100

0 commit comments

Comments
 (0)