Refactor Filter API (#4039)

This commit is contained in:
timoreo 2025-08-20 16:45:48 +02:00 committed by GitHub
commit 542ab62ab7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 105 additions and 283 deletions

View File

@ -46,8 +46,6 @@
#include "DataMigrationTask.h" #include "DataMigrationTask.h"
#include "java/JavaInstallList.h" #include "java/JavaInstallList.h"
#include "net/PasteUpload.h" #include "net/PasteUpload.h"
#include "pathmatcher/MultiMatcher.h"
#include "pathmatcher/SimplePrefixMatcher.h"
#include "tasks/Task.h" #include "tasks/Task.h"
#include "tools/GenericProfiler.h" #include "tools/GenericProfiler.h"
#include "ui/InstanceWindow.h" #include "ui/InstanceWindow.h"
@ -1985,22 +1983,23 @@ bool Application::handleDataMigration(const QString& currentData,
if (!currentExists) { if (!currentExists) {
// Migrate! // Migrate!
auto matcher = std::make_shared<MultiMatcher>(); using namespace Filters;
matcher->add(std::make_shared<SimplePrefixMatcher>(configFile));
matcher->add(std::make_shared<SimplePrefixMatcher>( QList<Filter> filters;
BuildConfig.LAUNCHER_CONFIGFILE)); // it's possible that we already used that directory before filters.append(equals(configFile));
matcher->add(std::make_shared<SimplePrefixMatcher>("logs/")); filters.append(equals(BuildConfig.LAUNCHER_CONFIGFILE)); // it's possible that we already used that directory before
matcher->add(std::make_shared<SimplePrefixMatcher>("accounts.json")); filters.append(startsWith("logs/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("accounts/")); filters.append(equals("accounts.json"));
matcher->add(std::make_shared<SimplePrefixMatcher>("assets/")); filters.append(startsWith("accounts/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("icons/")); filters.append(startsWith("assets/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("instances/")); filters.append(startsWith("icons/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("libraries/")); filters.append(startsWith("instances/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("mods/")); filters.append(startsWith("libraries/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("themes/")); filters.append(startsWith("mods/"));
filters.append(startsWith("themes/"));
ProgressDialog diag; ProgressDialog diag;
DataMigrationTask task(oldData, currentData, matcher); DataMigrationTask task(oldData, currentData, any(std::move(filters)));
if (diag.execWithTask(&task)) { if (diag.execWithTask(&task)) {
qDebug() << "<> Migration succeeded"; qDebug() << "<> Migration succeeded";
setDoNotMigrate(); setDoNotMigrate();

View File

@ -52,7 +52,6 @@
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include "MessageLevel.h" #include "MessageLevel.h"
#include "minecraft/auth/MinecraftAccount.h" #include "minecraft/auth/MinecraftAccount.h"
#include "pathmatcher/IPathMatcher.h"
#include "settings/INIFile.h" #include "settings/INIFile.h"
#include "net/Mode.h" #include "net/Mode.h"

View File

@ -56,7 +56,6 @@ set(CORE_SOURCES
# String filters # String filters
Filter.h Filter.h
Filter.cpp
# JSON parsing helpers # JSON parsing helpers
Json.h Json.h
@ -108,15 +107,6 @@ if (UNIX AND NOT CYGWIN AND NOT APPLE)
) )
endif() endif()
set(PATHMATCHER_SOURCES
# Path matchers
pathmatcher/FSTreeMatcher.h
pathmatcher/IPathMatcher.h
pathmatcher/MultiMatcher.h
pathmatcher/RegexpMatcher.h
pathmatcher/SimplePrefixMatcher.h
)
set(NET_SOURCES set(NET_SOURCES
# network stuffs # network stuffs
net/ByteArraySink.h net/ByteArraySink.h
@ -760,7 +750,6 @@ endif()
set(LOGIC_SOURCES set(LOGIC_SOURCES
${CORE_SOURCES} ${CORE_SOURCES}
${PATHMATCHER_SOURCES}
${NET_SOURCES} ${NET_SOURCES}
${LAUNCH_SOURCES} ${LAUNCH_SOURCES}
${UPDATE_SOURCES} ${UPDATE_SOURCES}

View File

@ -12,7 +12,7 @@
#include <QtConcurrent> #include <QtConcurrent>
DataMigrationTask::DataMigrationTask(const QString& sourcePath, const QString& targetPath, const IPathMatcher::Ptr pathMatcher) DataMigrationTask::DataMigrationTask(const QString& sourcePath, const QString& targetPath, Filter pathMatcher)
: Task(), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath) : Task(), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath)
{ {
m_copy.matcher(m_pathMatcher).whitelist(true); m_copy.matcher(m_pathMatcher).whitelist(true);

View File

@ -5,7 +5,7 @@
#pragma once #pragma once
#include "FileSystem.h" #include "FileSystem.h"
#include "pathmatcher/IPathMatcher.h" #include "Filter.h"
#include "tasks/Task.h" #include "tasks/Task.h"
#include <QFuture> #include <QFuture>
@ -18,7 +18,7 @@
class DataMigrationTask : public Task { class DataMigrationTask : public Task {
Q_OBJECT Q_OBJECT
public: public:
explicit DataMigrationTask(const QString& sourcePath, const QString& targetPath, IPathMatcher::Ptr pathmatcher); explicit DataMigrationTask(const QString& sourcePath, const QString& targetPath, Filter pathmatcher);
~DataMigrationTask() override = default; ~DataMigrationTask() override = default;
protected: protected:
@ -33,7 +33,7 @@ class DataMigrationTask : public Task {
private: private:
const QString& m_sourcePath; const QString& m_sourcePath;
const QString& m_targetPath; const QString& m_targetPath;
const IPathMatcher::Ptr m_pathMatcher; const Filter m_pathMatcher;
FS::copy m_copy; FS::copy m_copy;
int m_toCopy = 0; int m_toCopy = 0;

View File

@ -331,7 +331,7 @@ bool copy::operator()(const QString& offset, bool dryRun)
// Function that'll do the actual copying // Function that'll do the actual copying
auto copy_file = [this, dryRun, src, dst, opt, &err](QString src_path, QString relative_dst_path) { auto copy_file = [this, dryRun, src, dst, opt, &err](QString src_path, QString relative_dst_path) {
if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist)) if (m_matcher && (m_matcher(relative_dst_path) != m_whitelist))
return; return;
auto dst_path = PathCombine(dst, relative_dst_path); auto dst_path = PathCombine(dst, relative_dst_path);
@ -418,7 +418,7 @@ void create_link::make_link_list(const QString& offset)
// Function that'll do the actual linking // Function that'll do the actual linking
auto link_file = [this, dst](QString src_path, QString relative_dst_path) { auto link_file = [this, dst](QString src_path, QString relative_dst_path) {
if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist)) { if (m_matcher && (m_matcher(relative_dst_path) != m_whitelist)) {
qDebug() << "path" << relative_dst_path << "in black list or not in whitelist"; qDebug() << "path" << relative_dst_path << "in black list or not in whitelist";
return; return;
} }
@ -1277,7 +1277,7 @@ bool clone::operator()(const QString& offset, bool dryRun)
// Function that'll do the actual cloneing // Function that'll do the actual cloneing
auto cloneFile = [this, dryRun, dst, &err](QString src_path, QString relative_dst_path) { auto cloneFile = [this, dryRun, dst, &err](QString src_path, QString relative_dst_path) {
if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist)) if (m_matcher && (m_matcher(relative_dst_path) != m_whitelist))
return; return;
auto dst_path = PathCombine(dst, relative_dst_path); auto dst_path = PathCombine(dst, relative_dst_path);

View File

@ -38,7 +38,7 @@
#pragma once #pragma once
#include "Exception.h" #include "Exception.h"
#include "pathmatcher/IPathMatcher.h" #include "Filter.h"
#include <system_error> #include <system_error>
@ -115,9 +115,9 @@ class copy : public QObject {
m_followSymlinks = follow; m_followSymlinks = follow;
return *this; return *this;
} }
copy& matcher(IPathMatcher::Ptr filter) copy& matcher(Filter filter)
{ {
m_matcher = filter; m_matcher = std::move(filter);
return *this; return *this;
} }
copy& whitelist(bool whitelist) copy& whitelist(bool whitelist)
@ -147,7 +147,7 @@ class copy : public QObject {
private: private:
bool m_followSymlinks = true; bool m_followSymlinks = true;
IPathMatcher::Ptr m_matcher = nullptr; Filter m_matcher = nullptr;
bool m_whitelist = false; bool m_whitelist = false;
bool m_overwrite = false; bool m_overwrite = false;
QDir m_src; QDir m_src;
@ -209,9 +209,9 @@ class create_link : public QObject {
m_useHardLinks = useHard; m_useHardLinks = useHard;
return *this; return *this;
} }
create_link& matcher(IPathMatcher::Ptr filter) create_link& matcher(Filter filter)
{ {
m_matcher = filter; m_matcher = std::move(filter);
return *this; return *this;
} }
create_link& whitelist(bool whitelist) create_link& whitelist(bool whitelist)
@ -260,7 +260,7 @@ class create_link : public QObject {
private: private:
bool m_useHardLinks = false; bool m_useHardLinks = false;
IPathMatcher::Ptr m_matcher = nullptr; Filter m_matcher = nullptr;
bool m_whitelist = false; bool m_whitelist = false;
bool m_recursive = true; bool m_recursive = true;
@ -492,9 +492,9 @@ class clone : public QObject {
m_src.setPath(src); m_src.setPath(src);
m_dst.setPath(dst); m_dst.setPath(dst);
} }
clone& matcher(IPathMatcher::Ptr filter) clone& matcher(Filter filter)
{ {
m_matcher = filter; m_matcher = std::move(filter);
return *this; return *this;
} }
clone& whitelist(bool whitelist) clone& whitelist(bool whitelist)
@ -518,7 +518,7 @@ class clone : public QObject {
bool operator()(const QString& offset, bool dryRun = false); bool operator()(const QString& offset, bool dryRun = false);
private: private:
IPathMatcher::Ptr m_matcher = nullptr; Filter m_matcher = nullptr;
bool m_whitelist = false; bool m_whitelist = false;
QDir m_src; QDir m_src;
QDir m_dst; QDir m_dst;

View File

@ -1,37 +0,0 @@
#include "Filter.h"
ContainsFilter::ContainsFilter(const QString& pattern) : pattern(pattern) {}
bool ContainsFilter::accepts(const QString& value)
{
return value.contains(pattern);
}
ExactFilter::ExactFilter(const QString& pattern) : pattern(pattern) {}
bool ExactFilter::accepts(const QString& value)
{
return value == pattern;
}
ExactIfPresentFilter::ExactIfPresentFilter(const QString& pattern) : pattern(pattern) {}
bool ExactIfPresentFilter::accepts(const QString& value)
{
return value.isEmpty() || value == pattern;
}
RegexpFilter::RegexpFilter(const QString& regexp, bool invert) : invert(invert)
{
pattern.setPattern(regexp);
pattern.optimize();
}
bool RegexpFilter::accepts(const QString& value)
{
auto match = pattern.match(value);
bool matched = match.hasMatch();
return invert ? (!matched) : (matched);
}
ExactListFilter::ExactListFilter(const QStringList& pattern) : m_pattern(pattern) {}
bool ExactListFilter::accepts(const QString& value)
{
return m_pattern.isEmpty() || m_pattern.contains(value);
}

View File

@ -3,59 +3,52 @@
#include <QRegularExpression> #include <QRegularExpression>
#include <QString> #include <QString>
class Filter { using Filter = std::function<bool(const QString&)>;
public:
virtual ~Filter() = default;
virtual bool accepts(const QString& value) = 0;
};
class ContainsFilter : public Filter { namespace Filters {
public: inline Filter inverse(Filter filter)
ContainsFilter(const QString& pattern); {
virtual ~ContainsFilter() = default; return [filter = std::move(filter)](const QString& src) { return !filter(src); };
bool accepts(const QString& value) override; }
private: inline Filter any(QList<Filter> filters)
QString pattern; {
}; return [filters = std::move(filters)](const QString& src) {
for (auto& filter : filters)
if (filter(src))
return true;
class ExactFilter : public Filter { return false;
public: };
ExactFilter(const QString& pattern); }
virtual ~ExactFilter() = default;
bool accepts(const QString& value) override;
private: inline Filter equals(QString pattern)
QString pattern; {
}; return [pattern = std::move(pattern)](const QString& src) { return src == pattern; };
}
class ExactIfPresentFilter : public Filter { inline Filter equalsAny(QStringList patterns = {})
public: {
ExactIfPresentFilter(const QString& pattern); return [patterns = std::move(patterns)](const QString& src) { return patterns.isEmpty() || patterns.contains(src); };
virtual ~ExactIfPresentFilter() override = default; }
bool accepts(const QString& value) override;
private: inline Filter equalsOrEmpty(QString pattern)
QString pattern; {
}; return [pattern = std::move(pattern)](const QString& src) { return src.isEmpty() || src == pattern; };
}
class RegexpFilter : public Filter { inline Filter contains(QString pattern)
public: {
RegexpFilter(const QString& regexp, bool invert); return [pattern = std::move(pattern)](const QString& src) { return src.contains(pattern); };
virtual ~RegexpFilter() = default; }
bool accepts(const QString& value) override;
private: inline Filter startsWith(QString pattern)
QRegularExpression pattern; {
bool invert = false; return [pattern = std::move(pattern)](const QString& src) { return src.startsWith(pattern); };
}; }
class ExactListFilter : public Filter { inline Filter regexp(QRegularExpression pattern)
public: {
ExactListFilter(const QStringList& pattern = {}); return [pattern = std::move(pattern)](const QString& src) { return pattern.match(src).hasMatch(); };
virtual ~ExactListFilter() = default; }
bool accepts(const QString& value) override; } // namespace Filters
private:
QStringList m_pattern;
};

View File

@ -3,8 +3,8 @@
#include <QtConcurrentRun> #include <QtConcurrentRun>
#include <memory> #include <memory>
#include "FileSystem.h" #include "FileSystem.h"
#include "Filter.h"
#include "NullInstance.h" #include "NullInstance.h"
#include "pathmatcher/RegexpMatcher.h"
#include "settings/INISettingsObject.h" #include "settings/INISettingsObject.h"
#include "tasks/Task.h" #include "tasks/Task.h"
@ -30,9 +30,8 @@ InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, const InstanceCopyP
if (!filters.isEmpty()) { if (!filters.isEmpty()) {
// Set regex filter: // Set regex filter:
// FIXME: get this from the original instance type... // FIXME: get this from the original instance type...
auto matcherReal = new RegexpMatcher(filters); QRegularExpression regexp(filters, QRegularExpression::CaseInsensitiveOption);
matcherReal->caseSensitive(false); m_matcher = Filters::regexp(regexp);
m_matcher.reset(matcherReal);
} }
} }

View File

@ -5,6 +5,7 @@
#include <QUrl> #include <QUrl>
#include "BaseInstance.h" #include "BaseInstance.h"
#include "BaseVersion.h" #include "BaseVersion.h"
#include "Filter.h"
#include "InstanceCopyPrefs.h" #include "InstanceCopyPrefs.h"
#include "InstanceTask.h" #include "InstanceTask.h"
#include "net/NetJob.h" #include "net/NetJob.h"
@ -28,7 +29,7 @@ class InstanceCopyTask : public InstanceTask {
InstancePtr m_origInstance; InstancePtr m_origInstance;
QFuture<bool> m_copyFuture; QFuture<bool> m_copyFuture;
QFutureWatcher<bool> m_copyFutureWatcher; QFutureWatcher<bool> m_copyFutureWatcher;
IPathMatcher::Ptr m_matcher; Filter m_matcher;
bool m_keepPlaytime; bool m_keepPlaytime;
bool m_useLinks = false; bool m_useLinks = false;
bool m_useHardLinks = false; bool m_useHardLinks = false;

View File

@ -51,7 +51,7 @@
namespace MMCZip { namespace MMCZip {
// ours // ours
bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet<QString>& contained, const FilterFunction& filter) bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet<QString>& contained, const Filter& filter)
{ {
QuaZip modZip(from.filePath()); QuaZip modZip(from.filePath());
modZip.open(QuaZip::mdUnzip); modZip.open(QuaZip::mdUnzip);

View File

@ -52,16 +52,16 @@
#if defined(LAUNCHER_APPLICATION) #if defined(LAUNCHER_APPLICATION)
#include "minecraft/mod/Mod.h" #include "minecraft/mod/Mod.h"
#endif #endif
#include "Filter.h"
#include "tasks/Task.h" #include "tasks/Task.h"
namespace MMCZip { namespace MMCZip {
using FilterFunction = std::function<bool(const QString&)>;
using FilterFileFunction = std::function<bool(const QFileInfo&)>; using FilterFileFunction = std::function<bool(const QFileInfo&)>;
/** /**
* Merge two zip files, using a filter function * Merge two zip files, using a filter function
*/ */
bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet<QString>& contained, const FilterFunction& filter = nullptr); bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet<QString>& contained, const Filter& filter = nullptr);
/** /**
* Compress directory, by providing a list of files to compress * Compress directory, by providing a list of files to compress

View File

@ -78,7 +78,7 @@ QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir& directory)
} }
for (const QString& file : directory.entryList(QDir::Files | QDir::Hidden)) { for (const QString& file : directory.entryList(QDir::Files | QDir::Hidden)) {
auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file)); auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file));
if (m_matcher->matches(relPath)) { if (m_matcher(relPath)) {
ret.append(relPath); ret.append(relPath);
} }
} }

View File

@ -2,7 +2,7 @@
#include <QDir> #include <QDir>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
#include "pathmatcher/IPathMatcher.h" #include "Filter.h"
class RecursiveFileSystemWatcher : public QObject { class RecursiveFileSystemWatcher : public QObject {
Q_OBJECT Q_OBJECT
@ -16,7 +16,7 @@ class RecursiveFileSystemWatcher : public QObject {
void setWatchFiles(bool watchFiles); void setWatchFiles(bool watchFiles);
bool watchFiles() const { return m_watchFiles; } bool watchFiles() const { return m_watchFiles; }
void setMatcher(IPathMatcher::Ptr matcher) { m_matcher = matcher; } void setMatcher(Filter matcher) { m_matcher = std::move(matcher); }
QStringList files() const { return m_files; } QStringList files() const { return m_files; }
@ -32,7 +32,7 @@ class RecursiveFileSystemWatcher : public QObject {
QDir m_root; QDir m_root;
bool m_watchFiles = false; bool m_watchFiles = false;
bool m_isEnabled = false; bool m_isEnabled = false;
IPathMatcher::Ptr m_matcher; Filter m_matcher;
QFileSystemWatcher* m_watcher; QFileSystemWatcher* m_watcher;

View File

@ -63,7 +63,7 @@ class VersionFilterModel : public QSortFilterProxyModel {
for (auto it = filters.begin(); it != filters.end(); ++it) { for (auto it = filters.begin(); it != filters.end(); ++it) {
auto data = sourceModel()->data(idx, it.key()); auto data = sourceModel()->data(idx, it.key());
auto match = data.toString(); auto match = data.toString();
if (!it.value()->accepts(match)) { if (!it.value()(match)) {
return false; return false;
} }
} }
@ -380,9 +380,9 @@ void VersionProxyModel::clearFilters()
filterModel->filterChanged(); filterModel->filterChanged();
} }
void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, Filter* f) void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, Filter f)
{ {
m_filters[column].reset(f); m_filters[column] = std::move(f);
filterModel->filterChanged(); filterModel->filterChanged();
} }

View File

@ -10,7 +10,7 @@ class VersionProxyModel : public QAbstractProxyModel {
Q_OBJECT Q_OBJECT
public: public:
enum Column { Name, ParentVersion, Branch, Type, CPUArchitecture, Path, Time, JavaName, JavaMajor }; enum Column { Name, ParentVersion, Branch, Type, CPUArchitecture, Path, Time, JavaName, JavaMajor };
using FilterMap = QHash<BaseVersionList::ModelRoles, std::shared_ptr<Filter>>; using FilterMap = QHash<BaseVersionList::ModelRoles, Filter>;
public: public:
VersionProxyModel(QObject* parent = 0); VersionProxyModel(QObject* parent = 0);
@ -28,7 +28,7 @@ class VersionProxyModel : public QAbstractProxyModel {
const FilterMap& filters() const; const FilterMap& filters() const;
const QString& search() const; const QString& search() const;
void setFilter(BaseVersionList::ModelRoles column, Filter* filter); void setFilter(BaseVersionList::ModelRoles column, Filter filter);
void setSearch(const QString& search); void setSearch(const QString& search);
void clearFilters(); void clearFilters();
QModelIndex getRecommended() const; QModelIndex getRecommended() const;

View File

@ -53,7 +53,6 @@
#include "FileSystem.h" #include "FileSystem.h"
#include "MMCTime.h" #include "MMCTime.h"
#include "java/JavaVersion.h" #include "java/JavaVersion.h"
#include "pathmatcher/MultiMatcher.h"
#include "launch/LaunchTask.h" #include "launch/LaunchTask.h"
#include "launch/TaskStepWrapper.h" #include "launch/TaskStepWrapper.h"

View File

@ -1,14 +0,0 @@
#pragma once
#include <SeparatorPrefixTree.h>
#include "IPathMatcher.h"
class FSTreeMatcher : public IPathMatcher {
public:
virtual ~FSTreeMatcher() {};
FSTreeMatcher(SeparatorPrefixTree<'/'>& tree) : m_fsTree(tree) {}
bool matches(const QString& string) const override { return m_fsTree.covers(string); }
SeparatorPrefixTree<'/'>& m_fsTree;
};

View File

@ -1,12 +0,0 @@
#pragma once
#include <QString>
#include <memory>
class IPathMatcher {
public:
using Ptr = std::shared_ptr<IPathMatcher>;
public:
virtual ~IPathMatcher() {}
virtual bool matches(const QString& string) const = 0;
};

View File

@ -1,27 +0,0 @@
#pragma once
#include <SeparatorPrefixTree.h>
#include "IPathMatcher.h"
class MultiMatcher : public IPathMatcher {
public:
virtual ~MultiMatcher() {};
MultiMatcher() {}
MultiMatcher& add(Ptr add)
{
m_matchers.append(add);
return *this;
}
virtual bool matches(const QString& string) const override
{
for (auto iter : m_matchers) {
if (iter->matches(string)) {
return true;
}
}
return false;
}
QList<Ptr> m_matchers;
};

View File

@ -1,40 +0,0 @@
#pragma once
#include <QRegularExpression>
#include "IPathMatcher.h"
class RegexpMatcher : public IPathMatcher {
public:
virtual ~RegexpMatcher() {}
RegexpMatcher(const QString& regexp)
{
m_regexp.setPattern(regexp);
m_onlyFilenamePart = !regexp.contains('/');
}
RegexpMatcher(const QRegularExpression& regex) : m_regexp(regex) { m_onlyFilenamePart = !regex.pattern().contains('/'); }
RegexpMatcher& caseSensitive(bool cs = true)
{
if (cs) {
m_regexp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
} else {
m_regexp.setPatternOptions(QRegularExpression::NoPatternOption);
}
return *this;
}
virtual bool matches(const QString& string) const override
{
if (m_onlyFilenamePart) {
auto slash = string.lastIndexOf('/');
if (slash != -1) {
auto part = string.mid(slash + 1);
return m_regexp.match(part).hasMatch();
}
}
return m_regexp.match(string).hasMatch();
}
QRegularExpression m_regexp;
bool m_onlyFilenamePart = false;
};

View File

@ -1,24 +0,0 @@
// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu <contact@scrumplex.net>
//
// SPDX-License-Identifier: GPL-3.0-only
#include "IPathMatcher.h"
class SimplePrefixMatcher : public IPathMatcher {
public:
virtual ~SimplePrefixMatcher() {};
SimplePrefixMatcher(const QString& prefix)
{
m_prefix = prefix;
m_isPrefix = prefix.endsWith('/');
}
virtual bool matches(const QString& string) const override
{
if (m_isPrefix)
return string.startsWith(m_prefix);
return string == m_prefix;
}
QString m_prefix;
bool m_isPrefix = false;
};

View File

@ -140,9 +140,9 @@ class InstallJavaPage : public QWidget, public BasePage {
void recommendedFilterChanged() void recommendedFilterChanged()
{ {
if (m_recommend) { if (m_recommend) {
majorVersionSelect->setFilter(BaseVersionList::ModelRoles::JavaMajorRole, new ExactListFilter(m_recommended_majors)); majorVersionSelect->setFilter(BaseVersionList::ModelRoles::JavaMajorRole, Filters::equalsAny(m_recommended_majors));
} else { } else {
majorVersionSelect->setFilter(BaseVersionList::ModelRoles::JavaMajorRole, new ExactListFilter()); majorVersionSelect->setFilter(BaseVersionList::ModelRoles::JavaMajorRole, Filters::equalsAny());
} }
} }

View File

@ -38,7 +38,6 @@
#include <QWidget> #include <QWidget>
#include <Application.h> #include <Application.h>
#include <pathmatcher/IPathMatcher.h>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
#include "LogPage.h" #include "LogPage.h"
#include "ui/pages/BasePage.h" #include "ui/pages/BasePage.h"

View File

@ -104,7 +104,7 @@ void CustomPage::filterChanged()
if (ui->experimentsFilter->isChecked()) if (ui->experimentsFilter->isChecked())
out << "(experiment)"; out << "(experiment)";
auto regexp = out.join('|'); auto regexp = out.join('|');
ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false)); ui->versionList->setFilter(BaseVersionList::TypeRole, Filters::regexp(QRegularExpression(regexp)));
} }
void CustomPage::loaderFilterChanged() void CustomPage::loaderFilterChanged()

View File

@ -114,7 +114,7 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extended)
ui->setupUi(this); ui->setupUi(this);
m_versions_proxy = new VersionProxyModel(this); m_versions_proxy = new VersionProxyModel(this);
m_versions_proxy->setFilter(BaseVersionList::TypeRole, new ExactFilter("release")); m_versions_proxy->setFilter(BaseVersionList::TypeRole, Filters::equals("release"));
QAbstractProxyModel* proxy = new VersionBasicModel(this); QAbstractProxyModel* proxy = new VersionBasicModel(this);
proxy->setSourceModel(m_versions_proxy); proxy->setSourceModel(m_versions_proxy);
@ -256,7 +256,7 @@ void ModFilterWidget::onShowAllVersionsChanged()
if (ui->showAllVersions->isChecked()) if (ui->showAllVersions->isChecked())
m_versions_proxy->clearFilters(); m_versions_proxy->clearFilters();
else else
m_versions_proxy->setFilter(BaseVersionList::TypeRole, new ExactFilter("release")); m_versions_proxy->setFilter(BaseVersionList::TypeRole, Filters::equals("release"));
} }
void ModFilterWidget::onVersionFilterChanged(int) void ModFilterWidget::onVersionFilterChanged(int)

View File

@ -224,20 +224,20 @@ BaseVersion::Ptr VersionSelectWidget::selectedVersion() const
void VersionSelectWidget::setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter) void VersionSelectWidget::setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter)
{ {
m_proxyModel->setFilter(role, new ContainsFilter(filter)); m_proxyModel->setFilter(role, Filters::contains(filter));
} }
void VersionSelectWidget::setExactFilter(BaseVersionList::ModelRoles role, QString filter) void VersionSelectWidget::setExactFilter(BaseVersionList::ModelRoles role, QString filter)
{ {
m_proxyModel->setFilter(role, new ExactFilter(filter)); m_proxyModel->setFilter(role, Filters::equals(filter));
} }
void VersionSelectWidget::setExactIfPresentFilter(BaseVersionList::ModelRoles role, QString filter) void VersionSelectWidget::setExactIfPresentFilter(BaseVersionList::ModelRoles role, QString filter)
{ {
m_proxyModel->setFilter(role, new ExactIfPresentFilter(filter)); m_proxyModel->setFilter(role, Filters::equalsOrEmpty(filter));
} }
void VersionSelectWidget::setFilter(BaseVersionList::ModelRoles role, Filter* filter) void VersionSelectWidget::setFilter(BaseVersionList::ModelRoles role, Filter filter)
{ {
m_proxyModel->setFilter(role, filter); m_proxyModel->setFilter(role, filter);
} }

View File

@ -39,13 +39,13 @@
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QWidget> #include <QWidget>
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include "Filter.h"
#include "VersionListView.h" #include "VersionListView.h"
class VersionProxyModel; class VersionProxyModel;
class VersionListView; class VersionListView;
class QVBoxLayout; class QVBoxLayout;
class QProgressBar; class QProgressBar;
class Filter;
class VersionSelectWidget : public QWidget { class VersionSelectWidget : public QWidget {
Q_OBJECT Q_OBJECT
@ -70,7 +70,7 @@ class VersionSelectWidget : public QWidget {
void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter); void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter);
void setExactFilter(BaseVersionList::ModelRoles role, QString filter); void setExactFilter(BaseVersionList::ModelRoles role, QString filter);
void setExactIfPresentFilter(BaseVersionList::ModelRoles role, QString filter); void setExactIfPresentFilter(BaseVersionList::ModelRoles role, QString filter);
void setFilter(BaseVersionList::ModelRoles role, Filter* filter); void setFilter(BaseVersionList::ModelRoles role, Filter filter);
void setEmptyString(QString emptyString); void setEmptyString(QString emptyString);
void setEmptyErrorString(QString emptyErrorString); void setEmptyErrorString(QString emptyErrorString);
void setEmptyMode(VersionListView::EmptyMode mode); void setEmptyMode(VersionListView::EmptyMode mode);

View File

@ -12,8 +12,6 @@
#include <filesystem> #include <filesystem>
namespace fs = std::filesystem; namespace fs = std::filesystem;
#include <pathmatcher/RegexpMatcher.h>
class LinkTask : public Task { class LinkTask : public Task {
Q_OBJECT Q_OBJECT
@ -27,7 +25,7 @@ class LinkTask : public Task {
~LinkTask() { delete m_lnk; } ~LinkTask() { delete m_lnk; }
void matcher(IPathMatcher::Ptr filter) { m_lnk->matcher(filter); } void matcher(Filter filter) { m_lnk->matcher(filter); }
void linkRecursively(bool recursive) void linkRecursively(bool recursive)
{ {
@ -190,7 +188,7 @@ class FileSystemTest : public QObject {
qDebug() << tempDir.path(); qDebug() << tempDir.path();
qDebug() << target_dir.path(); qDebug() << target_dir.path();
FS::copy c(folder, target_dir.path()); FS::copy c(folder, target_dir.path());
RegexpMatcher::Ptr re = std::make_shared<RegexpMatcher>("[.]?mcmeta"); auto re = Filters::regexp(QRegularExpression("[.]?mcmeta"));
c.matcher(re); c.matcher(re);
c(); c();
@ -223,7 +221,7 @@ class FileSystemTest : public QObject {
qDebug() << tempDir.path(); qDebug() << tempDir.path();
qDebug() << target_dir.path(); qDebug() << target_dir.path();
FS::copy c(folder, target_dir.path()); FS::copy c(folder, target_dir.path());
RegexpMatcher::Ptr re = std::make_shared<RegexpMatcher>("[.]?mcmeta"); auto re = Filters::regexp(QRegularExpression("[.]?mcmeta"));
c.matcher(re); c.matcher(re);
c.whitelist(true); c.whitelist(true);
c(); c();
@ -415,7 +413,7 @@ class FileSystemTest : public QObject {
qDebug() << target_dir.path(); qDebug() << target_dir.path();
LinkTask lnk_tsk(folder, target_dir.path()); LinkTask lnk_tsk(folder, target_dir.path());
RegexpMatcher::Ptr re = std::make_shared<RegexpMatcher>("[.]?mcmeta"); auto re = Filters::regexp(QRegularExpression("[.]?mcmeta"));
lnk_tsk.matcher(re); lnk_tsk.matcher(re);
lnk_tsk.linkRecursively(true); lnk_tsk.linkRecursively(true);
connect(&lnk_tsk, &Task::finished, connect(&lnk_tsk, &Task::finished,
@ -461,7 +459,7 @@ class FileSystemTest : public QObject {
qDebug() << target_dir.path(); qDebug() << target_dir.path();
LinkTask lnk_tsk(folder, target_dir.path()); LinkTask lnk_tsk(folder, target_dir.path());
RegexpMatcher::Ptr re = std::make_shared<RegexpMatcher>("[.]?mcmeta"); auto re = Filters::regexp(QRegularExpression("[.]?mcmeta"));
lnk_tsk.matcher(re); lnk_tsk.matcher(re);
lnk_tsk.linkRecursively(true); lnk_tsk.linkRecursively(true);
lnk_tsk.whitelist(true); lnk_tsk.whitelist(true);