mirror of
https://github.com/Open-Shell/Open-Shell-Menu.git
synced 2026-04-11 17:37:22 +10:00
ModernSettings: Remove duplicates
Windows started to add newer version of settings to settings description file. These have the same description as older settings, but use different parameters. Unfortunately old settings are still present. This causes our modern settings folder to contain duplicates. And also we tend to use older setting definitions that no longer work properly. Thus we will de-duplicate parsed settings and try to keep newer ones (that should work better). New settings tend to have numeric suffix, so we will keep those with biggest suffix. Fixes #1031
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include <appmodel.h>
|
||||
#include <Shlobj.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <mutex>
|
||||
@@ -316,9 +317,9 @@ static std::vector<uint8_t> ParseSetting(CComPtr<IXMLDOMNode>& parent)
|
||||
return writer.buffer();
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> ParseModernSettings()
|
||||
static std::vector<std::vector<uint8_t>> ParseModernSettings()
|
||||
{
|
||||
AttributeWriter writer;
|
||||
std::vector<std::vector<uint8_t>> retval;
|
||||
|
||||
CComPtr<IXMLDOMDocument> doc;
|
||||
if (SUCCEEDED(doc.CoCreateInstance(L"Msxml2.FreeThreadedDOMDocument")))
|
||||
@@ -335,16 +336,13 @@ static std::vector<uint8_t> ParseModernSettings()
|
||||
CComPtr<IXMLDOMNode> root;
|
||||
if (doc->selectSingleNode(CComBSTR(L"PCSettings"), &root) == S_OK)
|
||||
{
|
||||
FileHdr hdr{};
|
||||
writer.addBlob(Id::Header, &hdr, sizeof(hdr));
|
||||
|
||||
CComPtr<IXMLDOMNode> node;
|
||||
root->get_firstChild(&node);
|
||||
while (node)
|
||||
{
|
||||
auto buffer = ParseSetting(node);
|
||||
if (!buffer.empty())
|
||||
writer.addBlob(Id::Blob, buffer.data(), buffer.size());
|
||||
retval.push_back(std::move(buffer));
|
||||
|
||||
CComPtr<IXMLDOMNode> next;
|
||||
if (FAILED(node->get_nextSibling(&next)))
|
||||
@@ -355,6 +353,19 @@ static std::vector<uint8_t> ParseModernSettings()
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> SerializeModernSettings(const std::vector<std::vector<uint8_t>>& settings)
|
||||
{
|
||||
AttributeWriter writer;
|
||||
|
||||
FileHdr hdr{};
|
||||
writer.addBlob(Id::Header, &hdr, sizeof(hdr));
|
||||
|
||||
for (const auto& setting : settings)
|
||||
writer.addBlob(Id::Blob, setting.data(), setting.size());
|
||||
|
||||
return writer.buffer();
|
||||
}
|
||||
|
||||
@@ -480,11 +491,30 @@ std::shared_ptr<ModernSettings> GetModernSettings()
|
||||
s_settings.reset();
|
||||
|
||||
// re-parse settings
|
||||
auto buffer = ParseModernSettings();
|
||||
if (!buffer.empty())
|
||||
auto settings = ParseModernSettings();
|
||||
if (!settings.empty())
|
||||
{
|
||||
// sort by setting name (in reverse order)
|
||||
// this way we will have newer settings (like SomeSetting-2) before older ones
|
||||
std::stable_sort(settings.begin(), settings.end(), [](const auto& a, const auto& b) {
|
||||
return ModernSettings::Setting(a).fileName > ModernSettings::Setting(b).fileName;
|
||||
});
|
||||
|
||||
// now sort by description (strings presented to the user)
|
||||
// and keep relative order of items with the same description
|
||||
std::stable_sort(settings.begin(), settings.end(), [](const auto& a, const auto& b) {
|
||||
return ModernSettings::Setting(a).description < ModernSettings::Setting(b).description;
|
||||
});
|
||||
|
||||
// remove duplicates
|
||||
settings.erase(std::unique(settings.begin(), settings.end(), [](const auto& a, const auto& b) {
|
||||
return ModernSettings::Setting(a).description == ModernSettings::Setting(b).description;
|
||||
}), settings.end());
|
||||
|
||||
// store to file
|
||||
{
|
||||
auto buffer = SerializeModernSettings(settings);
|
||||
|
||||
File f(path.c_str(), GENERIC_WRITE, 0, CREATE_ALWAYS);
|
||||
if (f)
|
||||
{
|
||||
|
||||
@@ -121,6 +121,7 @@ public:
|
||||
|
||||
Setting() = default;
|
||||
Setting(const Blob& blob);
|
||||
Setting(const std::vector<uint8_t>& blob) : Setting(Blob{ blob.data(), blob.size() }) {}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user