// // CrashRecoveryHandler.cpp // interface/src // // Created by David Rowe on 24 Aug 2015. // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "CrashRecoveryHandler.h" #include #include #include #include #include #include #include #include #include #include #include "Application.h" #include "Menu.h" #include #include #include bool CrashRecoveryHandler::checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt) { QSettings::setDefaultFormat(JSON_FORMAT); QSettings settings; settings.beginGroup("Developer"); QVariant displayCrashOptions = settings.value(MenuOption::DisplayCrashOptions); settings.endGroup(); settings.beginGroup("Settings"); QVariant askToResetSettingsOption = settings.value(MenuOption::AskToResetSettings); settings.endGroup(); bool askToResetSettings = askToResetSettingsOption.isValid() && askToResetSettingsOption.toBool(); // If option does not exist in Interface.ini so assume default behavior. bool displaySettingsResetOnCrash = !displayCrashOptions.isValid() || displayCrashOptions.toBool(); if (suppressPrompt) { return wasLikelyCrash; } if (wasLikelyCrash || askToResetSettings) { if (displaySettingsResetOnCrash || askToResetSettings) { Action action = promptUserForAction(wasLikelyCrash); if (action != DO_NOTHING) { handleCrash(action); } } } return wasLikelyCrash; } CrashRecoveryHandler::Action CrashRecoveryHandler::promptUserForAction(bool showCrashMessage) { QDialog crashDialog; QLabel* label; if (showCrashMessage) { crashDialog.setWindowTitle("Interface Crashed Last Run"); label = new QLabel("If you are having trouble starting would you like to reset your settings?"); } else { crashDialog.setWindowTitle("Reset Settings"); label = new QLabel("Would you like to reset your settings?"); } QVBoxLayout* layout = new QVBoxLayout; layout->addWidget(label); QRadioButton* option1 = new QRadioButton("Reset all my settings"); QRadioButton* option2 = new QRadioButton("Reset my settings but keep essential info"); QRadioButton* option3 = new QRadioButton("Continue with my current settings"); option3->setChecked(true); layout->addWidget(option1); layout->addWidget(option2); layout->addWidget(option3); layout->addSpacing(12); layout->addStretch(); QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok); layout->addWidget(buttons); crashDialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); crashDialog.setLayout(layout); int result = crashDialog.exec(); if (result == QDialog::Accepted) { if (option1->isChecked()) { return CrashRecoveryHandler::DELETE_INTERFACE_INI; } if (option2->isChecked()) { return CrashRecoveryHandler::RETAIN_IMPORTANT_INFO; } } // Dialog cancelled or "do nothing" option chosen return CrashRecoveryHandler::DO_NOTHING; } void CrashRecoveryHandler::handleCrash(CrashRecoveryHandler::Action action) { if (action != CrashRecoveryHandler::DELETE_INTERFACE_INI && action != CrashRecoveryHandler::RETAIN_IMPORTANT_INFO) { // CrashRecoveryHandler::DO_NOTHING or unexpected value return; } QSettings settings; const QString ADDRESS_MANAGER_GROUP = "AddressManager"; const QString ADDRESS_KEY = "address"; const QString AVATAR_GROUP = "Avatar"; const QString DISPLAY_NAME_KEY = "displayName"; const QString FULL_AVATAR_URL_KEY = "fullAvatarURL"; const QString FULL_AVATAR_MODEL_NAME_KEY = "fullAvatarModelName"; const QString TUTORIAL_COMPLETE_FLAG_KEY = "tutorialComplete"; QString displayName; QUrl fullAvatarURL; QString fullAvatarModelName; QUrl address; bool tutorialComplete = false; if (action == CrashRecoveryHandler::RETAIN_IMPORTANT_INFO) { // Read avatar info // Location and orientation settings.beginGroup(ADDRESS_MANAGER_GROUP); address = settings.value(ADDRESS_KEY).toUrl(); settings.endGroup(); // Display name and avatar settings.beginGroup(AVATAR_GROUP); displayName = settings.value(DISPLAY_NAME_KEY).toString(); fullAvatarURL = settings.value(FULL_AVATAR_URL_KEY).toUrl(); fullAvatarModelName = settings.value(FULL_AVATAR_MODEL_NAME_KEY).toString(); settings.endGroup(); // Tutorial complete tutorialComplete = settings.value(TUTORIAL_COMPLETE_FLAG_KEY).toBool(); } // Delete Interface.ini QFile settingsFile(settings.fileName()); if (settingsFile.exists()) { settingsFile.remove(); } if (action == CrashRecoveryHandler::RETAIN_IMPORTANT_INFO) { // Write avatar info // Location and orientation settings.beginGroup(ADDRESS_MANAGER_GROUP); settings.setValue(ADDRESS_KEY, address); settings.endGroup(); // Display name and avatar settings.beginGroup(AVATAR_GROUP); settings.setValue(DISPLAY_NAME_KEY, displayName); settings.setValue(FULL_AVATAR_URL_KEY, fullAvatarURL); settings.setValue(FULL_AVATAR_MODEL_NAME_KEY, fullAvatarModelName); settings.endGroup(); // Tutorial complete settings.setValue(TUTORIAL_COMPLETE_FLAG_KEY, tutorialComplete); } }