[Bf-blender-cvs] [871bdb5d1fe] blender-projects-basics: Keep track of unsaved changes, indicate in "Save Settings" button
Julian Eisel
noreply at git.blender.org
Thu Oct 6 17:04:05 CEST 2022
Commit: 871bdb5d1fec6a010801dbe90c78b327a9f685b0
Author: Julian Eisel
Date: Thu Oct 6 16:42:59 2022 +0200
Branches: blender-projects-basics
https://developer.blender.org/rB871bdb5d1fec6a010801dbe90c78b327a9f685b0
Keep track of unsaved changes, indicate in "Save Settings" button
===================================================================
M release/scripts/startup/bl_ui/space_project_settings.py
M source/blender/blenkernel/BKE_blender_project.h
M source/blender/blenkernel/BKE_blender_project.hh
M source/blender/blenkernel/intern/blender_project.cc
M source/blender/blenkernel/intern/blender_project_test.cc
M source/blender/makesrna/intern/rna_blender_project.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_project_settings.py b/release/scripts/startup/bl_ui/space_project_settings.py
index fcc1d51be8d..0a099cf2c1a 100644
--- a/release/scripts/startup/bl_ui/space_project_settings.py
+++ b/release/scripts/startup/bl_ui/space_project_settings.py
@@ -13,11 +13,13 @@ class PROJECTSETTINGS_HT_header(Header):
@staticmethod
def draw_buttons(layout, context):
+ project = context.project
+
layout.operator_context = 'EXEC_AREA'
- is_dirty = True
+
+ is_dirty = project and project.is_dirty
# Show '*' to let users know the settings have been modified.
- # TODO, wrong operator
layout.operator(
"wm.save_project_settings",
text=iface_("Save Settings") + (" *" if is_dirty else ""),
diff --git a/source/blender/blenkernel/BKE_blender_project.h b/source/blender/blenkernel/BKE_blender_project.h
index 2451e2d9f29..8241747a93a 100644
--- a/source/blender/blenkernel/BKE_blender_project.h
+++ b/source/blender/blenkernel/BKE_blender_project.h
@@ -46,6 +46,8 @@ const char *BKE_project_root_path_get(const BlenderProject *project) ATTR_WARN_U
void BKE_project_name_set(const BlenderProject *project_handle, const char *name) ATTR_NONNULL();
const char *BKE_project_name_get(const BlenderProject *project) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
+bool BKE_project_has_unsaved_changes(const BlenderProject *project) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_blender_project.hh b/source/blender/blenkernel/BKE_blender_project.hh
index bc93af92129..c4f836e0578 100644
--- a/source/blender/blenkernel/BKE_blender_project.hh
+++ b/source/blender/blenkernel/BKE_blender_project.hh
@@ -48,6 +48,7 @@ class ProjectSettings {
/* Path to the project root using slashes in the OS native format. */
std::string project_root_path_;
std::string project_name_;
+ bool has_unsaved_changes_ = false;
public:
inline static const StringRefNull SETTINGS_DIRNAME = ".blender_project";
@@ -76,13 +77,14 @@ class ProjectSettings {
* \return True on success. If the .blender_project directory doesn't exist, that's treated as
* failure.
*/
- auto save_to_disk(StringRef project_path) const -> bool;
+ auto save_to_disk(StringRef project_path) -> bool;
explicit ProjectSettings(StringRef project_root_path);
auto project_root_path [[nodiscard]] () const -> StringRefNull;
void project_name(StringRef new_name);
auto project_name [[nodiscard]] () const -> StringRefNull;
+ auto has_unsaved_changes [[nodiscard]] () const -> bool;
private:
auto to_dictionary() const -> std::unique_ptr<io::serialize::DictionaryValue>;
diff --git a/source/blender/blenkernel/intern/blender_project.cc b/source/blender/blenkernel/intern/blender_project.cc
index 452bc950db2..146f3f0bef6 100644
--- a/source/blender/blenkernel/intern/blender_project.cc
+++ b/source/blender/blenkernel/intern/blender_project.cc
@@ -235,7 +235,7 @@ static void write_settings_file(StringRef settings_filepath,
os.close();
}
-bool ProjectSettings::save_to_disk(StringRef project_path) const
+bool ProjectSettings::save_to_disk(StringRef project_path)
{
ResolvedPaths paths = resolve_paths_from_project_path(project_path);
@@ -249,6 +249,8 @@ bool ProjectSettings::save_to_disk(StringRef project_path) const
std::unique_ptr settings_as_dict = to_dictionary();
write_settings_file(paths.settings_filepath, std::move(settings_as_dict));
+ has_unsaved_changes_ = false;
+
return true;
}
@@ -260,6 +262,7 @@ StringRefNull ProjectSettings::project_root_path() const
void ProjectSettings::project_name(StringRef new_name)
{
project_name_ = new_name;
+ has_unsaved_changes_ = true;
}
StringRefNull ProjectSettings::project_name() const
@@ -267,6 +270,11 @@ StringRefNull ProjectSettings::project_name() const
return project_name_;
}
+bool ProjectSettings::has_unsaved_changes() const
+{
+ return has_unsaved_changes_;
+}
+
} // namespace blender::bke
/* ---------------------------------------------------------------------- */
@@ -313,7 +321,7 @@ bool BKE_project_settings_save(const BlenderProject *project_handle)
{
const bke::BlenderProject *project = reinterpret_cast<const bke::BlenderProject *>(
project_handle);
- const bke::ProjectSettings &settings = project->get_settings();
+ bke::ProjectSettings &settings = project->get_settings();
return settings.save_to_disk(settings.project_root_path());
}
@@ -337,3 +345,11 @@ const char *BKE_project_name_get(const BlenderProject *project_handle)
project_handle);
return project->get_settings().project_name().c_str();
}
+
+bool BKE_project_has_unsaved_changes(const BlenderProject *project_handle)
+{
+ const bke::BlenderProject *project = reinterpret_cast<const bke::BlenderProject *>(
+ project_handle);
+ const bke::ProjectSettings &settings = project->get_settings();
+ return settings.has_unsaved_changes();
+}
diff --git a/source/blender/blenkernel/intern/blender_project_test.cc b/source/blender/blenkernel/intern/blender_project_test.cc
index cb3c56070bb..f5bba2c0f06 100644
--- a/source/blender/blenkernel/intern/blender_project_test.cc
+++ b/source/blender/blenkernel/intern/blender_project_test.cc
@@ -185,6 +185,34 @@ TEST_F(ProjectTest, settings_json_write)
});
}
+TEST_F(ProjectTest, settings_read_change_write)
+{
+ SVNFiles svn_files{};
+ std::unique_ptr from_project_settings = ProjectSettings::load_from_disk(svn_files.project_root);
+
+ EXPECT_FALSE(from_project_settings->has_unsaved_changes());
+
+ /* Take the settings read from the SVN files and write it to /tmp/ projects. */
+ test_foreach_project_path(
+ [&from_project_settings](StringRefNull to_project_path, StringRefNull) {
+ ProjectSettings::create_settings_directory(to_project_path);
+
+ from_project_settings->project_name("новый");
+ EXPECT_TRUE(from_project_settings->has_unsaved_changes());
+
+ if (!from_project_settings->save_to_disk(to_project_path)) {
+ FAIL();
+ }
+ EXPECT_FALSE(from_project_settings->has_unsaved_changes());
+
+ /* Now check if the settings written to disk match the expectations. */
+ std::unique_ptr written_settings = ProjectSettings::load_from_disk(to_project_path);
+ EXPECT_NE(written_settings, nullptr);
+ EXPECT_EQ(written_settings->project_name(), "новый");
+ EXPECT_FALSE(from_project_settings->has_unsaved_changes());
+ });
+}
+
TEST_F(ProjectTest, project_root_path_find_from_path)
{
/* Test the temporarily created directories with their various path formats. */
diff --git a/source/blender/makesrna/intern/rna_blender_project.c b/source/blender/makesrna/intern/rna_blender_project.c
index 2da9e40e2fa..77a479ceba0 100644
--- a/source/blender/makesrna/intern/rna_blender_project.c
+++ b/source/blender/makesrna/intern/rna_blender_project.c
@@ -92,6 +92,16 @@ static int rna_BlenderProject_root_path_editable(PointerRNA *UNUSED(ptr), const
return 0;
}
+static bool rna_BlenderProject_is_dirty_get(PointerRNA *ptr)
+{
+ const BlenderProject *project = ptr->data;
+ if (!project) {
+ return false;
+ }
+
+ return BKE_project_has_unsaved_changes(project);
+}
+
#else
void RNA_def_blender_project(BlenderRNA *brna)
@@ -117,6 +127,14 @@ void RNA_def_blender_project(BlenderRNA *brna)
"rna_BlenderProject_root_path_set");
RNA_def_property_editable_func(prop, "rna_BlenderProject_root_path_editable");
RNA_def_property_ui_text(prop, "Location", "The location of the project on disk");
+
+ prop = RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_BlenderProject_is_dirty_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(
+ prop,
+ "Dirty",
+ "Project settings have changed since read from disk. Save the settings to keep them");
}
#endif
More information about the Bf-blender-cvs
mailing list