1st stage of moving to async dialogs

This commit is contained in:
vladest 2017-08-09 14:00:19 +02:00
parent e0daa92757
commit 556569819d
9 changed files with 244 additions and 170 deletions

View file

@ -894,7 +894,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(scriptEngines, &ScriptEngines::scriptLoadError,
scriptEngines, [](const QString& filename, const QString& error){
OffscreenUi::warning(nullptr, "Error Loading Script", filename + " failed to load.");
OffscreenUi::asyncWarning(nullptr, "Error Loading Script", filename + " failed to load.");
}, Qt::QueuedConnection);
#ifdef _WIN32
@ -1689,7 +1689,7 @@ void Application::domainConnectionRefused(const QString& reasonMessage, int reas
case DomainHandler::ConnectionRefusedReason::Unknown: {
QString message = "Unable to connect to the location you are visiting.\n";
message += reasonMessage;
OffscreenUi::warning("", message);
OffscreenUi::asyncWarning("", message);
break;
}
default:
@ -3626,7 +3626,7 @@ bool Application::acceptSnapshot(const QString& urlString) {
DependencyManager::get<AddressManager>()->handleLookupString(snapshotData->getURL().toString());
}
} else {
OffscreenUi::warning("", "No location details were found in the file\n" +
OffscreenUi::asyncWarning("", "No location details were found in the file\n" +
snapshotPath + "\nTry dragging in an authentic Hifi snapshot.");
}
return true;
@ -5997,7 +5997,7 @@ void Application::setSessionUUID(const QUuid& sessionUUID) const {
bool Application::askToSetAvatarUrl(const QString& url) {
QUrl realUrl(url);
if (realUrl.isLocalFile()) {
OffscreenUi::warning("", "You can not use local files for avatar components.");
OffscreenUi::asyncWarning("", "You can not use local files for avatar components.");
return false;
}
@ -6009,41 +6009,61 @@ bool Application::askToSetAvatarUrl(const QString& url) {
QString modelName = fstMapping["name"].toString();
QString modelLicense = fstMapping["license"].toString();
bool agreeToLicence = true; // assume true
bool agreeToLicense = true; // assume true
//create set avatar callback
auto setAvatar = [=] (QString url, QString modelName) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=] (QMessageBox::StandardButton answer) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr);
bool ok = (QMessageBox::Ok == answer);
if (ok) {
getMyAvatar()->useFullAvatarURL(url, modelName);
emit fullAvatarURLChanged(url, modelName);
} else {
qCDebug(interfaceapp) << "Declined to use the avatar: " << url;
}
});
OffscreenUi::asyncQuestion("Set Avatar",
"Would you like to use '" + modelName + "' for your avatar?",
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
};
if (!modelLicense.isEmpty()) {
// word wrap the licence text to fit in a reasonable shaped message box.
// word wrap the license text to fit in a reasonable shaped message box.
const int MAX_CHARACTERS_PER_LINE = 90;
modelLicense = simpleWordWrap(modelLicense, MAX_CHARACTERS_PER_LINE);
agreeToLicence = QMessageBox::Yes == OffscreenUi::question("Avatar Usage License",
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=, &agreeToLicense] (QMessageBox::StandardButton answer) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr);
agreeToLicense = (answer == QMessageBox::Yes);
if (agreeToLicense) {
switch (modelType) {
case FSTReader::HEAD_AND_BODY_MODEL: {
setAvatar(url, modelName);
break;
}
default:
OffscreenUi::asyncWarning("", modelName + "Does not support a head and body as required.");
break;
}
} else {
qCDebug(interfaceapp) << "Declined to agree to avatar license: " << url;
}
//auto offscreenUi = DependencyManager::get<OffscreenUi>();
});
OffscreenUi::asyncQuestion("Avatar Usage License",
modelLicense + "\nDo you agree to these terms?",
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
}
bool ok = false;
if (!agreeToLicence) {
qCDebug(interfaceapp) << "Declined to agree to avatar license: " << url;
} else {
switch (modelType) {
case FSTReader::HEAD_AND_BODY_MODEL:
ok = QMessageBox::Ok == OffscreenUi::question("Set Avatar",
"Would you like to use '" + modelName + "' for your avatar?",
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
break;
default:
OffscreenUi::warning("", modelName + "Does not support a head and body as required.");
break;
}
}
if (ok) {
getMyAvatar()->useFullAvatarURL(url, modelName);
emit fullAvatarURLChanged(url, modelName);
} else {
qCDebug(interfaceapp) << "Declined to use the avatar: " << url;
setAvatar(url, modelName);
}
return true;
@ -6051,8 +6071,6 @@ bool Application::askToSetAvatarUrl(const QString& url) {
bool Application::askToLoadScript(const QString& scriptFilenameOrURL) {
QMessageBox::StandardButton reply;
QString shortName = scriptFilenameOrURL;
QUrl scriptURL { scriptFilenameOrURL };
@ -6063,16 +6081,23 @@ bool Application::askToLoadScript(const QString& scriptFilenameOrURL) {
shortName = shortName.mid(startIndex, endIndex - startIndex);
}
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=] (QMessageBox::StandardButton answer) {
const QString& fileName = scriptFilenameOrURL;
if (answer == QMessageBox::Yes) {
qCDebug(interfaceapp) << "Chose to run the script: " << fileName;
DependencyManager::get<ScriptEngines>()->loadScript(fileName);
} else {
qCDebug(interfaceapp) << "Declined to run the script: " << scriptFilenameOrURL;
}
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr);
});
QString message = "Would you like to run this script:\n" + shortName;
reply = OffscreenUi::question(getWindow(), "Run Script", message, QMessageBox::Yes | QMessageBox::No);
OffscreenUi::asyncQuestion(getWindow(), "Run Script", message, QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
qCDebug(interfaceapp) << "Chose to run the script: " << scriptFilenameOrURL;
DependencyManager::get<ScriptEngines>()->loadScript(scriptFilenameOrURL);
} else {
qCDebug(interfaceapp) << "Declined to run the script: " << scriptFilenameOrURL;
}
return true;
}
@ -6109,22 +6134,29 @@ bool Application::askToWearAvatarAttachmentUrl(const QString& url) {
name = nameValue.toString();
}
// display confirmation dialog
if (displayAvatarAttachmentConfirmationDialog(name)) {
// add attachment to avatar
auto myAvatar = getMyAvatar();
assert(myAvatar);
auto attachmentDataVec = myAvatar->getAttachmentData();
AttachmentData attachmentData;
attachmentData.fromJson(jsonObject);
attachmentDataVec.push_back(attachmentData);
myAvatar->setAttachmentData(attachmentDataVec);
} else {
qCDebug(interfaceapp) << "User declined to wear the avatar attachment: " << url;
}
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=] (QMessageBox::StandardButton answer) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr);
if (answer == QMessageBox::Yes) {
// add attachment to avatar
auto myAvatar = getMyAvatar();
assert(myAvatar);
auto attachmentDataVec = myAvatar->getAttachmentData();
AttachmentData attachmentData;
attachmentData.fromJson(jsonObject);
attachmentDataVec.push_back(attachmentData);
myAvatar->setAttachmentData(attachmentDataVec);
} else {
qCDebug(interfaceapp) << "User declined to wear the avatar attachment: " << url;
}
});
auto avatarAttachmentConfirmationTitle = tr("Avatar Attachment Confirmation");
auto avatarAttachmentConfirmationMessage = tr("Would you like to wear '%1' on your avatar?").arg(name);
OffscreenUi::asyncQuestion(avatarAttachmentConfirmationTitle,
avatarAttachmentConfirmationMessage,
QMessageBox::Ok | QMessageBox::Cancel);
} else {
// json parse error
auto avatarAttachmentParseErrorString = tr("Error parsing attachment JSON from url: \"%1\"");
@ -6142,20 +6174,7 @@ bool Application::askToWearAvatarAttachmentUrl(const QString& url) {
void Application::displayAvatarAttachmentWarning(const QString& message) const {
auto avatarAttachmentWarningTitle = tr("Avatar Attachment Failure");
OffscreenUi::warning(avatarAttachmentWarningTitle, message);
}
bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name) const {
auto avatarAttachmentConfirmationTitle = tr("Avatar Attachment Confirmation");
auto avatarAttachmentConfirmationMessage = tr("Would you like to wear '%1' on your avatar?").arg(name);
auto reply = OffscreenUi::question(avatarAttachmentConfirmationTitle,
avatarAttachmentConfirmationMessage,
QMessageBox::Ok | QMessageBox::Cancel);
if (QMessageBox::Ok == reply) {
return true;
} else {
return false;
}
OffscreenUi::asyncWarning(avatarAttachmentWarningTitle, message);
}
void Application::showDialog(const QUrl& widgetUrl, const QUrl& tabletUrl, const QString& name) const {
@ -6722,7 +6741,7 @@ void Application::setPreviousScriptLocation(const QString& location) {
void Application::loadScriptURLDialog() const {
QString newScript = OffscreenUi::getText(OffscreenUi::ICON_NONE, "Open and Run Script", "Script URL");
if (QUrl(newScript).scheme() == "atp") {
OffscreenUi::warning("Error Loading Script", "Cannot load client script over ATP");
OffscreenUi::asyncWarning("Error Loading Script", "Cannot load client script over ATP");
} else if (!newScript.isEmpty()) {
DependencyManager::get<ScriptEngines>()->loadScript(newScript.trimmed());
}
@ -6836,7 +6855,7 @@ void Application::notifyPacketVersionMismatch() {
QString message = "The location you are visiting is running an incompatible server version.\n";
message += "Content may not display properly.";
OffscreenUi::warning("", message);
OffscreenUi::asyncWarning("", message);
}
}
@ -6845,7 +6864,7 @@ void Application::checkSkeleton() const {
qCDebug(interfaceapp) << "MyAvatar model has no skeleton";
QString message = "Your selected avatar body has no skeleton.\n\nThe default body will be loaded...";
OffscreenUi::warning("", message);
OffscreenUi::asyncWarning("", message);
getMyAvatar()->useFullAvatarURL(AvatarData::defaultFullAvatarModelUrl(), DEFAULT_FULL_AVATAR_MODEL_NAME);
} else {

View file

@ -428,7 +428,6 @@ private slots:
bool askToWearAvatarAttachmentUrl(const QString& url);
void displayAvatarAttachmentWarning(const QString& message) const;
bool displayAvatarAttachmentConfirmationDialog(const QString& name) const;
void setSessionUUID(const QUuid& sessionUUID) const;

View file

@ -79,7 +79,7 @@ bool ModelPackager::loadModel() {
if (_modelFile.completeSuffix().contains("fst")) {
QFile fst(_modelFile.filePath());
if (!fst.open(QFile::ReadOnly | QFile::Text)) {
OffscreenUi::warning(NULL,
OffscreenUi::asyncWarning(NULL,
QString("ModelPackager::loadModel()"),
QString("Could not open FST file %1").arg(_modelFile.filePath()),
QMessageBox::Ok);
@ -98,7 +98,7 @@ bool ModelPackager::loadModel() {
// open the fbx file
QFile fbx(_fbxInfo.filePath());
if (!_fbxInfo.exists() || !_fbxInfo.isFile() || !fbx.open(QIODevice::ReadOnly)) {
OffscreenUi::warning(NULL,
OffscreenUi::asyncWarning(NULL,
QString("ModelPackager::loadModel()"),
QString("Could not open FBX file %1").arg(_fbxInfo.filePath()),
QMessageBox::Ok);
@ -408,7 +408,7 @@ bool ModelPackager::copyTextures(const QString& oldDir, const QDir& newDir) {
}
if (!errors.isEmpty()) {
OffscreenUi::warning(nullptr, "ModelPackager::copyTextures()",
OffscreenUi::asyncWarning(nullptr, "ModelPackager::copyTextures()",
"Missing textures:" + errors);
qCDebug(interfaceapp) << "ModelPackager::copyTextures():" << errors;
return false;

View file

@ -201,7 +201,7 @@ void ModelPropertiesDialog::chooseTextureDirectory() {
return;
}
if (!directory.startsWith(_basePath)) {
OffscreenUi::warning(NULL, "Invalid texture directory", "Texture directory must be child of base path.");
OffscreenUi::asyncWarning(NULL, "Invalid texture directory", "Texture directory must be child of base path.");
return;
}
_textureDirectory->setText(directory.length() == _basePath.length() ? "." : directory.mid(_basePath.length() + 1));

View file

@ -53,105 +53,109 @@ void ATPAssetMigrator::loadEntityServerFile() {
" continue?\n\nMake sure you are connected to the right domain."
};
auto button = OffscreenUi::question(_dialogParent, MESSAGE_BOX_TITLE, MIGRATION_CONFIRMATION_TEXT,
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (button == QMessageBox::No) {
return;
}
// try to open the file at the given filename
QFile modelsFile { filename };
if (modelsFile.open(QIODevice::ReadOnly)) {
QByteArray compressedJsonData = modelsFile.readAll();
QByteArray jsonData;
if (!gunzip(compressedJsonData, jsonData)) {
OffscreenUi::warning(_dialogParent, "Error", "The file at" + filename + "was not in gzip format.");
}
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();
auto offscreenUi = DependencyManager::get<OffscreenUi>();
for (int i = 0; i < 2; ++i) {
bool isModelURL = (i == 0);
quint8 replacementType = i;
auto migrationURLString = (isModelURL) ? modelURLString : compoundURLString;
QObject::connect(offscreenUi.data(), &OffscreenUi::response, this, [=] (QMessageBox::StandardButton answer) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QObject::disconnect(offscreenUi.data(), &OffscreenUi::response, this, nullptr);
if (!migrationURLString.isEmpty()) {
QUrl migrationURL = QUrl(migrationURLString);
if (QMessageBox::Yes == answer) {
// try to open the file at the given filename
QFile modelsFile { filename };
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 (modelsFile.open(QIODevice::ReadOnly)) {
QByteArray compressedJsonData = modelsFile.readAll();
QByteArray jsonData;
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();
}
if (!gunzip(compressedJsonData, jsonData)) {
OffscreenUi::asyncWarning(_dialogParent, "Error", "The file at" + filename + "was not in gzip format.");
}
jsonValue = entityObject;
} else if (wantsToMigrateResource(migrationURL)) {
auto request =
DependencyManager::get<ResourceManager>()->createResourceRequest(this, migrationURL);
QJsonDocument modelsJSON = QJsonDocument::fromJson(jsonData);
_entitiesArray = modelsJSON.object()["Entities"].toArray();
if (request) {
qCDebug(asset_migrator) << "Requesting" << migrationURL << "for ATP asset migration";
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();
// 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)});
for (int i = 0; i < 2; ++i) {
bool isModelURL = (i == 0);
quint8 replacementType = i;
auto migrationURLString = (isModelURL) ? modelURLString : compoundURLString;
connect(request, &ResourceRequest::finished, this, [=]() {
if (request->getResult() == ResourceRequest::Success) {
migrateResource(request);
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 (_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 if (wantsToMigrateResource(migrationURL)) {
auto request =
DependencyManager::get<ResourceManager>()->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;
_pendingReplacements.remove(migrationURL);
qWarning() << "Could not retrieve asset at" << migrationURL.toString();
checkIfFinished();
qWarning() << "Count not create request for asset at" << migrationURL.toString();
}
request->deleteLater();
});
request->send();
} else {
++_errorCount;
qWarning() << "Count not create request for asset at" << migrationURL.toString();
} else {
_ignoredUrls.insert(migrationURL);
}
}
} else {
_ignoredUrls.insert(migrationURL);
}
}
}
}
_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::warning(_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);
}
}
@ -314,11 +318,11 @@ void ATPAssetMigrator::saveEntityServerFile() {
OffscreenUi::information(_dialogParent, "Success", infoMessage);
} else {
OffscreenUi::warning(_dialogParent, "Error", "Could not gzip JSON data for new entities file.");
OffscreenUi::asyncWarning(_dialogParent, "Error", "Could not gzip JSON data for new entities file.");
}
} else {
OffscreenUi::warning(_dialogParent, "Error",
OffscreenUi::asyncWarning(_dialogParent, "Error",
QString("Could not open file at %1 to write new entities file to.").arg(saveName));
}
}

View file

@ -59,7 +59,7 @@ WindowScriptingInterface::WindowScriptingInterface() {
QUrl url(urlString);
emit svoImportRequested(url.url());
} else {
OffscreenUi::warning("Import SVO Error", "You need to be running edit.js to import entities.");
OffscreenUi::asyncWarning("Import SVO Error", "You need to be running edit.js to import entities.");
}
});
@ -103,7 +103,7 @@ void WindowScriptingInterface::raiseMainWindow() {
/// \param const QString& message message to display
/// \return QScriptValue::UndefinedValue
void WindowScriptingInterface::alert(const QString& message) {
OffscreenUi::warning("", message);
OffscreenUi::asyncWarning("", message);
}
/// Display a confirmation box with the options 'Yes' and 'No'

View file

@ -136,7 +136,7 @@ void EyeTracker::onStreamStarted() {
qCWarning(interfaceapp) << "Eye Tracker: Error starting streaming:" << smiReturnValueToString(result);
// Display error dialog unless SMI SDK has already displayed an error message.
if (result != SMI_ERROR_HMD_NOT_SUPPORTED) {
OffscreenUi::warning(nullptr, "Eye Tracker Error", smiReturnValueToString(result));
OffscreenUi::asyncWarning(nullptr, "Eye Tracker Error", smiReturnValueToString(result));
}
} else {
qCDebug(interfaceapp) << "Eye Tracker: Started streaming";
@ -149,7 +149,7 @@ void EyeTracker::onStreamStarted() {
result = smi_loadCalibration(HIGH_FIDELITY_EYE_TRACKER_CALIBRATION);
if (result != SMI_RET_SUCCESS) {
qCWarning(interfaceapp) << "Eye Tracker: Error loading calibration:" << smiReturnValueToString(result);
OffscreenUi::warning(nullptr, "Eye Tracker Error", "Error loading calibration"
OffscreenUi::asyncWarning(nullptr, "Eye Tracker Error", "Error loading calibration"
+ smiReturnValueToString(result));
} else {
qCDebug(interfaceapp) << "Eye Tracker: Loaded calibration";
@ -165,7 +165,7 @@ void EyeTracker::setEnabled(bool enabled, bool simulate) {
int result = smi_setCallback(eyeTrackerCallback);
if (result != SMI_RET_SUCCESS) {
qCWarning(interfaceapp) << "Eye Tracker: Error setting callback:" << smiReturnValueToString(result);
OffscreenUi::warning(nullptr, "Eye Tracker Error", smiReturnValueToString(result));
OffscreenUi::asyncWarning(nullptr, "Eye Tracker Error", smiReturnValueToString(result));
} else {
_isInitialized = true;
}
@ -270,7 +270,7 @@ void EyeTracker::calibrate(int points) {
}
if (result != SMI_RET_SUCCESS) {
OffscreenUi::warning(nullptr, "Eye Tracker Error", "Calibration error: " + smiReturnValueToString(result));
OffscreenUi::asyncWarning(nullptr, "Eye Tracker Error", "Calibration error: " + smiReturnValueToString(result));
}
}
#endif

View file

@ -91,6 +91,12 @@ QObject* OffscreenUi::getFlags() {
return offscreenFlags;
}
void OffscreenUi::removeModalDialog(QObject* modal) {
if (modal) {
_modalDialogListeners.removeOne(modal);
}
}
void OffscreenUi::create(QOpenGLContext* context) {
OffscreenQmlSurface::create(context);
auto myContext = getSurfaceContext();
@ -204,6 +210,9 @@ private slots:
void onSelected(int button) {
_result = button;
_finished = true;
auto offscreenUi = DependencyManager::get<OffscreenUi>();
emit offscreenUi->response(static_cast<QMessageBox::StandardButton>(_result.toInt()));
offscreenUi->removeModalDialog(qobject_cast<QObject*>(this));
disconnect(_dialog);
}
};
@ -263,6 +272,21 @@ QMessageBox::StandardButton OffscreenUi::messageBox(Icon icon, const QString& ti
return static_cast<QMessageBox::StandardButton>(waitForMessageBoxResult(createMessageBox(icon, title, text, buttons, defaultButton)));
}
void OffscreenUi::asyncMessageBox(Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) {
if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "asyncMessageBox",
Q_ARG(Icon, icon),
Q_ARG(QString, title),
Q_ARG(QString, text),
Q_ARG(QMessageBox::StandardButtons, buttons),
Q_ARG(QMessageBox::StandardButton, defaultButton));
}
MessageBoxListener* messageBoxListener = new MessageBoxListener(createMessageBox(icon, title, text, buttons, defaultButton));
QObject* modalDialog = qobject_cast<QObject*>(messageBoxListener);
_modalDialogListeners.push_back(modalDialog);
}
QMessageBox::StandardButton OffscreenUi::critical(const QString& title, const QString& text,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) {
return DependencyManager::get<OffscreenUi>()->messageBox(OffscreenUi::Icon::ICON_CRITICAL, title, text, buttons, defaultButton);
@ -275,11 +299,18 @@ QMessageBox::StandardButton OffscreenUi::question(const QString& title, const QS
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) {
return DependencyManager::get<OffscreenUi>()->messageBox(OffscreenUi::Icon::ICON_QUESTION, title, text, buttons, defaultButton);
}
void OffscreenUi::asyncQuestion(const QString& title, const QString& text,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) {
DependencyManager::get<OffscreenUi>()->asyncMessageBox(OffscreenUi::Icon::ICON_QUESTION, title, text, buttons, defaultButton);
}
QMessageBox::StandardButton OffscreenUi::warning(const QString& title, const QString& text,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) {
return DependencyManager::get<OffscreenUi>()->messageBox(OffscreenUi::Icon::ICON_WARNING, title, text, buttons, defaultButton);
}
void OffscreenUi::asyncWarning(const QString& title, const QString& text,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) {
DependencyManager::get<OffscreenUi>()->asyncMessageBox(OffscreenUi::Icon::ICON_WARNING, title, text, buttons, defaultButton);
}
class InputDialogListener : public ModalDialogListener {

View file

@ -71,6 +71,7 @@ public:
// Message box compatibility
Q_INVOKABLE QMessageBox::StandardButton messageBox(Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
Q_INVOKABLE void asyncMessageBox(Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
// Must be called from the main thread
QQuickItem* createMessageBox(Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
// Must be called from the main thread
@ -94,12 +95,23 @@ public:
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) {
return question(title, text, buttons, defaultButton);
}
static void asyncQuestion(void* ignored, const QString& title, const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) {
return asyncQuestion(title, text, buttons, defaultButton);
}
/// Same design as QMessageBox::warning(), will block, returns result
static QMessageBox::StandardButton warning(void* ignored, const QString& title, const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) {
return warning(title, text, buttons, defaultButton);
}
static void asyncWarning(void* ignored, const QString& title, const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) {
return asyncWarning(title, text, buttons, defaultButton);
}
static QMessageBox::StandardButton critical(const QString& title, const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
@ -110,9 +122,15 @@ public:
static QMessageBox::StandardButton question(const QString& title, const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
static void asyncQuestion (const QString& title, const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
static QMessageBox::StandardButton warning(const QString& title, const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
static void asyncWarning(const QString& title, const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
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 QString fileSaveDialog(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
@ -153,9 +171,11 @@ public:
static QVariant getCustomInfo(const Icon icon, const QString& title, const QVariantMap& config, bool* ok = 0);
unsigned int getMenuUserDataId() const;
signals:
void showDesktop();
void response(QMessageBox::StandardButton response);
public slots:
void removeModalDialog(QObject* modal);
private:
QString fileDialog(const QVariantMap& properties);
@ -163,6 +183,7 @@ private:
QQuickItem* _desktop { nullptr };
QQuickItem* _toolWindow { nullptr };
QList<QObject*> _modalDialogListeners;
std::unordered_map<int, bool> _pressedKeys;
VrMenu* _vrMenu { nullptr };
QQueue<std::function<void(VrMenu*)>> _queuedMenuInitializers;