diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Donut9a.Designer.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Donut9a.Designer.cs index 016e60b53..687dfff7e 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Donut9a.Designer.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Donut9a.Designer.cs @@ -39,6 +39,8 @@ private void InitializeComponent() B_ModifyAll = new System.Windows.Forms.Button(); B_Reset = new System.Windows.Forms.Button(); donutEditor = new DonutEditor9a(); + B_Import = new System.Windows.Forms.Button(); + B_Export = new System.Windows.Forms.Button(); modifyMenu.SuspendLayout(); SuspendLayout(); // @@ -120,7 +122,7 @@ private void InitializeComponent() // B_Reset // B_Reset.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left; - B_Reset.Location = new System.Drawing.Point(208, 304); + B_Reset.Location = new System.Drawing.Point(548, 304); B_Reset.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); B_Reset.Name = "B_Reset"; B_Reset.Size = new System.Drawing.Size(128, 27); @@ -139,10 +141,36 @@ private void InitializeComponent() donutEditor.Size = new System.Drawing.Size(672, 283); donutEditor.TabIndex = 27; // + // B_Import + // + B_Import.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left; + B_Import.Location = new System.Drawing.Point(208, 304); + B_Import.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + B_Import.Name = "B_Import"; + B_Import.Size = new System.Drawing.Size(128, 27); + B_Import.TabIndex = 28; + B_Import.Text = "Import"; + B_Import.UseVisualStyleBackColor = true; + B_Import.Click += B_ImportClick; + // + // B_Export + // + B_Export.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left; + B_Export.Location = new System.Drawing.Point(344, 304); + B_Export.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + B_Export.Name = "B_Export"; + B_Export.Size = new System.Drawing.Size(128, 27); + B_Export.TabIndex = 29; + B_Export.Text = "Export"; + B_Export.UseVisualStyleBackColor = true; + B_Export.Click += B_Export_Click; + // // SAV_Donut9a // AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit; ClientSize = new System.Drawing.Size(894, 388); + Controls.Add(B_Export); + Controls.Add(B_Import); Controls.Add(donutEditor); Controls.Add(B_Reset); Controls.Add(B_ModifyAll); @@ -173,5 +201,7 @@ private void InitializeComponent() private System.Windows.Forms.Button B_ModifyAll; private System.Windows.Forms.Button B_Reset; private DonutEditor9a donutEditor; + private System.Windows.Forms.Button B_Import; + private System.Windows.Forms.Button B_Export; } } diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Donut9a.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Donut9a.cs index 99622716d..e746c5a6f 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Donut9a.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Donut9a.cs @@ -1,5 +1,6 @@ using System; using System.Drawing; +using System.Text; using System.Windows.Forms; using PKHeX.Core; @@ -151,4 +152,88 @@ private void ShinyAssortment(object sender, EventArgs e) } private void B_Reset_Click(object sender, EventArgs e) => donutEditor.Reset(); + + private void B_ImportClick(object sender, EventArgs e) + { + var current = Donuts.GetDonut(lastIndex); + var data = current.Data; + + if (!TryLoadDonut(data)) + return; + + donutEditor.LoadDonut(current); + System.Media.SystemSounds.Asterisk.Play(); + } + + private static bool TryLoadDonut(Span data) + { + if (ModifierKeys == Keys.Control) + return TryLoadDonutClipboard(data); + return TryLoadDonutOpenFile(data); + } + + private static bool TryLoadDonutClipboard(Span data) + { + // Import from clipboard as hex string + try + { + var hex = Clipboard.GetText().Trim(); + Util.GetBytesFromHexString(hex.Replace(" ", ""), data); + } + catch (Exception ex) + { + WinFormsUtil.Error($"Failed to import donut from clipboard:\n{ex.Message}"); + return false; + } + return true; + } + + private static bool TryLoadDonutOpenFile(Span data) + { + using var ofd = new OpenFileDialog(); + ofd.Title = "Import Donut"; + ofd.Filter = "Donut File (*.donut)|*.donut|All Files (*.*)|*.*"; + if (ofd.ShowDialog() != DialogResult.OK) + return false; + + try + { + var fileData = System.IO.File.ReadAllBytes(ofd.FileName); + if (fileData.Length != data.Length) + throw new Exception($"Invalid donut size: expected {data.Length} bytes, got {fileData.Length} bytes."); + fileData.AsSpan().CopyTo(data); + } + catch (Exception ex) + { + WinFormsUtil.Error($"Failed to import donut from file:\n{ex.Message}"); + return false; + } + return true; + } + + private void B_Export_Click(object sender, EventArgs e) + { + SetEntry(lastIndex); + var current = Donuts.GetDonut(lastIndex); + var data = current.Data; + + if (ModifierKeys == Keys.Control) + { + // Copy to clipboard as hex string + var sb = new StringBuilder(data.Length * 3); + foreach (var b in data) + sb.Append($"{b:X2} "); + Clipboard.SetText(sb.ToString().TrimEnd()); + System.Media.SystemSounds.Asterisk.Play(); + return; + } + + using var sfd = new SaveFileDialog(); + sfd.Title = "Export Donut"; + sfd.Filter = "Donut File (*.donut)|*.donut|All Files (*.*)|*.*"; + sfd.FileName = $"donut_{lastIndex + 1:000}.donut"; + if (sfd.ShowDialog() != DialogResult.OK) + return; + System.IO.File.WriteAllBytes(sfd.FileName, data); + } }