message: gui: Prompt to reset settings when settings.json cannot be read
  Fixes bitcoin/bitcoin#21340
diff: @@ -144,6 +144,58 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans
  QApplication::installTranslator(&translator);
  }
  +static std::string JoinErrors(const std::vector<std::string>& errors)
  +{
  + return Join(errors, "\n", [](const std::string& error) { return "- " + error; });
  +}
  +
  +static bool InitSettings()
  +{
  + if (!gArgs.GetSettingsPath()) {
  + return true; // Do nothing if settings file disabled.
  + }
  +
  + std::vector<std::string> errors;
  + if (!gArgs.ReadSettingsFile(&errors)) {
  + bilingual_str error = _("Settings file could not be read");
  + InitError(Untranslated(strprintf("%s:\n%s\n", error.original, JoinErrors(errors))));
  +
  + QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error.translated)), QMessageBox::Reset | QMessageBox::Abort);
  + /*: Explanatory text shown on startup when the settings file cannot be read.
  + Prompts user to make a choice between resetting or aborting. */
  + messagebox.setInformativeText(QObject::tr("Do you want to reset settings to default values, or to abort without making changes?"));
  + messagebox.setDetailedText(QString::fromStdString(JoinErrors(errors)));
  + messagebox.setTextFormat(Qt::PlainText);
  + messagebox.setDefaultButton(QMessageBox::Reset);
  + switch (messagebox.exec()) {
  + case QMessageBox::Reset:
  + break;
  + case QMessageBox::Abort:
  + return false;
  + default:
  + assert(false);
  + }
  + }
  +
  + errors.clear();
  + if (!gArgs.WriteSettingsFile(&errors)) {
  + bilingual_str error = _("Settings file could not be written");
  + InitError(Untranslated(strprintf("%s:\n%s\n", error.original, JoinErrors(errors))));
  +
  + QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error.translated)), QMessageBox::Ok);
  + /*: Explanatory text shown on startup when the settings file could not be written.
  + Prompts user to check that we have the ability to write to the file.
  + Explains that the user has the option of running without a settings file.*/
  + messagebox.setInformativeText(QObject::tr("A fatal error occured. Check that settings file is writable, or try running with -nosettings."));
  + messagebox.setDetailedText(QString::fromStdString(JoinErrors(errors)));
  + messagebox.setTextFormat(Qt::PlainText);
  + messagebox.setDefaultButton(QMessageBox::Ok);
  + messagebox.exec();
  + return false;
  + }
  + return true;
  +}
  +
  /* qDebug() message handler --> debug.log */
  void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
  {
  @@ -512,9 +564,8 @@ int GuiMain(int argc, char* argv[])
  // Parse URIs on command line -- this can affect Params()
  PaymentServer::ipcParseCommandLine(argc, argv);
  #endif
  - if (!gArgs.InitSettings(error)) {
  - InitError(Untranslated(error));
  - QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error initializing settings: %1").arg(QString::fromStdString(error)));
  +
  + if (!InitSettings()) {
  return EXIT_FAILURE;
  }
  