5#include <QtCore/private/qfactoryloader_p.h>
6#include <QtQml/qqmlcontext.h>
10Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, vectorImagePluginLoader,
11 (QQuickVectorImageFormatsPluginFactory_iid,
12 QLatin1String(
"/vectorimageformats"),
15void QQuickVectorImageWorker::process()
17 Q_ASSERT(m_generator !=
nullptr);
20 bool generatedWithPlugin =
false;
21 for (
const auto &pluginGenerator : std::as_const(m_pluginGenerators)) {
22 if ((generatedWithPlugin = pluginGenerator->generate(m_generator->fileName(), m_generator.get())))
26 if (!generatedWithPlugin)
27 m_generator->generate();
32QQuickVectorImageIncubator::QQuickVectorImageIncubator(IncubationMode incubationMode,
36 , QQmlIncubator(incubationMode)
37 , m_qmlContext(context)
41QQuickVectorImageIncubator::~QQuickVectorImageIncubator()
43 if (m_workerThread !=
nullptr && m_workerThread->isRunning()) {
44 m_workerThread->quit();
45 m_workerThread->wait();
49QQmlIncubator::Status QQuickVectorImageIncubator::status()
const
54void QQuickVectorImageIncubator::start(
const QString &fileName,
55 QQuickVectorImageGenerator::GeneratorFlags flags)
57 Q_ASSERT(m_generatorWorker ==
nullptr);
58 Q_ASSERT(m_workerThread ==
nullptr);
63 const bool asynchronous = flags.testFlag(QQuickVectorImageGenerator::AsynchronousLoading);
65 m_workerThread.reset(
new QThread);
67 m_generatorWorker.reset(
new QQuickVectorImageWorker);
68 m_generatorWorker->createGenerator(fileName, flags);
69 connect(m_generatorWorker.get(), &QQuickVectorImageWorker::finished,
70 this, &QQuickVectorImageIncubator::generatorFinished);
72 if (flags.testFlag(QQuickVectorImageGenerator::AssumeTrustedSource)) {
73 QFactoryLoader *loader = vectorImagePluginLoader();
75 const qsizetype count = loader->keyMap().size();
76 for (qsizetype i = 0; i < count; ++i) {
77 QQuickVectorImagePlugin *plugin = qobject_cast<QQuickVectorImagePlugin *>(loader->instance(i));
78 if (plugin !=
nullptr) {
79 QQuickVectorImagePluginGenerator *pluginGenerator = plugin->createGenerator(fileName);
80 if (pluginGenerator !=
nullptr)
81 m_generatorWorker->addPluginGenerator(pluginGenerator);
86 if (m_workerThread !=
nullptr) {
87 m_generatorWorker->moveToThread(m_workerThread.get());
88 m_workerThread->start();
92 QMetaObject::invokeMethod(m_generatorWorker.get(), &QQuickVectorImageWorker::process, Qt::AutoConnection);
95void QQuickVectorImageIncubator::generatorFinished()
97 Q_ASSERT(m_component ==
nullptr);
98 Q_ASSERT(m_generatorWorker !=
nullptr);
99 Q_ASSERT(m_generatorWorker->generator() !=
nullptr);
100 Q_ASSERT(m_workerThread ==
nullptr || m_workerThread->isRunning());
102 const QQuickVectorImageGenerator::ErrorState errorState = m_generatorWorker->generator()->errorState();
103 const bool asynchronous = m_generatorWorker->generator()->generatorFlags().testFlag(QQuickVectorImageGenerator::AsynchronousLoading);
104 const QByteArray result = m_generatorWorker->generator()->result();
105 const QString fileName = m_generatorWorker->generator()->fileName();
107 m_generatorWorker->disconnect(
this);
108 m_generatorWorker.release()->deleteLater();
110 if (m_workerThread !=
nullptr) {
111 m_workerThread->quit();
112 m_workerThread->wait();
113 m_workerThread.reset(
nullptr);
116 if (Q_LIKELY(errorState == QQuickVectorImageGenerator::NoError)) {
117 QQmlComponent::CompilationMode mode =
119 ? QQmlComponent::Asynchronous
120 : QQmlComponent::PreferSynchronous;
122 QQmlEngine *engine = m_qmlContext->engine();
123 if (Q_UNLIKELY(engine ==
nullptr)) {
124 qCWarning(lcQuickVectorImage) <<
"QQuickVectorImageIncubator::generatorFinished: Requires QML engine";
128 m_component.reset(
new QQmlComponent(engine));
129 connect(m_component.get(), &QQmlComponent::statusChanged,
130 this, &QQuickVectorImageIncubator::componentUpdated);
131 m_component->setData(result, QUrl{}, mode);
134 emit statusUpdated();
138void QQuickVectorImageIncubator::componentUpdated()
140 Q_ASSERT(m_component !=
nullptr);
141 Q_ASSERT(m_generatorWorker ==
nullptr);
142 Q_ASSERT(m_workerThread ==
nullptr);
144 if (!m_component->isLoading()) {
145 if (m_component->isReady()) {
146 m_component->create(*
this, m_qmlContext);
148 qCWarning(lcQuickVectorImage) <<
"Component failed to load:"
149 << m_component->errorString();
151 emit statusUpdated();
153 m_component.release()->deleteLater();
157void QQuickVectorImageIncubator::statusChanged(Status status)
159 if (m_status == status)
162 emit statusUpdated();
Combined button and popup list for selecting options.