using System;
+using System.Buffers.Text;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
+using System.Text;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Components;
using Dalamud.Plugin;
+using Dalamud.Plugin.Services;
using ImGuiNET;
using LLib.ImGui;
using Questionable.Controller;
internal sealed class PriorityWindow : LWindow
{
+ private const string ClipboardPrefix = "qst:v1:";
+ private const char ClipboardSeparator = ';';
+
private readonly QuestController _questController;
private readonly QuestRegistry _questRegistry;
private readonly QuestFunctions _questFunctions;
private readonly QuestTooltipComponent _questTooltipComponent;
private readonly UiUtils _uiUtils;
+ private readonly IChatGui _chatGui;
private readonly IDalamudPluginInterface _pluginInterface;
private string _searchString = string.Empty;
private ElementId? _draggedItem;
public PriorityWindow(QuestController questController, QuestRegistry questRegistry, QuestFunctions questFunctions,
- QuestTooltipComponent questTooltipComponent, UiUtils uiUtils, IDalamudPluginInterface pluginInterface)
+ QuestTooltipComponent questTooltipComponent, UiUtils uiUtils, IChatGui chatGui,
+ IDalamudPluginInterface pluginInterface)
: base("Quest Priority###QuestionableQuestPriority")
{
_questController = questController;
_questFunctions = questFunctions;
_questTooltipComponent = questTooltipComponent;
_uiUtils = uiUtils;
+ _chatGui = chatGui;
_pluginInterface = pluginInterface;
Size = new Vector2(400, 400);
ImGui.Text("Quests to do first:");
DrawQuestFilter();
DrawQuestList();
+
+ List<ElementId> clipboardItems = ParseClipboardItems();
+ ImGui.BeginDisabled(clipboardItems.Count == 0);
+ if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Download, "Import from Clipboard"))
+ ImportFromClipboard(clipboardItems);
+ ImGui.EndDisabled();
+ ImGui.SameLine();
+ ImGui.BeginDisabled(_questController.ManualPriorityQuests.Count == 0);
+ if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Upload, "Export to Clibpoard"))
+ ExportToClipboard();
+ ImGui.EndDisabled();
+
ImGui.Spacing();
ImGui.Separator();
priorityQuests.Insert(indexToAdd, itemToAdd);
}
}
+
+ private List<ElementId> ParseClipboardItems()
+ {
+ List<ElementId> clipboardItems = new List<ElementId>();
+ try
+ {
+ string? clipboardText = GetClipboardText();
+ if (clipboardText != null && clipboardText.StartsWith(ClipboardPrefix, StringComparison.InvariantCulture))
+ {
+ clipboardText = clipboardText.Substring(ClipboardPrefix.Length);
+ string text = Encoding.UTF8.GetString(Convert.FromBase64String(clipboardText));
+ foreach (string part in text.Split(ClipboardSeparator))
+ {
+ ElementId elementId = ElementId.FromString(part);
+ clipboardItems.Add(elementId);
+ }
+ }
+ }
+ catch (Exception)
+ {
+ clipboardItems.Clear();
+ }
+
+ return clipboardItems;
+ }
+
+ private void ExportToClipboard()
+ {
+ string clipboardText = ClipboardPrefix + Convert.ToBase64String(Encoding.UTF8.GetBytes(
+ string.Join(ClipboardSeparator, _questController.ManualPriorityQuests.Select(x => x.Id.ToString()))));
+ ImGui.SetClipboardText(clipboardText);
+ _chatGui.Print("Copied quests to clipboard.", CommandHandler.MessageTag, CommandHandler.TagColor);
+ }
+
+ private void ImportFromClipboard(List<ElementId> clipboardItems)
+ {
+ foreach (ElementId elementId in clipboardItems)
+ {
+ if (_questRegistry.TryGetQuest(elementId, out Quest? quest) &&
+ !_questController.ManualPriorityQuests.Contains(quest))
+ _questController.ManualPriorityQuests.Add(quest);
+ }
+ }
+
+ /// <summary>
+ /// The default implementation for <see cref="ImGui.GetClipboardText"/> throws an NullReferenceException if the clipboard is empty, maybe also if it doesn't contain text.
+ /// </summary>
+ private unsafe string? GetClipboardText()
+ {
+ byte* ptr = ImGuiNative.igGetClipboardText();
+ if (ptr == null)
+ return null;
+
+ int byteCount = 0;
+ while (ptr[byteCount] != 0)
+ ++byteCount;
+ return Encoding.UTF8.GetString(ptr, byteCount);
+ }
}