Skip to content

Commit 1052c39

Browse files
committed
Code modernization and cleanup.
Refactored namespaces to align with `Microsoft.PowerShell` conventions, replacing `OutGridView.Cmdlet` and `OutGridView.Models`. Updated the module version to `0.9.0` to reflect significant changes. Improved code readability and maintainability by adding XML documentation, enforcing consistent naming conventions, and removing redundant code. Enhanced null safety with nullable annotations and null checks. Refactored key classes (`ConsoleGui`, `GridViewDataSource`, `GridViewDetails`, `GridViewHelpers`, `OutConsoleGridviewCmdletCommand`, `ShowObjectTreeCmdletCommand`, etc.) to simplify logic, improve error handling, and ensure modern C# practices. Updated `launchSettings.json` to rename the `SOT` profile to `SHOT` for consistency with the `Show-ObjectTree` cmdlet. Enhanced serialization logic in `Serializers.cs` and improved type handling in `TypeGetter.cs`. These changes improve the maintainability, safety, and usability of the module while aligning with modern development standards.
1 parent 5fd9efd commit 1052c39

18 files changed

+897
-641
lines changed

GraphicalTools.sln.DotSettings

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2-
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String></wpf:ResourceDictionary>
2+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PS/@EntryIndexedValue">PS</s:String>
3+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UI/@EntryIndexedValue">UI</s:String>
4+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
5+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
6+
<s:Boolean x:Key="/Default/UserDictionary/Words/=BUGBUG/@EntryIndexedValue">True</s:Boolean>
7+
<s:Boolean x:Key="/Default/UserDictionary/Words/=ocgv/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
using System.Linq;
88
using System.Reflection;
99
using System.Text.RegularExpressions;
10-
using OutGridView.Models;
10+
using Microsoft.PowerShell.OutGridView.Models;
1111
using Terminal.Gui.App;
1212
using Terminal.Gui.Drawing;
1313
using Terminal.Gui.Input;
1414
using Terminal.Gui.ViewBase;
1515
using Terminal.Gui.Views;
1616

17-
namespace OutGridView.Cmdlet;
17+
namespace Microsoft.PowerShell.ConsoleGuiTools;
1818

1919
internal sealed class ConsoleGui : IDisposable
2020
{
@@ -63,7 +63,7 @@ public HashSet<int> Start(ApplicationData applicationData)
6363
var win = CreateTopLevelWindow();
6464

6565
// Create the headers and calculate column widths based on the DataTable
66-
var gridHeaders = _applicationData.DataTable.DataColumns.Select(c => c.Label).ToList();
66+
var gridHeaders = _applicationData.DataTable?.DataColumns.Select(c => c.Label).ToList();
6767

6868
// Copy the input DataTable into our master ListView source list; upon exit any items
6969
// that are IsMarked are returned (if OutputMode is set)
@@ -74,14 +74,14 @@ public HashSet<int> Start(ApplicationData applicationData)
7474
// Add Filter UI
7575
AddFilter(win);
7676
// Add Header UI
77-
AddHeaders(win, gridHeaders);
77+
AddHeaders(win);
7878
}
7979

8080
// Add ListView
8181
AddListView(win);
8282

8383
// Status bar is where our key-bindings are handled
84-
AddStatusBar(win, !_applicationData.MinUI);
84+
AddStatusBar(win);
8585

8686
// We *always* apply a filter, even if the -Filter parameter is not set or Filtering is not
8787
// available. The ListView always shows a filtered version of _inputSource even if there is no
@@ -126,7 +126,7 @@ private GridViewDataSource LoadData()
126126
if (_applicationData == null)
127127
return new GridViewDataSource(items);
128128

129-
for (var i = 0; i < _applicationData.DataTable.Data.Count; i++)
129+
for (var i = 0; i < _applicationData.DataTable!.Data.Count; i++)
130130
{
131131
var dataTableRow = _applicationData.DataTable.Data[i];
132132
var valueList = new List<string>();
@@ -155,7 +155,7 @@ private void UpdateDisplayStrings(GridViewDataSource? source)
155155
foreach (var gvr in source.GridViewRowList)
156156
{
157157
var valueList = new List<string>();
158-
var dataTableRow = _applicationData!.DataTable.Data[gvr.OriginalIndex];
158+
var dataTableRow = _applicationData!.DataTable!.Data[gvr.OriginalIndex];
159159
foreach (var dataTableColumn in _applicationData.DataTable.DataColumns)
160160
{
161161
var dataValue = dataTableRow.Values[dataTableColumn.ToString()].DisplayValue;
@@ -238,7 +238,7 @@ private Window CreateTopLevelWindow()
238238
return win;
239239
}
240240

241-
private void AddStatusBar(Window win, bool visible)
241+
private void AddStatusBar(Window win)
242242
{
243243
var shortcuts = new List<Shortcut>();
244244
if (_applicationData!.OutputMode != OutputModeOption.None)
@@ -299,15 +299,16 @@ private void AddStatusBar(Window win, bool visible)
299299
win.Add(new StatusBar(shortcuts));
300300
}
301301

302-
private void CalculateColumnWidths(List<string> gridHeaders)
302+
private void CalculateColumnWidths(List<string>? gridHeaders)
303303
{
304+
if (gridHeaders == null) return;
304305
_gridViewDetails!.ListViewColumnWidths = new int[gridHeaders.Count];
305306
var listViewColumnWidths = _gridViewDetails.ListViewColumnWidths;
306307

307308
for (var i = 0; i < gridHeaders.Count; i++) listViewColumnWidths[i] = gridHeaders[i].Length;
308309

309310
// calculate the width of each column based on longest string in each column for each row
310-
foreach (var row in _applicationData!.DataTable.Data)
311+
foreach (var row in _applicationData!.DataTable!.Data)
311312
{
312313
var index = 0;
313314

@@ -370,19 +371,19 @@ private void AddFilter(Window win)
370371
Text = string.Empty,
371372
X = Pos.Right(_filterLabel) + 1,
372373
Y = Pos.Top(_filterLabel) + 1,
373-
Width = Dim.Fill() - _filterLabel.Text!.Length,
374+
Width = Dim.Fill() - _filterLabel.Text.Length,
374375
// This enables the height to go 0, and the view to disappear when there is no error
375376
Height = Dim.Auto(DimAutoStyle.Text),
376377
SchemeName = "Error"
377378
};
378379

379-
_filterField.TextChanged += (sender, e) =>
380+
_filterField.TextChanged += (_, _) =>
380381
{
381382
var filterText = _filterField.Text;
382383
try
383384
{
384385
_filterErrorView.Text = string.Empty;
385-
_applicationData!.Filter = filterText!;
386+
_applicationData!.Filter = filterText;
386387
ApplyFilter();
387388
}
388389
catch (Exception ex)
@@ -397,16 +398,10 @@ private void AddFilter(Window win)
397398
_filterField.CursorPosition = _filterField.Text.Length;
398399
}
399400

400-
private void AddHeaders(Window win, List<string> gridHeaders)
401+
private void AddHeaders(Window win)
401402
{
402-
_header = new Label
403-
{
404-
//Text = GridViewHelpers.GetPaddedString(gridHeaders, _gridViewDetails!.ListViewOffset, _gridViewDetails.ListViewColumnWidths),
405-
};
406-
if (_applicationData!.MinUI)
407-
_header.Y = 0;
408-
else
409-
_header.Y = Pos.Bottom(_filterErrorView!);
403+
_header = new Label();
404+
_header.Y = _applicationData!.MinUI ? 0 : Pos.Bottom(_filterErrorView!);
410405
win.Add(_header);
411406

412407
if (!_applicationData.MinUI)

src/Microsoft.PowerShell.ConsoleGuiTools/GridViewDataSource.cs

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,83 @@
55
using System.Collections;
66
using System.Collections.Generic;
77
using System.Collections.Specialized;
8-
using System.Text;
98
using Terminal.Gui.App;
10-
using Terminal.Gui.Drivers;
11-
using Terminal.Gui.Text;
129
using Terminal.Gui.Views;
1310

14-
namespace OutGridView.Cmdlet;
11+
namespace Microsoft.PowerShell.ConsoleGuiTools;
1512

16-
internal sealed class GridViewDataSource : IListDataSource, IDisposable
13+
/// <summary>
14+
/// Provides a data source implementation for the grid view that manages rows and supports marking and rendering.
15+
/// </summary>
16+
internal sealed class GridViewDataSource : IListDataSource
1717
{
18+
/// <summary>
19+
/// Gets or sets the list of rows displayed in the grid view.
20+
/// </summary>
1821
public List<GridViewRow> GridViewRowList { get; set; }
1922

23+
/// <summary>
24+
/// Gets the number of rows in the data source.
25+
/// </summary>
2026
public int Count => GridViewRowList.Count;
21-
27+
28+
/// <summary>
29+
/// Gets the number of rows in the data source.
30+
/// </summary>
2231
public int Length => GridViewRowList.Count;
23-
32+
33+
/// <summary>
34+
/// Gets or sets a value indicating whether to suspend raising the <see cref="CollectionChanged" /> event.
35+
/// </summary>
2436
public bool SuspendCollectionChangedEvent { get; set; }
25-
37+
38+
#pragma warning disable CS0067
39+
/// <summary>
40+
/// Occurs when the collection changes.
41+
/// </summary>
2642
public event NotifyCollectionChangedEventHandler? CollectionChanged;
43+
#pragma warning restore CS0067
2744

45+
/// <summary>
46+
/// Initializes a new instance of the <see cref="GridViewDataSource" /> class with the specified item list.
47+
/// </summary>
48+
/// <param name="itemList">The list of grid view rows to display.</param>
2849
public GridViewDataSource(List<GridViewRow> itemList)
2950
{
3051
GridViewRowList = itemList;
3152
}
3253

54+
/// <summary>
55+
/// Renders a specific item in the list view at the specified position.
56+
/// </summary>
57+
/// <param name="listView">The list view to render into.</param>
58+
/// <param name="selected">A value indicating whether the item is selected.</param>
59+
/// <param name="item">The index of the item to render.</param>
60+
/// <param name="col">The column position to start rendering.</param>
61+
/// <param name="line">The line position to render on.</param>
62+
/// <param name="width">The width available for rendering.</param>
63+
/// <param name="start">The starting position within the item's display string.</param>
3364
public void Render(ListView listView, bool selected, int item, int col, int line, int width, int start = 0)
3465
{
3566
listView.Move(col, line);
3667

3768
var driver = Application.Driver;
3869
var row = GridViewRowList[item];
39-
driver!.AddStr(row.DisplayString);
40-
70+
driver!.AddStr(row.DisplayString ?? string.Empty);
4171
}
4272

73+
/// <summary>
74+
/// Determines whether the specified item is marked.
75+
/// </summary>
76+
/// <param name="item">The index of the item to check.</param>
77+
/// <returns><see langword="true" /> if the item is marked; otherwise, <see langword="false" />.</returns>
4378
public bool IsMarked(int item) => GridViewRowList[item].IsMarked;
4479

80+
/// <summary>
81+
/// Sets the marked state of the specified item and raises the <see cref="MarkChanged" /> event.
82+
/// </summary>
83+
/// <param name="item">The index of the item to mark or unmark.</param>
84+
/// <param name="value"><see langword="true" /> to mark the item; <see langword="false" /> to unmark it.</param>
4585
public void SetMark(int item, bool value)
4686
{
4787
var oldValue = GridViewRowList[item].IsMarked;
@@ -54,22 +94,38 @@ public void SetMark(int item, bool value)
5494
MarkChanged?.Invoke(this, args);
5595
}
5696

97+
/// <summary>
98+
/// Provides data for the <see cref="MarkChanged" /> event.
99+
/// </summary>
57100
public sealed class RowMarkedEventArgs : EventArgs
58101
{
102+
/// <summary>
103+
/// Gets or sets the row that was marked or unmarked.
104+
/// </summary>
59105
public required GridViewRow Row { get; set; }
106+
107+
/// <summary>
108+
/// Gets or sets the previous marked state of the row.
109+
/// </summary>
60110
public bool OldValue { get; set; }
61111
}
62112

113+
/// <summary>
114+
/// Occurs when a row's marked state changes.
115+
/// </summary>
63116
public event EventHandler<RowMarkedEventArgs>? MarkChanged;
64117

65-
public IList ToList()
66-
{
67-
return GridViewRowList;
68-
}
69-
118+
/// <summary>
119+
/// Converts the data source to a list.
120+
/// </summary>
121+
/// <returns>The grid view row list as an <see cref="IList" />.</returns>
122+
public IList ToList() => GridViewRowList;
123+
124+
/// <summary>
125+
/// Releases all resources used by the <see cref="GridViewDataSource" />.
126+
/// </summary>
70127
public void Dispose()
71128
{
72129
// No resources to dispose currently
73130
}
74-
75-
}
131+
}
Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
namespace OutGridView.Cmdlet
4+
namespace Microsoft.PowerShell.ConsoleGuiTools;
5+
6+
/// <summary>
7+
/// Contains layout and dimension details for rendering the grid view in the console.
8+
/// </summary>
9+
internal sealed class GridViewDetails
510
{
6-
internal sealed class GridViewDetails
7-
{
8-
// Contains the width of each column in the grid view.
9-
public int[] ListViewColumnWidths { get; set; }
11+
/// <summary>
12+
/// Gets or sets the width of each column in the grid view.
13+
/// </summary>
14+
public int[]? ListViewColumnWidths { get; set; }
1015

11-
// Dictates where the header should actually start considering
12-
// some offset is needed to factor in the checkboxes
13-
public int ListViewOffset { get; set; }
16+
/// <summary>
17+
/// Gets or sets the offset where the header should start, accounting for space needed for checkboxes.
18+
/// </summary>
19+
public int ListViewOffset { get; set; }
1420

15-
// The width that is actually useable on the screen after
16-
// subtracting space needed for a clean UI (spaces between columns, etc).
17-
public int UsableWidth { get; set; }
18-
}
19-
}
21+
/// <summary>
22+
/// Gets or sets the usable width available on the screen after subtracting space needed for UI elements such as spaces
23+
/// between columns.
24+
/// </summary>
25+
public int UsableWidth { get; set; }
26+
}

0 commit comments

Comments
 (0)