1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include <QtVirtualKeyboard/private/virtualkeyboardsettings_p.h>
31#include <QtVirtualKeyboard/private/settings_p.h>
32#include <QtVirtualKeyboard/private/virtualkeyboarddebug_p.h>
33#include <QQmlEngine>
34#include <QFileInfo>
35#include <QDir>
36#include <QRegularExpression>
37#include <QtCore/private/qobject_p.h>
38
39QT_BEGIN_NAMESPACE
40namespace QtVirtualKeyboard {
41
42class VirtualKeyboardSettingsPrivate : public QObjectPrivate
43{
44public:
45 VirtualKeyboardSettingsPrivate() :
46 QObjectPrivate(),
47 engine()
48 {}
49
50 QString buildStyleImportPath(const QString &path, const QString &name) const
51 {
52 QString importPath(path + name + QLatin1String("/style.qml"));
53 if (!importPath.startsWith(s: QLatin1String("qrc:"))) {
54 QUrl url = QUrl::fromLocalFile(localfile: importPath);
55 importPath = url.toString();
56 }
57 return importPath;
58 }
59
60 QString buildStyleFilePath(const QString &path, const QString &name) const
61 {
62 QString filePath(path);
63 if (filePath.startsWith(s: QLatin1String("qrc:")))
64 filePath.remove(i: 0, len: 3);
65 return filePath + name + QLatin1String("/style.qml");
66 }
67
68 QString styleImportPath(const QString &name) const
69 {
70 if (name.isEmpty())
71 return QString();
72
73 QStringList styleImportPathList;
74 styleImportPathList << QLatin1String("qrc:/QtQuick/VirtualKeyboard/content/styles/");
75 const QStringList importPathList = engine->importPathList();
76 // Add QML import path (Note: the QML base dir is usually the last entry in the list)
77 for (int i = importPathList.size() - 1; i >= 0; --i) {
78 const QString stylesPath = importPathList.at(i)
79 + QLatin1String("/QtQuick/VirtualKeyboard/Styles/");
80 styleImportPathList += stylesPath;
81 }
82
83 for (const QString &styleImportPath : qAsConst(t&: styleImportPathList)) {
84 QString filePath = buildStyleFilePath(path: styleImportPath, name);
85 bool pathExist = false;
86 pathExist = QFileInfo::exists(file: filePath);
87 if (pathExist)
88 return buildStyleImportPath(path: styleImportPath, name);
89 }
90 return QString();
91 }
92
93 QPointer<QQmlEngine> engine;
94 WordCandidateListSettings wordCandidateListSettings;
95};
96
97/*!
98 \qmlmodule QtQuick.VirtualKeyboard.Settings 2.\QtMinorVersion
99 \title Qt Quick Virtual Keyboard Settings QML Types
100 \ingroup qmlmodules
101
102 \brief Provides settings for Qt Virtual Keyboard.
103
104 The QML types can be imported into your application using the following
105 import statements in your .qml file:
106
107 \qml \QtMinorVersion
108 import QtQuick.VirtualKeyboard.Settings 2.\1
109 \endqml
110*/
111
112/*!
113 \qmltype VirtualKeyboardSettings
114 \inqmlmodule QtQuick.VirtualKeyboard.Settings
115 \ingroup qtvirtualkeyboard-settings-qml
116 \since QtQuick.VirtualKeyboard 1.2
117 \brief Provides settings for virtual keyboard.
118
119 This type provides a VirtualKeyboardSettings singleton instance,
120 which can be used to configure the virtual keyboard settings.
121
122 Please note that the settings have only effect in the current
123 application's lifetime, that is, configuration changes are not
124 permanent.
125
126 For example, to change the keyboard style in application:
127
128 \code
129 Component.onCompleted: VirtualKeyboardSettings.styleName = "retro"
130 \endcode
131*/
132
133/*!
134 \internal
135*/
136QObject *VirtualKeyboardSettings::registerSettingsModule(QQmlEngine *engine, QJSEngine *jsEngine)
137{
138 Q_UNUSED(jsEngine);
139 return new VirtualKeyboardSettings(engine);
140}
141
142/*!
143 \class QtVirtualKeyboard::VirtualKeyboardSettings
144 \internal
145*/
146
147/*!
148 \internal
149*/
150VirtualKeyboardSettings::VirtualKeyboardSettings(QQmlEngine *engine) :
151 QObject(*new VirtualKeyboardSettingsPrivate())
152{
153 Q_D(VirtualKeyboardSettings);
154 d->engine = engine;
155 Settings *settings = Settings::instance();
156 if (settings->styleName().isEmpty())
157 resetStyle();
158 if (settings->layoutPath().isEmpty())
159 resetLayoutPath();
160 connect(asender: settings, SIGNAL(styleChanged()), SIGNAL(styleChanged()));
161 connect(asender: settings, SIGNAL(styleNameChanged()), SIGNAL(styleNameChanged()));
162 connect(asender: settings, SIGNAL(localeChanged()), SIGNAL(localeChanged()));
163 connect(asender: settings, SIGNAL(availableLocalesChanged()), SIGNAL(availableLocalesChanged()));
164 connect(asender: settings, SIGNAL(activeLocalesChanged()), SIGNAL(activeLocalesChanged()));
165 connect(asender: settings, SIGNAL(layoutPathChanged()), SIGNAL(layoutPathChanged()));
166 connect(sender: settings, SIGNAL(wclAutoHideDelayChanged()), receiver: &d->wordCandidateListSettings, SIGNAL(autoHideDelayChanged()));
167 connect(sender: settings, SIGNAL(wclAlwaysVisibleChanged()), receiver: &d->wordCandidateListSettings, SIGNAL(alwaysVisibleChanged()));
168 connect(sender: settings, SIGNAL(wclAutoCommitWordChanged()), receiver: &d->wordCandidateListSettings, SIGNAL(autoCommitWordChanged()));
169 connect(asender: settings, SIGNAL(fullScreenModeChanged()), SIGNAL(fullScreenModeChanged()));
170}
171
172/*!
173 \internal
174*/
175QString VirtualKeyboardSettings::style() const
176{
177 return Settings::instance()->style();
178}
179
180/*!
181 \internal
182*/
183QString VirtualKeyboardSettings::styleName() const
184{
185 return Settings::instance()->styleName();
186}
187
188/*!
189 \internal
190*/
191void VirtualKeyboardSettings::setStyleName(const QString &styleName)
192{
193 Q_D(VirtualKeyboardSettings);
194 Settings *settings = Settings::instance();
195 QString style = d->styleImportPath(name: styleName);
196 if (style.isEmpty()) {
197 qWarning() << "WARNING: Cannot find style" << styleName << "- fallback:" << settings->styleName();
198 return;
199 }
200 settings->setStyleName(styleName);
201 settings->setStyle(style);
202}
203
204/*!
205 \internal
206*/
207QUrl VirtualKeyboardSettings::layoutPath() const
208{
209 return Settings::instance()->layoutPath();
210}
211
212/*!
213 \internal
214*/
215void VirtualKeyboardSettings::setLayoutPath(const QUrl &layoutPath)
216{
217 Settings *settings = Settings::instance();
218 QDir layoutDirectory(layoutPath.toLocalFile());
219 if (!layoutDirectory.exists()) {
220 qWarning() << "WARNING: Cannot find layout path" << layoutPath;
221 return;
222 }
223 settings->setLayoutPath(layoutPath);
224}
225
226void VirtualKeyboardSettings::resetLayoutPath()
227{
228 Settings *settings = Settings::instance();
229 QUrl layoutPath(QLatin1String(QT_VIRTUALKEYBOARD_DEFAULT_LAYOUTS_DIR));
230 const QString customLayoutPath(QDir::fromNativeSeparators(pathName: qEnvironmentVariable(varName: "QT_VIRTUALKEYBOARD_LAYOUT_PATH")));
231 if (!customLayoutPath.isEmpty()) {
232 bool found = false;
233 QDir customLayoutDirectory(customLayoutPath);
234 if (customLayoutDirectory.exists()) {
235 found = true;
236 layoutPath = QUrl::fromLocalFile(localfile: customLayoutPath);
237 } else {
238 customLayoutDirectory = QDir(QUrl(customLayoutPath).toLocalFile());
239 if (customLayoutDirectory.exists()) {
240 found = true;
241 layoutPath = QUrl(customLayoutPath);
242 }
243 }
244 if (!found) {
245 qWarning() << "WARNING: Cannot assign custom layout path" << customLayoutPath << "- fallback:" << layoutPath;
246 }
247 }
248 settings->setLayoutPath(layoutPath);
249}
250
251QString VirtualKeyboardSettings::locale() const
252{
253 return Settings::instance()->locale();
254}
255
256void VirtualKeyboardSettings::setLocale(const QString &locale)
257{
258 Settings::instance()->setLocale(locale);
259}
260
261QStringList VirtualKeyboardSettings::availableLocales() const
262{
263 return Settings::instance()->availableLocales();
264}
265
266void VirtualKeyboardSettings::setActiveLocales(const QStringList &activeLocales)
267{
268 Settings::instance()->setActiveLocales(activeLocales);
269}
270
271QStringList VirtualKeyboardSettings::activeLocales() const
272{
273 return Settings::instance()->activeLocales();
274}
275
276WordCandidateListSettings *VirtualKeyboardSettings::wordCandidateList() const
277{
278 Q_D(const VirtualKeyboardSettings);
279 return const_cast<WordCandidateListSettings *>(&d->wordCandidateListSettings);
280}
281
282bool VirtualKeyboardSettings::fullScreenMode() const
283{
284 return Settings::instance()->fullScreenMode();
285}
286
287void VirtualKeyboardSettings::setFullScreenMode(bool fullScreenMode)
288{
289 return Settings::instance()->setFullScreenMode(fullScreenMode);
290}
291
292void VirtualKeyboardSettings::resetStyle()
293{
294 Q_D(VirtualKeyboardSettings);
295 Settings *settings = Settings::instance();
296 QString styleName = QLatin1String(QT_VIRTUALKEYBOARD_DEFAULT_STYLE);
297 QString style = d->styleImportPath(name: styleName);
298 QString customStyleName = QString::fromLatin1(str: qgetenv(varName: "QT_VIRTUALKEYBOARD_STYLE"));
299 if (!customStyleName.isEmpty()) {
300 bool found = false;
301 QRegularExpression styleNameValidator(QLatin1String("\\A(?:\\w+)\\z"));
302 QRegularExpressionMatch match = styleNameValidator.match(subject: customStyleName);
303 if (match.hasMatch()) {
304 QString customStyle = d->styleImportPath(name: customStyleName);
305 if (!customStyle.isEmpty()) {
306 styleName = customStyleName;
307 style = customStyle;
308 found = true;
309 }
310 }
311 if (!found) {
312 qWarning() << "WARNING: Cannot find style" << customStyleName << "- fallback:" << styleName;
313 }
314 }
315 if (!style.isEmpty()) {
316 settings->setStyleName(styleName);
317 settings->setStyle(style);
318 }
319}
320
321/*!
322 \qmlproperty string VirtualKeyboardSettings::style
323 \internal
324*/
325
326/*!
327 \qmlproperty string VirtualKeyboardSettings::styleName
328
329 This property provides the current style. Application can change
330 the keyboard style by setting the styleName to different value.
331
332 The system wide keyboard style can be affected by setting
333 the QT_VIRTUALKEYBOARD_STYLE environment variable.
334*/
335
336/*!
337 \qmlproperty string VirtualKeyboardSettings::locale
338 \since QtQuick.VirtualKeyboard.Settings 2.0
339
340 This property provides the default locale for the keyboard.
341
342 When the locale is not specified, the default system locale is used instead.
343
344 If the keyboard locale is different from the new default locale, keyboard
345 language is changed immediately to reflect the new locale. If the locale setting
346 is incorrect, or it is not in the list of supported locales, it is ignored and
347 the default setting is used instead.
348
349 A locale is supported if it is included in the list of availableLocales.
350*/
351
352/*!
353 \qmlproperty list<string> VirtualKeyboardSettings::availableLocales
354 \since QtQuick.VirtualKeyboard.Settings 2.0
355 \readonly
356
357 This property contains a list of languages supported by the virtual keyboard.
358
359 This list is read-only and depends on the build-time configuration of the
360 virtual keyboard.
361*/
362
363/*!
364 \qmlproperty list<string> VirtualKeyboardSettings::activeLocales
365 \since QtQuick.VirtualKeyboard.Settings 2.0
366
367 This property contains a list of activated languages of the virtual keyboard.
368
369 The list of active languages is a subset of the available languages, and can be
370 used to limit the list of available languages in the application lifetime.
371*/
372
373/*!
374 \qmlproperty bool VirtualKeyboardSettings::fullScreenMode
375 \since QtQuick.VirtualKeyboard.Settings 2.2
376
377 This property enables the fullscreen mode for the virtual keyboard.
378
379 In fullscreen mode, the virtual keyboard replicates the contents of the
380 focused input field to the fullscreen input field located at the top of the
381 keyboard.
382
383 For example, to activate the fullscreen mode when the screen aspect ratio
384 is greater than 16:9:
385
386 \code
387 Binding {
388 target: VirtualKeyboardSettings
389 property: "fullScreenMode"
390 value: (Screen.width / Screen.height) > (16.0 / 9.0)
391 }
392 \endcode
393*/
394
395/*!
396 \since QtQuick.VirtualKeyboard.Settings 2.2
397 \qmlpropertygroup QtQuick.VirtualKeyboard::VirtualKeyboardSettings::wordCandidateList
398 \qmlproperty int QtQuick.VirtualKeyboard::VirtualKeyboardSettings::wordCandidateList.autoHideDelay
399 \qmlproperty bool QtQuick.VirtualKeyboard::VirtualKeyboardSettings::wordCandidateList.alwaysVisible
400
401 \table
402 \header
403 \li Name
404 \li Description
405 \row
406 \li autoHideDelay
407 \li This property defines the delay, in milliseconds, after which the
408 word candidate list is hidden if empty.
409
410 If the value is \c 0, the list is immediately hidden when cleared.
411
412 If the value is \c -1, the list is visible until input focus
413 changes, or the input panel is hidden.
414
415 The default value is \c 5000 milliseconds.
416 \row
417 \li alwaysVisible
418 \li This property defines whether the word candidate list should always
419 remain visible.
420
421 The default value is \c false.
422 \row
423 \li autoCommitWord
424 \li This property enables the automatic commit feature that is activated
425 when the word candidate list is narrowed down to a single candidate.
426
427 The automatic commit feature takes effect when the word candidate
428 list initially contains multiple words and is reduced to single word
429 after additional input. This word will be selected and committed
430 automatically without user interaction.
431
432 This property is set to \c false by default.
433 \endtable
434*/
435
436WordCandidateListSettings::WordCandidateListSettings(QObject *parent) :
437 QObject(parent)
438{
439}
440
441int WordCandidateListSettings::autoHideDelay() const
442{
443 return Settings::instance()->wclAutoHideDelay();
444}
445
446void WordCandidateListSettings::setAutoHideDelay(int autoHideDelay)
447{
448 Settings::instance()->setWclAutoHideDelay(autoHideDelay);
449}
450
451bool WordCandidateListSettings::alwaysVisible() const
452{
453 return Settings::instance()->wclAlwaysVisible();
454}
455
456void WordCandidateListSettings::setAlwaysVisible(bool alwaysVisible)
457{
458 Settings::instance()->setWclAlwaysVisible(alwaysVisible);
459}
460
461bool WordCandidateListSettings::autoCommitWord() const
462{
463 return Settings::instance()->wclAutoCommitWord();
464}
465
466void WordCandidateListSettings::setAutoCommitWord(bool autoCommitWord)
467{
468 Settings::instance()->setWclAutoCommitWord(autoCommitWord);
469}
470
471} // namespace QtVirtualKeyboard
472QT_END_NAMESPACE
473

source code of qtvirtualkeyboard/src/virtualkeyboard/virtualkeyboardsettings.cpp