Revision control
++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++ #include <QtVirtualKeyboard/private/settings_p.h>
++ #include <QtCore/private/qobject_p.h>
++ #include <QStandardPaths>
++ #include <QFileInfo>
++ #include <QDir>
++ #include "virtualkeyboarddebug_p.h"
++
++ QT_BEGIN_NAMESPACE
++ namespace QtVirtualKeyboard {
++
++ using namespace Qt::StringLiterals;
++
++ class SettingsPrivate : public QObjectPrivate
++ {
++ public:
++ SettingsPrivate() :
++ QObjectPrivate(),
++ style(),
++ styleName(),
++ locale(),
++ availableLocales(),
++ activeLocales(),
++ layoutPath(),
++ wclAutoHideDelay(defaultWclAutoHideDelay),
++ wclAlwaysVisible(false),
++ wclAutoCommitWord(false),
++ fullScreenMode(false),
++ userDataPath(defaultUserDataPath()),
++ hwrTimeoutForAlphabetic(defaultHwrTimeoutForAlphabetic),
++ hwrTimeoutForCjk(defaultHwrTimeoutForCjk),
++ handwritingModeDisabled(false),
++ defaultInputMethodDisabled(false),
++ defaultDictionaryDisabled(false),
++ visibleFunctionKeys(QtVirtualKeyboard::KeyboardFunctionKey::All),
++ closeOnReturn(false),
++ keySoundVolume(1.0),
++ #ifdef QT_VIRTUALKEYBOARD_ARROW_KEY_NAVIGATION
++ arrowKeyNavigationEnabled(true)
++ #else
++ arrowKeyNavigationEnabled(false)
++ #endif
++ {
++ ensureUserDataPathExists();
++ }
++
++ void ensureUserDataPathExists() const
++ {
++ if (!userDataPath.isEmpty() && !QFileInfo::exists(userDataPath)) {
++ if (!QDir::root().mkpath(userDataPath)) {
++ VIRTUALKEYBOARD_WARN() << "Cannot create directory for user data" << userDataPath;
++ }
++ }
++ }
++
++ static QString defaultUserDataPath()
++ {
++ static const QString path = u"%1/qtvirtualkeyboard"_s
++ .arg(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation));
++ return path;
++ }
++
++ QString style;
++ QString styleName;
++ QString locale;
++ QStringList availableLocales;
++ QStringList activeLocales;
++ QUrl layoutPath;
++ int wclAutoHideDelay;
++ bool wclAlwaysVisible;
++ bool wclAutoCommitWord;
++ bool fullScreenMode;
++ QString userDataPath;
++ int hwrTimeoutForAlphabetic;
++ int hwrTimeoutForCjk;
++ Qt::InputMethodHints inputMethodHints;
++ bool handwritingModeDisabled;
++ bool defaultInputMethodDisabled;
++ bool defaultDictionaryDisabled;
++ QtVirtualKeyboard::KeyboardFunctionKeys visibleFunctionKeys;
++ bool closeOnReturn;
++ qreal keySoundVolume;
++ bool arrowKeyNavigationEnabled;
++ QString screenName;
++
++ static const int defaultWclAutoHideDelay = 5000;
++ static const int defaultHwrTimeoutForAlphabetic = 500;
++ static const int defaultHwrTimeoutForCjk = 500;
++ };
++
++ static QScopedPointer<Settings> s_settingsInstance;
++
++ /*!
++ \class QtVirtualKeyboard::Settings
++ \internal
++ */
++
++ Settings::Settings(QObject *parent) :
++ QObject(*new SettingsPrivate(), parent)
++ {
++ resetLayoutPath();
++ }
++
++ Settings *Settings::instance()
++ {
++ if (!s_settingsInstance)
++ s_settingsInstance.reset(new Settings());
++ return s_settingsInstance.data();
++ }
++
++ QString Settings::style() const
++ {
++ Q_D(const Settings);
++ return d->style;
++ }
++
++ void Settings::setStyle(const QString &style)
++ {
++ Q_D(Settings);
++ if (d->style != style) {
++ d->style = style;
++ emit styleChanged();
++ }
++ }
++
++ QString Settings::styleName() const
++ {
++ Q_D(const Settings);
++ return d->styleName;
++ }
++
++ void Settings::setStyleName(const QString &styleName)
++ {
++ Q_D(Settings);
++ if (d->styleName != styleName) {
++ d->styleName = styleName;
++ emit styleNameChanged();
++ }
++ }
++
++ void Settings::resetStyleName()
++ {
++ emit requestResetStyle();
++ }
++
++ QString Settings::locale() const
++ {
++ Q_D(const Settings);
++ return d->locale;
++ }
++
++ void Settings::setLocale(const QString &locale)
++ {
++ Q_D(Settings);
++ if (d->locale != locale) {
++ d->locale = locale;
++ emit localeChanged();
++ }
++ }
++
++ void Settings::resetLocale()
++ {
++ setLocale(QString());
++ }
++
++ QStringList Settings::availableLocales() const
++ {
++ Q_D(const Settings);
++ return d->availableLocales;
++ }
++
++ void Settings::setAvailableLocales(const QStringList &availableLocales)
++ {
++ Q_D(Settings);
++ if (d->availableLocales != availableLocales) {
++ d->availableLocales = availableLocales;
++ emit availableLocalesChanged();
++ }
++ }
++
++ QStringList Settings::activeLocales() const
++ {
++ Q_D(const Settings);
++ return d->activeLocales;
++ }
++
++ void Settings::setActiveLocales(const QStringList &activeLocales)
++ {
++ Q_D(Settings);
++ if (d->activeLocales != activeLocales) {
++ d->activeLocales = activeLocales;
++ emit activeLocalesChanged();
++ }
++ }
++
++ void Settings::resetActiveLocales()
++ {
++ setActiveLocales(QStringList());
++ }
++
++ QUrl Settings::layoutPath() const
++ {
++ Q_D(const Settings);
++ return d->layoutPath;
++ }
++
++ void Settings::setLayoutPath(const QUrl &layoutPath)
++ {
++ Q_D(Settings);
++ if (d->layoutPath != layoutPath) {
++ d->layoutPath = layoutPath;
++ emit layoutPathChanged();
++ }
++ }
++
++ void Settings::resetLayoutPath()
++ {
++ QUrl newLayoutPath(QLatin1String(QT_VIRTUALKEYBOARD_DEFAULT_LAYOUTS_DIR));
++ const QString customLayoutPath(QDir::fromNativeSeparators(qEnvironmentVariable("QT_VIRTUALKEYBOARD_LAYOUT_PATH")));
++ if (!customLayoutPath.isEmpty()) {
++ bool found = false;
++ QDir customLayoutDirectory(customLayoutPath);
++ if (customLayoutDirectory.exists()) {
++ found = true;
++ newLayoutPath = QUrl::fromLocalFile(customLayoutPath);
++ } else {
++ customLayoutDirectory = QDir(QUrl(customLayoutPath).toLocalFile());
++ if (customLayoutDirectory.exists()) {
++ found = true;
++ newLayoutPath = QUrl(customLayoutPath);
++ }
++ }
++ if (!found) {
++ qWarning() << "WARNING: Cannot assign custom layout path" << customLayoutPath << "- fallback:" << newLayoutPath;
++ }
++ }
++ setLayoutPath(newLayoutPath);
++ }
++
++ int Settings::wclAutoHideDelay() const
++ {
++ Q_D(const Settings);
++ return d->wclAutoHideDelay;
++ }
++
++ void Settings::setWclAutoHideDelay(int wclAutoHideDelay)
++ {
++ Q_D(Settings);
++ if (d->wclAutoHideDelay != wclAutoHideDelay) {
++ d->wclAutoHideDelay = wclAutoHideDelay;
++ emit wclAutoHideDelayChanged();
++ }
++ }
++
++ void Settings::resetWclAutoHideDelay()
++ {
++ setWclAutoHideDelay(SettingsPrivate::defaultWclAutoHideDelay);
++ }
++
++ bool Settings::wclAlwaysVisible() const
++ {
++ Q_D(const Settings);
++ return d->wclAlwaysVisible;
++ }
++
++ void Settings::setWclAlwaysVisible(bool wclAlwaysVisible)
++ {
++ Q_D(Settings);
++ if (d->wclAlwaysVisible != wclAlwaysVisible) {
++ d->wclAlwaysVisible = wclAlwaysVisible;
++ emit wclAlwaysVisibleChanged();
++ }
++ }
++
++ void Settings::resetWclAlwaysVisible()
++ {
++ setWclAlwaysVisible(false);
++ }
++
++ bool Settings::wclAutoCommitWord() const
++ {
++ Q_D(const Settings);
++ return d->wclAutoCommitWord;
++ }
++
++ void Settings::setWclAutoCommitWord(bool wclAutoCommitWord)
++ {
++ Q_D(Settings);
++ if (d->wclAutoCommitWord != wclAutoCommitWord) {
++ d->wclAutoCommitWord = wclAutoCommitWord;
++ emit wclAutoCommitWordChanged();
++ }
++ }
++
++ void Settings::resetWclAutoCommitWord()
++ {
++ setWclAutoCommitWord(false);
++ }
++
++ bool Settings::fullScreenMode() const
++ {
++ Q_D(const Settings);
++ return d->fullScreenMode;
++ }
++
++ void Settings::setFullScreenMode(bool fullScreenMode)
++ {
++ Q_D(Settings);
++ if (d->fullScreenMode != fullScreenMode) {
++ d->fullScreenMode = fullScreenMode;
++ emit fullScreenModeChanged();
++ }
++ }
++
++ void Settings::resetFullScreenMode()
++ {
++ setFullScreenMode(false);
++ }
++
++ QString Settings::userDataPath() const
++ {
++ Q_D(const Settings);
++ return d->userDataPath;
++ }
++
++ void Settings::setUserDataPath(const QString &userDataPath)
++ {
++ Q_D(Settings);
++ if (d->userDataPath != userDataPath) {
++ d->userDataPath = userDataPath;
++ d->ensureUserDataPathExists();
++ emit userDataPathChanged();
++ }
++ }
++
++ void Settings::resetUserDataPath()
++ {
++ setUserDataPath(SettingsPrivate::defaultUserDataPath());
++ }
++
++ int Settings::hwrTimeoutForAlphabetic() const
++ {
++ Q_D(const Settings);
++ return d->hwrTimeoutForAlphabetic;
++ }
++
++ void Settings::setHwrTimeoutForAlphabetic(int hwrTimeoutForAlphabetic)
++ {
++ Q_D(Settings);
++ if (d->hwrTimeoutForAlphabetic != hwrTimeoutForAlphabetic) {
++ d->hwrTimeoutForAlphabetic = hwrTimeoutForAlphabetic;
++ emit hwrTimeoutForAlphabeticChanged();
++ }
++ }
++
++ void Settings::resetHwrTimeoutForAlphabetic()
++ {
++ setHwrTimeoutForAlphabetic(SettingsPrivate::defaultHwrTimeoutForAlphabetic);
++ }
++
++ int Settings::hwrTimeoutForCjk() const
++ {
++ Q_D(const Settings);
++ return d->hwrTimeoutForCjk;
++ }
++
++ void Settings::setHwrTimeoutForCjk(int hwrTimeoutForCjk)
++ {
++ Q_D(Settings);
++ if (d->hwrTimeoutForCjk != hwrTimeoutForCjk) {
++ d->hwrTimeoutForCjk = hwrTimeoutForCjk;
++ emit hwrTimeoutForCjkChanged();
++ }
++ }
++
++ void Settings::resetHwrTimeoutForCjk()
++ {
++ setHwrTimeoutForCjk(SettingsPrivate::defaultHwrTimeoutForCjk);
++ }
++
++ Qt::InputMethodHints Settings::inputMethodHints() const
++ {
++ Q_D(const Settings);
++ return d->inputMethodHints;
++ }
++
++ void Settings::setInputMethodHints(const Qt::InputMethodHints &inputMethodHints)
++ {
++ Q_D(Settings);
++ if (d->inputMethodHints != inputMethodHints) {
++ d->inputMethodHints = inputMethodHints;
++ emit inputMethodHintsChanged();
++ }
++ }
++
++ void Settings::resetInputMethodHints()
++ {
++ setInputMethodHints(Qt::InputMethodHints());
++ }
++
++ bool Settings::isHandwritingModeDisabled() const
++ {
++ Q_D(const Settings);
++ return d->handwritingModeDisabled;
++ }
++
++ void Settings::setHandwritingModeDisabled(bool handwritingModeDisabled)
++ {
++ Q_D(Settings);
++ if (d->handwritingModeDisabled != handwritingModeDisabled) {
++ d->handwritingModeDisabled = handwritingModeDisabled;
++ emit handwritingModeDisabledChanged();
++ }
++ }
++
++ void Settings::resetHandwritingModeDisabled()
++ {
++ setHandwritingModeDisabled(false);
++ }
++
++ bool Settings::isDefaultInputMethodDisabled() const
++ {
++ Q_D(const Settings);
++ return d->defaultInputMethodDisabled;
++ }
++
++ void Settings::setDefaultInputMethodDisabled(bool defaultInputMethodDisabled)
++ {
++ Q_D(Settings);
++ if (d->defaultInputMethodDisabled != defaultInputMethodDisabled) {
++ d->defaultInputMethodDisabled = defaultInputMethodDisabled;
++ emit defaultInputMethodDisabledChanged();
++ }
++ }
++
++ void Settings::resetDefaultInputMethodDisabled()
++ {
++ setDefaultInputMethodDisabled(false);
++ }
++
++ bool QtVirtualKeyboard::Settings::isDefaultDictionaryDisabled() const
++ {
++ Q_D(const Settings);
++ return d->defaultDictionaryDisabled;
++ }
++
++ void QtVirtualKeyboard::Settings::setDefaultDictionaryDisabled(bool defaultDictionaryDisabled)
++ {
++ Q_D(Settings);
++ if (d->defaultDictionaryDisabled != defaultDictionaryDisabled) {
++ d->defaultDictionaryDisabled = defaultDictionaryDisabled;
++ emit defaultDictionaryDisabledChanged();
++ }
++ }
++
++ void Settings::resetDefaultDictionaryDisabled()
++ {
++ setDefaultDictionaryDisabled(false);
++ }
++
++ QtVirtualKeyboard::KeyboardFunctionKeys Settings::visibleFunctionKeys() const
++ {
++ Q_D(const Settings);
++ return d->visibleFunctionKeys;
++ }
++
++ void Settings::setVisibleFunctionKeys(QtVirtualKeyboard::KeyboardFunctionKeys newVisibleFunctionKeys)
++ {
++ Q_D(Settings);
++ if (d->visibleFunctionKeys != newVisibleFunctionKeys) {
++ d->visibleFunctionKeys = newVisibleFunctionKeys;
++ emit visibleFunctionKeysChanged();
++ }
++ }
++
++ void Settings::resetVisibleFunctionKeys()
++ {
++ setVisibleFunctionKeys(QtVirtualKeyboard::KeyboardFunctionKey::All);
++ }
++
++ bool Settings::closeOnReturn() const
++ {
++ Q_D(const Settings);
++ return d->closeOnReturn;
++ }
++
++ void Settings::setCloseOnReturn(bool enabled)
++ {
++ Q_D(Settings);
++ if (d->closeOnReturn != enabled) {
++ d->closeOnReturn = enabled;
++ emit closeOnReturnChanged();
++ }
++ }
++
++ void Settings::resetCloseOnReturn()
++ {
++ setCloseOnReturn(false);
++ }
++
++ qreal Settings::keySoundVolume() const
++ {
++ Q_D(const Settings);
++ return d->keySoundVolume;
++ }
++
++ void Settings::setKeySoundVolume(qreal volume)
++ {
++ Q_D(Settings);
++ qreal volumeBounded = qBound(0.0, volume, 1.0);
++ if (d->keySoundVolume != volumeBounded) {
++ d->keySoundVolume = volumeBounded;
++ emit keySoundVolumeChanged();
++ }
++ }
++
++ void Settings::resetKeySoundVolume()
++ {
++ setKeySoundVolume(1.0);
++ }
++
++ bool Settings::arrowKeyNavigationEnabled() const
++ {
++ Q_D(const Settings);
++ return d->arrowKeyNavigationEnabled;
++ }
++
++ void Settings::setArrowKeyNavigationEnabled(bool arrowKeyNavigationEnabled)
++ {
++ Q_D(Settings);
++ if (d->arrowKeyNavigationEnabled != arrowKeyNavigationEnabled) {
++ d->arrowKeyNavigationEnabled = arrowKeyNavigationEnabled;
++ emit arrowKeyNavigationEnabledChanged();
++ }
++ }
++
++ void Settings::resetArrowKeyNavigationEnabled()
++ {
++ #ifdef QT_VIRTUALKEYBOARD_ARROW_KEY_NAVIGATION
++ setArrowKeyNavigationEnabled(true);
++ #else
++ setArrowKeyNavigationEnabled(false);
++ #endif
++ }
++
++ QString Settings::screenName() const
++ {
++ Q_D(const Settings);
++ return d->screenName;
++ }
++
++ void Settings::setScreenName(const QString &screenName)
++ {
++ Q_D(Settings);
++ if (d->screenName != screenName) {
++ d->screenName = screenName;
++ emit screenNameChanged();
++ }
++ }
++
++ void Settings::resetScreenName()
++ {
++ setScreenName(QString());
++ }
++
++ } // namespace QtVirtualKeyboard
++ QT_END_NAMESPACE