Skip to content

Commit

Permalink
Use new Skip File & Skip Directory in usvfs (#2033)
Browse files Browse the repository at this point in the history
* Use new Skip File & Skip Directory in usvfs.

# Motivations
ModOrganizer2/usvfs#61 Highlights some reasons why the ability to skip files & directories would be beneficial

# Modifications
- Add two new settings, `skip_file_suffixes` and `skip_directories`
- Wire the two new settings up to usvfs
- Add two new buttons to the `Workarounds` dialog, one to adjust Skip File Suffixes and another for Skip Directories, both buttons act nearly identical to the Executable Blacklist button
- Add a new grouping in the `Workarounds` dialog box that contains the usvfs buttons to keep the dialog a tad organized
  • Loading branch information
Twinki14 authored Jun 15, 2024
1 parent 6d08d43 commit d3b647a
Show file tree
Hide file tree
Showing 10 changed files with 264 additions and 15 deletions.
9 changes: 6 additions & 3 deletions src/organizercore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,12 +469,14 @@ void OrganizerCore::updateVFSParams(log::Levels logLevel,
env::CoreDumpTypes coreDumpType,
const QString& crashDumpsPath,
std::chrono::seconds spawnDelay,
QString executableBlacklist)
QString executableBlacklist,
const QStringList& skipFileSuffixes,
const QStringList& skipDirectories)
{
setGlobalCoreDumpType(coreDumpType);

m_USVFS.updateParams(logLevel, coreDumpType, crashDumpsPath, spawnDelay,
executableBlacklist);
executableBlacklist, skipFileSuffixes, skipDirectories);
}

void OrganizerCore::setLogLevel(log::Levels level)
Expand All @@ -484,7 +486,8 @@ void OrganizerCore::setLogLevel(log::Levels level)
updateVFSParams(
m_Settings.diagnostics().logLevel(), m_Settings.diagnostics().coreDumpType(),
QString::fromStdWString(getGlobalCoreDumpPath()),
m_Settings.diagnostics().spawnDelay(), m_Settings.executablesBlacklist());
m_Settings.diagnostics().spawnDelay(), m_Settings.executablesBlacklist(),
m_Settings.skipFileSuffixes(), m_Settings.skipDirectories());

log::getDefault().setLevel(m_Settings.diagnostics().logLevel());
}
Expand Down
3 changes: 2 additions & 1 deletion src/organizercore.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,8 @@ class OrganizerCore : public QObject, public MOBase::IPluginDiagnose

void updateVFSParams(MOBase::log::Levels logLevel, env::CoreDumpTypes coreDumpType,
const QString& coreDumpsPath, std::chrono::seconds spawnDelay,
QString executableBlacklist);
QString executableBlacklist, const QStringList& skipFileSuffixes,
const QStringList& skipDirectories);

void setLogLevel(MOBase::log::Levels level);

Expand Down
28 changes: 28 additions & 0 deletions src/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,34 @@ void Settings::setExecutablesBlacklist(const QString& s)
set(m_Settings, "Settings", "executable_blacklist", s);
}

QStringList Settings::skipFileSuffixes() const
{
static const QStringList def = QStringList() << ".mohidden";

auto setting = get<QStringList>(m_Settings, "Settings", "skip_file_suffixes", def);

return setting;
}

void Settings::setSkipFileSuffixes(const QStringList& s)
{
set(m_Settings, "Settings", "skip_file_suffixes", s);
}

QStringList Settings::skipDirectories() const
{
static const QStringList def = QStringList() << ".git";

auto setting = get<QStringList>(m_Settings, "Settings", "skip_directories", def);

return setting;
}

void Settings::setSkipDirectories(const QStringList& s)
{
set(m_Settings, "Settings", "skip_directories", s);
}

void Settings::setMotdHash(uint hash)
{
set(m_Settings, "General", "motd_hash", hash);
Expand Down
6 changes: 6 additions & 0 deletions src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,12 @@ class Settings : public QObject
bool isExecutableBlacklisted(const QString& s) const;
void setExecutablesBlacklist(const QString& s);

QStringList skipFileSuffixes() const;
void setSkipFileSuffixes(const QStringList& s);

QStringList skipDirectories() const;
void setSkipDirectories(const QStringList& s);

// ? looks obsolete, only used by dead code
//
unsigned int motdHash() const;
Expand Down
85 changes: 76 additions & 9 deletions src/settingsdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -2016,6 +2016,60 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="bsaDateBtn">
<property name="toolTip">
<string>
For Skyrim, this can be used instead of Archive Invalidation. It should make AI redundant for all Profiles.
For the other games this is not a sufficient replacement for AI!
</string>
</property>
<property name="whatsThis">
<string>
For Skyrim, this can be used instead of Archive Invalidation. It should make AI redundant for all Profiles.
For the other games this is not a sufficient replacement for AI!
</string>
</property>
<property name="text">
<string>Back-date BSAs</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/MO/gui/resources/emblem-readonly.png</normaloff>:/MO/gui/resources/emblem-readonly.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_usvfs" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="execBlacklistBtn">
<property name="toolTip">
Expand All @@ -2037,21 +2091,34 @@ programs you are intentionally running.</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="bsaDateBtn">
<widget class="QPushButton" name="skipFileSuffixBtn">
<property name="toolTip">
<string>For Skyrim, this can be used instead of Archive Invalidation. It should make AI redundant for all Profiles.
For the other games this is not a sufficient replacement for AI!</string>
<string>Files to skip or ignore from the virtual file system.</string>
</property>
<property name="whatsThis">
<string>For Skyrim, this can be used instead of Archive Invalidation. It should make AI redundant for all Profiles.
For the other games this is not a sufficient replacement for AI!</string>
<string>Files to skip or ignore from the virtual file system.</string>
</property>
<property name="text">
<string>Back-date BSAs</string>
<string>Skip File Suffixes</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/MO/gui/resources/emblem-readonly.png</normaloff>:/MO/gui/resources/emblem-readonly.png</iconset>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="skipDirectoriesBtn">
<property name="toolTip">
<string>Directories to skip or ignore from the virtual file system.</string>
</property>
<property name="whatsThis">
<string>Directories to skip or ignore from the virtual file system.</string>
</property>
<property name="text">
<string>Skip Directories</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
Expand Down
89 changes: 89 additions & 0 deletions src/settingsdialogworkarounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,21 @@ WorkaroundsSettingsTab::WorkaroundsSettingsTab(Settings& s, SettingsDialog& d)

// buttons
m_ExecutableBlacklist = settings().executablesBlacklist();
m_SkipFileSuffixes = settings().skipFileSuffixes();
m_SkipDirectories = settings().skipDirectories();

QObject::connect(ui->bsaDateBtn, &QPushButton::clicked, [&] {
on_bsaDateBtn_clicked();
});
QObject::connect(ui->execBlacklistBtn, &QPushButton::clicked, [&] {
on_execBlacklistBtn_clicked();
});
QObject::connect(ui->skipFileSuffixBtn, &QPushButton::clicked, [&] {
on_skipFileSuffixBtn_clicked();
});
QObject::connect(ui->skipDirectoriesBtn, &QPushButton::clicked, [&] {
on_skipDirectoriesBtn_clicked();
});
QObject::connect(ui->resetGeometryBtn, &QPushButton::clicked, [&] {
on_resetGeometryBtn_clicked();
});
Expand Down Expand Up @@ -69,6 +77,8 @@ void WorkaroundsSettingsTab::update()

// buttons
settings().setExecutablesBlacklist(m_ExecutableBlacklist);
settings().setSkipFileSuffixes(m_SkipFileSuffixes);
settings().setSkipDirectories(m_SkipDirectories);
}

bool WorkaroundsSettingsTab::changeBlacklistNow(QWidget* parent, Settings& settings)
Expand Down Expand Up @@ -114,13 +124,92 @@ WorkaroundsSettingsTab::changeBlacklistLater(QWidget* parent, const QString& cur
return blacklist.join(";");
}

std::optional<QStringList>
WorkaroundsSettingsTab::changeSkipFileSuffixes(QWidget* parent,
const QStringList& current)
{
bool ok = false;

QString result = QInputDialog::getMultiLineText(
parent, QObject::tr("Skip File Suffixes"),
QObject::tr(
"Enter one file suffix per line to be skipped / ignored from the virtual "
"file system.\n"
"Not to be confused with file extensions, file suffixes are simply how the "
"filename ends.\n\n"
"Example:\n"
" .txt - Would skip all files that end with .txt, <any text>.txt\n"
" some_file.txt - Would skip all files that end with some_file.txt, <any "
"text>some_file.txt"),
current.join("\n"), &ok);

if (!ok) {
return {};
}

QStringList fileSuffixes;
for (auto& suffix : result.split("\n")) {
auto trimmed = suffix.trimmed();
if (!trimmed.isEmpty()) {
fileSuffixes << trimmed;
}
}

return fileSuffixes;
}

std::optional<QStringList>
WorkaroundsSettingsTab::changeSkipDirectories(QWidget* parent,
const QStringList& current)
{
bool ok = false;

QString result = QInputDialog::getMultiLineText(
parent, QObject::tr("Skip Directories"),
QObject::tr(
"Enter one directory per line to be skipped / ignored from the virtual "
"file system.\n\n"
"Example:\n"
" .git\n"
" instructions"),
current.join("\n"), &ok);

if (!ok) {
return {};
}

QStringList directories;
for (auto& dir : result.split("\n")) {
auto trimmed = dir.trimmed();
if (!trimmed.isEmpty()) {
directories << trimmed;
}
}

return directories;
}

void WorkaroundsSettingsTab::on_execBlacklistBtn_clicked()
{
if (auto s = changeBlacklistLater(parentWidget(), m_ExecutableBlacklist)) {
m_ExecutableBlacklist = *s;
}
}

void WorkaroundsSettingsTab::on_skipFileSuffixBtn_clicked()
{
if (auto s = changeSkipFileSuffixes(parentWidget(), m_SkipFileSuffixes)) {
m_SkipFileSuffixes = *s;
}
}

void WorkaroundsSettingsTab::on_skipDirectoriesBtn_clicked()
{
if (auto s = changeSkipDirectories(parentWidget(), m_SkipDirectories)) {
m_SkipDirectories = *s;
}
}

void WorkaroundsSettingsTab::on_bsaDateBtn_clicked()
{
const auto* game = qApp->property("managed_game").value<MOBase::IPluginGame*>();
Expand Down
16 changes: 16 additions & 0 deletions src/settingsdialogworkarounds.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,29 @@ class WorkaroundsSettingsTab : public SettingsTab
static std::optional<QString> changeBlacklistLater(QWidget* parent,
const QString& current);

// shows the blacklist dialog from the given string and returns the new
// blacklist if the user accepted it
//
static std::optional<QStringList> changeSkipFileSuffixes(QWidget* parent,
const QStringList& current);

// shows the blacklist dialog from the given string and returns the new
// blacklist if the user accepted it
//
static std::optional<QStringList> changeSkipDirectories(QWidget* parent,
const QStringList& current);

void update();

private:
QString m_ExecutableBlacklist;
QStringList m_SkipFileSuffixes;
QStringList m_SkipDirectories;

void on_bsaDateBtn_clicked();
void on_execBlacklistBtn_clicked();
void on_skipFileSuffixBtn_clicked();
void on_skipDirectoriesBtn_clicked();
void on_resetGeometryBtn_clicked();
};

Expand Down
6 changes: 6 additions & 0 deletions src/settingsutilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ struct ValueConverter<QVariantList>
}
};

template <>
struct ValueConverter<QStringList>
{
static QString convert(const QStringList& t) { return t.join(", "); }
};

bool shouldLogSetting(const QString& displayName);

template <class T>
Expand Down
Loading

0 comments on commit d3b647a

Please sign in to comment.