5#include <QtCore/private/qfactoryloader_p.h>
6#include <QtQml/qqmlcontext.h>
7#include <QtQml/private/qqmlcomponent_p.h>
11Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, vectorImagePluginLoader,
12 (QQuickVectorImageFormatsPluginFactory_iid,
13 QLatin1String(
"/vectorimageformats"),
16void QQuickVectorImageWorker::process()
18 Q_ASSERT(m_generator !=
nullptr);
21 bool generatedWithPlugin =
false;
22 for (
const auto &pluginGenerator : std::as_const(m_pluginGenerators)) {
23 if ((generatedWithPlugin = pluginGenerator->generate(m_generator->fileName(), m_generator.get())))
27 if (!generatedWithPlugin)
28 m_generator->generate();
33QQuickVectorImageIncubator::QQuickVectorImageIncubator(IncubationMode incubationMode,
37 , QQmlIncubator(incubationMode)
38 , m_qmlContext(context)
42QQuickVectorImageIncubator::~QQuickVectorImageIncubator()
44 if (m_workerThread !=
nullptr && m_workerThread->isRunning()) {
45 m_workerThread->quit();
46 m_workerThread->wait();
50QQmlIncubator::Status QQuickVectorImageIncubator::status()
const
55void QQuickVectorImageIncubator::start(
const QString &fileName,
56 QQuickVectorImageGenerator::GeneratorFlags flags)
58 Q_ASSERT(m_generatorWorker ==
nullptr);
59 Q_ASSERT(m_workerThread ==
nullptr);
64 const bool asynchronous = flags.testFlag(QQuickVectorImageGenerator::AsynchronousLoading);
66 m_workerThread.reset(
new QThread);
68 m_generatorWorker.reset(
new QQuickVectorImageWorker);
69 m_generatorWorker->createGenerator(fileName, flags);
70 connect(m_generatorWorker.get(), &QQuickVectorImageWorker::finished,
71 this, &QQuickVectorImageIncubator::generatorFinished);
73 if (flags.testFlag(QQuickVectorImageGenerator::AssumeTrustedSource)) {
74 QFactoryLoader *loader = vectorImagePluginLoader();
76 const qsizetype count = loader->keyMap().size();
77 for (qsizetype i = 0; i < count; ++i) {
78 QQuickVectorImagePlugin *plugin = qobject_cast<QQuickVectorImagePlugin *>(loader->instance(i));
79 if (plugin !=
nullptr) {
80 QQuickVectorImagePluginGenerator *pluginGenerator = plugin->createGenerator(fileName);
81 if (pluginGenerator !=
nullptr)
82 m_generatorWorker->addPluginGenerator(pluginGenerator);
87 if (m_workerThread !=
nullptr) {
88 m_generatorWorker->moveToThread(m_workerThread.get());
89 m_workerThread->start();
93 QMetaObject::invokeMethod(m_generatorWorker.get(), &QQuickVectorImageWorker::process, Qt::AutoConnection);
96void QQuickVectorImageIncubator::generatorFinished()
98 Q_ASSERT(m_component ==
nullptr);
99 Q_ASSERT(m_generatorWorker !=
nullptr);
100 Q_ASSERT(m_generatorWorker->generator() !=
nullptr);
101 Q_ASSERT(m_workerThread ==
nullptr || m_workerThread->isRunning());
103 const QQuickVectorImageGenerator::ErrorState errorState = m_generatorWorker->generator()->errorState();
104 const bool asynchronous = m_generatorWorker->generator()->generatorFlags().testFlag(QQuickVectorImageGenerator::AsynchronousLoading);
105 const QByteArray result = m_generatorWorker->generator()->result();
106 const QString fileName = m_generatorWorker->generator()->fileName();
108 m_generatorWorker->disconnect(
this);
109 m_generatorWorker.release()->deleteLater();
111 if (m_workerThread !=
nullptr) {
112 m_workerThread->quit();
113 m_workerThread->wait();
114 m_workerThread.reset(
nullptr);
117 if (Q_LIKELY(errorState == QQuickVectorImageGenerator::NoError)) {
118 QQmlEngine *engine = m_qmlContext->engine();
119 if (Q_UNLIKELY(engine ==
nullptr)) {
120 qCWarning(lcQuickVectorImage) <<
"QQuickVectorImageIncubator::generatorFinished: Requires QML engine";
124 m_component.reset(
new QQmlComponent(engine));
125 connect(m_component.get(), &QQmlComponent::statusChanged,
126 this, &QQuickVectorImageIncubator::componentUpdated);
128 QQmlComponentPrivate *d = QQmlComponentPrivate::get(m_component.get());
129 d->setData(result, QUrl{}, QQmlComponent::Asynchronous);
130 emit m_component->statusChanged(m_component->status());
132 m_component->setData(result, QUrl{});
136 emit statusUpdated();
140void QQuickVectorImageIncubator::componentUpdated()
142 Q_ASSERT(m_component !=
nullptr);
143 Q_ASSERT(m_generatorWorker ==
nullptr);
144 Q_ASSERT(m_workerThread ==
nullptr);
146 if (!m_component->isLoading()) {
147 if (m_component->isReady()) {
148 m_component->create(*
this, m_qmlContext);
150 qCWarning(lcQuickVectorImage) <<
"Component failed to load:"
151 << m_component->errorString();
153 emit statusUpdated();
155 m_component.release()->deleteLater();
159void QQuickVectorImageIncubator::statusChanged(Status status)
161 if (m_status == status)
164 emit statusUpdated();
Combined button and popup list for selecting options.