Added a copy button to modal window for easier bug fixing

This commit is contained in:
Frederik Jacobsen 2025-10-18 23:14:52 +02:00
parent 589495911d
commit d1aae545e9
2 changed files with 79 additions and 13 deletions

View File

@ -186,13 +186,40 @@ public partial class LeftTreeView : UserControl
// Compose content
if (dialog.Content is Grid grid)
{
var textBlock = new TextBlock
// Use a read-only TextBox so users can select text easily
var textBox = new TextBox
{
Text = text,
IsReadOnly = true,
AcceptsReturn = true,
TextWrapping = Avalonia.Media.TextWrapping.Wrap,
Margin = new Thickness(12)
};
var scroller = new ScrollViewer { Content = textBlock };
var scroller = new ScrollViewer { Content = textBox };
// Copy button
var copyButton = new Button
{
Content = "Copy",
MinWidth = 80,
HorizontalAlignment = HorizontalAlignment.Right,
Margin = new Thickness(8)
};
copyButton.Click += async (_, _) =>
{
var topLevel = TopLevel.GetTopLevel(this);
if (topLevel?.Clipboard != null)
{
await topLevel.Clipboard.SetTextAsync(text);
// Provide lightweight feedback by changing content briefly
if (copyButton.Content is string)
copyButton.Content = "Copied";
await Task.Delay(1000);
if (copyButton.Content is string)
copyButton.Content = "Copy";
}
};
var closeButton = new Button
{
@ -208,6 +235,7 @@ public partial class LeftTreeView : UserControl
Orientation = Orientation.Horizontal,
HorizontalAlignment = HorizontalAlignment.Right
};
buttonsPanel.Children.Add(copyButton);
buttonsPanel.Children.Add(closeButton);
Grid.SetRow(buttonsPanel, 1);

View File

@ -18,15 +18,7 @@ public static class XmlValidator
{
var result = new XmlValidationResult();
// Ensure the requested element exists in the schema set
var qname = new XmlQualifiedName(elementName, elementNamespace ?? string.Empty);
if (schemas.GlobalElements[qname] is not XmlSchemaElement)
{
result.AddError($"Element '{qname}' was not found in the compiled schema set.");
return result;
}
// Probe XML root element
// Probe XML root element first, we may use its namespace as a hint
(string localName, string nsUri)? rootInfo = TryReadRoot(xmlPath);
if (rootInfo is null)
{
@ -35,6 +27,42 @@ public static class XmlValidator
}
var (rootLocal, rootNs) = rootInfo.Value;
// Try to ensure the requested element exists in the schema set; if not, try to infer the correct namespace instead of failing hard.
var qname = new XmlQualifiedName(elementName, elementNamespace ?? string.Empty);
if (schemas.GlobalElements[qname] is not XmlSchemaElement)
{
// Try to find candidates with the same local name across namespaces
var candidates = schemas.GlobalElements.Names.Cast<XmlQualifiedName>().Where(n => string.Equals(n.Name, elementName, StringComparison.Ordinal)).Distinct().ToList();
if (candidates.Count == 1)
{
elementNamespace = candidates[0].Namespace;
qname = new XmlQualifiedName(elementName, elementNamespace ?? string.Empty);
result.AddWarning($"Element '{{{qname.Namespace}}}{qname.Name}' was not found with the provided namespace. Using detected namespace '{candidates[0].Namespace}'.");
}
else if (candidates.Count > 1)
{
// Prefer a candidate matching the XML root namespace if any
var preferred = candidates.FirstOrDefault(c => string.Equals(c.Namespace ?? string.Empty, rootNs ?? string.Empty, StringComparison.Ordinal));
if (preferred != null)
{
elementNamespace = preferred.Namespace;
qname = new XmlQualifiedName(elementName, elementNamespace ?? string.Empty);
result.AddWarning($"Element namespace adjusted to match XML root namespace: '{{{preferred.Namespace}}}{preferred.Name}'.");
}
else
{
var list = string.Join(", ", candidates.Select(c => $"'{{{c.Namespace}}}{c.Name}'"));
result.AddWarning($"Element '{{{qname.Namespace}}}{qname.Name}' was not found in the compiled schema set. Candidates by name: {list}. Proceeding with best-effort validation.");
}
}
else
{
// No candidates at all; continue and let the validator report more actionable errors.
result.AddWarning($"Element '{{{qname.Namespace}}}{qname.Name}' was not found in the compiled schema set. Proceeding with best-effort validation.");
}
}
var matchesRoot = string.Equals(rootLocal, elementName, StringComparison.Ordinal) && string.Equals(rootNs ?? string.Empty, elementNamespace ?? string.Empty, StringComparison.Ordinal);
var settings = new XmlReaderSettings
@ -99,8 +127,18 @@ public static class XmlValidator
if (elementNode is null)
{
result.AddError($"Could not find any element '{{{elementNamespace}}}{elementName}' in the XML document to validate against.");
return result;
// Try again ignoring namespace, in case the provided namespace was incorrect or omitted
var retry = FindFirstElementNode(xmlPath, elementName, null).Node;
if (retry is not null)
{
result.AddWarning($"Could not find element '{{{elementNamespace}}}{elementName}' with the specified namespace; validating first occurrence by local name only.");
elementNode = retry;
}
else
{
result.AddError($"Could not find any element '{{{elementNamespace}}}{elementName}' in the XML document to validate against.");
return result;
}
}
// Inform as a warning that we validate a subtree instead of the document root