mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge pull request #119 from Flow-Launcher/add_filecontent_search
Add file content search for Explorer plugin
This commit is contained in:
commit
87ae60d2e8
15 changed files with 367 additions and 36 deletions
|
|
@ -15,6 +15,16 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
if (Plugins.ContainsKey(metadata.ID))
|
||||
{
|
||||
var settings = Plugins[metadata.ID];
|
||||
|
||||
// TODO: Remove. This is one off for 1.2.0 release.
|
||||
// Introduced a new action keyword in Explorer, so need to update plugin setting in the UserData folder.
|
||||
// This kind of plugin meta update should be handled by a dedicated method trigger by version bump.
|
||||
if (metadata.ID == "572be03c74c642baae319fc283e561a8" && metadata.ActionKeywords.Count != settings.ActionKeywords.Count)
|
||||
settings.ActionKeywords = metadata.ActionKeywords;
|
||||
|
||||
if (string.IsNullOrEmpty(settings.Version))
|
||||
settings.Version = metadata.Version;
|
||||
|
||||
if (settings.ActionKeywords?.Count > 0)
|
||||
{
|
||||
metadata.ActionKeywords = settings.ActionKeywords;
|
||||
|
|
@ -28,6 +38,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
{
|
||||
ID = metadata.ID,
|
||||
Name = metadata.Name,
|
||||
Version = metadata.Version,
|
||||
ActionKeywords = metadata.ActionKeywords,
|
||||
Disabled = metadata.Disabled
|
||||
};
|
||||
|
|
@ -39,6 +50,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
{
|
||||
public string ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Version { get; set; }
|
||||
public List<string> ActionKeywords { get; set; } // a reference of the action keywords from plugin manager
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -184,6 +184,55 @@ namespace Flow.Launcher.Test.Plugins
|
|||
$"Actual number of results is {results.Count} {Environment.NewLine}");
|
||||
}
|
||||
|
||||
[TestCase(@"some words", @"FREETEXT('some words')")]
|
||||
public void GivenWindowsIndexSearch_WhenQueryWhereRestrictionsIsForFileContentSearch_ThenShouldReturnFreeTextString(
|
||||
string querySearchString, string expectedString)
|
||||
{
|
||||
// Given
|
||||
var queryConstructor = new QueryConstructor(new Settings());
|
||||
|
||||
//When
|
||||
var resultString = queryConstructor.QueryWhereRestrictionsForFileContentSearch(querySearchString);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(resultString == expectedString,
|
||||
$"Expected QueryWhereRestrictions string: {expectedString}{Environment.NewLine} " +
|
||||
$"Actual string was: {resultString}{Environment.NewLine}");
|
||||
}
|
||||
|
||||
[TestCase("some words", "SELECT TOP 100 System.FileName, System.ItemPathDisplay, System.ItemType " +
|
||||
"FROM SystemIndex WHERE FREETEXT('some words') AND scope='file:'")]
|
||||
public void GivenWindowsIndexSearch_WhenSearchForFileContent_ThenQueryShouldUseExpectedString(
|
||||
string userSearchString, string expectedString)
|
||||
{
|
||||
// Given
|
||||
var queryConstructor = new QueryConstructor(new Settings());
|
||||
|
||||
//When
|
||||
var resultString = queryConstructor.QueryForFileContentSearch(userSearchString);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(resultString == expectedString,
|
||||
$"Expected query string: {expectedString}{Environment.NewLine} " +
|
||||
$"Actual string was: {resultString}{Environment.NewLine}");
|
||||
}
|
||||
|
||||
public void GivenQuery_WhenActionKeywordForFileContentSearchExists_ThenFileContentSearchRequiredShouldReturnTrue()
|
||||
{
|
||||
// Given
|
||||
var query = new Query { ActionKeyword = "doc:", Search = "search term" };
|
||||
|
||||
var searchManager = new SearchManager(new Settings(), new PluginInitContext());
|
||||
|
||||
// When
|
||||
var result = searchManager.IsFileContentSearch(query.ActionKeyword);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(result,
|
||||
$"Expected True for file content search. {Environment.NewLine} " +
|
||||
$"Actual result was: {result}{Environment.NewLine}");
|
||||
}
|
||||
|
||||
[TestCase(@"c:\\", false)]
|
||||
[TestCase(@"i:\", true)]
|
||||
[TestCase(@"\c:\", false)]
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@
|
|||
<system:String x:Key="done">Done</system:String>
|
||||
<system:String x:Key="cannotFindSpecifiedPlugin">Can't find specified plugin</system:String>
|
||||
<system:String x:Key="newActionKeywordsCannotBeEmpty">New Action Keyword can't be empty</system:String>
|
||||
<system:String x:Key="newActionKeywordsHasBeenAssigned">New Action Keywords have been assigned to another plugin, please assign other new action keyword</system:String>
|
||||
<system:String x:Key="newActionKeywordsHasBeenAssigned">This new Action Keyword is already assigned to another plugin, please choose a different one</system:String>
|
||||
<system:String x:Key="success">Success</system:String>
|
||||
<system:String x:Key="actionkeyword_tips">Use * if you don't want to specify an action keyword</system:String>
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Flow.Launcher.Core\Flow.Launcher.Core.csproj" />
|
||||
<ProjectReference Include="..\..\Flow.Launcher.Infrastructure\Flow.Launcher.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
|
||||
<!--Dialogues-->
|
||||
<system:String x:Key="plugin_explorer_make_selection_warning">Please make a selection first</system:String>
|
||||
<system:String x:Key="plugin_explorer_select_folder_link_warning">Please select a folder link</system:String>
|
||||
<system:String x:Key="plugin_explorer_delete_folder_link">Are you sure you want to delete {0}?</system:String>
|
||||
<system:String x:Key="plugin_explorer_deletefilefolderconfirm">Are you sure you want to permanently delete this {0}?</system:String>
|
||||
|
|
@ -13,10 +14,12 @@
|
|||
<system:String x:Key="plugin_explorer_delete">Delete</system:String>
|
||||
<system:String x:Key="plugin_explorer_edit">Edit</system:String>
|
||||
<system:String x:Key="plugin_explorer_add">Add</system:String>
|
||||
<system:String x:Key="plugin_explorer_manageactionkeywords_header">Customise Action Keywords</system:String>
|
||||
<system:String x:Key="plugin_explorer_quickfolderaccess_header">Quick Folder Access Paths</system:String>
|
||||
<system:String x:Key="plugin_explorer_indexsearchexcludedpaths_header">Index Search Excluded Paths</system:String>
|
||||
<system:String x:Key="plugin_explorer_manageindexoptions">Indexing Options</system:String>
|
||||
|
||||
<system:String x:Key="plugin_explorer_actionkeywordview_search">Search Activation:</system:String>
|
||||
<system:String x:Key="plugin_explorer_actionkeywordview_filecontentsearch">File Content Search:</system:String>
|
||||
|
||||
<!--Plugin Infos-->
|
||||
<system:String x:Key="plugin_explorer_plugin_name">Explorer</system:String>
|
||||
|
|
|
|||
|
|
@ -36,12 +36,15 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
|
||||
var quickFolderLinks = quickFolderAccess.FolderList(query, settings.QuickFolderAccessLinks, context);
|
||||
|
||||
if (quickFolderLinks.Count > 0)
|
||||
if (quickFolderLinks.Count > 0 && query.ActionKeyword == settings.SearchActionKeyword)
|
||||
return quickFolderLinks;
|
||||
|
||||
if (string.IsNullOrEmpty(querySearch))
|
||||
return results;
|
||||
|
||||
if (IsFileContentSearch(query.ActionKeyword))
|
||||
return WindowsIndexFileContentSearch(query, querySearch);
|
||||
|
||||
var isEnvironmentVariable = EnvironmentVariables.IsEnvironmentVariableSearch(querySearch);
|
||||
|
||||
if (isEnvironmentVariable)
|
||||
|
|
@ -74,6 +77,24 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
return results;
|
||||
}
|
||||
|
||||
private List<Result> WindowsIndexFileContentSearch(Query query, string querySearchString)
|
||||
{
|
||||
var queryConstructor = new QueryConstructor(settings);
|
||||
|
||||
if (string.IsNullOrEmpty(querySearchString))
|
||||
return new List<Result>();
|
||||
|
||||
return indexSearch.WindowsIndexSearch(querySearchString,
|
||||
queryConstructor.CreateQueryHelper().ConnectionString,
|
||||
queryConstructor.QueryForFileContentSearch,
|
||||
query);
|
||||
}
|
||||
|
||||
public bool IsFileContentSearch(string actionKeyword)
|
||||
{
|
||||
return actionKeyword == settings.FileContentSearchActionKeyword;
|
||||
}
|
||||
|
||||
private List<Result> DirectoryInfoClassSearch(Query query, string querySearch)
|
||||
{
|
||||
var directoryInfoSearch = new DirectoryInfoSearch(context);
|
||||
|
|
|
|||
|
|
@ -117,5 +117,23 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
|
|||
{
|
||||
return $"scope='file:'";
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Search will be performed on all indexed file contents for the specified search keywords.
|
||||
///</summary>
|
||||
public string QueryForFileContentSearch(string userSearchString)
|
||||
{
|
||||
string query = "SELECT TOP " + settings.MaxResult + $" {CreateBaseQuery().QuerySelectColumns} FROM {SystemIndex} WHERE ";
|
||||
|
||||
return query + QueryWhereRestrictionsForFileContentSearch(userSearchString) + " AND " + QueryWhereRestrictionsForAllFilesAndFoldersSearch();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Set the required WHERE clause restriction to search within file content.
|
||||
///</summary>
|
||||
public string QueryWhereRestrictionsForFileContentSearch(string searchQuery)
|
||||
{
|
||||
return $"FREETEXT('{searchQuery}')";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,5 +17,11 @@ namespace Flow.Launcher.Plugin.Explorer
|
|||
|
||||
[JsonProperty]
|
||||
public List<FolderLink> IndexSearchExcludedSubdirectoryPaths { get; set; } = new List<FolderLink>();
|
||||
|
||||
[JsonProperty]
|
||||
public string SearchActionKeyword { get; set; } = Query.GlobalPluginWildcardSign;
|
||||
|
||||
[JsonProperty]
|
||||
public string FileContentSearchActionKeyword { get; set; } = "doc:";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using Flow.Launcher.Infrastructure.Storage;
|
||||
using Flow.Launcher.Core.Plugin;
|
||||
using Flow.Launcher.Infrastructure.Storage;
|
||||
using Flow.Launcher.Plugin.Explorer.Search;
|
||||
using Flow.Launcher.Plugin.Explorer.Search.FolderLinks;
|
||||
using System.Diagnostics;
|
||||
|
|
@ -40,5 +41,18 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
|
|||
|
||||
Process.Start(psi);
|
||||
}
|
||||
|
||||
internal void UpdateActionKeyword(string newActionKeyword, string oldActionKeyword)
|
||||
{
|
||||
PluginManager.ReplaceActionKeyword(Context.CurrentPluginMetadata.ID, oldActionKeyword, newActionKeyword);
|
||||
|
||||
if (Settings.FileContentSearchActionKeyword == oldActionKeyword)
|
||||
Settings.FileContentSearchActionKeyword = newActionKeyword;
|
||||
|
||||
if (Settings.SearchActionKeyword == oldActionKeyword)
|
||||
Settings.SearchActionKeyword = newActionKeyword;
|
||||
}
|
||||
|
||||
internal bool IsActionKeywordAlreadyAssigned(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
<Window x:Class="Flow.Launcher.Plugin.Explorer.Views.ActionKeywordSetting"
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Flow.Launcher.Plugin.Explorer.Views"
|
||||
mc:Ignorable="d"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="Action Keyword Setting" Height="200" Width="500">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="180" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Margin="20 10 10 10" FontSize="14" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left" Text="Current Action Keyword:" />
|
||||
<TextBox Name="txtCurrentActionKeyword"
|
||||
Margin="10" Grid.Row="0" Width="105" Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="1" Grid.Column="1">
|
||||
<Button Click="OnConfirmButtonClick"
|
||||
Margin="10 0 10 0" Width="80" Height="35"
|
||||
Content="OK" />
|
||||
<Button Click="OnCancelButtonClick"
|
||||
Margin="10 0 10 0" Width="80" Height="35"
|
||||
Content="Cancel" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
using Flow.Launcher.Plugin.Explorer.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Flow.Launcher.Plugin.Explorer.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ActionKeywordSetting.xaml
|
||||
/// </summary>
|
||||
public partial class ActionKeywordSetting : Window
|
||||
{
|
||||
private SettingsViewModel settingsViewModel;
|
||||
|
||||
private ActionKeywordView currentActionKeyword;
|
||||
|
||||
private List<ActionKeywordView> actionKeywordListView;
|
||||
|
||||
public ActionKeywordSetting(SettingsViewModel settingsViewModel, List<ActionKeywordView> actionKeywordListView, ActionKeywordView selectedActionKeyword)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.settingsViewModel = settingsViewModel;
|
||||
|
||||
currentActionKeyword = selectedActionKeyword;
|
||||
|
||||
txtCurrentActionKeyword.Text = selectedActionKeyword.Keyword;
|
||||
|
||||
this.actionKeywordListView = actionKeywordListView;
|
||||
}
|
||||
|
||||
private void OnConfirmButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var newActionKeyword = txtCurrentActionKeyword.Text;
|
||||
|
||||
if (string.IsNullOrEmpty(newActionKeyword))
|
||||
return;
|
||||
|
||||
if (newActionKeyword == currentActionKeyword.Keyword)
|
||||
{
|
||||
Close();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!settingsViewModel.IsActionKeywordAlreadyAssigned(newActionKeyword))
|
||||
{
|
||||
settingsViewModel.UpdateActionKeyword(newActionKeyword, currentActionKeyword.Keyword);
|
||||
|
||||
actionKeywordListView.Where(x => x.Description == currentActionKeyword.Description).FirstOrDefault().Keyword = newActionKeyword;
|
||||
|
||||
Close();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBox.Show(settingsViewModel.Context.API.GetTranslation("newActionKeywordsHasBeenAssigned"));
|
||||
}
|
||||
|
||||
private void OnCancelButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<UserControl x:Class="Flow.Launcher.Plugin.Explorer.Views.ExplorerSettings"
|
||||
<UserControl x:Class="Flow.Launcher.Plugin.Explorer.Views.ExplorerSettings"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
|
|
@ -17,6 +17,16 @@
|
|||
Text="{Binding Nickname, Mode=OneTime}"
|
||||
Margin="0,5,0,5" />
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="ListViewActionKeywords">
|
||||
<Grid>
|
||||
<TextBlock
|
||||
Text="{Binding Description, Mode=OneTime}"
|
||||
Margin="0,5,0,0" />
|
||||
<TextBlock
|
||||
Text="{Binding Keyword, Mode=OneTime}"
|
||||
Margin="150,5,0,0" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
|
|
@ -25,8 +35,14 @@
|
|||
</Grid.RowDefinitions>
|
||||
<ScrollViewer Margin="20 35 0 0" HorizontalScrollBarVisibility="Hidden" Grid.Row="0" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<Expander Name="expActionKeywords" Header="{DynamicResource plugin_explorer_manageactionkeywords_header}"
|
||||
Expanded="expActionKeywords_Click" Collapsed="expActionKeywords_Collapsed">
|
||||
<ListView x:Name="lbxActionKeywords"
|
||||
ItemTemplate="{StaticResource ListViewActionKeywords}"/>
|
||||
</Expander>
|
||||
<Expander Name="expFolderLinks" Header="{DynamicResource plugin_explorer_quickfolderaccess_header}"
|
||||
Expanded="expFolderLinks_Click" Collapsed="expFolderLinks_Click">
|
||||
Expanded="expFolderLinks_Click" Collapsed="expFolderLinks_Collapsed"
|
||||
Margin="0 10 0 0">
|
||||
<ListView
|
||||
x:Name="lbxFolderLinks" AllowDrop="True"
|
||||
Drop="lbxFolders_Drop"
|
||||
|
|
@ -34,7 +50,7 @@
|
|||
ItemTemplate="{StaticResource ListViewTemplateFolderLinks}"/>
|
||||
</Expander>
|
||||
<Expander x:Name="expExcludedPaths" Header="{DynamicResource plugin_explorer_indexsearchexcludedpaths_header}"
|
||||
Expanded="expExcludedPaths_Click" Collapsed="expExcludedPaths_Click"
|
||||
Expanded="expExcludedPaths_Click"
|
||||
Margin="0 10 0 0">
|
||||
<ListView
|
||||
x:Name="lbxExcludedPaths" AllowDrop="True"
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ namespace Flow.Launcher.Plugin.Explorer.Views
|
|||
public partial class ExplorerSettings
|
||||
{
|
||||
private readonly SettingsViewModel viewModel;
|
||||
|
||||
private List<ActionKeywordView> actionKeywordsListView;
|
||||
|
||||
public ExplorerSettings(SettingsViewModel viewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
|
@ -30,6 +33,22 @@ namespace Flow.Launcher.Plugin.Explorer.Views
|
|||
|
||||
lbxExcludedPaths.ItemsSource = this.viewModel.Settings.IndexSearchExcludedSubdirectoryPaths;
|
||||
|
||||
actionKeywordsListView = new List<ActionKeywordView>
|
||||
{
|
||||
new ActionKeywordView()
|
||||
{
|
||||
Description = viewModel.Context.API.GetTranslation("plugin_explorer_actionkeywordview_search"),
|
||||
Keyword = this.viewModel.Settings.SearchActionKeyword
|
||||
},
|
||||
new ActionKeywordView()
|
||||
{
|
||||
Description = viewModel.Context.API.GetTranslation("plugin_explorer_actionkeywordview_filecontentsearch"),
|
||||
Keyword = this.viewModel.Settings.FileContentSearchActionKeyword
|
||||
}
|
||||
};
|
||||
|
||||
lbxActionKeywords.ItemsSource = actionKeywordsListView;
|
||||
|
||||
RefreshView();
|
||||
}
|
||||
|
||||
|
|
@ -43,9 +62,14 @@ namespace Flow.Launcher.Plugin.Explorer.Views
|
|||
btnEdit.Visibility = Visibility.Hidden;
|
||||
btnAdd.Visibility = Visibility.Hidden;
|
||||
|
||||
if (expFolderLinks.IsExpanded || expExcludedPaths.IsExpanded)
|
||||
if (expFolderLinks.IsExpanded || expExcludedPaths.IsExpanded || expActionKeywords.IsExpanded)
|
||||
{
|
||||
btnAdd.Visibility = Visibility.Visible;
|
||||
if (!expActionKeywords.IsExpanded)
|
||||
btnAdd.Visibility = Visibility.Visible;
|
||||
|
||||
if (expActionKeywords.IsExpanded
|
||||
&& btnEdit.Visibility == Visibility.Hidden)
|
||||
btnEdit.Visibility = Visibility.Visible;
|
||||
|
||||
if ((lbxFolderLinks.Items.Count == 0 && lbxExcludedPaths.Items.Count == 0)
|
||||
&& btnDelete.Visibility == Visibility.Visible
|
||||
|
|
@ -77,22 +101,50 @@ namespace Flow.Launcher.Plugin.Explorer.Views
|
|||
lbxFolderLinks.Items.Refresh();
|
||||
|
||||
lbxExcludedPaths.Items.Refresh();
|
||||
|
||||
lbxActionKeywords.Items.Refresh();
|
||||
}
|
||||
|
||||
private void expActionKeywords_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (expActionKeywords.IsExpanded)
|
||||
expActionKeywords.Height = 215;
|
||||
|
||||
if (expExcludedPaths.IsExpanded)
|
||||
expExcludedPaths.IsExpanded = false;
|
||||
|
||||
if (expFolderLinks.IsExpanded)
|
||||
expFolderLinks.IsExpanded = false;
|
||||
|
||||
RefreshView();
|
||||
}
|
||||
|
||||
private void expActionKeywords_Collapsed(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!expActionKeywords.IsExpanded)
|
||||
expActionKeywords.Height = Double.NaN;
|
||||
}
|
||||
|
||||
private void expFolderLinks_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (expFolderLinks.IsExpanded)
|
||||
expFolderLinks.Height = 235;
|
||||
|
||||
if (!expFolderLinks.IsExpanded)
|
||||
expFolderLinks.Height = Double.NaN;
|
||||
expFolderLinks.Height = 215;
|
||||
|
||||
if (expExcludedPaths.IsExpanded)
|
||||
expExcludedPaths.IsExpanded = false;
|
||||
|
||||
if (expActionKeywords.IsExpanded)
|
||||
expActionKeywords.IsExpanded = false;
|
||||
|
||||
RefreshView();
|
||||
}
|
||||
|
||||
private void expFolderLinks_Collapsed(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!expFolderLinks.IsExpanded)
|
||||
expFolderLinks.Height = Double.NaN;
|
||||
}
|
||||
|
||||
private void expExcludedPaths_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (expExcludedPaths.IsExpanded)
|
||||
|
|
@ -101,6 +153,9 @@ namespace Flow.Launcher.Plugin.Explorer.Views
|
|||
if (expFolderLinks.IsExpanded)
|
||||
expFolderLinks.IsExpanded = false;
|
||||
|
||||
if (expActionKeywords.IsExpanded)
|
||||
expActionKeywords.IsExpanded = false;
|
||||
|
||||
RefreshView();
|
||||
}
|
||||
|
||||
|
|
@ -132,33 +187,46 @@ namespace Flow.Launcher.Plugin.Explorer.Views
|
|||
|
||||
private void btnEdit_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectedRow = lbxFolderLinks.SelectedItem as FolderLink ?? lbxExcludedPaths.SelectedItem as FolderLink;
|
||||
|
||||
if (selectedRow != null)
|
||||
if (lbxActionKeywords.SelectedItem is ActionKeywordView)
|
||||
{
|
||||
var folderBrowserDialog = new FolderBrowserDialog();
|
||||
folderBrowserDialog.SelectedPath = selectedRow.Path;
|
||||
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
if (expFolderLinks.IsExpanded)
|
||||
{
|
||||
var link = viewModel.Settings.QuickFolderAccessLinks.First(x => x.Path == selectedRow.Path);
|
||||
link.Path = folderBrowserDialog.SelectedPath;
|
||||
}
|
||||
var selectedActionKeyword = lbxActionKeywords.SelectedItem as ActionKeywordView;
|
||||
|
||||
if (expExcludedPaths.IsExpanded)
|
||||
{
|
||||
var link = viewModel.Settings.IndexSearchExcludedSubdirectoryPaths.First(x => x.Path == selectedRow.Path);
|
||||
link.Path = folderBrowserDialog.SelectedPath;
|
||||
}
|
||||
}
|
||||
var actionKeywordWindow = new ActionKeywordSetting(viewModel, actionKeywordsListView, selectedActionKeyword);
|
||||
|
||||
actionKeywordWindow.ShowDialog();
|
||||
|
||||
RefreshView();
|
||||
}
|
||||
else
|
||||
{
|
||||
string warning = viewModel.Context.API.GetTranslation("plugin_explorer_select_folder_link_warning");
|
||||
MessageBox.Show(warning);
|
||||
var selectedRow = lbxFolderLinks.SelectedItem as FolderLink ?? lbxExcludedPaths.SelectedItem as FolderLink;
|
||||
|
||||
if (selectedRow != null)
|
||||
{
|
||||
var folderBrowserDialog = new FolderBrowserDialog();
|
||||
folderBrowserDialog.SelectedPath = selectedRow.Path;
|
||||
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
if (expFolderLinks.IsExpanded)
|
||||
{
|
||||
var link = viewModel.Settings.QuickFolderAccessLinks.First(x => x.Path == selectedRow.Path);
|
||||
link.Path = folderBrowserDialog.SelectedPath;
|
||||
}
|
||||
|
||||
if (expExcludedPaths.IsExpanded)
|
||||
{
|
||||
var link = viewModel.Settings.IndexSearchExcludedSubdirectoryPaths.First(x => x.Path == selectedRow.Path);
|
||||
link.Path = folderBrowserDialog.SelectedPath;
|
||||
}
|
||||
}
|
||||
|
||||
RefreshView();
|
||||
}
|
||||
else
|
||||
{
|
||||
string warning = viewModel.Context.API.GetTranslation("plugin_explorer_make_selection_warning");
|
||||
MessageBox.Show(warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,4 +310,11 @@ namespace Flow.Launcher.Plugin.Explorer.Views
|
|||
viewModel.OpenWindowsIndexingOptions();
|
||||
}
|
||||
}
|
||||
|
||||
public class ActionKeywordView
|
||||
{
|
||||
public string Description { get; set; }
|
||||
|
||||
public string Keyword { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
{
|
||||
"ID": "572be03c74c642baae319fc283e561a8",
|
||||
"ActionKeyword": "*",
|
||||
"ActionKeywords": [
|
||||
"*",
|
||||
"doc:"
|
||||
],
|
||||
"Name": "Explorer",
|
||||
"Description": "Search and manage files and folders. Explorer utilises Windows Index Search",
|
||||
"Author": "Jeremy Wu",
|
||||
"Version": "1.1.0",
|
||||
"Version": "1.2.0",
|
||||
"Language": "csharp",
|
||||
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
|
||||
"ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ Flow Launcher. Dedicated to make your workflow flow more seamlessly. Aimed at be
|
|||

|
||||
|
||||
- Search everything from applications, files, bookmarks, YouTube, Twitter and more. All from the comfort of your keyboard without ever touching the mouse.
|
||||
- Search for file contents
|
||||
- Support search using environment variable paths
|
||||
- Run batch and PowerShell commands as Administrator or a different user.
|
||||
- Support languages from Chinese to Italian and more.
|
||||
|
|
|
|||
Loading…
Reference in a new issue