From 6af1903d8c461a02cd94d461a756164d0a3bc888 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 11 Mar 2020 15:55:02 -0700 Subject: [PATCH 01/27] Fixed #58: Multi-line commands rendering wrong --- src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index e0e27cd..07eb4bd 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using OutGridView.Models; using Terminal.Gui; @@ -164,6 +165,11 @@ private static string GetPaddedString(List strings, int[] colWidths, int builder.Append(' '); } + // Replace any newlines with encoded newline (`n) + // Note we can't use Environment.Newline because we don't know that the + // Command honors that. + strings[i] = strings[i].Replace("\n", "`n"); + // If the string won't fit in the column, append an ellipsis. if (strings[i].Length > colWidths[i]) { From a69373eae9534aaf1a771f372982b5ea03ecc6de Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 11 Mar 2020 16:00:25 -0700 Subject: [PATCH 02/27] Fixed #58 - Newlines in commands render incorrectly --- src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 07eb4bd..19deced 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Text.RegularExpressions; using OutGridView.Models; using Terminal.Gui; From f155262ca88adaab5c49c16fd232b789d6c32abe Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 11 Mar 2020 16:30:01 -0700 Subject: [PATCH 03/27] Added debug instructions to readme --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 073a375..5672e70 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,35 @@ Get-Process | Out-ConsoleGridView > NOTE: If you change the code and rebuild the project, you'll need to launch a > _new_ PowerShell process since the dll is already loaded and can't be unloaded. +### Debugging in Visual Studio Code + + +```powershell +PS C:\path\to\GraphicalTools> code . +``` + +Build by hitting `Ctrl-Shift-b` in VS Code. + +To debug: + +In a Powershell session in the `c:\path\to\GraphicalTools` directory, run `pwsh` (thus nesting powershell). + +Then do the folowing: + +```powershell +Import-Module .\module\Microsoft.PowerShell.ConsoleGuiTools +$pid +``` + +This will import the latest built DLL and output the process ID you'll need for debugging. Copy this ID to the clipboard. + +In VScode, set your breakpoints, etc... Then hit `F5`. In the VScode search box, paste the value printed by `$pid`. You'll see something like `pwsh.exe 18328`. Click that and the debug session will start. + +In the Powershell session run your commands; breakpoints will be hit, etc... + +When done, run `exit` to exit the nested PowerShell and run `pwsh` again. This unloads the DLL. Repeat. + + ## Contributions Welcome! We would love to incorporate community contributions into this project. If you would like to From 440833ea33563e47efbb1c2558be67fd125291ef Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 11 Mar 2020 16:31:28 -0700 Subject: [PATCH 04/27] Update src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs Co-Authored-By: Tyler James Leonhardt --- src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 19deced..e784836 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -167,6 +167,7 @@ private static string GetPaddedString(List strings, int[] colWidths, int // Replace any newlines with encoded newline (`n) // Note we can't use Environment.Newline because we don't know that the // Command honors that. + strings[i] = strings[i].Replace("\r\n", "`r`n"); strings[i] = strings[i].Replace("\n", "`n"); // If the string won't fit in the column, append an ellipsis. From dd2e765f705d9914aee7ad1b4e6cde2eeafcc432 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 11 Mar 2020 19:45:23 -0700 Subject: [PATCH 05/27] simplified stripping of newline/linefeed --- src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index e784836..2692d5b 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -164,10 +164,10 @@ private static string GetPaddedString(List strings, int[] colWidths, int builder.Append(' '); } - // Replace any newlines with encoded newline (`n) + // Replace any newlines with encoded newline/linefeed (`n or `r) // Note we can't use Environment.Newline because we don't know that the // Command honors that. - strings[i] = strings[i].Replace("\r\n", "`r`n"); + strings[i] = strings[i].Replace("\r", "`r"); strings[i] = strings[i].Replace("\n", "`n"); // If the string won't fit in the column, append an ellipsis. From 474826e6dd3987041e94692f8ea4b1cfca758afb Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Tue, 29 Sep 2020 10:39:32 -0700 Subject: [PATCH 06/27] made column spacing tigher --- .../ConsoleGui.cs | 34 ++++++++++--------- .../GridViewDetails.cs | 2 +- ...icrosoft.PowerShell.ConsoleGuiTools.csproj | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 78e76ad..0dd3ac5 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -14,8 +14,11 @@ namespace OutGridView.Cmdlet internal class ConsoleGui : IDisposable { private const string FILTER_LABEL = "Filter"; + // This adjusts the left margin of all controls + private const int FILTER_LABEL_X = 2; private bool _cancelled; private GridViewDataSource _itemSource; + private Label _filterLabel; private TextField _filterField; private ListView _listView; private ApplicationData _applicationData; @@ -28,9 +31,8 @@ public HashSet Start(ApplicationData applicationData) _gridViewDetails = new GridViewDetails { // If OutputMode is Single or Multiple, then we make items selectable. If we make them selectable, - // they have a 8 character addition of a checkbox (".....[ ]" or ".....( )") - // that we have to factor in. - ListViewOffset = _applicationData.OutputMode != OutputModeOption.None ? 8 : 4 + // 2 columns are required for the check/selection indicator and space. + ListViewOffset = _applicationData.OutputMode != OutputModeOption.None ? FILTER_LABEL_X + 2 : FILTER_LABEL_X }; Window win = AddTopLevelWindow(); @@ -189,25 +191,25 @@ private void CalculateColumnWidths(List gridHeaders) private void AddFilter(Window win) { - var filterLabel = new Label(FILTER_LABEL) + _filterLabel = new Label(FILTER_LABEL) { - X = 2 + X = FILTER_LABEL_X }; _filterField = new TextField(string.Empty) { - X = Pos.Right(filterLabel) + 1, - Y = Pos.Top(filterLabel), + X = Pos.Right(_filterLabel) + 1, + Y = Pos.Top(_filterLabel), CanFocus = true, - Width = Dim.Fill() - filterLabel.Text.Length + Width = Dim.Fill() - _filterLabel.Text.Length }; var filterErrorLabel = new Label(string.Empty) { - X = Pos.Right(filterLabel) + 1, - Y = Pos.Top(filterLabel) + 1, + X = Pos.Right(_filterLabel) + 1, + Y = Pos.Top(_filterLabel) + 1, ColorScheme = Colors.Base, - Width = Dim.Fill() - filterLabel.Text.Length + Width = Dim.Fill() - _filterLabel.Text.Length }; _filterField.TextChanged += (str) => @@ -232,14 +234,14 @@ private void AddFilter(Window win) } }; - win.Add(filterLabel, _filterField, filterErrorLabel); + win.Add(_filterLabel, _filterField, filterErrorLabel); } private void AddHeaders(Window win, List gridHeaders) { var header = new Label(GridViewHelpers.GetPaddedString( gridHeaders, - _gridViewDetails.ListViewOffset + _gridViewDetails.ListViewOffset - 1, + _gridViewDetails.ListViewOffset, _gridViewDetails.ListViewColumnWidths)) { X = 0, @@ -286,7 +288,7 @@ private void LoadData() valueList.Add(dataValue); } - string displayString = GridViewHelpers.GetPaddedString(valueList, _gridViewDetails.ListViewOffset, _gridViewDetails.ListViewColumnWidths); + string displayString = GridViewHelpers.GetPaddedString(valueList, 0, _gridViewDetails.ListViewColumnWidths); items.Add(new GridViewRow { @@ -304,8 +306,8 @@ private void AddRows(Window win) { _listView = new ListView(_itemSource) { - X = 3, - Y = 4, + X = Pos.Left(_filterLabel), + Y = Pos.Bottom(_filterLabel) + 3, // 1 for space, 1 for header, 1 for header underline Width = Dim.Fill(2), Height = Dim.Fill(2), AllowsMarking = _applicationData.OutputMode != OutputModeOption.None, diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/GridViewDetails.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/GridViewDetails.cs index 2b4a6c7..4841b7f 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/GridViewDetails.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/GridViewDetails.cs @@ -8,7 +8,7 @@ internal class GridViewDetails // Contains the width of each column in the grid view. public int[] ListViewColumnWidths { get; set; } - // Dictates where the grid should actually start considering + // Dictates where the header should actually start considering // some offset is needed to factor in the checkboxes public int ListViewOffset { get; set; } diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj b/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj index 9aa0f20..edb4ee5 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj @@ -6,7 +6,7 @@ - + From 3112550bf3cd4b97d13812d742952cd0e4f7fa6a Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Tue, 29 Sep 2020 11:06:48 -0700 Subject: [PATCH 07/27] update to new Terminal.gui package; no code changes --- .../Microsoft.PowerShell.ConsoleGuiTools.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj b/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj index 9aa0f20..897219a 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj @@ -6,7 +6,7 @@ - + From 86a72b558dc36f6e242362300c648e3e506b1999 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Tue, 29 Sep 2020 11:40:27 -0700 Subject: [PATCH 08/27] removed excess padding on right --- src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 7ec8296..29bb520 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -171,7 +171,7 @@ private void CalculateColumnWidths(List gridHeaders) // if the total width is wider than the usable width, remove 1 from widest column until it fits // the gui loses 3 chars on the left and 2 chars on the right - _gridViewDetails.UsableWidth = Application.Top.Frame.Width - 3 - listViewColumnWidths.Length - _gridViewDetails.ListViewOffset - 2; + _gridViewDetails.UsableWidth = Application.Top.Frame.Width - 3 - listViewColumnWidths.Length - _gridViewDetails.ListViewOffset; int columnWidthsSum = listViewColumnWidths.Sum(); while (columnWidthsSum >= _gridViewDetails.UsableWidth) { From c95abc569c2bcf4e0fcfbfeec4a13d88a052306c Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Tue, 29 Sep 2020 11:47:43 -0700 Subject: [PATCH 09/27] removed excess rows at bottom --- src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs | 5 ++--- .../GridViewDataSource.cs | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 29bb520..db866d1 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -170,8 +170,7 @@ private void CalculateColumnWidths(List gridHeaders) } // if the total width is wider than the usable width, remove 1 from widest column until it fits - // the gui loses 3 chars on the left and 2 chars on the right - _gridViewDetails.UsableWidth = Application.Top.Frame.Width - 3 - listViewColumnWidths.Length - _gridViewDetails.ListViewOffset; + _gridViewDetails.UsableWidth = Application.Top.Frame.Width - MARGIN_LEFT - listViewColumnWidths.Length - _gridViewDetails.ListViewOffset; int columnWidthsSum = listViewColumnWidths.Sum(); while (columnWidthsSum >= _gridViewDetails.UsableWidth) { @@ -311,7 +310,7 @@ private void AddRows(Window win) X = Pos.Left(_filterLabel), Y = Pos.Bottom(_filterLabel) + 3, // 1 for space, 1 for header, 1 for header underline Width = Dim.Fill(2), - Height = Dim.Fill(2), + Height = Dim.Fill(), AllowsMarking = _applicationData.OutputMode != OutputModeOption.None, AllowsMultipleSelection = _applicationData.OutputMode == OutputModeOption.Multiple, }; diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/GridViewDataSource.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/GridViewDataSource.cs index ff82fb5..f8047ce 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/GridViewDataSource.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/GridViewDataSource.cs @@ -47,7 +47,7 @@ private void RenderUstr(ConsoleDriver driver, ustring ustr, int col, int line, i { (var rune, var size) = Utf8.DecodeRune(ustr, index, index - ustr.Length); var count = Rune.ColumnWidth(rune); - if (used + count >= width) break; + if (used + count > width) break; driver.AddRune(rune); used += count; index += size; From 142ffe5aaf95555c86a7bc0e8ca0e47e8c715e88 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Tue, 29 Sep 2020 13:33:48 -0700 Subject: [PATCH 10/27] status bar wsa occluding window --- src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index db866d1..00be36f 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -95,7 +95,7 @@ private Window AddTopLevelWindow() Y = 0, // By using Dim.Fill(), it will automatically resize without manual intervention Width = Dim.Fill(), - Height = Dim.Fill() + Height = Dim.Fill(1) }; Application.Top.Add(win); From 65c3c5ae6d8698bd7a07dfadd942d7c860c5ea39 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 30 Sep 2020 11:05:00 -0700 Subject: [PATCH 11/27] tweaks --- .../ConsoleGui.cs | 18 +++++++++++++----- .../OutConsoleGridviewCmdletCommand.cs | 7 +++++++ src/OutGridView.Models/ApplicationData.cs | 1 + 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 00be36f..92a1602 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -44,7 +44,10 @@ public HashSet Start(ApplicationData applicationData) List gridHeaders = _applicationData.DataTable.DataColumns.Select((c) => c.Label).ToList(); CalculateColumnWidths(gridHeaders); - AddFilter(win); + if (!_applicationData.MinUI) + { + AddFilter(win); + } AddHeaders(win, gridHeaders); // GridView row logic @@ -91,11 +94,11 @@ private Window AddTopLevelWindow() // Creates the top-level window to show var win = new Window(_applicationData.Title) { - X = 0, - Y = 0, + X = _applicationData.MinUI ? -1 : 0, + Y = _applicationData.MinUI ? -1 : 0, // By using Dim.Fill(), it will automatically resize without manual intervention - Width = Dim.Fill(), - Height = Dim.Fill(1) + Width = Dim.Fill(_applicationData.MinUI ? -1 : 0), + Height = Dim.Fill(_applicationData.MinUI ? -1 : 1) }; Application.Top.Add(win); @@ -138,6 +141,11 @@ private void AddStatusBar() } ); + if (_applicationData.MinUI) + { + statusBar.Visible = false; + } + Application.Top.Add(statusBar); } diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/OutConsoleGridviewCmdletCommand.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/OutConsoleGridviewCmdletCommand.cs index 3f8a623..f4f5a9b 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/OutConsoleGridviewCmdletCommand.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/OutConsoleGridviewCmdletCommand.cs @@ -52,6 +52,12 @@ public class OutConsoleGridViewCmdletCommand : PSCmdlet, IDisposable [Parameter()] public string Filter { set; get; } + /// + /// gets or sets the whether "minimum UI" mode will be enabled + /// + [Parameter()] + public SwitchParameter MinUI { set; get; } + #endregion Input Parameters // This method gets called once for each cmdlet in the pipeline when the pipeline starts executing @@ -133,6 +139,7 @@ protected override void EndProcessing() Title = Title ?? "Out-ConsoleGridView", OutputMode = OutputMode, Filter = Filter, + MinUI = MinUI, DataTable = dataTable }; diff --git a/src/OutGridView.Models/ApplicationData.cs b/src/OutGridView.Models/ApplicationData.cs index 954c9dd..d193e5a 100644 --- a/src/OutGridView.Models/ApplicationData.cs +++ b/src/OutGridView.Models/ApplicationData.cs @@ -12,6 +12,7 @@ public class ApplicationData public OutputModeOption OutputMode { get; set; } public bool PassThru { get; set; } public string Filter { get; set; } + public bool MinUI { get; set; } public DataTable DataTable { get; set; } } } From fd934e168ce6454164be2b7357c4e5c49f14886b Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Thu, 1 Oct 2020 10:54:12 -0700 Subject: [PATCH 12/27] fixed build scripts to only build ocgv --- .vscode/tasks.json | 7 ++++++- Build.ps1 | 12 ++++++++++-- GraphicalTools.build.ps1 | 4 +++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 8af661d..0056896 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -16,7 +16,12 @@ "args": [ "-c", "Invoke-Build", - "Build" + // Build both modules + //"Build -ModuleName Microsoft.PowerShell.GraphicalTools, Microsoft.PowerShell.ConsoleGuiTools", + // Build only Out-GridView + //"Build -ModuleName Microsoft.PowerShell.GraphicalTools", + // Build only Out-ConsoleGridView + "Build -ModuleName Microsoft.PowerShell.ConsoleGuiTools", ], "problemMatcher": "$msCompile", "group": { diff --git a/Build.ps1 b/Build.ps1 index 1398d79..e514a57 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -1,3 +1,11 @@ -Invoke-Build Build -pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.GraphicalTools'; Get-Process | Out-GridView -PassThru" +# Build script for buildling/testing from the commnad line. See tasks.json for how build is invoked within VS Code +# GraphicalTools includes two modules: Microsoft.PowerShell.GraphicalTools and Microsoft.PowerShell.ConsoleGuiTools +# To build them all leave -ModuleName off the `InvokeBuild` command (e.g. Invoke-Build Build). +# To build only one, specify it using the -ModuleName paramater (e.g. Invoke-Build Build -ModuleName Microsoft.PowerShell.ConsoleGuiTools). + +# Build... +Invoke-Build Build -ModuleName Microsoft.PowerShell.ConsoleGuiTools + +# Run what was built... +# pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.GraphicalTools'; Get-Process | Out-GridView -PassThru" pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.ConsoleGuiTools'; Get-PSProfile | Out-ConsoleGridView -OutputMode Single -Title 'PS Profiles' -Filter power" \ No newline at end of file diff --git a/GraphicalTools.build.ps1 b/GraphicalTools.build.ps1 index dd3d3c7..dbbeef9 100644 --- a/GraphicalTools.build.ps1 +++ b/GraphicalTools.build.ps1 @@ -3,7 +3,9 @@ param( [ValidateSet("Debug", "Release")] [string]$Configuration = "Debug", - [string[]]$ModuleName = @( "Microsoft.PowerShell.GraphicalTools", "Microsoft.PowerShell.ConsoleGuiTools" ) + [string[]]$ModuleName = @( + "Microsoft.PowerShell.GraphicalTools", + "Microsoft.PowerShell.ConsoleGuiTools" ) ) $script:IsUnix = $PSVersionTable.PSEdition -and $PSVersionTable.PSEdition -eq "Core" -and !$IsWindows From 8e89181c487cf0a3ef20e8a2368f2c37f9cd17b1 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Thu, 1 Oct 2020 12:57:32 -0700 Subject: [PATCH 13/27] refactored to make logic more obvious --- Build.ps1 | 2 +- .../ConsoleGui.cs | 161 ++++++++++-------- 2 files changed, 93 insertions(+), 70 deletions(-) diff --git a/Build.ps1 b/Build.ps1 index e514a57..b07618a 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -8,4 +8,4 @@ Invoke-Build Build -ModuleName Microsoft.PowerShell.ConsoleGuiTools # Run what was built... # pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.GraphicalTools'; Get-Process | Out-GridView -PassThru" -pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.ConsoleGuiTools'; Get-PSProfile | Out-ConsoleGridView -OutputMode Single -Title 'PS Profiles' -Filter power" \ No newline at end of file +pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.ConsoleGuiTools'; Get-PSProfile | Out-ConsoleGridView -OutputMode Single -Title 'PS Profiles' -Filter ISE" \ No newline at end of file diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 92a1602..67cd7a2 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -19,10 +19,10 @@ internal class ConsoleGui : IDisposable // Width of Terminal.Gui ListView selection/check UI elements (old == 4, new == 2) private const int CHECK_WIDTH = 4; private bool _cancelled; - private GridViewDataSource _itemSource; private Label _filterLabel; private TextField _filterField; private ListView _listView; + private GridViewDataSource _itemSource; private ApplicationData _applicationData; private GridViewDetails _gridViewDetails; @@ -37,25 +37,36 @@ public HashSet Start(ApplicationData applicationData) ListViewOffset = _applicationData.OutputMode != OutputModeOption.None ? MARGIN_LEFT + CHECK_WIDTH : MARGIN_LEFT }; - Window win = AddTopLevelWindow(); - AddStatusBar(); + Window win = CreateTopLevelWindow(); - // GridView header logic + // Create the headers and calculate column widths based on the DataTable List gridHeaders = _applicationData.DataTable.DataColumns.Select((c) => c.Label).ToList(); CalculateColumnWidths(gridHeaders); + // Copy DataTable into the ListView's DataSource + _itemSource = LoadData(); + + // Add Filter UI if (!_applicationData.MinUI) { AddFilter(win); } - AddHeaders(win, gridHeaders); - // GridView row logic - LoadData(); - AddRows(win); + // Add Header UI + if (!_applicationData.MinUI) + { + AddHeaders(win, gridHeaders); + } + + // Add ListView + AddListView(win); + + // Status bar is where our key-bindings are handled + AddStatusBar(!_applicationData.MinUI); + + // If -Filter parameter is set, apply it. + ApplyFilter(); - _filterField.Text = _applicationData.Filter ?? string.Empty; - _filterField.CursorPosition = _filterField.Text.Length; // Run the GUI. Application.Run(); Application.Shutdown(); @@ -78,6 +89,40 @@ public HashSet Start(ApplicationData applicationData) return selectedIndexes; } + private GridViewDataSource LoadData() + { + var items = new List(); + int newIndex = 0; + for (int i = 0; i < _applicationData.DataTable.Data.Count; i++) + { + var dataTableRow = _applicationData.DataTable.Data[i]; + var valueList = new List(); + foreach (var dataTableColumn in _applicationData.DataTable.DataColumns) + { + string dataValue = dataTableRow.Values[dataTableColumn.ToString()].DisplayValue; + valueList.Add(dataValue); + } + + string displayString = GridViewHelpers.GetPaddedString(valueList, 0, _gridViewDetails.ListViewColumnWidths); + + items.Add(new GridViewRow + { + DisplayString = displayString, + OriginalIndex = i + }); + + newIndex++; + } + + return new GridViewDataSource(items); + } + + private void ApplyFilter(){ + List itemList = GridViewHelpers.FilterData(_itemSource.GridViewRowList, _applicationData.Filter ?? string.Empty); + // Set the ListView to show only the subset defined by the filter + _listView.Source = new GridViewDataSource(itemList); + } + private void Accept() { Application.RequestStop(); @@ -89,7 +134,7 @@ private void Close() Application.RequestStop(); } - private Window AddTopLevelWindow() + private Window CreateTopLevelWindow() { // Creates the top-level window to show var win = new Window(_applicationData.Title) @@ -105,7 +150,7 @@ private Window AddTopLevelWindow() return win; } - private void AddStatusBar() + private void AddStatusBar(bool visible) { var statusBar = new StatusBar( _applicationData.OutputMode != OutputModeOption.None @@ -140,12 +185,7 @@ private void AddStatusBar() new StatusItem(Key.Esc, "~ESC~ Close", () => Close()) } ); - - if (_applicationData.MinUI) - { - statusBar.Visible = false; - } - + statusBar.Visible = visible; Application.Top.Add(statusBar); } @@ -202,10 +242,11 @@ private void AddFilter(Window win) { _filterLabel = new Label(FILTER_LABEL) { - X = MARGIN_LEFT + X = MARGIN_LEFT, + Y = 0 }; - _filterField = new TextField(string.Empty) + _filterField = new TextField(_applicationData.Filter ?? string.Empty) { X = Pos.Right(_filterLabel) + 1, Y = Pos.Top(_filterLabel), @@ -230,9 +271,9 @@ private void AddFilter(Window win) filterErrorLabel.Text = " "; filterErrorLabel.ColorScheme = Colors.Base; filterErrorLabel.Redraw(filterErrorLabel.Bounds); + _applicationData.Filter = filterText; + ApplyFilter(); - List itemList = GridViewHelpers.FilterData(_itemSource.GridViewRowList, filterText); - _listView.Source = new GridViewDataSource(itemList); } catch (Exception ex) { @@ -251,12 +292,16 @@ private void AddHeaders(Window win, List gridHeaders) var header = new Label(GridViewHelpers.GetPaddedString( gridHeaders, _gridViewDetails.ListViewOffset, - _gridViewDetails.ListViewColumnWidths)) + _gridViewDetails.ListViewColumnWidths)); + header.X = 0; + if (_applicationData.MinUI) { - X = 0, - Y = 2 - }; - + header.Y = 0; + } + else + { + header.Y = 2; + } win.Add(header); // This renders dashes under the header to make it more clear what is header and what is data @@ -274,54 +319,32 @@ private void AddHeaders(Window win, List gridHeaders) } } - var headerLine = new Label(headerLineText.ToString()) - { - X = 0, - Y = 3 - }; - - win.Add(headerLine); - } - - private void LoadData() - { - var items = new List(); - int newIndex = 0; - for (int i = 0; i < _applicationData.DataTable.Data.Count; i++) - { - var dataTableRow = _applicationData.DataTable.Data[i]; - var valueList = new List(); - foreach (var dataTableColumn in _applicationData.DataTable.DataColumns) - { - string dataValue = dataTableRow.Values[dataTableColumn.ToString()].DisplayValue; - valueList.Add(dataValue); - } - - string displayString = GridViewHelpers.GetPaddedString(valueList, 0, _gridViewDetails.ListViewColumnWidths); - - items.Add(new GridViewRow + if (!_applicationData.MinUI){ + var headerLine = new Label(headerLineText.ToString()) { - DisplayString = displayString, - OriginalIndex = i - }); - - newIndex++; + X = 0, + Y = Pos.Bottom(header) + }; + win.Add(headerLine); } - - _itemSource = new GridViewDataSource(items); } - private void AddRows(Window win) + private void AddListView(Window win) { - _listView = new ListView(_itemSource) + _listView = new ListView(_itemSource); + _listView.X = MARGIN_LEFT; + if (!_applicationData.MinUI) { - X = Pos.Left(_filterLabel), - Y = Pos.Bottom(_filterLabel) + 3, // 1 for space, 1 for header, 1 for header underline - Width = Dim.Fill(2), - Height = Dim.Fill(), - AllowsMarking = _applicationData.OutputMode != OutputModeOption.None, - AllowsMultipleSelection = _applicationData.OutputMode == OutputModeOption.Multiple, - }; + _listView.Y = Pos.Bottom(_filterLabel) + 3; // 1 for space, 1 for header, 1 for header underline + } + else + { + _listView.Y = 1; // 1 for space, 1 for header, 1 for header underline + } + _listView.Width = Dim.Fill(2); + _listView.Height = Dim.Fill(); + _listView.AllowsMarking = _applicationData.OutputMode != OutputModeOption.None; + _listView.AllowsMultipleSelection = _applicationData.OutputMode == OutputModeOption.Multiple; win.Add(_listView); } From e530f373e5c3be405ff42c007e2073eb9169512b Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Sat, 3 Oct 2020 09:41:31 -0700 Subject: [PATCH 14/27] removed orig files --- Build.ps1.orig | 16 - .../ConsoleGui.cs.orig | 417 ------------------ 2 files changed, 433 deletions(-) delete mode 100644 Build.ps1.orig delete mode 100644 src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig diff --git a/Build.ps1.orig b/Build.ps1.orig deleted file mode 100644 index e26b262..0000000 --- a/Build.ps1.orig +++ /dev/null @@ -1,16 +0,0 @@ -# Build script for buildling/testing from the commnad line. See tasks.json for how build is invoked within VS Code -# GraphicalTools includes two modules: Microsoft.PowerShell.GraphicalTools and Microsoft.PowerShell.ConsoleGuiTools -# To build them all leave -ModuleName off the `InvokeBuild` command (e.g. Invoke-Build Build). -# To build only one, specify it using the -ModuleName paramater (e.g. Invoke-Build Build -ModuleName Microsoft.PowerShell.ConsoleGuiTools). - -# Build... -Invoke-Build Build -ModuleName Microsoft.PowerShell.ConsoleGuiTools - -# Run what was built... -<<<<<<< HEAD -# pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.GraphicalTools'; Get-Process | Out-GridView -PassThru" -pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.ConsoleGuiTools'; Get-PSProfile | Out-ConsoleGridView -OutputMode Single -Title 'PS Profiles' -Filter ISE" -======= -# pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.GraphicalTools'; Get-Module -all | Out-GridView -OutputMode Single -Title 'Imported Modules' -pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.ConsoleGuiTools'; Get-Module -all | Out-ConsoleGridView -OutputMode Single -Title 'Imported Modules' -Filter power" ->>>>>>> master diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig deleted file mode 100644 index 7ebb5eb..0000000 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig +++ /dev/null @@ -1,417 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NStack; -using OutGridView.Models; -using Terminal.Gui; - -namespace OutGridView.Cmdlet -{ - internal class ConsoleGui : IDisposable - { - private const string FILTER_LABEL = "Filter"; - // This adjusts the left margin of all controls - private const int MARGIN_LEFT = 2; - // Width of Terminal.Gui ListView selection/check UI elements (old == 4, new == 2) - private const int CHECK_WIDTH = 4; - private bool _cancelled; -<<<<<<< HEAD -======= - private GridViewDataSource _itemSource; ->>>>>>> master - private Label _filterLabel; - private TextField _filterField; - private ListView _listView; - private GridViewDataSource _itemSource; - private ApplicationData _applicationData; - private GridViewDetails _gridViewDetails; - - public HashSet Start(ApplicationData applicationData) - { - Application.Init(); - _applicationData = applicationData; - _gridViewDetails = new GridViewDetails - { - // If OutputMode is Single or Multiple, then we make items selectable. If we make them selectable, - // 2 columns are required for the check/selection indicator and space. - ListViewOffset = _applicationData.OutputMode != OutputModeOption.None ? MARGIN_LEFT + CHECK_WIDTH : MARGIN_LEFT - }; - - Window win = CreateTopLevelWindow(); - - // Create the headers and calculate column widths based on the DataTable - List gridHeaders = _applicationData.DataTable.DataColumns.Select((c) => c.Label).ToList(); - CalculateColumnWidths(gridHeaders); - - // Copy DataTable into the ListView's DataSource - _itemSource = LoadData(); - - // Add Filter UI - if (!_applicationData.MinUI) - { - AddFilter(win); - } - - // Add Header UI - if (!_applicationData.MinUI) - { - AddHeaders(win, gridHeaders); - } - - // Add ListView - AddListView(win); - - // Status bar is where our key-bindings are handled - AddStatusBar(!_applicationData.MinUI); - - // If -Filter parameter is set, apply it. - ApplyFilter(); - - // Run the GUI. - Application.Run(); - Application.Shutdown(); - - // Return results of selection if required. - HashSet selectedIndexes = new HashSet(); - if (_cancelled) - { - return selectedIndexes; - } - - foreach (GridViewRow gvr in _itemSource.GridViewRowList) - { - if (gvr.IsMarked) - { - selectedIndexes.Add(gvr.OriginalIndex); - } - } - - return selectedIndexes; - } - - private GridViewDataSource LoadData() - { - var items = new List(); - int newIndex = 0; - for (int i = 0; i < _applicationData.DataTable.Data.Count; i++) - { - var dataTableRow = _applicationData.DataTable.Data[i]; - var valueList = new List(); - foreach (var dataTableColumn in _applicationData.DataTable.DataColumns) - { - string dataValue = dataTableRow.Values[dataTableColumn.ToString()].DisplayValue; - valueList.Add(dataValue); - } - - string displayString = GridViewHelpers.GetPaddedString(valueList, 0, _gridViewDetails.ListViewColumnWidths); - - items.Add(new GridViewRow - { - DisplayString = displayString, - OriginalIndex = i - }); - - newIndex++; - } - - return new GridViewDataSource(items); - } - - private void ApplyFilter(){ - List itemList = GridViewHelpers.FilterData(_itemSource.GridViewRowList, _applicationData.Filter ?? string.Empty); - // Set the ListView to show only the subset defined by the filter - _listView.Source = new GridViewDataSource(itemList); - } - - private void Accept() - { - Application.RequestStop(); - } - - private void Close() - { - _cancelled = true; - Application.RequestStop(); - } - - private Window CreateTopLevelWindow() - { - // Creates the top-level window to show - var win = new Window(_applicationData.Title) - { - X = _applicationData.MinUI ? -1 : 0, - Y = _applicationData.MinUI ? -1 : 0, - // By using Dim.Fill(), it will automatically resize without manual intervention -<<<<<<< HEAD - Width = Dim.Fill(_applicationData.MinUI ? -1 : 0), - Height = Dim.Fill(_applicationData.MinUI ? -1 : 1) -======= - Width = Dim.Fill(), - Height = Dim.Fill(1) ->>>>>>> master - }; - - Application.Top.Add(win); - return win; - } - - private void AddStatusBar(bool visible) - { - var statusBar = new StatusBar( - _applicationData.OutputMode != OutputModeOption.None - ? new StatusItem[] - { - // Use Key.Unknown for SPACE with no delegate because ListView already - // handles SPACE - new StatusItem(Key.Unknown, "~SPACE~ Mark Item", null), - new StatusItem(Key.Enter, "~ENTER~ Accept", () => - { - if (Application.Top.MostFocused == _listView) - { - // If nothing was explicitly marked, we return the item that was selected - // when ENTER is pressed in Single mode. If something was previously selected - // (using SPACE) then honor that as the single item to return - if (_applicationData.OutputMode == OutputModeOption.Single && - _itemSource.GridViewRowList.Find(i => i.IsMarked) == null) - { - _listView.MarkUnmarkRow(); - } - Accept(); - } - else if (Application.Top.MostFocused == _filterField) - { - _listView.SetFocus(); - } - }), - new StatusItem(Key.Esc, "~ESC~ Close", () => Close()) - } - : new StatusItem[] - { - new StatusItem(Key.Esc, "~ESC~ Close", () => Close()) - } - ); - statusBar.Visible = visible; - Application.Top.Add(statusBar); - } - - private void CalculateColumnWidths(List gridHeaders) - { - _gridViewDetails.ListViewColumnWidths = new int[gridHeaders.Count]; - var listViewColumnWidths = _gridViewDetails.ListViewColumnWidths; - - for (int i = 0; i < gridHeaders.Count; i++) - { - listViewColumnWidths[i] = gridHeaders[i].Length; - } - - // calculate the width of each column based on longest string in each column for each row - foreach (var row in _applicationData.DataTable.Data) - { - int index = 0; - - // use half of the visible buffer height for the number of objects to inspect to calculate widths - foreach (var col in row.Values.Take(Application.Top.Frame.Height / 2)) - { - var len = col.Value.DisplayValue.Length; - if (len > listViewColumnWidths[index]) - { - listViewColumnWidths[index] = len; - } - - index++; - } - } - - // if the total width is wider than the usable width, remove 1 from widest column until it fits - _gridViewDetails.UsableWidth = Application.Top.Frame.Width - MARGIN_LEFT - listViewColumnWidths.Length - _gridViewDetails.ListViewOffset; - int columnWidthsSum = listViewColumnWidths.Sum(); - while (columnWidthsSum >= _gridViewDetails.UsableWidth) - { - int maxWidth = 0; - int maxIndex = 0; - for (int i = 0; i < listViewColumnWidths.Length; i++) - { - if (listViewColumnWidths[i] > maxWidth) - { - maxWidth = listViewColumnWidths[i]; - maxIndex = i; - } - } - - listViewColumnWidths[maxIndex]--; - columnWidthsSum--; - } - } - - private void AddFilter(Window win) - { - _filterLabel = new Label(FILTER_LABEL) - { -<<<<<<< HEAD - X = MARGIN_LEFT, - Y = 0 -======= - X = MARGIN_LEFT ->>>>>>> master - }; - - _filterField = new TextField(_applicationData.Filter ?? string.Empty) - { - X = Pos.Right(_filterLabel) + 1, - Y = Pos.Top(_filterLabel), - CanFocus = true, - Width = Dim.Fill() - _filterLabel.Text.Length - }; - - var filterErrorLabel = new Label(string.Empty) - { - X = Pos.Right(_filterLabel) + 1, - Y = Pos.Top(_filterLabel) + 1, - ColorScheme = Colors.Base, - Width = Dim.Fill() - _filterLabel.Text.Length - }; - - _filterField.TextChanged += (str) => - { - // str is the OLD value - string filterText = _filterField.Text?.ToString(); - try - { - filterErrorLabel.Text = " "; - filterErrorLabel.ColorScheme = Colors.Base; - filterErrorLabel.Redraw(filterErrorLabel.Bounds); - _applicationData.Filter = filterText; - ApplyFilter(); - - } - catch (Exception ex) - { - filterErrorLabel.Text = ex.Message; - filterErrorLabel.ColorScheme = Colors.Error; - filterErrorLabel.Redraw(filterErrorLabel.Bounds); - _listView.Source = _itemSource; - } - }; - - win.Add(_filterLabel, _filterField, filterErrorLabel); - } - - private void AddHeaders(Window win, List gridHeaders) - { - var header = new Label(GridViewHelpers.GetPaddedString( - gridHeaders, - _gridViewDetails.ListViewOffset, -<<<<<<< HEAD - _gridViewDetails.ListViewColumnWidths)); - header.X = 0; - if (_applicationData.MinUI) -======= - _gridViewDetails.ListViewColumnWidths)) ->>>>>>> master - { - header.Y = 0; - } - else - { - header.Y = 2; - } - win.Add(header); - - // This renders dashes under the header to make it more clear what is header and what is data - var headerLineText = new StringBuilder(); - foreach (char c in header.Text) - { - if (c.Equals(' ')) - { - headerLineText.Append(' '); - } - else - { - // When gui.cs supports text decorations, should replace this with just underlining the header - headerLineText.Append('-'); - } - } - -<<<<<<< HEAD - if (!_applicationData.MinUI){ - var headerLine = new Label(headerLineText.ToString()) -======= - var headerLine = new Label(headerLineText.ToString()) - { - X = 0, - Y = 3 - }; - - win.Add(headerLine); - } - - private void LoadData() - { - var items = new List(); - int newIndex = 0; - for (int i = 0; i < _applicationData.DataTable.Data.Count; i++) - { - var dataTableRow = _applicationData.DataTable.Data[i]; - var valueList = new List(); - foreach (var dataTableColumn in _applicationData.DataTable.DataColumns) - { - string dataValue = dataTableRow.Values[dataTableColumn.ToString()].DisplayValue; - valueList.Add(dataValue); - } - - string displayString = GridViewHelpers.GetPaddedString(valueList, 0, _gridViewDetails.ListViewColumnWidths); - - items.Add(new GridViewRow ->>>>>>> master - { - X = 0, - Y = Pos.Bottom(header) - }; - win.Add(headerLine); - } - } - - private void AddListView(Window win) - { - _listView = new ListView(_itemSource); - _listView.X = MARGIN_LEFT; - if (!_applicationData.MinUI) - { -<<<<<<< HEAD - _listView.Y = Pos.Bottom(_filterLabel) + 3; // 1 for space, 1 for header, 1 for header underline - } - else - { - _listView.Y = 1; // 1 for space, 1 for header, 1 for header underline - } - _listView.Width = Dim.Fill(2); - _listView.Height = Dim.Fill(); - _listView.AllowsMarking = _applicationData.OutputMode != OutputModeOption.None; - _listView.AllowsMultipleSelection = _applicationData.OutputMode == OutputModeOption.Multiple; -======= - X = Pos.Left(_filterLabel), - Y = Pos.Bottom(_filterLabel) + 3, // 1 for space, 1 for header, 1 for header underline - Width = Dim.Fill(2), - Height = Dim.Fill(), - AllowsMarking = _applicationData.OutputMode != OutputModeOption.None, - AllowsMultipleSelection = _applicationData.OutputMode == OutputModeOption.Multiple, - }; ->>>>>>> master - - win.Add(_listView); - } - - public void Dispose() - { - // By emitting this, we fix an issue where arrow keys don't work in the console - // because .NET requires application mode to support Arrow key escape sequences - // Esc[?1h - Set cursor key to application mode - // See http://ascii-table.com/ansi-escape-sequences-vt-100.php - Console.Write("\u001b[?1h"); - } - } -} From 25204bce067be424dc098550c5b4fa52b07ffa4b Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 3 Aug 2022 14:20:17 -0700 Subject: [PATCH 15/27] Upgrade to Terminal.Gui v1.7 --- .../Microsoft.PowerShell.ConsoleGuiTools.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj b/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj index 2bd6ac6..adeabd1 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj @@ -6,7 +6,7 @@ - + From b474f840307b3f4fd6cae4c07812821ca0909429 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 3 Aug 2022 15:22:15 -0700 Subject: [PATCH 16/27] removed border when minui is enabled --- src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 4464b42..5876fb9 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -141,11 +141,16 @@ private Window CreateTopLevelWindow() { X = _applicationData.MinUI ? -1 : 0, Y = _applicationData.MinUI ? -1 : 0, + // By using Dim.Fill(), it will automatically resize without manual intervention Width = Dim.Fill(_applicationData.MinUI ? -1 : 0), Height = Dim.Fill(_applicationData.MinUI ? -1 : 1) }; - + + if (_applicationData.MinUI) { + win.Border.BorderStyle = BorderStyle.None; + } + Application.Top.Add(win); return win; } From 75ca4d110b0075d8cc2e3b07f74c7c6c89576a96 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 3 Aug 2022 15:58:59 -0700 Subject: [PATCH 17/27] re-implemented feature post merge screw up --- .../ConsoleGui.cs | 96 ++++++++++++------- 1 file changed, 60 insertions(+), 36 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 5876fb9..73c90f0 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -62,7 +62,7 @@ public HashSet Start(ApplicationData applicationData) AddListView(win); // Status bar is where our key-bindings are handled - AddStatusBar(!_applicationData.MinUI); + AddStatusBar(); // If -Filter parameter is set, apply it. ApplyFilter(); @@ -117,7 +117,8 @@ private GridViewDataSource LoadData() return new GridViewDataSource(items); } - private void ApplyFilter(){ + private void ApplyFilter() + { List itemList = GridViewHelpers.FilterData(_itemSource.GridViewRowList, _applicationData.Filter ?? string.Empty); // Set the ListView to show only the subset defined by the filter _listView.Source = new GridViewDataSource(itemList); @@ -146,50 +147,72 @@ private Window CreateTopLevelWindow() Width = Dim.Fill(_applicationData.MinUI ? -1 : 0), Height = Dim.Fill(_applicationData.MinUI ? -1 : 1) }; - - if (_applicationData.MinUI) { + + if (_applicationData.MinUI) + { win.Border.BorderStyle = BorderStyle.None; - } - + } + Application.Top.Add(win); return win; } private void AddStatusBar(bool visible) { - var statusBar = new StatusBar( - _applicationData.OutputMode != OutputModeOption.None - ? new StatusItem[] + var statusItems = new List(); + if (_applicationData.OutputMode != OutputModeOption.None) + { + // Use Key.Unknown for SPACE with no delegate because ListView already + // handles SPACE + statusItems.Add(new StatusItem(Key.Unknown, "~SPACE~ Select Item", null)); + } + + if (_applicationData.OutputMode == OutputModeOption.Multiple) + { + statusItems.Add(new StatusItem(Key.A | Key.CtrlMask, "~^A~ Select All", () => + { + // This selects only the items that match the Filter + var gvds = _listView.Source as GridViewDataSource; + gvds.GridViewRowList.ForEach(i => i.IsMarked = true); + _listView.SetNeedsDisplay(); + })); + + // Use Ctrl-N until Terminal.Gui supports ctrl-shift chords + statusItems.Add(new StatusItem(Key.N | Key.CtrlMask, "~^N~ Select None", () => + { + // This un-selects only the items that match the Filter + var gvds = _listView.Source as GridViewDataSource; + gvds.GridViewRowList.ForEach(i => i.IsMarked = false); + _listView.SetNeedsDisplay(); + })); + } + + if (_applicationData.OutputMode != OutputModeOption.None) + { + statusItems.Add(new StatusItem(Key.Enter, "~ENTER~ Accept", () => + { + if (Application.Top.MostFocused == _listView) { - // Use Key.Unknown for SPACE with no delegate because ListView already - // handles SPACE - new StatusItem(Key.Unknown, "~SPACE~ Mark Item", null), - new StatusItem(Key.Enter, "~ENTER~ Accept", () => + // If nothing was explicitly marked, we return the item that was selected + // when ENTER is pressed in Single mode. If something was previously selected + // (using SPACE) then honor that as the single item to return + if (_applicationData.OutputMode == OutputModeOption.Single && + _itemSource.GridViewRowList.Find(i => i.IsMarked) == null) { - if (Application.Top.MostFocused == _listView) - { - // If nothing was explicitly marked, we return the item that was selected - // when ENTER is pressed in Single mode. If something was previously selected - // (using SPACE) then honor that as the single item to return - if (_applicationData.OutputMode == OutputModeOption.Single && - _itemSource.GridViewRowList.Find(i => i.IsMarked) == null) - { - _listView.MarkUnmarkRow(); - } - Accept(); - } - else if (Application.Top.MostFocused == _filterField) - { - _listView.SetFocus(); - } - }), - new StatusItem(Key.Esc, "~ESC~ Close", () => Close()) + _listView.MarkUnmarkRow(); + } + Accept(); } - : new StatusItem[] + else if (Application.Top.MostFocused == _filterField) { - new StatusItem(Key.Esc, "~ESC~ Close", () => Close()) + _listView.SetFocus(); } - ); + })); + } + + statusItems.Add(new StatusItem(Key.Esc, "~ESC~ Close", () => Close())); + + var statusBar = new StatusBar(statusItems.ToArray()); statusBar.Visible = visible; Application.Top.Add(statusBar); } @@ -324,7 +347,8 @@ private void AddHeaders(Window win, List gridHeaders) } } - if (!_applicationData.MinUI){ + if (!_applicationData.MinUI) + { var headerLine = new Label(headerLineText.ToString()) { X = 0, @@ -341,7 +365,7 @@ private void AddListView(Window win) if (!_applicationData.MinUI) { _listView.Y = Pos.Bottom(_filterLabel) + 3; // 1 for space, 1 for header, 1 for header underline - } + } else { _listView.Y = 1; // 1 for space, 1 for header, 1 for header underline From fd6483e57f170fac14bdd6812b2a2efaebb788f2 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 3 Aug 2022 16:20:43 -0700 Subject: [PATCH 18/27] tweaks --- .../ConsoleGui.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 73c90f0..5642e96 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -62,7 +62,7 @@ public HashSet Start(ApplicationData applicationData) AddListView(win); // Status bar is where our key-bindings are handled - AddStatusBar(); + AddStatusBar(!_applicationData.MinUI); // If -Filter parameter is set, apply it. ApplyFilter(); @@ -169,7 +169,7 @@ private void AddStatusBar(bool visible) if (_applicationData.OutputMode == OutputModeOption.Multiple) { - statusItems.Add(new StatusItem(Key.A | Key.CtrlMask, "~^A~ Select All", () => + statusItems.Add(new StatusItem(Key.A | Key.CtrlMask, "~CTRL-A~ Select All", () => { // This selects only the items that match the Filter var gvds = _listView.Source as GridViewDataSource; @@ -177,8 +177,8 @@ private void AddStatusBar(bool visible) _listView.SetNeedsDisplay(); })); - // Use Ctrl-N until Terminal.Gui supports ctrl-shift chords - statusItems.Add(new StatusItem(Key.N | Key.CtrlMask, "~^N~ Select None", () => + // Ctrl-D is commonly used in GUIs for select-none + statusItems.Add(new StatusItem(Key.D | Key.CtrlMask, "~CTRL-D~ Select None", () => { // This un-selects only the items that match the Filter var gvds = _listView.Source as GridViewDataSource; @@ -240,7 +240,6 @@ private void CalculateColumnWidths(List gridHeaders) { listViewColumnWidths[index] = len; } - index++; } } @@ -282,6 +281,13 @@ private void AddFilter(Window win) Width = Dim.Fill() - _filterLabel.Text.Length }; + // TextField captures Ctrl-A (select all text) and Ctrl-D (delete backwards) + // In OCGV these are used for select-all/none of items. Selecting items is more + // common than editing the filter field so we turn them off in the filter textview. + // BACKSPACE still works for delete backwards + _filterField.ClearKeybinding(Key.A | Key.CtrlMask); + _filterField.ClearKeybinding(Key.D | Key.CtrlMask); + var filterErrorLabel = new Label(string.Empty) { X = Pos.Right(_filterLabel) + 1, From c06641e18487d2a8c4514ac09f3c425103508391 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 3 Aug 2022 16:54:38 -0700 Subject: [PATCH 19/27] improve VS code build and debug support --- .vscode/launch.json | 29 ++++++++++++----------------- .vscode/settings.json | 2 +- .vscode/tasks.json | 39 ++++++++++++++------------------------- README.md | 26 ++++++-------------------- 4 files changed, 33 insertions(+), 63 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 17f330a..fcc366c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,25 +6,20 @@ "configurations": [ { "name": ".NET Core Launch (console)", + "preLaunchTask": "build ConsoleGuiTools", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceFolder}/Cmdlet/bin/Debug/net6.0/win10-x64/OutGridViewCmdlet.dll", - "args": [], - "cwd": "${workspaceFolder}/Cmdlet", - "console": "internalConsole", - "stopAtEntry": false - }, - { - "name": ".NET Core Launch (application)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceFolder}/Application/bin/Debug/net6.0/win10-x64/OutGridViewApplication.dll", - "args": [], - "cwd": "${workspaceFolder}/Application", - "console": "internalConsole", - "stopAtEntry": false + "program": "pwsh", + "args": [ + "-NoExit", + "-NoProfile", + "-Command", + "Import-Module ${workspaceFolder}/module/Microsoft.PowerShell.ConsoleGuiTools" + ], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "stopAtEntry": false, + "justMyCode": false }, { "name": ".NET Core Attach", diff --git a/.vscode/settings.json b/.vscode/settings.json index 351aacc..d528a62 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { "files.associations": { - "**/.vsts-ci/**/*.yml":"azure-pipelines" + "**/.vsts-ci/**/*.yml":"azure-pipelines", } } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 0056896..e0a35c4 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,33 +1,22 @@ -{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + { "version": "2.0.0", "tasks": [ { - "label": "build", - "osx": { - "command": "/usr/local/bin/pwsh" - }, - "windows": { - "command": "pwsh.exe" - }, - "linux": { - "command": "/usr/local/bin/pwsh" - }, - "type": "process", + "label": "build ConsoleGuiTools", + "command": "Invoke-Build", + "type": "shell", "args": [ - "-c", - "Invoke-Build", - // Build both modules - //"Build -ModuleName Microsoft.PowerShell.GraphicalTools, Microsoft.PowerShell.ConsoleGuiTools", - // Build only Out-GridView - //"Build -ModuleName Microsoft.PowerShell.GraphicalTools", - // Build only Out-ConsoleGridView - "Build -ModuleName Microsoft.PowerShell.ConsoleGuiTools", + "Build", + "-Module", + "Microsoft.PowerShell.ConsoleGuiTools" ], - "problemMatcher": "$msCompile", - "group": { - "kind": "build", - "isDefault": true - } + "group": "build", + "presentation": { + "reveal": "silent" + }, + "problemMatcher": "$msCompile" } ] } \ No newline at end of file diff --git a/README.md b/README.md index d762d96..5a3fcd9 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,9 @@ to view and filter objects graphically. ## Development -### 1. Install PowerShell 7.1+ +### 1. Install PowerShell 7.2+ -Install PowerShell 7.1+ with [these instructions](https://github.com/PowerShell/PowerShell#get-powershell). +Install PowerShell 7.2+ with [these instructions](https://github.com/PowerShell/PowerShell#get-powershell). ### 2. Clone the GitHub repository @@ -72,29 +72,15 @@ PS ./GraphicalTools> code . Build by hitting `Ctrl-Shift-B` in VS Code. -To debug: +Set a breakpoint and hit `F5` to start the debugger. -In a PowerShell session in the `./GraphicalTools` directory, run `pwsh` (thus -nesting PowerShell). - -Then do the folowing: +Click on the VS Code "TERMINAL" tab and type your command that starts `Out-ConsoleGridView`, e.g. ```powershell -Import-Module ./module/Microsoft.PowerShell.ConsoleGuiTools -$pid +ls | ocgv ``` -This will import the latest built DLL and output the process ID you'll need -for debugging. Copy this ID to the clipboard. - -In VScode, set your breakpoints, etc. Then hit `F5`. In the VScode search -box, paste the value printed by `$pid`. You'll see something like `pwsh.exe -18328`. Click that and the debug session will start. - -In the PowerShell session run your commands; breakpoints will be hit, etc. - -When done, run `exit` to exit the nested PowerShell and run `pwsh` again. -This unloads the DLL. Repeat. +Your breakpoint should be hit. ## Contributions Welcome From 6833168b04951c54741b6796f8bb2d16bb7c8919 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 3 Aug 2022 17:40:25 -0700 Subject: [PATCH 20/27] On exit, ensure only visible marked items are output --- src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 2ad6f0d..dd42dc6 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -64,7 +64,10 @@ public HashSet Start(ApplicationData applicationData) return selectedIndexes; } - foreach (GridViewRow gvr in _itemSource.GridViewRowList) + // Ensure that only items that are marked AND not filtered out + // get returned (See Issue #121) + List itemList = GridViewHelpers.FilterData(_itemSource.GridViewRowList, _filterField.Text.ToString()); + foreach (GridViewRow gvr in itemList) { if (gvr.IsMarked) { From ac54e61e43f64ed000223449a261f1deeb44e51b Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 3 Aug 2022 20:10:29 -0600 Subject: [PATCH 21/27] Fixes 87 --- src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs index 2ad6f0d..c600b9d 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs @@ -53,6 +53,9 @@ public HashSet Start(ApplicationData applicationData) _filterField.Text = _applicationData.Filter ?? string.Empty; _filterField.CursorPosition = _filterField.Text.Length; + + _listView.SetFocus(); + // Run the GUI. Application.Run(); Application.Shutdown(); From 3efc919b6f8eca936ebd29f45ef2b6a30e3f90a9 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 17 Aug 2022 14:17:17 -0700 Subject: [PATCH 22/27] Tweaked build to have a better test at end --- Build.ps1 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Build.ps1 b/Build.ps1 index 2789206..aac77f1 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -6,6 +6,8 @@ # Build... Invoke-Build Build -ModuleName Microsoft.PowerShell.ConsoleGuiTools -# Run what was built... -# pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.GraphicalTools'; Get-Module -all | Out-GridView -OutputMode Single -Title 'Imported Modules' -pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.ConsoleGuiTools'; Get-Module -all | Out-ConsoleGridView -OutputMode Single -Title 'Imported Modules' -Filter power" +# Run what was built as a bit of test of: +# - Scale: recursive ls of the project +# - Filter: proving regex works +# - SelectMultiple +pwsh -noprofile -command "Import-Module -verbose '$PSScriptRoot/module/Microsoft.PowerShell.ConsoleGuiTools'; Get-ChildItem -Recurse | Out-ConsoleGridView -OutputMode Multiple -Title 'Imported Modules' -Filter \.xml" From 59e1cf7c4d3c03287d8d178bc63f533b4b7de817 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 17 Aug 2022 14:31:02 -0700 Subject: [PATCH 23/27] merge --- .../ConsoleGui.cs.orig | 349 ++++++++++++++++++ ...oft.PowerShell.ConsoleGuiTools.csproj.orig | 26 ++ 2 files changed, 375 insertions(+) create mode 100644 src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig create mode 100644 src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj.orig diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig new file mode 100644 index 0000000..ff5a97b --- /dev/null +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig @@ -0,0 +1,349 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NStack; +using OutGridView.Models; +using Terminal.Gui; + +namespace OutGridView.Cmdlet +{ + internal class ConsoleGui : IDisposable + { + private const string FILTER_LABEL = "Filter"; + // This adjusts the left margin of all controls +<<<<<<< HEAD + private const int MARGIN_LEFT = 2; + // Width of Terminal.Gui ListView selection/check UI elements (old == 4, new == 2) + private const int CHECK_WIDTH = 4; +======= + private const int FILTER_LABEL_X = 2; +>>>>>>> 474826e (made column spacing tigher) + private bool _cancelled; + private GridViewDataSource _itemSource; + private Label _filterLabel; + private TextField _filterField; + private ListView _listView; + private ApplicationData _applicationData; + private GridViewDetails _gridViewDetails; + + public HashSet Start(ApplicationData applicationData) + { + Application.Init(); + _applicationData = applicationData; + _gridViewDetails = new GridViewDetails + { + // If OutputMode is Single or Multiple, then we make items selectable. If we make them selectable, + // 2 columns are required for the check/selection indicator and space. +<<<<<<< HEAD + ListViewOffset = _applicationData.OutputMode != OutputModeOption.None ? MARGIN_LEFT + CHECK_WIDTH : MARGIN_LEFT +======= + ListViewOffset = _applicationData.OutputMode != OutputModeOption.None ? FILTER_LABEL_X + 2 : FILTER_LABEL_X +>>>>>>> 474826e (made column spacing tigher) + }; + + Window win = AddTopLevelWindow(); + AddStatusBar(); + + // GridView header logic + List gridHeaders = _applicationData.DataTable.DataColumns.Select((c) => c.Label).ToList(); + CalculateColumnWidths(gridHeaders); + + AddFilter(win); + AddHeaders(win, gridHeaders); + + // GridView row logic + LoadData(); + AddRows(win); + + _filterField.Text = _applicationData.Filter ?? string.Empty; + _filterField.CursorPosition = _filterField.Text.Length; + // Run the GUI. + Application.Run(); + Application.Shutdown(); + + // Return results of selection if required. + HashSet selectedIndexes = new HashSet(); + if (_cancelled) + { + return selectedIndexes; + } + + foreach (GridViewRow gvr in _itemSource.GridViewRowList) + { + if (gvr.IsMarked) + { + selectedIndexes.Add(gvr.OriginalIndex); + } + } + + return selectedIndexes; + } + + private void Accept() + { + Application.RequestStop(); + } + + private void Close() + { + _cancelled = true; + Application.RequestStop(); + } + + private Window AddTopLevelWindow() + { + // Creates the top-level window to show + var win = new Window(_applicationData.Title) + { + X = 0, + Y = 0, + // By using Dim.Fill(), it will automatically resize without manual intervention + Width = Dim.Fill(), + Height = Dim.Fill(1) + }; + + Application.Top.Add(win); + return win; + } + + private void AddStatusBar() + { + var statusBar = new StatusBar( + _applicationData.OutputMode != OutputModeOption.None + ? new StatusItem[] + { + // Use Key.Unknown for SPACE with no delegate because ListView already + // handles SPACE + new StatusItem(Key.Unknown, "~SPACE~ Mark Item", null), + new StatusItem(Key.Enter, "~ENTER~ Accept", () => + { + if (Application.Top.MostFocused == _listView) + { + // If nothing was explicitly marked, we return the item that was selected + // when ENTER is pressed in Single mode. If something was previously selected + // (using SPACE) then honor that as the single item to return + if (_applicationData.OutputMode == OutputModeOption.Single && + _itemSource.GridViewRowList.Find(i => i.IsMarked) == null) + { + _listView.MarkUnmarkRow(); + } + Accept(); + } + else if (Application.Top.MostFocused == _filterField) + { + _listView.SetFocus(); + } + }), + new StatusItem(Key.Esc, "~ESC~ Close", () => Close()) + } + : new StatusItem[] + { + new StatusItem(Key.Esc, "~ESC~ Close", () => Close()) + } + ); + + Application.Top.Add(statusBar); + } + + private void CalculateColumnWidths(List gridHeaders) + { + _gridViewDetails.ListViewColumnWidths = new int[gridHeaders.Count]; + var listViewColumnWidths = _gridViewDetails.ListViewColumnWidths; + + for (int i = 0; i < gridHeaders.Count; i++) + { + listViewColumnWidths[i] = gridHeaders[i].Length; + } + + // calculate the width of each column based on longest string in each column for each row + foreach (var row in _applicationData.DataTable.Data) + { + int index = 0; + + // use half of the visible buffer height for the number of objects to inspect to calculate widths + foreach (var col in row.Values.Take(Application.Top.Frame.Height / 2)) + { + var len = col.Value.DisplayValue.Length; + if (len > listViewColumnWidths[index]) + { + listViewColumnWidths[index] = len; + } + + index++; + } + } + + // if the total width is wider than the usable width, remove 1 from widest column until it fits + _gridViewDetails.UsableWidth = Application.Top.Frame.Width - MARGIN_LEFT - listViewColumnWidths.Length - _gridViewDetails.ListViewOffset; + int columnWidthsSum = listViewColumnWidths.Sum(); + while (columnWidthsSum >= _gridViewDetails.UsableWidth) + { + int maxWidth = 0; + int maxIndex = 0; + for (int i = 0; i < listViewColumnWidths.Length; i++) + { + if (listViewColumnWidths[i] > maxWidth) + { + maxWidth = listViewColumnWidths[i]; + maxIndex = i; + } + } + + listViewColumnWidths[maxIndex]--; + columnWidthsSum--; + } + } + + private void AddFilter(Window win) + { + _filterLabel = new Label(FILTER_LABEL) + { +<<<<<<< HEAD + X = MARGIN_LEFT +======= + X = FILTER_LABEL_X +>>>>>>> 474826e (made column spacing tigher) + }; + + _filterField = new TextField(string.Empty) + { + X = Pos.Right(_filterLabel) + 1, + Y = Pos.Top(_filterLabel), + CanFocus = true, + Width = Dim.Fill() - _filterLabel.Text.Length + }; + + var filterErrorLabel = new Label(string.Empty) + { + X = Pos.Right(_filterLabel) + 1, + Y = Pos.Top(_filterLabel) + 1, + ColorScheme = Colors.Base, + Width = Dim.Fill() - _filterLabel.Text.Length + }; + + _filterField.TextChanged += (str) => + { + // str is the OLD value + string filterText = _filterField.Text?.ToString(); + try + { + filterErrorLabel.Text = " "; + filterErrorLabel.ColorScheme = Colors.Base; + filterErrorLabel.Redraw(filterErrorLabel.Bounds); + + List itemList = GridViewHelpers.FilterData(_itemSource.GridViewRowList, filterText); + _listView.Source = new GridViewDataSource(itemList); + } + catch (Exception ex) + { + filterErrorLabel.Text = ex.Message; + filterErrorLabel.ColorScheme = Colors.Error; + filterErrorLabel.Redraw(filterErrorLabel.Bounds); + _listView.Source = _itemSource; + } + }; + + win.Add(_filterLabel, _filterField, filterErrorLabel); + } + + private void AddHeaders(Window win, List gridHeaders) + { + var header = new Label(GridViewHelpers.GetPaddedString( + gridHeaders, + _gridViewDetails.ListViewOffset, + _gridViewDetails.ListViewColumnWidths)) + { + X = 0, + Y = 2 + }; + + win.Add(header); + + // This renders dashes under the header to make it more clear what is header and what is data + var headerLineText = new StringBuilder(); + foreach (char c in header.Text) + { + if (c.Equals(' ')) + { + headerLineText.Append(' '); + } + else + { + // When gui.cs supports text decorations, should replace this with just underlining the header + headerLineText.Append('-'); + } + } + + var headerLine = new Label(headerLineText.ToString()) + { + X = 0, + Y = 3 + }; + + win.Add(headerLine); + } + + private void LoadData() + { + var items = new List(); + int newIndex = 0; + for (int i = 0; i < _applicationData.DataTable.Data.Count; i++) + { + var dataTableRow = _applicationData.DataTable.Data[i]; + var valueList = new List(); + foreach (var dataTableColumn in _applicationData.DataTable.DataColumns) + { + string dataValue = dataTableRow.Values[dataTableColumn.ToString()].DisplayValue; + valueList.Add(dataValue); + } + + string displayString = GridViewHelpers.GetPaddedString(valueList, 0, _gridViewDetails.ListViewColumnWidths); + + items.Add(new GridViewRow + { + DisplayString = displayString, + OriginalIndex = i + }); + + newIndex++; + } + + _itemSource = new GridViewDataSource(items); + } + + private void AddRows(Window win) + { + _listView = new ListView(_itemSource) + { + X = Pos.Left(_filterLabel), + Y = Pos.Bottom(_filterLabel) + 3, // 1 for space, 1 for header, 1 for header underline + Width = Dim.Fill(2), + Height = Dim.Fill(), + AllowsMarking = _applicationData.OutputMode != OutputModeOption.None, + AllowsMultipleSelection = _applicationData.OutputMode == OutputModeOption.Multiple, + }; + + win.Add(_listView); + } + + public void Dispose() + { + if (!Console.IsInputRedirected) + { + // By emitting this, we fix two issues: + // 1. An issue where arrow keys don't work in the console because .NET + // requires application mode to support Arrow key escape sequences. + // Esc[?1h sets the cursor key to application mode + // See http://ascii-table.com/ansi-escape-sequences-vt-100.php + // 2. An issue where moving the mouse causes characters to show up because + // mouse tracking is still on. Esc[?1003l turns it off. + // See https://www.xfree86.org/current/ctlseqs.html#Mouse%20Tracking + Console.Write("\u001b[?1h\u001b[?1003l"); + } + } + } +} diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj.orig b/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj.orig new file mode 100644 index 0000000..6f48f24 --- /dev/null +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj.orig @@ -0,0 +1,26 @@ + + + + net6.0 + + + +<<<<<<< HEAD + + + +======= + + + +>>>>>>> 474826e (made column spacing tigher) + + + + + + + + + + From ef2c3847f96d1a76b237412f2490718e597a18fd Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 17 Aug 2022 14:33:09 -0700 Subject: [PATCH 24/27] removed merge artifacts --- .../ConsoleGui.cs.orig | 349 ------------------ ...oft.PowerShell.ConsoleGuiTools.csproj.orig | 26 -- 2 files changed, 375 deletions(-) delete mode 100644 src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig delete mode 100644 src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj.orig diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig deleted file mode 100644 index ff5a97b..0000000 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs.orig +++ /dev/null @@ -1,349 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NStack; -using OutGridView.Models; -using Terminal.Gui; - -namespace OutGridView.Cmdlet -{ - internal class ConsoleGui : IDisposable - { - private const string FILTER_LABEL = "Filter"; - // This adjusts the left margin of all controls -<<<<<<< HEAD - private const int MARGIN_LEFT = 2; - // Width of Terminal.Gui ListView selection/check UI elements (old == 4, new == 2) - private const int CHECK_WIDTH = 4; -======= - private const int FILTER_LABEL_X = 2; ->>>>>>> 474826e (made column spacing tigher) - private bool _cancelled; - private GridViewDataSource _itemSource; - private Label _filterLabel; - private TextField _filterField; - private ListView _listView; - private ApplicationData _applicationData; - private GridViewDetails _gridViewDetails; - - public HashSet Start(ApplicationData applicationData) - { - Application.Init(); - _applicationData = applicationData; - _gridViewDetails = new GridViewDetails - { - // If OutputMode is Single or Multiple, then we make items selectable. If we make them selectable, - // 2 columns are required for the check/selection indicator and space. -<<<<<<< HEAD - ListViewOffset = _applicationData.OutputMode != OutputModeOption.None ? MARGIN_LEFT + CHECK_WIDTH : MARGIN_LEFT -======= - ListViewOffset = _applicationData.OutputMode != OutputModeOption.None ? FILTER_LABEL_X + 2 : FILTER_LABEL_X ->>>>>>> 474826e (made column spacing tigher) - }; - - Window win = AddTopLevelWindow(); - AddStatusBar(); - - // GridView header logic - List gridHeaders = _applicationData.DataTable.DataColumns.Select((c) => c.Label).ToList(); - CalculateColumnWidths(gridHeaders); - - AddFilter(win); - AddHeaders(win, gridHeaders); - - // GridView row logic - LoadData(); - AddRows(win); - - _filterField.Text = _applicationData.Filter ?? string.Empty; - _filterField.CursorPosition = _filterField.Text.Length; - // Run the GUI. - Application.Run(); - Application.Shutdown(); - - // Return results of selection if required. - HashSet selectedIndexes = new HashSet(); - if (_cancelled) - { - return selectedIndexes; - } - - foreach (GridViewRow gvr in _itemSource.GridViewRowList) - { - if (gvr.IsMarked) - { - selectedIndexes.Add(gvr.OriginalIndex); - } - } - - return selectedIndexes; - } - - private void Accept() - { - Application.RequestStop(); - } - - private void Close() - { - _cancelled = true; - Application.RequestStop(); - } - - private Window AddTopLevelWindow() - { - // Creates the top-level window to show - var win = new Window(_applicationData.Title) - { - X = 0, - Y = 0, - // By using Dim.Fill(), it will automatically resize without manual intervention - Width = Dim.Fill(), - Height = Dim.Fill(1) - }; - - Application.Top.Add(win); - return win; - } - - private void AddStatusBar() - { - var statusBar = new StatusBar( - _applicationData.OutputMode != OutputModeOption.None - ? new StatusItem[] - { - // Use Key.Unknown for SPACE with no delegate because ListView already - // handles SPACE - new StatusItem(Key.Unknown, "~SPACE~ Mark Item", null), - new StatusItem(Key.Enter, "~ENTER~ Accept", () => - { - if (Application.Top.MostFocused == _listView) - { - // If nothing was explicitly marked, we return the item that was selected - // when ENTER is pressed in Single mode. If something was previously selected - // (using SPACE) then honor that as the single item to return - if (_applicationData.OutputMode == OutputModeOption.Single && - _itemSource.GridViewRowList.Find(i => i.IsMarked) == null) - { - _listView.MarkUnmarkRow(); - } - Accept(); - } - else if (Application.Top.MostFocused == _filterField) - { - _listView.SetFocus(); - } - }), - new StatusItem(Key.Esc, "~ESC~ Close", () => Close()) - } - : new StatusItem[] - { - new StatusItem(Key.Esc, "~ESC~ Close", () => Close()) - } - ); - - Application.Top.Add(statusBar); - } - - private void CalculateColumnWidths(List gridHeaders) - { - _gridViewDetails.ListViewColumnWidths = new int[gridHeaders.Count]; - var listViewColumnWidths = _gridViewDetails.ListViewColumnWidths; - - for (int i = 0; i < gridHeaders.Count; i++) - { - listViewColumnWidths[i] = gridHeaders[i].Length; - } - - // calculate the width of each column based on longest string in each column for each row - foreach (var row in _applicationData.DataTable.Data) - { - int index = 0; - - // use half of the visible buffer height for the number of objects to inspect to calculate widths - foreach (var col in row.Values.Take(Application.Top.Frame.Height / 2)) - { - var len = col.Value.DisplayValue.Length; - if (len > listViewColumnWidths[index]) - { - listViewColumnWidths[index] = len; - } - - index++; - } - } - - // if the total width is wider than the usable width, remove 1 from widest column until it fits - _gridViewDetails.UsableWidth = Application.Top.Frame.Width - MARGIN_LEFT - listViewColumnWidths.Length - _gridViewDetails.ListViewOffset; - int columnWidthsSum = listViewColumnWidths.Sum(); - while (columnWidthsSum >= _gridViewDetails.UsableWidth) - { - int maxWidth = 0; - int maxIndex = 0; - for (int i = 0; i < listViewColumnWidths.Length; i++) - { - if (listViewColumnWidths[i] > maxWidth) - { - maxWidth = listViewColumnWidths[i]; - maxIndex = i; - } - } - - listViewColumnWidths[maxIndex]--; - columnWidthsSum--; - } - } - - private void AddFilter(Window win) - { - _filterLabel = new Label(FILTER_LABEL) - { -<<<<<<< HEAD - X = MARGIN_LEFT -======= - X = FILTER_LABEL_X ->>>>>>> 474826e (made column spacing tigher) - }; - - _filterField = new TextField(string.Empty) - { - X = Pos.Right(_filterLabel) + 1, - Y = Pos.Top(_filterLabel), - CanFocus = true, - Width = Dim.Fill() - _filterLabel.Text.Length - }; - - var filterErrorLabel = new Label(string.Empty) - { - X = Pos.Right(_filterLabel) + 1, - Y = Pos.Top(_filterLabel) + 1, - ColorScheme = Colors.Base, - Width = Dim.Fill() - _filterLabel.Text.Length - }; - - _filterField.TextChanged += (str) => - { - // str is the OLD value - string filterText = _filterField.Text?.ToString(); - try - { - filterErrorLabel.Text = " "; - filterErrorLabel.ColorScheme = Colors.Base; - filterErrorLabel.Redraw(filterErrorLabel.Bounds); - - List itemList = GridViewHelpers.FilterData(_itemSource.GridViewRowList, filterText); - _listView.Source = new GridViewDataSource(itemList); - } - catch (Exception ex) - { - filterErrorLabel.Text = ex.Message; - filterErrorLabel.ColorScheme = Colors.Error; - filterErrorLabel.Redraw(filterErrorLabel.Bounds); - _listView.Source = _itemSource; - } - }; - - win.Add(_filterLabel, _filterField, filterErrorLabel); - } - - private void AddHeaders(Window win, List gridHeaders) - { - var header = new Label(GridViewHelpers.GetPaddedString( - gridHeaders, - _gridViewDetails.ListViewOffset, - _gridViewDetails.ListViewColumnWidths)) - { - X = 0, - Y = 2 - }; - - win.Add(header); - - // This renders dashes under the header to make it more clear what is header and what is data - var headerLineText = new StringBuilder(); - foreach (char c in header.Text) - { - if (c.Equals(' ')) - { - headerLineText.Append(' '); - } - else - { - // When gui.cs supports text decorations, should replace this with just underlining the header - headerLineText.Append('-'); - } - } - - var headerLine = new Label(headerLineText.ToString()) - { - X = 0, - Y = 3 - }; - - win.Add(headerLine); - } - - private void LoadData() - { - var items = new List(); - int newIndex = 0; - for (int i = 0; i < _applicationData.DataTable.Data.Count; i++) - { - var dataTableRow = _applicationData.DataTable.Data[i]; - var valueList = new List(); - foreach (var dataTableColumn in _applicationData.DataTable.DataColumns) - { - string dataValue = dataTableRow.Values[dataTableColumn.ToString()].DisplayValue; - valueList.Add(dataValue); - } - - string displayString = GridViewHelpers.GetPaddedString(valueList, 0, _gridViewDetails.ListViewColumnWidths); - - items.Add(new GridViewRow - { - DisplayString = displayString, - OriginalIndex = i - }); - - newIndex++; - } - - _itemSource = new GridViewDataSource(items); - } - - private void AddRows(Window win) - { - _listView = new ListView(_itemSource) - { - X = Pos.Left(_filterLabel), - Y = Pos.Bottom(_filterLabel) + 3, // 1 for space, 1 for header, 1 for header underline - Width = Dim.Fill(2), - Height = Dim.Fill(), - AllowsMarking = _applicationData.OutputMode != OutputModeOption.None, - AllowsMultipleSelection = _applicationData.OutputMode == OutputModeOption.Multiple, - }; - - win.Add(_listView); - } - - public void Dispose() - { - if (!Console.IsInputRedirected) - { - // By emitting this, we fix two issues: - // 1. An issue where arrow keys don't work in the console because .NET - // requires application mode to support Arrow key escape sequences. - // Esc[?1h sets the cursor key to application mode - // See http://ascii-table.com/ansi-escape-sequences-vt-100.php - // 2. An issue where moving the mouse causes characters to show up because - // mouse tracking is still on. Esc[?1003l turns it off. - // See https://www.xfree86.org/current/ctlseqs.html#Mouse%20Tracking - Console.Write("\u001b[?1h\u001b[?1003l"); - } - } - } -} diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj.orig b/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj.orig deleted file mode 100644 index 6f48f24..0000000 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/Microsoft.PowerShell.ConsoleGuiTools.csproj.orig +++ /dev/null @@ -1,26 +0,0 @@ - - - - net6.0 - - - -<<<<<<< HEAD - - - -======= - - - ->>>>>>> 474826e (made column spacing tigher) - - - - - - - - - - From 20ce94567b54124ecdcd27adcf8c0d9a564459a5 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 17 Aug 2022 14:33:42 -0700 Subject: [PATCH 25/27] exclude .orig files (merge artifacts) --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index cacf0ef..995941e 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,6 @@ module/ # Ignore package Microsoft.PowerShell.GraphicalTools.zip Microsoft.PowerShell.ConsoleGuiTools.zip + +# git artifacts +*.orig \ No newline at end of file From 8503cc2ee2a98b79d482b428886539fdb2b9a258 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 24 Aug 2022 20:23:29 -0600 Subject: [PATCH 26/27] Updated HelpMessages; fixed old readme contents --- README.md | 105 +++++++++++++++++- .../Out-ConsoleGridView.md | 25 ++++- .../OutConsoleGridviewCmdletCommand.cs | 10 +- 3 files changed, 124 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index b7dfbd2..70c1f64 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,109 @@ to view and filter objects graphically. ![screenshot of Out-ConsoleGridView](docs/Microsoft.PowerShell.ConsoleGuiTools/ocgv.gif) -### Examples +## Examples -Get a process ID: -```powershell -gps | ocgv -OutputMode Single +### Example 1: Output processes to a grid view + +```PowerShell +PS C:\> Get-Process | Out-ConsoleGridView +``` + +This command gets the processes running on the local computer and sends them to a grid view window. + +### Example 2: Use a variable to output processes to a grid view + +```PowerShell +PS C:\> $P = Get-Process +PS C:\> $P | Out-ConsoleGridView -OutputMode Single ``` -See the [F7 History](https://github.com/gui-cs/F7History) script to show the PowerShell command history when F7 is pressed. +This command also gets the processes running on the local computer and sends them to a grid view window. + +The first command uses the Get-Process cmdlet to get the processes on the computer and then saves the process objects in the $P variable. + +The second command uses a pipeline operator to send the $P variable to **Out-ConsoleGridView**. + +By specifying `-OutputMode Single` the grid view window will be restricted to a single selection, ensuring now more than a single object is returned. + +### Example 3: Display a formatted table in a grid view + +```PowerShell +PS C:\> Get-Process | Select-Object -Property Name, WorkingSet, PeakWorkingSet | Sort-Object -Property WorkingSet -Descending | Out-ConsoleGridView +``` + +This command displays a formatted table in a grid view window. + +It uses the Get-Process cmdlet to get the processes on the computer. + +Then, it uses a pipeline operator (|) to send the process objects to the Select-Object cmdlet. +The command uses the **Property** parameter of **Select-Object** to select the Name, WorkingSet, and PeakWorkingSet properties to be displayed in the table. + +Another pipeline operator sends the filtered objects to the Sort-Object cmdlet, which sorts them in descending order by the value of the **WorkingSet** property. + +The final part of the command uses a pipeline operator (|) to send the formatted table to **Out-ConsoleGridView**. + +You can now use the features of the grid view to search, sort, and filter the data. + +### Example 4: Save output to a variable, and then output a grid view + +```PowerShell +PS C:\> ($A = Get-ChildItem -Path $pshome -Recurse) | Out-ConsoleGridView +``` + +This command saves its output in a variable and sends it to **Out-ConsoleGridView**. + +The command uses the Get-ChildItem cmdlet to get the files in the Windows PowerShell installation directory and its subdirectories. +The path to the installation directory is saved in the $pshome automatic variable. + +The command uses the assignment operator (=) to save the output in the $A variable and the pipeline operator (|) to send the output to **Out-ConsoleGridView**. + +The parentheses in the command establish the order of operations. +As a result, the output from the Get-ChildItem command is saved in the $A variable before it is sent to **Out-ConsoleGridView**. + +### Example 5: Output processes for a specified computer to a grid view + +```PowerShell +PS C:\> Get-Process -ComputerName "Server01" | ocgv -Title "Processes - Server01" +``` + +This command displays the processes that are running on the Server01 computer in a grid view window. + +The command uses `ocgv`, which is the built-in alias for the **Out-ConsoleGridView** cmdlet, it uses the *Title* parameter to specify the window title. + +### Example 6: Define a function to kill processes using a graphical chooser + +```PowerShell +PS C:\> function killp { Get-Process | Out-ConsoleGridView -OutputMode Single -Filter $args[0] | Stop-Process -Id {$_.Id} } +PS C:\> killp note +``` +This example shows defining a function named `killp` that shows a grid view of all running processes and allows the user to select one to kill it. + +The example uses the `-Filter` paramter to filter for all proceses with a name that includes `note` (thus highlighting `Notepad` if it were running. Selecting an item in the grid view and pressing `ENTER` will kill that process. + +### Example 7: Pass multiple items through Out-ConsoleGridView + +```PowerShell +PS C:\> Get-Process | Out-ConsoleGridView -PassThru | Export-Csv -Path .\ProcessLog.csv +``` + +This command lets you select multiple processes from the **Out-ConsoleGridView** window. +The processes that you select are passed to the **Export-Csv** command and written to the ProcessLog.csv file. + +The command uses the *PassThru* parameter of **Out-ConsoleGridView**, which lets you send multiple items down the pipeline. +The *PassThru* parameter is equivalent to using the Multiple value of the *OutputMode* parameter. + +### Example 8: Use F7 as "Show Command History" + +Add [gui-cs/F7History](https://github.com/gui-cs/F7History) to your Powershell profile... + +Press `F7` to see the history for the current PowerShell instance + +Press `Shift-F7` to see the history for all PowerShell instances. + +Whatever you select within `Out-ConsoleGridView` will be inserted on your command line. + +Whatever was typed on the command line prior to hitting `F7` or `Shift-F7` will be used as a filter. ## Development diff --git a/docs/Microsoft.PowerShell.ConsoleGuiTools/Out-ConsoleGridView.md b/docs/Microsoft.PowerShell.ConsoleGuiTools/Out-ConsoleGridView.md index b0958bd..895bce4 100644 --- a/docs/Microsoft.PowerShell.ConsoleGuiTools/Out-ConsoleGridView.md +++ b/docs/Microsoft.PowerShell.ConsoleGuiTools/Out-ConsoleGridView.md @@ -3,7 +3,7 @@ external help file: ConsoleGuiToolsModule.dll-Help.xml keywords: powershell,cmdlet locale: en-us Module Name: Microsoft.PowerShell.ConsoleGuiTools -ms.date: 08/09/2019 +ms.date: 08/24/2022 schema: 2.0.0 title: Out-ConsoleGridView --- @@ -18,7 +18,7 @@ Sends output to an interactive table in the same console window. ```PowerShell Out-ConsoleGridView [-InputObject ] [-Title ] [-OutputMode {None | Single | - Multiple}] [-Filter ] [] + Multiple}] [-Filter ] [-MinUi] [] ``` ## DESCRIPTION @@ -27,7 +27,7 @@ The **Out-ConsoleGridView** cmdlet sends the output from a command to a grid vie You can use the following features of the table to examine your data: -- Quick Filter. Use the Filter box at the top of the window to search the text in the table. You can search for text in a particular column, search for literals, and search for multiple words. You can use the `-Filter` command to pre-populate the Filter box. +- Quick Filter. Use the Filter box at the top of the window to search the text in the table. You can search for text in a particular column, search for literals, and search for multiple words. You can use the `-Filter` command to pre-populate the Filter box. The filter uses regular expressions. For instructions for using these features, type `Get-Help Out-ConsoleGridView -Full` and see How to Use the Grid View Window Features in the Notes section. @@ -175,7 +175,7 @@ Accept wildcard characters: False ### -OutputMode Specifies the items that the interactive window sends down the pipeline as input to other commands. -By default, this cmdlet does not generate any output. +By default, this cmdlet generates zero, one, or many items. To send items from the interactive window down the pipeline, click to select the items (either the the mouse in terminals that support mouse or the `SPACE` key) and then press `ENTER`. `ESC` cancels. @@ -215,6 +215,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -MinUi +If specified no window frame, filter box, or status bar will be displayed in the **Out-ConsoleGridView** window. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). @@ -238,8 +253,6 @@ By default `Out-ConsoleGridView` returns objects representing the selected rows ## RELATED LINKS -[Out-GridView](Out-GridView.md) - [Out-File](Out-File.md) [Out-Printer](Out-Printer.md) diff --git a/src/Microsoft.PowerShell.ConsoleGuiTools/OutConsoleGridviewCmdletCommand.cs b/src/Microsoft.PowerShell.ConsoleGuiTools/OutConsoleGridviewCmdletCommand.cs index f4f5a9b..4eb3f12 100644 --- a/src/Microsoft.PowerShell.ConsoleGuiTools/OutConsoleGridviewCmdletCommand.cs +++ b/src/Microsoft.PowerShell.ConsoleGuiTools/OutConsoleGridviewCmdletCommand.cs @@ -29,13 +29,13 @@ public class OutConsoleGridViewCmdletCommand : PSCmdlet, IDisposable /// /// This parameter specifies the current pipeline object. /// - [Parameter(ValueFromPipeline = true)] + [Parameter(ValueFromPipeline = true, HelpMessage = "Specifies the input pipeline object")] public PSObject InputObject { get; set; } = AutomationNull.Value; /// /// Gets/sets the title of the Out-GridView window. /// - [Parameter] + [Parameter(HelpMessage = "Specifies the text that appears in the title bar of the Out-ConsoleGridView window. y default, the title bar displays the command that invokes Out-ConsoleGridView.")] [ValidateNotNullOrEmpty] public string Title { get; set; } @@ -43,19 +43,19 @@ public class OutConsoleGridViewCmdletCommand : PSCmdlet, IDisposable /// Get or sets a value indicating whether the selected items should be written to the pipeline /// and if it should be possible to select multiple or single list items. /// - [Parameter()] + [Parameter(HelpMessage = "Determines whether a single item (Single), multiple items (Multiple; default), or no items (None) will be written to the pipeline. Also determines selection behavior in the GUI.")] public OutputModeOption OutputMode { set; get; } = OutputModeOption.Multiple; /// /// gets or sets the initial value for the filter in the GUI /// - [Parameter()] + [Parameter(HelpMessage = "Pre-populates the Filter edit box, allowing filtering to be specified on the command line. The filter uses regular expressions." )] public string Filter { set; get; } /// /// gets or sets the whether "minimum UI" mode will be enabled /// - [Parameter()] + [Parameter(HelpMessage = "If specified no window frame, filter box, or status bar will be displayed in the GUI.")] public SwitchParameter MinUI { set; get; } #endregion Input Parameters From a2b50581e35d42ab5ae59bafd6c53e5da61eb202 Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Wed, 24 Aug 2022 20:37:40 -0600 Subject: [PATCH 27/27] Fixed typos in README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 70c1f64..d950cff 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ The GraphicalTools repo contains the `Out-ConsoleGridView` PowerShell Cmdlet providing console-based GUI experiences based on -[Terminal.Gui (gui.cs)](https://github.com/migueldeicaza/gui.cs). +[Terminal.Gui (gui.cs)](https://github.com/gui-cs/Terminal.Gui). _Note:_ A module named `Microsoft.PowerShell.GraphicalTools` used to be built and published out of this repo, but per [#101](https://github.com/PowerShell/GraphicalTools/issues/101) it is deprecated and unmaintained until such time that it can be rewritten on top of [.NET MAUI](https://devblogs.microsoft.com/dotnet/introducing-net-multi-platform-app-ui/). @@ -43,7 +43,7 @@ The first command uses the Get-Process cmdlet to get the processes on the comput The second command uses a pipeline operator to send the $P variable to **Out-ConsoleGridView**. -By specifying `-OutputMode Single` the grid view window will be restricted to a single selection, ensuring now more than a single object is returned. +By specifying `-OutputMode Single` the grid view window will be restricted to a single selection, ensuring no more than a single object is returned. ### Example 3: Display a formatted table in a grid view @@ -114,7 +114,7 @@ The *PassThru* parameter is equivalent to using the Multiple value of the *Outpu ### Example 8: Use F7 as "Show Command History" -Add [gui-cs/F7History](https://github.com/gui-cs/F7History) to your Powershell profile... +Add [gui-cs/F7History](https://github.com/gui-cs/F7History) to your Powershell profile. Press `F7` to see the history for the current PowerShell instance @@ -192,14 +192,14 @@ you would like to contribute code, documentation, tests, or bug reports, please read the [development section above](https://github.com/PowerShell/GraphicalTools#development) to learn more. -## (Deprecated) Microsoft.PowerShell.GraphicalTools Architecture +## Microsoft.PowerShell.ConsoleGuiTools Architecture -`GraphicalTools` consists of 2 .NET Projects: +`ConsoleGuiTools` consists of 2 .NET Projects: - ConsoleGuiTools - Cmdlet implementation for Out-ConsoleGridView - OutGridView.Models - Contains data contracts between the GUI & Cmdlet -_Note:_ Previously, GraphicalTools also included the Avalonia-based `Out-GridView` which was implemented in `.\Microsoft.PowerShell.GraphicalTools` and `.\OutGridView.Gui`. These components have been deprecated (see note above). +_Note:_ Previously, this repo included `Microsoft.PowerShell.GraphicalTools` which included the Avalonia-based `Out-GridView` (implemented in `.\Microsoft.PowerShell.GraphicalTools` and `.\OutGridView.Gui`). These components have been deprecated (see note above). ## Maintainers