diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.cpp index c1cbca6f5ee..5f448b90da5 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.cpp @@ -29,18 +29,21 @@ #include #endif +#include +#include +#include #include #include -#include -#include #include -#include +#include +#include namespace Import3D { -void import3D(const QString &sourceAsset, const QString &outDir, int exitId, const QString &options) +void import3D(const QString &sourceAsset, const QString &outDir, const QString &options) { + QString errorStr; #ifdef IMPORT_QUICK3D_ASSETS QScopedPointer importer {new QSSGAssetImportManager}; @@ -48,32 +51,35 @@ void import3D(const QString &sourceAsset, const QString &outDir, int exitId, con QJsonDocument optDoc = QJsonDocument::fromJson(options.toUtf8(), &error); if (!optDoc.isNull() && optDoc.isObject()) { - QString errorStr; QJsonObject optObj = optDoc.object(); if (importer->importFile(sourceAsset, outDir, optObj.toVariantMap(), &errorStr) != QSSGAssetImportManager::ImportState::Success) { - qWarning() << __FUNCTION__ << "Failed to import 3D asset" - << sourceAsset << "with error:" << errorStr; - } else { - // Allow little time for file operations to finish - QTimer::singleShot(2000, nullptr, [exitId]() { - qApp->exit(exitId); - }); - return; } } else { - qWarning() << __FUNCTION__ << "Failed to parse import options:" << error.errorString(); + errorStr = QObject::tr("Failed to parse import options: %1").arg(error.errorString()); } #else + errorStr = QObject::tr("QtQuick3D is not available."); Q_UNUSED(sourceAsset) Q_UNUSED(outDir) - Q_UNUSED(exitId) Q_UNUSED(options) - qWarning() << __FUNCTION__ << "Failed to parse import options, Quick3DAssetImport not available"; #endif - QTimer::singleShot(0, nullptr, [exitId]() { - // Negative exitId means import failure - qApp->exit(-exitId); + if (!errorStr.isEmpty()) { + qWarning() << __FUNCTION__ << "Failed to import asset:" << errorStr << outDir; + + // Write the error into a file in outDir to pass it to creator side + QString errorFileName = outDir + "/__error.log"; + QFile file(errorFileName); + if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + QTextStream out(&file); + out << errorStr; + file.close(); + } + } + + // Allow little time for file operations to finish + QTimer::singleShot(2000, nullptr, []() { + qApp->exit(0); }); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.h index eb2e4731724..3f53ef33c79 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.h @@ -29,5 +29,5 @@ namespace Import3D { - void import3D(const QString &sourceAsset, const QString &outDir, int id, const QString &options); + void import3D(const QString &sourceAsset, const QString &outDir, const QString &options); }; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp index 8b6135c6222..5a7e0d7dd8b 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp @@ -228,10 +228,9 @@ int internalMain(QGuiApplication *application) if (application->arguments().at(1) == "--import3dAsset") { QString sourceAsset = application->arguments().at(2); QString outDir = application->arguments().at(3); - int exitId = application->arguments().at(4).toInt(); - QString options = application->arguments().at(5); + QString options = application->arguments().at(4); - Import3D::import3D(sourceAsset, outDir, exitId, options); + Import3D::import3D(sourceAsset, outDir, options); return application->exec(); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp index 1ff31aad632..7e22efe016f 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp @@ -142,9 +142,10 @@ void ItemLibraryAssetImporter::addInfo(const QString &infoMsg, const QString &sr emit infoReported(infoMsg, srcPath); } -void ItemLibraryAssetImporter::importProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +void ItemLibraryAssetImporter::importProcessFinished(int exitCode, QProcess::ExitStatus exitStatus, + int importId) { - Q_UNUSED(exitStatus) + Q_UNUSED(exitCode) ++m_qmlImportFinishedCount; @@ -154,9 +155,32 @@ void ItemLibraryAssetImporter::importProcessFinished(int exitCode, QProcess::Exi return !entry || entry->state() == QProcess::NotRunning; })); - if (m_parseData.contains(-exitCode)) { - const ParseData pd = m_parseData.take(-exitCode); - addError(tr("Asset import process failed for: \"%1\".").arg(pd.sourceInfo.absoluteFilePath())); + if (m_parseData.contains(importId)) { + const ParseData &pd = m_parseData[importId]; + QString errStr; + if (exitStatus == QProcess::ExitStatus::CrashExit) { + errStr = tr("Import process crashed."); + } else { + bool unknownFail = !pd.outDir.exists() || pd.outDir.isEmpty(); + if (!unknownFail) { + QFile errorLog(pd.outDir.filePath("__error.log")); + if (errorLog.exists()) { + if (errorLog.open(QIODevice::ReadOnly)) + errStr = QString::fromUtf8(errorLog.readAll()); + else + unknownFail = true; + } + } + if (unknownFail) + errStr = tr("Import failed for unknown reason."); + } + + if (!errStr.isEmpty()) { + addError(tr("Asset import process failed: \"%1\".") + .arg(pd.sourceInfo.absoluteFilePath())); + addError(errStr); + m_parseData.remove(importId); + } } if (m_qmlImportFinishedCount == m_qmlPuppetCount) { @@ -565,15 +589,14 @@ bool ItemLibraryAssetImporter::startImportProcess(const ParseData &pd) QJsonDocument optDoc(pd.options); puppetArgs << "--import3dAsset" << pd.sourceInfo.absoluteFilePath() - << pd.outDir.absolutePath() << QString::number(pd.importId) - << QString::fromUtf8(optDoc.toJson()); + << pd.outDir.absolutePath() << QString::fromUtf8(optDoc.toJson()); QProcessUniquePointer process = puppetCreator.createPuppetProcess( "custom", {}, [&] {}, [&](int exitCode, QProcess::ExitStatus exitStatus) { - importProcessFinished(exitCode, exitStatus); + importProcessFinished(exitCode, exitStatus, pd.importId); }, puppetArgs); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h index 9abc315fbe0..83be9af5f4e 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h @@ -74,7 +74,7 @@ signals: void importFinished(); private slots: - void importProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + void importProcessFinished(int exitCode, QProcess::ExitStatus exitStatus, int importId); void iconProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); private: @@ -125,7 +125,7 @@ private: std::vector m_qmlPuppetProcesses; int m_qmlPuppetCount = 0; int m_qmlImportFinishedCount = 0; - int m_importIdCounter = 1000000; // Use ids in range unlikely to clash with any normal process exit codes + int m_importIdCounter = 0; QHash m_parseData; QString m_progressTitle; QList m_requiredImports;