From 757af1e2e51903c41cb8d65c58a80a6fd2021fbb Mon Sep 17 00:00:00 2001 From: vladest Date: Tue, 15 Aug 2017 14:44:01 +0200 Subject: [PATCH] Added Save, Directory and Assets async methods --- interface/src/Application.cpp | 2 + interface/src/assets/ATPAssetMigrator.cpp | 266 +++++++++++----------- libraries/ui/src/OffscreenUi.cpp | 110 ++++++++- libraries/ui/src/OffscreenUi.h | 8 + 4 files changed, 254 insertions(+), 132 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 966cead203..130ef49dd0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6776,6 +6776,8 @@ void Application::loadDialog() { auto scriptEngines = DependencyManager::get(); auto offscreenUi = DependencyManager::get(); connect(offscreenUi.data(), &OffscreenUi::fileDialogResponse, this, [=] (QString response) { + auto offscreenUi = DependencyManager::get(); + disconnect(offscreenUi.data(), &OffscreenUi::fileDialogResponse, this, nullptr); if (!response.isEmpty() && QFile(response).exists()) { setPreviousScriptLocation(QFileInfo(response).absolutePath()); DependencyManager::get()->loadScript(response, true, false, false, true); // Don't load from cache diff --git a/interface/src/assets/ATPAssetMigrator.cpp b/interface/src/assets/ATPAssetMigrator.cpp index 45459683e8..a86c012a55 100644 --- a/interface/src/assets/ATPAssetMigrator.cpp +++ b/interface/src/assets/ATPAssetMigrator.cpp @@ -42,159 +42,165 @@ static const QString COMPOUND_SHAPE_URL_KEY = "compoundShapeURL"; static const QString MESSAGE_BOX_TITLE = "ATP Asset Migration"; void ATPAssetMigrator::loadEntityServerFile() { - auto filename = OffscreenUi::getOpenFileName(_dialogParent, tr("Select an entity-server content file to migrate"), QString(), tr("Entity-Server Content (*.gz)")); - - if (!filename.isEmpty()) { - qCDebug(asset_migrator) << "Selected filename for ATP asset migration: " << filename; - - auto migrateResources = [=](QUrl migrationURL, QJsonValueRef jsonValue, bool isModelURL) { - auto request = - DependencyManager::get()->createResourceRequest(this, migrationURL); - - if (request) { - qCDebug(asset_migrator) << "Requesting" << migrationURL << "for ATP asset migration"; - - // add this combination of QUrl and QJsonValueRef to our multi hash so we can change the URL - // to an ATP one once ready - _pendingReplacements.insert(migrationURL, { jsonValue, (isModelURL ? 0 : 1)}); - - connect(request, &ResourceRequest::finished, this, [=]() { - if (request->getResult() == ResourceRequest::Success) { - migrateResource(request); - } else { - ++_errorCount; - _pendingReplacements.remove(migrationURL); - qWarning() << "Could not retrieve asset at" << migrationURL.toString(); - - checkIfFinished(); - } - request->deleteLater(); - }); - - request->send(); - } else { - ++_errorCount; - qWarning() << "Count not create request for asset at" << migrationURL.toString(); - } - - }; - static const QString MIGRATION_CONFIRMATION_TEXT { - "The ATP Asset Migration process will scan the selected entity-server file,\nupload discovered resources to the"\ - " current asset-server\nand then save a new entity-server file with the ATP URLs.\n\nAre you ready to"\ - " continue?\n\nMake sure you are connected to the right domain." - }; - + auto offscreenUi = DependencyManager::get(); + connect(offscreenUi.data(), &OffscreenUi::fileDialogResponse, this, [=] (QString filename) { auto offscreenUi = DependencyManager::get(); - QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=] (QMessageBox::StandardButton answer) { + disconnect(offscreenUi.data(), &OffscreenUi::fileDialogResponse, this, nullptr); + if (!filename.isEmpty()) { + qCDebug(asset_migrator) << "Selected filename for ATP asset migration: " << filename; + + auto migrateResources = [=](QUrl migrationURL, QJsonValueRef jsonValue, bool isModelURL) { + auto request = + DependencyManager::get()->createResourceRequest(this, migrationURL); + + if (request) { + qCDebug(asset_migrator) << "Requesting" << migrationURL << "for ATP asset migration"; + + // add this combination of QUrl and QJsonValueRef to our multi hash so we can change the URL + // to an ATP one once ready + _pendingReplacements.insert(migrationURL, { jsonValue, (isModelURL ? 0 : 1)}); + + connect(request, &ResourceRequest::finished, this, [=]() { + if (request->getResult() == ResourceRequest::Success) { + migrateResource(request); + } else { + ++_errorCount; + _pendingReplacements.remove(migrationURL); + qWarning() << "Could not retrieve asset at" << migrationURL.toString(); + + checkIfFinished(); + } + request->deleteLater(); + }); + + request->send(); + } else { + ++_errorCount; + qWarning() << "Count not create request for asset at" << migrationURL.toString(); + } + + }; + static const QString MIGRATION_CONFIRMATION_TEXT { + "The ATP Asset Migration process will scan the selected entity-server file,\nupload discovered resources to the"\ + " current asset-server\nand then save a new entity-server file with the ATP URLs.\n\nAre you ready to"\ + " continue?\n\nMake sure you are connected to the right domain." + }; + auto offscreenUi = DependencyManager::get(); - QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr); + QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=] (QMessageBox::StandardButton answer) { + auto offscreenUi = DependencyManager::get(); + QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr); - if (QMessageBox::Yes == answer) { - // try to open the file at the given filename - QFile modelsFile { filename }; + if (QMessageBox::Yes == answer) { + // try to open the file at the given filename + QFile modelsFile { filename }; - if (modelsFile.open(QIODevice::ReadOnly)) { - QByteArray compressedJsonData = modelsFile.readAll(); - QByteArray jsonData; + if (modelsFile.open(QIODevice::ReadOnly)) { + QByteArray compressedJsonData = modelsFile.readAll(); + QByteArray jsonData; - if (!gunzip(compressedJsonData, jsonData)) { - OffscreenUi::asyncWarning(_dialogParent, "Error", "The file at" + filename + "was not in gzip format."); - } + if (!gunzip(compressedJsonData, jsonData)) { + OffscreenUi::asyncWarning(_dialogParent, "Error", "The file at" + filename + "was not in gzip format."); + } - QJsonDocument modelsJSON = QJsonDocument::fromJson(jsonData); - _entitiesArray = modelsJSON.object()["Entities"].toArray(); + QJsonDocument modelsJSON = QJsonDocument::fromJson(jsonData); + _entitiesArray = modelsJSON.object()["Entities"].toArray(); - for (auto jsonValue : _entitiesArray) { - QJsonObject entityObject = jsonValue.toObject(); - QString modelURLString = entityObject.value(MODEL_URL_KEY).toString(); - QString compoundURLString = entityObject.value(COMPOUND_SHAPE_URL_KEY).toString(); + for (auto jsonValue : _entitiesArray) { + QJsonObject entityObject = jsonValue.toObject(); + QString modelURLString = entityObject.value(MODEL_URL_KEY).toString(); + QString compoundURLString = entityObject.value(COMPOUND_SHAPE_URL_KEY).toString(); - for (int i = 0; i < 2; ++i) { - bool isModelURL = (i == 0); - quint8 replacementType = i; - auto migrationURLString = (isModelURL) ? modelURLString : compoundURLString; + for (int i = 0; i < 2; ++i) { + bool isModelURL = (i == 0); + quint8 replacementType = i; + auto migrationURLString = (isModelURL) ? modelURLString : compoundURLString; - if (!migrationURLString.isEmpty()) { - QUrl migrationURL = QUrl(migrationURLString); + if (!migrationURLString.isEmpty()) { + QUrl migrationURL = QUrl(migrationURLString); - if (!_ignoredUrls.contains(migrationURL) - && (migrationURL.scheme() == URL_SCHEME_HTTP || migrationURL.scheme() == URL_SCHEME_HTTPS - || migrationURL.scheme() == URL_SCHEME_FILE || migrationURL.scheme() == URL_SCHEME_FTP)) { + if (!_ignoredUrls.contains(migrationURL) + && (migrationURL.scheme() == URL_SCHEME_HTTP || migrationURL.scheme() == URL_SCHEME_HTTPS + || migrationURL.scheme() == URL_SCHEME_FILE || migrationURL.scheme() == URL_SCHEME_FTP)) { - if (_pendingReplacements.contains(migrationURL)) { - // we already have a request out for this asset, just store the QJsonValueRef - // so we can do the hash replacement when the request comes back - _pendingReplacements.insert(migrationURL, { jsonValue, replacementType }); - } else if (_uploadedAssets.contains(migrationURL)) { - // we already have a hash for this asset - // so just do the replacement immediately - if (isModelURL) { - entityObject[MODEL_URL_KEY] = _uploadedAssets.value(migrationURL).toString(); + if (_pendingReplacements.contains(migrationURL)) { + // we already have a request out for this asset, just store the QJsonValueRef + // so we can do the hash replacement when the request comes back + _pendingReplacements.insert(migrationURL, { jsonValue, replacementType }); + } else if (_uploadedAssets.contains(migrationURL)) { + // we already have a hash for this asset + // so just do the replacement immediately + if (isModelURL) { + entityObject[MODEL_URL_KEY] = _uploadedAssets.value(migrationURL).toString(); + } else { + entityObject[COMPOUND_SHAPE_URL_KEY] = _uploadedAssets.value(migrationURL).toString(); + } + + jsonValue = entityObject; } else { - entityObject[COMPOUND_SHAPE_URL_KEY] = _uploadedAssets.value(migrationURL).toString(); - } - jsonValue = entityObject; - } else { + static bool hasAskedForCompleteMigration { false }; + static bool wantsCompleteMigration { false }; - static bool hasAskedForCompleteMigration { false }; - static bool wantsCompleteMigration { false }; - - if (!hasAskedForCompleteMigration) { - // this is the first resource migration - ask the user if they just want to migrate everything - static const QString COMPLETE_MIGRATION_TEXT { "Do you want to migrate all assets found in this entity-server file?\n"\ - "Select \"Yes\" to upload all discovered assets to the current asset-server immediately.\n"\ - "Select \"No\" to be prompted for each discovered asset." - }; - auto offscreenUi = DependencyManager::get(); - QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=] (QMessageBox::StandardButton answer) { + if (!hasAskedForCompleteMigration) { + // this is the first resource migration - ask the user if they just want to migrate everything + static const QString COMPLETE_MIGRATION_TEXT { "Do you want to migrate all assets found in this entity-server file?\n"\ + "Select \"Yes\" to upload all discovered assets to the current asset-server immediately.\n"\ + "Select \"No\" to be prompted for each discovered asset." + }; auto offscreenUi = DependencyManager::get(); - QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr); - if (answer == QMessageBox::Yes) { - wantsCompleteMigration = true; - migrateResources(migrationURL, jsonValue, isModelURL); - } else { - QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=] (QMessageBox::StandardButton answer) { - auto offscreenUi = DependencyManager::get(); - QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr); - if (answer == QMessageBox::Yes) { - migrateResources(migrationURL, jsonValue, isModelURL); - } else { - _ignoredUrls.insert(migrationURL); - } - }); - OffscreenUi::asyncQuestion(_dialogParent, MESSAGE_BOX_TITLE, - "Would you like to migrate the following resource?\n" + migrationURL.toString(), - QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=] (QMessageBox::StandardButton answer) { + auto offscreenUi = DependencyManager::get(); + QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr); + if (answer == QMessageBox::Yes) { + wantsCompleteMigration = true; + migrateResources(migrationURL, jsonValue, isModelURL); + } else { + QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=] (QMessageBox::StandardButton answer) { + auto offscreenUi = DependencyManager::get(); + QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr); + if (answer == QMessageBox::Yes) { + migrateResources(migrationURL, jsonValue, isModelURL); + } else { + _ignoredUrls.insert(migrationURL); + } + }); + OffscreenUi::asyncQuestion(_dialogParent, MESSAGE_BOX_TITLE, + "Would you like to migrate the following resource?\n" + migrationURL.toString(), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); - } - }); - OffscreenUi::asyncQuestion(_dialogParent, MESSAGE_BOX_TITLE, COMPLETE_MIGRATION_TEXT, - QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); - hasAskedForCompleteMigration = true; - } - if (wantsCompleteMigration) { - migrateResources(migrationURL, jsonValue, isModelURL); + } + }); + OffscreenUi::asyncQuestion(_dialogParent, MESSAGE_BOX_TITLE, COMPLETE_MIGRATION_TEXT, + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + hasAskedForCompleteMigration = true; + } + if (wantsCompleteMigration) { + migrateResources(migrationURL, jsonValue, isModelURL); + } } } } } } + + _doneReading = true; + + checkIfFinished(); + + } else { + OffscreenUi::asyncWarning(_dialogParent, "Error", + "There was a problem loading that entity-server file for ATP asset migration. Please try again"); } - - _doneReading = true; - - checkIfFinished(); - - } else { - OffscreenUi::asyncWarning(_dialogParent, "Error", - "There was a problem loading that entity-server file for ATP asset migration. Please try again"); } - } - }); - OffscreenUi::asyncQuestion(_dialogParent, MESSAGE_BOX_TITLE, MIGRATION_CONFIRMATION_TEXT, - QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); - } + }); + OffscreenUi::asyncQuestion(_dialogParent, MESSAGE_BOX_TITLE, MIGRATION_CONFIRMATION_TEXT, + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + + } + }); + OffscreenUi::getOpenFileNameAsync(_dialogParent, tr("Select an entity-server content file to migrate"), + QString(), tr("Entity-Server Content (*.gz)")); } void ATPAssetMigrator::migrateResource(ResourceRequest* request) { diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 8ea92d2b1e..470603d0d0 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -736,9 +736,7 @@ QString OffscreenUi::fileOpenDialog(const QString& caption, const QString& dir, void OffscreenUi::fileOpenDialogAsync(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) { if (QThread::currentThread() != thread()) { - QString result; BLOCKING_INVOKE_METHOD(this, "fileOpenDialogAsync", - Q_RETURN_ARG(QString, result), Q_ARG(QString, caption), Q_ARG(QString, dir), Q_ARG(QString, filter), @@ -780,6 +778,28 @@ QString OffscreenUi::fileSaveDialog(const QString& caption, const QString& dir, return fileDialog(map); } +void OffscreenUi::fileSaveDialogAsync(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "fileSaveDialogAsync", + Q_ARG(QString, caption), + Q_ARG(QString, dir), + Q_ARG(QString, filter), + Q_ARG(QString*, selectedFilter), + Q_ARG(QFileDialog::Options, options)); + return; + } + + // FIXME support returning the selected filter... somehow? + QVariantMap map; + map.insert("caption", caption); + map.insert("dir", QUrl::fromLocalFile(dir)); + map.insert("filter", filter); + map.insert("options", static_cast(options)); + map.insert("saveDialog", true); + + return fileDialogAsync(map); +} + QString OffscreenUi::existingDirectoryDialog(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) { if (QThread::currentThread() != thread()) { QString result; @@ -802,6 +822,26 @@ QString OffscreenUi::existingDirectoryDialog(const QString& caption, const QStri return fileDialog(map); } +void OffscreenUi::existingDirectoryDialogAsync(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "existingDirectoryDialogAsync", + Q_ARG(QString, caption), + Q_ARG(QString, dir), + Q_ARG(QString, filter), + Q_ARG(QString*, selectedFilter), + Q_ARG(QFileDialog::Options, options)); + return; + } + + QVariantMap map; + map.insert("caption", caption); + map.insert("dir", QUrl::fromLocalFile(dir)); + map.insert("filter", filter); + map.insert("options", static_cast(options)); + map.insert("selectDirectory", true); + return fileDialogAsync(map); +} + QString OffscreenUi::getOpenFileName(void* ignored, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { return DependencyManager::get()->fileOpenDialog(caption, dir, filter, selectedFilter, options); } @@ -814,10 +854,18 @@ QString OffscreenUi::getSaveFileName(void* ignored, const QString &caption, cons return DependencyManager::get()->fileSaveDialog(caption, dir, filter, selectedFilter, options); } +void OffscreenUi::getSaveFileNameAsync(void* ignored, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { + return DependencyManager::get()->fileSaveDialogAsync(caption, dir, filter, selectedFilter, options); +} + QString OffscreenUi::getExistingDirectory(void* ignored, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { return DependencyManager::get()->existingDirectoryDialog(caption, dir, filter, selectedFilter, options); } +void OffscreenUi::getExistingDirectoryAsync(void* ignored, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { + return DependencyManager::get()->existingDirectoryDialogAsync(caption, dir, filter, selectedFilter, options); +} + class AssetDialogListener : public ModalDialogListener { // ATP equivalent of FileDialogListener. Q_OBJECT @@ -833,6 +881,9 @@ class AssetDialogListener : public ModalDialogListener { private slots: void onSelectedAsset(QVariant asset) { _result = asset; + auto offscreenUi = DependencyManager::get(); + emit offscreenUi->assetDialogResponse(_result.toUrl().toLocalFile()); + offscreenUi->removeModalDialog(qobject_cast(this)); _finished = true; disconnect(_dialog); } @@ -870,6 +921,35 @@ QString OffscreenUi::assetDialog(const QVariantMap& properties) { return result.toUrl().toString(); } +void OffscreenUi::assetDialogAsync(const QVariantMap& properties) { + // ATP equivalent of fileDialog(). + QVariant buildDialogResult; + bool invokeResult; + auto tabletScriptingInterface = DependencyManager::get(); + TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + if (tablet->getToolbarMode()) { + invokeResult = QMetaObject::invokeMethod(_desktop, "assetDialog", + Q_RETURN_ARG(QVariant, buildDialogResult), + Q_ARG(QVariant, QVariant::fromValue(properties))); + } else { + QQuickItem* tabletRoot = tablet->getTabletRoot(); + invokeResult = QMetaObject::invokeMethod(tabletRoot, "assetDialog", + Q_RETURN_ARG(QVariant, buildDialogResult), + Q_ARG(QVariant, QVariant::fromValue(properties))); + emit tabletScriptingInterface->tabletNotification(); + } + + if (!invokeResult) { + qWarning() << "Failed to create asset open dialog"; + return; + } + + AssetDialogListener* assetDialogListener = new AssetDialogListener(qvariant_cast(buildDialogResult)); + QObject* assetModalDialog = qobject_cast(assetDialogListener); + _modalDialogListeners.push_back(assetModalDialog); + return; +} + QString OffscreenUi::assetOpenDialog(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) { // ATP equivalent of fileOpenDialog(). if (QThread::currentThread() != thread()) { @@ -893,11 +973,37 @@ QString OffscreenUi::assetOpenDialog(const QString& caption, const QString& dir, return assetDialog(map); } +void OffscreenUi::assetOpenDialogAsync(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) { + // ATP equivalent of fileOpenDialog(). + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "assetOpenDialogAsync", + Q_ARG(QString, caption), + Q_ARG(QString, dir), + Q_ARG(QString, filter), + Q_ARG(QString*, selectedFilter), + Q_ARG(QFileDialog::Options, options)); + return; + } + + // FIXME support returning the selected filter... somehow? + QVariantMap map; + map.insert("caption", caption); + map.insert("dir", dir); + map.insert("filter", filter); + map.insert("options", static_cast(options)); + return assetDialogAsync(map); +} + QString OffscreenUi::getOpenAssetName(void* ignored, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { // ATP equivalent of getOpenFileName(). return DependencyManager::get()->assetOpenDialog(caption, dir, filter, selectedFilter, options); } +void OffscreenUi::getOpenAssetNameAsync(void* ignored, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { + // ATP equivalent of getOpenFileName(). + return DependencyManager::get()->assetOpenDialogAsync(caption, dir, filter, selectedFilter, options); +} + bool OffscreenUi::eventFilter(QObject* originalDestination, QEvent* event) { if (!filterEnabled(originalDestination, event)) { return false; diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index 335645ce06..a3529da89c 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -151,9 +151,12 @@ public: Q_INVOKABLE QString fileOpenDialog(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); Q_INVOKABLE void fileOpenDialogAsync(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); Q_INVOKABLE QString fileSaveDialog(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); + Q_INVOKABLE void fileSaveDialogAsync(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); Q_INVOKABLE QString existingDirectoryDialog(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); + Q_INVOKABLE void existingDirectoryDialogAsync(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); Q_INVOKABLE QString assetOpenDialog(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); + Q_INVOKABLE void assetOpenDialogAsync(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); // Compatibility with QFileDialog::getOpenFileName static QString getOpenFileName(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); @@ -161,10 +164,13 @@ public: // Compatibility with QFileDialog::getSaveFileName static QString getSaveFileName(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); + static void getSaveFileNameAsync(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); // Compatibility with QFileDialog::getExistingDirectory static QString getExistingDirectory(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); + static void getExistingDirectoryAsync(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); static QString getOpenAssetName(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); + static void getOpenAssetNameAsync(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); Q_INVOKABLE QVariant inputDialog(const Icon icon, const QString& title, const QString& label = QString(), const QVariant& current = QVariant()); Q_INVOKABLE QVariant customInputDialog(const Icon icon, const QString& title, const QVariantMap& config); @@ -194,6 +200,7 @@ signals: void showDesktop(); void response(QMessageBox::StandardButton response); void fileDialogResponse(QString response); + void assetDialogResponse(QString response); public slots: void removeModalDialog(QObject* modal); @@ -201,6 +208,7 @@ private: QString fileDialog(const QVariantMap& properties); void fileDialogAsync(const QVariantMap &properties); QString assetDialog(const QVariantMap& properties); + void assetDialogAsync(const QVariantMap& properties); QQuickItem* _desktop { nullptr }; QQuickItem* _toolWindow { nullptr };