Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve metadata saving logic in Item properties and Filter panel #863

Merged
merged 3 commits into from
Mar 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
71 changes: 71 additions & 0 deletions foo_ui_columns/file_info_utils.cpp
Original file line number Diff line number Diff line change
@@ -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<std::string> split_meta_value(std::string_view value)
{
std::vector<std::string> 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<std::string_view> get_meta_field_values(const file_info& info, std::string_view field)
{
std::vector<std::string_view> 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<std::string_view> 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
23 changes: 23 additions & 0 deletions foo_ui_columns/file_info_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

namespace cui::helpers {

std::vector<std::string> split_meta_value(std::string_view value);

std::vector<std::string_view> 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<std::string> 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<std::string> m_new_values;
};

} // namespace cui::helpers
3 changes: 0 additions & 3 deletions foo_ui_columns/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -913,9 +913,6 @@ pfc::list_t<FieldData> FilterPanel::g_field_data;

pfc::list_t<FilterStream::ptr> 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<AppearanceClient> g_appearance_client_impl;
}
Expand Down
4 changes: 2 additions & 2 deletions foo_ui_columns/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
65 changes: 24 additions & 41 deletions foo_ui_columns/filter_inline_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,52 +27,35 @@ bool FilterPanel::notify_create_inline_edit(const pfc::list_base_const_t<size_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<file_info_impl> infos;
pfc::list_t<bool> mask;
pfc::list_t<const file_info*> 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<size_t>::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<file_info_filter_impl> filter = new service_impl_t<file_info_filter_impl>(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()
{
Expand Down
2 changes: 2 additions & 0 deletions foo_ui_columns/foo_ui_columns.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@
<ClCompile Include="dark_mode_active_ui.cpp" />
<ClCompile Include="dark_mode_dialog.cpp" />
<ClCompile Include="dark_mode_spin.cpp" />
<ClCompile Include="file_info_utils.cpp" />
<ClCompile Include="font_manager.cpp" />
<ClCompile Include="gdi.cpp" />
<ClCompile Include="icons.cpp" />
Expand Down Expand Up @@ -440,6 +441,7 @@
<ClInclude Include="dark_mode_active_ui.h" />
<ClInclude Include="dark_mode_spin.h" />
<ClInclude Include="event_token.h" />
<ClInclude Include="file_info_utils.h" />
<ClInclude Include="font_manager_data.h" />
<ClInclude Include="gdi.h" />
<ClInclude Include="gdiplus.h" />
Expand Down
6 changes: 6 additions & 0 deletions foo_ui_columns/foo_ui_columns.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,9 @@
<ClCompile Include="ng_playlist\ng_playlist_config.cpp">
<Filter>Playlist view</Filter>
</ClCompile>
<ClCompile Include="file_info_utils.cpp">
<Filter>Utilities</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
Expand Down Expand Up @@ -890,6 +893,9 @@
<ClInclude Include="core_drop_down_list_toolbar.h">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="file_info_utils.h">
<Filter>Utilities</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include=".clang-format" />
Expand Down
Loading
Loading