summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2016-10-21 15:08:05 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2016-11-03 08:31:16 +0000
commit8575ed82ff0dd43aed8f5de67b4cfef06fec8c33 (patch)
treecca94f81ed02915f5301bd8b6ce859f63ec00d29
parent01a560811df01514673315dc461ad7f51eff1dfa (diff)
Fix a leak and a crash in designerv5.7.1
This change downports the 56ac0c12ab5e7269e16bcc1248e4241302d91d09 change to the 5.7.1 branch in order to have a chance for releasing Qt Creator 4.2 with a fix. The crash doesn't appear in the standalone Designer, it only appears in the Designer plugin of Qt Creator during reload. There is no other way to fix that crash outside of Qt. Task-number: QTCREATORBUG-17150 Change-Id: Ide521677a1526d3de862d0d8e283531a67b2a7a8 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> (cherry picked from commit 56ac0c12ab5e7269e16bcc1248e4241302d91d09)
-rw-r--r--src/designer/src/lib/shared/formwindowbase.cpp61
-rw-r--r--src/designer/src/lib/shared/formwindowbase_p.h4
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertysheet.cpp35
3 files changed, 71 insertions, 29 deletions
diff --git a/src/designer/src/lib/shared/formwindowbase.cpp b/src/designer/src/lib/shared/formwindowbase.cpp
index e702d777a..d8f422a0a 100644
--- a/src/designer/src/lib/shared/formwindowbase.cpp
+++ b/src/designer/src/lib/shared/formwindowbase.cpp
@@ -47,6 +47,7 @@
#include <QtCore/qdebug.h>
#include <QtCore/QList>
+#include <QtCore/QSet>
#include <QtCore/QTimer>
#include <QtWidgets/QMenu>
#include <QtWidgets/QListWidget>
@@ -112,6 +113,15 @@ FormWindowBase::FormWindowBase(QDesignerFormEditorInterface *core, QWidget *pare
FormWindowBase::~FormWindowBase()
{
+ QSet<QDesignerPropertySheet *> sheets = m_d->m_reloadableResources.keys().toSet();
+ sheets |= m_d->m_reloadablePropertySheets.keys().toSet();
+
+ m_d->m_reloadableResources.clear();
+ m_d->m_reloadablePropertySheets.clear();
+
+ for (QDesignerPropertySheet *sheet : sheets)
+ disconnectSheet(sheet);
+
delete m_d;
}
@@ -137,14 +147,17 @@ void FormWindowBase::setResourceSet(QtResourceSet *resourceSet)
void FormWindowBase::addReloadableProperty(QDesignerPropertySheet *sheet, int index)
{
+ connectSheet(sheet);
m_d->m_reloadableResources[sheet][index] = true;
}
void FormWindowBase::removeReloadableProperty(QDesignerPropertySheet *sheet, int index)
{
m_d->m_reloadableResources[sheet].remove(index);
- if (m_d->m_reloadableResources[sheet].count() == 0)
+ if (!m_d->m_reloadableResources[sheet].count()) {
m_d->m_reloadableResources.remove(sheet);
+ disconnectSheet(sheet);
+ }
}
void FormWindowBase::addReloadablePropertySheet(QDesignerPropertySheet *sheet, QObject *object)
@@ -152,13 +165,53 @@ void FormWindowBase::addReloadablePropertySheet(QDesignerPropertySheet *sheet, Q
if (qobject_cast<QTreeWidget *>(object) ||
qobject_cast<QTableWidget *>(object) ||
qobject_cast<QListWidget *>(object) ||
- qobject_cast<QComboBox *>(object))
+ qobject_cast<QComboBox *>(object)) {
+ connectSheet(sheet);
m_d->m_reloadablePropertySheets[sheet] = object;
+ }
}
-void FormWindowBase::removeReloadablePropertySheet(QDesignerPropertySheet *sheet)
+void FormWindowBase::connectSheet(QDesignerPropertySheet *sheet)
{
- m_d->m_reloadablePropertySheets.remove(sheet);
+ if (m_d->m_reloadableResources.contains(sheet)
+ || m_d->m_reloadablePropertySheets.contains(sheet)) {
+ // already connected
+ return;
+ }
+ connect(sheet, &QObject::destroyed, this, &FormWindowBase::sheetDestroyed);
+}
+
+void FormWindowBase::disconnectSheet(QDesignerPropertySheet *sheet)
+{
+ if (m_d->m_reloadableResources.contains(sheet)
+ || m_d->m_reloadablePropertySheets.contains(sheet)) {
+ // still need to be connected
+ return;
+ }
+ disconnect(sheet, &QObject::destroyed, this, &FormWindowBase::sheetDestroyed);
+}
+
+void FormWindowBase::sheetDestroyed(QObject *object)
+{
+ // qobject_cast<QDesignerPropertySheet *>(object)
+ // will fail since the destructor of QDesignerPropertySheet
+ // has already finished
+
+ for (auto it = m_d->m_reloadableResources.begin();
+ it != m_d->m_reloadableResources.end(); ++it) {
+ if (it.key() == object) {
+ m_d->m_reloadableResources.erase(it);
+ break;
+ }
+ }
+
+ for (auto it = m_d->m_reloadablePropertySheets.begin();
+ it != m_d->m_reloadablePropertySheets.end(); ++it) {
+ if (it.key() == object) {
+ m_d->m_reloadablePropertySheets.erase(it);
+ break;
+ }
+ }
}
void FormWindowBase::reloadProperties()
diff --git a/src/designer/src/lib/shared/formwindowbase_p.h b/src/designer/src/lib/shared/formwindowbase_p.h
index 0740e48a6..ceb8beb80 100644
--- a/src/designer/src/lib/shared/formwindowbase_p.h
+++ b/src/designer/src/lib/shared/formwindowbase_p.h
@@ -138,7 +138,6 @@ public:
void addReloadableProperty(QDesignerPropertySheet *sheet, int index);
void removeReloadableProperty(QDesignerPropertySheet *sheet, int index);
void addReloadablePropertySheet(QDesignerPropertySheet *sheet, QObject *object);
- void removeReloadablePropertySheet(QDesignerPropertySheet *sheet);
void reloadProperties();
void emitWidgetRemoved(QWidget *w);
@@ -167,9 +166,12 @@ public slots:
private slots:
void triggerDefaultAction(QWidget *w);
+ void sheetDestroyed(QObject *object);
private:
void syncGridFeature();
+ void connectSheet(QDesignerPropertySheet *sheet);
+ void disconnectSheet(QDesignerPropertySheet *sheet);
FormWindowBasePrivate *m_d;
};
diff --git a/src/designer/src/lib/shared/qdesigner_propertysheet.cpp b/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
index 3caaba690..6a0910e2a 100644
--- a/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
+++ b/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
@@ -699,8 +699,6 @@ QDesignerPropertySheet::QDesignerPropertySheet(QObject *object, QObject *parent)
QDesignerPropertySheet::~QDesignerPropertySheet()
{
- if (d->m_fwb)
- d->m_fwb->removeReloadablePropertySheet(this);
delete d;
}
@@ -1627,8 +1625,6 @@ struct QDesignerAbstractPropertySheetFactory::PropertySheetFactoryPrivate {
typedef QMap<QObject*, QObject*> ExtensionMap;
ExtensionMap m_extensions;
- typedef QHash<QObject*, bool> ExtendedSet;
- ExtendedSet m_extended;
};
QDesignerAbstractPropertySheetFactory::PropertySheetFactoryPrivate::PropertySheetFactoryPrivate() :
@@ -1653,30 +1649,20 @@ QDesignerAbstractPropertySheetFactory::~QDesignerAbstractPropertySheetFactory()
QObject *QDesignerAbstractPropertySheetFactory::extension(QObject *object, const QString &iid) const
{
- typedef PropertySheetFactoryPrivate::ExtensionMap ExtensionMap;
if (!object)
return 0;
if (iid != m_impl->m_propertySheetId && iid != m_impl->m_dynamicPropertySheetId)
return 0;
- ExtensionMap::iterator it = m_impl->m_extensions.find(object);
- if (it == m_impl->m_extensions.end()) {
- if (QObject *ext = createPropertySheet(object, const_cast<QDesignerAbstractPropertySheetFactory*>(this))) {
- connect(ext, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed);
- it = m_impl->m_extensions.insert(object, ext);
- }
- }
-
- if (!m_impl->m_extended.contains(object)) {
+ QObject *ext = m_impl->m_extensions.value(object, 0);
+ if (!ext && (ext = createPropertySheet(object, const_cast<QDesignerAbstractPropertySheetFactory*>(this)))) {
+ connect(ext, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed);
connect(object, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed);
- m_impl->m_extended.insert(object, true);
+ m_impl->m_extensions.insert(object, ext);
}
- if (it == m_impl->m_extensions.end())
- return 0;
-
- return it.value();
+ return ext;
}
void QDesignerAbstractPropertySheetFactory::objectDestroyed(QObject *object)
@@ -1684,14 +1670,15 @@ void QDesignerAbstractPropertySheetFactory::objectDestroyed(QObject *object)
QMutableMapIterator<QObject*, QObject*> it(m_impl->m_extensions);
while (it.hasNext()) {
it.next();
-
- QObject *o = it.key();
- if (o == object || object == it.value()) {
+ if (it.key() == object || it.value() == object) {
+ if (it.key() == object) {
+ QObject *ext = it.value();
+ disconnect(ext, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed);
+ delete ext;
+ }
it.remove();
}
}
-
- m_impl->m_extended.remove(object);
}
QT_END_NAMESPACE