Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmlsettings.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qqmlsettings_p.h"
5
6#include <QtQml/qjsvalue.h>
7#include <QtQml/qqmlfile.h>
8#include <QtQml/qqmlinfo.h>
9
10#include <QtCore/qcoreapplication.h>
11#include <QtCore/qcoreevent.h>
12#include <QtCore/qdebug.h>
13#include <QtCore/qhash.h>
14#include <QtCore/qloggingcategory.h>
15#include <QtCore/qpointer.h>
16#include <QtCore/qsettings.h>
17
19
23
201using namespace Qt::StringLiterals;
202
203Q_LOGGING_CATEGORY(lcQmlSettings, "qt.core.settings")
204
205static constexpr const int settingsWriteDelay = 500;
206
208{
209 Q_DISABLE_COPY_MOVE(QQmlSettingsPrivate)
210 Q_DECLARE_PUBLIC(QQmlSettings)
211
212public:
213 QQmlSettingsPrivate() = default;
215
216 QSettings *instance() const;
217
218 void init();
219 void reset();
220
221 void load();
222 void store();
223
224 void _q_propertyChanged();
225 QVariant readProperty(const QMetaProperty &property) const;
226
227 QQmlSettings *q_ptr = nullptr;
228 int timerId = 0;
229 bool initialized = false;
232 mutable QPointer<QSettings> settings = nullptr;
233 QHash<const char *, QVariant> changedProperties = {};
234};
235
237{
238 if (settings)
239 return settings;
240
241 QQmlSettings *q = const_cast<QQmlSettings *>(q_func());
244 : new QSettings(q);
245
247 // TODO: can't print out the enum due to the following error:
248 // error: C2666: 'QQmlInfo::operator <<': 15 overloads have similar conversions
249 qmlWarning(q) << "Failed to initialize QSettings instance. Status code is: " << int(settings->status());
250
252 QStringList missingIdentifiers = {};
254 missingIdentifiers.append(u"organizationName"_s);
256 missingIdentifiers.append(u"organizationDomain"_s);
257 if (QCoreApplication::applicationName().isEmpty())
258 missingIdentifiers.append(u"applicationName"_s);
259
260 if (!missingIdentifiers.isEmpty())
261 qmlWarning(q) << "The following application identifiers have not been set: " << missingIdentifiers;
262 }
263
264 return settings;
265 }
266
267 if (!category.isEmpty())
269
270 if (initialized)
271 q->d_func()->load();
272
273 return settings;
274}
275
277{
278 if (initialized)
279 return;
280 load();
281 initialized = true;
282 qCDebug(lcQmlSettings) << "QQmlSettings: stored at" << instance()->fileName();
283}
284
286{
288 store();
289 delete settings;
290}
291
293{
294 Q_Q(QQmlSettings);
295 const QMetaObject *mo = q->metaObject();
296 const int offset = mo->propertyOffset();
297 const int count = mo->propertyCount();
298
299 // don't save built-in properties if there aren't any qml properties
300 if (offset == 1)
301 return;
302
303 for (int i = offset; i < count; ++i) {
304 QMetaProperty property = mo->property(i);
305 const QString propertyName = QString::fromUtf8(property.name());
306
307 const QVariant previousValue = readProperty(property);
308 const QVariant currentValue = instance()->value(propertyName,
309 previousValue);
310
311 if (!currentValue.isNull() && (!previousValue.isValid()
312 || (currentValue.canConvert(previousValue.metaType())
313 && previousValue != currentValue))) {
314 property.write(q, currentValue);
315 qCDebug(lcQmlSettings) << "QQmlSettings: load" << property.name() << "setting:" << currentValue << "default:" << previousValue;
316 }
317
318 // ensure that a non-existent setting gets written
319 // even if the property wouldn't change later
320 if (!instance()->contains(propertyName))
322
323 // setup change notifications on first load
324 if (!initialized && property.hasNotifySignal()) {
325 static const int propertyChangedIndex = mo->indexOfSlot("_q_propertyChanged()");
326 QMetaObject::connect(q, property.notifySignalIndex(), q, propertyChangedIndex);
327 }
328 }
329}
330
332{
334 while (it != changedProperties.constEnd()) {
335 instance()->setValue(QString::fromUtf8(it.key()), it.value());
336 qCDebug(lcQmlSettings) << "QQmlSettings: store" << it.key() << ":" << it.value();
337 ++it;
338 }
340}
341
343{
344 Q_Q(QQmlSettings);
345 const QMetaObject *mo = q->metaObject();
346 const int offset = mo->propertyOffset();
347 const int count = mo->propertyCount();
348 for (int i = offset; i < count; ++i) {
349 const QMetaProperty &property = mo->property(i);
352 qCDebug(lcQmlSettings) << "QQmlSettings: cache" << property.name() << ":" << value;
353 }
354 if (timerId != 0)
355 q->killTimer(timerId);
356 timerId = q->startTimer(settingsWriteDelay);
357}
358
360{
361 Q_Q(const QQmlSettings);
362 QVariant var = property.read(q);
363 if (var.metaType() == QMetaType::fromType<QJSValue>())
365 return var;
366}
367
369 : QObject(parent), d_ptr(new QQmlSettingsPrivate)
370{
371 Q_D(QQmlSettings);
372 d->q_ptr = this;
373}
374
376{
377 Q_D(QQmlSettings);
378 d->reset(); // flush pending changes
379}
380
391{
392 Q_D(const QQmlSettings);
393 return d->category;
394}
395
397{
398 Q_D(QQmlSettings);
399 if (d->category == category)
400 return;
401 d->reset();
402 d->category = category;
403 if (d->initialized)
404 d->load();
406}
407
420{
421 Q_D(const QQmlSettings);
422 return d->location;
423}
424
426{
427 Q_D(QQmlSettings);
428 if (d->location == location)
429 return;
430 d->reset();
431 d->location = location;
432 if (d->initialized)
433 d->load();
435}
436
445QVariant QQmlSettings::value(const QString &key, const QVariant &defaultValue) const
446{
447 Q_D(const QQmlSettings);
448 return d->instance()->value(key, defaultValue);
449}
450
460{
461 Q_D(const QQmlSettings);
462 d->instance()->setValue(key, value);
463 qCDebug(lcQmlSettings) << "QQmlSettings: setValue" << key << ":" << value;
464}
465
480{
481 Q_D(QQmlSettings);
482 d->instance()->sync();
483}
484
488
490{
491 Q_D(QQmlSettings);
492 d->init();
493}
494
496{
497 Q_D(QQmlSettings);
499 if (event->timerId() != d->timerId)
500 return;
501 killTimer(d->timerId);
502 d->timerId = 0;
503 d->store();
504}
505
507
508#include "moc_qqmlsettings_p.cpp"
QString organizationName
the name of the organization that wrote this application
QString applicationName
the name of this application
QString organizationDomain
the Internet domain of the organization that wrote this application
\inmodule QtCore
Definition qhash.h:1145
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
Definition qhash.h:1219
const_iterator constBegin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
Definition qhash.h:1215
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
Definition qhash.h:951
bool isEmpty() const noexcept
Returns true if the hash contains no items; otherwise returns false.
Definition qhash.h:928
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1303
The QJSValue class acts as a container for Qt/JavaScript data types.
Definition qjsvalue.h:31
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:103
virtual void timerEvent(QTimerEvent *event)
This event handler can be reimplemented in a subclass to receive timer events for the object.
Definition qobject.cpp:1470
void killTimer(int id)
Kills the timer with timer identifier, id.
Definition qobject.cpp:1912
static bool isLocalFile(const QString &url)
Returns true if url is a local file that can be opened with \l{QFile}.
Definition qqmlfile.cpp:644
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to \l{QFile}.
Definition qqmlfile.cpp:742
QPointer< QSettings > settings
QHash< const char *, QVariant > changedProperties
QVariant readProperty(const QMetaProperty &property) const
~QQmlSettingsPrivate()=default
QSettings * instance() const
~QQmlSettings() override
void setLocation(const QUrl &location)
void classBegin() override
Invoked after class creation, but before any properties have been set.
void timerEvent(QTimerEvent *event) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
Q_INVOKABLE void sync()
\qmlmethod Settings::sync()
Q_INVOKABLE void setValue(const QString &key, const QVariant &value)
\qmlmethod Settings::setValue(string key, var value)
void setCategory(const QString &category)
QQmlSettings(QObject *parent=nullptr)
void locationChanged(const QUrl &arg)
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
Q_INVOKABLE QVariant value(const QString &key, const QVariant &defaultValue={}) const
\qmlmethod var Settings::value(string key, var defaultValue)
void categoryChanged(const QString &arg)
\inmodule QtCore
Definition qsettings.h:30
QString fileName() const
Returns the path where settings written using this QSettings object are stored.
void setValue(QAnyStringView key, const QVariant &value)
Sets the value of setting key to value.
QVariant value(QAnyStringView key, const QVariant &defaultValue) const
Returns the value for setting key.
@ AccessError
Definition qsettings.h:41
void beginGroup(QAnyStringView prefix)
Appends prefix to the current group.
Status status() const
Returns a status code indicating the first error that was met by QSettings, or QSettings::NoError if ...
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
\inmodule QtCore
Definition qcoreevent.h:366
\inmodule QtCore
Definition qurl.h:94
\inmodule QtCore
Definition qvariant.h:65
T value() const &
Definition qvariant.h:516
QMetaType metaType() const
static constexpr const int settingsWriteDelay
const QLoggingCategory & category()
[1]
p1 load("image.bmp")
QSet< QString >::iterator it
auto mo
[7]
static QT_BEGIN_NAMESPACE const int settingsWriteDelay
\qmlmodule Qt.labs.settings 1.0 \title Qt Labs Settings QML Types
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
static bool contains(const QJsonArray &haystack, unsigned needle)
Definition qopengl.cpp:116
GLint location
GLuint64 key
GLenum GLenum GLsizei count
GLenum GLuint GLintptr offset
struct _cl_event * event
GLboolean reset
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
#define Q_EMIT
static QVariant toVariant(const QV4::Value &value, QMetaType typeHint, JSToQVariantConversionBehavior conversionBehavior, V4ObjectSet *visitedObjects)
const char property[13]
Definition qwizard.cpp:101
QSettings settings("MySoft", "Star Runner")
[0]
\inmodule QtCore
static Connection connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type=0, int *types=nullptr)
Definition qobject.cpp:3556