1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00
qTox/src/widget/form/settings/userinterfaceform.cpp

350 lines
11 KiB
C++

/*
Copyright © 2014-2016 by The qTox Project Contributors
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
qTox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with qTox. If not, see <http://www.gnu.org/licenses/>.
*/
#include "userinterfaceform.h"
#include "ui_userinterfacesettings.h"
#include <QDebug>
#include <QDesktopWidget>
#include <QFileDialog>
#include <QFont>
#include <QMessageBox>
#include <QRegularExpressionValidator>
#include <QStandardPaths>
#include <QStyleFactory>
#include <QTime>
#include <QVector>
#include "src/core/core.h"
#include "src/core/coreav.h"
#include "src/core/recursivesignalblocker.h"
#include "src/net/autoupdate.h"
#include "src/nexus.h"
#include "src/persistence/profile.h"
#include "src/persistence/settings.h"
#include "src/persistence/smileypack.h"
#include "src/widget/form/settingswidget.h"
#include "src/widget/style.h"
#include "src/widget/translator.h"
#include "src/widget/widget.h"
/**
* @class UserInterfaceForm
*
* This form contains all settings which change the UI appearance or behaviour.
* It also contains the smiley configuration.
*/
/**
* @brief Constructor of UserInterfaceForm.
* @param myParent Setting widget which will contain this form as tab.
*
* Restores all controls from the settings.
*/
UserInterfaceForm::UserInterfaceForm(SettingsWidget* myParent)
: GenericForm(QPixmap(":/img/settings/general.png"))
{
parent = myParent;
bodyUI = new Ui::UserInterfaceSettings;
bodyUI->setupUi(this);
// block all child signals during initialization
const RecursiveSignalBlocker signalBlocker(this);
Settings& s = Settings::getInstance();
const QFont chatBaseFont = s.getChatMessageFont();
bodyUI->txtChatFontSize->setValue(QFontInfo(chatBaseFont).pixelSize());
bodyUI->txtChatFont->setCurrentFont(chatBaseFont);
int index = static_cast<int>(s.getStylePreference());
bodyUI->textStyleComboBox->setCurrentIndex(index);
bool showWindow = s.getShowWindow();
bodyUI->showWindow->setChecked(showWindow);
bodyUI->showInFront->setChecked(s.getShowInFront());
bodyUI->showInFront->setEnabled(showWindow);
bodyUI->groupAlwaysNotify->setChecked(s.getGroupAlwaysNotify());
bodyUI->cbGroupchatPosition->setChecked(s.getGroupchatPosition());
bodyUI->cbCompactLayout->setChecked(s.getCompactLayout());
bodyUI->cbSeparateWindow->setChecked(s.getSeparateWindow());
bodyUI->cbDontGroupWindows->setChecked(s.getDontGroupWindows());
bodyUI->cbDontGroupWindows->setEnabled(s.getSeparateWindow());
bodyUI->useEmoticons->setChecked(s.getUseEmoticons());
for (auto entry : SmileyPack::listSmileyPacks())
bodyUI->smileyPackBrowser->addItem(entry.first, entry.second);
smileLabels = {bodyUI->smile1, bodyUI->smile2, bodyUI->smile3, bodyUI->smile4, bodyUI->smile5};
int currentPack = bodyUI->smileyPackBrowser->findData(s.getSmileyPack());
bodyUI->smileyPackBrowser->setCurrentIndex(currentPack);
reloadSmileys();
bodyUI->smileyPackBrowser->setEnabled(bodyUI->useEmoticons->isChecked());
bodyUI->styleBrowser->addItem(tr("None"));
bodyUI->styleBrowser->addItems(QStyleFactory::keys());
QString style;
if (QStyleFactory::keys().contains(s.getStyle()))
style = s.getStyle();
else
style = tr("None");
bodyUI->styleBrowser->setCurrentText(style);
for (QString color : Style::getThemeColorNames())
bodyUI->themeColorCBox->addItem(color);
bodyUI->themeColorCBox->setCurrentIndex(s.getThemeColor());
bodyUI->emoticonSize->setValue(s.getEmojiFontPointSize());
QLocale ql;
QStringList timeFormats;
timeFormats << ql.timeFormat(QLocale::ShortFormat) << ql.timeFormat(QLocale::LongFormat)
<< "hh:mm AP"
<< "hh:mm:ss AP"
<< "hh:mm:ss";
timeFormats.removeDuplicates();
bodyUI->timestamp->addItems(timeFormats);
QRegularExpression re(QString("^[^\\n]{0,%0}$").arg(MAX_FORMAT_LENGTH));
QRegularExpressionValidator* validator = new QRegularExpressionValidator(re, this);
QString timeFormat = s.getTimestampFormat();
if (!re.match(timeFormat).hasMatch())
timeFormat = timeFormats[0];
bodyUI->timestamp->setCurrentText(timeFormat);
bodyUI->timestamp->setValidator(validator);
on_timestamp_editTextChanged(timeFormat);
QStringList dateFormats;
dateFormats << QStringLiteral("yyyy-MM-dd") // ISO 8601
// format strings from system locale
<< ql.dateFormat(QLocale::LongFormat) << ql.dateFormat(QLocale::ShortFormat)
<< ql.dateFormat(QLocale::NarrowFormat) << "dd-MM-yyyy"
<< "d-MM-yyyy"
<< "dddd dd-MM-yyyy"
<< "dddd d-MM";
dateFormats.removeDuplicates();
bodyUI->dateFormats->addItems(dateFormats);
QString dateFormat = s.getDateFormat();
if (!re.match(dateFormat).hasMatch())
dateFormat = dateFormats[0];
bodyUI->dateFormats->setCurrentText(dateFormat);
bodyUI->dateFormats->setValidator(validator);
on_dateFormats_editTextChanged(dateFormat);
eventsInit();
Translator::registerHandler(std::bind(&UserInterfaceForm::retranslateUi, this), this);
}
UserInterfaceForm::~UserInterfaceForm()
{
Translator::unregister(this);
delete bodyUI;
}
void UserInterfaceForm::on_styleBrowser_currentIndexChanged(QString style)
{
if (bodyUI->styleBrowser->currentIndex() == 0)
Settings::getInstance().setStyle("None");
else
Settings::getInstance().setStyle(style);
this->setStyle(QStyleFactory::create(style));
parent->setBodyHeadStyle(style);
}
void UserInterfaceForm::on_emoticonSize_editingFinished()
{
Settings::getInstance().setEmojiFontPointSize(bodyUI->emoticonSize->value());
}
void UserInterfaceForm::on_timestamp_editTextChanged(const QString& format)
{
QString timeExample = QTime::currentTime().toString(format);
bodyUI->timeExample->setText(timeExample);
Settings::getInstance().setTimestampFormat(format);
Translator::translate();
}
void UserInterfaceForm::on_dateFormats_editTextChanged(const QString& format)
{
QString dateExample = QDate::currentDate().toString(format);
bodyUI->dateExample->setText(dateExample);
Settings::getInstance().setDateFormat(format);
Translator::translate();
}
void UserInterfaceForm::on_useEmoticons_stateChanged()
{
Settings::getInstance().setUseEmoticons(bodyUI->useEmoticons->isChecked());
bodyUI->smileyPackBrowser->setEnabled(bodyUI->useEmoticons->isChecked());
}
void UserInterfaceForm::on_textStyleComboBox_currentTextChanged()
{
Settings::StyleType styleType =
static_cast<Settings::StyleType>(bodyUI->textStyleComboBox->currentIndex());
Settings::getInstance().setStylePreference(styleType);
}
void UserInterfaceForm::on_smileyPackBrowser_currentIndexChanged(int index)
{
QString filename = bodyUI->smileyPackBrowser->itemData(index).toString();
Settings::getInstance().setSmileyPack(filename);
reloadSmileys();
}
/**
* @brief Reload smileys and size information.
*/
void UserInterfaceForm::reloadSmileys()
{
QList<QStringList> emoticons = SmileyPack::getInstance().getEmoticons();
// sometimes there are no emoticons available, don't crash in this case
if (emoticons.isEmpty()) {
qDebug() << "reloadSmilies: No emoticons found";
return;
}
QStringList smileys;
for (int i = 0; i < emoticons.size(); ++i)
smileys.push_front(emoticons.at(i).first());
const QSize size(18, 18);
for (int i = 0; i < smileLabels.size(); ++i) {
QIcon icon = SmileyPack::getInstance().getAsIcon(smileys[i]);
smileLabels[i]->setPixmap(icon.pixmap(size));
smileLabels[i]->setToolTip(smileys[i]);
}
// set maximum size of emoji
QDesktopWidget desktop;
// 8 is the count of row and column in emoji's in widget
const int sideSize = 8;
int maxSide = qMin(desktop.geometry().height() / sideSize, desktop.geometry().width() / sideSize);
QSize maxSize(maxSide, maxSide);
QIcon icon = SmileyPack::getInstance().getAsIcon(smileys[0]);
QSize actualSize = icon.actualSize(maxSize);
bodyUI->emoticonSize->setMaximum(actualSize.width());
}
void UserInterfaceForm::on_showWindow_stateChanged()
{
bool isChecked = bodyUI->showWindow->isChecked();
Settings::getInstance().setShowWindow(isChecked);
bodyUI->showInFront->setEnabled(isChecked);
}
void UserInterfaceForm::on_showInFront_stateChanged()
{
Settings::getInstance().setShowInFront(bodyUI->showInFront->isChecked());
}
void UserInterfaceForm::on_groupAlwaysNotify_stateChanged()
{
Settings::getInstance().setGroupAlwaysNotify(bodyUI->groupAlwaysNotify->isChecked());
}
void UserInterfaceForm::on_cbCompactLayout_stateChanged()
{
Settings::getInstance().setCompactLayout(bodyUI->cbCompactLayout->isChecked());
}
void UserInterfaceForm::on_cbSeparateWindow_stateChanged()
{
bool checked = bodyUI->cbSeparateWindow->isChecked();
bodyUI->cbDontGroupWindows->setEnabled(checked);
Settings::getInstance().setSeparateWindow(checked);
}
void UserInterfaceForm::on_cbDontGroupWindows_stateChanged()
{
Settings::getInstance().setDontGroupWindows(bodyUI->cbDontGroupWindows->isChecked());
}
void UserInterfaceForm::on_cbGroupchatPosition_stateChanged()
{
Settings::getInstance().setGroupchatPosition(bodyUI->cbGroupchatPosition->isChecked());
}
void UserInterfaceForm::on_themeColorCBox_currentIndexChanged(int)
{
int index = bodyUI->themeColorCBox->currentIndex();
Settings::getInstance().setThemeColor(index);
Style::setThemeColor(index);
Style::applyTheme();
}
/**
* @brief Retranslate all elements in the form.
*/
void UserInterfaceForm::retranslateUi()
{
// Block signals during translation to prevent settings change
RecursiveSignalBlocker signalBlocker{this};
bodyUI->retranslateUi(this);
// Restore text style index once translation is complete
bodyUI->textStyleComboBox->setCurrentIndex(
static_cast<int>(Settings::getInstance().getStylePreference()));
QStringList colorThemes(Style::getThemeColorNames());
for (int i = 0; i < colorThemes.size(); ++i) {
bodyUI->themeColorCBox->setItemText(i, colorThemes[i]);
}
bodyUI->styleBrowser->setItemText(0, tr("None"));
}
void UserInterfaceForm::on_txtChatFont_currentFontChanged(const QFont& f)
{
QFont tmpFont = f;
const int px = bodyUI->txtChatFontSize->value();
if (QFontInfo(tmpFont).pixelSize() != px)
tmpFont.setPixelSize(px);
Settings::getInstance().setChatMessageFont(tmpFont);
}
void UserInterfaceForm::on_txtChatFontSize_valueChanged(int px)
{
Settings& s = Settings::getInstance();
QFont tmpFont = s.getChatMessageFont();
const int fontSize = QFontInfo(tmpFont).pixelSize();
if (px != fontSize) {
tmpFont.setPixelSize(px);
s.setChatMessageFont(tmpFont);
}
}