mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-08 20:27:36 +02:00
[PTRun][Search]Add setting to exclude files/patterns from indexer (#31459)
* Add patterns exclusion to PTRun indexer * Apply xaml styling * Fix pattern escaping issues * Add placeholder to indexer exclusion options * Add placeholder text to textboxes * Fix failing to split multiline text in indexer settings * Add placeholder text to checkbox and textbox setting * Change generated source comments to english
This commit is contained in:
@@ -24,6 +24,7 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
internal class Main : ISettingProvider, IPlugin, ISavable, IPluginI18n, IContextMenu, IDisposable, IDelayedExecutionPlugin
|
internal class Main : ISettingProvider, IPlugin, ISavable, IPluginI18n, IContextMenu, IDisposable, IDelayedExecutionPlugin
|
||||||
{
|
{
|
||||||
private const string DisableDriveDetectionWarning = nameof(DisableDriveDetectionWarning);
|
private const string DisableDriveDetectionWarning = nameof(DisableDriveDetectionWarning);
|
||||||
|
private const string ExcludedPatterns = nameof(ExcludedPatterns);
|
||||||
private static readonly IFileSystem _fileSystem = new FileSystem();
|
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||||
|
|
||||||
// This variable contains metadata about the Plugin
|
// This variable contains metadata about the Plugin
|
||||||
@@ -35,6 +36,9 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
// Contains information about the plugin stored in json format
|
// Contains information about the plugin stored in json format
|
||||||
private PluginJsonStorage<IndexerSettings> _storage;
|
private PluginJsonStorage<IndexerSettings> _storage;
|
||||||
|
|
||||||
|
// Excluded patterns settings
|
||||||
|
private List<string> _excludedPatterns = new List<string>();
|
||||||
|
|
||||||
// To access Windows Search functionalities
|
// To access Windows Search functionalities
|
||||||
private static readonly OleDBSearch _search = new OleDBSearch();
|
private static readonly OleDBSearch _search = new OleDBSearch();
|
||||||
private readonly WindowsSearchAPI _api = new WindowsSearchAPI(_search);
|
private readonly WindowsSearchAPI _api = new WindowsSearchAPI(_search);
|
||||||
@@ -61,6 +65,15 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
DisplayLabel = Properties.Resources.disable_drive_detection_warning,
|
DisplayLabel = Properties.Resources.disable_drive_detection_warning,
|
||||||
Value = false,
|
Value = false,
|
||||||
},
|
},
|
||||||
|
new PluginAdditionalOption()
|
||||||
|
{
|
||||||
|
PluginOptionType = PluginAdditionalOption.AdditionalOptionType.MultilineTextbox,
|
||||||
|
Key = ExcludedPatterns,
|
||||||
|
DisplayLabel = Properties.Resources.excluded_patterns_label,
|
||||||
|
DisplayDescription = Properties.Resources.excluded_patterns_description,
|
||||||
|
PlaceholderText = Properties.Resources.excluded_patterns_placeholder,
|
||||||
|
TextValue = string.Empty,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
private ContextMenuLoader _contextMenuLoader;
|
private ContextMenuLoader _contextMenuLoader;
|
||||||
@@ -108,7 +121,7 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
|
|
||||||
// This uses the Microsoft.Search.Interop assembly
|
// This uses the Microsoft.Search.Interop assembly
|
||||||
var searchManager = new CSearchManager();
|
var searchManager = new CSearchManager();
|
||||||
var searchResultsList = _api.Search(searchQuery, searchManager, maxCount: _settings.MaxSearchCount).ToList();
|
var searchResultsList = _api.Search(searchQuery, searchManager, excludedPatterns: _excludedPatterns, maxCount: _settings.MaxSearchCount).ToList();
|
||||||
|
|
||||||
// If the delayed execution query is not required (since the SQL query is fast) return empty results
|
// If the delayed execution query is not required (since the SQL query is fast) return empty results
|
||||||
if (searchResultsList.Count == 0 && isFullQuery)
|
if (searchResultsList.Count == 0 && isFullQuery)
|
||||||
@@ -232,9 +245,18 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
|
|
||||||
if (settings.AdditionalOptions != null)
|
if (settings.AdditionalOptions != null)
|
||||||
{
|
{
|
||||||
var option = settings.AdditionalOptions.FirstOrDefault(x => x.Key == DisableDriveDetectionWarning);
|
var driveDetectionOption = settings.AdditionalOptions.FirstOrDefault(x => x.Key == DisableDriveDetectionWarning);
|
||||||
|
|
||||||
driveDetection = option == null ? false : option.Value;
|
driveDetection = driveDetectionOption == null ? false : driveDetectionOption.Value;
|
||||||
|
|
||||||
|
var excludedPatternsOption = settings.AdditionalOptions.FirstOrDefault(x => x.Key == ExcludedPatterns);
|
||||||
|
|
||||||
|
if (excludedPatternsOption != null)
|
||||||
|
{
|
||||||
|
_excludedPatterns = excludedPatternsOption.TextValue
|
||||||
|
.Split("\r", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_driveDetection.IsDriveDetectionWarningCheckBoxSelected = driveDetection;
|
_driveDetection.IsDriveDetectionWarningCheckBoxSelected = driveDetection;
|
||||||
|
|||||||
@@ -69,6 +69,33 @@ namespace Microsoft.Plugin.Indexer.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Prevents files and folders showing up in search results if pattern is matched. Add one pattern per line..
|
||||||
|
/// </summary>
|
||||||
|
public static string excluded_patterns_description {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("excluded_patterns_description", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Excluded patterns.
|
||||||
|
/// </summary>
|
||||||
|
public static string excluded_patterns_label {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("excluded_patterns_label", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Example: *.exe.
|
||||||
|
/// </summary>
|
||||||
|
public static string excluded_patterns_placeholder {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("excluded_patterns_placeholder", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Fail to set text in clipboard.
|
/// Looks up a localized string similar to Fail to set text in clipboard.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -165,4 +165,13 @@
|
|||||||
<data name="Microsoft_plugin_indexer_run_as_user" xml:space="preserve">
|
<data name="Microsoft_plugin_indexer_run_as_user" xml:space="preserve">
|
||||||
<value>Run as different user (Ctrl+Shift+U)</value>
|
<value>Run as different user (Ctrl+Shift+U)</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="excluded_patterns_label" xml:space="preserve">
|
||||||
|
<value>Excluded patterns</value>
|
||||||
|
</data>
|
||||||
|
<data name="excluded_patterns_description" xml:space="preserve">
|
||||||
|
<value>Prevents files and folders showing up in search results if pattern is matched. Add one pattern per line.</value>
|
||||||
|
</data>
|
||||||
|
<data name="excluded_patterns_placeholder" xml:space="preserve">
|
||||||
|
<value>Example: *.exe</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -65,7 +65,7 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ModifyQueryHelper(ref ISearchQueryHelper queryHelper, string pattern)
|
public static void ModifyQueryHelper(ref ISearchQueryHelper queryHelper, string pattern, List<string> excludedPatterns = null)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(pattern);
|
ArgumentNullException.ThrowIfNull(pattern);
|
||||||
|
|
||||||
@@ -88,6 +88,35 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
|
|||||||
queryHelper.QueryWhereRestrictions += " AND Contains(System.FileName, '" + pattern + "') ";
|
queryHelper.QueryWhereRestrictions += " AND Contains(System.FileName, '" + pattern + "') ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (excludedPatterns != null)
|
||||||
|
{
|
||||||
|
foreach (string p in excludedPatterns)
|
||||||
|
{
|
||||||
|
if (p == string.Empty)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var excludedPattern = p;
|
||||||
|
|
||||||
|
excludedPattern = excludedPattern.Replace("\\", "/", StringComparison.Ordinal);
|
||||||
|
|
||||||
|
if (excludedPattern.Contains('*', StringComparison.Ordinal) || excludedPattern.Contains('?', StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
excludedPattern = excludedPattern
|
||||||
|
.Replace("%", "[%]", StringComparison.Ordinal)
|
||||||
|
.Replace("_", "[_]", StringComparison.Ordinal)
|
||||||
|
.Replace("*", "%", StringComparison.Ordinal)
|
||||||
|
.Replace("?", "_", StringComparison.Ordinal);
|
||||||
|
queryHelper.QueryWhereRestrictions += " AND System.ItemUrl NOT LIKE '%" + excludedPattern + "%' ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queryHelper.QueryWhereRestrictions += " AND NOT Contains(System.ItemUrl, '" + excludedPattern + "') ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InitQueryHelper(out ISearchQueryHelper queryHelper, ISearchManager manager, int maxCount, bool displayHiddenFiles)
|
public static void InitQueryHelper(out ISearchQueryHelper queryHelper, ISearchManager manager, int maxCount, bool displayHiddenFiles)
|
||||||
@@ -122,13 +151,14 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
|
|||||||
queryHelper.QuerySorting = "System.DateModified DESC";
|
queryHelper.QuerySorting = "System.DateModified DESC";
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<SearchResult> Search(string keyword, ISearchManager manager, string pattern = "*", int maxCount = 30)
|
public IEnumerable<SearchResult> Search(string keyword, ISearchManager manager, string pattern = "*", List<string> excludedPatterns = null, int maxCount = 30)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(manager);
|
ArgumentNullException.ThrowIfNull(manager);
|
||||||
|
excludedPatterns ??= new List<string>();
|
||||||
|
|
||||||
ISearchQueryHelper queryHelper;
|
ISearchQueryHelper queryHelper;
|
||||||
InitQueryHelper(out queryHelper, manager, maxCount, DisplayHiddenFiles);
|
InitQueryHelper(out queryHelper, manager, maxCount, DisplayHiddenFiles);
|
||||||
ModifyQueryHelper(ref queryHelper, pattern);
|
ModifyQueryHelper(ref queryHelper, pattern, excludedPatterns);
|
||||||
return ExecuteQuery(queryHelper, keyword);
|
return ExecuteQuery(queryHelper, keyword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
Combobox = 1,
|
Combobox = 1,
|
||||||
Textbox = 2,
|
Textbox = 2,
|
||||||
Numberbox = 3,
|
Numberbox = 3,
|
||||||
|
MultilineTextbox = 4,
|
||||||
CheckboxAndCombobox = 11,
|
CheckboxAndCombobox = 11,
|
||||||
CheckboxAndTextbox = 12,
|
CheckboxAndTextbox = 12,
|
||||||
CheckboxAndNumberbox = 13,
|
CheckboxAndNumberbox = 13,
|
||||||
@@ -71,6 +72,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
public int? TextBoxMaxLength { get; set; }
|
public int? TextBoxMaxLength { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value for the placeholder of a textbox.
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
|
public string PlaceholderText { get; set; }
|
||||||
|
|
||||||
public double NumberValue { get; set; }
|
public double NumberValue { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -446,6 +446,29 @@
|
|||||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||||
MaxWidth="450"
|
MaxWidth="450"
|
||||||
MaxLength="{x:Bind TextBoxMaxLength, Mode=OneWay}"
|
MaxLength="{x:Bind TextBoxMaxLength, Mode=OneWay}"
|
||||||
|
PlaceholderText="{x:Bind Path=PlaceholderText}"
|
||||||
|
Text="{x:Bind TextValue, Mode=TwoWay}" />
|
||||||
|
</tkcontrols:SettingsCard>
|
||||||
|
<!-- MultilineTextBox setting -->
|
||||||
|
<tkcontrols:SettingsCard
|
||||||
|
MinHeight="0"
|
||||||
|
Margin="56,8,45,8"
|
||||||
|
HorizontalContentAlignment="Stretch"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderThickness="0,0,0,0"
|
||||||
|
ContentAlignment="Vertical"
|
||||||
|
CornerRadius="0"
|
||||||
|
Description="{x:Bind Path=DisplayDescription}"
|
||||||
|
Header="{x:Bind Path=DisplayLabel}"
|
||||||
|
Visibility="{x:Bind Path=ShowMultilineTextBox, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
|
<TextBox
|
||||||
|
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||||
|
MinHeight="160"
|
||||||
|
AcceptsReturn="True"
|
||||||
|
PlaceholderText="{x:Bind Path=PlaceholderText}"
|
||||||
|
ScrollViewer.IsVerticalRailEnabled="True"
|
||||||
|
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
||||||
|
ScrollViewer.VerticalScrollMode="Enabled"
|
||||||
Text="{x:Bind TextValue, Mode=TwoWay}" />
|
Text="{x:Bind TextValue, Mode=TwoWay}" />
|
||||||
</tkcontrols:SettingsCard>
|
</tkcontrols:SettingsCard>
|
||||||
<!-- NumberBox setting -->
|
<!-- NumberBox setting -->
|
||||||
@@ -535,6 +558,7 @@
|
|||||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||||
MaxWidth="450"
|
MaxWidth="450"
|
||||||
MaxLength="{x:Bind TextBoxMaxLength, Mode=OneWay}"
|
MaxLength="{x:Bind TextBoxMaxLength, Mode=OneWay}"
|
||||||
|
PlaceholderText="{x:Bind Path=PlaceholderText}"
|
||||||
Text="{x:Bind TextValue, Mode=TwoWay}" />
|
Text="{x:Bind TextValue, Mode=TwoWay}" />
|
||||||
</tkcontrols:SettingsCard>
|
</tkcontrols:SettingsCard>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@@ -83,6 +83,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MultilineTextBox setting
|
||||||
|
public bool ShowMultilineTextBox => _additionalOption.PluginOptionType == PluginAdditionalOption.AdditionalOptionType.MultilineTextbox;
|
||||||
|
|
||||||
|
public string PlaceholderText => _additionalOption.PlaceholderText;
|
||||||
|
|
||||||
// NumberBox setting
|
// NumberBox setting
|
||||||
public bool ShowNumberBox => _additionalOption.PluginOptionType == PluginAdditionalOption.AdditionalOptionType.Numberbox;
|
public bool ShowNumberBox => _additionalOption.PluginOptionType == PluginAdditionalOption.AdditionalOptionType.Numberbox;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user