explorer general touch ups- no logic change

This commit is contained in:
Jeremy Wu 2020-06-08 14:20:22 +10:00
parent 0ee0fb8d2b
commit 5d696bd3ab
12 changed files with 131 additions and 95 deletions

View file

@ -261,7 +261,7 @@ namespace Flow.Launcher.Test.Plugins
public void GivenDirectoryInfoSearch_WhenSearchPatternHotKeyIsSearchAll_ThenSearchCriteriaShouldUseCriteriaString(string path, string expectedString)
{
// Given
var criteriaConstructor = new DirectoryInfoSearch(new Settings());
var criteriaConstructor = new DirectoryInfoSearch(new PluginInitContext());
//When
var resultString = criteriaConstructor.ConstructSearchCriteria(path);

View file

@ -15,6 +15,16 @@ namespace Flow.Launcher.Plugin.Explorer
{
internal class ContextMenu : IContextMenu
{
private PluginInitContext Context { get; set; }
private Settings Settings { get; set; }
public ContextMenu(PluginInitContext context, Settings settings)
{
Context = context;
Settings = settings;
}
public List<Result> LoadContextMenus(Result selectedResult)
{
var contextMenus = new List<Result>();
@ -50,7 +60,7 @@ namespace Flow.Launcher.Plugin.Explorer
{
var message = "Fail to set text in clipboard";
LogException(message, e);
Main.Context.API.ShowMsg(message);
Context.API.ShowMsg(message);
return false;
}
},
@ -72,7 +82,7 @@ namespace Flow.Launcher.Plugin.Explorer
{
var message = $"Fail to set {fileOrFolder} in clipboard";
LogException(message, e);
Main.Context.API.ShowMsg(message);
Context.API.ShowMsg(message);
return false;
}
@ -98,7 +108,7 @@ namespace Flow.Launcher.Plugin.Explorer
{
var message = $"Fail to delete {fileOrFolder} at {record.FullPath}";
LogException(message, e);
Main.Context.API.ShowMsg(message);
Context.API.ShowMsg(message);
return false;
}
@ -121,7 +131,7 @@ namespace Flow.Launcher.Plugin.Explorer
{
var name = "Plugin: Folder";
var message = $"File not found: {e.Message}";
Main.Context.API.ShowMsg(name, message);
Context.API.ShowMsg(name, message);
}
return true;
@ -148,7 +158,7 @@ namespace Flow.Launcher.Plugin.Explorer
{
var message = $"Fail to open file at {record.FullPath}";
LogException(message, e);
Main.Context.API.ShowMsg(message);
Context.API.ShowMsg(message);
return false;
}
@ -177,7 +187,7 @@ namespace Flow.Launcher.Plugin.Explorer
{
var message = $"Fail to editor for file at {record.FullPath}";
LogException(message, e);
Main.Context.API.ShowMsg(message);
Context.API.ShowMsg(message);
return false;
}
},
@ -193,8 +203,8 @@ namespace Flow.Launcher.Plugin.Explorer
SubTitle = "Path: " + record.FullPath,
Action = _ =>
{
if(!Main.Settings.IndexSearchExcludedSubdirectoryPaths.Any(x => x.Path == record.FullPath))
Main.Settings.IndexSearchExcludedSubdirectoryPaths.Add(new FolderLink { Path = record.FullPath });
if(!Settings.IndexSearchExcludedSubdirectoryPaths.Any(x => x.Path == record.FullPath))
Settings.IndexSearchExcludedSubdirectoryPaths.Add(new FolderLink { Path = record.FullPath });
var pluginDirectory = Directory.GetParent(Assembly.GetExecutingAssembly().Location.ToString());
@ -202,10 +212,10 @@ namespace Flow.Launcher.Plugin.Explorer
Task.Run(() =>
{
Main.Context.API.ShowMsg("Excluded from Index Search", "Path: " + record.FullPath, iconPath);
Context.API.ShowMsg("Excluded from Index Search", "Path: " + record.FullPath, iconPath);
// so the new path can be persisted to storage and not wait till next ViewModel save.
Main.Context.API.SaveAppAllSettings();
Context.API.SaveAppAllSettings();
});
return false;

View file

@ -3,37 +3,36 @@ using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.ViewModels;
using Flow.Launcher.Plugin.Explorer.Views;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Controls;
namespace Flow.Launcher.Plugin.Explorer
{
public class Main : ISettingProvider, IPlugin, ISavable, IContextMenu //, IPluginI18n <=== do later
{
internal static PluginInitContext Context { get; set; }
internal PluginInitContext Context { get; set; }
internal static Settings Settings;
internal Settings Settings;
private SettingsViewModel _viewModel;
private SettingsViewModel viewModel;
private IContextMenu _contextMenu;
private IContextMenu contextMenu;
public Control CreateSettingPanel()
{
return new ExplorerSettings();
return new ExplorerSettings(viewModel);
}
public void Init(PluginInitContext context)
{
Context = context;
_viewModel = new SettingsViewModel();
Settings = _viewModel.Settings;
_contextMenu = new ContextMenu();
viewModel = new SettingsViewModel(context);
Settings = viewModel.Settings;
contextMenu = new ContextMenu(Context, Settings);
}
public List<Result> LoadContextMenus(Result selectedResult)
{
return _contextMenu.LoadContextMenus(selectedResult);
return contextMenu.LoadContextMenus(selectedResult);
}
public List<Result> Query(Query query)
@ -48,7 +47,7 @@ namespace Flow.Launcher.Plugin.Explorer
public void Save()
{
_viewModel.Save();
viewModel.Save();
}
}
}

View file

@ -10,11 +10,11 @@ namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
{
public class DirectoryInfoSearch
{
private Settings _settings;
private readonly ResultManager resultManager;
public DirectoryInfoSearch(Settings settings)
public DirectoryInfoSearch(PluginInitContext context)
{
_settings = settings;
resultManager = new ResultManager(context);
}
internal List<Result> TopLevelDirectorySearch(Query query, string search)
@ -66,11 +66,11 @@ namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
if (fileSystemInfo is System.IO.DirectoryInfo)
{
folderList.Add(ResultManager.CreateFolderResult(fileSystemInfo.Name, Constants.DefaultFolderSubtitleString, fileSystemInfo.FullName, query, true, false));
folderList.Add(resultManager.CreateFolderResult(fileSystemInfo.Name, Constants.DefaultFolderSubtitleString, fileSystemInfo.FullName, query, true, false));
}
else
{
fileList.Add(ResultManager.CreateFileResult(fileSystemInfo.FullName, query, true, false));
fileList.Add(resultManager.CreateFileResult(fileSystemInfo.FullName, query, true, false));
}
}
}

View file

@ -46,7 +46,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
return environmentVariablePath;
}
internal static List<Result> GetEnvironmentStringPathSuggestions(string querySearch, Query query)
internal static List<Result> GetEnvironmentStringPathSuggestions(string querySearch, Query query, PluginInitContext context)
{
var results = new List<Result>();
@ -62,7 +62,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
var expandedPath = environmentVariables[search];
results.Add(ResultManager.CreateFolderResult($"%{search}%", expandedPath, expandedPath, query));
results.Add(new ResultManager(context).CreateFolderResult($"%{search}%", expandedPath, expandedPath, query));
return results;
}
@ -81,7 +81,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
if (p.Key.StartsWith(search))
{
results.Add(ResultManager.CreateFolderResult($"%{p.Key}%", p.Value, p.Value, query));
results.Add(new ResultManager(context).CreateFolderResult($"%{p.Key}%", p.Value, p.Value, query));
}
}
return results;

View file

@ -10,13 +10,13 @@ namespace Flow.Launcher.Plugin.Explorer.Search.FolderLinks
{
public class QuickFolderAccess
{
internal List<Result> FolderList(Query query, List<FolderLink> folderLinks)
internal List<Result> FolderList(Query query, List<FolderLink> folderLinks, PluginInitContext context)
{
string search = query.Search.ToLower();
var userFolderLinks = folderLinks.Where(
x => x.Nickname.StartsWith(search, StringComparison.OrdinalIgnoreCase));
var results = userFolderLinks.Select(item =>
ResultManager.CreateFolderResult(item.Nickname, Constants.DefaultFolderSubtitleString, item.Path, query)).ToList();
new ResultManager(context).CreateFolderResult(item.Nickname, Constants.DefaultFolderSubtitleString, item.Path, query)).ToList();
return results;
}
}

View file

@ -1,17 +1,21 @@
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.SharedCommands;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
namespace Flow.Launcher.Plugin.Explorer.Search
{
internal static class ResultManager
public class ResultManager
{
internal static Result CreateFolderResult(string title, string subtitle, string path, Query query, bool showIndexState = false, bool windowsIndexed = false)
private readonly PluginInitContext context;
public ResultManager(PluginInitContext context)
{
this.context = context;
}
internal Result CreateFolderResult(string title, string subtitle, string path, Query query, bool showIndexState = false, bool windowsIndexed = false)
{
return new Result
{
@ -36,7 +40,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
string changeTo = path.EndsWith(Constants.DirectorySeperator) ? path : path + Constants.DirectorySeperator;
Main.Context.API.ChangeQuery(string.IsNullOrEmpty(query.ActionKeyword) ?
context.API.ChangeQuery(string.IsNullOrEmpty(query.ActionKeyword) ?
changeTo :
query.ActionKeyword + " " + changeTo);
return false;
@ -45,7 +49,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
};
}
internal static Result CreateOpenCurrentFolderResult(string path, bool windowsIndexed = false)
internal Result CreateOpenCurrentFolderResult(string path, bool windowsIndexed = false)
{
var retrievedDirectoryPath = FilesFolders.ReturnPreviousDirectoryIfIncompleteString(path);
@ -85,7 +89,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
};
}
internal static Result CreateFileResult(string filePath, Query query, bool showIndexState = false, bool windowsIndexed = false)
internal Result CreateFileResult(string filePath, Query query, bool showIndexState = false, bool windowsIndexed = false)
{
var result = new Result
{

View file

@ -1,4 +1,4 @@
using Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo;
using Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo;
using Flow.Launcher.Plugin.Explorer.Search.FolderLinks;
using Flow.Launcher.Plugin.Explorer.Search.WindowsIndex;
using Flow.Launcher.Plugin.SharedCommands;
@ -10,25 +10,29 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
public class SearchManager
{
private Settings _settings;
private PluginInitContext _context;
private readonly PluginInitContext context;
private IndexSearch _indexSearch;
private readonly IndexSearch indexSearch;
private QuickFolderAccess quickFolderAccess = new QuickFolderAccess();
private readonly QuickFolderAccess quickFolderAccess = new QuickFolderAccess();
private readonly ResultManager resultManager;
private readonly Settings settings;
public SearchManager(Settings settings, PluginInitContext context)
{
_settings = settings;
_context = context;
_indexSearch = new IndexSearch();
this.context = context;
indexSearch = new IndexSearch(context);
resultManager = new ResultManager(context);
this.settings = settings;
}
internal List<Result> Search(Query query)
{
var querySearch = query.Search;
var quickFolderLinks = quickFolderAccess.FolderList(query, _settings.QuickFolderAccessLinks);
var quickFolderLinks = quickFolderAccess.FolderList(query, settings.QuickFolderAccessLinks, context);
if (quickFolderLinks.Count > 0)
return quickFolderLinks;
@ -40,7 +44,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
if (EnvironmentVariables.IsEnvironmentVariableSearch(locationPath))
{
return EnvironmentVariables.GetEnvironmentStringPathSuggestions(locationPath, query);
return EnvironmentVariables.GetEnvironmentStringPathSuggestions(locationPath, query, context);
}
// Query is a location path with a full environment variable, eg. %appdata%\somefolder\
@ -56,7 +60,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
var useIndexSearch = UseWindowsIndexForDirectorySearch(locationPath);
results.Add(ResultManager.CreateOpenCurrentFolderResult(locationPath, useIndexSearch));
results.Add(resultManager.CreateOpenCurrentFolderResult(locationPath, useIndexSearch));
results.AddRange(TopLevelDirectorySearchBehaviour(WindowsIndexTopLevelFolderSearch,
DirectoryInfoClassSearch,
@ -69,7 +73,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
private List<Result> DirectoryInfoClassSearch(Query query, string querySearch)
{
var directoryInfoSearch = new DirectoryInfoSearch(_settings);
var directoryInfoSearch = new DirectoryInfoSearch(context);
return directoryInfoSearch.TopLevelDirectorySearch(query, querySearch);
}
@ -89,9 +93,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search
private List<Result> WindowsIndexFilesAndFoldersSearch(Query query, string querySearchString)
{
var queryConstructor = new QueryConstructor(_settings);
var queryConstructor = new QueryConstructor(settings);
return _indexSearch.WindowsIndexSearch(querySearchString,
return indexSearch.WindowsIndexSearch(querySearchString,
queryConstructor.CreateQueryHelper().ConnectionString,
queryConstructor.QueryForAllFilesAndFolders,
query);
@ -99,9 +103,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search
private List<Result> WindowsIndexTopLevelFolderSearch(Query query, string path)
{
var queryConstructor = new QueryConstructor(_settings);
var queryConstructor = new QueryConstructor(settings);
return _indexSearch.WindowsIndexSearch(path,
return indexSearch.WindowsIndexSearch(path,
queryConstructor.CreateQueryHelper().ConnectionString,
queryConstructor.QueryForTopLevelDirectorySearch,
query);
@ -109,14 +113,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search
private bool UseWindowsIndexForDirectorySearch(string locationPath)
{
if (!_settings.UseWindowsIndexForDirectorySearch)
if (!settings.UseWindowsIndexForDirectorySearch)
return false;
if (_settings.IndexSearchExcludedSubdirectoryPaths
if (settings.IndexSearchExcludedSubdirectoryPaths
.Any(x => FilesFolders.ReturnPreviousDirectoryIfIncompleteString(locationPath).StartsWith(x.Path)))
return false;
return _indexSearch.PathIsIndexed(locationPath);
return indexSearch.PathIsIndexed(locationPath);
}
}
}

View file

@ -14,14 +14,21 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
{
private readonly object _lock = new object();
public OleDbConnection conn;
private OleDbConnection conn;
public OleDbCommand command;
private OleDbCommand command;
public OleDbDataReader dataReaderResults;
private OleDbDataReader dataReaderResults;
private readonly ResultManager resultManager;
// Reserved keywords in oleDB
private string ReservedStringPattern = @"^[\/\\\$\%]+$";
private readonly string reservedStringPattern = @"^[\/\\\$\%]+$";
internal IndexSearch(PluginInitContext context)
{
resultManager = new ResultManager(context);
}
internal List<Result> ExecuteWindowsIndexSearch(string indexQueryString, string connectionString, Query query)
{
@ -71,16 +78,16 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
private Result CreateResult(string filename, string path, string fileType, Query query)
{
if (fileType == "Directory")
return ResultManager.CreateFolderResult(filename, Constants.DefaultFolderSubtitleString, path, query, true, true);
return resultManager.CreateFolderResult(filename, Constants.DefaultFolderSubtitleString, path, query, true, true);
else
{
return ResultManager.CreateFileResult(path, query, true, true);
return resultManager.CreateFileResult(path, query, true, true);
}
}
internal List<Result> WindowsIndexSearch(string searchString, string connectionString, Func<string, string> constructQuery, Query query)
{
var regexMatch = Regex.Match(searchString, ReservedStringPattern);
var regexMatch = Regex.Match(searchString, reservedStringPattern);
if (regexMatch.Success)
return new List<Result>();

View file

@ -4,13 +4,13 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
{
public class QueryConstructor
{
private Settings _settings;
private readonly Settings settings;
private const string SystemIndex = "SystemIndex";
public QueryConstructor(Settings settings)
{
_settings = settings;
this.settings = settings;
}
public CSearchQueryHelper CreateBaseQuery()
@ -18,7 +18,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
var baseQuery = CreateQueryHelper();
// Set the number of results we want. Don't set this property if all results are needed.
baseQuery.QueryMaxResults = _settings.MaxResult;
baseQuery.QueryMaxResults = settings.MaxResult;
// Set list of columns we want to display, getting the path presently
baseQuery.QuerySelectColumns = "System.FileName, System.ItemPathDisplay, System.ItemType";
@ -93,7 +93,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
///</summary>
public string QueryForTopLevelDirectorySearch(string path)
{
string query = "SELECT TOP " + _settings.MaxResult + $" {CreateBaseQuery().QuerySelectColumns} FROM {SystemIndex} WHERE ";
string query = "SELECT TOP " + settings.MaxResult + $" {CreateBaseQuery().QuerySelectColumns} FROM {SystemIndex} WHERE ";
if (path.LastIndexOf(Constants.AllFilesFolderSearchWildcard) > path.LastIndexOf(Constants.DirectorySeperator))
return query + QueryWhereRestrictionsForTopLevelDirectoryAllFilesAndFoldersSearch(path);

View file

@ -1,4 +1,5 @@
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin.Explorer.Search.FolderLinks;
using System;
using System.Collections.Generic;
using System.Text;
@ -7,19 +8,26 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
{
public class SettingsViewModel
{
private readonly PluginJsonStorage<Settings> _storage;
private readonly PluginJsonStorage<Settings> storage;
public Settings Settings { get; set; }
internal Settings Settings { get; set; }
public SettingsViewModel()
internal PluginInitContext Context { get; set; }
public SettingsViewModel(PluginInitContext context)
{
_storage = new PluginJsonStorage<Settings>();
Settings = _storage.Load();
Context = context;
storage = new PluginJsonStorage<Settings>();
Settings = storage.Load();
}
public void Save()
{
_storage.Save();
storage.Save();
}
internal void RemoveFolderLinkFromQuickFolders(FolderLink selectedRow) => Settings.QuickFolderAccessLinks.Remove(selectedRow);
internal void RemoveFolderLinkFromExcludedIndexPaths(FolderLink selectedRow) => Settings.IndexSearchExcludedSubdirectoryPaths.Remove(selectedRow);
}
}

View file

@ -1,4 +1,5 @@
using Flow.Launcher.Plugin.Explorer.Search.FolderLinks;
using Flow.Launcher.Plugin.Explorer.ViewModels;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@ -18,13 +19,16 @@ namespace Flow.Launcher.Plugin.Explorer.Views
/// </summary>
public partial class ExplorerSettings
{
public ExplorerSettings()
private readonly SettingsViewModel viewModel;
public ExplorerSettings(SettingsViewModel viewModel)
{
InitializeComponent();
lbxFolderLinks.ItemsSource = Main.Settings.QuickFolderAccessLinks;
this.viewModel = viewModel;
lbxExcludedPaths.ItemsSource = Main.Settings.IndexSearchExcludedSubdirectoryPaths;
lbxFolderLinks.ItemsSource = this.viewModel.Settings.QuickFolderAccessLinks;
lbxExcludedPaths.ItemsSource = this.viewModel.Settings.IndexSearchExcludedSubdirectoryPaths;
RefreshView();
}
@ -106,22 +110,22 @@ namespace Flow.Launcher.Plugin.Explorer.Views
if (selectedRow != null)
{
string msg = string.Format(Main.Context.API.GetTranslation("flowlauncher_plugin_folder_delete_folder_link"), selectedRow.Path);
string msg = string.Format(viewModel.Context.API.GetTranslation("flowlauncher_plugin_folder_delete_folder_link"), selectedRow.Path);
if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
if (expFolderLinks.IsExpanded)
Main.Settings.QuickFolderAccessLinks.Remove(selectedRow);
viewModel.RemoveFolderLinkFromQuickFolders(selectedRow);
if (expExcludedPaths.IsExpanded)
Main.Settings.IndexSearchExcludedSubdirectoryPaths.Remove(selectedRow);
viewModel.RemoveFolderLinkFromExcludedIndexPaths(selectedRow);
RefreshView();
}
}
else
{
string warning = Main.Context.API.GetTranslation("flowlauncher_plugin_folder_select_folder_link_warning");
string warning = viewModel.Context.API.GetTranslation("flowlauncher_plugin_folder_select_folder_link_warning");
MessageBox.Show(warning);
}
}
@ -138,13 +142,13 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
if (expFolderLinks.IsExpanded)
{
var link = Main.Settings.QuickFolderAccessLinks.First(x => x.Path == selectedRow.Path);
var link = viewModel.Settings.QuickFolderAccessLinks.First(x => x.Path == selectedRow.Path);
link.Path = folderBrowserDialog.SelectedPath;
}
if (expExcludedPaths.IsExpanded)
{
var link = Main.Settings.IndexSearchExcludedSubdirectoryPaths.First(x => x.Path == selectedRow.Path);
var link = viewModel.Settings.IndexSearchExcludedSubdirectoryPaths.First(x => x.Path == selectedRow.Path);
link.Path = folderBrowserDialog.SelectedPath;
}
}
@ -153,7 +157,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views
}
else
{
string warning = Main.Context.API.GetTranslation("flowlauncher_plugin_folder_select_folder_link_warning");
string warning = viewModel.Context.API.GetTranslation("flowlauncher_plugin_folder_select_folder_link_warning");
MessageBox.Show(warning);
}
}
@ -180,8 +184,8 @@ namespace Flow.Launcher.Plugin.Explorer.Views
if (files != null && files.Count() > 0)
{
if (expFolderLinks.IsExpanded && Main.Settings.QuickFolderAccessLinks == null)
Main.Settings.QuickFolderAccessLinks = new List<FolderLink>();
if (expFolderLinks.IsExpanded && viewModel.Settings.QuickFolderAccessLinks == null)
viewModel.Settings.QuickFolderAccessLinks = new List<FolderLink>();
foreach (string s in files)
{
@ -203,21 +207,21 @@ namespace Flow.Launcher.Plugin.Explorer.Views
private void AddFolderLink(FolderLink newFolderLink)
{
if (expFolderLinks.IsExpanded
&& !Main.Settings.QuickFolderAccessLinks.Any(x => x.Path == newFolderLink.Path))
&& !viewModel.Settings.QuickFolderAccessLinks.Any(x => x.Path == newFolderLink.Path))
{
if (Main.Settings.QuickFolderAccessLinks == null)
Main.Settings.QuickFolderAccessLinks = new List<FolderLink>();
if (viewModel.Settings.QuickFolderAccessLinks == null)
viewModel.Settings.QuickFolderAccessLinks = new List<FolderLink>();
Main.Settings.QuickFolderAccessLinks.Add(newFolderLink);
viewModel.Settings.QuickFolderAccessLinks.Add(newFolderLink);
}
if (expExcludedPaths.IsExpanded
&& !Main.Settings.IndexSearchExcludedSubdirectoryPaths.Any(x => x.Path == newFolderLink.Path))
&& !viewModel.Settings.IndexSearchExcludedSubdirectoryPaths.Any(x => x.Path == newFolderLink.Path))
{
if (Main.Settings.IndexSearchExcludedSubdirectoryPaths == null)
Main.Settings.IndexSearchExcludedSubdirectoryPaths = new List<FolderLink>();
if (viewModel.Settings.IndexSearchExcludedSubdirectoryPaths == null)
viewModel.Settings.IndexSearchExcludedSubdirectoryPaths = new List<FolderLink>();
Main.Settings.IndexSearchExcludedSubdirectoryPaths.Add(newFolderLink);
viewModel.Settings.IndexSearchExcludedSubdirectoryPaths.Add(newFolderLink);
}
}