void ensureInitialized() { if (!onVisibleChanged.isValid()) { int index = q_ptr->metaObject()->indexOfMethod("implementationVisibileChanged()"); Q_ASSERT(index >= 0); onVisibleChanged = q_ptr->metaObject()->method(index); } if (component.isNull()) { Config config; config.beginGroup(QStringLiteral("qml/themes")); QString themeName = config.value(dialogName, QStringLiteral("default")); QString themePath = ThemeManager::path(QStringLiteral("qml/") + dialogName, themeName); if (themePath.isEmpty()) { qWarning() << "Failed to find theme:" << themeName << "for dialog:" << dialogName; themePath = ThemeManager::path(QStringLiteral("qml/") + dialogName, QStringLiteral("default")); if (themePath.isEmpty()) { qCritical() << "Failed to find default theme for dialog:" << dialogName; return; } } QString fileName = themePath + QStringLiteral("/main.qml"); component.reset(new QQmlComponent(DeclarativeView::globalEngine(), fileName)); } if (dialog.isNull()) { dialog = component->create(); visibleProperty = QMetaProperty(); if (!dialog) { qCritical() << "Failed to create object for component:" << component->url() << "errors:"; for (QQmlError error : component->errors()) { qCritical() << error.toString(); } return; } deathConnection = QObject::connect(dialog.data(), &QObject::destroyed, q_ptr, [this] () { dialog.clear(); visibleProperty = QMetaProperty(); updateVisible(); }); int visibleIndex = dialog->metaObject()->indexOfProperty("visible"); if (visibleIndex < 0) { qCritical() << "Failed to find \"visible\" property for component:" << component->url(); return; } visibleProperty = dialog->metaObject()->property(visibleIndex); if (!visibleProperty.hasNotifySignal()) { qCritical() << "Property \"visible\" has no notify signal for component:" << component->url(); } else { QObject::connect(dialog.data(), visibleProperty.notifySignal(), q_ptr, onVisibleChanged); } updateVisible(); } }