Browse Source

QSL regex commands links (#510)

* by default starting short value with > runs as powershell

* Search with first letters of each word in ShortValue of Lookup item

* Enable searching by RegEx

* enable regex when doing ctrl + r
pull/512/merge
Joe Finney 6 months ago
committed by GitHub
parent
commit
668f8b18ca
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 14
      Text-Grab/Controls/RegExIcon.xaml
  2. 23
      Text-Grab/Controls/RegExIcon.xaml.cs
  3. 7
      Text-Grab/Models/LookupItem.cs
  4. 16
      Text-Grab/Views/QuickSimpleLookup.xaml
  5. 159
      Text-Grab/Views/QuickSimpleLookup.xaml.cs

14
Text-Grab/Controls/RegExIcon.xaml

@ -0,0 +1,14 @@
<UserControl
x:Class="Text_Grab.Controls.RegExIcon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Text_Grab.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="200"
d:DesignWidth="222"
mc:Ignorable="d">
<Viewbox>
<Path Data="M148 97L117.5 149.5L87.5 128L125 82L75 71.5L86 38.5L135.5 57.5L125 0H171.5L161 57.5L210.5 38.5L221.5 71.5L171.5 82L209 128L179 149.5L148 97Z M0 129 L75 129 L 75 204 L0 204 z" Fill="{Binding IconColor}" />
</Viewbox>
</UserControl>

23
Text-Grab/Controls/RegExIcon.xaml.cs

@ -0,0 +1,23 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Text_Grab.Controls;
public partial class RegExIcon : UserControl
{
public SolidColorBrush IconColor
{
get { return (SolidColorBrush)GetValue(IconColorProperty); }
set { SetValue(IconColorProperty, value); }
}
public static readonly DependencyProperty IconColorProperty =
DependencyProperty.Register("IconColor", typeof(SolidColorBrush), typeof(RegExIcon), new PropertyMetadata(null));
public RegExIcon()
{
DataContext = this;
InitializeComponent();
}
}

7
Text-Grab/Models/LookupItem.cs

@ -1,5 +1,6 @@
using Humanizer;
using System;
using System.Linq;
namespace Text_Grab.Models;
@ -9,6 +10,8 @@ public enum LookupItemKind
EditWindow = 1,
GrabFrame = 2,
Link = 3,
Command = 4,
Dynamic = 5,
}
public class LookupItem : IEquatable<LookupItem>
@ -26,6 +29,8 @@ public class LookupItem : IEquatable<LookupItem>
LookupItemKind.EditWindow => Wpf.Ui.Controls.SymbolRegular.Window24,
LookupItemKind.GrabFrame => Wpf.Ui.Controls.SymbolRegular.PanelBottom20,
LookupItemKind.Link => Wpf.Ui.Controls.SymbolRegular.Link24,
LookupItemKind.Command => Wpf.Ui.Controls.SymbolRegular.WindowConsole20,
LookupItemKind.Dynamic => Wpf.Ui.Controls.SymbolRegular.Flash24,
_ => Wpf.Ui.Controls.SymbolRegular.Copy20,
};
}
@ -38,6 +43,8 @@ public class LookupItem : IEquatable<LookupItem>
}
public string FirstLettersString => string.Join("", ShortValue.Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(s => s[0])).ToLower();
public LookupItem(string sv, string lv)
{
ShortValue = sv;

16
Text-Grab/Views/QuickSimpleLookup.xaml

@ -66,6 +66,22 @@
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
IsHitTestVisible="False"
Opacity="0.5" />
<ToggleButton
x:Name="RegExToggleButton"
Grid.Column="0"
Height="26"
Margin="0,0,5,0"
Padding="7,4"
HorizontalAlignment="Right"
VerticalAlignment="Center"
BorderThickness="1"
Checked="RegExToggleButton_Checked"
Style="{StaticResource ToggleSymbolButton}"
Unchecked="RegExToggleButton_Checked">
<Viewbox Width="12" Height="12">
<controls:RegExIcon IconColor="{DynamicResource TextFillColorPrimaryBrush}" />
</Viewbox>
</ToggleButton>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<controls:CollapsibleButton
x:Name="AddItemBtn"

159
Text-Grab/Views/QuickSimpleLookup.xaml.cs

@ -1,4 +1,6 @@
using Microsoft.Win32;
using CliWrap.Buffered;
using CliWrap;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -15,6 +17,7 @@ using Text_Grab.Models;
using Text_Grab.Properties;
using Text_Grab.Services;
using Text_Grab.Utilities;
using System.Text.RegularExpressions;
namespace Text_Grab.Views;
@ -56,6 +59,22 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
private static LookupItem ParseStringToLookupItem(char splitChar, string row)
{
LookupItemKind kind = LookupItemKind.Simple;
if (row.StartsWith('>'))
{
kind = LookupItemKind.Command;
}
else if (row.StartsWith("http"))
kind = LookupItemKind.Link;
else if (row.StartsWith("🔗"))
{
kind = LookupItemKind.Link;
}
else if (row.StartsWith('⚡'))
{
kind = LookupItemKind.Dynamic;
}
List<string> cells = [.. row.Split(splitChar)];
LookupItem newRow = new();
if (cells.FirstOrDefault() is string firstCell)
@ -64,6 +83,8 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
newRow.LongValue = "";
if (cells.Count > 1 && cells[1] is not null)
newRow.LongValue = string.Join(" ", cells.Skip(1).ToArray());
newRow.Kind = kind;
return newRow;
}
@ -477,6 +498,11 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
Process.Start(new ProcessStartInfo(lItem.LongValue) { UseShellExecute = true });
openedHistoryItemOrLink = true;
break;
case LookupItemKind.Command:
openedHistoryItemOrLink = await RunCli(lItem.LongValue);
break;
case LookupItemKind.Dynamic:
break;
default:
stringBuilder.AppendLine(lItem.LongValue);
break;
@ -534,6 +560,48 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
WindowUtilities.ShouldShutDown();
}
/// <summary>
///
/// </summary>
/// <param name="longValue"></param>
/// <returns>returns if output is empty or whitespace</returns>
private async Task<bool> RunCli(string longValue)
{
string[] commands = longValue.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (commands.Length == 0)
return true;
BufferedCommandResult result = await Cli.Wrap("powershell")
.WithArguments(commands)
.WithValidation(CommandResultValidation.None)
.ExecuteBufferedAsync(Encoding.UTF8);
string outputText = result.StandardOutput.Trim();
string errorText = result.StandardError.Trim();
string shortOutput = "Output";
if (string.IsNullOrWhiteSpace(outputText))
{
if (string.IsNullOrWhiteSpace(errorText))
return true;
shortOutput = "ERROR!";
outputText = errorText;
}
LookupItem newItem = new(shortOutput, outputText)
{
Kind = LookupItemKind.Simple
};
MainDataGrid.ItemsSource = null;
List<LookupItem> newItems = [newItem];
MainDataGrid.ItemsSource = newItems;
return false;
}
private async void QuickSimpleLookup_PreviewKeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
@ -606,6 +674,13 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
e.Handled = true;
}
break;
case Key.R:
if (KeyboardExtensions.IsCtrlDown())
{
RegExToggleButton.IsChecked = !RegExToggleButton.IsChecked;
e.Handled = true;
}
break;
case Key.End:
GoToEndOfMainDataGrid();
break;
@ -690,12 +765,17 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
if (sender is not TextBox searchingBox || !IsLoaded)
return;
if (string.IsNullOrEmpty(searchingBox.Text))
await ReSearch(searchingBox.Text);
}
private async Task ReSearch(string searchString)
{
if (string.IsNullOrEmpty(searchString))
SearchLabel.Visibility = Visibility.Visible;
else
SearchLabel.Visibility = Visibility.Collapsed;
if (searchingBox.Text.Contains('\t'))
if (searchString.Contains('\t'))
{
// a tab has been entered and this will be a new entry
AddItemBtn.Visibility = Visibility.Visible;
@ -707,7 +787,7 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
MainDataGrid.ItemsSource = null;
if (string.IsNullOrEmpty(searchingBox.Text))
if (string.IsNullOrEmpty(searchString))
{
MainDataGrid.ItemsSource = ItemsDictionary;
MainDataGrid.CanUserAddRows = true;
@ -719,9 +799,13 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
if (row is null)
{
MainDataGrid.UpdateLayout();
MainDataGrid.ScrollIntoView(MainDataGrid.Items[lastSelectionInt]);
await Task.Delay(lastSelectionInt > maxMsDelay ? maxMsDelay : lastSelectionInt);
row = (DataGridRow)MainDataGrid.ItemContainerGenerator.ContainerFromIndex(lastSelectionInt);
if (lastSelectionInt > -1)
{
MainDataGrid.ScrollIntoView(MainDataGrid.Items[lastSelectionInt]);
await Task.Delay(lastSelectionInt > maxMsDelay ? maxMsDelay : lastSelectionInt);
row = (DataGridRow)MainDataGrid.ItemContainerGenerator.ContainerFromIndex(lastSelectionInt);
}
}
if (row is not null)
@ -740,7 +824,55 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
else
MainDataGrid.CanUserAddRows = false;
List<string> searchArray = [.. SearchBox.Text.ToLower().Split()];
if (RegExToggleButton.IsChecked is true)
RegexSearch(searchString);
else
StandardSearch(searchString);
UpdateRowCount();
}
private void RegexSearch(string searchString)
{
Regex searchRegex;
try
{
searchRegex = new Regex(searchString, RegexOptions.IgnoreCase);
}
catch
{
RegExToggleButton.BorderBrush = Brushes.Red;
RegExToggleButton.ToolTip = "Invalid Regular Expression";
return;
}
RegExToggleButton.BorderBrush = Brushes.Transparent;
RegExToggleButton.ToolTip = "Searh using Regular Expression Syntax";
List<LookupItem> filteredList = [];
foreach (LookupItem lItem in ItemsDictionary)
{
string lItemAsString = lItem.ToString().ToLower();
if (searchRegex.IsMatch(lItemAsString)
|| lItem.FirstLettersString.Contains(SearchBox.Text.ToLower(), StringComparison.CurrentCultureIgnoreCase))
filteredList.Add(lItem);
}
MainDataGrid.ItemsSource = filteredList;
if (MainDataGrid.Items.Count > 0)
MainDataGrid.SelectedIndex = 0;
}
private void StandardSearch(string searchString)
{
RegExToggleButton.BorderBrush = Brushes.Transparent;
RegExToggleButton.ToolTip = "Searh using Regular Expression Syntax";
List<string> searchArray = [.. searchString.ToLower().Split()];
searchArray.Sort();
List<LookupItem> filteredList = [];
@ -756,7 +888,8 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
matchAllSearchWords = false;
}
if (matchAllSearchWords)
if (matchAllSearchWords
|| lItem.FirstLettersString.Contains(SearchBox.Text.ToLower(), StringComparison.CurrentCultureIgnoreCase))
filteredList.Add(lItem);
}
@ -764,8 +897,6 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
if (MainDataGrid.Items.Count > 0)
MainDataGrid.SelectedIndex = 0;
UpdateRowCount();
}
private void TextGrabSettingsMenuItem_Click(object sender, RoutedEventArgs e)
@ -915,5 +1046,11 @@ public partial class QuickSimpleLookup : Wpf.Ui.Controls.FluentWindow
break;
}
}
private async void RegExToggleButton_Checked(object sender, RoutedEventArgs e)
{
await ReSearch(SearchBox.Text);
}
#endregion Methods
}
Loading…
Cancel
Save