Warning, file /frameworks/knewstuff/src/qtquickdialogwrapper.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2020 Alexander Lohnau <alexander.lohnau@gmx.de> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include "qtquickdialogwrapper.h" 0008 0009 #include <QEventLoop> 0010 #include <QGuiApplication> 0011 #include <QQmlComponent> 0012 #include <QQmlContext> 0013 #include <QQmlEngine> 0014 #include <QTimer> 0015 #include <QWindow> 0016 0017 #include <KLocalizedContext> 0018 0019 #include "core/engine.h" 0020 #include "knewstuff_debug.h" 0021 0022 using namespace KNS3; 0023 0024 class KNS3::QtQuickDialogWrapperPrivate 0025 { 0026 public: 0027 QQmlEngine *engine = nullptr; 0028 QObject *item = nullptr; 0029 KNSCore::Engine *coreEngine = nullptr; 0030 QList<KNSCore::EntryInternal> changedEntries; 0031 }; 0032 0033 QtQuickDialogWrapper::QtQuickDialogWrapper(const QString &configFile, QObject *parent) 0034 : QObject(parent) 0035 , d(new QtQuickDialogWrapperPrivate()) 0036 { 0037 d->engine = new QQmlEngine(this); 0038 auto *context = new KLocalizedContext(d->engine); 0039 context->setTranslationDomain(QStringLiteral("knewstuff5")); 0040 d->engine->rootContext()->setContextObject(context); 0041 QQmlComponent component(d->engine); 0042 d->engine->rootContext()->setContextProperty(QStringLiteral("knsrcfile"), configFile); 0043 component.setData(QByteArrayLiteral("import QtQuick 2.7\n" 0044 "import org.kde.newstuff 1.62 as NewStuff\n" 0045 "\n" 0046 "NewStuff.Dialog {\n" 0047 " id: component\n" 0048 " signal closed()\n" 0049 " configFile: knsrcfile\n" 0050 " onVisibleChanged: if (!visible) {closed()}\n" 0051 "}"), 0052 QUrl()); 0053 d->item = component.create(); 0054 // If there is an error on the QML side of things we get a nullptr 0055 if (d->item) { 0056 d->item->setParent(this); 0057 0058 QObject *qtquickEngine = d->item->property("engine").value<QObject *>(); 0059 Q_ASSERT(qtquickEngine); 0060 d->coreEngine = qtquickEngine->property("engine").value<KNSCore::Engine *>(); 0061 Q_ASSERT(d->coreEngine); 0062 0063 connect(d->coreEngine, &KNSCore::Engine::signalEntryEvent, this, [this](const KNSCore::EntryInternal &entry, KNSCore::EntryInternal::EntryEvent event) { 0064 if (event == KNSCore::EntryInternal::StatusChangedEvent) { 0065 if (entry.status() == KNS3::Entry::Installing || entry.status() == KNS3::Entry::Updating) { 0066 return; // We do not care about intermediate states 0067 } 0068 // To make sure we have no duplicates and always the latest entry 0069 d->changedEntries.removeOne(entry); 0070 d->changedEntries.append(entry); 0071 } 0072 }); 0073 0074 // Forward relevant signals 0075 connect(d->item, SIGNAL(closed()), this, SIGNAL(closed())); 0076 0077 // Otherwise, the dialog is not in front of other popups, BUG: 452593 0078 auto window = qobject_cast<QWindow *>(d->item); 0079 Q_ASSERT(window); 0080 auto transientParent = QGuiApplication::focusWindow(); 0081 0082 // TODO KF6: only use focusWindow as transientParent 0083 // BUG 454895: If transientParent is a menu/popup, don't use it as a parent 0084 // Instead follow its parent until we get a "real" window 0085 while (transientParent && transientParent->flags().testFlag(Qt::Popup)) { 0086 transientParent = transientParent->transientParent(); 0087 } 0088 0089 window->setTransientParent(transientParent); 0090 } else { 0091 qWarning(KNEWSTUFF) << "Error creating QtQuickDialogWrapper component:" << component.errors(); 0092 } 0093 } 0094 0095 QtQuickDialogWrapper::~QtQuickDialogWrapper() 0096 { 0097 // Empty destructor needed for std::unique_ptr to incomplete class. 0098 } 0099 0100 void QtQuickDialogWrapper::open() 0101 { 0102 if (d->item) { 0103 d->changedEntries.clear(); 0104 QMetaObject::invokeMethod(d->item, "open"); 0105 } 0106 } 0107 0108 KNSCore::Engine *QtQuickDialogWrapper::engine() 0109 { 0110 return d->coreEngine; 0111 } 0112 0113 QList<KNSCore::Entry> QtQuickDialogWrapper::changedEntries() const 0114 { 0115 return d->changedEntries; 0116 } 0117 0118 #if KNEWSTUFF_BUILD_DEPRECATED_SINCE(5, 94) 0119 QList<KNSCore::EntryInternal> QtQuickDialogWrapper::exec() 0120 { 0121 open(); 0122 QEventLoop loop; 0123 connect(this, &QtQuickDialogWrapper::closed, &loop, &QEventLoop::quit); 0124 loop.exec(); 0125 return d->changedEntries; 0126 } 0127 #endif 0128 0129 #include "moc_qtquickdialogwrapper.cpp"