Newer
Older
// SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr>
// SPDX-FileCopyrightText: 2021 Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include <QCoreApplication>
#include <QFileDialog>
#include <QFontComboBox>
#include <QInputDialog>
#include <QLineEdit>
#include <QMessageBox>
#include <QProcessEnvironment>
#include <QResizeEvent>
#include <QScroller>
#include <QSpinBox>
#include <QString>
#include "Cache.h"
#include "MatrixClient.h"
#include "Olm.h"
#include "ui/FlatButton.h"
#include "ui/ToggleButton.h"
QSharedPointer<UserSettings> UserSettings::instance_;
UserSettings::UserSettings()
{
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, []() {
instance_.clear();
});
}
QSharedPointer<UserSettings>
UserSettings::instance()
{
return instance_;
}
UserSettings::initialize(std::optional<QString> profile)
{
instance_.reset(new UserSettings());
instance_->load(profile);
}
void
UserSettings::load(std::optional<QString> profile)
tray_ = settings.value("user/window/tray", false).toBool();
hasDesktopNotifications_ = settings.value("user/desktop_notifications", true).toBool();
hasAlertOnNotification_ = settings.value("user/alert_on_notification", false).toBool();
startInTray_ = settings.value("user/window/start_in_tray", false).toBool();
groupView_ = settings.value("user/group_view", true).toBool();
hiddenTags_ = settings.value("user/hidden_tags", QStringList{}).toStringList();
buttonsInTimeline_ = settings.value("user/timeline/buttons", true).toBool();
timelineMaxWidth_ = settings.value("user/timeline/max_width", 0).toInt();
messageHoverHighlight_ =
settings.value("user/timeline/message_hover_highlight", false).toBool();
settings.value("user/timeline/enlarge_emoji_only_msg", false).toBool();
markdown_ = settings.value("user/markdown_enabled", true).toBool();
typingNotifications_ = settings.value("user/typing_notifications", true).toBool();
sortByImportance_ = settings.value("user/sort_by_unread", true).toBool();
readReceipts_ = settings.value("user/read_receipts", true).toBool();
theme_ = settings.value("user/theme", defaultTheme_).toString();
font_ = settings.value("user/font_family", "default").toString();
avatarCircles_ = settings.value("user/avatar_circles", true).toBool();
decryptSidebar_ = settings.value("user/decrypt_sidebar", true).toBool();
privacyScreen_ = settings.value("user/privacy_screen", false).toBool();
privacyScreenTimeout_ = settings.value("user/privacy_screen_timeout", 0).toInt();
shareKeysWithTrustedUsers_ =
settings.value("user/share_keys_with_trusted_users", true).toBool();
mobileMode_ = settings.value("user/mobile_mode", false).toBool();
emojiFont_ = settings.value("user/emoji_font_family", "default").toString();
baseFontSize_ = settings.value("user/font_size", QFont().pointSizeF()).toDouble();
auto tempPresence = settings.value("user/presence", "").toString().toStdString();
auto presenceValue = QMetaEnum::fromType<Presence>().keyToValue(tempPresence.c_str());
if (presenceValue < 0)
presenceValue = 0;
presence_ = static_cast<Presence>(presenceValue);
ringtone_ = settings.value("user/ringtone", "Default").toString();
microphone_ = settings.value("user/microphone", QString()).toString();
camera_ = settings.value("user/camera", QString()).toString();
cameraResolution_ = settings.value("user/camera_resolution", QString()).toString();
cameraFrameRate_ = settings.value("user/camera_frame_rate", QString()).toString();
screenShareFrameRate_ = settings.value("user/screen_share_frame_rate", 5).toInt();
screenSharePiP_ = settings.value("user/screen_share_pip", true).toBool();
screenShareRemoteVideo_ = settings.value("user/screen_share_remote_video", false).toBool();
screenShareHideCursor_ = settings.value("user/screen_share_hide_cursor", false).toBool();
useStunServer_ = settings.value("user/use_stun_server", false).toBool();
if (profile) // set to "" if it's the default to maintain compatibility
profile_ = (*profile == "default") ? "" : *profile;
else
profile_ = settings.value("user/currentProfile", "").toString();
QString prefix =
(profile_ != "" && profile_ != "default") ? "profile/" + profile_ + "/" : "";
accessToken_ = settings.value(prefix + "auth/access_token", "").toString();
homeserver_ = settings.value(prefix + "auth/home_server", "").toString();
userId_ = settings.value(prefix + "auth/user_id", "").toString();
deviceId_ = settings.value(prefix + "auth/device_id", "").toString();
disableCertificateValidation_ =
settings.value("disable_certificate_validation", false).toBool();
void
UserSettings::setMessageHoverHighlight(bool state)
{
if (state == messageHoverHighlight_)
return;
emit messageHoverHighlightChanged(state);
save();
}
void
UserSettings::setEnlargeEmojiOnlyMessages(bool state)
{
if (state == enlargeEmojiOnlyMessages_)
return;
enlargeEmojiOnlyMessages_ = state;
emit enlargeEmojiOnlyMessagesChanged(state);
save();
}
void
UserSettings::setTray(bool state)
{
return;
emit trayChanged(state);
save();
}
void
UserSettings::setStartInTray(bool state)
{
return;
emit startInTrayChanged(state);
save();
}
void
UserSettings::setMobileMode(bool state)
{
if (state == mobileMode_)
return;
mobileMode_ = state;
emit mobileModeChanged(state);
save();
}
void
UserSettings::setGroupView(bool state)
{
emit groupViewStateChanged(state);
save();
}
void
UserSettings::setHiddenTags(QStringList hiddenTags)
{
hiddenTags_ = hiddenTags;
save();
}
void
UserSettings::setMarkdown(bool state)
{
return;
emit markdownChanged(state);
save();
}
void
UserSettings::setReadReceipts(bool state)
{
return;
emit readReceiptsChanged(state);
save();
}
void
UserSettings::setTypingNotifications(bool state)
{
if (state == typingNotifications_)
return;
emit typingNotificationsChanged(state);
save();
}
void
UserSettings::setSortByImportance(bool state)
{
if (state == sortByImportance_)
return;
sortByImportance_ = state;
emit roomSortingChanged(state);
save();
}
void
UserSettings::setButtonsInTimeline(bool state)
{
return;
emit buttonInTimelineChanged(state);
save();
}
void
UserSettings::setTimelineMaxWidth(int state)
{
if (state == timelineMaxWidth_)
return;
timelineMaxWidth_ = state;
emit timelineMaxWidthChanged(state);
save();
}
void
UserSettings::setDesktopNotifications(bool state)
{
if (state == hasDesktopNotifications_)
return;
hasDesktopNotifications_ = state;
emit desktopNotificationsChanged(state);
save();
}
void
UserSettings::setAlertOnNotification(bool state)
{
if (state == hasAlertOnNotification_)
return;
hasAlertOnNotification_ = state;
emit alertOnNotificationChanged(state);
save();
}
void
UserSettings::setAvatarCircles(bool state)
{
if (state == avatarCircles_)
return;
avatarCircles_ = state;
emit avatarCirclesChanged(state);
save();
}
void
UserSettings::setDecryptSidebar(bool state)
{
if (state == decryptSidebar_)
return;
decryptSidebar_ = state;
emit decryptSidebarChanged(state);
save();
}
void
UserSettings::setPrivacyScreen(bool state)
{
if (state == privacyScreen_) {
return;
}
privacyScreen_ = state;
emit privacyScreenChanged(state);
save();
}
void
UserSettings::setPrivacyScreenTimeout(int state)
{
if (state == privacyScreenTimeout_) {
return;
}
privacyScreenTimeout_ = state;
emit privacyScreenTimeoutChanged(state);
save();
}
void
UserSettings::setFontSize(double size)
{
if (size == baseFontSize_)
return;
baseFontSize_ = size;
emit fontSizeChanged(size);
void
UserSettings::setFontFamily(QString family)
{
if (family == font_)
return;
emit fontChanged(family);
void
UserSettings::setEmojiFontFamily(QString family)
{
if (family == emojiFont_)
return;
emit emojiFontChanged(family);
void
UserSettings::setPresence(Presence state)
{
if (state == presence_)
return;
presence_ = state;
emit presenceChanged(state);
save();
}
void
UserSettings::setTheme(QString theme)
{
return;
theme_ = theme;
save();
applyTheme();
emit themeChanged(theme);
void
UserSettings::setUseStunServer(bool useStunServer)
{
if (useStunServer == useStunServer_)
return;
useStunServer_ = useStunServer;
emit useStunServerChanged(useStunServer);
save();
}
void
UserSettings::setShareKeysWithTrustedUsers(bool shareKeys)
{
if (shareKeys == shareKeysWithTrustedUsers_)
return;
shareKeysWithTrustedUsers_ = shareKeys;
emit shareKeysWithTrustedUsersChanged(shareKeys);
save();
}
void
UserSettings::setRingtone(QString ringtone)
{
if (ringtone == ringtone_)
return;
ringtone_ = ringtone;
emit ringtoneChanged(ringtone);
save();
}
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
microphone_ = microphone;
emit microphoneChanged(microphone);
save();
}
void
UserSettings::setCamera(QString camera)
{
if (camera == camera_)
return;
camera_ = camera;
emit cameraChanged(camera);
save();
}
void
UserSettings::setCameraResolution(QString resolution)
{
if (resolution == cameraResolution_)
return;
cameraResolution_ = resolution;
emit cameraResolutionChanged(resolution);
save();
}
void
UserSettings::setCameraFrameRate(QString frameRate)
{
if (frameRate == cameraFrameRate_)
return;
cameraFrameRate_ = frameRate;
emit cameraFrameRateChanged(frameRate);
void
UserSettings::setScreenShareFrameRate(int frameRate)
{
if (frameRate == screenShareFrameRate_)
return;
screenShareFrameRate_ = frameRate;
emit screenShareFrameRateChanged(frameRate);
save();
}
void
UserSettings::setScreenSharePiP(bool state)
{
if (state == screenSharePiP_)
return;
screenSharePiP_ = state;
emit screenSharePiPChanged(state);
save();
}
void
UserSettings::setScreenShareRemoteVideo(bool state)
{
if (state == screenShareRemoteVideo_)
return;
screenShareRemoteVideo_ = state;
emit screenShareRemoteVideoChanged(state);
save();
}
void
UserSettings::setScreenShareHideCursor(bool state)
{
if (state == screenShareHideCursor_)
return;
screenShareHideCursor_ = state;
emit screenShareHideCursorChanged(state);
save();
}
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
void
UserSettings::setProfile(QString profile)
{
if (profile == profile_)
return;
profile_ = profile;
emit profileChanged(profile_);
save();
}
void
UserSettings::setUserId(QString userId)
{
if (userId == userId_)
return;
userId_ = userId;
emit userIdChanged(userId_);
save();
}
void
UserSettings::setAccessToken(QString accessToken)
{
if (accessToken == accessToken_)
return;
accessToken_ = accessToken;
emit accessTokenChanged(accessToken_);
save();
}
void
UserSettings::setDeviceId(QString deviceId)
{
if (deviceId == deviceId_)
return;
deviceId_ = deviceId;
emit deviceIdChanged(deviceId_);
save();
}
void
UserSettings::setHomeserver(QString homeserver)
{
if (homeserver == homeserver_)
return;
homeserver_ = homeserver;
emit homeserverChanged(homeserver_);
save();
}
void
UserSettings::setDisableCertificateValidation(bool disabled)
{
if (disabled == disableCertificateValidation_)
return;
disableCertificateValidation_ = disabled;
http::client()->verify_certificates(!disabled);
emit disableCertificateValidationChanged(disabled);
save();
}
void
UserSettings::applyTheme()
{
QFile stylefile;
static QPalette original;
if (this->theme() == "light") {
stylefile.setFileName(":/styles/styles/nheko.qss");
QPalette lightActive(
/*windowText*/ QColor("#333"),
/*dark*/ QColor(110, 110, 110),
/*mid*/ QColor(220, 220, 220),
/*text*/ QColor("#333"),
/*bright_text*/ QColor("#333"),
lightActive.setColor(QPalette::AlternateBase, QColor("#eee"));
lightActive.setColor(QPalette::Highlight, QColor("#38a3d8"));
lightActive.setColor(QPalette::ToolTipBase, lightActive.base().color());
lightActive.setColor(QPalette::ToolTipText, lightActive.text().color());
lightActive.setColor(QPalette::Link, QColor("#0077b5"));
lightActive.setColor(QPalette::ButtonText, QColor("#333"));
QApplication::setPalette(lightActive);
} else if (this->theme() == "dark") {
stylefile.setFileName(":/styles/styles/nheko-dark.qss");
QPalette darkActive(
/*windowText*/ QColor("#caccd1"),
/*button*/ QColor(0xff, 0xff, 0xff),
/*light*/ QColor("#caccd1"),
/*dark*/ QColor(110, 110, 110),
/*mid*/ QColor("#202228"),
/*text*/ QColor("#caccd1"),
/*bright_text*/ QColor(0xff, 0xff, 0xff),
/*base*/ QColor("#202228"),
/*window*/ QColor("#2d3139"));
darkActive.setColor(QPalette::AlternateBase, QColor("#2d3139"));
darkActive.setColor(QPalette::Highlight, QColor("#38a3d8"));
darkActive.setColor(QPalette::ToolTipBase, darkActive.base().color());
darkActive.setColor(QPalette::ToolTipText, darkActive.text().color());
darkActive.setColor(QPalette::Link, QColor("#38a3d8"));
darkActive.setColor(QPalette::ButtonText, "#727274");
} else {
stylefile.setFileName(":/styles/styles/system.qss");
}
stylefile.open(QFile::ReadOnly);
QString stylesheet = QString(stylefile.readAll());
qobject_cast<QApplication *>(QApplication::instance())->setStyleSheet(stylesheet);
}
void
UserSettings::save()
{
QSettings settings;
settings.beginGroup("user");
settings.beginGroup("window");
settings.setValue("tray", tray_);
settings.setValue("start_in_tray", startInTray_);
settings.endGroup(); // window
Nicolas Werner
committed
settings.beginGroup("timeline");
settings.setValue("buttons", buttonsInTimeline_);
settings.setValue("message_hover_highlight", messageHoverHighlight_);
settings.setValue("enlarge_emoji_only_msg", enlargeEmojiOnlyMessages_);
settings.setValue("max_width", timelineMaxWidth_);
settings.endGroup(); // timeline
Nicolas Werner
committed
settings.setValue("avatar_circles", avatarCircles_);
settings.setValue("decrypt_sidebar", decryptSidebar_);
settings.setValue("privacy_screen", privacyScreen_);
settings.setValue("privacy_screen_timeout", privacyScreenTimeout_);
settings.setValue("share_keys_with_trusted_users", shareKeysWithTrustedUsers_);
settings.setValue("mobile_mode", mobileMode_);
settings.setValue("font_size", baseFontSize_);
settings.setValue("typing_notifications", typingNotifications_);
Emi Simpson
committed
settings.setValue("minor_events", sortByImportance_);
settings.setValue("read_receipts", readReceipts_);
settings.setValue("group_view", groupView_);
settings.setValue("markdown_enabled", markdown_);
settings.setValue("desktop_notifications", hasDesktopNotifications_);
settings.setValue("alert_on_notification", hasAlertOnNotification_);
settings.setValue("emoji_font_family", emojiFont_);
settings.setValue("presence",
QString::fromUtf8(QMetaEnum::fromType<Presence>().valueToKey(
static_cast<int>(presence_))));
settings.setValue("ringtone", ringtone_);
settings.setValue("microphone", microphone_);
settings.setValue("camera", camera_);
settings.setValue("camera_resolution", cameraResolution_);
settings.setValue("camera_frame_rate", cameraFrameRate_);
settings.setValue("screen_share_frame_rate", screenShareFrameRate_);
settings.setValue("screen_share_pip", screenSharePiP_);
settings.setValue("screen_share_remote_video", screenShareRemoteVideo_);
settings.setValue("screen_share_hide_cursor", screenShareHideCursor_);
settings.setValue("currentProfile", profile_);
QString prefix =
(profile_ != "" && profile_ != "default") ? "profile/" + profile_ + "/" : "";
settings.setValue(prefix + "auth/access_token", accessToken_);
settings.setValue(prefix + "auth/home_server", homeserver_);
settings.setValue(prefix + "auth/user_id", userId_);
settings.setValue(prefix + "auth/device_id", deviceId_);
settings.setValue("disable_certificate_validation", disableCertificateValidation_);
settings.sync();
}
HorizontalLine::HorizontalLine(QWidget *parent)
{
setFrameShape(QFrame::HLine);
setFrameShadow(QFrame::Sunken);
}
UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidget *parent)
: QWidget{parent}
, settings_{settings}
QIcon icon;
icon.addFile(":/icons/icons/ui/angle-pointing-to-left.png");
backBtn_->setMinimumSize(QSize(24, 24));
backBtn_->setIcon(icon);
backBtn_->setIconSize(QSize(24, 24));
QFont font;
font.setPointSizeF(font.pointSizeF() * 1.1);
auto versionInfo = new QLabel(QString("%1 | %2").arg(nheko::version).arg(nheko::build_os));
if (QCoreApplication::applicationName() != "nheko")
versionInfo->setText(versionInfo->text() + " | " +
tr("profile: %1").arg(QCoreApplication::applicationName()));
versionInfo->setTextInteractionFlags(Qt::TextBrowserInteraction);
topBarLayout_ = new QHBoxLayout;
topBarLayout_->setSpacing(0);
topBarLayout_->setMargin(0);
topBarLayout_->addWidget(backBtn_, 1, Qt::AlignLeft | Qt::AlignVCenter);
topBarLayout_->addStretch(1);
formLayout_ = new QFormLayout;
formLayout_->setLabelAlignment(Qt::AlignLeft);
formLayout_->setFormAlignment(Qt::AlignRight);
formLayout_->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
formLayout_->setRowWrapPolicy(QFormLayout::WrapLongRows);
formLayout_->setHorizontalSpacing(0);
auto general_ = new QLabel{tr("GENERAL"), this};
general_->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
general_->setFont(font);
trayToggle_ = new Toggle{this};
startInTrayToggle_ = new Toggle{this};
avatarCircles_ = new Toggle{this};
decryptSidebar_ = new Toggle(this);
shareKeysWithTrustedUsers_ = new Toggle(this);
groupViewToggle_ = new Toggle{this};
timelineButtonsToggle_ = new Toggle{this};
typingNotifications_ = new Toggle{this};
messageHoverHighlight_ = new Toggle{this};
enlargeEmojiOnlyMessages_ = new Toggle{this};
sortByImportance_ = new Toggle{this};
readReceipts_ = new Toggle{this};
markdown_ = new Toggle{this};
desktopNotifications_ = new Toggle{this};
alertOnNotification_ = new Toggle{this};
useStunServer_ = new Toggle{this};
mobileMode_ = new Toggle{this};
scaleFactorCombo_ = new QComboBox{this};
fontSizeCombo_ = new QComboBox{this};
fontSelectionCombo_ = new QFontComboBox{this};
emojiFontSelectionCombo_ = new QComboBox{this};
ringtoneCombo_ = new QComboBox{this};
microphoneCombo_ = new QComboBox{this};
cameraCombo_ = new QComboBox{this};
cameraResolutionCombo_ = new QComboBox{this};
cameraFrameRateCombo_ = new QComboBox{this};
timelineMaxWidthSpin_ = new QSpinBox{this};
privacyScreenTimeout_ = new QSpinBox{this};
trayToggle_->setChecked(settings_->tray());
startInTrayToggle_->setChecked(settings_->startInTray());
avatarCircles_->setChecked(settings_->avatarCircles());
decryptSidebar_->setChecked(settings_->decryptSidebar());
privacyScreen_->setChecked(settings_->privacyScreen());
shareKeysWithTrustedUsers_->setChecked(settings_->shareKeysWithTrustedUsers());
groupViewToggle_->setChecked(settings_->groupView());
timelineButtonsToggle_->setChecked(settings_->buttonsInTimeline());
typingNotifications_->setChecked(settings_->typingNotifications());
messageHoverHighlight_->setChecked(settings_->messageHoverHighlight());
enlargeEmojiOnlyMessages_->setChecked(settings_->enlargeEmojiOnlyMessages());
sortByImportance_->setChecked(settings_->sortByImportance());
readReceipts_->setChecked(settings_->readReceipts());
markdown_->setChecked(settings_->markdown());
desktopNotifications_->setChecked(settings_->hasDesktopNotifications());
alertOnNotification_->setChecked(settings_->hasAlertOnNotification());
useStunServer_->setChecked(settings_->useStunServer());
mobileMode_->setChecked(settings_->mobileMode());
if (!settings_->tray()) {
startInTrayToggle_->setState(false);
startInTrayToggle_->setDisabled(true);
}
if (!settings_->privacyScreen()) {
privacyScreenTimeout_->setDisabled(true);
}
avatarCircles_->setFixedSize(64, 48);
auto uiLabel_ = new QLabel{tr("INTERFACE"), this};
uiLabel_->setFixedHeight(uiLabel_->minimumHeight() + LayoutTopMargin);
uiLabel_->setAlignment(Qt::AlignBottom);
for (double option = 1; option <= 3; option += 0.25)
scaleFactorCombo_->addItem(QString::number(option));
for (double option = 6; option <= 24; option += 0.5)
fontSizeCombo_->addItem(QString("%1 ").arg(QString::number(option)));
// TODO: Is there a way to limit to just emojis, rather than
// all emoji fonts?
auto emojiFamilies = fontDb.families(QFontDatabase::Symbol);
emojiFontSelectionCombo_->addItem(tr("Default"));
for (const auto &family : emojiFamilies) {
emojiFontSelectionCombo_->addItem(family);
}
if (currentFont != "default" || currentFont != "") {
fontSelectionCombo_->setCurrentIndex(fontSelectionCombo_->findText(currentFont));
emojiFontSelectionCombo_->setCurrentIndex(
emojiFontSelectionCombo_->findText(settings_->emojiFont()));
themeCombo_->addItem("Light");
themeCombo_->addItem("Dark");
QString themeStr = settings_->theme();
themeStr.replace(0, 1, themeStr[0].toUpper());
int themeIndex = themeCombo_->findText(themeStr);
themeCombo_->setCurrentIndex(themeIndex);
timelineMaxWidthSpin_->setMinimum(0);
timelineMaxWidthSpin_->setMaximum(100'000'000);
timelineMaxWidthSpin_->setSingleStep(10);
privacyScreenTimeout_->setMinimum(0);
privacyScreenTimeout_->setMaximum(3600);
privacyScreenTimeout_->setSingleStep(10);
auto callsLabel = new QLabel{tr("CALLS"), this};
callsLabel->setFixedHeight(callsLabel->minimumHeight() + LayoutTopMargin);
callsLabel->setAlignment(Qt::AlignBottom);
callsLabel->setFont(font);
auto encryptionLabel_ = new QLabel{tr("ENCRYPTION"), this};
encryptionLabel_->setFixedHeight(encryptionLabel_->minimumHeight() + LayoutTopMargin);
encryptionLabel_->setAlignment(Qt::AlignBottom);
encryptionLabel_->setFont(font);
QFont monospaceFont;
monospaceFont.setFamily("Monospace");
monospaceFont.setStyleHint(QFont::Monospace);
monospaceFont.setPointSizeF(monospaceFont.pointSizeF() * 0.9);
deviceIdValue_ = new QLabel{this};
deviceIdValue_->setTextInteractionFlags(Qt::TextSelectableByMouse);
deviceIdValue_->setFont(monospaceFont);
deviceFingerprintValue_ = new QLabel{this};
deviceFingerprintValue_->setTextInteractionFlags(Qt::TextSelectableByMouse);
deviceFingerprintValue_->setFont(monospaceFont);
deviceFingerprintValue_->setText(utils::humanReadableFingerprint(QString(44, 'X')));
backupSecretCached = new QLabel{this};
masterSecretCached = new QLabel{this};
selfSigningSecretCached = new QLabel{this};
userSigningSecretCached = new QLabel{this};
backupSecretCached->setFont(monospaceFont);
masterSecretCached->setFont(monospaceFont);
selfSigningSecretCached->setFont(monospaceFont);
userSigningSecretCached->setFont(monospaceFont);
auto sessionKeysLabel = new QLabel{tr("Session Keys"), this};
sessionKeysLabel->setFont(font);
sessionKeysLabel->setMargin(OptionMargin);
auto sessionKeysImportBtn = new QPushButton{tr("IMPORT"), this};
auto sessionKeysExportBtn = new QPushButton{tr("EXPORT"), this};
auto sessionKeysLayout = new QHBoxLayout;
sessionKeysLayout->addWidget(new QLabel{"", this}, 1, Qt::AlignRight);
sessionKeysLayout->addWidget(sessionKeysExportBtn, 0, Qt::AlignRight);
sessionKeysLayout->addWidget(sessionKeysImportBtn, 0, Qt::AlignRight);
auto crossSigningKeysLabel = new QLabel{tr("Cross Signing Keys"), this};
crossSigningKeysLabel->setFont(font);
crossSigningKeysLabel->setMargin(OptionMargin);
auto crossSigningRequestBtn = new QPushButton{tr("REQUEST"), this};
auto crossSigningDownloadBtn = new QPushButton{tr("DOWNLOAD"), this};
auto crossSigningKeysLayout = new QHBoxLayout;
crossSigningKeysLayout->addWidget(new QLabel{"", this}, 1, Qt::AlignRight);
crossSigningKeysLayout->addWidget(crossSigningRequestBtn, 0, Qt::AlignRight);
crossSigningKeysLayout->addWidget(crossSigningDownloadBtn, 0, Qt::AlignRight);
auto boxWrap = [this, &font](QString labelText, QWidget *field, QString tooltipText = "") {
label->setFont(font);
label->setMargin(OptionMargin);
if (!tooltipText.isEmpty()) {
label->setToolTip(tooltipText);
}
layout->addWidget(field, 0, Qt::AlignRight);
formLayout_->addRow(label, layout);
};
formLayout_->addRow(general_);
formLayout_->addRow(new HorizontalLine{this});
boxWrap(
tr("Minimize to tray"),
trayToggle_,
tr("Keep the application running in the background after closing the client window."));
boxWrap(tr("Start in tray"),
startInTrayToggle_,
tr("Start the application in the background without showing the client window."));
formLayout_->addRow(new HorizontalLine{this});
boxWrap(tr("Circular Avatars"),
avatarCircles_,
tr("Change the appearance of user avatars in chats.\nOFF - square, ON - Circle."));
boxWrap(tr("Group's sidebar"),
groupViewToggle_,
tr("Show a column containing groups and tags next to the room list."));
boxWrap(tr("Decrypt messages in sidebar"),
decryptSidebar_,
tr("Decrypt the messages shown in the sidebar.\nOnly affects messages in "
"encrypted chats."));
privacyScreen_,
tr("When the window loses focus, the timeline will\nbe blurred."));
tr("Privacy screen timeout (in seconds [0 - 3600])"),
privacyScreenTimeout_,
tr("Set timeout (in seconds) for how long after window loses\nfocus before the screen"
" will be blurred.\nSet to 0 to blur immediately after focus loss. Max value of 1 "
"hour (3600 seconds)"));
boxWrap(tr("Show buttons in timeline"),
timelineButtonsToggle_,
tr("Show buttons to quickly reply, react or access additional options next to each "
"message."));
boxWrap(tr("Limit width of timeline"),
timelineMaxWidthSpin_,
tr("Set the max width of messages in the timeline (in pixels). This can help "
"readability on wide screen, when Nheko is maximised"));
boxWrap(tr("Typing notifications"),
typingNotifications_,
tr("Show who is typing in a room.\nThis will also enable or disable sending typing "
"notifications to others."));
boxWrap(
tr("Sort rooms by unreads"),
sortByImportance_,
tr(
"Display rooms with new messages first.\nIf this is off, the list of rooms will only "
"be sorted by the timestamp of the last message in a room.\nIf this is on, rooms which "
"have active notifications (the small circle with a number in it) will be sorted on "
"top. Rooms, that you have muted, will still be sorted by timestamp, since you don't "
"seem to consider them as important as the other rooms."));
formLayout_->addRow(new HorizontalLine{this});
boxWrap(tr("Read receipts"),
readReceipts_,
tr("Show if your message was read.\nStatus is displayed next to timestamps."));
boxWrap(
tr("Send messages as Markdown"),
tr("Allow using markdown in messages.\nWhen disabled, all messages are sent as a plain "
"text."));
boxWrap(tr("Desktop notifications"),
desktopNotifications_,
tr("Notify about received message when the client is not currently focused."));
boxWrap(tr("Alert on notification"),
alertOnNotification_,
tr("Show an alert when a message is received.\nThis usually causes the application "
"icon in the task bar to animate in some fashion."));
boxWrap(tr("Highlight message on hover"),
messageHoverHighlight_,
tr("Change the background color of messages when you hover over them."));
boxWrap(tr("Large Emoji in timeline"),
enlargeEmojiOnlyMessages_,
tr("Make font size larger if messages with only a few emojis are displayed."));
formLayout_->addRow(new HorizontalLine{this});
boxWrap(tr("Touchscreen mode"),
tr("Will prevent text selection in the timeline to make touch scrolling easier."));
boxWrap(tr("Scale factor"),
scaleFactorCombo_,
tr("Change the scale factor of the whole user interface."));
#else
scaleFactorCombo_->hide();
#endif
boxWrap(tr("Font size"), fontSizeCombo_);
boxWrap(tr("Font Family"), fontSelectionCombo_);
boxWrap(tr("Emoji Font Family"), emojiFontSelectionCombo_);
#else
emojiFontSelectionCombo_->hide();
#endif
boxWrap(tr("Theme"), themeCombo_);
formLayout_->addRow(callsLabel);
formLayout_->addRow(new HorizontalLine{this});
boxWrap(tr("Ringtone"),
ringtoneCombo_,
tr("Set the notification sound to play when a call invite arrives"));
boxWrap(tr("Microphone"), microphoneCombo_);
boxWrap(tr("Camera"), cameraCombo_);
boxWrap(tr("Camera resolution"), cameraResolutionCombo_);
boxWrap(tr("Camera frame rate"), cameraFrameRateCombo_);
ringtoneCombo_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
ringtoneCombo_->addItem("Mute");
ringtoneCombo_->addItem("Default");
ringtoneCombo_->addItem("Other...");
const QString &ringtone = settings_->ringtone();