public SearchInfoCollection(ISearchMetadataCollection searchMetadataCollection, ISearchMetadataFactory searchMetadataFactory, IFileWatcher fileWatcher) { _metadataCollection = searchMetadataCollection; _searchMetadataFactory = searchMetadataFactory; _fileWatcher = fileWatcher; //Add a complete file display All = _fileWatcher.Latest.Index().Replay(1).RefCount(); //create a collection with 1 item, which is used to show entire file var systemSearches = new SourceCache<SearchInfo, string>(t => t.SearchText); systemSearches.AddOrUpdate(new SearchInfo("<All>", All, SearchType.All)); //create a collection of all possible user filters var userSearches = searchMetadataCollection.Metadata .Connect(meta => meta.Filter) .IgnoreUpdateWhen((current,previous)=> SearchMetadata.EffectsFilterComparer.Equals(current, previous)) .Transform(meta => { var latest = _fileWatcher.Latest .Search(meta.BuildPredicate()) .Replay(1).RefCount(); return new SearchInfo(meta.SearchText, latest, SearchType.User); }); //combine te results into a single collection Searches = systemSearches.Connect() .Or(userSearches) .AsObservableCache(); _cleanUp = new CompositeDisposable(Searches, systemSearches); }
public TailViewModelFactory([NotNull] IObjectProvider objectProvider, [NotNull] ISchedulerProvider schedulerProvider, [NotNull] IColourProvider colourProvider, [NotNull] ISearchMetadataFactory searchMetadataFactory, [NotNull] IIconProvider iconProvider, [NotNull] ITailViewStateControllerFactory tailViewStateControllerFactory, [NotNull] ITextAssociationCollection textAssociationCollection, [NotNull] IThemeProvider themeProvider) { if (objectProvider == null) throw new ArgumentNullException(nameof(objectProvider)); if (schedulerProvider == null) throw new ArgumentNullException(nameof(schedulerProvider)); if (colourProvider == null) throw new ArgumentNullException(nameof(colourProvider)); if (searchMetadataFactory == null) throw new ArgumentNullException(nameof(searchMetadataFactory)); if (iconProvider == null) throw new ArgumentNullException(nameof(iconProvider)); if (tailViewStateControllerFactory == null) throw new ArgumentNullException(nameof(tailViewStateControllerFactory)); _objectProvider = objectProvider; _schedulerProvider = schedulerProvider; _colourProvider = colourProvider; _searchMetadataFactory = searchMetadataFactory; _iconProvider = iconProvider; _tailViewStateControllerFactory = tailViewStateControllerFactory; _textAssociationCollection = textAssociationCollection; _themeProvider = themeProvider; }
public TailViewModelFactory(IObjectProvider objectProvider, ISchedulerProvider schedulerProvider, IColourProvider colourProvider, ISearchMetadataFactory searchMetadataFactory, IIconProvider iconProvider) { _objectProvider = objectProvider; _schedulerProvider = schedulerProvider; _colourProvider = colourProvider; _searchMetadataFactory = searchMetadataFactory; _iconProvider = iconProvider; }
public SearchProxyCollectionFactory([NotNull] ISearchMetadataFactory searchMetadataFactory, [NotNull] ISchedulerProvider schedulerProvider, [NotNull] IColourProvider colourProvider, [NotNull] IIconProvider iconsProvider, [NotNull] ITextAssociationCollection textAssociationCollection, [NotNull] IThemeProvider themeProvider) { SearchMetadataFactory = searchMetadataFactory ?? throw new ArgumentNullException(nameof(searchMetadataFactory)); SchedulerProvider = schedulerProvider ?? throw new ArgumentNullException(nameof(schedulerProvider)); ColourProvider = colourProvider ?? throw new ArgumentNullException(nameof(colourProvider)); IconsProvider = iconsProvider ?? throw new ArgumentNullException(nameof(iconsProvider)); TextAssociationCollection = textAssociationCollection ?? throw new ArgumentNullException(nameof(textAssociationCollection)); ThemeProvider = themeProvider ?? throw new ArgumentNullException(nameof(themeProvider)); }
public TailViewModelFactory([NotNull] IObjectProvider objectProvider, [NotNull] ISchedulerProvider schedulerProvider, [NotNull] IColourProvider colourProvider, [NotNull] ISearchMetadataFactory searchMetadataFactory, [NotNull] IIconProvider iconProvider, [NotNull] ITailViewStateControllerFactory tailViewStateControllerFactory, [NotNull] ITextAssociationCollection textAssociationCollection, [NotNull] IThemeProvider themeProvider) { if (objectProvider == null) { throw new ArgumentNullException(nameof(objectProvider)); } if (schedulerProvider == null) { throw new ArgumentNullException(nameof(schedulerProvider)); } if (colourProvider == null) { throw new ArgumentNullException(nameof(colourProvider)); } if (searchMetadataFactory == null) { throw new ArgumentNullException(nameof(searchMetadataFactory)); } if (iconProvider == null) { throw new ArgumentNullException(nameof(iconProvider)); } if (tailViewStateControllerFactory == null) { throw new ArgumentNullException(nameof(tailViewStateControllerFactory)); } _objectProvider = objectProvider; _schedulerProvider = schedulerProvider; _colourProvider = colourProvider; _searchMetadataFactory = searchMetadataFactory; _iconProvider = iconProvider; _tailViewStateControllerFactory = tailViewStateControllerFactory; _textAssociationCollection = textAssociationCollection; _themeProvider = themeProvider; }
public SearchInfoCollection(ISearchMetadataCollection searchMetadataCollection, ISearchMetadataFactory searchMetadataFactory, IColourProvider colourProvider, IEnumerable <IFileWatcher> filesWatcher, IDefaultIconSelector defaultIconSelector) { _metadataCollection = searchMetadataCollection; _searchMetadataFactory = searchMetadataFactory; _colourProvider = colourProvider; _filesWatcher = filesWatcher; _defaultIconSelector = defaultIconSelector; //Add a complete file display All = _filesWatcher.Select(t => t.Latest).Index(); //create a collection with 1 item, which is used to show entire file var systemSearches = new SourceCache <SearchInfo, string>(t => t.SearchText); systemSearches.AddOrUpdate(new SearchInfo("<All>", All, SearchType.All)); //create a collection of all possible user filters var userSearches = searchMetadataCollection.Metadata .Connect(meta => meta.Filter) .IgnoreUpdateWhen((current, previous) => SearchMetadata.EffectsFilterComparer.Equals(current, previous)) .Transform(meta => { var latest = _filesWatcher .Select(t => t.Latest) .Merge() .Search(meta.BuildPredicate()); return(new SearchInfo(meta.SearchText, latest, SearchType.User)); }); //combine te results into a single collection Searches = systemSearches.Connect() .Or(userSearches) .AsObservableCache(); _cleanUp = new CompositeDisposable(Searches, systemSearches); }
public SearchOptionsViewModel(ISearchMetadataCollection metadataCollection, ISearchMetadataFactory searchMetadataFactory, ISchedulerProvider schedulerProvider, IColourProvider colourProvider, IIconProvider iconsProvider, SearchHints searchHints) { SearchHints = searchHints; var proxyItems = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => { return(new SearchOptionsProxy(meta, colourProvider, new IconSelector(iconsProvider, schedulerProvider), m => metadataCollection.Remove(m.SearchText), iconsProvider.DefaultIconSelector, Id)); }) .SubscribeMany(so => { //when a value changes, write the original value back to the cache return(so.WhenAnyPropertyChanged() .Select(_ => (SearchMetadata)so) .Subscribe(metadataCollection.AddorUpdate)); }) .AsObservableCache(); var monitor = MonitorPositionalChanges() .Subscribe(positionChangedArgs => { positionChangedArgs.ForEach(metadataCollection.AddorUpdate); }); //load data onto grid var collection = new ObservableCollectionExtended <SearchOptionsProxy>(); var userOptions = proxyItems.Connect() .Sort(SortExpressionComparer <SearchOptionsProxy> .Ascending(proxy => proxy.Position)) .ObserveOn(schedulerProvider.MainThread) //force reset for each new or removed item dues to a bug in the underlying dragablz control which inserts in an incorrect position .Bind(collection, new ObservableCollectionAdaptor <SearchOptionsProxy, string>(0)) .DisposeMany() .Subscribe(); Data = new ReadOnlyObservableCollection <SearchOptionsProxy>(collection); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested.Subscribe(request => { schedulerProvider.Background.Schedule(() => { var meta = searchMetadataFactory.Create(request.Text, request.UseRegEx, metadataCollection.NextIndex(), false); metadataCollection.AddorUpdate(meta); }); }); _cleanUp = new CompositeDisposable(searchInvoker, userOptions, searchInvoker, monitor, SearchHints); }
public SearchInfoCollection(ICombinedSearchMetadataCollection combinedSearchMetadataCollection, ISearchMetadataFactory searchMetadataFactory, IFileWatcher fileWatcher) { _localMetadataCollection = combinedSearchMetadataCollection.Local; _combinedSearchMetadataCollection = combinedSearchMetadataCollection; _searchMetadataFactory = searchMetadataFactory; _fileWatcher = fileWatcher; var exclusionPredicate = combinedSearchMetadataCollection.Combined.Connect() .IncludeUpdateWhen((current, previous) => !SearchMetadata.EffectsFilterComparer.Equals(current, previous)) .Filter(meta => meta.IsExclusion) .ToCollection() .Select(searchMetadataItems => { Func <string, bool> predicate = null; if (searchMetadataItems.Count == 0) { return(predicate); } var predicates = searchMetadataItems.Select(meta => meta.BuildPredicate()).ToArray(); predicate = str => { return(!predicates.Any(item => item(str))); }; return(predicate); }).StartWith((Func <string, bool>)null) .Replay(1).RefCount(); All = exclusionPredicate.Select(predicate => { if (predicate == null) { return(_fileWatcher.Latest.Index()); } return(_fileWatcher.Latest.Search(predicate)); }).Switch().Replay(1).RefCount(); //create a collection with 1 item, which is used to show entire file var systemSearches = new SourceCache <SearchInfo, string>(t => t.SearchText); systemSearches.AddOrUpdate(new SearchInfo("<All>", false, All, SearchType.All)); //create a collection of all possible user filters var userSearches = combinedSearchMetadataCollection.Combined .Connect(meta => meta.Filter) .IgnoreUpdateWhen((current, previous) => SearchMetadata.EffectsFilterComparer.Equals(current, previous)) .Transform(meta => { var latest = exclusionPredicate .Select(exclpredicate => { Func <string, bool> resultingPredicate; if (exclpredicate == null) { resultingPredicate = meta.BuildPredicate(); } else { var toMatch = meta.BuildPredicate(); resultingPredicate = str => toMatch(str) && exclpredicate(str); } return(_fileWatcher.Latest.Search(resultingPredicate)); }) .Switch() .Replay(1).RefCount(); return(new SearchInfo(meta.SearchText, meta.IsGlobal, latest, SearchType.User)); }); //combine the results into a single collection Searches = systemSearches.Connect() .Or(userSearches) .AsObservableCache(); _cleanUp = new CompositeDisposable(Searches, systemSearches); }
public SearchOptionsViewModel(ICombinedSearchMetadataCollection combinedSearchMetadataCollection, ISearchProxyCollectionFactory searchProxyCollectionFactory, ISearchMetadataFactory searchMetadataFactory, ISchedulerProvider schedulerProvider, SearchHints searchHints) { SearchHints = searchHints; var global = combinedSearchMetadataCollection.Global; var local = combinedSearchMetadataCollection.Local; Action <SearchMetadata> changeScopeAction = meta => { if (meta.IsGlobal) { //make global global.Remove(meta.SearchText); var newValue = new SearchMetadata(meta, local.NextIndex(), false); local.AddorUpdate(newValue); } else { //make local local.Remove(meta.SearchText); var newValue = new SearchMetadata(meta, global.NextIndex(), true); global.AddorUpdate(newValue); } }; Local = searchProxyCollectionFactory.Create(local, Id, changeScopeAction); Global = searchProxyCollectionFactory.Create(global, Id, changeScopeAction); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested .ObserveOn(schedulerProvider.Background) .Subscribe(request => { var isGlobal = SelectedIndex == 1; var nextIndex = isGlobal ? global.NextIndex() : local.NextIndex(); var meta = searchMetadataFactory.Create(request.Text, request.UseRegEx, nextIndex, false, isGlobal); if (isGlobal) { global.AddorUpdate(meta); } else { local.AddorUpdate(meta); } }); _cleanUp = new CompositeDisposable(searchInvoker, searchInvoker, SearchHints, Global, Local); }
public SearchOptionsViewModel(ISearchMetadataCollection metadataCollection, ISearchMetadataFactory searchMetadataFactory, ISchedulerProvider schedulerProvider, IColourProvider colourProvider, IIconProvider iconsProvider, ITextAssociationCollection textAssociationCollection, SearchHints searchHints) { SearchHints = searchHints; var proxyItems = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => { return(new SearchOptionsProxy(meta, colourProvider, new IconSelector(iconsProvider, schedulerProvider), m => metadataCollection.Remove(m.SearchText), iconsProvider.DefaultIconSelector, Id)); }) .SubscribeMany(so => { //when a value changes, write the original value back to the metadata collection var anyPropertyHasChanged = so.WhenAnyPropertyChanged() .Select(_ => (SearchMetadata)so) .Subscribe(metadataCollection.AddorUpdate); //when an icon or colour has changed we need to record user choice so //the same choice can be used again var iconChanged = so.WhenValueChanged(proxy => proxy.IconKind, false).ToUnit(); var colourChanged = so.WhenValueChanged(proxy => proxy.HighlightHue, false).ToUnit(); var ignoreCaseChanged = so.WhenValueChanged(proxy => proxy.IgnoreCase, false).ToUnit(); var textAssociationChanged = iconChanged.Merge(colourChanged).Merge(ignoreCaseChanged) .Throttle(TimeSpan.FromMilliseconds(250)) .Select(_ => new TextAssociation(so.Text, so.IgnoreCase, so.UseRegex, so.HighlightHue.Swatch, so.IconKind.ToString(), so.HighlightHue.Name, DateTime.Now)) .Subscribe(textAssociationCollection.MarkAsChanged); return(new CompositeDisposable(anyPropertyHasChanged, textAssociationChanged)); }) .AsObservableCache(); var monitor = MonitorPositionalChanges() .Subscribe(metadataCollection.Add); //load data onto grid var collection = new ObservableCollectionExtended <SearchOptionsProxy>(); var userOptions = proxyItems.Connect() .Sort(SortExpressionComparer <SearchOptionsProxy> .Ascending(proxy => proxy.Position)) .ObserveOn(schedulerProvider.MainThread) //force reset for each new or removed item dues to a bug in the underlying dragablz control which inserts in an incorrect position .Bind(collection, new ObservableCollectionAdaptor <SearchOptionsProxy, string>(0)) .DisposeMany() .Subscribe(); Data = new ReadOnlyObservableCollection <SearchOptionsProxy>(collection); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested .ObserveOn(schedulerProvider.Background) .Subscribe(request => { var meta = searchMetadataFactory.Create(request.Text, request.UseRegEx, metadataCollection.NextIndex(), false); metadataCollection.AddorUpdate(meta); }); _cleanUp = new CompositeDisposable(searchInvoker, userOptions, searchInvoker, monitor, SearchHints); }
public SearchOptionsViewModel(ICombinedSearchMetadataCollection combinedSearchMetadataCollection, ISearchProxyCollectionFactory searchProxyCollectionFactory, ISearchMetadataFactory searchMetadataFactory, ISchedulerProvider schedulerProvider, SearchHints searchHints) { SearchHints = searchHints; var global = combinedSearchMetadataCollection.Global; var local = combinedSearchMetadataCollection.Local; Action<SearchMetadata> changeScopeAction = meta => { if (meta.IsGlobal) { //make global global.Remove(meta.SearchText); var newValue = new SearchMetadata(meta, local.NextIndex(),false); local.AddorUpdate(newValue); } else { //make local local.Remove(meta.SearchText); var newValue = new SearchMetadata(meta, global.NextIndex(), true); global.AddorUpdate(newValue); } }; Local = searchProxyCollectionFactory.Create(local, Id, changeScopeAction); Global = searchProxyCollectionFactory.Create(global, Id, changeScopeAction); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested .ObserveOn(schedulerProvider.Background) .Subscribe(request => { var isGlobal = SelectedIndex == 1; var nextIndex = isGlobal ? global.NextIndex() : local.NextIndex(); var meta = searchMetadataFactory.Create(request.Text, request.UseRegEx, nextIndex, false, isGlobal); if (isGlobal) { global.AddorUpdate(meta); } else { local.AddorUpdate(meta); } }); _cleanUp = new CompositeDisposable(searchInvoker, searchInvoker, SearchHints, Global, Local); }
public SearchInfoCollection(ICombinedSearchMetadataCollection combinedSearchMetadataCollection, ISearchMetadataFactory searchMetadataFactory, IFileWatcher fileWatcher) { _localMetadataCollection = combinedSearchMetadataCollection.Local; _combinedSearchMetadataCollection = combinedSearchMetadataCollection; _searchMetadataFactory = searchMetadataFactory; _fileWatcher = fileWatcher; var exclusionPredicate = combinedSearchMetadataCollection.Combined.Connect() .IncludeUpdateWhen((current, previous) => !SearchMetadata.EffectsFilterComparer.Equals(current, previous)) .Filter(meta=> meta.IsExclusion) .ToCollection() .Select(searchMetadataItems => { Func<string, bool> predicate = null; if (searchMetadataItems.Count == 0) return predicate; var predicates = searchMetadataItems.Select(meta => meta.BuildPredicate()).ToArray(); predicate = str => { return !predicates.Any(item => item(str)); }; return predicate; }).StartWith((Func<string, bool>)null) .Replay(1).RefCount(); All = exclusionPredicate.Select(predicate => { if (predicate==null) return _fileWatcher.Latest.Index(); return _fileWatcher.Latest.Search(predicate); }).Switch().Replay(1).RefCount(); //create a collection with 1 item, which is used to show entire file var systemSearches = new SourceCache<SearchInfo, string>(t => t.SearchText); systemSearches.AddOrUpdate(new SearchInfo("<All>", false, All, SearchType.All)); //create a collection of all possible user filters var userSearches = combinedSearchMetadataCollection.Combined .Connect(meta => meta.Filter) .IgnoreUpdateWhen((current,previous)=> SearchMetadata.EffectsFilterComparer.Equals(current, previous)) .Transform(meta => { var latest = exclusionPredicate .Select(exclpredicate => { Func<string, bool> resultingPredicate; if (exclpredicate == null) { resultingPredicate = meta.BuildPredicate(); } else { var toMatch = meta.BuildPredicate(); resultingPredicate = str=> toMatch(str) && exclpredicate(str); } return _fileWatcher.Latest.Search(resultingPredicate); }) .Switch() .Replay(1).RefCount(); return new SearchInfo(meta.SearchText, meta.IsGlobal, latest, SearchType.User); }); //combine te results into a single collection Searches = systemSearches.Connect() .Or(userSearches) .AsObservableCache(); _cleanUp = new CompositeDisposable(Searches, systemSearches); }
public SearchOptionsViewModel(ISearchMetadataCollection metadataCollection, ISearchMetadataFactory searchMetadataFactory, ISchedulerProvider schedulerProvider, IColourProvider colourProvider, IIconProvider iconsProvider, ITextAssociationCollection textAssociationCollection, SearchHints searchHints, IThemeProvider themeProvider) { SearchHints = searchHints; var proxyItems = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => { return new SearchOptionsProxy(meta, colourProvider, themeProvider, new IconSelector(iconsProvider, schedulerProvider), m => metadataCollection.Remove(m.SearchText), iconsProvider.DefaultIconSelector, Id); }) .SubscribeMany(so => { //when a value changes, write the original value back to the metadata collection var anyPropertyHasChanged = so.WhenAnyPropertyChanged() .Select(_ => (SearchMetadata) so) .Subscribe(metadataCollection.AddorUpdate); //when an icon or colour has changed we need to record user choice so //the same choice can be used again var iconChanged = so.WhenValueChanged(proxy => proxy.IconKind,false).ToUnit(); var colourChanged = so.WhenValueChanged(proxy => proxy.HighlightHue, false).ToUnit(); var ignoreCaseChanged = so.WhenValueChanged(proxy => proxy.IgnoreCase, false).ToUnit(); var textAssociationChanged = iconChanged.Merge(colourChanged).Merge(ignoreCaseChanged) .Throttle(TimeSpan.FromMilliseconds(250)) .Select(_=> new TextAssociation(so.Text, so.IgnoreCase, so.UseRegex, so.HighlightHue.Swatch, so.IconKind.ToString(), so.HighlightHue.Name, DateTime.Now)) .Subscribe(textAssociationCollection.MarkAsChanged); return new CompositeDisposable(anyPropertyHasChanged, textAssociationChanged); }) .AsObservableCache(); var monitor = MonitorPositionalChanges() .Subscribe(metadataCollection.Add); //load data onto grid var collection = new ObservableCollectionExtended<SearchOptionsProxy>(); var userOptions = proxyItems.Connect() .Sort(SortExpressionComparer<SearchOptionsProxy>.Ascending(proxy => proxy.Position)) .ObserveOn(schedulerProvider.MainThread) //force reset for each new or removed item dues to a bug in the underlying dragablz control which inserts in an incorrect position .Bind(collection, new ObservableCollectionAdaptor<SearchOptionsProxy, string>(0)) .DisposeMany() .Subscribe(); Data = new ReadOnlyObservableCollection<SearchOptionsProxy>(collection); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested .ObserveOn(schedulerProvider.Background) .Subscribe(request => { var meta = searchMetadataFactory.Create(request.Text, request.UseRegEx, metadataCollection.NextIndex(), false); metadataCollection.AddorUpdate(meta); }); _cleanUp = new CompositeDisposable(searchInvoker, userOptions, searchInvoker, monitor, SearchHints); }