mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
300 lines
7.3 KiB
C++
300 lines
7.3 KiB
C++
#include "singletons/Settings.hpp"
|
|
|
|
#include "Application.hpp"
|
|
#include "common/Args.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/moderationactions/ModerationAction.hpp"
|
|
#include "controllers/nicknames/Nickname.hpp"
|
|
#include "debug/Benchmark.hpp"
|
|
#include "pajlada/settings/signalargs.hpp"
|
|
#include "util/WindowsHelper.hpp"
|
|
|
|
#include <pajlada/signals/scoped-connection.hpp>
|
|
|
|
namespace {
|
|
|
|
using namespace chatterino;
|
|
|
|
template <typename T>
|
|
void initializeSignalVector(pajlada::Signals::SignalHolder &signalHolder,
|
|
ChatterinoSetting<std::vector<T>> &setting,
|
|
SignalVector<T> &vec)
|
|
{
|
|
// Fill the SignalVector up with initial values
|
|
for (auto &&item : setting.getValue())
|
|
{
|
|
vec.append(item);
|
|
}
|
|
|
|
// Set up a signal to
|
|
signalHolder.managedConnect(vec.delayedItemsChanged, [&] {
|
|
setting.setValue(vec.raw());
|
|
});
|
|
}
|
|
|
|
} // 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();
|
|
|
|
for (const auto &highlightedUser : *items)
|
|
{
|
|
if (highlightedUser.isMatch(username))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool Settings::isBlacklistedUser(const QString &username)
|
|
{
|
|
auto items = this->blacklistedUsers.readOnly();
|
|
|
|
for (const auto &blacklistedUser : *items)
|
|
{
|
|
if (blacklistedUser.isMatch(username))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool Settings::isMutedChannel(const QString &channelName)
|
|
{
|
|
auto items = this->mutedChannels.readOnly();
|
|
|
|
for (const auto &channel : *items)
|
|
{
|
|
if (channelName.toLower() == channel.toLower())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
std::optional<QString> Settings::matchNickname(const QString &usernameText)
|
|
{
|
|
auto nicknames = this->nicknames.readOnly();
|
|
|
|
for (const auto &nickname : *nicknames)
|
|
{
|
|
if (auto nicknameText = nickname.match(usernameText))
|
|
{
|
|
return nicknameText;
|
|
}
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
void Settings::mute(const QString &channelName)
|
|
{
|
|
mutedChannels.append(channelName);
|
|
}
|
|
|
|
void Settings::unmute(const QString &channelName)
|
|
{
|
|
for (std::vector<int>::size_type i = 0; i != mutedChannels.raw().size();
|
|
i++)
|
|
{
|
|
if (mutedChannels.raw()[i].toLower() == channelName.toLower())
|
|
{
|
|
mutedChannels.removeAt(i);
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Settings::toggleMutedChannel(const QString &channelName)
|
|
{
|
|
if (this->isMutedChannel(channelName))
|
|
{
|
|
unmute(channelName);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
mute(channelName);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
Settings *Settings::instance_ = nullptr;
|
|
|
|
Settings::Settings(const Args &args, const QString &settingsDirectory)
|
|
: prevInstance_(Settings::instance_)
|
|
, disableSaving(args.dontSaveSettings)
|
|
{
|
|
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::SaveManually;
|
|
|
|
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;
|
|
|
|
#ifdef USEWINSDK
|
|
this->autorun = isRegisteredForStartup();
|
|
this->autorun.connect(
|
|
[](bool autorun) {
|
|
setRegisteredForStartup(autorun);
|
|
},
|
|
false);
|
|
#endif
|
|
}
|
|
|
|
Settings::~Settings()
|
|
{
|
|
Settings::instance_ = this->prevInstance_;
|
|
}
|
|
|
|
void Settings::requestSave() const
|
|
{
|
|
if (this->disableSaving)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pajlada::Settings::SettingManager::gSave();
|
|
}
|
|
|
|
void Settings::saveSnapshot()
|
|
{
|
|
BenchmarkGuard benchmark("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;
|
|
}
|
|
|
|
BenchmarkGuard benchmark("Settings::restoreSnapshot");
|
|
|
|
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;
|
|
}
|
|
|
|
pajlada::Settings::SignalArgs args;
|
|
args.compareBeforeSet = true;
|
|
|
|
setting->marshalJSON(snapshot[path], std::move(args));
|
|
}
|
|
}
|
|
|
|
float Settings::getClampedUiScale() const
|
|
{
|
|
return std::clamp(this->uiScale.getValue(), 0.2F, 10.F);
|
|
}
|
|
|
|
void Settings::setClampedUiScale(float value)
|
|
{
|
|
this->uiScale.setValue(std::clamp(value, 0.2F, 10.F));
|
|
}
|
|
|
|
Settings &Settings::instance()
|
|
{
|
|
assert(instance_ != nullptr);
|
|
|
|
return *instance_;
|
|
}
|
|
|
|
Settings *getSettings()
|
|
{
|
|
return &Settings::instance();
|
|
}
|
|
|
|
} // namespace chatterino
|