Files
HSUI/Config/ImportConfig.cs
T

296 lines
9.1 KiB
C#

using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Config.Profiles;
using HSUI.Helpers;
using Dalamud.Bindings.ImGui;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Reflection;
using System.Text.RegularExpressions;
namespace HSUI.Interface
{
[Disableable(false)]
[Exportable(false)]
[Shareable(false)]
[Resettable(false)]
[Section("Import")]
[SubSection("General", 0)]
public class ImportConfig : PluginConfigObject
{
private string _importString = "";
private bool _importing = false;
private string? _errorMessage = null;
private List<ImportData>? _importDataList = null;
private List<bool>? _importDataEnabled = null;
public new static ImportConfig DefaultConfig() { return new ImportConfig(); }
[ManualDraw]
public bool Draw(ref bool changed)
{
ImGui.Text("Import string:");
ImGui.InputText("", ref _importString, 999999);
ImGui.Text("Here you can import specific parts of a profile.\nIf the string contains more than one part you will be able to select which parts you wish to import.");
if (ImGui.Button("Import", new Vector2(560, 24)))
{
_importing = _importString.Length > 0;
}
ImGuiHelper.DrawSeparator(1, 1);
// error modal
if (_errorMessage != null)
{
if (ImGuiHelper.DrawErrorModal(_errorMessage))
{
_importing = false;
_errorMessage = null;
}
return false;
}
// parse import string
if (_importing && _importDataList == null)
{
_errorMessage = Parse();
}
// confirmation modal
if (_importDataList != null && _importDataList.Count > 0)
{
var (didConfirm, didClose) = DrawImportConfirmationModal();
if (didConfirm)
{
_errorMessage = Import();
if (_errorMessage == null)
{
_importString = "";
}
}
if (didConfirm || didClose)
{
_importing = false;
_importDataList = null;
_importDataEnabled = null;
changed = true;
}
return didConfirm && _errorMessage == null;
}
return false;
}
private string? Import()
{
if (_importDataList == null || _importDataEnabled == null)
{
return null;
}
List<PluginConfigObject> configObjects = new List<PluginConfigObject>(_importDataList.Count);
for (int i = 0; i < _importDataList.Count; i++)
{
if (i >= _importDataEnabled.Count || _importDataEnabled[i] == false)
{
continue;
}
ImportData importData = _importDataList[i];
PluginConfigObject? config = importData.GetObject();
if (config == null)
{
return "Couldn't import \"" + importData.Name + "\"";
}
configObjects.Add(config);
}
foreach (PluginConfigObject config in configObjects)
{
ConfigurationManager.Instance.SetConfigObject(config);
}
return null;
}
private string? Parse()
{
string[] importStrings = _importString.Trim().Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
if (importStrings.Length == 0)
{
return null;
}
_importDataList = new List<ImportData>(importStrings.Length);
_importDataEnabled = new List<bool>(importStrings.Length);
foreach (var str in importStrings)
{
try
{
ImportData importData = new ImportData(str);
_importDataList.Add(importData);
_importDataEnabled.Add(true);
}
catch (Exception e)
{
_importDataList = null;
_importDataEnabled = null;
return e is ArgumentException ? e.Message : "Invalid import string!";
}
}
return null;
}
public (bool, bool) DrawImportConfirmationModal()
{
if (_importDataList == null || _importDataEnabled == null)
{
return (false, true);
}
ConfigurationManager.Instance.ShowingModalWindow = true;
bool didConfirm = false;
bool didClose = false;
ImGui.OpenPopup("Import ##HSUI");
Vector2 center = ImGui.GetMainViewport().GetCenter();
ImGui.SetNextWindowPos(center, ImGuiCond.Appearing, new Vector2(0.5f, 0.5f));
bool p_open = true; // i've no idea what this is used for
if (ImGui.BeginPopupModal("Import ##HSUI", ref p_open, ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoMove))
{
float width = 300;
ImGui.Text("Select which parts to import:");
ImGui.NewLine();
if (ImGui.Button("Select All", new Vector2(width / 2f - 5, 24)))
{
for (int i = 0; i < _importDataEnabled.Count; i++)
{
_importDataEnabled[i] = true;
}
}
ImGui.SameLine();
if (ImGui.Button("Deselect All", new Vector2(width / 2f - 5, 24)))
{
for (int i = 0; i < _importDataEnabled.Count; i++)
{
_importDataEnabled[i] = false;
}
}
ImGui.NewLine();
float height = Math.Min(30 * _importDataList.Count, 400);
ImGui.BeginChild("import checkboxes", new Vector2(width, height), false);
for (int i = 0; i < _importDataList.Count; i++)
{
bool value = _importDataEnabled[i];
if (ImGui.Checkbox(_importDataList[i].Name, ref value))
{
_importDataEnabled[i] = value;
}
}
ImGui.EndChild();
ImGui.NewLine();
if (ImGui.Button("OK", new Vector2(width / 2f - 5, 24)))
{
ImGui.CloseCurrentPopup();
didConfirm = true;
didClose = true;
}
ImGui.SetItemDefaultFocus();
ImGui.SameLine();
if (ImGui.Button("Cancel", new Vector2(width / 2f - 5, 24)))
{
ImGui.CloseCurrentPopup();
didClose = true;
}
ImGui.EndPopup();
}
// close button on nav
else
{
didClose = true;
}
if (didClose)
{
ConfigurationManager.Instance.ShowingModalWindow = false;
}
return (didConfirm, didClose);
}
}
public class ImportData
{
public readonly Type ConfigType;
public readonly string Name;
public readonly string ImportString;
public readonly string JsonString;
public ImportData(string base64String)
{
ImportString = base64String;
JsonString = ImportExportHelper.Base64DecodeAndDecompress(base64String);
string? typeString = (string?)JObject.Parse(JsonString)["$type"];
if (typeString == null)
{
throw new ArgumentException("Invalid type");
}
// Migrate DelvUI type names to HSUI for profile/import compatibility
if (typeString.Contains("DelvUI"))
{
typeString = typeString.Replace("DelvUI.", "HSUI.").Replace(", DelvUI", ", HSUI");
}
Type? type = Type.GetType(typeString);
if (type == null)
{
throw new ArgumentException("Invalid type: \"" + typeString + "\"");
}
ConfigType = type;
Name = Utils.UserFriendlyConfigName(type.Name);
}
public PluginConfigObject? GetObject()
{
MethodInfo? methodInfo = typeof(PluginConfigObject).GetMethod("LoadFromJsonString", BindingFlags.Public | BindingFlags.Static);
MethodInfo? function = methodInfo?.MakeGenericMethod(ConfigType);
return (PluginConfigObject?)function?.Invoke(this, new object[] { JsonString })!;
}
}
}