mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Remove BaseSettings & merge ConcurrentSettings (#4775)
This commit is contained in:
parent
4c942a2a42
commit
7cb04bf58b
|
@ -6,6 +6,7 @@
|
||||||
- Dev: Fixed UTF16 encoding of `modes` file for the installer. (#4791)
|
- Dev: Fixed UTF16 encoding of `modes` file for the installer. (#4791)
|
||||||
- Dev: Temporarily disable High DPI scaling on Qt6 builds on Windows. (#4767)
|
- Dev: Temporarily disable High DPI scaling on Qt6 builds on Windows. (#4767)
|
||||||
- Dev: Tests now run on Ubuntu 22.04 instead of 20.04 to loosen C++ restrictions in tests. (#4774)
|
- Dev: Tests now run on Ubuntu 22.04 instead of 20.04 to loosen C++ restrictions in tests. (#4774)
|
||||||
|
- Dev: Do a pretty major refactor of the Settings classes. List settings (e.g. highlights) are most heavily modified, and should have an extra eye kept on them. (#4775)
|
||||||
|
|
||||||
## 2.4.5
|
## 2.4.5
|
||||||
|
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
#include "BaseSettings.hpp"
|
|
||||||
|
|
||||||
#include "util/Clamp.hpp"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
namespace chatterino {
|
|
||||||
|
|
||||||
std::vector<std::weak_ptr<pajlada::Settings::SettingData>> _settings;
|
|
||||||
|
|
||||||
AB_SETTINGS_CLASS *AB_SETTINGS_CLASS::instance = nullptr;
|
|
||||||
|
|
||||||
void _actuallyRegisterSetting(
|
|
||||||
std::weak_ptr<pajlada::Settings::SettingData> setting)
|
|
||||||
{
|
|
||||||
_settings.push_back(std::move(setting));
|
|
||||||
}
|
|
||||||
|
|
||||||
AB_SETTINGS_CLASS::AB_SETTINGS_CLASS(const QString &settingsDirectory)
|
|
||||||
{
|
|
||||||
AB_SETTINGS_CLASS::instance = this;
|
|
||||||
|
|
||||||
QString settingsPath = settingsDirectory + "/settings.json";
|
|
||||||
|
|
||||||
// get global instance of the settings library
|
|
||||||
auto settingsInstance = pajlada::Settings::SettingManager::getInstance();
|
|
||||||
|
|
||||||
settingsInstance->load(qPrintable(settingsPath));
|
|
||||||
|
|
||||||
settingsInstance->setBackupEnabled(true);
|
|
||||||
settingsInstance->setBackupSlots(9);
|
|
||||||
settingsInstance->saveMethod =
|
|
||||||
pajlada::Settings::SettingManager::SaveMethod::SaveOnExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AB_SETTINGS_CLASS::saveSnapshot()
|
|
||||||
{
|
|
||||||
rapidjson::Document *d = new rapidjson::Document(rapidjson::kObjectType);
|
|
||||||
rapidjson::Document::AllocatorType &a = d->GetAllocator();
|
|
||||||
|
|
||||||
for (const auto &weakSetting : _settings)
|
|
||||||
{
|
|
||||||
auto setting = weakSetting.lock();
|
|
||||||
if (!setting)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
rapidjson::Value key(setting->getPath().c_str(), a);
|
|
||||||
auto curVal = setting->unmarshalJSON();
|
|
||||||
if (curVal == nullptr)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
rapidjson::Value val;
|
|
||||||
val.CopyFrom(*curVal, a);
|
|
||||||
d->AddMember(key.Move(), val.Move(), a);
|
|
||||||
}
|
|
||||||
|
|
||||||
// log("Snapshot state: {}", rj::stringify(*d));
|
|
||||||
|
|
||||||
this->snapshot_.reset(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AB_SETTINGS_CLASS::restoreSnapshot()
|
|
||||||
{
|
|
||||||
if (!this->snapshot_)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &snapshot = *(this->snapshot_.get());
|
|
||||||
|
|
||||||
if (!snapshot.IsObject())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &weakSetting : _settings)
|
|
||||||
{
|
|
||||||
auto setting = weakSetting.lock();
|
|
||||||
if (!setting)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *path = setting->getPath().c_str();
|
|
||||||
|
|
||||||
if (!snapshot.HasMember(path))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
setting->marshalJSON(snapshot[path]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float AB_SETTINGS_CLASS::getClampedUiScale() const
|
|
||||||
{
|
|
||||||
return clamp<float>(this->uiScale.getValue(), 0.2f, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AB_SETTINGS_CLASS::setClampedUiScale(float value)
|
|
||||||
{
|
|
||||||
this->uiScale.setValue(clamp<float>(value, 0.2f, 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef AB_CUSTOM_SETTINGS
|
|
||||||
Settings *getSettings()
|
|
||||||
{
|
|
||||||
static_assert(std::is_same_v<AB_SETTINGS_CLASS, Settings>,
|
|
||||||
"`AB_SETTINGS_CLASS` must be the same as `Settings`");
|
|
||||||
|
|
||||||
assert(AB_SETTINGS_CLASS::instance != nullptr);
|
|
||||||
|
|
||||||
return AB_SETTINGS_CLASS::instance;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AB_SETTINGS_CLASS *getABSettings()
|
|
||||||
{
|
|
||||||
assert(AB_SETTINGS_CLASS::instance);
|
|
||||||
|
|
||||||
return AB_SETTINGS_CLASS::instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace chatterino
|
|
|
@ -1,47 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/ChatterinoSetting.hpp"
|
|
||||||
|
|
||||||
#include <pajlada/settings/settingdata.hpp>
|
|
||||||
#include <QString>
|
|
||||||
#include <rapidjson/document.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#ifdef AB_CUSTOM_SETTINGS
|
|
||||||
# define AB_SETTINGS_CLASS ABSettings
|
|
||||||
#else
|
|
||||||
# define AB_SETTINGS_CLASS Settings
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace chatterino {
|
|
||||||
|
|
||||||
class Settings;
|
|
||||||
|
|
||||||
void _actuallyRegisterSetting(
|
|
||||||
std::weak_ptr<pajlada::Settings::SettingData> setting);
|
|
||||||
|
|
||||||
class AB_SETTINGS_CLASS
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AB_SETTINGS_CLASS(const QString &settingsDirectory);
|
|
||||||
|
|
||||||
void saveSnapshot();
|
|
||||||
void restoreSnapshot();
|
|
||||||
|
|
||||||
static AB_SETTINGS_CLASS *instance;
|
|
||||||
|
|
||||||
FloatSetting uiScale = {"/appearance/uiScale2", 1};
|
|
||||||
BoolSetting windowTopMost = {"/appearance/windowAlwaysOnTop", false};
|
|
||||||
|
|
||||||
float getClampedUiScale() const;
|
|
||||||
void setClampedUiScale(float value);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<rapidjson::Document> snapshot_;
|
|
||||||
};
|
|
||||||
|
|
||||||
Settings *getSettings();
|
|
||||||
AB_SETTINGS_CLASS *getABSettings();
|
|
||||||
|
|
||||||
} // namespace chatterino
|
|
|
@ -9,8 +9,6 @@ option(CHATTERINO_DEBUG_NATIVE_MESSAGES "Debug native messages" OFF)
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
Application.cpp
|
Application.cpp
|
||||||
Application.hpp
|
Application.hpp
|
||||||
BaseSettings.cpp
|
|
||||||
BaseSettings.hpp
|
|
||||||
BrowserExtension.cpp
|
BrowserExtension.cpp
|
||||||
BrowserExtension.hpp
|
BrowserExtension.hpp
|
||||||
RunGui.cpp
|
RunGui.cpp
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "common/ChatterinoSetting.hpp"
|
#include "common/ChatterinoSetting.hpp"
|
||||||
|
|
||||||
#include "BaseSettings.hpp"
|
#include "singletons/Settings.hpp"
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,14 @@ namespace chatterino {
|
||||||
FilterSet::FilterSet()
|
FilterSet::FilterSet()
|
||||||
{
|
{
|
||||||
this->listener_ =
|
this->listener_ =
|
||||||
getCSettings().filterRecords.delayedItemsChanged.connect([this] {
|
getSettings()->filterRecords.delayedItemsChanged.connect([this] {
|
||||||
this->reloadFilters();
|
this->reloadFilters();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterSet::FilterSet(const QList<QUuid> &filterIds)
|
FilterSet::FilterSet(const QList<QUuid> &filterIds)
|
||||||
{
|
{
|
||||||
auto filters = getCSettings().filterRecords.readOnly();
|
auto filters = getSettings()->filterRecords.readOnly();
|
||||||
for (const auto &f : *filters)
|
for (const auto &f : *filters)
|
||||||
{
|
{
|
||||||
if (filterIds.contains(f->getId()))
|
if (filterIds.contains(f->getId()))
|
||||||
|
@ -23,7 +23,7 @@ FilterSet::FilterSet(const QList<QUuid> &filterIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
this->listener_ =
|
this->listener_ =
|
||||||
getCSettings().filterRecords.delayedItemsChanged.connect([this] {
|
getSettings()->filterRecords.delayedItemsChanged.connect([this] {
|
||||||
this->reloadFilters();
|
this->reloadFilters();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ const QList<QUuid> FilterSet::filterIds() const
|
||||||
|
|
||||||
void FilterSet::reloadFilters()
|
void FilterSet::reloadFilters()
|
||||||
{
|
{
|
||||||
auto filters = getCSettings().filterRecords.readOnly();
|
auto filters = getSettings()->filterRecords.readOnly();
|
||||||
for (const auto &key : this->filters_.keys())
|
for (const auto &key : this->filters_.keys())
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
|
@ -441,7 +441,7 @@ void HighlightController::initialize(Settings &settings, Paths & /*paths*/)
|
||||||
});
|
});
|
||||||
|
|
||||||
this->signalHolder_.managedConnect(
|
this->signalHolder_.managedConnect(
|
||||||
getCSettings().highlightedBadges.delayedItemsChanged,
|
getSettings()->highlightedBadges.delayedItemsChanged,
|
||||||
[this, &settings] {
|
[this, &settings] {
|
||||||
qCDebug(chatterinoHighlights)
|
qCDebug(chatterinoHighlights)
|
||||||
<< "Rebuild checks because highlight badges changed";
|
<< "Rebuild checks because highlight badges changed";
|
||||||
|
@ -449,14 +449,14 @@ void HighlightController::initialize(Settings &settings, Paths & /*paths*/)
|
||||||
});
|
});
|
||||||
|
|
||||||
this->signalHolder_.managedConnect(
|
this->signalHolder_.managedConnect(
|
||||||
getCSettings().highlightedUsers.delayedItemsChanged, [this, &settings] {
|
getSettings()->highlightedUsers.delayedItemsChanged, [this, &settings] {
|
||||||
qCDebug(chatterinoHighlights)
|
qCDebug(chatterinoHighlights)
|
||||||
<< "Rebuild checks because highlight users changed";
|
<< "Rebuild checks because highlight users changed";
|
||||||
this->rebuildChecks(settings);
|
this->rebuildChecks(settings);
|
||||||
});
|
});
|
||||||
|
|
||||||
this->signalHolder_.managedConnect(
|
this->signalHolder_.managedConnect(
|
||||||
getCSettings().highlightedMessages.delayedItemsChanged,
|
getSettings()->highlightedMessages.delayedItemsChanged,
|
||||||
[this, &settings] {
|
[this, &settings] {
|
||||||
qCDebug(chatterinoHighlights)
|
qCDebug(chatterinoHighlights)
|
||||||
<< "Rebuild checks because highlight messages changed";
|
<< "Rebuild checks because highlight messages changed";
|
||||||
|
|
|
@ -14,7 +14,7 @@ bool isIgnoredMessage(IgnoredMessageParameters &¶ms)
|
||||||
if (!params.message.isEmpty())
|
if (!params.message.isEmpty())
|
||||||
{
|
{
|
||||||
// TODO(pajlada): Do we need to check if the phrase is valid first?
|
// TODO(pajlada): Do we need to check if the phrase is valid first?
|
||||||
auto phrases = getCSettings().ignoredMessages.readOnly();
|
auto phrases = getSettings()->ignoredMessages.readOnly();
|
||||||
for (const auto &phrase : *phrases)
|
for (const auto &phrase : *phrases)
|
||||||
{
|
{
|
||||||
if (phrase.isBlock() && phrase.isMatch(params.message))
|
if (phrase.isBlock() && phrase.isMatch(params.message))
|
||||||
|
|
|
@ -806,7 +806,7 @@ void TwitchModerationElement::addToContainer(MessageLayoutContainer &container,
|
||||||
{
|
{
|
||||||
QSize size(int(container.getScale() * 16),
|
QSize size(int(container.getScale() * 16),
|
||||||
int(container.getScale() * 16));
|
int(container.getScale() * 16));
|
||||||
auto actions = getCSettings().moderationActions.readOnly();
|
auto actions = getSettings()->moderationActions.readOnly();
|
||||||
for (const auto &action : *actions)
|
for (const auto &action : *actions)
|
||||||
{
|
{
|
||||||
if (auto image = action.getImage())
|
if (auto image = action.getImage())
|
||||||
|
|
|
@ -147,7 +147,7 @@ void SharedMessageBuilder::parseUsername()
|
||||||
|
|
||||||
void SharedMessageBuilder::parseHighlights()
|
void SharedMessageBuilder::parseHighlights()
|
||||||
{
|
{
|
||||||
if (getCSettings().isBlacklistedUser(this->ircMessage->nick()))
|
if (getSettings()->isBlacklistedUser(this->ircMessage->nick()))
|
||||||
{
|
{
|
||||||
// Do nothing. We ignore highlights from this user.
|
// Do nothing. We ignore highlights from this user.
|
||||||
return;
|
return;
|
||||||
|
@ -206,7 +206,7 @@ void SharedMessageBuilder::triggerHighlights()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getCSettings().isMutedChannel(this->channel->getName()))
|
if (getSettings()->isMutedChannel(this->channel->getName()))
|
||||||
{
|
{
|
||||||
// Do nothing. Pings are muted in this channel.
|
// Do nothing. Pings are muted in this channel.
|
||||||
return;
|
return;
|
||||||
|
@ -270,7 +270,7 @@ QString SharedMessageBuilder::stylizeUsername(const QString &username,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto nicknameText = getCSettings().matchNickname(usernameText))
|
if (auto nicknameText = getSettings()->matchNickname(usernameText))
|
||||||
{
|
{
|
||||||
usernameText = *nicknameText;
|
usernameText = *nicknameText;
|
||||||
}
|
}
|
||||||
|
|
|
@ -834,7 +834,7 @@ void TwitchMessageBuilder::appendUsername()
|
||||||
void TwitchMessageBuilder::runIgnoreReplaces(
|
void TwitchMessageBuilder::runIgnoreReplaces(
|
||||||
std::vector<TwitchEmoteOccurrence> &twitchEmotes)
|
std::vector<TwitchEmoteOccurrence> &twitchEmotes)
|
||||||
{
|
{
|
||||||
auto phrases = getCSettings().ignoredMessages.readOnly();
|
auto phrases = getSettings()->ignoredMessages.readOnly();
|
||||||
auto removeEmotesInRange = [](int pos, int len,
|
auto removeEmotesInRange = [](int pos, int len,
|
||||||
auto &twitchEmotes) mutable {
|
auto &twitchEmotes) mutable {
|
||||||
auto it = std::partition(
|
auto it = std::partition(
|
||||||
|
|
|
@ -8,40 +8,46 @@
|
||||||
#include "controllers/ignores/IgnorePhrase.hpp"
|
#include "controllers/ignores/IgnorePhrase.hpp"
|
||||||
#include "controllers/moderationactions/ModerationAction.hpp"
|
#include "controllers/moderationactions/ModerationAction.hpp"
|
||||||
#include "controllers/nicknames/Nickname.hpp"
|
#include "controllers/nicknames/Nickname.hpp"
|
||||||
|
#include "util/Clamp.hpp"
|
||||||
#include "util/PersistSignalVector.hpp"
|
#include "util/PersistSignalVector.hpp"
|
||||||
#include "util/WindowsHelper.hpp"
|
#include "util/WindowsHelper.hpp"
|
||||||
|
|
||||||
namespace chatterino {
|
#include <pajlada/signals/scoped-connection.hpp>
|
||||||
|
|
||||||
ConcurrentSettings *concurrentInstance_{};
|
namespace {
|
||||||
|
|
||||||
ConcurrentSettings::ConcurrentSettings()
|
using namespace chatterino;
|
||||||
// NOTE: these do not get deleted
|
|
||||||
: highlightedMessages(*new SignalVector<HighlightPhrase>())
|
template <typename T>
|
||||||
, highlightedUsers(*new SignalVector<HighlightPhrase>())
|
void initializeSignalVector(pajlada::Signals::SignalHolder &signalHolder,
|
||||||
, highlightedBadges(*new SignalVector<HighlightBadge>())
|
ChatterinoSetting<std::vector<T>> &setting,
|
||||||
, blacklistedUsers(*new SignalVector<HighlightBlacklistUser>())
|
SignalVector<T> &vec)
|
||||||
, ignoredMessages(*new SignalVector<IgnorePhrase>())
|
|
||||||
, mutedChannels(*new SignalVector<QString>())
|
|
||||||
, filterRecords(*new SignalVector<FilterRecordPtr>())
|
|
||||||
, nicknames(*new SignalVector<Nickname>())
|
|
||||||
, moderationActions(*new SignalVector<ModerationAction>)
|
|
||||||
, loggedChannels(*new SignalVector<ChannelLog>)
|
|
||||||
{
|
{
|
||||||
persist(this->highlightedMessages, "/highlighting/highlights");
|
// Fill the SignalVector up with initial values
|
||||||
persist(this->blacklistedUsers, "/highlighting/blacklist");
|
for (auto &&item : setting.getValue())
|
||||||
persist(this->highlightedBadges, "/highlighting/badges");
|
{
|
||||||
persist(this->highlightedUsers, "/highlighting/users");
|
vec.append(item);
|
||||||
persist(this->ignoredMessages, "/ignore/phrases");
|
}
|
||||||
persist(this->mutedChannels, "/pings/muted");
|
|
||||||
persist(this->filterRecords, "/filtering/filters");
|
// Set up a signal to
|
||||||
persist(this->nicknames, "/nicknames");
|
signalHolder.managedConnect(vec.delayedItemsChanged, [&] {
|
||||||
// tagged users?
|
setting.setValue(vec.raw());
|
||||||
persist(this->moderationActions, "/moderation/actions");
|
});
|
||||||
persist(this->loggedChannels, "/logging/channels");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConcurrentSettings::isHighlightedUser(const QString &username)
|
} // namespace
|
||||||
|
|
||||||
|
namespace chatterino {
|
||||||
|
|
||||||
|
std::vector<std::weak_ptr<pajlada::Settings::SettingData>> _settings;
|
||||||
|
|
||||||
|
void _actuallyRegisterSetting(
|
||||||
|
std::weak_ptr<pajlada::Settings::SettingData> setting)
|
||||||
|
{
|
||||||
|
_settings.push_back(std::move(setting));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::isHighlightedUser(const QString &username)
|
||||||
{
|
{
|
||||||
auto items = this->highlightedUsers.readOnly();
|
auto items = this->highlightedUsers.readOnly();
|
||||||
|
|
||||||
|
@ -54,7 +60,7 @@ bool ConcurrentSettings::isHighlightedUser(const QString &username)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConcurrentSettings::isBlacklistedUser(const QString &username)
|
bool Settings::isBlacklistedUser(const QString &username)
|
||||||
{
|
{
|
||||||
auto items = this->blacklistedUsers.readOnly();
|
auto items = this->blacklistedUsers.readOnly();
|
||||||
|
|
||||||
|
@ -67,7 +73,7 @@ bool ConcurrentSettings::isBlacklistedUser(const QString &username)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConcurrentSettings::isMutedChannel(const QString &channelName)
|
bool Settings::isMutedChannel(const QString &channelName)
|
||||||
{
|
{
|
||||||
auto items = this->mutedChannels.readOnly();
|
auto items = this->mutedChannels.readOnly();
|
||||||
|
|
||||||
|
@ -81,10 +87,9 @@ bool ConcurrentSettings::isMutedChannel(const QString &channelName)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<QString> ConcurrentSettings::matchNickname(
|
boost::optional<QString> Settings::matchNickname(const QString &usernameText)
|
||||||
const QString &usernameText)
|
|
||||||
{
|
{
|
||||||
auto nicknames = getCSettings().nicknames.readOnly();
|
auto nicknames = this->nicknames.readOnly();
|
||||||
|
|
||||||
for (const auto &nickname : *nicknames)
|
for (const auto &nickname : *nicknames)
|
||||||
{
|
{
|
||||||
|
@ -97,12 +102,12 @@ boost::optional<QString> ConcurrentSettings::matchNickname(
|
||||||
return boost::none;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConcurrentSettings::mute(const QString &channelName)
|
void Settings::mute(const QString &channelName)
|
||||||
{
|
{
|
||||||
mutedChannels.append(channelName);
|
mutedChannels.append(channelName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConcurrentSettings::unmute(const QString &channelName)
|
void Settings::unmute(const QString &channelName)
|
||||||
{
|
{
|
||||||
for (std::vector<int>::size_type i = 0; i != mutedChannels.raw().size();
|
for (std::vector<int>::size_type i = 0; i != mutedChannels.raw().size();
|
||||||
i++)
|
i++)
|
||||||
|
@ -115,7 +120,7 @@ void ConcurrentSettings::unmute(const QString &channelName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConcurrentSettings::toggleMutedChannel(const QString &channelName)
|
bool Settings::toggleMutedChannel(const QString &channelName)
|
||||||
{
|
{
|
||||||
if (this->isMutedChannel(channelName))
|
if (this->isMutedChannel(channelName))
|
||||||
{
|
{
|
||||||
|
@ -129,21 +134,44 @@ bool ConcurrentSettings::toggleMutedChannel(const QString &channelName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConcurrentSettings &getCSettings()
|
|
||||||
{
|
|
||||||
// `concurrentInstance_` gets assigned in Settings ctor.
|
|
||||||
assert(concurrentInstance_);
|
|
||||||
|
|
||||||
return *concurrentInstance_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings *Settings::instance_ = nullptr;
|
Settings *Settings::instance_ = nullptr;
|
||||||
|
|
||||||
Settings::Settings(const QString &settingsDirectory)
|
Settings::Settings(const QString &settingsDirectory)
|
||||||
: ABSettings(settingsDirectory)
|
|
||||||
{
|
{
|
||||||
|
QString settingsPath = settingsDirectory + "/settings.json";
|
||||||
|
|
||||||
|
// get global instance of the settings library
|
||||||
|
auto settingsInstance = pajlada::Settings::SettingManager::getInstance();
|
||||||
|
|
||||||
|
settingsInstance->load(qPrintable(settingsPath));
|
||||||
|
|
||||||
|
settingsInstance->setBackupEnabled(true);
|
||||||
|
settingsInstance->setBackupSlots(9);
|
||||||
|
settingsInstance->saveMethod =
|
||||||
|
pajlada::Settings::SettingManager::SaveMethod::SaveOnExit;
|
||||||
|
|
||||||
|
initializeSignalVector(this->signalHolder, this->highlightedMessagesSetting,
|
||||||
|
this->highlightedMessages);
|
||||||
|
initializeSignalVector(this->signalHolder, this->highlightedUsersSetting,
|
||||||
|
this->highlightedUsers);
|
||||||
|
initializeSignalVector(this->signalHolder, this->highlightedBadgesSetting,
|
||||||
|
this->highlightedBadges);
|
||||||
|
initializeSignalVector(this->signalHolder, this->blacklistedUsersSetting,
|
||||||
|
this->blacklistedUsers);
|
||||||
|
initializeSignalVector(this->signalHolder, this->ignoredMessagesSetting,
|
||||||
|
this->ignoredMessages);
|
||||||
|
initializeSignalVector(this->signalHolder, this->mutedChannelsSetting,
|
||||||
|
this->mutedChannels);
|
||||||
|
initializeSignalVector(this->signalHolder, this->filterRecordsSetting,
|
||||||
|
this->filterRecords);
|
||||||
|
initializeSignalVector(this->signalHolder, this->nicknamesSetting,
|
||||||
|
this->nicknames);
|
||||||
|
initializeSignalVector(this->signalHolder, this->moderationActionsSetting,
|
||||||
|
this->moderationActions);
|
||||||
|
initializeSignalVector(this->signalHolder, this->loggedChannelsSetting,
|
||||||
|
this->loggedChannels);
|
||||||
|
|
||||||
instance_ = this;
|
instance_ = this;
|
||||||
concurrentInstance_ = this;
|
|
||||||
|
|
||||||
#ifdef USEWINSDK
|
#ifdef USEWINSDK
|
||||||
this->autorun = isRegisteredForStartup();
|
this->autorun = isRegisteredForStartup();
|
||||||
|
@ -160,6 +188,81 @@ Settings::Settings(const QString &settingsDirectory)
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Settings::~Settings() = default;
|
||||||
|
|
||||||
|
void Settings::saveSnapshot()
|
||||||
|
{
|
||||||
|
rapidjson::Document *d = new rapidjson::Document(rapidjson::kObjectType);
|
||||||
|
rapidjson::Document::AllocatorType &a = d->GetAllocator();
|
||||||
|
|
||||||
|
for (const auto &weakSetting : _settings)
|
||||||
|
{
|
||||||
|
auto setting = weakSetting.lock();
|
||||||
|
if (!setting)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rapidjson::Value key(setting->getPath().c_str(), a);
|
||||||
|
auto curVal = setting->unmarshalJSON();
|
||||||
|
if (curVal == nullptr)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rapidjson::Value val;
|
||||||
|
val.CopyFrom(*curVal, a);
|
||||||
|
d->AddMember(key.Move(), val.Move(), a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// log("Snapshot state: {}", rj::stringify(*d));
|
||||||
|
|
||||||
|
this->snapshot_.reset(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::restoreSnapshot()
|
||||||
|
{
|
||||||
|
if (!this->snapshot_)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &snapshot = *(this->snapshot_.get());
|
||||||
|
|
||||||
|
if (!snapshot.IsObject())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &weakSetting : _settings)
|
||||||
|
{
|
||||||
|
auto setting = weakSetting.lock();
|
||||||
|
if (!setting)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *path = setting->getPath().c_str();
|
||||||
|
|
||||||
|
if (!snapshot.HasMember(path))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
setting->marshalJSON(snapshot[path]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float Settings::getClampedUiScale() const
|
||||||
|
{
|
||||||
|
return clamp<float>(this->uiScale.getValue(), 0.2f, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setClampedUiScale(float value)
|
||||||
|
{
|
||||||
|
this->uiScale.setValue(clamp<float>(value, 0.2f, 10));
|
||||||
|
}
|
||||||
|
|
||||||
Settings &Settings::instance()
|
Settings &Settings::instance()
|
||||||
{
|
{
|
||||||
assert(instance_ != nullptr);
|
assert(instance_ != nullptr);
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "BaseSettings.hpp"
|
|
||||||
#include "common/Channel.hpp"
|
#include "common/Channel.hpp"
|
||||||
|
#include "common/ChatterinoSetting.hpp"
|
||||||
#include "common/enums/MessageOverflow.hpp"
|
#include "common/enums/MessageOverflow.hpp"
|
||||||
#include "common/SignalVector.hpp"
|
#include "common/SignalVector.hpp"
|
||||||
|
#include "controllers/filters/FilterRecord.hpp"
|
||||||
|
#include "controllers/highlights/HighlightBadge.hpp"
|
||||||
|
#include "controllers/highlights/HighlightBlacklistUser.hpp"
|
||||||
|
#include "controllers/highlights/HighlightPhrase.hpp"
|
||||||
|
#include "controllers/ignores/IgnorePhrase.hpp"
|
||||||
#include "controllers/logging/ChannelLog.hpp"
|
#include "controllers/logging/ChannelLog.hpp"
|
||||||
|
#include "controllers/moderationactions/ModerationAction.hpp"
|
||||||
|
#include "controllers/nicknames/Nickname.hpp"
|
||||||
#include "singletons/Toasts.hpp"
|
#include "singletons/Toasts.hpp"
|
||||||
#include "util/RapidJsonSerializeQString.hpp"
|
#include "util/RapidJsonSerializeQString.hpp"
|
||||||
#include "util/StreamerMode.hpp"
|
#include "util/StreamerMode.hpp"
|
||||||
|
@ -12,49 +19,14 @@
|
||||||
|
|
||||||
#include <pajlada/settings/setting.hpp>
|
#include <pajlada/settings/setting.hpp>
|
||||||
#include <pajlada/settings/settinglistener.hpp>
|
#include <pajlada/settings/settinglistener.hpp>
|
||||||
|
#include <pajlada/signals/signalholder.hpp>
|
||||||
|
|
||||||
using TimeoutButton = std::pair<QString, int>;
|
using TimeoutButton = std::pair<QString, int>;
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
class HighlightPhrase;
|
void _actuallyRegisterSetting(
|
||||||
class HighlightBlacklistUser;
|
std::weak_ptr<pajlada::Settings::SettingData> setting);
|
||||||
class IgnorePhrase;
|
|
||||||
class FilterRecord;
|
|
||||||
using FilterRecordPtr = std::shared_ptr<FilterRecord>;
|
|
||||||
class Nickname;
|
|
||||||
class HighlightBadge;
|
|
||||||
class ModerationAction;
|
|
||||||
|
|
||||||
/// Settings which are available for reading on all threads.
|
|
||||||
class ConcurrentSettings
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ConcurrentSettings();
|
|
||||||
|
|
||||||
SignalVector<HighlightPhrase> &highlightedMessages;
|
|
||||||
SignalVector<HighlightPhrase> &highlightedUsers;
|
|
||||||
SignalVector<HighlightBadge> &highlightedBadges;
|
|
||||||
SignalVector<HighlightBlacklistUser> &blacklistedUsers;
|
|
||||||
SignalVector<IgnorePhrase> &ignoredMessages;
|
|
||||||
SignalVector<QString> &mutedChannels;
|
|
||||||
SignalVector<FilterRecordPtr> &filterRecords;
|
|
||||||
SignalVector<Nickname> &nicknames;
|
|
||||||
SignalVector<ModerationAction> &moderationActions;
|
|
||||||
SignalVector<ChannelLog> &loggedChannels;
|
|
||||||
|
|
||||||
bool isHighlightedUser(const QString &username);
|
|
||||||
bool isBlacklistedUser(const QString &username);
|
|
||||||
bool isMutedChannel(const QString &channelName);
|
|
||||||
bool toggleMutedChannel(const QString &channelName);
|
|
||||||
boost::optional<QString> matchNickname(const QString &username);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void mute(const QString &channelName);
|
|
||||||
void unmute(const QString &channelName);
|
|
||||||
};
|
|
||||||
|
|
||||||
ConcurrentSettings &getCSettings();
|
|
||||||
|
|
||||||
enum UsernameDisplayMode : int {
|
enum UsernameDisplayMode : int {
|
||||||
Username = 1, // Username
|
Username = 1, // Username
|
||||||
|
@ -91,15 +63,25 @@ enum UsernameRightClickBehavior : int {
|
||||||
|
|
||||||
/// Settings which are availlable for reading and writing on the gui thread.
|
/// Settings which are availlable for reading and writing on the gui thread.
|
||||||
// These settings are still accessed concurrently in the code but it is bad practice.
|
// These settings are still accessed concurrently in the code but it is bad practice.
|
||||||
class Settings : public ABSettings, public ConcurrentSettings
|
class Settings
|
||||||
{
|
{
|
||||||
static Settings *instance_;
|
static Settings *instance_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Settings(const QString &settingsDirectory);
|
Settings(const QString &settingsDirectory);
|
||||||
|
~Settings();
|
||||||
|
|
||||||
static Settings &instance();
|
static Settings &instance();
|
||||||
|
|
||||||
|
void saveSnapshot();
|
||||||
|
void restoreSnapshot();
|
||||||
|
|
||||||
|
FloatSetting uiScale = {"/appearance/uiScale2", 1};
|
||||||
|
BoolSetting windowTopMost = {"/appearance/windowAlwaysOnTop", false};
|
||||||
|
|
||||||
|
float getClampedUiScale() const;
|
||||||
|
void setClampedUiScale(float value);
|
||||||
|
|
||||||
/// Appearance
|
/// Appearance
|
||||||
BoolSetting showTimestamps = {"/appearance/messages/showTimestamps", true};
|
BoolSetting showTimestamps = {"/appearance/messages/showTimestamps", true};
|
||||||
BoolSetting animationsWhenFocused = {
|
BoolSetting animationsWhenFocused = {
|
||||||
|
@ -575,7 +557,55 @@ public:
|
||||||
"/plugins/enabledPlugins", {}};
|
"/plugins/enabledPlugins", {}};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ChatterinoSetting<std::vector<HighlightPhrase>> highlightedMessagesSetting =
|
||||||
|
{"/highlighting/highlights"};
|
||||||
|
ChatterinoSetting<std::vector<HighlightPhrase>> highlightedUsersSetting = {
|
||||||
|
"/highlighting/users"};
|
||||||
|
ChatterinoSetting<std::vector<HighlightBadge>> highlightedBadgesSetting = {
|
||||||
|
"/highlighting/badges"};
|
||||||
|
ChatterinoSetting<std::vector<HighlightBlacklistUser>>
|
||||||
|
blacklistedUsersSetting = {"/highlighting/blacklist"};
|
||||||
|
ChatterinoSetting<std::vector<IgnorePhrase>> ignoredMessagesSetting = {
|
||||||
|
"/ignore/phrases"};
|
||||||
|
ChatterinoSetting<std::vector<QString>> mutedChannelsSetting = {
|
||||||
|
"/pings/muted"};
|
||||||
|
ChatterinoSetting<std::vector<FilterRecordPtr>> filterRecordsSetting = {
|
||||||
|
"/filtering/filters"};
|
||||||
|
ChatterinoSetting<std::vector<Nickname>> nicknamesSetting = {"/nicknames"};
|
||||||
|
ChatterinoSetting<std::vector<ModerationAction>> moderationActionsSetting =
|
||||||
|
{"/moderation/actions"};
|
||||||
|
ChatterinoSetting<std::vector<ChannelLog>> loggedChannelsSetting = {
|
||||||
|
"/logging/channels"};
|
||||||
|
|
||||||
|
public:
|
||||||
|
SignalVector<HighlightPhrase> highlightedMessages;
|
||||||
|
SignalVector<HighlightPhrase> highlightedUsers;
|
||||||
|
SignalVector<HighlightBadge> highlightedBadges;
|
||||||
|
SignalVector<HighlightBlacklistUser> blacklistedUsers;
|
||||||
|
SignalVector<IgnorePhrase> ignoredMessages;
|
||||||
|
SignalVector<QString> mutedChannels;
|
||||||
|
SignalVector<FilterRecordPtr> filterRecords;
|
||||||
|
SignalVector<Nickname> nicknames;
|
||||||
|
SignalVector<ModerationAction> moderationActions;
|
||||||
|
SignalVector<ChannelLog> loggedChannels;
|
||||||
|
|
||||||
|
bool isHighlightedUser(const QString &username);
|
||||||
|
bool isBlacklistedUser(const QString &username);
|
||||||
|
bool isMutedChannel(const QString &channelName);
|
||||||
|
bool toggleMutedChannel(const QString &channelName);
|
||||||
|
boost::optional<QString> matchNickname(const QString &username);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void mute(const QString &channelName);
|
||||||
|
void unmute(const QString &channelName);
|
||||||
|
|
||||||
void updateModerationActions();
|
void updateModerationActions();
|
||||||
|
|
||||||
|
std::unique_ptr<rapidjson::Document> snapshot_;
|
||||||
|
|
||||||
|
pajlada::Signals::SignalHolder signalHolder;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Settings *getSettings();
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "widgets/BaseWidget.hpp"
|
#include "widgets/BaseWidget.hpp"
|
||||||
|
|
||||||
#include "BaseSettings.hpp"
|
|
||||||
#include "common/QLogging.hpp"
|
#include "common/QLogging.hpp"
|
||||||
#include "controllers/hotkeys/HotkeyController.hpp"
|
#include "controllers/hotkeys/HotkeyController.hpp"
|
||||||
#include "singletons/Theme.hpp"
|
#include "singletons/Theme.hpp"
|
||||||
|
|
|
@ -710,7 +710,7 @@ void BaseWindow::updateScale()
|
||||||
auto scale =
|
auto scale =
|
||||||
this->nativeScale_ * (this->flags_.has(DisableCustomScaling)
|
this->nativeScale_ * (this->flags_.has(DisableCustomScaling)
|
||||||
? 1
|
? 1
|
||||||
: getABSettings()->getClampedUiScale());
|
: getSettings()->getClampedUiScale());
|
||||||
|
|
||||||
this->setScale(scale);
|
this->setScale(scale);
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ SelectChannelFiltersDialog::SelectChannelFiltersDialog(
|
||||||
(this->windowFlags() & ~(Qt::WindowContextHelpButtonHint)) |
|
(this->windowFlags() & ~(Qt::WindowContextHelpButtonHint)) |
|
||||||
Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
|
Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
|
||||||
|
|
||||||
auto availableFilters = getCSettings().filterRecords.readOnly();
|
auto availableFilters = getSettings()->filterRecords.readOnly();
|
||||||
|
|
||||||
if (availableFilters->size() == 0)
|
if (availableFilters->size() == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "controllers/highlights/HighlightController.hpp"
|
#include "controllers/highlights/HighlightController.hpp"
|
||||||
|
|
||||||
#include "BaseSettings.hpp"
|
|
||||||
#include "controllers/accounts/AccountController.hpp"
|
#include "controllers/accounts/AccountController.hpp"
|
||||||
#include "controllers/highlights/HighlightPhrase.hpp"
|
#include "controllers/highlights/HighlightPhrase.hpp"
|
||||||
#include "messages/MessageBuilder.hpp" // for MessageParseArgs
|
#include "messages/MessageBuilder.hpp" // for MessageParseArgs
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include "Application.hpp"
|
#include "Application.hpp"
|
||||||
#include "BaseSettings.hpp"
|
|
||||||
#include "common/Aliases.hpp"
|
#include "common/Aliases.hpp"
|
||||||
#include "common/CompletionModel.hpp"
|
#include "common/CompletionModel.hpp"
|
||||||
#include "controllers/accounts/AccountController.hpp"
|
#include "controllers/accounts/AccountController.hpp"
|
||||||
|
|
Loading…
Reference in a new issue