From 91914b103266a2c0f8b321b912e48907fff7abc2 Mon Sep 17 00:00:00 2001 From: Reupen Shah Date: Wed, 6 Mar 2024 20:43:43 +0000 Subject: [PATCH 1/3] Rename some static members for consistency This changes the prefix for some static class members from `g_` to `s_` in line with current conventions in the project. --- foo_ui_columns/filter.cpp | 3 -- foo_ui_columns/filter.h | 4 +- foo_ui_columns/item_properties.cpp | 54 +++++++++---------- foo_ui_columns/item_properties.h | 18 +++---- foo_ui_columns/list_view_panel.h | 2 +- foo_ui_columns/ng_playlist/ng_playlist.cpp | 2 - foo_ui_columns/ng_playlist/ng_playlist.h | 4 +- .../ng_playlist/ng_playlist_artwork.cpp | 2 +- .../ng_playlist/ng_playlist_renderer.cpp | 4 +- .../ng_playlist/ng_playlist_style.cpp | 4 +- foo_ui_columns/playlist_switcher.cpp | 4 -- foo_ui_columns/playlist_switcher.h | 4 +- 12 files changed, 46 insertions(+), 59 deletions(-) diff --git a/foo_ui_columns/filter.cpp b/foo_ui_columns/filter.cpp index bc3cc204a..04bc3656e 100644 --- a/foo_ui_columns/filter.cpp +++ b/foo_ui_columns/filter.cpp @@ -913,9 +913,6 @@ pfc::list_t FilterPanel::g_field_data; pfc::list_t FilterPanel::g_streams; -// {4D6774AF-C292-44ac-8A8F-3B0855DCBDF4} -const GUID AppearanceClient::g_guid = {0x4d6774af, 0xc292, 0x44ac, {0x8a, 0x8f, 0x3b, 0x8, 0x55, 0xdc, 0xbd, 0xf4}}; - namespace { colours::client::factory g_appearance_client_impl; } diff --git a/foo_ui_columns/filter.h b/foo_ui_columns/filter.h index aeaeac3b8..4a22a2b64 100644 --- a/foo_ui_columns/filter.h +++ b/foo_ui_columns/filter.h @@ -6,9 +6,9 @@ namespace cui::panels::filter { class AppearanceClient : public colours::client { public: - static const GUID g_guid; + static constexpr GUID id{0x4d6774af, 0xc292, 0x44ac, {0x8a, 0x8f, 0x3b, 0x8, 0x55, 0xdc, 0xbd, 0xf4}}; - const GUID& get_client_guid() const override { return g_guid; } + const GUID& get_client_guid() const override { return id; } void get_name(pfc::string_base& p_out) const override { p_out = "Filter panel"; } uint32_t get_supported_colours() const override { return colours::colour_flag_all; } uint32_t get_supported_bools() const override diff --git a/foo_ui_columns/item_properties.cpp b/foo_ui_columns/item_properties.cpp index b5e9069d8..8ca5c6587 100644 --- a/foo_ui_columns/item_properties.cpp +++ b/foo_ui_columns/item_properties.cpp @@ -45,32 +45,28 @@ cfg_uint cfg_selection_properties_info_sections(g_guid_selection_poperties_info_ cfg_bool cfg_selection_poperties_show_column_titles(g_guid_selection_poperties_show_column_titles, true); cfg_bool cfg_selection_poperties_show_group_titles(g_guid_selection_poperties_show_group_titles, true); -std::vector ItemProperties::g_windows; - -// {862F8A37-16E0-4a74-B27E-2B73DB567D0F} -const GUID ItemPropertiesColoursClient::g_guid - = {0x862f8a37, 0x16e0, 0x4a74, {0xb2, 0x7e, 0x2b, 0x73, 0xdb, 0x56, 0x7d, 0xf}}; +std::vector ItemProperties::s_windows; namespace { colours::client::factory g_appearance_client_impl; } -void ItemProperties::g_redraw_all() +void ItemProperties::s_redraw_all() { - for (auto& window : g_windows) + for (auto& window : s_windows) window->invalidate_all(); } void ItemProperties::s_on_dark_mode_status_change() { const auto is_dark = colours::is_dark_mode_active(); - for (auto&& window : g_windows) + for (auto&& window : s_windows) window->set_use_dark_mode(is_dark); } -void ItemProperties::g_on_app_activate(bool b_activated) +void ItemProperties::s_on_app_activate(bool b_activated) { - for (auto& window : g_windows) + for (auto& window : s_windows) window->on_app_activate(b_activated); } @@ -194,15 +190,15 @@ void ItemProperties::notify_on_create() metadb_io_v3::get()->register_callback(this); refresh_contents(); - if (g_windows.empty()) + if (s_windows.empty()) s_create_message_window(); - g_windows.push_back(this); + s_windows.push_back(this); } void ItemProperties::notify_on_destroy() { - std::erase(g_windows, this); - if (g_windows.empty()) + std::erase(s_windows, this); + if (s_windows.empty()) s_destroy_message_window(); play_callback_manager::get()->unregister_callback(this); @@ -683,7 +679,7 @@ class ItemsFontClientItemProperties : public fonts::client { fonts::font_type_t get_default_font_type() const override { return fonts::font_type_items; } - void on_font_changed() const override { ItemProperties::g_on_font_items_change(); } + void on_font_changed() const override { ItemProperties::s_on_font_items_change(); } }; class HeaderFontClientItemProperties : public fonts::client { @@ -693,7 +689,7 @@ class HeaderFontClientItemProperties : public fonts::client { fonts::font_type_t get_default_font_type() const override { return fonts::font_type_items; } - void on_font_changed() const override { ItemProperties::g_on_font_header_change(); } + void on_font_changed() const override { ItemProperties::s_on_font_header_change(); } }; class GroupClientItemProperties : public fonts::client { @@ -703,31 +699,31 @@ class GroupClientItemProperties : public fonts::client { fonts::font_type_t get_default_font_type() const override { return fonts::font_type_items; } - void on_font_changed() const override { ItemProperties::g_on_font_groups_change(); } + void on_font_changed() const override { ItemProperties::s_on_font_groups_change(); } }; -void ItemProperties::g_on_font_items_change() +void ItemProperties::s_on_font_items_change() { LOGFONT lf; fb2k::std_api_get()->get_font(g_guid_selection_properties_items_font_client, lf); - for (auto& window : g_windows) { + for (auto& window : s_windows) { window->set_font(&lf); } } -void ItemProperties::g_on_font_groups_change() +void ItemProperties::s_on_font_groups_change() { LOGFONT lf; fb2k::std_api_get()->get_font(g_guid_selection_properties_group_font_client, lf); - for (auto& window : g_windows) { + for (auto& window : s_windows) { window->set_group_font(&lf); } } -void ItemProperties::g_on_font_header_change() +void ItemProperties::s_on_font_header_change() { LOGFONT lf; fb2k::std_api_get()->get_font(g_guid_selection_properties_header_font_client, lf); - for (auto& window : g_windows) { + for (auto& window : s_windows) { window->set_header_font(&lf); } } @@ -765,7 +761,7 @@ void ItemProperties::s_create_message_window() s_message_window = std::make_unique( config, [](auto&& wnd, auto&& msg, auto&& wp, auto&& lp) -> LRESULT { if (msg == WM_ACTIVATEAPP) - g_on_app_activate(wp != 0); + s_on_app_activate(wp != 0); return DefWindowProc(wnd, msg, wp, lp); }); s_message_window->create(nullptr); @@ -809,7 +805,7 @@ void ItemProperties::notify_save_inline_edit(const char* value) infos_ptr.add_item(&infos[i]); if (!mask[i]) { pfc::string8 old_value; - g_print_field(m_edit_field, infos[i], old_value); + s_print_field(m_edit_field, infos[i], old_value); if (!(mask[i] = !((strcmp(old_value, value))))) { infos[i].meta_remove_field(m_edit_field); for (size_t j = 0; j < value_count; j++) @@ -877,12 +873,12 @@ bool ItemProperties::notify_create_inline_edit(const pfc::list_base_const_tget_info_ref(p_info)) - g_print_field(m_edit_field, p_info->info(), text); + s_print_field(m_edit_field, p_info->info(), text); size_t count = m_handles.get_count(); for (size_t i = 1; i < count; i++) { temp.reset(); if (m_edit_handles[i]->get_info_ref(p_info)) - g_print_field(m_edit_field, p_info->info(), temp); + s_print_field(m_edit_field, p_info->info(), temp); if (strcmp(temp, text) != 0) { text = ""; break; @@ -895,7 +891,7 @@ bool ItemProperties::notify_create_inline_edit(const pfc::list_base_const_t& indices, size_t column, bool b_source_mouse) override; - static void g_print_field(const char* field, const file_info& p_info, pfc::string_base& p_out); + static void s_print_field(const char* field, const file_info& p_info, pfc::string_base& p_out); bool notify_create_inline_edit(const pfc::list_base_const_t& indices, size_t column, pfc::string_base& p_text, size_t& p_flags, mmh::ComPtr& pAutocompleteEntries) override; void notify_save_inline_edit(const char* value) override; @@ -179,12 +179,12 @@ class ItemProperties void on_changed_sorted(metadb_handle_list_cref p_items_sorted, bool p_fromhook) override; - static void g_on_app_activate(bool b_activated); - static void g_redraw_all(); + static void s_on_app_activate(bool b_activated); + static void s_redraw_all(); static void s_on_dark_mode_status_change(); - static void g_on_font_items_change(); - static void g_on_font_header_change(); - static void g_on_font_groups_change(); + static void s_on_font_items_change(); + static void s_on_font_header_change(); + static void s_on_font_groups_change(); ItemProperties(); @@ -199,7 +199,7 @@ class ItemProperties void on_tracking_mode_change(); bool check_process_on_selection_changed(); - static std::vector g_windows; + static std::vector s_windows; ui_selection_holder::ptr m_selection_holder; metadb_handle_list m_handles; diff --git a/foo_ui_columns/list_view_panel.h b/foo_ui_columns/list_view_panel.h index d43db33b2..827fc85ec 100644 --- a/foo_ui_columns/list_view_panel.h +++ b/foo_ui_columns/list_view_panel.h @@ -50,7 +50,7 @@ class ListViewPanelBase bool should_show_drag_text(size_t selection_count) override { return true; } void render_get_colour_data(ColourData& p_out) override { - cui::colours::helper p_helper(t_appearance_client::g_guid); + cui::colours::helper p_helper(t_appearance_client::id); p_out.m_themed = p_helper.get_themed(); p_out.m_use_custom_active_item_frame = p_helper.get_bool(cui::colours::bool_use_custom_active_item_frame); p_out.m_text = p_helper.get_colour(cui::colours::colour_text); diff --git a/foo_ui_columns/ng_playlist/ng_playlist.cpp b/foo_ui_columns/ng_playlist/ng_playlist.cpp index f97e84368..9fceab9d5 100644 --- a/foo_ui_columns/ng_playlist/ng_playlist.cpp +++ b/foo_ui_columns/ng_playlist/ng_playlist.cpp @@ -1418,8 +1418,6 @@ const GUID PlaylistView::g_extension_guid uie::window_factory g_pvt; -// {C882D3AC-C014-44df-9C7E-2DADF37645A0} -const GUID ColoursClient::g_guid = {0xc882d3ac, 0xc014, 0x44df, {0x9c, 0x7e, 0x2d, 0xad, 0xf3, 0x76, 0x45, 0xa0}}; ColoursClient::factory g_appearance_client_ngpv_impl; // {19F8E0B3-E822-4f07-B200-D4A67E4872F9} diff --git a/foo_ui_columns/ng_playlist/ng_playlist.h b/foo_ui_columns/ng_playlist/ng_playlist.h index 2a7bcad31..00690c066 100644 --- a/foo_ui_columns/ng_playlist/ng_playlist.h +++ b/foo_ui_columns/ng_playlist/ng_playlist.h @@ -280,9 +280,9 @@ class ArtworkReaderManager : public std::enable_shared_from_thisactiveplaylist_get_item_handle(handle, index_item); std::shared_ptr p_reader; m_artwork_manager->request(handle, p_reader, cx, cy, - colours::helper(ColoursClient::g_guid).get_colour(colours::colour_background), cfg_artwork_reflection, + colours::helper(ColoursClient::id).get_colour(colours::colour_background), cfg_artwork_reflection, std::move(ptr)); group->m_artwork_load_attempted = true; return nullptr; diff --git a/foo_ui_columns/ng_playlist/ng_playlist_renderer.cpp b/foo_ui_columns/ng_playlist/ng_playlist_renderer.cpp index 556337c22..13d2105a6 100644 --- a/foo_ui_columns/ng_playlist/ng_playlist_renderer.cpp +++ b/foo_ui_columns/ng_playlist/ng_playlist_renderer.cpp @@ -34,7 +34,7 @@ void PlaylistViewRenderer::render_item(uih::lv::RendererContext context, size_t std::vector sub_items, int indentation, bool b_selected, bool b_window_focused, bool b_highlight, bool should_hide_focus, bool b_focused, RECT rc) { - colours::helper p_helper(ColoursClient::g_guid); + colours::helper p_helper(ColoursClient::id); const auto calculated_use_highlight = b_highlight && !context.m_is_high_contrast_active; @@ -144,7 +144,7 @@ void PlaylistViewRenderer::render_item(uih::lv::RendererContext context, size_t void PlaylistViewRenderer::render_group(uih::lv::RendererContext context, size_t item_index, size_t group_index, std::string_view text, int indentation, size_t level, RECT rc) { - colours::helper p_helper(ColoursClient::g_guid); + colours::helper p_helper(ColoursClient::id); bool b_theme_enabled = p_helper.get_themed(); int text_width = NULL; diff --git a/foo_ui_columns/ng_playlist/ng_playlist_style.cpp b/foo_ui_columns/ng_playlist/ng_playlist_style.cpp index 8e7134e22..0f3ee4259 100644 --- a/foo_ui_columns/ng_playlist/ng_playlist_style.cpp +++ b/foo_ui_columns/ng_playlist/ng_playlist_style.cpp @@ -32,7 +32,7 @@ SharedCellStyleData::~SharedCellStyleData() CellStyleData CellStyleData::g_create_default() { - colours::helper p_helper(ColoursClient::g_guid); + colours::helper p_helper(ColoursClient::id); return CellStyleData(p_helper.get_colour(colours::colour_text), p_helper.get_colour(colours::colour_selection_text), p_helper.get_colour(colours::colour_background), p_helper.get_colour(colours::colour_selection_background), p_helper.get_colour(colours::colour_inactive_selection_text), @@ -112,7 +112,7 @@ bool StyleTitleformatHook::process_field( return true; } if (!stricmp_utf8_ex(p_name + 1, p_name_length - 1, "themed", pfc_infinite)) { - colours::helper p_helper(ColoursClient::g_guid); + colours::helper p_helper(ColoursClient::id); if (p_helper.get_themed()) { p_out->write(titleformat_inputtypes::unknown, "1", 1); p_found_flag = true; diff --git a/foo_ui_columns/playlist_switcher.cpp b/foo_ui_columns/playlist_switcher.cpp index 4677e350a..089ae4abd 100644 --- a/foo_ui_columns/playlist_switcher.cpp +++ b/foo_ui_columns/playlist_switcher.cpp @@ -23,10 +23,6 @@ class PlaylistSwitcherFontClient : public fonts::client { PlaylistSwitcherFontClient::factory g_font_client_switcher; -// {EB38A997-3B5F-4126-8746-262AA9C1F94B} -const GUID PlaylistSwitcherColoursClient::g_guid - = {0xeb38a997, 0x3b5f, 0x4126, {0x87, 0x46, 0x26, 0x2a, 0xa9, 0xc1, 0xf9, 0x4b}}; - PlaylistSwitcherColoursClient::factory g_appearance_client_ps_impl; void PlaylistSwitcherColoursClient::on_colour_changed(uint32_t mask) const diff --git a/foo_ui_columns/playlist_switcher.h b/foo_ui_columns/playlist_switcher.h index c1d718540..03cce6944 100644 --- a/foo_ui_columns/playlist_switcher.h +++ b/foo_ui_columns/playlist_switcher.h @@ -4,9 +4,9 @@ namespace cui::panels::playlist_switcher { class PlaylistSwitcherColoursClient : public colours::client { public: - static const GUID g_guid; + static constexpr GUID id{0xeb38a997, 0x3b5f, 0x4126, {0x87, 0x46, 0x26, 0x2a, 0xa9, 0xc1, 0xf9, 0x4b}}; - const GUID& get_client_guid() const override { return g_guid; } + const GUID& get_client_guid() const override { return id; } void get_name(pfc::string_base& p_out) const override { p_out = "Playlist switcher"; } From ddc8adeea2347b69174292aa81885ea128997d16 Mon Sep 17 00:00:00 2001 From: Reupen Shah Date: Thu, 7 Mar 2024 20:02:03 +0000 Subject: [PATCH 2/3] Improve Item properties tag writing logic This makes how metadata changes are saved in Item properties consistent with how they are saved in the playlist view. This includes sharing more logic and pushing more logic to the `file_info_filter` implementation. --- foo_ui_columns/file_info_utils.cpp | 71 ++++++++++++++++ foo_ui_columns/file_info_utils.h | 23 +++++ foo_ui_columns/foo_ui_columns.vcxproj | 2 + foo_ui_columns/foo_ui_columns.vcxproj.filters | 6 ++ foo_ui_columns/item_properties.cpp | 76 ++++------------- .../ng_playlist/ng_playlist_inline_edit.cpp | 84 ++----------------- 6 files changed, 125 insertions(+), 137 deletions(-) create mode 100644 foo_ui_columns/file_info_utils.cpp create mode 100644 foo_ui_columns/file_info_utils.h diff --git a/foo_ui_columns/file_info_utils.cpp b/foo_ui_columns/file_info_utils.cpp new file mode 100644 index 000000000..0b2bd883c --- /dev/null +++ b/foo_ui_columns/file_info_utils.cpp @@ -0,0 +1,71 @@ +#include "pch.h" + +#include "file_info_utils.h" + +namespace cui::helpers { + +namespace { + +std::string_view trim_string(std::string_view value) +{ + const auto start = value.find_first_not_of(' '); + const auto end = value.find_last_not_of(' '); + + if (start > end || start == std::string_view::npos) + return ""sv; + + return value.substr(start, end - start + 1); +} + +} // namespace + +std::vector split_meta_value(std::string_view value) +{ + std::vector values; + + for (size_t offset{};;) { + const size_t index = value.find(";"sv, offset); + const auto substr = value.substr(offset, index - offset); + const auto trimmed_substr = trim_string(substr); + + if (trimmed_substr.length() > 0) + values.emplace_back(trimmed_substr); + + if (index == std::string_view::npos) + break; + + offset = index + 1; + } + + return values; +} + +std::vector get_meta_field_values(const file_info& info, std::string_view field) +{ + std::vector values; + + for (const auto index : ranges::views::iota(size_t{}, info.meta_get_count_by_name(field.data()))) { + values.emplace_back(info.meta_get(field.data(), index)); + } + + return values; +} + +bool SingleFieldFileInfoFilter::apply_filter(metadb_handle_ptr p_location, t_filestats p_stats, file_info& p_info) +{ + auto old_values = get_meta_field_values(p_info, m_field); + std::vector new_values; + ranges::push_back(new_values, m_new_values); + + if (old_values == new_values) + return false; + + p_info.meta_remove_field(m_field.data()); + + for (auto&& value : m_new_values) + p_info.meta_add_ex(m_field.data(), m_field.length(), value.data(), value.length()); + + return true; +} + +} // namespace cui::helpers diff --git a/foo_ui_columns/file_info_utils.h b/foo_ui_columns/file_info_utils.h new file mode 100644 index 000000000..d4cb5eb93 --- /dev/null +++ b/foo_ui_columns/file_info_utils.h @@ -0,0 +1,23 @@ +#pragma once + +namespace cui::helpers { + +std::vector split_meta_value(std::string_view value); + +std::vector get_meta_field_values(const file_info& info, std::string_view field); + +class SingleFieldFileInfoFilter : public file_info_filter { +public: + SingleFieldFileInfoFilter(std::string field, std::vector new_values) + : m_field(std::move(field)) + , m_new_values(std::move(new_values)) + { + } + + bool apply_filter(metadb_handle_ptr p_location, t_filestats p_stats, file_info& p_info) override; + + std::string m_field; + std::vector m_new_values; +}; + +} // namespace cui::helpers diff --git a/foo_ui_columns/foo_ui_columns.vcxproj b/foo_ui_columns/foo_ui_columns.vcxproj index c8d742f6a..cda629e12 100644 --- a/foo_ui_columns/foo_ui_columns.vcxproj +++ b/foo_ui_columns/foo_ui_columns.vcxproj @@ -266,6 +266,7 @@ + @@ -440,6 +441,7 @@ + diff --git a/foo_ui_columns/foo_ui_columns.vcxproj.filters b/foo_ui_columns/foo_ui_columns.vcxproj.filters index e3479cdbc..5f0387f47 100644 --- a/foo_ui_columns/foo_ui_columns.vcxproj.filters +++ b/foo_ui_columns/foo_ui_columns.vcxproj.filters @@ -611,6 +611,9 @@ Playlist view + + Utilities + @@ -890,6 +893,9 @@ Utilities + + Utilities + diff --git a/foo_ui_columns/item_properties.cpp b/foo_ui_columns/item_properties.cpp index 8ca5c6587..4fa2191d8 100644 --- a/foo_ui_columns/item_properties.cpp +++ b/foo_ui_columns/item_properties.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "item_properties.h" +#include "file_info_utils.h" + namespace cui::panels::item_properties { // {8F6069CD-2E36-4ead-B171-93F3DFF0073A} @@ -775,68 +777,22 @@ void ItemProperties::s_destroy_message_window() void ItemProperties::notify_save_inline_edit(const char* value) { - const auto tagger_api = metadb_io_v2::get(); - if (strcmp(value, "") != 0) { - pfc::list_t values; - const char* ptr = value; - const char* start = ptr; - while (*ptr) { - start = ptr; - while (*ptr != ';' && *ptr) - ptr++; - values.add_item(pfc::string8(start, ptr - start)); - while (*ptr == ' ' || *ptr == ';') - ptr++; - } + auto _ = gsl::finally([this] { + m_edit_column = pfc_infinite; + m_edit_index = pfc_infinite; + m_edit_field.reset(); + m_edit_handles.remove_all(); + }); + + if (strcmp(value, "") == 0) + return; - size_t value_count = values.get_count(); - - metadb_handle_list ptrs(m_edit_handles); - pfc::list_t infos; - pfc::list_t mask; - pfc::list_t infos_ptr; - size_t count = ptrs.get_count(); - mask.set_count(count); - infos.set_count(count); - // infos.set_count(count); - for (size_t i = 0; i < count; i++) { - assert(ptrs[i].is_valid()); - mask[i] = !ptrs[i]->get_info(infos[i]); - infos_ptr.add_item(&infos[i]); - if (!mask[i]) { - pfc::string8 old_value; - s_print_field(m_edit_field, infos[i], old_value); - if (!(mask[i] = !((strcmp(old_value, value))))) { - infos[i].meta_remove_field(m_edit_field); - for (size_t j = 0; j < value_count; j++) - infos[i].meta_add(m_edit_field, values[j]); - } - } - } - infos_ptr.remove_mask(mask.get_ptr()); - ptrs.remove_mask(mask.get_ptr()); - - { - service_ptr_t filter = new service_impl_t(ptrs, infos_ptr); - tagger_api->update_info_async(ptrs, filter, GetAncestor(get_wnd(), GA_ROOT), - metadb_io_v2::op_flag_no_errors | metadb_io_v2::op_flag_background | metadb_io_v2::op_flag_delay_ui, - nullptr); - } - } + auto values = helpers::split_meta_value(value); + const auto filter + = fb2k::service_new(m_edit_field.get_ptr(), std::move(values)); - /*if (m_edit_index < m_fields.get_count()) - { - (m_edit_column ? m_fields[m_edit_index].m_name : m_fields[m_edit_index].m_name_friendly) = value; - pfc::list_t items; - items.set_count(1); - items[0].m_subitems.add_item(m_fields[m_edit_index].m_name_friendly); - items[0].m_subitems.add_item(m_fields[m_edit_index].m_name); - replace_items(m_edit_index, items); - }*/ - m_edit_column = pfc_infinite; - m_edit_index = pfc_infinite; - m_edit_field.reset(); - m_edit_handles.remove_all(); + metadb_io_v2::get()->update_info_async(m_edit_handles, filter, GetAncestor(get_wnd(), GA_ROOT), + metadb_io_v2::op_flag_no_errors | metadb_io_v2::op_flag_background | metadb_io_v2::op_flag_delay_ui, nullptr); } bool ItemProperties::notify_create_inline_edit(const pfc::list_base_const_t& indices, size_t column, diff --git a/foo_ui_columns/ng_playlist/ng_playlist_inline_edit.cpp b/foo_ui_columns/ng_playlist/ng_playlist_inline_edit.cpp index 17263588b..a620c9a85 100644 --- a/foo_ui_columns/ng_playlist/ng_playlist_inline_edit.cpp +++ b/foo_ui_columns/ng_playlist/ng_playlist_inline_edit.cpp @@ -1,63 +1,10 @@ #include "pch.h" + +#include "file_info_utils.h" #include "ng_playlist.h" namespace cui::panels::playlist_view { -namespace { - -std::string_view trim_string(std::string_view value) -{ - const auto start = value.find_first_not_of(' '); - const auto end = value.find_last_not_of(' '); - - if (start > end || start == std::string_view::npos) - return ""sv; - - return value.substr(start, end - start + 1); -} - -auto get_info_field_values(const file_info& info, std::string_view field) -{ - std::vector values; - - for (size_t i{}; i < info.meta_get_count_by_name(field.data()); ++i) { - values.emplace_back(info.meta_get(field.data(), i)); - } - - return values; -} - -class InlineEditFileInfoFilter : public file_info_filter { -public: - InlineEditFileInfoFilter(std::string field, std::vector new_values) - : m_field(std::move(field)) - , m_new_values(std::move(new_values)) - { - } - - bool apply_filter(metadb_handle_ptr p_location, t_filestats p_stats, file_info& p_info) override - { - auto old_values = get_info_field_values(p_info, m_field); - std::vector new_values; - ranges::push_back(new_values, m_new_values); - - if (old_values == new_values) - return false; - - p_info.meta_remove_field(m_field.data()); - - for (auto&& value : m_new_values) - p_info.meta_add_ex(m_field.data(), m_field.length(), value.data(), value.length()); - - return true; - } - - std::string m_field; - std::vector m_new_values; -}; - -} // namespace - bool PlaylistView::notify_before_create_inline_edit( const pfc::list_base_const_t& indices, size_t column, bool b_source_mouse) { @@ -87,7 +34,7 @@ bool PlaylistView::notify_create_inline_edit(const pfc::list_base_const_tget_info_ref(); auto& info = info_container->info(); - auto item_values = get_info_field_values(info, m_edit_field.get_ptr()); + auto item_values = helpers::get_meta_field_values(info, m_edit_field.get_ptr()); if (i == 0) { values = item_values; @@ -124,28 +71,11 @@ bool PlaylistView::notify_create_inline_edit(const pfc::list_base_const_t values; - - size_t offset{}; - for (;;) { - const size_t index = value_view.find(";"sv, offset); - const auto substr = value_view.substr(offset, index - offset); - const auto trimmed_substr = trim_string(substr); - - if (trimmed_substr.length() > 0) - values.emplace_back(trimmed_substr); - - if (index == std::string_view::npos) - break; - - offset = index + 1; - } - - const auto tagger_api = metadb_io_v2::get(); + auto values = helpers::split_meta_value(value); + const auto filter + = fb2k::service_new(m_edit_field.get_ptr(), std::move(values)); - const auto filter = fb2k::service_new(m_edit_field.get_ptr(), values); - tagger_api->update_info_async(m_edit_handles, filter, GetAncestor(get_wnd(), GA_ROOT), + metadb_io_v2::get()->update_info_async(m_edit_handles, filter, GetAncestor(get_wnd(), GA_ROOT), metadb_io_v2::op_flag_no_errors | metadb_io_v2::op_flag_background | metadb_io_v2::op_flag_delay_ui, nullptr); } From 555ab6023e52c217b7223f89210587f94a15808e Mon Sep 17 00:00:00 2001 From: Reupen Shah Date: Thu, 7 Mar 2024 20:59:36 +0000 Subject: [PATCH 3/3] Improve Filter panel tag writing logic This makes how metadata changes are saved in Item properties more consistent with how they are saved in the playlist view and Item properties. This is by pushing more logic to the `file_info_filter` implementation. --- CHANGELOG.md | 3 ++ foo_ui_columns/filter_inline_edit.cpp | 65 ++++++++++----------------- 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03bfa84d7..89a4c0d70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,9 @@ This makes the behaviour consistent with what happens when there are Filter panels in the layout. +- The way metadata changes are saved in Item properties and Filter panel was + improved. [[#863](https://github.com/reupen/columns_ui/pull/863)] + ### Bug fixes - Various rendering glitches in Playlist tabs and Tab stack when dark mode is diff --git a/foo_ui_columns/filter_inline_edit.cpp b/foo_ui_columns/filter_inline_edit.cpp index 75b2167e5..b81c38639 100644 --- a/foo_ui_columns/filter_inline_edit.cpp +++ b/foo_ui_columns/filter_inline_edit.cpp @@ -27,52 +27,35 @@ bool FilterPanel::notify_create_inline_edit(const pfc::list_base_const_t } void FilterPanel::notify_save_inline_edit(const char* value) { - const auto tagger_api = metadb_io_v2::get(); - { - metadb_handle_list ptrs(m_edit_handles); - pfc::list_t infos; - pfc::list_t mask; - pfc::list_t infos_ptr; - size_t count = ptrs.get_count(); - mask.set_count(count); - infos.set_count(count); - // infos.set_count(count); - for (size_t i = 0; i < count; i++) { - assert(ptrs[i].is_valid()); - mask[i] = !ptrs[i]->get_info(infos[i]); - infos_ptr.add_item(&infos[i]); - if (!mask[i]) { - bool b_remove = true; - size_t jcount = m_edit_fields.size(); - for (size_t j = 0; j < jcount; j++) { - size_t field_index = infos[i].meta_find(m_edit_fields[j]); - if (field_index != pfc_infinite) { - size_t field_count = infos[i].meta_enum_value_count(field_index); + auto apply_filter = [edit_fields = m_edit_fields, edit_previous_value = m_edit_previous_value, + value = std::string{value}](trackRef location, t_filestats stats, file_info& info) -> bool { + bool changed = false; - for (size_t k = 0; k < field_count; k++) { - const char* ptr = infos[i].meta_enum_value(field_index, k); - if (((!ptr && m_edit_previous_value.is_empty()) - || !stricmp_utf8(m_edit_previous_value, ptr)) - && strcmp(value, ptr) != 0) { - infos[i].meta_modify_value(field_index, k, value); - b_remove = false; - } - } - } + for (auto& field : edit_fields) { + const size_t field_index = info.meta_find(field); + + if (field_index == std::numeric_limits::max()) + continue; + + size_t value_count = info.meta_enum_value_count(field_index); + + for (auto value_index : std::ranges::views::iota(size_t{}, value_count)) { + auto field_value = info.meta_enum_value(field_index, value_index); + + if (!stricmp_utf8(edit_previous_value, field_value) && strcmp(value.c_str(), field_value) != 0) { + info.meta_modify_value(field_index, value_index, value.c_str()); + changed = true; } - mask[i] = b_remove; } } - infos_ptr.remove_mask(mask.get_ptr()); - ptrs.remove_mask(mask.get_ptr()); - { - service_ptr_t filter = new service_impl_t(ptrs, infos_ptr); - tagger_api->update_info_async(ptrs, filter, GetAncestor(get_wnd(), GA_ROOT), - metadb_io_v2::op_flag_no_errors | metadb_io_v2::op_flag_background | metadb_io_v2::op_flag_delay_ui, - nullptr); - } - } + return changed; + }; + + auto filter = file_info_filter::create(std::move(apply_filter)); + + metadb_io_v2::get()->update_info_async(m_edit_handles, filter, GetAncestor(get_wnd(), GA_ROOT), + metadb_io_v2::op_flag_no_errors | metadb_io_v2::op_flag_background | metadb_io_v2::op_flag_delay_ui, nullptr); } void FilterPanel::notify_exit_inline_edit() {