Qt 6.x
The Qt SDK
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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#include <qcoreevent.h>
6#include <qcoreapplication.h>
7#include <qloggingcategory.h>
8#include <qsettings.h>
9#include <qpointer.h>
10#include <qjsvalue.h>
11#include <qqmlinfo.h>
12#include <qdebug.h>
13#include <qhash.h>
14
16
20
198using namespace Qt::StringLiterals;
199
200Q_LOGGING_CATEGORY(lcQmlSettings, "qt.core.settings")
201
202static constexpr const int settingsWriteDelay = 500;
203
205{
206 Q_DISABLE_COPY_MOVE(QQmlSettingsPrivate)
207 Q_DECLARE_PUBLIC(QQmlSettings)
208
209public:
210 QQmlSettingsPrivate() = default;
212
213 QSettings *instance() const;
214
215 void init();
216 void reset();
217
218 void load();
219 void store();
220
221 void _q_propertyChanged();
222 QVariant readProperty(const QMetaProperty &property) const;
223
224 QQmlSettings *q_ptr = nullptr;
225 int timerId = 0;
226 bool initialized = false;
229 mutable QPointer<QSettings> settings = nullptr;
230 QHash<const char *, QVariant> changedProperties = {};
231};
232
234{
235 if (settings)
236 return settings;
237
238 QQmlSettings *q = const_cast<QQmlSettings *>(q_func());
239 settings = location.isLocalFile() ? new QSettings(location.toLocalFile(), QSettings::IniFormat, q) : new QSettings(q);
240
242 // TODO: can't print out the enum due to the following error:
243 // error: C2666: 'QQmlInfo::operator <<': 15 overloads have similar conversions
244 qmlWarning(q) << "Failed to initialize QSettings instance. Status code is: " << int(settings->status());
245
247 QStringList missingIdentifiers = {};
249 missingIdentifiers.append(u"organizationName"_s);
251 missingIdentifiers.append(u"organizationDomain"_s);
252 if (QCoreApplication::applicationName().isEmpty())
253 missingIdentifiers.append(u"applicationName"_s);
254
255 if (!missingIdentifiers.isEmpty())
256 qmlWarning(q) << "The following application identifiers have not been set: " << missingIdentifiers;
257 }
258
259 return settings;
260 }
261
262 if (!category.isEmpty())
264
265 if (initialized)
266 q->d_func()->load();
267
268 return settings;
269}
270
272{
273 if (initialized)
274 return;
275 load();
276 initialized = true;
277 qCDebug(lcQmlSettings) << "QQmlSettings: stored at" << instance()->fileName();
278}
279
281{
283 store();
284 delete settings;
285}
286
288{
289 Q_Q(QQmlSettings);
290 const QMetaObject *mo = q->metaObject();
291 const int offset = mo->propertyOffset();
292 const int count = mo->propertyCount();
293
294 // don't save built-in properties if there aren't any qml properties
295 if (offset == 1)
296 return;
297
298 for (int i = offset; i < count; ++i) {
299 QMetaProperty property = mo->property(i);
300 const QString propertyName = QString::fromUtf8(property.name());
301
302 const QVariant previousValue = readProperty(property);
303 const QVariant currentValue = instance()->value(propertyName,
304 previousValue);
305
306 if (!currentValue.isNull() && (!previousValue.isValid()
307 || (currentValue.canConvert(previousValue.metaType())
308 && previousValue != currentValue))) {
309 property.write(q, currentValue);
310 qCDebug(lcQmlSettings) << "QQmlSettings: load" << property.name() << "setting:" << currentValue << "default:" << previousValue;
311 }
312
313 // ensure that a non-existent setting gets written
314 // even if the property wouldn't change later
315 if (!instance()->contains(propertyName))
317
318 // setup change notifications on first load
319 if (!initialized && property.hasNotifySignal()) {
320 static const int propertyChangedIndex = mo->indexOfSlot("_q_propertyChanged()");
321 QMetaObject::connect(q, property.notifySignalIndex(), q, propertyChangedIndex);
322 }
323 }
324}
325
327{
329 while (it != changedProperties.constEnd()) {
330 instance()->setValue(QString::fromUtf8(it.key()), it.value());
331 qCDebug(lcQmlSettings) << "QQmlSettings: store" << it.key() << ":" << it.value();
332 ++it;
333 }
335}
336
338{
339 Q_Q(QQmlSettings);
340 const QMetaObject *mo = q->metaObject();
341 const int offset = mo->propertyOffset();
342 const int count = mo->propertyCount();
343 for (int i = offset; i < count; ++i) {
344 const QMetaProperty &property = mo->property(i);
347 qCDebug(lcQmlSettings) << "QQmlSettings: cache" << property.name() << ":" << value;
348 }
349 if (timerId != 0)
350 q->killTimer(timerId);
351 timerId = q->startTimer(settingsWriteDelay);
352}
353
355{
356 Q_Q(const QQmlSettings);
357 QVariant var = property.read(q);
358 if (var.metaType() == QMetaType::fromType<QJSValue>())
360 return var;
361}
362
364 : QObject(parent), d_ptr(new QQmlSettingsPrivate)
365{
366 Q_D(QQmlSettings);
367 d->q_ptr = this;
368}
369
371{
372 Q_D(QQmlSettings);
373 d->reset(); // flush pending changes
374}
375
386{
387 Q_D(const QQmlSettings);
388 return d->category;
389}
390
392{
393 Q_D(QQmlSettings);
394 if (d->category == category)
395 return;
396 d->reset();
397 d->category = category;
398 if (d->initialized)
399 d->load();
401}
402
415{
416 Q_D(const QQmlSettings);
417 return d->location;
418}
419
421{
422 Q_D(QQmlSettings);
423 if (d->location == location)
424 return;
425 d->reset();
426 d->location = location;
427 if (d->initialized)
428 d->load();
430}
431
440QVariant QQmlSettings::value(const QString &key, const QVariant &defaultValue) const
441{
442 Q_D(const QQmlSettings);
443 return d->instance()->value(key, defaultValue);
444}
445
455{
456 Q_D(const QQmlSettings);
457 d->instance()->setValue(key, value);
458 qCDebug(lcQmlSettings) << "QQmlSettings: setValue" << key << ":" << value;
459}
460
475{
476 Q_D(QQmlSettings);
477 d->instance()->sync();
478}
479
481{
482}
483
485{
486 Q_D(QQmlSettings);
487 d->init();
488}
489
491{
492 Q_D(QQmlSettings);
494 if (event->timerId() != d->timerId)
495 return;
496 killTimer(d->timerId);
497 d->timerId = 0;
498 d->store();
499}
500
502
503#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:1135
\inmodule QtCore
Definition qhash.h:818
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:1209
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:1205
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:949
bool isEmpty() const noexcept
Returns true if the hash contains no items; otherwise returns false.
Definition qhash.h:926
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1283
The QJSValue class acts as a container for Qt/JavaScript data types.
Definition qjsvalue.h:31
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:90
virtual void timerEvent(QTimerEvent *event)
This event handler can be reimplemented in a subclass to receive timer events for the object.
Definition qobject.cpp:1433
void killTimer(int id)
Kills the timer with timer identifier, id.
Definition qobject.cpp:1872
\inmodule QtCore
Definition qpointer.h:18
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:127
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
\inmodule QtCore
Definition qcoreevent.h:359
\inmodule QtCore
Definition qurl.h:94
\inmodule QtCore
Definition qvariant.h:64
T value() const &
Definition qvariant.h:511
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:707
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, bool createJSValueForObjectsAndSymbols, 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:3419
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent