aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-08-28 11:51:57 +0200
committerUlf Hermann <ulf.hermann@qt.io>2018-08-30 09:06:40 +0000
commite56e964aa5975b08eb003f0280118fb6f6b5f95f (patch)
tree26670a773b0359133629bf5992d02f5f0f900a50
parent8ef4964168ccca6153cd9dbfc631043d8293e370 (diff)
Tracing: Properly signal destruction of non-owned properties
When the zoomer, model, or notes properties for TimelineAbstractRenderer are destroyed, the QPointers become null, and therefore the change signals need to be emitted, and an update to the widget should be scheduled. If this is not done, clients using the property might keep a dangling pointer in some cache and dereference it later. Change-Id: I63fb657afb8138e9ac54c7d839d4a52271f8f3e8 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--src/libs/tracing/timelineabstractrenderer.cpp54
1 files changed, 44 insertions, 10 deletions
diff --git a/src/libs/tracing/timelineabstractrenderer.cpp b/src/libs/tracing/timelineabstractrenderer.cpp
index 4b9f775c3b..c2e8886ee1 100644
--- a/src/libs/tracing/timelineabstractrenderer.cpp
+++ b/src/libs/tracing/timelineabstractrenderer.cpp
@@ -108,9 +108,12 @@ void TimelineAbstractRenderer::setModel(TimelineModel *model)
this, &TimelineAbstractRenderer::setRowHeightsDirty);
disconnect(d->model, &TimelineModel::contentChanged,
this, &TimelineAbstractRenderer::setModelDirty);
+ disconnect(d->model, &QObject::destroyed, this, nullptr);
+ d->renderPasses.clear();
}
d->model = model;
+
if (d->model) {
connect(d->model, &TimelineModel::expandedChanged, this, &QQuickItem::update);
connect(d->model, &TimelineModel::hiddenChanged, this, &QQuickItem::update);
@@ -118,6 +121,13 @@ void TimelineAbstractRenderer::setModel(TimelineModel *model)
this, &TimelineAbstractRenderer::setRowHeightsDirty);
connect(d->model, &TimelineModel::contentChanged,
this, &TimelineAbstractRenderer::setModelDirty);
+ connect(d->model, &QObject::destroyed, this, [this, d]() {
+ // Weak pointers are supposed to be notified before the destroyed() signal is sent.
+ Q_ASSERT(d->model.isNull());
+ d->renderPasses.clear();
+ setModelDirty();
+ emit modelChanged(d->model);
+ });
d->renderPasses = d->model->supportedRenderPasses();
}
@@ -137,14 +147,23 @@ void TimelineAbstractRenderer::setNotes(TimelineNotesModel *notes)
if (d->notes == notes)
return;
- if (d->notes)
+ if (d->notes) {
disconnect(d->notes, &TimelineNotesModel::changed,
this, &TimelineAbstractRenderer::setNotesDirty);
+ disconnect(d->notes, &QObject::destroyed, this, nullptr);
+ }
d->notes = notes;
- if (d->notes)
+ if (d->notes) {
connect(d->notes, &TimelineNotesModel::changed,
this, &TimelineAbstractRenderer::setNotesDirty);
+ connect(d->notes, &QObject::destroyed, this, [this, d]() {
+ // Weak pointers are supposed to be notified before the destroyed() signal is sent.
+ Q_ASSERT(d->notes.isNull());
+ setNotesDirty();
+ emit notesChanged(d->notes);
+ });
+ }
setNotesDirty();
emit notesChanged(d->notes);
@@ -160,11 +179,20 @@ void TimelineAbstractRenderer::setZoomer(TimelineZoomControl *zoomer)
{
Q_D(TimelineAbstractRenderer);
if (zoomer != d->zoomer) {
- if (d->zoomer != 0)
+ if (d->zoomer) {
disconnect(d->zoomer, &TimelineZoomControl::windowChanged, this, &QQuickItem::update);
+ disconnect(d->zoomer, &QObject::destroyed, this, nullptr);
+ }
d->zoomer = zoomer;
- if (d->zoomer != 0)
+ if (d->zoomer) {
connect(d->zoomer, &TimelineZoomControl::windowChanged, this, &QQuickItem::update);
+ connect(d->zoomer, &QObject::destroyed, this, [this, d]() {
+ // Weak pointers are supposed to be notified before the destroyed() signal is sent.
+ Q_ASSERT(d->zoomer.isNull());
+ emit zoomerChanged(d->zoomer);
+ update();
+ });
+ }
emit zoomerChanged(zoomer);
update();
}
@@ -191,22 +219,28 @@ bool TimelineAbstractRenderer::rowHeightsDirty() const
void TimelineAbstractRenderer::setModelDirty()
{
Q_D(TimelineAbstractRenderer);
- d->modelDirty = true;
- update();
+ if (!d->modelDirty) {
+ d->modelDirty = true;
+ update();
+ }
}
void TimelineAbstractRenderer::setRowHeightsDirty()
{
Q_D(TimelineAbstractRenderer);
- d->rowHeightsDirty = true;
- update();
+ if (!d->rowHeightsDirty) {
+ d->rowHeightsDirty = true;
+ update();
+ }
}
void TimelineAbstractRenderer::setNotesDirty()
{
Q_D(TimelineAbstractRenderer);
- d->notesDirty = true;
- update();
+ if (!d->notesDirty) {
+ d->notesDirty = true;
+ update();
+ }
}
// Reset the dirty flags, delete the old node (if given), and return 0