From b2f1680d6d103ea838f74ebafc0b15e633499d8f Mon Sep 17 00:00:00 2001 From: Sergej Geringer Date: Thu, 8 Sep 2022 19:43:09 +0200 Subject: [PATCH] GUI/Parameter: put back file param safety checks via FilePathParam project directory validation support --- core/include/mmcore/param/FilePathParam.h | 6 ++ core/src/param/FilePathParam.cpp | 5 + frontend/services/gui/src/graph/Parameter.cpp | 101 +++++++++--------- .../gui/src/widgets/FileBrowserWidget.cpp | 3 +- 4 files changed, 64 insertions(+), 51 deletions(-) diff --git a/core/include/mmcore/param/FilePathParam.h b/core/include/mmcore/param/FilePathParam.h index 283bb0ccfc..5a4e5e12cb 100644 --- a/core/include/mmcore/param/FilePathParam.h +++ b/core/include/mmcore/param/FilePathParam.h @@ -45,6 +45,8 @@ class FilePathParam : public AbstractParam { * @param flags The flags for the parameter * @param exts The required file extensions for the parameter */ + FilePathParam(const std::filesystem::path& initVal, Flags_t flags, const Extensions_t& exts, + const std::filesystem::path& project_directory); FilePathParam(const std::filesystem::path& initVal, Flags_t flags = Flag_File, const Extensions_t& exts = {}); FilePathParam(const std::string& initVal, Flags_t flags = Flag_File, const Extensions_t& exts = {}); FilePathParam(const char* initVal, Flags_t flags = Flag_File, const Extensions_t& exts = {}); @@ -113,6 +115,10 @@ class FilePathParam : public AbstractParam { return this->extensions; } + inline std::filesystem::path GetProjectDirectory() const { + return this->project_directory; + } + /** * Function checks if path is valid for given flags * diff --git a/core/src/param/FilePathParam.cpp b/core/src/param/FilePathParam.cpp index fb909cb540..fed4960b75 100644 --- a/core/src/param/FilePathParam.cpp +++ b/core/src/param/FilePathParam.cpp @@ -10,6 +10,11 @@ using namespace megamol::core::param; +FilePathParam::FilePathParam(const std::filesystem::path& initVal, Flags_t flags, const Extensions_t& exts, + const std::filesystem::path& project_directory) + : FilePathParam(initVal, flags, exts) { + this->SetProjectDirectory(project_directory); +} FilePathParam::FilePathParam(const std::filesystem::path& initVal, Flags_t flags, const Extensions_t& exts) : AbstractParam() diff --git a/frontend/services/gui/src/graph/Parameter.cpp b/frontend/services/gui/src/graph/Parameter.cpp index e874e8382a..82c1a8e9f0 100644 --- a/frontend/services/gui/src/graph/Parameter.cpp +++ b/frontend/services/gui/src/graph/Parameter.cpp @@ -170,14 +170,10 @@ std::string megamol::gui::Parameter::GetValueString() const { } else if constexpr (std::is_same_v) { value_string = arg; } else if constexpr (std::is_same_v) { - //if (this->core_param_ptr != nullptr) { - // value_string = this->core_param_ptr->ValueString(); - //} else { - // auto file_storage = this->GetStorage(); - // auto parameter = megamol::core::param::FilePathParam(arg, file_storage.first, file_storage.second); - // value_string = parameter.ValueString(); - //} - value_string = arg.u8string(); + auto file_storage = this->GetStorage(); + auto parameter = megamol::core::param::FilePathParam( + arg, file_storage.flags, file_storage.extensions, file_storage.project_directory); + value_string = parameter.ValueString(); } else if constexpr (std::is_same_v) { auto parameter = megamol::core::param::TernaryParam(arg); value_string = parameter.ValueString(); @@ -250,10 +246,10 @@ bool megamol::gui::Parameter::SetValueString(const std::string& val_str, bool se } break; case (ParamType_t::FILEPATH): { auto file_storage = this->GetStorage(); - megamol::core::param::FilePathParam parameter( - std::filesystem::u8path(val_str), file_storage.first, file_storage.second); + megamol::core::param::FilePathParam parameter(std::filesystem::path(val_str), file_storage.flags, + file_storage.extensions, file_storage.project_directory); retval = parameter.ParseValue(val_str); - this->SetValue(parameter.Value(), set_default_val, set_dirty); + this->SetValue(parameter.ValueString(), set_default_val, set_dirty); } break; case (ParamType_t::FLEXENUM): { megamol::core::param::FlexEnumParam parameter(val_str); @@ -346,7 +342,7 @@ bool megamol::gui::Parameter::ReadNewCoreParameterToStockParameter( } else if (auto* p_ptr = in_param_slot.Param()) { out_param.type = ParamType_t::FILEPATH; out_param.default_value = p_ptr->ValueString(); - out_param.storage = FilePathStorage_t({p_ptr->GetFlags(), p_ptr->GetExtensions()}); + out_param.storage = FilePathStorage_t{p_ptr->GetFlags(), p_ptr->GetExtensions(), p_ptr->GetProjectDirectory()}; } else if (auto* p_ptr = in_param_slot.Param()) { out_param.type = ParamType_t::FLEXENUM; out_param.default_value = p_ptr->ValueString(); @@ -490,8 +486,8 @@ bool megamol::gui::Parameter::ReadNewCoreParameterToNewParameter(megamol::core:: out_param->SetValue(p_ptr->Value(), set_default_val, set_dirty); } else if (auto* p_ptr = in_param_slot.Param()) { out_param = std::make_shared(megamol::gui::GenerateUniqueID(), ParamType_t::FILEPATH, - FilePathStorage_t({p_ptr->GetFlags(), p_ptr->GetExtensions()}), std::monostate(), std::monostate(), - std::monostate(), param_name, description); + FilePathStorage_t{p_ptr->GetFlags(), p_ptr->GetExtensions(), p_ptr->GetProjectDirectory()}, + std::monostate(), std::monostate(), std::monostate(), param_name, description); out_param->SetValue(p_ptr->Value(), set_default_val, set_dirty); } else { megamol::core::utility::log::Log::DefaultLog.WriteError( @@ -569,7 +565,8 @@ bool megamol::gui::Parameter::ReadCoreParameterToParameter( } else if (auto* p_ptr = dynamic_cast(in_param_ptr.get())) { if (out_param.type == ParamType_t::FILEPATH) { out_param.SetValue(std::filesystem::path{p_ptr->ValueString()}, set_default_val, set_dirty); - auto file_storage = FilePathStorage_t({p_ptr->GetFlags(), p_ptr->GetExtensions()}); + auto file_storage = + FilePathStorage_t{p_ptr->GetFlags(), p_ptr->GetExtensions(), p_ptr->GetProjectDirectory()}; out_param.SetStorage(file_storage); } else { type_error = true; @@ -1477,41 +1474,45 @@ bool megamol::gui::Parameter::widget_filepath(megamol::gui::Parameter::WidgetSco auto tmp_val_str = std::get(this->gui_widget_value); std::replace(tmp_val_str.begin(), tmp_val_str.end(), '\\', '/'); val = std::filesystem::path(tmp_val_str); - //try { - // if (last_val != val) { - // auto error_flags = FilePathParam::ValidatePath(val, file_extensions, file_flags); - // if (error_flags & FilePathParam::FilePathParam::Flag_File) { - // this->gui_popup_msg = - // "Omitting value '" + val.generic_u8string() + "'. Expected file but directory is given."; - // } - // if (error_flags & FilePathParam::Flag_Directory) { - // this->gui_popup_msg = - // "Omitting value '" + val.generic_u8string() + "'. Expected directory but file is given."; - // } - // if (error_flags & FilePathParam::Internal_NoExistenceCheck) { - // this->gui_popup_msg = "Omitting value '" + val.generic_u8string() + "'. File does not exist."; - // } - // if (error_flags & FilePathParam::Internal_RestrictExtension) { - // std::string log_exts; - // for (auto& ext : file_extensions) { - // log_exts += "'." + ext + "' "; - // } - // this->gui_popup_msg = "Omitting value '" + val.generic_u8string() + - // "'. File does not have required extension: " + log_exts; - // } - // if (error_flags != 0) { - // val = last_val; - // megamol::core::utility::log::Log::DefaultLog.WriteWarn( - // (std::string("[FilePathParam] ") + this->gui_popup_msg).c_str()); - // if (!this->gui_popup_disabled) { - // ImGui::OpenPopup(popup_name.c_str()); - // } - // } - // } - //} catch (std::filesystem::filesystem_error& e) { - // megamol::core::utility::log::Log::DefaultLog.WriteError( - // "Filesystem Error: %s [%s, %s, line %d]\n", e.what(), __FILE__, __FUNCTION__, __LINE__); - //} + try { + const auto& extensions = store.extensions; + const auto& flags = store.flags; + const auto& projdir = store.project_directory; + + if (last_val != val) { + auto error_flags = FilePathParam::ValidatePath(val, extensions, flags, projdir); + if (error_flags & FilePathParam::FilePathParam::Flag_File) { + this->gui_popup_msg = + "Omitting value '" + val.generic_u8string() + "'. Expected file but directory is given."; + } + if (error_flags & FilePathParam::Flag_Directory) { + this->gui_popup_msg = + "Omitting value '" + val.generic_u8string() + "'. Expected directory but file is given."; + } + if (error_flags & FilePathParam::Internal_NoExistenceCheck) { + this->gui_popup_msg = "Omitting value '" + val.generic_u8string() + "'. File does not exist."; + } + if (error_flags & FilePathParam::Internal_RestrictExtension) { + std::string log_exts; + for (auto& ext : extensions) { + log_exts += "'." + ext + "' "; + } + this->gui_popup_msg = "Omitting value '" + val.generic_u8string() + + "'. File does not have required extension: " + log_exts; + } + if (error_flags != 0) { + val = last_val; + megamol::core::utility::log::Log::DefaultLog.WriteWarn( + (std::string("[FilePathParam] ") + this->gui_popup_msg).c_str()); + if (!this->gui_popup_disabled) { + ImGui::OpenPopup(popup_name.c_str()); + } + } + } + } catch (std::filesystem::filesystem_error& e) { + megamol::core::utility::log::Log::DefaultLog.WriteError( + "Filesystem Error: %s [%s, %s, line %d]\n", e.what(), __FILE__, __FUNCTION__, __LINE__); + } this->filepath_scroll_xmax = true; retval = true; } else if (!ImGui::IsItemActive() && !ImGui::IsItemEdited()) { diff --git a/frontend/services/gui/src/widgets/FileBrowserWidget.cpp b/frontend/services/gui/src/widgets/FileBrowserWidget.cpp index d7ab242b7e..7116ac3b0b 100644 --- a/frontend/services/gui/src/widgets/FileBrowserWidget.cpp +++ b/frontend/services/gui/src/widgets/FileBrowserWidget.cpp @@ -461,6 +461,7 @@ void megamol::gui::FileBrowserWidget::validate_file(FileBrowserWidget::DialogMod auto const& flags = store.flags; auto const& extensions = store.extensions; + auto const& project_dir = store.project_directory; try { this->file_errors.clear(); @@ -476,7 +477,7 @@ void megamol::gui::FileBrowserWidget::validate_file(FileBrowserWidget::DialogMod tmp_filepath = dir; } } - auto error_flags = FilePathParam::ValidatePath(tmp_filepath, extensions, flags); + auto error_flags = FilePathParam::ValidatePath(tmp_filepath, extensions, flags, project_dir); if (error_flags != 0) { this->valid_file = false; }