@@ -89,7 +89,7 @@ static bool InitializeConfig(std::string settings_filename);
89
89
static bool ShouldUsePortableMode ();
90
90
static void SetAppRoot ();
91
91
static void SetResourcesDirectory ();
92
- static void SetDataDirectory ();
92
+ static bool SetDataDirectory ();
93
93
static bool SetCriticalFolders ();
94
94
static void SetDefaultSettings (SettingsInterface& si, bool system, bool controller);
95
95
static void SaveSettings ();
@@ -335,13 +335,13 @@ bool QtHost::InitializeConfig(std::string settings_filename)
335
335
if (settings_filename.empty ())
336
336
settings_filename = Path::Combine (EmuFolders::DataRoot, " settings.ini" );
337
337
338
- Log_InfoPrintf ( " Loading config from %s. " , settings_filename.c_str ());
339
- s_run_setup_wizard = s_run_setup_wizard || ! FileSystem::FileExists ( settings_filename. c_str () );
338
+ const bool settings_exists = FileSystem::FileExists ( settings_filename.c_str ());
339
+ Log_InfoFmt ( " Loading config from {}. " , settings_filename);
340
340
s_base_settings_interface = std::make_unique<INISettingsInterface>(std::move (settings_filename));
341
341
Host::Internal::SetBaseSettingsLayer (s_base_settings_interface.get ());
342
342
343
343
uint settings_version;
344
- if (!s_base_settings_interface->Load () ||
344
+ if (!settings_exists || ! s_base_settings_interface->Load () ||
345
345
!s_base_settings_interface->GetUIntValue (" Main" , " SettingsVersion" , &settings_version) ||
346
346
settings_version != SETTINGS_VERSION)
347
347
{
@@ -356,9 +356,22 @@ bool QtHost::InitializeConfig(std::string settings_filename)
356
356
s_base_settings_interface->SetBoolValue (" ControllerPorts" , " ControllerSettingsMigrated" , true );
357
357
SetDefaultSettings (*s_base_settings_interface, true , true );
358
358
359
- // Don't save if we're running the setup wizard. We want to run it next time if they don't finish it.
360
- if (!s_run_setup_wizard)
361
- s_base_settings_interface->Save ();
359
+ // Flag for running the setup wizard if this is our first run. We want to run it next time if they don't finish it.
360
+ s_base_settings_interface->SetBoolValue (" Main" , " SetupWizardIncomplete" , true );
361
+
362
+ // Make sure we can actually save the config, and the user doesn't have some permission issue.
363
+ Error error;
364
+ if (!s_base_settings_interface->Save (&error))
365
+ {
366
+ QMessageBox::critical (
367
+ nullptr , QStringLiteral (" DuckStation" ),
368
+ QStringLiteral (
369
+ " Failed to save configuration to\n\n %1\n\n The error was: %2\n\n Please ensure this directory is writable. You "
370
+ " can also try portable mode by creating portable.txt in the same directory you installed DuckStation into." )
371
+ .arg (QString::fromStdString (s_base_settings_interface->GetFileName ()))
372
+ .arg (QString::fromStdString (error.GetDescription ())));
373
+ return false ;
374
+ }
362
375
}
363
376
364
377
// Setup wizard was incomplete last time?
@@ -391,7 +404,8 @@ bool QtHost::SetCriticalFolders()
391
404
{
392
405
SetAppRoot ();
393
406
SetResourcesDirectory ();
394
- SetDataDirectory ();
407
+ if (!SetDataDirectory ())
408
+ return false ;
395
409
396
410
// logging of directories in case something goes wrong super early
397
411
Log_DevPrintf (" AppRoot Directory: %s" , EmuFolders::AppRoot.c_str ());
@@ -438,16 +452,16 @@ void QtHost::SetResourcesDirectory()
438
452
#endif
439
453
}
440
454
441
- void QtHost::SetDataDirectory ()
455
+ bool QtHost::SetDataDirectory ()
442
456
{
443
457
// Already set, e.g. by -portable.
444
458
if (!EmuFolders::DataRoot.empty ())
445
- return ;
459
+ return true ;
446
460
447
461
if (ShouldUsePortableMode ())
448
462
{
449
463
EmuFolders::DataRoot = EmuFolders::AppRoot;
450
- return ;
464
+ return true ;
451
465
}
452
466
453
467
#if defined(_WIN32)
@@ -491,13 +505,26 @@ void QtHost::SetDataDirectory()
491
505
if (!EmuFolders::DataRoot.empty () && !FileSystem::DirectoryExists (EmuFolders::DataRoot.c_str ()))
492
506
{
493
507
// we're in trouble if we fail to create this directory... but try to hobble on with portable
494
- if (!FileSystem::EnsureDirectoryExists (EmuFolders::DataRoot.c_str (), false ))
495
- EmuFolders::DataRoot.clear ();
508
+ Error error;
509
+ if (!FileSystem::EnsureDirectoryExists (EmuFolders::DataRoot.c_str (), false , &error))
510
+ {
511
+ // no point translating, config isn't loaded
512
+ QMessageBox::critical (
513
+ nullptr , QStringLiteral (" DuckStation" ),
514
+ QStringLiteral (" Failed to create data directory at path\n\n %1\n\n The error was: %2\n Please ensure this "
515
+ " directory is writable. You can also try portable mode by creating portable.txt in the same "
516
+ " directory you installed DuckStation into." )
517
+ .arg (QString::fromStdString (EmuFolders::DataRoot))
518
+ .arg (QString::fromStdString (error.GetDescription ())));
519
+ return false ;
520
+ }
496
521
}
497
522
498
523
// couldn't determine the data directory? fallback to portable.
499
524
if (EmuFolders::DataRoot.empty ())
500
525
EmuFolders::DataRoot = EmuFolders::AppRoot;
526
+
527
+ return true ;
501
528
}
502
529
503
530
void Host::LoadSettings (SettingsInterface& si, std::unique_lock<std::mutex>& lock)
@@ -2212,10 +2239,6 @@ bool QtHost::ParseCommandLineParametersAndInitializeConfig(QApplication& app,
2212
2239
2213
2240
bool QtHost::RunSetupWizard ()
2214
2241
{
2215
- // Set a flag in the config so that even though we created the ini, we'll run the wizard next time.
2216
- Host::SetBaseBoolSettingValue (" Main" , " SetupWizardIncomplete" , true );
2217
- Host::CommitBaseSettingChanges ();
2218
-
2219
2242
SetupWizardDialog dialog;
2220
2243
if (dialog.exec () == QDialog::Rejected)
2221
2244
return false ;
0 commit comments