/*
 * Copyright (C) 2014-2026 CZ.NIC
 *
 * This program is free 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.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#include <QColorDialog>
#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
#include <QString>
#include <QToolTip>

#include "src/common.h"
#include "src/datovka_shared/graphics/colour.h"
#include "src/datovka_shared/localisation/localisation.h"
#include "src/datovka_shared/settings/prefs.h"
#include "src/dimensions/dimensions.h"
#include "src/global.h"
#include "src/gui/dlg_pin_setup.h"
#include "src/gui/dlg_preferences.h"
#include "src/gui/dlg_view_filename_param_list.h"
#include "src/initialisation_gui.h" /* loadAppUiThemeFromValues() */
#include "src/models/message_timestamp_listing_model.h" /* RESTAMPING_INTERVAL_SUGGESTED */
#include "src/settings/prefs_specific.h"
#include "ui_dlg_preferences.h"

#define MSEC_IN_SEC 1000 /* One second in milliseconds. */
#define MSEC_IN_MIN 60000 /* One minute in milliseconds. */

/*!
 * @brief Language order as they are listed in the combo box.
 */
enum LangIndex {
	LANG_SYSTEM = 0,
	LANG_CZECH = 1,
	LANG_ENGLISH = 2
};

DlgPreferences::DlgPreferences(const Prefs &prefs, const PinSettings &pinSett,
    int tabNum, QWidget *parent)
    : QDialog(parent),
    m_ui(new (::std::nothrow) Ui::DlgPreferences),
    m_pinSett(pinSett),
    m_storeMessagesOnDiskOrig(PrefsSpecific::messageDbOnDisk(prefs)),
    m_storeAdditionalDataOnDiskOrig(PrefsSpecific::accountDbOnDisk(prefs)),
    m_paramListDlg(Q_NULLPTR)
{
	m_ui->setupUi(this);
	/* Tab order is defined in UI file. */

	{
		/* Adjust window size according to font size. */
		QSize newSize = Dimensions::windowSize(this, 46.0, 44.0);
		if (newSize.isValid()) {
			resize(newSize);
		}
	}
	initDialogue(prefs);
	activatePinButtons(m_pinSett);

	if ((0 <= tabNum) && (tabNum < MAX_TABNUM)) {
		m_ui->prefWidget->setCurrentIndex(tabNum);
	}
}

DlgPreferences::~DlgPreferences(void)
{
	closeParamListDlg();
	delete m_ui;
}

bool DlgPreferences::modify(Prefs &prefs, PinSettings &pinSett, int tabNum,
    QWidget *parent)
{
	DlgPreferences dlg(prefs, pinSett, tabNum, parent);
	const QString dlgName("preferences");

	const QSize dfltSize = dlg.size();
	{
		const QSize newSize = Dimensions::dialogueSize(&dlg,
		    PrefsSpecific::dlgSize(*GlobInstcs::prefsPtr, dlgName),
		    dfltSize);
		if (newSize.isValid()) {
			dlg.resize(newSize);
		}
	}

	connect(&dlg, SIGNAL(themeChanged(int)), parent, SLOT(changeTheme(int)));

	int ret = dlg.exec();

	PrefsSpecific::setDlgSize(*GlobInstcs::prefsPtr, dlgName,
	    dlg.size(), dfltSize);

	if (QDialog::Accepted == ret) {
		dlg.saveSettings(prefs, pinSett);
		return true;
	}

	/* Reset theme to value stored in preferences. */
	emit dlg.themeChanged(-1);
	return false;
}

void DlgPreferences::activateBackgroundTimer(int checkState)
{
	const bool enable = Qt::Checked == checkState;
	m_ui->timerPreLabel->setEnabled(enable);
	m_ui->timerSpinBox->setEnabled(enable);
	m_ui->timerPostLabel->setEnabled(enable);
}

/*!
 * @brief Notification dialogue.
 *
 * @param[in] parent Parent widget.
 */
static
void showNeededRestartNotification(QWidget *parent = Q_NULLPTR)
{
	QMessageBox::warning(parent, DlgPreferences::tr("Restart Needed"),
	    DlgPreferences::tr(
	        "In order to put this change into action you must restart the application after the new settings have been confirmed."),
	    QMessageBox::Ok, QMessageBox::Ok);
}

void DlgPreferences::storeMessagesOnDiskChanged(int state)
{
	if ((state == Qt::Checked) != m_storeMessagesOnDiskOrig) {
		showNeededRestartNotification(this);
	}
}

void DlgPreferences::storeAdditionalDataOnDiskChanged(int state)
{
	if ((state == Qt::Checked) != m_storeAdditionalDataOnDiskOrig) {
		showNeededRestartNotification(this);
	}
}

void DlgPreferences::setSavePath(void)
{
	QString newDir = QFileDialog::getExistingDirectory(this,
	    tr("Select Directory"), m_ui->savePath->text(),
	    QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);

	if (!newDir.isEmpty()) {
		m_ui->savePath->setText(QDir::toNativeSeparators(newDir));
	}
}

void DlgPreferences::setAddFilePath(void)
{
	QString newDir = QFileDialog::getExistingDirectory(this,
	    tr("Select Directory"), m_ui->addFilePath->text(),
	    QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
	if (!newDir.isEmpty()) {
		m_ui->addFilePath->setText(QDir::toNativeSeparators(newDir));
	}
}

void DlgPreferences::setSaveBackupPath(void)
{
	QString newDir = QFileDialog::getExistingDirectory(this,
	    tr("Select Directory"), m_ui->backupPath->text(),
	    QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);

	if (!newDir.isEmpty()) {
		m_ui->backupPath->setText(QDir::toNativeSeparators(newDir));
	}
}

void DlgPreferences::setPin(void)
{
	if (Q_UNLIKELY(m_pinSett.pinConfigured())) {
		Q_ASSERT(0);
		return;
	}

	DlgPinSetup::change(m_pinSett, this);
	activatePinButtons(m_pinSett);
}

void DlgPreferences::changePin(void)
{
	if (Q_UNLIKELY(!m_pinSett.pinConfigured())) {
		Q_ASSERT(0);
		return;
	}

	DlgPinSetup::change(m_pinSett, this);
	activatePinButtons(m_pinSett);
}

void DlgPreferences::clearPin(void)
{
	if (Q_UNLIKELY(!m_pinSett.pinConfigured())) {
		Q_ASSERT(0);
		return;
	}

	DlgPinSetup::erase(m_pinSett, this);
	activatePinButtons(m_pinSett);
}

/*!
 * @brief Set button colour.
 *
 * @param[in,out] button Button whose colour should be altered.
 * @param[in]     colour Colour sting.
 */
static
void setPreviewButtonColor(QPushButton &button, const QString &colour)
{
	/* This block of code is also used in the tag dialogue. */
	QPalette pal(button.palette());
	pal.setColor(QPalette::Button, QColor("#" + colour));
	const QString style = "border-style: outset; background-color: ";
	button.setStyleSheet(style + "#" + colour);
}

/*!
 * @brief Get button colour.
 * @param[in] button Button whose colour should be read.
 * @return Colour string without leading '#'.
 */
static
QString previewButtonColor(const QPushButton &button)
{
	QPalette pal = button.palette();
	return pal.color(QPalette::Button).name(QColor::HexRgb).toLower().replace("#", QString());
}

void DlgPreferences::setMsgDelColour(void)
{
	QPushButton &button = *(m_ui->messageToBeDeletedColour);

	QColor colour = QColorDialog::getColor(
	    QColor("#" + previewButtonColor(button)),
	    this, tr("Choose a Colour"));

	if (colour.isValid()) {
		QString colourName = colour.name(QColor::HexRgb).toLower().replace("#", QString());
		if (Colour::isValidColourStr(colourName)) {
			setPreviewButtonColor(button, colourName);
		}
	}
}

void DlgPreferences::setApplicationThemeIndex(int index)
{
	/*
	 * Reload entire theme via slot in main window connected to the
	 * emitted themeChanged signal.
	 */
	emit themeChanged(index);
}

void DlgPreferences::setApplicationThemeFontScale(int percent)
{
	loadAppUiThemeFromValues(m_ui->appThemeComboBox->currentIndex(),
	    percent);
}

void DlgPreferences::activateAllAttachDelivInfoFileNameFmt(void)
{
	m_ui->allAttachDelInfoFileNameFmt->setEnabled(
	    m_ui->delInfoForEveryFile->checkState() == Qt::Checked);
}

void DlgPreferences::showParamListDlg(void)
{
	if (m_paramListDlg != Q_NULLPTR) {
		if (!m_paramListDlg->isMinimized()) {
			m_paramListDlg->show();
		} else {
			m_paramListDlg->showNormal();
		}
		m_paramListDlg->raise();
		m_paramListDlg->activateWindow();
		return;
	}

	m_paramListDlg = new (::std::nothrow)
	    DlgViewFilenameParamList(this, Qt::WindowStaysOnTopHint);
	if (Q_UNLIKELY(m_paramListDlg == Q_NULLPTR)) {
		Q_ASSERT(0);
		return;
	}
	m_paramListDlg->show();
}

void DlgPreferences::closeParamListDlg(void)
{
	if (m_paramListDlg != Q_NULLPTR) {
		m_paramListDlg->setAttribute(Qt::WA_DeleteOnClose, true);
		m_paramListDlg->deleteLater();
		m_paramListDlg = Q_NULLPTR;
	}
}

void DlgPreferences::onTabChangedCloseParamListDlg(int index)
{
	if (index != TAB_SAVING) {
		closeParamListDlg();
	}
}

void DlgPreferences::showBuildReportDetail(void)
{
	QToolTip::showText(
	    m_ui->collectBuildReportLabel->mapToGlobal(QPoint(0, 0)),
	    m_ui->collectBuildReportLabel->toolTip());
}

void DlgPreferences::showConfReportDetail(void)
{
	QToolTip::showText(
	    m_ui->collectConfReportLabel->mapToGlobal(QPoint(0, 0)),
	    m_ui->collectConfReportLabel->toolTip());
}

void DlgPreferences::showUsageReportDetail(void)
{
	QToolTip::showText(
	    m_ui->collectUsageReport->mapToGlobal(QPoint(0, 0)),
	    m_ui->collectUsageReport->toolTip());
}

/*!
 * @brief Converts selected language index to language name.
 *
 * @param[in] index Language entry index.
 * @return Language name as used in settings.
 */
static
const char *indexToSettingsLang(int index)
{
	switch (index) {
	case LANG_CZECH:
		return Localisation::langCs;
		break;
	case LANG_ENGLISH:
		return Localisation::langEn;
		break;
	default:
		return Localisation::langSystem;
		break;
	}
}

/*!
 * @brief Converts language name to index.
 *
 * @param[in] lang Language name as used in settings.
 * @return Corresponding index.
 */
static
int settingsLangtoIndex(const QString &lang)
{
	if (Localisation::langCs == lang) {
		return LANG_CZECH;
	} else if (Localisation::langEn == lang) {
		return LANG_ENGLISH;
	} else {
		return LANG_SYSTEM;
	}
}

void DlgPreferences::saveSettings(Prefs &prefs, PinSettings &pinSett) const
{
	/* downloading */
	prefs.setBoolVal(
	    "window.main.action.sync_all_accounts.background.enabled",
	    m_ui->downloadOnBackground->isChecked());
	PrefsSpecific::setBackgroundSyncTimerMinutes(prefs,
	    m_ui->timerSpinBox->value());
	prefs.setBoolVal("action.sync_account.tie.action.download_message",
	    m_ui->autoDownloadWholeMessages->isChecked());
	prefs.setBoolVal("window.main.on.start.tie.action.sync_all_accounts",
	    m_ui->downloadAtStart->isChecked());
	prefs.setBoolVal("action.send_message.tie.action.download_message",
	    m_ui->downloadAfterSending->isChecked());
	prefs.setIntVal("network.isds.communication.timeout.ms",
	    m_ui->timeoutMinSpinBox->value() * MSEC_IN_MIN);
	prefs.setIntVal("window.main.message_list.read.mark_read.timeout.ms",
	    m_ui->timeoutMarkMsgSpinBox->value() * MSEC_IN_SEC);
	PrefsSpecific::setCheckNewVersions(prefs,
	    m_ui->checkNewVersions->isChecked());

	/* security */
	prefs.setBoolVal("storage.database.messages.on_disk.enabled",
	    m_ui->storeMessagesOnDisk->isChecked());
	prefs.setBoolVal("storage.database.accounts.on_disk.enabled",
	    m_ui->storeAdditionalDataOnDisk->isChecked());
	prefs.setIntVal("crypto.message.validation.date.type",
	    m_ui->certValidationDateNow->isChecked() ?
	        PrefsSpecific::CURRENT_DATE : PrefsSpecific::DOWNLOAD_DATE);
	prefs.setBoolVal("crypto.crl.check.enabled",
	    m_ui->checkCrl->isChecked());
	prefs.setIntVal("crypto.message.timestamp.expiration.notify_ahead.days",
	    m_ui->timestampExpirSpinBox->value());
	prefs.setBoolVal("action.download_message.received.tie.action.track_timestamp_expiration.enabled",
	    m_ui->timestampTrackReceivedCheckBox->isChecked());
	prefs.setBoolVal("action.download_message.sent.tie.action.track_timestamp_expiration.enabled",
	    m_ui->timestampTrackSentCheckBox->isChecked());
	pinSett = m_pinSett;

	/* navigation */
	{
		int val = PrefsSpecific::SELECT_NOTHING;
		if (m_ui->afterStartSelectNewest->isChecked()) {
			val = PrefsSpecific::SELECT_NEWEST;
		} else if (m_ui->afterStartSelectLast->isChecked()) {
			val = PrefsSpecific::SELECT_LAST_VISITED;
		} else {
			val = PrefsSpecific::SELECT_NOTHING;
		}
		prefs.setIntVal(
		    "window.main.message_list.select.on.account_change", val);
	}

	/* interface */
	{
		prefs.setIntVal(
		    "application.ui.theme",
		    m_ui->appThemeComboBox->currentIndex());
		prefs.setIntVal(
		    "application.ui.theme.custom.font_scale.percent",
		    m_ui->fontScaleSpinBox->value());
		prefs.setIntVal(
		    "window.main.message.isds_deletion.notify_ahead.days",
		    m_ui->messageToBeDeletedSpinBox->value());
		prefs.setColourVal(
		    "window.main.message.isds_deletion.notify_ahead.colour",
		    previewButtonColor(*(m_ui->messageToBeDeletedColour)));
	}

	/* directories */
	PrefsSpecific::setUseGlobalPaths(prefs,
	    m_ui->enableGlobalPaths->isChecked());
	PrefsSpecific::setSaveAttachDir(prefs,
	    QDir::fromNativeSeparators(m_ui->savePath->text()));
	PrefsSpecific::setLoadAttachDir(prefs,
	    QDir::fromNativeSeparators(m_ui->addFilePath->text()));

	/* saving */
	prefs.setBoolVal(
	    "action.save_all_attachments.tie.action.export_message_zfo",
	    m_ui->allAttachmentsSaveZfoMsg->isChecked());
	prefs.setBoolVal(
	    "action.save_all_attachments.tie.action.export_acceptance_info_zfo",
	    m_ui->allAttachmentsSaveZfoDelInfo->isChecked());
	prefs.setBoolVal(
	    "action.save_all_attachments.tie.action.export_envelope_pdf",
	    m_ui->allAttachmentsSavePdfMsgEnvel->isChecked());
	prefs.setBoolVal(
	    "action.save_all_attachments.tie.action.export_acceptance_info_pdf",
	    m_ui->allAttachmentsSavePdfDelInfo->isChecked());
	prefs.setStrVal("file_system.format.filename.message",
	    m_ui->msgFileNameFmt->text());
	prefs.setStrVal("file_system.format.filename.acceptance_info",
	    m_ui->delInfoFileNameFmt->text());
	prefs.setStrVal("file_system.format.filename.attachment",
	    m_ui->attachFileNameFmt->text());
	prefs.setBoolVal(
	    "action.save_all_attachments.every_attachment.export_acceptance_info",
	    m_ui->delInfoForEveryFile->isChecked());
	prefs.setStrVal(
	    "file_system.format.filename.every_attachment_acceptance_info",
	    m_ui->allAttachDelInfoFileNameFmt->text());

	/* backups */
	PrefsSpecific::setAutoBackupEnabled(prefs,
	    m_ui->enableBackupNotifications->isChecked());
	PrefsSpecific::setAutoBackupPath(prefs,
	    QDir::fromNativeSeparators(m_ui->backupPath->text()));
	PrefsSpecific::setAutoBackupPeriodMonths(prefs,
	    m_ui->backupMonthIntervalSpinBox->value());

	/* language */
	prefs.setStrVal("translation.language",
	    indexToSettingsLang(m_ui->langComboBox->currentIndex()));

	/* data collection */
	PrefsSpecific::setStatsReportUsage(prefs, m_ui->collectUsageReport->isChecked());
}

void DlgPreferences::initDialogue(const Prefs &prefs)
{
	/* downloading */
	{
		bool val = false;
		if (prefs.boolVal(
		        "window.main.action.sync_all_accounts.background.enabled",
		        val)) {
			m_ui->downloadOnBackground->setChecked(val);
		}
	}
	m_ui->timerSpinBox->setValue(
	    PrefsSpecific::backgroundSyncTimerMinutes(prefs));
	{
		bool val = false;
		if (prefs.boolVal(
		        "action.sync_account.tie.action.download_message",
		        val)) {
			m_ui->autoDownloadWholeMessages->setChecked(val);
		}
	}
	{
		bool val = false;
		if (prefs.boolVal(
		        "window.main.on.start.tie.action.sync_all_accounts",
		        val)) {
			m_ui->downloadAtStart->setChecked(val);
		}
	}
	{
		bool val = false;
		if (prefs.boolVal("action.send_message.tie.action.download_message", val)) {
			m_ui->downloadAfterSending->setChecked(val);
		}
	}
	{
		qint64 val = 0;
		if (prefs.intVal("network.isds.communication.timeout.ms",
		        val)) {
			m_ui->timeoutMinSpinBox->setValue(val / MSEC_IN_MIN);
		}
	}
	m_ui->labelTimeoutNote->setText(tr(
	    "Note: If you have a slow network connection or you cannot download complete messages, here you can increase the connection timeout. "
	    "Default value is %n minute(s). Use 0 to disable the timeout limit (not recommended).",
	    "", ISDS_DOWNLOAD_TIMEOUT_MS / MSEC_IN_MIN));
	{
		qint64 val = 0;
		if (prefs.intVal(
		        "window.main.message_list.read.mark_read.timeout.ms",
		        val)) {
			m_ui->timeoutMarkMsgSpinBox->setValue(val / MSEC_IN_SEC);
		}
	}
	m_ui->noteMarkMsgLabel->setText(tr(
	    "Note: A marked unread message will be marked as read after the set interval. "
	    "Default value is %n second(s). Use -1 to disable the function.",
	    "", TIMER_MARK_MSG_READ_MS / MSEC_IN_SEC));
	m_ui->checkNewVersions->setChecked(
	    PrefsSpecific::checkNewVersions(prefs));
	m_ui->checkNewVersions->setEnabled(
	    PrefsSpecific::canConfigureCheckNewVersions());
	/* TODO - this choice must be disabled */
//	m_ui->sendStatsWithVersionChecks->setChecked(
//	    PrefsSpecific::sendStatsWithVersionChecks(prefs));
//	m_ui->sendStatsWithVersionChecks->setEnabled(
//	    m_ui->checkNewVersions->isChecked());

	connect(m_ui->downloadOnBackground, SIGNAL(stateChanged(int)),
	    this, SLOT(activateBackgroundTimer(int)));

	activateBackgroundTimer(m_ui->downloadOnBackground->checkState());

	/* security */
	{
		bool val = false;
		if (prefs.boolVal("storage.database.messages.on_disk.enabled",
		        val)) {
			m_ui->storeMessagesOnDisk->setChecked(val);
		}
	}
	{
		bool val = false;
		if (prefs.boolVal("storage.database.accounts.on_disk.enabled",
		        val)) {
			m_ui->storeAdditionalDataOnDisk->setChecked(val);
		}
	}
	{
		m_ui->certValidationDateNow->setChecked(false);
		m_ui->certValidationDateDownload->setChecked(false);
		qint64 val = PrefsSpecific::DOWNLOAD_DATE;
		if (prefs.intVal("crypto.message.validation.date.type", val)) {
			switch (val) {
			case PrefsSpecific::CURRENT_DATE:
				m_ui->certValidationDateNow->setChecked(true);
				break;
			case PrefsSpecific::DOWNLOAD_DATE:
				m_ui->certValidationDateDownload->setChecked(true);
				break;
			default:
				Q_ASSERT(0);
				break;
			}
		}
	}
	{
		bool val = false;
		if (prefs.boolVal("crypto.crl.check.enabled", val)) {
			m_ui->checkCrl->setChecked(val);
		}
	}
	{
		m_ui->timestampExpirSpinBox->setMinimum(1);
		m_ui->timestampExpirSpinBox->setMaximum(RESTAMPING_INTERVAL_SUGGESTED);
		qint64 val = 0;
		if (prefs.intVal(
		    "crypto.message.timestamp.expiration.notify_ahead.days",
		    val)) {
			m_ui->timestampExpirSpinBox->setValue(val);
		}
	}
	{
		bool val = false;
		if (prefs.boolVal("action.download_message.received.tie.action.track_timestamp_expiration.enabled", val)) {
			m_ui->timestampTrackReceivedCheckBox->setChecked(val);
		}
	}
	{
		bool val = false;
		if (prefs.boolVal("action.download_message.sent.tie.action.track_timestamp_expiration.enabled", val)) {
			m_ui->timestampTrackSentCheckBox->setChecked(val);
		}
	}

	connect(m_ui->storeMessagesOnDisk, SIGNAL(stateChanged(int)),
	    this, SLOT(storeMessagesOnDiskChanged(int)));
	connect(m_ui->storeAdditionalDataOnDisk, SIGNAL(stateChanged(int)),
	    this, SLOT(storeAdditionalDataOnDiskChanged(int)));

	connect(m_ui->setPinButton, SIGNAL(clicked()), this, SLOT(setPin()));
	connect(m_ui->changePinButton, SIGNAL(clicked()),
	    this, SLOT(changePin()));
	connect(m_ui->clearPinButton, SIGNAL(clicked()),
	    this, SLOT(clearPin()));

	/* navigation */
	{
		m_ui->afterStartSelectNewest->setChecked(false);
		m_ui->afterStartSelectLast->setChecked(false);
		m_ui->afterStartSelectNothing->setChecked(false);
		qint64 val = PrefsSpecific::SELECT_NOTHING;
		if (prefs.intVal(
		        "window.main.message_list.select.on.account_change",
		        val)) {
			switch (val) {
			case PrefsSpecific::SELECT_NEWEST:
				m_ui->afterStartSelectNewest->setChecked(true);
				break;
			case PrefsSpecific::SELECT_LAST_VISITED:
				m_ui->afterStartSelectLast->setChecked(true);
				break;
			case PrefsSpecific::SELECT_NOTHING:
				m_ui->afterStartSelectNothing->setChecked(true);
				break;
			default:
				Q_ASSERT(0);
				break;
			}
		}
	}

	/* interface */
	{
		qint64 days = 0;
		QString colour;
		if (prefs.intVal(
		        "window.main.message.isds_deletion.notify_ahead.days",
		        days)) {
			if (days >= 0) {
				m_ui->messageToBeDeletedSpinBox->setValue(days);
			}
		}
		if (prefs.colourVal(
		        "window.main.message.isds_deletion.notify_ahead.colour",
		        colour)) {
			if (!colour.isEmpty()) {
				setPreviewButtonColor(
				     *(m_ui->messageToBeDeletedColour),
				     colour);
			}
		}
	}

	m_ui->labelToBeDeletedHighlightNote->setText(tr(
	    "Note: Messages to be deleted from the ISDS within the specified period are going to be highlighted using the set colour in the message listing. "
	    "Use 0 to disable the function."));

	m_ui->messageToBeDeletedColour->setEnabled(false);
	connect(m_ui->changeMessageToBeDeletedColourButton, SIGNAL(clicked()),
	    this, SLOT(setMsgDelColour()));

#if defined(Q_OS_MACOS)
	m_ui->appThemeComboBox->addItem(tr("Default"));
	m_ui->appThemeComboBox->addItem(tr("Custom"));
#else /* !defined(Q_OS_MACOS) */
	m_ui->appThemeComboBox->addItem(tr("Default"));
	m_ui->appThemeComboBox->addItem(tr("Light"));
	m_ui->appThemeComboBox->addItem(tr("Dark"));
#endif /* defined(Q_OS_MACOS) */

	connect(m_ui->appThemeComboBox, SIGNAL(currentIndexChanged(int)),
	    this, SLOT(setApplicationThemeIndex(int)));

	m_ui->appThemeComboBox->setCurrentIndex(
	    PrefsSpecific::appUiTheme(*GlobInstcs::prefsPtr));

	connect(m_ui->fontScaleSpinBox, SIGNAL(valueChanged(int)),
	    this, SLOT(setApplicationThemeFontScale(int)));

	m_ui->fontScaleSpinBox->setValue(
	    PrefsSpecific::appUiThemeFontScalePercent(*GlobInstcs::prefsPtr));

	/* directories */
	m_ui->enableGlobalPaths->setChecked(
	    PrefsSpecific::useGlobalPaths(prefs));
	m_ui->savePath->setText(
	    QDir::toNativeSeparators(PrefsSpecific::saveAttachDir(prefs)));
	m_ui->addFilePath->setText(
	    QDir::toNativeSeparators(PrefsSpecific::loadAttachDir(prefs)));

	connect(m_ui->savePathPushButton, SIGNAL(clicked()),
	    this, SLOT(setSavePath()));
	connect(m_ui->addFilePathPushButton, SIGNAL(clicked()),
	    this, SLOT(setAddFilePath()));

	/* saving */
	{
		bool val = false;
		if (prefs.boolVal(
		        "action.save_all_attachments.tie.action.export_message_zfo",
		        val)) {
			m_ui->allAttachmentsSaveZfoMsg->setChecked(val);
		}
	}
	{
		bool val = false;
		if (prefs.boolVal(
		        "action.save_all_attachments.tie.action.export_acceptance_info_zfo",
		        val)) {
			m_ui->allAttachmentsSaveZfoDelInfo->setChecked(val);
		}
	}
	{
		bool val = false;
		if (prefs.boolVal(
		        "action.save_all_attachments.tie.action.export_envelope_pdf",
		        val)) {
			m_ui->allAttachmentsSavePdfMsgEnvel->setChecked(val);
		}
	}
	{
		bool val = false;
		if (prefs.boolVal(
		        "action.save_all_attachments.tie.action.export_acceptance_info_pdf",
		        val)) {
			m_ui->allAttachmentsSavePdfDelInfo->setChecked(val);
		}
	}
	{
		QString val;
		if (prefs.strVal("file_system.format.filename.message", val)) {
			if (!val.isEmpty()) {
				m_ui->msgFileNameFmt->setText(val);
			}
		}
	}
	{
		QString val;
		if (prefs.strVal("file_system.format.filename.acceptance_info",
		        val)) {
			if (!val.isEmpty()) {
				m_ui->delInfoFileNameFmt->setText(val);
			}
		}
	}
	{
		QString val;
		if (prefs.strVal("file_system.format.filename.attachment",
		        val)) {
			if (!val.isEmpty()) {
				m_ui->attachFileNameFmt->setText(val);
			}
		}
	}
	{
		bool val = false;
		if (prefs.boolVal(
		        "action.save_all_attachments.every_attachment.export_acceptance_info",
		        val)) {
			m_ui->delInfoForEveryFile->setChecked(val);
		}
		m_ui->allAttachDelInfoFileNameFmt->setEnabled(val);
		connect(m_ui->delInfoForEveryFile, SIGNAL(clicked()),
		    this, SLOT(activateAllAttachDelivInfoFileNameFmt()));
	}
	{
		QString val;
		if (prefs.strVal(
		        "file_system.format.filename.every_attachment_acceptance_info",
		        val)) {
			m_ui->allAttachDelInfoFileNameFmt->setText(val);
		}
		connect(m_ui->showParamListButton, SIGNAL(clicked()),
		    this, SLOT(showParamListDlg()));
		connect(m_ui->closeParamListButton, SIGNAL(clicked()),
		    this, SLOT(closeParamListDlg()));
	}

	/* backups */
	m_ui->enableBackupNotifications->setChecked(
	    PrefsSpecific::autoBackupEnabled(prefs));
	m_ui->backupMonthIntervalSpinBox->setValue(
	    PrefsSpecific::autoBackupPeriodMonths(prefs));
	m_ui->backupPath->setText(
	    QDir::toNativeSeparators(PrefsSpecific::autoBackupPath(prefs)));
	connect(m_ui->backupPathPushButton, SIGNAL(clicked()),
	    this, SLOT(setSaveBackupPath()));

	/* language */
	m_ui->langComboBox->addItem(tr("Use system language"));
	m_ui->langComboBox->addItem(tr("Czech"));
	m_ui->langComboBox->addItem(tr("English"));
	{
		QString val;
		if (prefs.strVal("translation.language", val)) {
			m_ui->langComboBox->setCurrentIndex(
			    settingsLangtoIndex(val));
		}
	}

	/* data collection*/
	m_ui->collectUsageReport->setChecked(PrefsSpecific::statsReportUsage(prefs));

	/* Set detail tool tips. */
	m_ui->buildReportToolButton->setToolTip(m_ui->collectBuildReportLabel->toolTip());
	m_ui->confReportToolButton->setToolTip(m_ui->collectConfReportLabel->toolTip());
	m_ui->usageReportToolButton->setToolTip(m_ui->collectUsageReport->toolTip());

	connect(m_ui->buildReportToolButton, SIGNAL(clicked()),
	    this, SLOT(showBuildReportDetail()));
	connect(m_ui->confReportToolButton, SIGNAL(clicked()),
	    this, SLOT(showConfReportDetail()));
	connect(m_ui->usageReportToolButton, SIGNAL(clicked()),
	    this, SLOT(showUsageReportDetail()));

	connect(m_ui->prefWidget, SIGNAL(currentChanged(int)),
	    this, SLOT(onTabChangedCloseParamListDlg(int)));
}

void DlgPreferences::activatePinButtons(const PinSettings &pinSett)
{
	m_ui->setPinButton->setEnabled(!pinSett.pinConfigured());
	m_ui->setPinButton->setVisible(!pinSett.pinConfigured());
	m_ui->changePinButton->setEnabled(pinSett.pinConfigured());
	m_ui->changePinButton->setVisible(pinSett.pinConfigured());
	m_ui->clearPinButton->setEnabled(pinSett.pinConfigured());
	m_ui->clearPinButton->setVisible(pinSett.pinConfigured());
}
