diff --git a/src/BizHawk.Client.Common/DialogControllerExtensions.cs b/src/BizHawk.Client.Common/DialogControllerExtensions.cs
index 9c83be78dc..aa607e9507 100644
--- a/src/BizHawk.Client.Common/DialogControllerExtensions.cs
+++ b/src/BizHawk.Client.Common/DialogControllerExtensions.cs
@@ -5,6 +5,13 @@ using System.Diagnostics;
namespace BizHawk.Client.Common
{
+ public enum TryAgainResult
+ {
+ Saved,
+ IgnoredFailure,
+ Canceled,
+ }
+
public static class DialogControllerExtensions
{
public static void AddOnScreenMessage(this IDialogParent dialogParent, string message, int? duration = null)
@@ -80,7 +87,7 @@ namespace BizHawk.Client.Common
/// The user will be repeatedly asked if they want to try again until either success or the user says no.
///
/// Returns true on success or if the user said no. Returns false if the user said cancel.
- public static bool DoWithTryAgainBox(
+ public static TryAgainResult DoWithTryAgainBox(
this IDialogParent dialogParent,
Func action,
string message)
@@ -94,12 +101,12 @@ namespace BizHawk.Client.Common
$"{fileResult.UserFriendlyErrorMessage()}\n{fileResult.Exception!.Message}",
caption: "Error",
icon: EMsgBoxIcon.Error);
- if (askResult == null) return false;
- if (askResult == false) return true;
+ if (askResult == null) return TryAgainResult.Canceled;
+ if (askResult == false) return TryAgainResult.IgnoredFailure;
if (askResult == true) fileResult = action();
}
- return true;
+ return TryAgainResult.Saved;
}
/// Creates and shows a System.Windows.Forms.OpenFileDialog or equivalent with the receiver () as its parent
diff --git a/src/BizHawk.Client.Common/FileWriter.cs b/src/BizHawk.Client.Common/FileWriter.cs
index 8a0a83c22d..227ebb0168 100644
--- a/src/BizHawk.Client.Common/FileWriter.cs
+++ b/src/BizHawk.Client.Common/FileWriter.cs
@@ -56,6 +56,22 @@ namespace BizHawk.Client.Common
return createResult.Value.CloseAndDispose(backupPath);
}
+ public static FileWriteResult Write(string path, Action writeCallback, string? backupPath = null)
+ {
+ FileWriteResult createResult = Create(path);
+ if (createResult.IsError) return createResult;
+
+ try
+ {
+ writeCallback(createResult.Value!.Stream);
+ }
+ catch (Exception ex)
+ {
+ return new(FileWriteEnum.FailedDuringWrite, createResult.Value!.Paths, ex);
+ }
+
+ return createResult.Value.CloseAndDispose(backupPath);
+ }
///
/// Create a FileWriter instance, or return an error if unable to access the file.
@@ -76,6 +92,7 @@ namespace BizHawk.Client.Common
FileWritePaths paths = new(path, writePath);
try
{
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
FileStream fs = new(writePath, FileMode.Create, FileAccess.Write);
return new(new FileWriter(paths, fs), paths);
}
diff --git a/src/BizHawk.Client.Common/lua/LuaFileList.cs b/src/BizHawk.Client.Common/lua/LuaFileList.cs
index 13784bf6f8..15b2493c0a 100644
--- a/src/BizHawk.Client.Common/lua/LuaFileList.cs
+++ b/src/BizHawk.Client.Common/lua/LuaFileList.cs
@@ -102,9 +102,8 @@ namespace BizHawk.Client.Common
return true;
}
- public void Save(string path)
+ public FileWriteResult Save(string path)
{
- using var sw = new StreamWriter(path);
var sb = new StringBuilder();
var saveDirectory = Path.GetDirectoryName(Path.GetFullPath(path));
foreach (var file in this)
@@ -123,10 +122,19 @@ namespace BizHawk.Client.Common
}
}
- sw.Write(sb.ToString());
+ FileWriteResult result = FileWriter.Write(path, (fs) =>
+ {
+ using var sw = new StreamWriter(fs);
+ sw.Write(sb.ToString());
+ });
- Filename = path;
- Changes = false;
+ if (!result.IsError)
+ {
+ Filename = path;
+ Changes = false;
+ }
+
+ return result;
}
}
}
diff --git a/src/BizHawk.Client.Common/movie/MovieSession.cs b/src/BizHawk.Client.Common/movie/MovieSession.cs
index d63501bf4a..52055e4ce9 100644
--- a/src/BizHawk.Client.Common/movie/MovieSession.cs
+++ b/src/BizHawk.Client.Common/movie/MovieSession.cs
@@ -385,6 +385,8 @@ namespace BizHawk.Client.Common
switch (Settings.MovieEndAction)
{
case MovieEndAction.Stop:
+ // Technically this can save the movie, but it'd be weird to be in that situation.
+ // Do we want that?
StopMovie();
break;
case MovieEndAction.Record:
diff --git a/src/BizHawk.Client.Common/tools/CheatList.cs b/src/BizHawk.Client.Common/tools/CheatList.cs
index a9cca688a9..5de61df7a3 100644
--- a/src/BizHawk.Client.Common/tools/CheatList.cs
+++ b/src/BizHawk.Client.Common/tools/CheatList.cs
@@ -88,20 +88,10 @@ namespace BizHawk.Client.Common
return file.Exists && Load(domains, file.FullName, false);
}
- public void NewList(string defaultFileName, bool autosave = false)
+ public void NewList(string defaultFileName)
{
_defaultFileName = defaultFileName;
- if (autosave && _changes && _cheatList.Count is not 0)
- {
- if (string.IsNullOrEmpty(CurrentFileName))
- {
- CurrentFileName = _defaultFileName;
- }
-
- Save();
- }
-
_cheatList.Clear();
CurrentFileName = "";
Changes = false;
@@ -220,7 +210,7 @@ namespace BizHawk.Client.Common
public bool IsActive(MemoryDomain domain, long address)
=> _cheatList.Exists(cheat => !cheat.IsSeparator && cheat.Enabled && cheat.Domain == domain && cheat.Contains(address));
- public void SaveOnClose()
+ public FileWriteResult SaveOnClose()
{
if (_config.AutoSaveOnClose)
{
@@ -231,17 +221,27 @@ namespace BizHawk.Client.Common
CurrentFileName = _defaultFileName;
}
- SaveFile(CurrentFileName);
+ return SaveFile(CurrentFileName);
}
else if (_cheatList.Count is 0 && !string.IsNullOrWhiteSpace(CurrentFileName))
{
- File.Delete(CurrentFileName);
+ try
+ {
+ File.Delete(CurrentFileName);
+ }
+ catch (Exception ex)
+ {
+ return new(FileWriteEnum.FailedToDeleteGeneric, new(CurrentFileName, ""), ex);
+ }
_config.Recent.Remove(CurrentFileName);
+ return new();
}
}
+
+ return new();
}
- public bool Save()
+ public FileWriteResult Save()
{
if (string.IsNullOrWhiteSpace(CurrentFileName))
{
@@ -251,54 +251,51 @@ namespace BizHawk.Client.Common
return SaveFile(CurrentFileName);
}
- public bool SaveFile(string path)
+ public FileWriteResult SaveFile(string path)
{
- try
+ var sb = new StringBuilder();
+
+ foreach (var cheat in _cheatList)
{
- new FileInfo(path).Directory?.Create();
- var sb = new StringBuilder();
-
- foreach (var cheat in _cheatList)
+ if (cheat.IsSeparator)
{
- if (cheat.IsSeparator)
- {
- sb.AppendLine("----");
- }
- else
- {
- // Set to hex for saving
- var tempCheatType = cheat.Type;
-
- cheat.SetType(WatchDisplayType.Hex);
-
- sb
- .Append(cheat.AddressStr).Append('\t')
- .Append(cheat.ValueStr).Append('\t')
- .Append(cheat.Compare is null ? "N" : cheat.CompareStr).Append('\t')
- .Append(cheat.Domain != null ? cheat.Domain.Name : "").Append('\t')
- .Append(cheat.Enabled ? '1' : '0').Append('\t')
- .Append(cheat.Name).Append('\t')
- .Append(cheat.SizeAsChar).Append('\t')
- .Append(cheat.TypeAsChar).Append('\t')
- .Append(cheat.BigEndian is true ? '1' : '0').Append('\t')
- .Append(cheat.ComparisonType).Append('\t')
- .AppendLine();
-
- cheat.SetType(tempCheatType);
- }
+ sb.AppendLine("----");
}
+ else
+ {
+ // Set to hex for saving
+ var tempCheatType = cheat.Type;
- File.WriteAllText(path, sb.ToString());
+ cheat.SetType(WatchDisplayType.Hex);
+ sb
+ .Append(cheat.AddressStr).Append('\t')
+ .Append(cheat.ValueStr).Append('\t')
+ .Append(cheat.Compare is null ? "N" : cheat.CompareStr).Append('\t')
+ .Append(cheat.Domain != null ? cheat.Domain.Name : "").Append('\t')
+ .Append(cheat.Enabled ? '1' : '0').Append('\t')
+ .Append(cheat.Name).Append('\t')
+ .Append(cheat.SizeAsChar).Append('\t')
+ .Append(cheat.TypeAsChar).Append('\t')
+ .Append(cheat.BigEndian is true ? '1' : '0').Append('\t')
+ .Append(cheat.ComparisonType).Append('\t')
+ .AppendLine();
+
+ cheat.SetType(tempCheatType);
+ }
+ }
+ FileWriteResult result = FileWriter.Write(path, (fs) =>
+ {
+ StreamWriter sw = new(fs);
+ sw.Write(sb.ToString());
+ });
+ if (!result.IsError)
+ {
CurrentFileName = path;
_config.Recent.Add(CurrentFileName);
Changes = false;
- return true;
- }
- catch
- {
- return false;
}
+ return result;
}
public bool Load(IMemoryDomains domains, string path, bool append)
diff --git a/src/BizHawk.Client.Common/tools/Watch/WatchList/WatchList.cs b/src/BizHawk.Client.Common/tools/Watch/WatchList/WatchList.cs
index 0a3e12d913..eb5afeb1de 100644
--- a/src/BizHawk.Client.Common/tools/Watch/WatchList/WatchList.cs
+++ b/src/BizHawk.Client.Common/tools/Watch/WatchList/WatchList.cs
@@ -1,5 +1,6 @@
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -338,39 +339,37 @@ namespace BizHawk.Client.Common
}
}
- public bool Save()
+ public FileWriteResult Save()
{
if (string.IsNullOrWhiteSpace(CurrentFileName))
{
- return false;
+ return new();
}
- using (var sw = new StreamWriter(CurrentFileName))
+ var sb = new StringBuilder();
+ sb.Append("SystemID ").AppendLine(_systemId);
+
+ foreach (var watch in _watchList)
{
- var sb = new StringBuilder();
- sb.Append("SystemID ").AppendLine(_systemId);
-
- foreach (var watch in _watchList)
- {
- sb.AppendLine(watch.ToString());
- }
-
- sw.WriteLine(sb.ToString());
+ sb.AppendLine(watch.ToString());
}
- Changes = false;
- return true;
+ FileWriteResult result = FileWriter.Write(CurrentFileName, (fs) =>
+ {
+ using var sw = new StreamWriter(fs);
+ sw.WriteLine(sb.ToString());
+ });
+
+ if (!result.IsError) Changes = false;
+ return result;
}
- public bool SaveAs(FileInfo file)
+ public FileWriteResult SaveAs(FileInfo file)
{
- if (file != null)
- {
- CurrentFileName = file.FullName;
- return Save();
- }
+ Debug.Assert(file != null, "Cannot save as without a file name.");
- return false;
+ CurrentFileName = file.FullName;
+ return Save();
}
private bool LoadFile(string path, bool append)
diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs
index 4bfebc1358..0479ab9f8b 100644
--- a/src/BizHawk.Client.EmuHawk/MainForm.cs
+++ b/src/BizHawk.Client.EmuHawk/MainForm.cs
@@ -3934,7 +3934,7 @@ namespace BizHawk.Client.EmuHawk
if (previousRom != CurrentlyOpenRom)
{
- CheatList.NewList(Tools.GenerateDefaultCheatFilename(), autosave: true);
+ CheatList.NewList(Tools.GenerateDefaultCheatFilename());
if (Config.Cheats.LoadFileByGame && Emulator.HasMemoryDomains())
{
if (CheatList.AttemptToLoadCheatFile(Emulator.AsMemoryDomains()))
@@ -3951,7 +3951,7 @@ namespace BizHawk.Client.EmuHawk
}
else
{
- CheatList.NewList(Tools.GenerateDefaultCheatFilename(), autosave: true);
+ CheatList.NewList(Tools.GenerateDefaultCheatFilename());
}
}
@@ -3988,7 +3988,7 @@ namespace BizHawk.Client.EmuHawk
DisplayManager.UpdateGlobals(Config, Emulator);
DisplayManager.Blank();
ExtToolManager.BuildToolStrip();
- CheatList.NewList("", autosave: true);
+ CheatList.NewList("");
OnRomChanged();
return false;
}
@@ -4050,25 +4050,30 @@ namespace BizHawk.Client.EmuHawk
{
CommitCoreSettingsToConfig(); // Must happen before stopping the movie, since it checks for active movie.
+ GameIsClosing = true;
if (!Tools.AskSave())
{
+ GameIsClosing = false;
return false;
}
// There is a cheats tool, but cheats can be active while the "cheats tool" is not. And have auto-save option.
- CheatList.SaveOnClose();
-
- GameIsClosing = true;
- FileWriteResult saveResult = MovieSession.StopMovie();
- GameIsClosing = false;
- if (saveResult.IsError)
+ TryAgainResult cheatSaveResult = this.DoWithTryAgainBox(CheatList.SaveOnClose, "Failed to save cheats.");
+ if (cheatSaveResult == TryAgainResult.Canceled)
{
- if (!this.ModalMessageBox2(
- caption: "Quit anyway?",
- icon: EMsgBoxIcon.Question,
- text: "The currently playing movie could not be saved. Continue and quit anyway? All unsaved changes will be lost."))
- {
- return false;
- }
+ GameIsClosing = false;
+ return false;
+ }
+
+ // If TAStudio is open, we already asked about saving the movie.
+ if (Tools.IsLoaded())
+ {
+ GameIsClosing = false;
+ }
+ else
+ {
+ TryAgainResult saveMovieResult = this.DoWithTryAgainBox(() => MovieSession.StopMovie(), "Failed to save movie.");
+ GameIsClosing = false;
+ if (saveMovieResult == TryAgainResult.Canceled) return false;
}
if (clearSram)
@@ -4076,7 +4081,7 @@ namespace BizHawk.Client.EmuHawk
var path = Config.PathEntries.SaveRamAbsolutePath(Game, MovieSession.Movie);
if (File.Exists(path))
{
- bool clearResult = this.DoWithTryAgainBox(() => {
+ TryAgainResult clearResult = this.DoWithTryAgainBox(() => {
try
{
File.Delete(path);
@@ -4088,7 +4093,7 @@ namespace BizHawk.Client.EmuHawk
return new(FileWriteEnum.FailedToDeleteGeneric, new(path, ""), ex);
}
}, "Failed to clear SRAM.");
- if (!clearResult)
+ if (clearResult == TryAgainResult.Canceled)
{
return false;
}
@@ -4096,14 +4101,14 @@ namespace BizHawk.Client.EmuHawk
}
else if (Emulator.HasSaveRam())
{
- bool flushResult = this.DoWithTryAgainBox(
+ TryAgainResult flushResult = this.DoWithTryAgainBox(
() => FlushSaveRAM(),
"Failed flushing the game's Save RAM to your disk.");
- if (!flushResult) return false;
+ if (flushResult == TryAgainResult.Canceled) return false;
}
- bool stateSaveResult = this.DoWithTryAgainBox(AutoSaveStateIfConfigured, "Failed to auto-save state.");
- if (!stateSaveResult) return false;
+ TryAgainResult stateSaveResult = this.DoWithTryAgainBox(AutoSaveStateIfConfigured, "Failed to auto-save state.");
+ if (stateSaveResult == TryAgainResult.Canceled) return false;
StopAv();
@@ -4146,7 +4151,7 @@ namespace BizHawk.Client.EmuHawk
PauseOnFrame = null;
CurrentlyOpenRom = null;
CurrentlyOpenRomArgs = null;
- CheatList.NewList("", autosave: true);
+ CheatList.NewList("");
OnRomChanged();
}
}
diff --git a/src/BizHawk.Client.EmuHawk/tools/CDL.cs b/src/BizHawk.Client.EmuHawk/tools/CDL.cs
index 5c12ce5572..317a104128 100644
--- a/src/BizHawk.Client.EmuHawk/tools/CDL.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/CDL.cs
@@ -214,19 +214,23 @@ namespace BizHawk.Client.EmuHawk
{
if (_currentFilename != null)
{
- RunSave();
+ bool saveResult2 = RunSave();
ShutdownCDL();
- return true;
+ return saveResult2;
}
}
- // TODO - I don't like this system. It's hard to figure out how to use it. It should be done in multiple passes.
- var result = DialogController.ShowMessageBox2("Save changes to CDL session?", "CDL Auto Save", EMsgBoxIcon.Question);
- if (!result)
+ var result = DialogController.ShowMessageBox3("Save changes to CDL session?", "CDL Save", EMsgBoxIcon.Question);
+ if (result == false)
{
ShutdownCDL();
return true;
}
+ else if (result == null)
+ {
+ ShutdownCDL();
+ return false;
+ }
if (string.IsNullOrWhiteSpace(_currentFilename))
{
@@ -240,9 +244,9 @@ namespace BizHawk.Client.EmuHawk
return false;
}
- RunSave();
+ bool saveResult = RunSave();
ShutdownCDL();
- return true;
+ return saveResult;
}
private bool _autoloading;
@@ -341,11 +345,20 @@ namespace BizHawk.Client.EmuHawk
LoadFile(file.FullName);
}
- private void RunSave()
+ ///
+ /// returns false if the operation was canceled
+ ///
+ private bool RunSave()
{
- _recent.Add(_currentFilename);
- using var fs = new FileStream(_currentFilename, FileMode.Create, FileAccess.Write);
- _cdl.Save(fs);
+ TryAgainResult result = this.DoWithTryAgainBox(
+ () => FileWriter.Write(_currentFilename, _cdl.Save),
+ "Failed to save CDL session.");
+ if (result == TryAgainResult.Saved)
+ {
+ _recent.Add(_currentFilename);
+ return true;
+ }
+ return result != TryAgainResult.Canceled;
}
private void SaveMenuItem_Click(object sender, EventArgs e)
@@ -386,8 +399,7 @@ namespace BizHawk.Client.EmuHawk
return false;
SetCurrentFilename(file.FullName);
- RunSave();
- return true;
+ return RunSave();
}
private void SaveAsMenuItem_Click(object sender, EventArgs e)
diff --git a/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs b/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs
index 3c8447ea79..0addc928b8 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs
@@ -142,7 +142,7 @@ namespace BizHawk.Client.EmuHawk
}
}
- private bool SaveAs()
+ private FileWriteResult SaveAs()
{
var fileName = MainForm.CheatList.CurrentFileName;
if (string.IsNullOrWhiteSpace(fileName))
@@ -156,7 +156,8 @@ namespace BizHawk.Client.EmuHawk
CheatsFSFilterSet,
this);
- return file != null && MainForm.CheatList.SaveFile(file.FullName);
+ if (file == null) return new();
+ else return MainForm.CheatList.SaveFile(file.FullName);
}
private void Cheats_Load(object sender, EventArgs e)
@@ -361,7 +362,12 @@ namespace BizHawk.Client.EmuHawk
{
if (MainForm.CheatList.Changes)
{
- if (MainForm.CheatList.Save())
+ FileWriteResult result = MainForm.CheatList.Save();
+ if (result.IsError)
+ {
+ this.ErrorMessageBox(result);
+ }
+ else
{
UpdateMessageLabel(saved: true);
}
@@ -374,7 +380,12 @@ namespace BizHawk.Client.EmuHawk
private void SaveAsMenuItem_Click(object sender, EventArgs e)
{
- if (SaveAs())
+ FileWriteResult result = SaveAs();
+ if (result.IsError)
+ {
+ this.ErrorMessageBox(result);
+ }
+ else
{
UpdateMessageLabel(saved: true);
}
diff --git a/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs b/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs
index 7fdd0e5cd0..c74284f79f 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs
@@ -681,15 +681,25 @@ namespace BizHawk.Client.EmuHawk
return result is not null ? new FileInfo(result) : null;
}
- private void SaveSessionAs()
+ private FileWriteResult SaveSessionAs()
{
var file = GetSaveFileFromUser();
if (file != null)
{
- LuaImp.ScriptList.Save(file.FullName);
- Config.RecentLuaSession.Add(file.FullName);
- OutputMessages.Text = $"{file.Name} saved.";
+ FileWriteResult saveResult = LuaImp.ScriptList.Save(file.FullName);
+ if (saveResult.IsError)
+ {
+ this.ErrorMessageBox(saveResult);
+ OutputMessages.Text = $"Lua session could not be saved to {file.Name}";
+ }
+ else
+ {
+ Config.RecentLuaSession.Add(file.FullName);
+ OutputMessages.Text = $"{file.Name} saved.";
+ }
+ return saveResult;
}
+ return new();
}
private void LoadSessionFromRecent(string path)
@@ -717,7 +727,11 @@ namespace BizHawk.Client.EmuHawk
icon: EMsgBoxIcon.Question,
text: $"Save {WindowTitleStatic} session?"));
if (result is null) return false;
- if (result.Value) SaveOrSaveAs();
+ if (result.Value)
+ {
+ TryAgainResult saveResult = this.DoWithTryAgainBox(SaveOrSaveAs, "Failed to save Lua session.");
+ return saveResult != TryAgainResult.Canceled;
+ }
else LuaImp.ScriptList.Changes = false;
return true;
}
@@ -732,16 +746,20 @@ namespace BizHawk.Client.EmuHawk
}
}
- private void SaveOrSaveAs()
+ private FileWriteResult SaveOrSaveAs()
{
if (!string.IsNullOrWhiteSpace(LuaImp.ScriptList.Filename))
{
- LuaImp.ScriptList.Save(LuaImp.ScriptList.Filename);
- Config.RecentLuaSession.Add(LuaImp.ScriptList.Filename);
+ FileWriteResult result = LuaImp.ScriptList.Save(LuaImp.ScriptList.Filename);
+ if (!result.IsError)
+ {
+ Config.RecentLuaSession.Add(LuaImp.ScriptList.Filename);
+ }
+ return result;
}
else
{
- SaveSessionAs();
+ return SaveSessionAs();
}
}
@@ -784,8 +802,16 @@ namespace BizHawk.Client.EmuHawk
{
if (LuaImp.ScriptList.Changes)
{
- SaveOrSaveAs();
- OutputMessages.Text = $"{Path.GetFileName(LuaImp.ScriptList.Filename)} saved.";
+ FileWriteResult result = SaveOrSaveAs();
+ if (result.IsError)
+ {
+ this.ErrorMessageBox(result, "Failed to save Lua session.");
+ OutputMessages.Text = $"Failed to save {Path.GetFileName(LuaImp.ScriptList.Filename)}";
+ }
+ else
+ {
+ OutputMessages.Text = $"{Path.GetFileName(LuaImp.ScriptList.Filename)} saved.";
+ }
}
}
diff --git a/src/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs b/src/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs
index dc865572e0..a3758c05ce 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs
@@ -112,6 +112,7 @@ namespace BizHawk.Client.EmuHawk
return true;
}
+ // Intentionally not updating this to use FileWriter because this tool is going to be removed later.
foreach (var zone in _unsavedZones)
{
SaveMacroAs(_zones[zone]);
diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs
index 3b8a33b1e5..16e9ea4302 100644
--- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.IToolForm.cs
@@ -161,15 +161,8 @@ namespace BizHawk.Client.EmuHawk
text: $"Save {WindowTitleStatic} project?"));
if (shouldSaveResult == true)
{
- FileWriteResult saveResult = SaveTas();
- while (saveResult.IsError && shouldSaveResult != true)
- {
- shouldSaveResult = this.ModalMessageBox3(
- $"Failed to save movie. {saveResult.UserFriendlyErrorMessage()}\n{saveResult.Exception.Message}\n\nTry again?",
- "Error",
- EMsgBoxIcon.Error);
- if (shouldSaveResult == true) saveResult = SaveTas();
- }
+ TryAgainResult saveResult = this.DoWithTryAgainBox(() => SaveTas(), "Failed to save movie.");
+ return saveResult != TryAgainResult.Canceled;
}
if (shouldSaveResult is null) return false;
else CurrentTasMovie.ClearChanges();
diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
index 6a303c2a95..07921b0b22 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
@@ -1008,7 +1008,13 @@ namespace BizHawk.Client.EmuHawk
if (!string.IsNullOrWhiteSpace(watches.CurrentFileName))
{
- if (watches.Save())
+ FileWriteResult saveResult = watches.Save();
+ if (saveResult.IsError)
+ {
+ this.ErrorMessageBox(saveResult);
+ MessageLabel.Text = $"Failed to save {Path.GetFileName(_currentFileName)}";
+ }
+ else
{
_currentFileName = watches.CurrentFileName;
MessageLabel.Text = $"{Path.GetFileName(_currentFileName)} saved";
@@ -1017,11 +1023,20 @@ namespace BizHawk.Client.EmuHawk
}
else
{
- var result = watches.SaveAs(GetWatchSaveFileFromUser(CurrentFileName()));
- if (result)
+ FileInfo/*?*/ file = GetWatchSaveFileFromUser(CurrentFileName());
+ if (file != null)
{
- MessageLabel.Text = $"{Path.GetFileName(_currentFileName)} saved";
- Settings.RecentSearches.Add(watches.CurrentFileName);
+ var result = watches.SaveAs(file);
+ if (result.IsError)
+ {
+ this.ErrorMessageBox(result);
+ MessageLabel.Text = $"Failed to save {Path.GetFileName(_currentFileName)}";
+ }
+ else
+ {
+ MessageLabel.Text = $"{Path.GetFileName(_currentFileName)} saved";
+ Settings.RecentSearches.Add(watches.CurrentFileName);
+ }
}
}
}
@@ -1035,7 +1050,15 @@ namespace BizHawk.Client.EmuHawk
watches.Add(_searches[i]);
}
- if (watches.SaveAs(GetWatchSaveFileFromUser(CurrentFileName())))
+ FileInfo/*?*/ file = GetWatchSaveFileFromUser(CurrentFileName());
+ if (file == null) return;
+ FileWriteResult result = watches.SaveAs(file);
+ if (result.IsError)
+ {
+ this.ErrorMessageBox(result);
+ MessageLabel.Text = $"Failed to save {Path.GetFileName(_currentFileName)}";
+ }
+ else
{
_currentFileName = watches.CurrentFileName;
MessageLabel.Text = $"{Path.GetFileName(_currentFileName)} saved";
diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs
index e54bf3a62f..9555251765 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs
@@ -213,15 +213,8 @@ namespace BizHawk.Client.EmuHawk
if (result is null) return false;
if (result.Value)
{
- if (string.IsNullOrWhiteSpace(_watches.CurrentFileName))
- {
- SaveAs();
- }
- else
- {
- _watches.Save();
- Config.RecentWatches.Add(_watches.CurrentFileName);
- }
+ TryAgainResult saveResult = this.DoWithTryAgainBox(Save, "Failed to save watch list.");
+ return saveResult != TryAgainResult.Canceled;
}
else
{
@@ -591,14 +584,47 @@ namespace BizHawk.Client.EmuHawk
: Game.FilesystemSafeName();
}
- private void SaveAs()
+ private FileWriteResult SaveAs()
{
- var result = _watches.SaveAs(GetWatchSaveFileFromUser(CurrentFileName()));
- if (result)
+ FileInfo/*?*/ file = GetWatchSaveFileFromUser(CurrentFileName());
+ if (file == null) return new();
+
+ FileWriteResult result = _watches.SaveAs(file);
+ if (result.IsError)
{
- UpdateStatusBar(saved: true);
- Config.RecentWatches.Add(_watches.CurrentFileName);
+ MessageLabel.Text = $"Failed to save {Path.GetFileName(_watches.CurrentFileName)}";
}
+ else
+ {
+ MessageLabel.Text = $"{Path.GetFileName(_watches.CurrentFileName)} saved";
+ Config.RecentWatches.Add(_watches.CurrentFileName);
+ UpdateStatusBar(saved: true);
+ }
+ return result;
+ }
+
+ private FileWriteResult Save()
+ {
+ if (string.IsNullOrWhiteSpace(_watches.CurrentFileName))
+ {
+ return SaveAs();
+ }
+ else
+ {
+ FileWriteResult saveResult = _watches.Save();
+ if (saveResult.IsError)
+ {
+ MessageLabel.Text = $"Failed to save {Path.GetFileName(_watches.CurrentFileName)}";
+ }
+ else
+ {
+ MessageLabel.Text = $"{Path.GetFileName(_watches.CurrentFileName)} saved";
+ Config.RecentWatches.Add(_watches.CurrentFileName);
+ UpdateStatusBar(saved: true);
+ }
+ return saveResult;
+ }
+
}
private void SaveConfigSettings()
@@ -727,23 +753,20 @@ namespace BizHawk.Client.EmuHawk
private void SaveMenuItem_Click(object sender, EventArgs e)
{
- if (!string.IsNullOrWhiteSpace(_watches.CurrentFileName))
+ FileWriteResult saveResult = Save();
+ if (saveResult.IsError)
{
- if (_watches.Save())
- {
- Config.RecentWatches.Add(_watches.CurrentFileName);
- UpdateStatusBar(saved: true);
- }
- }
- else
- {
- SaveAs();
+ this.ErrorMessageBox(saveResult, "Failed to save watch list.");
}
}
private void SaveAsMenuItem_Click(object sender, EventArgs e)
{
- SaveAs();
+ FileWriteResult saveResult = SaveAs();
+ if (saveResult.IsError)
+ {
+ this.ErrorMessageBox(saveResult, "Failed to save watch list.");
+ }
}
private void RecentSubMenu_DropDownOpened(object sender, EventArgs e)