Handle file writing errors for movies and all tools.
This commit is contained in:
parent
5559b48319
commit
1e57b74fb2
|
@ -5,6 +5,13 @@ using System.Diagnostics;
|
||||||
|
|
||||||
namespace BizHawk.Client.Common
|
namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
|
public enum TryAgainResult
|
||||||
|
{
|
||||||
|
Saved,
|
||||||
|
IgnoredFailure,
|
||||||
|
Canceled,
|
||||||
|
}
|
||||||
|
|
||||||
public static class DialogControllerExtensions
|
public static class DialogControllerExtensions
|
||||||
{
|
{
|
||||||
public static void AddOnScreenMessage(this IDialogParent dialogParent, string message, int? duration = null)
|
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.
|
/// The user will be repeatedly asked if they want to try again until either success or the user says no.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Returns true on success or if the user said no. Returns false if the user said cancel.</returns>
|
/// <returns>Returns true on success or if the user said no. Returns false if the user said cancel.</returns>
|
||||||
public static bool DoWithTryAgainBox(
|
public static TryAgainResult DoWithTryAgainBox(
|
||||||
this IDialogParent dialogParent,
|
this IDialogParent dialogParent,
|
||||||
Func<FileWriteResult> action,
|
Func<FileWriteResult> action,
|
||||||
string message)
|
string message)
|
||||||
|
@ -94,12 +101,12 @@ namespace BizHawk.Client.Common
|
||||||
$"{fileResult.UserFriendlyErrorMessage()}\n{fileResult.Exception!.Message}",
|
$"{fileResult.UserFriendlyErrorMessage()}\n{fileResult.Exception!.Message}",
|
||||||
caption: "Error",
|
caption: "Error",
|
||||||
icon: EMsgBoxIcon.Error);
|
icon: EMsgBoxIcon.Error);
|
||||||
if (askResult == null) return false;
|
if (askResult == null) return TryAgainResult.Canceled;
|
||||||
if (askResult == false) return true;
|
if (askResult == false) return TryAgainResult.IgnoredFailure;
|
||||||
if (askResult == true) fileResult = action();
|
if (askResult == true) fileResult = action();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return TryAgainResult.Saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Creates and shows a <c>System.Windows.Forms.OpenFileDialog</c> or equivalent with the receiver (<paramref name="dialogParent"/>) as its parent</summary>
|
/// <summary>Creates and shows a <c>System.Windows.Forms.OpenFileDialog</c> or equivalent with the receiver (<paramref name="dialogParent"/>) as its parent</summary>
|
||||||
|
|
|
@ -56,6 +56,22 @@ namespace BizHawk.Client.Common
|
||||||
return createResult.Value.CloseAndDispose(backupPath);
|
return createResult.Value.CloseAndDispose(backupPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FileWriteResult Write(string path, Action<Stream> writeCallback, string? backupPath = null)
|
||||||
|
{
|
||||||
|
FileWriteResult<FileWriter> 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);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a FileWriter instance, or return an error if unable to access the file.
|
/// 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);
|
FileWritePaths paths = new(path, writePath);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||||
FileStream fs = new(writePath, FileMode.Create, FileAccess.Write);
|
FileStream fs = new(writePath, FileMode.Create, FileAccess.Write);
|
||||||
return new(new FileWriter(paths, fs), paths);
|
return new(new FileWriter(paths, fs), paths);
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,9 +102,8 @@ namespace BizHawk.Client.Common
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(string path)
|
public FileWriteResult Save(string path)
|
||||||
{
|
{
|
||||||
using var sw = new StreamWriter(path);
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
var saveDirectory = Path.GetDirectoryName(Path.GetFullPath(path));
|
var saveDirectory = Path.GetDirectoryName(Path.GetFullPath(path));
|
||||||
foreach (var file in this)
|
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;
|
if (!result.IsError)
|
||||||
Changes = false;
|
{
|
||||||
|
Filename = path;
|
||||||
|
Changes = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,6 +385,8 @@ namespace BizHawk.Client.Common
|
||||||
switch (Settings.MovieEndAction)
|
switch (Settings.MovieEndAction)
|
||||||
{
|
{
|
||||||
case MovieEndAction.Stop:
|
case MovieEndAction.Stop:
|
||||||
|
// Technically this can save the movie, but it'd be weird to be in that situation.
|
||||||
|
// Do we want that?
|
||||||
StopMovie();
|
StopMovie();
|
||||||
break;
|
break;
|
||||||
case MovieEndAction.Record:
|
case MovieEndAction.Record:
|
||||||
|
|
|
@ -88,20 +88,10 @@ namespace BizHawk.Client.Common
|
||||||
return file.Exists && Load(domains, file.FullName, false);
|
return file.Exists && Load(domains, file.FullName, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void NewList(string defaultFileName, bool autosave = false)
|
public void NewList(string defaultFileName)
|
||||||
{
|
{
|
||||||
_defaultFileName = defaultFileName;
|
_defaultFileName = defaultFileName;
|
||||||
|
|
||||||
if (autosave && _changes && _cheatList.Count is not 0)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(CurrentFileName))
|
|
||||||
{
|
|
||||||
CurrentFileName = _defaultFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
_cheatList.Clear();
|
_cheatList.Clear();
|
||||||
CurrentFileName = "";
|
CurrentFileName = "";
|
||||||
Changes = false;
|
Changes = false;
|
||||||
|
@ -220,7 +210,7 @@ namespace BizHawk.Client.Common
|
||||||
public bool IsActive(MemoryDomain domain, long address)
|
public bool IsActive(MemoryDomain domain, long address)
|
||||||
=> _cheatList.Exists(cheat => !cheat.IsSeparator && cheat.Enabled && cheat.Domain == domain && cheat.Contains(address));
|
=> _cheatList.Exists(cheat => !cheat.IsSeparator && cheat.Enabled && cheat.Domain == domain && cheat.Contains(address));
|
||||||
|
|
||||||
public void SaveOnClose()
|
public FileWriteResult SaveOnClose()
|
||||||
{
|
{
|
||||||
if (_config.AutoSaveOnClose)
|
if (_config.AutoSaveOnClose)
|
||||||
{
|
{
|
||||||
|
@ -231,17 +221,27 @@ namespace BizHawk.Client.Common
|
||||||
CurrentFileName = _defaultFileName;
|
CurrentFileName = _defaultFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveFile(CurrentFileName);
|
return SaveFile(CurrentFileName);
|
||||||
}
|
}
|
||||||
else if (_cheatList.Count is 0 && !string.IsNullOrWhiteSpace(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);
|
_config.Recent.Remove(CurrentFileName);
|
||||||
|
return new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Save()
|
public FileWriteResult Save()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(CurrentFileName))
|
if (string.IsNullOrWhiteSpace(CurrentFileName))
|
||||||
{
|
{
|
||||||
|
@ -251,54 +251,51 @@ namespace BizHawk.Client.Common
|
||||||
return SaveFile(CurrentFileName);
|
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();
|
if (cheat.IsSeparator)
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
foreach (var cheat in _cheatList)
|
|
||||||
{
|
{
|
||||||
if (cheat.IsSeparator)
|
sb.AppendLine("----");
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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;
|
CurrentFileName = path;
|
||||||
_config.Recent.Add(CurrentFileName);
|
_config.Recent.Add(CurrentFileName);
|
||||||
Changes = false;
|
Changes = false;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Load(IMemoryDomains domains, string path, bool append)
|
public bool Load(IMemoryDomains domains, string path, bool append)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -338,39 +339,37 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Save()
|
public FileWriteResult Save()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(CurrentFileName))
|
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.AppendLine(watch.ToString());
|
||||||
sb.Append("SystemID ").AppendLine(_systemId);
|
|
||||||
|
|
||||||
foreach (var watch in _watchList)
|
|
||||||
{
|
|
||||||
sb.AppendLine(watch.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
sw.WriteLine(sb.ToString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Changes = false;
|
FileWriteResult result = FileWriter.Write(CurrentFileName, (fs) =>
|
||||||
return true;
|
{
|
||||||
|
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)
|
Debug.Assert(file != null, "Cannot save as without a file name.");
|
||||||
{
|
|
||||||
CurrentFileName = file.FullName;
|
|
||||||
return Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
CurrentFileName = file.FullName;
|
||||||
|
return Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadFile(string path, bool append)
|
private bool LoadFile(string path, bool append)
|
||||||
|
|
|
@ -3934,7 +3934,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
if (previousRom != CurrentlyOpenRom)
|
if (previousRom != CurrentlyOpenRom)
|
||||||
{
|
{
|
||||||
CheatList.NewList(Tools.GenerateDefaultCheatFilename(), autosave: true);
|
CheatList.NewList(Tools.GenerateDefaultCheatFilename());
|
||||||
if (Config.Cheats.LoadFileByGame && Emulator.HasMemoryDomains())
|
if (Config.Cheats.LoadFileByGame && Emulator.HasMemoryDomains())
|
||||||
{
|
{
|
||||||
if (CheatList.AttemptToLoadCheatFile(Emulator.AsMemoryDomains()))
|
if (CheatList.AttemptToLoadCheatFile(Emulator.AsMemoryDomains()))
|
||||||
|
@ -3951,7 +3951,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CheatList.NewList(Tools.GenerateDefaultCheatFilename(), autosave: true);
|
CheatList.NewList(Tools.GenerateDefaultCheatFilename());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3988,7 +3988,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
DisplayManager.UpdateGlobals(Config, Emulator);
|
DisplayManager.UpdateGlobals(Config, Emulator);
|
||||||
DisplayManager.Blank();
|
DisplayManager.Blank();
|
||||||
ExtToolManager.BuildToolStrip();
|
ExtToolManager.BuildToolStrip();
|
||||||
CheatList.NewList("", autosave: true);
|
CheatList.NewList("");
|
||||||
OnRomChanged();
|
OnRomChanged();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4050,25 +4050,30 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
CommitCoreSettingsToConfig(); // Must happen before stopping the movie, since it checks for active movie.
|
CommitCoreSettingsToConfig(); // Must happen before stopping the movie, since it checks for active movie.
|
||||||
|
|
||||||
|
GameIsClosing = true;
|
||||||
if (!Tools.AskSave())
|
if (!Tools.AskSave())
|
||||||
{
|
{
|
||||||
|
GameIsClosing = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// There is a cheats tool, but cheats can be active while the "cheats tool" is not. And have auto-save option.
|
// There is a cheats tool, but cheats can be active while the "cheats tool" is not. And have auto-save option.
|
||||||
CheatList.SaveOnClose();
|
TryAgainResult cheatSaveResult = this.DoWithTryAgainBox(CheatList.SaveOnClose, "Failed to save cheats.");
|
||||||
|
if (cheatSaveResult == TryAgainResult.Canceled)
|
||||||
GameIsClosing = true;
|
|
||||||
FileWriteResult saveResult = MovieSession.StopMovie();
|
|
||||||
GameIsClosing = false;
|
|
||||||
if (saveResult.IsError)
|
|
||||||
{
|
{
|
||||||
if (!this.ModalMessageBox2(
|
GameIsClosing = false;
|
||||||
caption: "Quit anyway?",
|
return false;
|
||||||
icon: EMsgBoxIcon.Question,
|
}
|
||||||
text: "The currently playing movie could not be saved. Continue and quit anyway? All unsaved changes will be lost."))
|
|
||||||
{
|
// If TAStudio is open, we already asked about saving the movie.
|
||||||
return false;
|
if (Tools.IsLoaded<TAStudio>())
|
||||||
}
|
{
|
||||||
|
GameIsClosing = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TryAgainResult saveMovieResult = this.DoWithTryAgainBox(() => MovieSession.StopMovie(), "Failed to save movie.");
|
||||||
|
GameIsClosing = false;
|
||||||
|
if (saveMovieResult == TryAgainResult.Canceled) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clearSram)
|
if (clearSram)
|
||||||
|
@ -4076,7 +4081,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
var path = Config.PathEntries.SaveRamAbsolutePath(Game, MovieSession.Movie);
|
var path = Config.PathEntries.SaveRamAbsolutePath(Game, MovieSession.Movie);
|
||||||
if (File.Exists(path))
|
if (File.Exists(path))
|
||||||
{
|
{
|
||||||
bool clearResult = this.DoWithTryAgainBox(() => {
|
TryAgainResult clearResult = this.DoWithTryAgainBox(() => {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.Delete(path);
|
File.Delete(path);
|
||||||
|
@ -4088,7 +4093,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
return new(FileWriteEnum.FailedToDeleteGeneric, new(path, ""), ex);
|
return new(FileWriteEnum.FailedToDeleteGeneric, new(path, ""), ex);
|
||||||
}
|
}
|
||||||
}, "Failed to clear SRAM.");
|
}, "Failed to clear SRAM.");
|
||||||
if (!clearResult)
|
if (clearResult == TryAgainResult.Canceled)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4096,14 +4101,14 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
else if (Emulator.HasSaveRam())
|
else if (Emulator.HasSaveRam())
|
||||||
{
|
{
|
||||||
bool flushResult = this.DoWithTryAgainBox(
|
TryAgainResult flushResult = this.DoWithTryAgainBox(
|
||||||
() => FlushSaveRAM(),
|
() => FlushSaveRAM(),
|
||||||
"Failed flushing the game's Save RAM to your disk.");
|
"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.");
|
TryAgainResult stateSaveResult = this.DoWithTryAgainBox(AutoSaveStateIfConfigured, "Failed to auto-save state.");
|
||||||
if (!stateSaveResult) return false;
|
if (stateSaveResult == TryAgainResult.Canceled) return false;
|
||||||
|
|
||||||
StopAv();
|
StopAv();
|
||||||
|
|
||||||
|
@ -4146,7 +4151,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
PauseOnFrame = null;
|
PauseOnFrame = null;
|
||||||
CurrentlyOpenRom = null;
|
CurrentlyOpenRom = null;
|
||||||
CurrentlyOpenRomArgs = null;
|
CurrentlyOpenRomArgs = null;
|
||||||
CheatList.NewList("", autosave: true);
|
CheatList.NewList("");
|
||||||
OnRomChanged();
|
OnRomChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,19 +214,23 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
if (_currentFilename != null)
|
if (_currentFilename != null)
|
||||||
{
|
{
|
||||||
RunSave();
|
bool saveResult2 = RunSave();
|
||||||
ShutdownCDL();
|
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.ShowMessageBox3("Save changes to CDL session?", "CDL Save", EMsgBoxIcon.Question);
|
||||||
var result = DialogController.ShowMessageBox2("Save changes to CDL session?", "CDL Auto Save", EMsgBoxIcon.Question);
|
if (result == false)
|
||||||
if (!result)
|
|
||||||
{
|
{
|
||||||
ShutdownCDL();
|
ShutdownCDL();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (result == null)
|
||||||
|
{
|
||||||
|
ShutdownCDL();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(_currentFilename))
|
if (string.IsNullOrWhiteSpace(_currentFilename))
|
||||||
{
|
{
|
||||||
|
@ -240,9 +244,9 @@ namespace BizHawk.Client.EmuHawk
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RunSave();
|
bool saveResult = RunSave();
|
||||||
ShutdownCDL();
|
ShutdownCDL();
|
||||||
return true;
|
return saveResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _autoloading;
|
private bool _autoloading;
|
||||||
|
@ -341,11 +345,20 @@ namespace BizHawk.Client.EmuHawk
|
||||||
LoadFile(file.FullName);
|
LoadFile(file.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RunSave()
|
/// <summary>
|
||||||
|
/// returns false if the operation was canceled
|
||||||
|
/// </summary>
|
||||||
|
private bool RunSave()
|
||||||
{
|
{
|
||||||
_recent.Add(_currentFilename);
|
TryAgainResult result = this.DoWithTryAgainBox(
|
||||||
using var fs = new FileStream(_currentFilename, FileMode.Create, FileAccess.Write);
|
() => FileWriter.Write(_currentFilename, _cdl.Save),
|
||||||
_cdl.Save(fs);
|
"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)
|
private void SaveMenuItem_Click(object sender, EventArgs e)
|
||||||
|
@ -386,8 +399,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SetCurrentFilename(file.FullName);
|
SetCurrentFilename(file.FullName);
|
||||||
RunSave();
|
return RunSave();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveAsMenuItem_Click(object sender, EventArgs e)
|
private void SaveAsMenuItem_Click(object sender, EventArgs e)
|
||||||
|
|
|
@ -142,7 +142,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SaveAs()
|
private FileWriteResult SaveAs()
|
||||||
{
|
{
|
||||||
var fileName = MainForm.CheatList.CurrentFileName;
|
var fileName = MainForm.CheatList.CurrentFileName;
|
||||||
if (string.IsNullOrWhiteSpace(fileName))
|
if (string.IsNullOrWhiteSpace(fileName))
|
||||||
|
@ -156,7 +156,8 @@ namespace BizHawk.Client.EmuHawk
|
||||||
CheatsFSFilterSet,
|
CheatsFSFilterSet,
|
||||||
this);
|
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)
|
private void Cheats_Load(object sender, EventArgs e)
|
||||||
|
@ -361,7 +362,12 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
if (MainForm.CheatList.Changes)
|
if (MainForm.CheatList.Changes)
|
||||||
{
|
{
|
||||||
if (MainForm.CheatList.Save())
|
FileWriteResult result = MainForm.CheatList.Save();
|
||||||
|
if (result.IsError)
|
||||||
|
{
|
||||||
|
this.ErrorMessageBox(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
UpdateMessageLabel(saved: true);
|
UpdateMessageLabel(saved: true);
|
||||||
}
|
}
|
||||||
|
@ -374,7 +380,12 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private void SaveAsMenuItem_Click(object sender, EventArgs e)
|
private void SaveAsMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (SaveAs())
|
FileWriteResult result = SaveAs();
|
||||||
|
if (result.IsError)
|
||||||
|
{
|
||||||
|
this.ErrorMessageBox(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
UpdateMessageLabel(saved: true);
|
UpdateMessageLabel(saved: true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -681,15 +681,25 @@ namespace BizHawk.Client.EmuHawk
|
||||||
return result is not null ? new FileInfo(result) : null;
|
return result is not null ? new FileInfo(result) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveSessionAs()
|
private FileWriteResult SaveSessionAs()
|
||||||
{
|
{
|
||||||
var file = GetSaveFileFromUser();
|
var file = GetSaveFileFromUser();
|
||||||
if (file != null)
|
if (file != null)
|
||||||
{
|
{
|
||||||
LuaImp.ScriptList.Save(file.FullName);
|
FileWriteResult saveResult = LuaImp.ScriptList.Save(file.FullName);
|
||||||
Config.RecentLuaSession.Add(file.FullName);
|
if (saveResult.IsError)
|
||||||
OutputMessages.Text = $"{file.Name} saved.";
|
{
|
||||||
|
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)
|
private void LoadSessionFromRecent(string path)
|
||||||
|
@ -717,7 +727,11 @@ namespace BizHawk.Client.EmuHawk
|
||||||
icon: EMsgBoxIcon.Question,
|
icon: EMsgBoxIcon.Question,
|
||||||
text: $"Save {WindowTitleStatic} session?"));
|
text: $"Save {WindowTitleStatic} session?"));
|
||||||
if (result is null) return false;
|
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;
|
else LuaImp.ScriptList.Changes = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -732,16 +746,20 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveOrSaveAs()
|
private FileWriteResult SaveOrSaveAs()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(LuaImp.ScriptList.Filename))
|
if (!string.IsNullOrWhiteSpace(LuaImp.ScriptList.Filename))
|
||||||
{
|
{
|
||||||
LuaImp.ScriptList.Save(LuaImp.ScriptList.Filename);
|
FileWriteResult result = LuaImp.ScriptList.Save(LuaImp.ScriptList.Filename);
|
||||||
Config.RecentLuaSession.Add(LuaImp.ScriptList.Filename);
|
if (!result.IsError)
|
||||||
|
{
|
||||||
|
Config.RecentLuaSession.Add(LuaImp.ScriptList.Filename);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SaveSessionAs();
|
return SaveSessionAs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -784,8 +802,16 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
if (LuaImp.ScriptList.Changes)
|
if (LuaImp.ScriptList.Changes)
|
||||||
{
|
{
|
||||||
SaveOrSaveAs();
|
FileWriteResult result = SaveOrSaveAs();
|
||||||
OutputMessages.Text = $"{Path.GetFileName(LuaImp.ScriptList.Filename)} saved.";
|
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.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Intentionally not updating this to use FileWriter because this tool is going to be removed later.
|
||||||
foreach (var zone in _unsavedZones)
|
foreach (var zone in _unsavedZones)
|
||||||
{
|
{
|
||||||
SaveMacroAs(_zones[zone]);
|
SaveMacroAs(_zones[zone]);
|
||||||
|
|
|
@ -161,15 +161,8 @@ namespace BizHawk.Client.EmuHawk
|
||||||
text: $"Save {WindowTitleStatic} project?"));
|
text: $"Save {WindowTitleStatic} project?"));
|
||||||
if (shouldSaveResult == true)
|
if (shouldSaveResult == true)
|
||||||
{
|
{
|
||||||
FileWriteResult saveResult = SaveTas();
|
TryAgainResult saveResult = this.DoWithTryAgainBox(() => SaveTas(), "Failed to save movie.");
|
||||||
while (saveResult.IsError && shouldSaveResult != true)
|
return saveResult != TryAgainResult.Canceled;
|
||||||
{
|
|
||||||
shouldSaveResult = this.ModalMessageBox3(
|
|
||||||
$"Failed to save movie. {saveResult.UserFriendlyErrorMessage()}\n{saveResult.Exception.Message}\n\nTry again?",
|
|
||||||
"Error",
|
|
||||||
EMsgBoxIcon.Error);
|
|
||||||
if (shouldSaveResult == true) saveResult = SaveTas();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (shouldSaveResult is null) return false;
|
if (shouldSaveResult is null) return false;
|
||||||
else CurrentTasMovie.ClearChanges();
|
else CurrentTasMovie.ClearChanges();
|
||||||
|
|
|
@ -1008,7 +1008,13 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(watches.CurrentFileName))
|
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;
|
_currentFileName = watches.CurrentFileName;
|
||||||
MessageLabel.Text = $"{Path.GetFileName(_currentFileName)} saved";
|
MessageLabel.Text = $"{Path.GetFileName(_currentFileName)} saved";
|
||||||
|
@ -1017,11 +1023,20 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var result = watches.SaveAs(GetWatchSaveFileFromUser(CurrentFileName()));
|
FileInfo/*?*/ file = GetWatchSaveFileFromUser(CurrentFileName());
|
||||||
if (result)
|
if (file != null)
|
||||||
{
|
{
|
||||||
MessageLabel.Text = $"{Path.GetFileName(_currentFileName)} saved";
|
var result = watches.SaveAs(file);
|
||||||
Settings.RecentSearches.Add(watches.CurrentFileName);
|
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]);
|
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;
|
_currentFileName = watches.CurrentFileName;
|
||||||
MessageLabel.Text = $"{Path.GetFileName(_currentFileName)} saved";
|
MessageLabel.Text = $"{Path.GetFileName(_currentFileName)} saved";
|
||||||
|
|
|
@ -213,15 +213,8 @@ namespace BizHawk.Client.EmuHawk
|
||||||
if (result is null) return false;
|
if (result is null) return false;
|
||||||
if (result.Value)
|
if (result.Value)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(_watches.CurrentFileName))
|
TryAgainResult saveResult = this.DoWithTryAgainBox(Save, "Failed to save watch list.");
|
||||||
{
|
return saveResult != TryAgainResult.Canceled;
|
||||||
SaveAs();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_watches.Save();
|
|
||||||
Config.RecentWatches.Add(_watches.CurrentFileName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -591,14 +584,47 @@ namespace BizHawk.Client.EmuHawk
|
||||||
: Game.FilesystemSafeName();
|
: Game.FilesystemSafeName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveAs()
|
private FileWriteResult SaveAs()
|
||||||
{
|
{
|
||||||
var result = _watches.SaveAs(GetWatchSaveFileFromUser(CurrentFileName()));
|
FileInfo/*?*/ file = GetWatchSaveFileFromUser(CurrentFileName());
|
||||||
if (result)
|
if (file == null) return new();
|
||||||
|
|
||||||
|
FileWriteResult result = _watches.SaveAs(file);
|
||||||
|
if (result.IsError)
|
||||||
{
|
{
|
||||||
UpdateStatusBar(saved: true);
|
MessageLabel.Text = $"Failed to save {Path.GetFileName(_watches.CurrentFileName)}";
|
||||||
Config.RecentWatches.Add(_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()
|
private void SaveConfigSettings()
|
||||||
|
@ -727,23 +753,20 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private void SaveMenuItem_Click(object sender, EventArgs e)
|
private void SaveMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(_watches.CurrentFileName))
|
FileWriteResult saveResult = Save();
|
||||||
|
if (saveResult.IsError)
|
||||||
{
|
{
|
||||||
if (_watches.Save())
|
this.ErrorMessageBox(saveResult, "Failed to save watch list.");
|
||||||
{
|
|
||||||
Config.RecentWatches.Add(_watches.CurrentFileName);
|
|
||||||
UpdateStatusBar(saved: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SaveAs();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveAsMenuItem_Click(object sender, EventArgs e)
|
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)
|
private void RecentSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||||
|
|
Loading…
Reference in New Issue