Skip to content

Commit 616330b

Browse files
committed
Add clipboard functionality and notification for copying element state
1 parent 7b81223 commit 616330b

File tree

3 files changed

+102
-23
lines changed

3 files changed

+102
-23
lines changed

src/FlaUInspect/ViewModels/MainViewModel.cs

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public class MainViewModel : ObservableObject {
2828
private AutomationBase? _automation;
2929
private RelayCommand? _captureSelectedItemCommand;
3030
private RelayCommand? _closeInfoCommand;
31+
private RelayCommand? _copyDetailsToClipboardCommand;
32+
private RelayCommand? _currentElementSaveStateCommand;
3133
private ObservableCollection<ElementPatternItem>? _elementPatterns = [];
3234
private FocusTrackingMode? _focusTrackingMode;
3335
private HoverMode? _hoverMode;
@@ -39,7 +41,6 @@ public class MainViewModel : ObservableObject {
3941
private AutomationElement? _rootElement;
4042
private RelayCommand? _startNewInstanceCommand;
4143
private ITreeWalker? _treeWalker;
42-
private RelayCommand? _currentElementSaveStateCommand;
4344

4445
public MainViewModel(AutomationType automationType, string applicationVersion, InternalLogger logger) {
4546
_logger = logger;
@@ -182,14 +183,41 @@ public string? ApplicationVersion {
182183
public ICommand CloseInfoCommand => _closeInfoCommand ??= new RelayCommand(_ => {
183184
IsInfoVisible = false;
184185
});
185-
186-
public event Action? CopiedNotificationRequested;
187186

188187
public ICommand CurrentElementSaveStateCommand => _currentElementSaveStateCommand ??= new RelayCommand(_ => {
189188
if (SelectedItem?.AutomationElement == null) {
190189
return;
191190
}
192191

192+
try {
193+
XDocument document = new ();
194+
document.Add(new XElement("Root"));
195+
ExportElement(document.Root!, SelectedItem);
196+
197+
Clipboard.SetText(document.ToString());
198+
CopiedNotificationCurrentElementSaveStateRequested?.Invoke();
199+
} catch (Exception e) {
200+
_logger?.LogError(e.ToString());
201+
}
202+
});
203+
204+
public ICommand CollapseAllDetailsCommand => new RelayCommand(_ => {
205+
foreach (ElementPatternItem pattern in ElementPatterns) {
206+
pattern.IsExpanded = false;
207+
}
208+
});
209+
210+
public ICommand ExpandAllDetailsCommand => new RelayCommand(_ => {
211+
foreach (ElementPatternItem pattern in ElementPatterns) {
212+
pattern.IsExpanded = true;
213+
}
214+
});
215+
216+
public ICommand CopyDetailsToClipboardCommand => _copyDetailsToClipboardCommand ??= new RelayCommand(_ => {
217+
if (SelectedItem?.AutomationElement == null) {
218+
return;
219+
}
220+
193221
try {
194222
XDocument document = new ();
195223
document.Add(new XElement("Root"));
@@ -217,17 +245,49 @@ public string? ApplicationVersion {
217245
}
218246
});
219247

220-
public ICommand CollapseAllDetailsCommand => new RelayCommand(_ => {
221-
foreach (ElementPatternItem pattern in ElementPatterns) {
222-
pattern.IsExpanded = false;
248+
public event Action? CopiedNotificationRequested;
249+
public event Action? CopiedNotificationCurrentElementSaveStateRequested;
250+
251+
private void ExportElement(XElement parent, ElementViewModel element) {
252+
XElement xElement = CreateXElement(element);
253+
parent.Add(xElement);
254+
255+
try {
256+
foreach (ElementViewModel children in element.Children!) {
257+
try {
258+
xElement.Add(CreateXElement(children!));
259+
} catch {
260+
// ignored
261+
}
262+
}
263+
264+
foreach (ElementViewModel children in element.Children.Where(x => x is { IsExpanded: true }).Where(x => x != null)!) {
265+
try {
266+
ExportElement(xElement, children!);
267+
} catch {
268+
// ignored
269+
}
270+
}
271+
} catch {
272+
// ignored
223273
}
224-
});
274+
}
225275

226-
public ICommand ExpandAllDetailsCommand => new RelayCommand(_ => {
227-
foreach (ElementPatternItem pattern in ElementPatterns) {
228-
pattern.IsExpanded = true;
276+
private XElement CreateXElement(ElementViewModel element) {
277+
278+
List<XAttribute> attrs = [
279+
new ("Name", element.Name),
280+
new ("AutomationId", element.AutomationId),
281+
new ("ControlType", element.ControlType)
282+
];
283+
284+
if (EnableXPath) {
285+
attrs.Add(new XAttribute("XPath", element.XPath));
229286
}
230-
});
287+
288+
XElement xElement = new ("Element", attrs);
289+
return xElement;
290+
}
231291

232292
private void ReadPatternsForSelectedItem(AutomationElement? selectedItemAutomationElement) {
233293
if (SelectedItem?.AutomationElement == null || selectedItemAutomationElement == null) {

src/FlaUInspect/Views/MainWindow.xaml

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,27 @@
114114
HorizontalAlignment="Left"
115115
VerticalAlignment="Top"
116116
Orientation="Horizontal">
117-
<Button Command="{Binding CurrentElementSaveStateCommand}"
118-
Style="{StaticResource RibbonButtonStyle}"
119-
ToolTip="Get current element state">
120-
<StackPanel Orientation="Vertical">
121-
<Viewbox Width="20"
122-
Height="20"
123-
Stretch="Uniform">
124-
<ContentControl Content="{StaticResource TreeIcon}" />
125-
</Viewbox>
126-
</StackPanel>
127-
</Button>
117+
<Grid>
118+
<Button Command="{Binding CurrentElementSaveStateCommand}"
119+
Style="{StaticResource RibbonButtonStyle}"
120+
ToolTip="Get current element state">
121+
<StackPanel Orientation="Vertical">
122+
<Viewbox Width="20"
123+
Height="20"
124+
Stretch="Uniform">
125+
<ContentControl Content="{StaticResource TreeIcon}" />
126+
</Viewbox>
127+
</StackPanel>
128+
</Button>
129+
<Grid Background="DarkBlue"
130+
x:Name="CopiedNotificationCurrentElementSaveStateGrid"
131+
Visibility="Collapsed">
132+
<TextBlock Text="Copied."
133+
Foreground="White"
134+
HorizontalAlignment="Center"
135+
VerticalAlignment="Center" />
136+
</Grid>
137+
</Grid>
128138

129139
<Button Command="{Binding CaptureSelectedItemCommand}"
130140
Style="{StaticResource RibbonButtonStyle}"
@@ -339,7 +349,7 @@
339349
</Style>
340350
</StackPanel.Resources>
341351
<Grid>
342-
<Button Command="{Binding CurrentElementSaveStateCommand}"
352+
<Button Command="{Binding CopyDetailsToClipboardCommand}"
343353
Style="{StaticResource RibbonButtonStyle}"
344354
ToolTip="Copy current element state to clipboard">
345355
<StackPanel Orientation="Vertical">

src/FlaUInspect/Views/MainWindow.xaml.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,18 @@ private void MainWindow_Loaded(object sender, EventArgs e) {
1515
if (DataContext is MainViewModel mainViewModel) {
1616
mainViewModel.Initialize();
1717
mainViewModel.CopiedNotificationRequested += ShowCopiedNotification;
18+
mainViewModel.CopiedNotificationCurrentElementSaveStateRequested += ShowCopiedNotificationCurrentElementSaveStateRequested;
1819
}
1920
}
2021

22+
private async void ShowCopiedNotificationCurrentElementSaveStateRequested() {
23+
CopiedNotificationCurrentElementSaveStateGrid.Visibility = Visibility.Visible;
24+
var animation = new DoubleAnimation(1, 0, TimeSpan.FromSeconds(1));
25+
CopiedNotificationCurrentElementSaveStateGrid.BeginAnimation(UIElement.OpacityProperty, animation);
26+
await Task.Delay(1000);
27+
CopiedNotificationCurrentElementSaveStateGrid.Visibility = Visibility.Collapsed;
28+
}
29+
2130
private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) {
2231
if (DataContext is MainViewModel mainViewModel) {
2332
mainViewModel.SelectedItem = e.NewValue as ElementViewModel;

0 commit comments

Comments
 (0)