| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:GPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 3 or (at your option) any later version |
| ** approved by the KDE Free Qt Foundation. The licenses are as published by |
| ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include <QtVirtualKeyboard/private/virtualkeyboardsettings_p.h> |
| #include <QtVirtualKeyboard/private/settings_p.h> |
| #include <QtVirtualKeyboard/private/virtualkeyboarddebug_p.h> |
| #include <QQmlEngine> |
| #include <QFileInfo> |
| #include <QDir> |
| #include <QRegularExpression> |
| #include <QtCore/private/qobject_p.h> |
| |
| QT_BEGIN_NAMESPACE |
| namespace QtVirtualKeyboard { |
| |
| class VirtualKeyboardSettingsPrivate : public QObjectPrivate |
| { |
| public: |
| VirtualKeyboardSettingsPrivate() : |
| QObjectPrivate(), |
| engine() |
| {} |
| |
| QString buildStyleImportPath(const QString &path, const QString &name) const |
| { |
| QString importPath(path + name + QLatin1String("/style.qml")); |
| if (!importPath.startsWith(QLatin1String("qrc:"))) { |
| QUrl url = QUrl::fromLocalFile(importPath); |
| importPath = url.toString(); |
| } |
| return importPath; |
| } |
| |
| QString buildStyleFilePath(const QString &path, const QString &name) const |
| { |
| QString filePath(path); |
| if (filePath.startsWith(QLatin1String("qrc:"))) |
| filePath.remove(0, 3); |
| return filePath + name + QLatin1String("/style.qml"); |
| } |
| |
| QString styleImportPath(const QString &name) const |
| { |
| if (name.isEmpty()) |
| return QString(); |
| |
| QStringList styleImportPathList; |
| styleImportPathList << QLatin1String("qrc:/QtQuick/VirtualKeyboard/content/styles/"); |
| const QStringList importPathList = engine->importPathList(); |
| // Add QML import path (Note: the QML base dir is usually the last entry in the list) |
| for (int i = importPathList.size() - 1; i >= 0; --i) { |
| const QString stylesPath = importPathList.at(i) |
| + QLatin1String("/QtQuick/VirtualKeyboard/Styles/"); |
| styleImportPathList += stylesPath; |
| } |
| |
| for (const QString &styleImportPath : qAsConst(styleImportPathList)) { |
| QString filePath = buildStyleFilePath(styleImportPath, name); |
| bool pathExist = false; |
| pathExist = QFileInfo::exists(filePath); |
| if (pathExist) |
| return buildStyleImportPath(styleImportPath, name); |
| } |
| return QString(); |
| } |
| |
| QPointer<QQmlEngine> engine; |
| WordCandidateListSettings wordCandidateListSettings; |
| }; |
| |
| /*! |
| \qmlmodule QtQuick.VirtualKeyboard.Settings 2.\QtMinorVersion |
| \title Qt Quick Virtual Keyboard Settings QML Types |
| \ingroup qmlmodules |
| |
| \brief Provides settings for Qt Virtual Keyboard. |
| |
| The QML types can be imported into your application using the following |
| import statements in your .qml file: |
| |
| \qml \QtMinorVersion |
| import QtQuick.VirtualKeyboard.Settings 2.\1 |
| \endqml |
| */ |
| |
| /*! |
| \qmltype VirtualKeyboardSettings |
| \inqmlmodule QtQuick.VirtualKeyboard.Settings |
| \ingroup qtvirtualkeyboard-settings-qml |
| \since QtQuick.VirtualKeyboard 1.2 |
| \brief Provides settings for virtual keyboard. |
| |
| This type provides a VirtualKeyboardSettings singleton instance, |
| which can be used to configure the virtual keyboard settings. |
| |
| Please note that the settings have only effect in the current |
| application's lifetime, that is, configuration changes are not |
| permanent. |
| |
| For example, to change the keyboard style in application: |
| |
| \code |
| Component.onCompleted: VirtualKeyboardSettings.styleName = "retro" |
| \endcode |
| */ |
| |
| /*! |
| \internal |
| */ |
| QObject *VirtualKeyboardSettings::registerSettingsModule(QQmlEngine *engine, QJSEngine *jsEngine) |
| { |
| Q_UNUSED(jsEngine); |
| return new VirtualKeyboardSettings(engine); |
| } |
| |
| /*! |
| \class QtVirtualKeyboard::VirtualKeyboardSettings |
| \internal |
| */ |
| |
| /*! |
| \internal |
| */ |
| VirtualKeyboardSettings::VirtualKeyboardSettings(QQmlEngine *engine) : |
| QObject(*new VirtualKeyboardSettingsPrivate()) |
| { |
| Q_D(VirtualKeyboardSettings); |
| d->engine = engine; |
| Settings *settings = Settings::instance(); |
| if (settings->styleName().isEmpty()) |
| resetStyle(); |
| if (settings->layoutPath().isEmpty()) |
| resetLayoutPath(); |
| connect(settings, SIGNAL(styleChanged()), SIGNAL(styleChanged())); |
| connect(settings, SIGNAL(styleNameChanged()), SIGNAL(styleNameChanged())); |
| connect(settings, SIGNAL(localeChanged()), SIGNAL(localeChanged())); |
| connect(settings, SIGNAL(availableLocalesChanged()), SIGNAL(availableLocalesChanged())); |
| connect(settings, SIGNAL(activeLocalesChanged()), SIGNAL(activeLocalesChanged())); |
| connect(settings, SIGNAL(layoutPathChanged()), SIGNAL(layoutPathChanged())); |
| connect(settings, SIGNAL(wclAutoHideDelayChanged()), &d->wordCandidateListSettings, SIGNAL(autoHideDelayChanged())); |
| connect(settings, SIGNAL(wclAlwaysVisibleChanged()), &d->wordCandidateListSettings, SIGNAL(alwaysVisibleChanged())); |
| connect(settings, SIGNAL(wclAutoCommitWordChanged()), &d->wordCandidateListSettings, SIGNAL(autoCommitWordChanged())); |
| connect(settings, SIGNAL(fullScreenModeChanged()), SIGNAL(fullScreenModeChanged())); |
| } |
| |
| /*! |
| \internal |
| */ |
| QString VirtualKeyboardSettings::style() const |
| { |
| return Settings::instance()->style(); |
| } |
| |
| /*! |
| \internal |
| */ |
| QString VirtualKeyboardSettings::styleName() const |
| { |
| return Settings::instance()->styleName(); |
| } |
| |
| /*! |
| \internal |
| */ |
| void VirtualKeyboardSettings::setStyleName(const QString &styleName) |
| { |
| Q_D(VirtualKeyboardSettings); |
| Settings *settings = Settings::instance(); |
| QString style = d->styleImportPath(styleName); |
| if (style.isEmpty()) { |
| qWarning() << "WARNING: Cannot find style" << styleName << "- fallback:" << settings->styleName(); |
| return; |
| } |
| settings->setStyleName(styleName); |
| settings->setStyle(style); |
| } |
| |
| /*! |
| \internal |
| */ |
| QUrl VirtualKeyboardSettings::layoutPath() const |
| { |
| return Settings::instance()->layoutPath(); |
| } |
| |
| /*! |
| \internal |
| */ |
| void VirtualKeyboardSettings::setLayoutPath(const QUrl &layoutPath) |
| { |
| Settings *settings = Settings::instance(); |
| QDir layoutDirectory(layoutPath.toLocalFile()); |
| if (!layoutDirectory.exists()) { |
| qWarning() << "WARNING: Cannot find layout path" << layoutPath; |
| return; |
| } |
| settings->setLayoutPath(layoutPath); |
| } |
| |
| void VirtualKeyboardSettings::resetLayoutPath() |
| { |
| Settings *settings = Settings::instance(); |
| QUrl layoutPath(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; |
| layoutPath = QUrl::fromLocalFile(customLayoutPath); |
| } else { |
| customLayoutDirectory = QDir(QUrl(customLayoutPath).toLocalFile()); |
| if (customLayoutDirectory.exists()) { |
| found = true; |
| layoutPath = QUrl(customLayoutPath); |
| } |
| } |
| if (!found) { |
| qWarning() << "WARNING: Cannot assign custom layout path" << customLayoutPath << "- fallback:" << layoutPath; |
| } |
| } |
| settings->setLayoutPath(layoutPath); |
| } |
| |
| QString VirtualKeyboardSettings::locale() const |
| { |
| return Settings::instance()->locale(); |
| } |
| |
| void VirtualKeyboardSettings::setLocale(const QString &locale) |
| { |
| Settings::instance()->setLocale(locale); |
| } |
| |
| QStringList VirtualKeyboardSettings::availableLocales() const |
| { |
| return Settings::instance()->availableLocales(); |
| } |
| |
| void VirtualKeyboardSettings::setActiveLocales(const QStringList &activeLocales) |
| { |
| Settings::instance()->setActiveLocales(activeLocales); |
| } |
| |
| QStringList VirtualKeyboardSettings::activeLocales() const |
| { |
| return Settings::instance()->activeLocales(); |
| } |
| |
| WordCandidateListSettings *VirtualKeyboardSettings::wordCandidateList() const |
| { |
| Q_D(const VirtualKeyboardSettings); |
| return const_cast<WordCandidateListSettings *>(&d->wordCandidateListSettings); |
| } |
| |
| bool VirtualKeyboardSettings::fullScreenMode() const |
| { |
| return Settings::instance()->fullScreenMode(); |
| } |
| |
| void VirtualKeyboardSettings::setFullScreenMode(bool fullScreenMode) |
| { |
| return Settings::instance()->setFullScreenMode(fullScreenMode); |
| } |
| |
| void VirtualKeyboardSettings::resetStyle() |
| { |
| Q_D(VirtualKeyboardSettings); |
| Settings *settings = Settings::instance(); |
| QString styleName = QLatin1String(QT_VIRTUALKEYBOARD_DEFAULT_STYLE); |
| QString style = d->styleImportPath(styleName); |
| QString customStyleName = QString::fromLatin1(qgetenv("QT_VIRTUALKEYBOARD_STYLE")); |
| if (!customStyleName.isEmpty()) { |
| bool found = false; |
| QRegularExpression styleNameValidator(QLatin1String("\\A(?:\\w+)\\z")); |
| QRegularExpressionMatch match = styleNameValidator.match(customStyleName); |
| if (match.hasMatch()) { |
| QString customStyle = d->styleImportPath(customStyleName); |
| if (!customStyle.isEmpty()) { |
| styleName = customStyleName; |
| style = customStyle; |
| found = true; |
| } |
| } |
| if (!found) { |
| qWarning() << "WARNING: Cannot find style" << customStyleName << "- fallback:" << styleName; |
| } |
| } |
| if (!style.isEmpty()) { |
| settings->setStyleName(styleName); |
| settings->setStyle(style); |
| } |
| } |
| |
| /*! |
| \qmlproperty string VirtualKeyboardSettings::style |
| \internal |
| */ |
| |
| /*! |
| \qmlproperty string VirtualKeyboardSettings::styleName |
| |
| This property provides the current style. Application can change |
| the keyboard style by setting the styleName to different value. |
| |
| The system wide keyboard style can be affected by setting |
| the QT_VIRTUALKEYBOARD_STYLE environment variable. |
| */ |
| |
| /*! |
| \qmlproperty string VirtualKeyboardSettings::locale |
| \since QtQuick.VirtualKeyboard.Settings 2.0 |
| |
| This property provides the default locale for the keyboard. |
| |
| When the locale is not specified, the default system locale is used instead. |
| |
| If the keyboard locale is different from the new default locale, keyboard |
| language is changed immediately to reflect the new locale. If the locale setting |
| is incorrect, or it is not in the list of supported locales, it is ignored and |
| the default setting is used instead. |
| |
| A locale is supported if it is included in the list of availableLocales. |
| */ |
| |
| /*! |
| \qmlproperty list<string> VirtualKeyboardSettings::availableLocales |
| \since QtQuick.VirtualKeyboard.Settings 2.0 |
| |
| This property contains a list of languages supported by the virtual keyboard. |
| |
| This list is read-only and depends on the build-time configuration of the |
| virtual keyboard. |
| */ |
| |
| /*! |
| \qmlproperty list<string> VirtualKeyboardSettings::activeLocales |
| \since QtQuick.VirtualKeyboard.Settings 2.0 |
| |
| This property contains a list of activated languages of the virtual keyboard. |
| |
| The list of active languages is a subset of the available languages, and can be |
| used to limit the list of available languages in the application lifetime. |
| */ |
| |
| /*! |
| \qmlproperty bool VirtualKeyboardSettings::fullScreenMode |
| \since QtQuick.VirtualKeyboard.Settings 2.2 |
| |
| This property enables the fullscreen mode for the virtual keyboard. |
| |
| In fullscreen mode, the virtual keyboard replicates the contents of the |
| focused input field to the fullscreen input field located at the top of the |
| keyboard. |
| |
| For example, to activate the fullscreen mode when the screen aspect ratio |
| is greater than 16:9: |
| |
| \code |
| Binding { |
| target: VirtualKeyboardSettings |
| property: "fullScreenMode" |
| value: (Screen.width / Screen.height) > (16.0 / 9.0) |
| } |
| \endcode |
| */ |
| |
| /*! |
| \since QtQuick.VirtualKeyboard.Settings 2.2 |
| \qmlpropertygroup QtQuick.VirtualKeyboard::VirtualKeyboardSettings::wordCandidateList |
| \qmlproperty int QtQuick.VirtualKeyboard::VirtualKeyboardSettings::wordCandidateList.autoHideDelay |
| \qmlproperty bool QtQuick.VirtualKeyboard::VirtualKeyboardSettings::wordCandidateList.alwaysVisible |
| |
| \table |
| \header |
| \li Name |
| \li Description |
| \row |
| \li autoHideDelay |
| \li This property defines the delay, in milliseconds, after which the |
| word candidate list is hidden if empty. |
| |
| If the value is \c 0, the list is immediately hidden when cleared. |
| |
| If the value is \c -1, the list is visible until input focus |
| changes, or the input panel is hidden. |
| |
| The default value is \c 5000 milliseconds. |
| \row |
| \li alwaysVisible |
| \li This property defines whether the word candidate list should always |
| remain visible. |
| |
| The default value is \c false. |
| \row |
| \li autoCommitWord |
| \li This property enables the automatic commit feature that is activated |
| when the word candidate list is narrowed down to a single candidate. |
| |
| The automatic commit feature takes effect when the word candidate |
| list initially contains multiple words and is reduced to single word |
| after additional input. This word will be selected and committed |
| automatically without user interaction. |
| |
| This property is set to \c false by default. |
| \endtable |
| */ |
| |
| WordCandidateListSettings::WordCandidateListSettings(QObject *parent) : |
| QObject(parent) |
| { |
| } |
| |
| int WordCandidateListSettings::autoHideDelay() const |
| { |
| return Settings::instance()->wclAutoHideDelay(); |
| } |
| |
| void WordCandidateListSettings::setAutoHideDelay(int autoHideDelay) |
| { |
| Settings::instance()->setWclAutoHideDelay(autoHideDelay); |
| } |
| |
| bool WordCandidateListSettings::alwaysVisible() const |
| { |
| return Settings::instance()->wclAlwaysVisible(); |
| } |
| |
| void WordCandidateListSettings::setAlwaysVisible(bool alwaysVisible) |
| { |
| Settings::instance()->setWclAlwaysVisible(alwaysVisible); |
| } |
| |
| bool WordCandidateListSettings::autoCommitWord() const |
| { |
| return Settings::instance()->wclAutoCommitWord(); |
| } |
| |
| void WordCandidateListSettings::setAutoCommitWord(bool autoCommitWord) |
| { |
| Settings::instance()->setWclAutoCommitWord(autoCommitWord); |
| } |
| |
| } // namespace QtVirtualKeyboard |
| QT_END_NAMESPACE |