summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2020-12-14 12:27:53 +0100
committerIvan Solovev <ivan.solovev@qt.io>2021-04-21 15:34:28 +0200
commit1a65a4faf52f83ba3fbbba88cea1c4bb800e8de7 (patch)
tree3873a758298aba37faade1b1cd60c755815eae1c /src
parent696f5ffc64ac90e92520fd8cf9e8313fe80e3b76 (diff)
QObject: port to new property system
Extended QObjectPrivate::ExtraData to store a pointer to its parent, and reimplemented qGetBindingStorage() function for QObjectPrivate::ExtraData. This allows to use Q_OBJECT_COMPAT_PROPERTY macro for a property, stored in QObjectPrivate::ExtraData and solves all the problems with calling a custom setter. Task-number: QTBUG-85520 Change-Id: I40e01c29430846359ef9160fa1ae97c702be9a18 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qhooks.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp30
-rw-r--r--src/corelib/kernel/qobject.h4
-rw-r--r--src/corelib/kernel/qobject_p.h31
4 files changed, 55 insertions, 12 deletions
diff --git a/src/corelib/global/qhooks.cpp b/src/corelib/global/qhooks.cpp
index c3a625bb5f..491e126b7a 100644
--- a/src/corelib/global/qhooks.cpp
+++ b/src/corelib/global/qhooks.cpp
@@ -67,7 +67,7 @@ quintptr Q_CORE_EXPORT qtHookData[] = {
// The required sizes and offsets are tested in tests/auto/other/toolsupport.
// When this fails and the change was intentional, adjust the test and
// adjust this value here.
- 20
+ 21
};
static_assert(QHooks::LastHookIndex == sizeof(qtHookData) / sizeof(qtHookData[0]));
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 343922581c..b115066dce 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1214,6 +1214,11 @@ QObjectPrivate::Connection::~Connection()
QString QObject::objectName() const
{
Q_D(const QObject);
+ if (!d->extraData && QtPrivate::isAnyBindingEvaluating()) {
+ QObjectPrivate *dd = const_cast<QObjectPrivate *>(d);
+ // extraData is mutable, so this should be safe
+ dd->extraData = new QObjectPrivate::ExtraData(dd);
+ }
return d->extraData ? d->extraData->objectName : QString();
}
@@ -1223,15 +1228,28 @@ QString QObject::objectName() const
void QObject::setObjectName(const QString &name)
{
Q_D(QObject);
+
if (!d->extraData)
- d->extraData = new QObjectPrivate::ExtraData;
+ d->extraData = new QObjectPrivate::ExtraData(d);
+
+ d->extraData->objectName.removeBindingUnlessInWrapper();
if (d->extraData->objectName != name) {
- d->extraData->objectName = name;
- emit objectNameChanged(d->extraData->objectName, QPrivateSignal());
+ d->extraData->objectName.setValueBypassingBindings(name);
+ d->extraData->objectName.notify(); // also emits a signal
}
}
+QBindable<QString> QObject::bindableObjectName()
+{
+ Q_D(QObject);
+
+ if (!d->extraData)
+ d->extraData = new QObjectPrivate::ExtraData(d);
+
+ return QBindable<QString>(&d->extraData->objectName);
+}
+
/*! \fn void QObject::objectNameChanged(const QString &objectName)
This signal is emitted after the object's name has been changed. The new object name is passed as \a objectName.
@@ -1731,7 +1749,7 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)
}
int timerId = thisThreadData->eventDispatcher.loadRelaxed()->registerTimer(interval, timerType, this);
if (!d->extraData)
- d->extraData = new QObjectPrivate::ExtraData;
+ d->extraData = new QObjectPrivate::ExtraData(d);
d->extraData->runningTimers.append(timerId);
return timerId;
}
@@ -2164,7 +2182,7 @@ void QObject::installEventFilter(QObject *obj)
}
if (!d->extraData)
- d->extraData = new QObjectPrivate::ExtraData;
+ d->extraData = new QObjectPrivate::ExtraData(d);
// clean up unused items in the list
d->extraData->eventFilters.removeAll((QObject *)nullptr);
@@ -3971,7 +3989,7 @@ bool QObject::setProperty(const char *name, const QVariant &value)
int id = meta->indexOfProperty(name);
if (id < 0) {
if (!d->extraData)
- d->extraData = new QObjectPrivate::ExtraData;
+ d->extraData = new QObjectPrivate::ExtraData(d);
const int idx = d->extraData->propertyNames.indexOf(name);
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 5742db1c22..c59518367d 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -120,7 +120,8 @@ class Q_CORE_EXPORT QObject
{
Q_OBJECT
- Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged)
+ Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged
+ BINDABLE bindableObjectName)
Q_DECLARE_PRIVATE(QObject)
public:
@@ -137,6 +138,7 @@ public:
QString objectName() const;
void setObjectName(const QString &name);
+ QBindable<QString> bindableObjectName();
inline bool isWidgetType() const { return d_ptr->isWidget; }
inline bool isWindowType() const { return d_ptr->isWindow; }
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 019473018f..673c75fff1 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -61,6 +61,7 @@
#include "QtCore/qsharedpointer.h"
#include "QtCore/qvariant.h"
#include "QtCore/qproperty.h"
+#include "QtCore/private/qproperty_p.h"
QT_BEGIN_NAMESPACE
@@ -102,12 +103,26 @@ class Q_CORE_EXPORT QObjectPrivate : public QObjectData
public:
struct ExtraData
{
- ExtraData() {}
+ ExtraData(QObjectPrivate *ptr) : parent(ptr) { }
+
+ inline void setObjectNameForwarder(const QString &name)
+ {
+ parent->q_func()->setObjectName(name);
+ }
+
+ inline void nameChangedForwarder(const QString &name)
+ {
+ emit parent->q_func()->objectNameChanged(name, QObject::QPrivateSignal());
+ }
+
QList<QByteArray> propertyNames;
QList<QVariant> propertyValues;
QList<int> runningTimers;
QList<QPointer<QObject>> eventFilters;
- QString objectName;
+ Q_OBJECT_COMPAT_PROPERTY(QObjectPrivate::ExtraData, QString, objectName,
+ &QObjectPrivate::ExtraData::setObjectNameForwarder,
+ &QObjectPrivate::ExtraData::nameChangedForwarder)
+ QObjectPrivate *parent;
};
typedef void (*StaticMetaCallFunction)(QObject *, QMetaObject::Call, int, void **);
@@ -369,8 +384,9 @@ public:
cd->ref.ref();
connections.storeRelaxed(cd);
}
+
public:
- ExtraData *extraData; // extra data set by the user
+ mutable ExtraData *extraData; // extra data set by the user
// This atomic requires acquire/release semantics in a few places,
// e.g. QObject::moveToThread must synchronize with QCoreApplication::postEvent,
// because postEvent is thread-safe.
@@ -619,7 +635,14 @@ inline QBindingStorage *qGetBindingStorage(QObjectPrivate *o)
{
return &o->bindingStorage;
}
-
+inline const QBindingStorage *qGetBindingStorage(const QObjectPrivate::ExtraData *ed)
+{
+ return &ed->parent->bindingStorage;
+}
+inline QBindingStorage *qGetBindingStorage(QObjectPrivate::ExtraData *ed)
+{
+ return &ed->parent->bindingStorage;
+}
QT_END_NAMESPACE