Added a copy button to modal window for easier bug fixing
This commit is contained in:
parent
589495911d
commit
d1aae545e9
@ -186,13 +186,40 @@ public partial class LeftTreeView : UserControl
|
|||||||
// Compose content
|
// Compose content
|
||||||
if (dialog.Content is Grid grid)
|
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,
|
Text = text,
|
||||||
|
IsReadOnly = true,
|
||||||
|
AcceptsReturn = true,
|
||||||
TextWrapping = Avalonia.Media.TextWrapping.Wrap,
|
TextWrapping = Avalonia.Media.TextWrapping.Wrap,
|
||||||
Margin = new Thickness(12)
|
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
|
var closeButton = new Button
|
||||||
{
|
{
|
||||||
@ -208,6 +235,7 @@ public partial class LeftTreeView : UserControl
|
|||||||
Orientation = Orientation.Horizontal,
|
Orientation = Orientation.Horizontal,
|
||||||
HorizontalAlignment = HorizontalAlignment.Right
|
HorizontalAlignment = HorizontalAlignment.Right
|
||||||
};
|
};
|
||||||
|
buttonsPanel.Children.Add(copyButton);
|
||||||
buttonsPanel.Children.Add(closeButton);
|
buttonsPanel.Children.Add(closeButton);
|
||||||
|
|
||||||
Grid.SetRow(buttonsPanel, 1);
|
Grid.SetRow(buttonsPanel, 1);
|
||||||
|
|||||||
@ -18,15 +18,7 @@ public static class XmlValidator
|
|||||||
{
|
{
|
||||||
var result = new XmlValidationResult();
|
var result = new XmlValidationResult();
|
||||||
|
|
||||||
// Ensure the requested element exists in the schema set
|
// Probe XML root element first, we may use its namespace as a hint
|
||||||
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
|
|
||||||
(string localName, string nsUri)? rootInfo = TryReadRoot(xmlPath);
|
(string localName, string nsUri)? rootInfo = TryReadRoot(xmlPath);
|
||||||
if (rootInfo is null)
|
if (rootInfo is null)
|
||||||
{
|
{
|
||||||
@ -35,6 +27,42 @@ public static class XmlValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (rootLocal, rootNs) = rootInfo.Value;
|
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 matchesRoot = string.Equals(rootLocal, elementName, StringComparison.Ordinal) && string.Equals(rootNs ?? string.Empty, elementNamespace ?? string.Empty, StringComparison.Ordinal);
|
||||||
|
|
||||||
var settings = new XmlReaderSettings
|
var settings = new XmlReaderSettings
|
||||||
@ -99,8 +127,18 @@ public static class XmlValidator
|
|||||||
|
|
||||||
if (elementNode is null)
|
if (elementNode is null)
|
||||||
{
|
{
|
||||||
result.AddError($"Could not find any element '{{{elementNamespace}}}{elementName}' in the XML document to validate against.");
|
// Try again ignoring namespace, in case the provided namespace was incorrect or omitted
|
||||||
return result;
|
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
|
// Inform as a warning that we validate a subtree instead of the document root
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user