public void SetUp() { XmlCompletionDataProvider completionDataProvider = new XmlCompletionDataProvider(new XmlSchemaCompletionDataCollection(), null, String.Empty); treeViewContainerControl = new XmlTreeViewContainerControl(); treeView = treeViewContainerControl.TreeView; treeViewContainerControl.LoadXml(GetXml(), completionDataProvider); doc = treeViewContainerControl.Document; clipboardHandler = treeViewContainerControl as IClipboardHandler; htmlElement = doc.DocumentElement; bodyElement = htmlElement.FirstChild as XmlElement; paragraphElement = bodyElement.SelectSingleNode("p") as XmlElement; paragraphText = paragraphElement.SelectSingleNode("text()") as XmlText; bodyComment = bodyElement.SelectSingleNode("comment()") as XmlComment; htmlTreeNode = treeView.Nodes[0] as XmlElementTreeNode; htmlTreeNode.PerformInitialization(); bodyTreeNode = htmlTreeNode.FirstNode as XmlElementTreeNode; bodyTreeNode.PerformInitialization(); bodyCommentTreeNode = bodyTreeNode.FirstNode as XmlCommentTreeNode; paragraphTreeNode = bodyTreeNode.LastNode as XmlElementTreeNode; paragraphTreeNode.PerformInitialization(); paragraphTextTreeNode = paragraphTreeNode.FirstNode as XmlTextTreeNode; }
protected void OnUpdateSelectAll(CommandInfo info) { IClipboardHandler handler = GetContent <IClipboardHandler> (); if (handler != null) { info.Enabled = handler.EnableSelectAll; } else { info.Bypass = true; } }
protected void OnUpdatePaste(CommandInfo info) { IClipboardHandler handler = GetContent <IClipboardHandler> (); if (handler != null && handler.EnablePaste) { info.Enabled = true; } else { info.Bypass = true; } }
public void ResetHandler(object handler) { hUndo = handler as IUndoHandler; hClip = handler as IClipboardHandler; hDelete = handler as IDeleteHandler; hSelectAll = handler as ISelectAllHandler; hFind = handler as IFindReplaceHandler; this.menuUndo.Tag = hUndo != null; this.menuRedo.Tag = hUndo != null; this.menuCut.Tag = hClip != null; this.menuCopy.Tag = hClip != null; this.menuPaste.Tag = hClip != null; this.menuDelete.Tag = hDelete != null; this.menuSelectAll.Tag = hSelectAll != null; this.menuFind.Tag = hFind != null; this.menuReplace.Tag = hFind != null; }
public override void Run() { if (IsEnabled) { if (Owner is ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.SharpDevelopTextAreaControl) { ((ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.SharpDevelopTextAreaControl)Owner).ActiveTextAreaControl.TextArea.ClipboardHandler.Paste(null, null); return; } IWorkbenchWindow window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow; IClipboardHandler editable = window != null ? window.ActiveViewContent as IClipboardHandler : null; if (editable != null) { editable.Paste(); } } }
public void SetUp() { MockOpenedFile openedFile = new MockOpenedFile("test.xml"); XmlSchemaCompletionCollection schemas = new XmlSchemaCompletionCollection(); xmlView = new MockXmlViewContent(openedFile); view = new XmlTreeView(xmlView, schemas, null); treeViewContainer = (XmlTreeViewContainerControl)view.Control; treeView = treeViewContainer.TreeView; clipboardHandler = view as IClipboardHandler; xmlView.GetDocumentForFile(null).Text = "<html><body><p></p></body></html>"; openedFile.SwitchToView(view); htmlTreeNode = treeView.Nodes[0] as XmlElementTreeNode; htmlTreeNode.PerformInitialization(); bodyTreeNode = htmlTreeNode.Nodes[0] as XmlElementTreeNode; bodyTreeNode.PerformInitialization(); paragraphTreeNode = bodyTreeNode.Nodes[0] as XmlElementTreeNode; treeView.SelectedNode = null; }
protected void OnUpdateSelectAll(CommandInfo info) { bool inWpf = false; #if WIN32 if (System.Windows.Input.Keyboard.FocusedElement != null) { inWpf = true; } #endif IClipboardHandler handler = GetContent <IClipboardHandler> (); if (!inWpf && handler != null) { info.Enabled = handler.EnableSelectAll; } else { info.Bypass = true; } }
public void SetUp() { MockOpenedFile openedFile = new MockOpenedFile("test.xml"); XmlSchemaCompletionDataCollection schemas = new XmlSchemaCompletionDataCollection(); xmlView = new XmlView(new DefaultTextEditorProperties(), schemas); xmlView.SetPrimaryFileUnitTestMode(openedFile); view = new XmlTreeView(xmlView, null, null); treeViewContainer = (XmlTreeViewContainerControl)view.Control; treeView = treeViewContainer.TreeView; clipboardHandler = view as IClipboardHandler; xmlView.XmlEditor.Text = "<html><body><p></p></body></html>"; openedFile.SwitchToView(view); htmlTreeNode = treeView.Nodes[0] as XmlElementTreeNode; htmlTreeNode.PerformInitialization(); bodyTreeNode = htmlTreeNode.Nodes[0] as XmlElementTreeNode; bodyTreeNode.PerformInitialization(); paragraphTreeNode = bodyTreeNode.Nodes[0] as XmlElementTreeNode; treeView.SelectedNode = null; }
private void UpdateMenuStates() { closeToolStripMenuItem.Enabled = sandDockManager.ActiveTabbedDocument != null; IUndoRedoHandler undoRedoHandler = GetHandler <IUndoRedoHandler>(); undoToolStripMenuItem.Enabled = undoRedoHandler != null && undoRedoHandler.CanUndo(); redoToolStripMenuItem.Enabled = undoRedoHandler != null && undoRedoHandler.CanRedo(); undoToolStripButton.Enabled = undoRedoHandler != null && undoRedoHandler.CanUndo(); redoToolStripButton.Enabled = undoRedoHandler != null && undoRedoHandler.CanRedo(); IClipboardHandler clipboardHandler = GetHandler <IClipboardHandler>(); cutToolStripMenuItem.Enabled = clipboardHandler != null && clipboardHandler.HasSelection && !clipboardHandler.IsReadOnly; copyToolStripMenuItem.Enabled = clipboardHandler != null && clipboardHandler.HasSelection; pasteToolStripMenuItem.Enabled = clipboardHandler != null && !clipboardHandler.IsReadOnly; deleteToolStripMenuItem.Enabled = clipboardHandler != null && clipboardHandler.HasSelection && !clipboardHandler.IsReadOnly; selectAllToolStripMenuItem.Enabled = clipboardHandler != null; cutToolStripButton.Enabled = clipboardHandler != null && clipboardHandler.HasSelection && !clipboardHandler.IsReadOnly; copyToolStripButton.Enabled = clipboardHandler != null && clipboardHandler.HasSelection; pasteToolStripButton.Enabled = clipboardHandler != null && !clipboardHandler.IsReadOnly; IQueryHandler queryHandler = GetHandler <IQueryHandler>(); importTestDefinitionToolStripMenuItem.Enabled = queryHandler != null; exportTestDefinitionToolStripMenuItem.Enabled = queryHandler != null; executeToolStripMenuItem.Enabled = queryHandler != null; explainToolStripMenuItem.Enabled = queryHandler != null; executeToolStripButton.Enabled = queryHandler != null; explainQueryToolStripButton.Enabled = queryHandler != null; saveResultsToolStripButton.Enabled = queryHandler != null; IIntelliSenseHandler intelliSenseHandler = GetHandler <IIntelliSenseHandler>(); listMembersToolStripMenuItem.Enabled = intelliSenseHandler != null; parameterInfoToolStripMenuItem.Enabled = intelliSenseHandler != null; completeWordToolStripMenuItem.Enabled = intelliSenseHandler != null; }
public void SetUp() { treeViewContainerControl = new DerivedXmlTreeViewContainerControl(); treeView = treeViewContainerControl.TreeView; treeViewContainerControl.LoadXml(GetXml()); doc = treeViewContainerControl.Document; clipboardHandler = treeViewContainerControl as IClipboardHandler; htmlElement = doc.DocumentElement; bodyElement = htmlElement.FirstChild as XmlElement; paragraphElement = bodyElement.SelectSingleNode("p") as XmlElement; paragraphText = paragraphElement.SelectSingleNode("text()") as XmlText; bodyComment = bodyElement.SelectSingleNode("comment()") as XmlComment; htmlTreeNode = treeView.Nodes[0] as XmlElementTreeNode; htmlTreeNode.PerformInitialization(); bodyTreeNode = htmlTreeNode.FirstNode as XmlElementTreeNode; bodyTreeNode.PerformInitialization(); bodyCommentTreeNode = bodyTreeNode.FirstNode as XmlCommentTreeNode; paragraphTreeNode = bodyTreeNode.LastNode as XmlElementTreeNode; paragraphTreeNode.PerformInitialization(); paragraphTextTreeNode = paragraphTreeNode.FirstNode as XmlTextTreeNode; }
protected abstract bool GetEnabled(IClipboardHandler editable);
public TailViewModel([NotNull] ILogger logger, [NotNull] ISchedulerProvider schedulerProvider, [NotNull] IEnumerable <IFileWatcher> fileWatcher, [NotNull] ISelectionMonitor selectionMonitor, [NotNull] IClipboardHandler clipboardHandler, [NotNull] ISearchInfoCollection searchInfoCollection, [NotNull] IInlineViewerFactory inlineViewerFactory, [NotNull] ISetting <GeneralOptions> generalOptions, [NotNull] ISearchMetadataCollection searchMetadataCollection, [NotNull] SearchOptionsViewModel searchOptionsViewModel, [NotNull] SearchHints searchHints) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } if (schedulerProvider == null) { throw new ArgumentNullException(nameof(schedulerProvider)); } if (fileWatcher == null) { throw new ArgumentNullException(nameof(fileWatcher)); } if (selectionMonitor == null) { throw new ArgumentNullException(nameof(selectionMonitor)); } if (clipboardHandler == null) { throw new ArgumentNullException(nameof(clipboardHandler)); } if (searchInfoCollection == null) { throw new ArgumentNullException(nameof(searchInfoCollection)); } if (inlineViewerFactory == null) { throw new ArgumentNullException(nameof(inlineViewerFactory)); } if (generalOptions == null) { throw new ArgumentNullException(nameof(generalOptions)); } if (searchMetadataCollection == null) { throw new ArgumentNullException(nameof(searchMetadataCollection)); } if (searchOptionsViewModel == null) { throw new ArgumentNullException(nameof(searchOptionsViewModel)); } if (searchHints == null) { throw new ArgumentNullException(nameof(searchHints)); } _stateProvider = new TailViewPersister(this); var enumerable = fileWatcher as IFileWatcher[] ?? fileWatcher.ToArray(); Names = enumerable.Select(t => t.FullName); SelectionMonitor = selectionMonitor; SearchOptions = searchOptionsViewModel; SearchHints = searchHints; SearchCollection = new SearchCollection(searchInfoCollection, schedulerProvider); CopyToClipboardCommand = new Command(() => clipboardHandler.WriteToClipboard(selectionMonitor.GetSelectedText())); OpenFileCommand = new Command(() => Process.Start(enumerable[0].FullName)); OpenFolderCommand = new Command(() => Process.Start(enumerable[0].Folder)); UsingDarkTheme = generalOptions.Value .ObserveOn(schedulerProvider.MainThread) .Select(options => options.Theme == Theme.Dark) .ForBinding(); HighlightTail = generalOptions.Value .ObserveOn(schedulerProvider.MainThread) .Select(options => options.HighlightTail) .ForBinding(); HighlightDuration = generalOptions.Value .ObserveOn(schedulerProvider.MainThread) .Select(options => new Duration(TimeSpan.FromSeconds(options.HighlightDuration))) .ForBinding(); //An observable which acts as a scroll command var autoChanged = this.WhenValueChanged(vm => vm.AutoTail); var scroller = _userScrollRequested.CombineLatest(autoChanged, (user, auto) => { var mode = AutoTail ? ScrollReason.Tail : ScrollReason.User; return(new ScrollRequest(mode, user.PageSize, user.FirstIndex)); }) .Do(x => logger.Info("Scrolling to {0}/{1}", x.FirstIndex, x.PageSize)) .DistinctUntilChanged(); FileStatus = enumerable .Select(t => t.Status) .Merge() .Scan(default(FileStatus), (status, fileStatus) => status | fileStatus) .ForBinding(); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested.Subscribe( request => { searchInfoCollection.Add(request.Text, request.UseRegEx); }); //User feedback to show file size FileSizeText = enumerable .Select(t => t.Latest) .Merge() .Select(t => t.Size) .Scan(0f, (previousSize, currentSize) => previousSize + currentSize / 2f) .Select(t => ((long)t).FormatWithAbbreviation()) .DistinctUntilChanged() .ForBinding(); //tailer is the main object used to tail, scroll and filter in a file var lineScroller = new LineScroller(SearchCollection.Latest.ObserveOn(schedulerProvider.Background), scroller); //load lines into observable collection var lineProxyFactory = new LineProxyFactory(new TextFormatter(searchMetadataCollection), new LineMatches(searchMetadataCollection)); var loader = lineScroller.Lines.Connect() .RecordChanges(logger, "Received") .Transform(lineProxyFactory.Create, new ParallelisationOptions(ParallelType.Ordered, 3)) .Sort(SortExpressionComparer <LineProxy> .Ascending(proxy => proxy)) .ObserveOn(schedulerProvider.MainThread) .Bind(out _data, 100) .DisposeMany() .LogErrors(logger) .Subscribe(); //monitor matching lines and start index, Count = searchInfoCollection.All .GroupBy(t => t) .Select(groupedProvider => groupedProvider.Key.Count) .Scan(0, (i, providerCount) => i + providerCount) .ForBinding(); CountText = searchInfoCollection.All .GroupBy(t => t) .Select(groupedProvider => groupedProvider.Key.Count) .Scan(0, (i, providerCount) => i + providerCount) .Select(latestCount => $"{latestCount.ToString("##,###")} lines") .ForBinding(); //iterate over every items to evaluate the lines' count LatestCount = SearchCollection.Latest .GroupBy(t => t) .Do(Console.WriteLine) .Scan(0, (acc, provider) => { if (provider.Key is IndexCollection && provider.Key.NumberOfPreviousProvider == 0) { acc = 0; } else if (provider.Key is FileSearchResult && provider.Key.NumberOfPreviousProvider == 0) { acc = 0; } return(provider.Key.Count + acc); }) .ForBinding(); ////track first visible index var firstIndexMonitor = lineScroller.Lines.Connect() .Buffer(TimeSpan.FromMilliseconds(25)).FlattenBufferResult() .ToCollection() .Select(lines => lines.Count == 0 ? 0 : lines.Select(l => l.Index).Max() - lines.Count + 1) .ObserveOn(schedulerProvider.MainThread) .Subscribe(first => { FirstIndex = first; }); //Create objects required for inline viewing var isUserDefinedChanged = SearchCollection.WhenValueChanged(sc => sc.Selected) .Where(selected => selected != null) .Select(selected => selected.IsUserDefined) .DistinctUntilChanged() .Replay(1) .RefCount(); var inlineViewerVisible = isUserDefinedChanged.CombineLatest(this.WhenValueChanged(vm => vm.ShowInline), (userDefined, showInline) => userDefined && showInline); CanViewInline = isUserDefinedChanged.ForBinding(); InlineViewerVisible = inlineViewerVisible.ForBinding(); //return an empty line provider unless user is viewing inline - this saves needless trips to the file var inline = searchInfoCollection.All.CombineLatest(inlineViewerVisible, (index, ud) => ud ? index : new EmptyLineProvider()); var firstVisibleRow = _data.ToObservableChangeSet().ToCollection() .Select(collection => collection.FirstOrDefault()); //var itemToSelect = this.WhenValueChanged(vm => vm.SelectedItem) // .CombineLatest(firstVisibleRow, (selected, first) => selected ?? first); //// InlineViewer = inlineViewerFactory.Create(inline, this.WhenValueChanged(vm => vm.SelectedItem), lineProxyFactory); _cleanUp = new CompositeDisposable(lineScroller, loader, firstIndexMonitor, FileStatus, Count, LatestCount, FileSizeText, CanViewInline, InlineViewer, InlineViewerVisible, SearchCollection, searchInfoCollection, HighlightTail, UsingDarkTheme, searchHints, searchMetadataCollection, searchMetadataCollection, SelectionMonitor, SearchOptions, searchInvoker, _userScrollRequested.SetAsComplete()); }
private void menuEdit_DropDownOpening(object sender, EventArgs e) { IUndoHandler hUndo = this.DockPanel.ActiveContent as IUndoHandler; IClipboardHandler hClip = this.DockPanel.ActiveContent as IClipboardHandler; IDeleteHandler hDelete = this.DockPanel.ActiveContent as IDeleteHandler; ISelectAllHandler hSelectAll = this.DockPanel.ActiveContent as ISelectAllHandler; IFindReplaceHandler hFind = this.DockPanel.ActiveContent as IFindReplaceHandler; if (hUndo != null) { this.menuEditUndo.Enabled = hUndo.CanUndo; this.menuEditRedo.Enabled = hUndo.CanRedo; } else { this.menuEditUndo.Enabled = false; this.menuEditRedo.Enabled = false; } if (hClip != null) { this.menuEditCut.Enabled = hClip.CanCut; this.menuEditCopy.Enabled = hClip.CanCopy; this.menuEditPaste.Enabled = hClip.CanPaste; } else { this.menuEditCut.Enabled = false; this.menuEditCopy.Enabled = false; this.menuEditPaste.Enabled = false; } if (hDelete != null) { this.menuEditDelete.Enabled = hDelete.CanDelete; } else { this.menuEditDelete.Enabled = false; } if (hSelectAll != null) { this.menuEditSelectAll.Enabled = hSelectAll.CanSelectAll; } else { this.menuEditSelectAll.Enabled = false; } if (hFind != null) { this.menuEditFind.Enabled = hFind.CanShowFindDialog; this.menuEditReplace.Enabled = hFind.CanShowReplaceDialog; } else { this.menuEditFind.Enabled = false; this.menuEditReplace.Enabled = false; } }
public TailViewModel([NotNull] ILogger logger, [NotNull] ISchedulerProvider schedulerProvider, [NotNull] IFileWatcher fileWatcher, [NotNull] ISelectionMonitor selectionMonitor, [NotNull] IClipboardHandler clipboardHandler, [NotNull] ISearchInfoCollection searchInfoCollection, [NotNull] IInlineViewerFactory inlineViewerFactory, [NotNull] GeneralOptionBindings generalOptionBindings, [NotNull] ICombinedSearchMetadataCollection combinedSearchMetadataCollection, [NotNull] IStateBucketService stateBucketService, [NotNull] ITailViewStateRestorer restorer, [NotNull] SearchHints searchHints, [NotNull] ITailViewStateControllerFactory tailViewStateControllerFactory, [NotNull] IThemeProvider themeProvider, [NotNull] SearchCollection searchCollection, [NotNull] ITextFormatter textFormatter, [NotNull] ILineMatches lineMatches, [NotNull] IObjectProvider objectProvider, [NotNull] IDialogCoordinator dialogCoordinator) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } if (schedulerProvider == null) { throw new ArgumentNullException(nameof(schedulerProvider)); } if (fileWatcher == null) { throw new ArgumentNullException(nameof(fileWatcher)); } if (clipboardHandler == null) { throw new ArgumentNullException(nameof(clipboardHandler)); } if (searchInfoCollection == null) { throw new ArgumentNullException(nameof(searchInfoCollection)); } if (inlineViewerFactory == null) { throw new ArgumentNullException(nameof(inlineViewerFactory)); } if (stateBucketService == null) { throw new ArgumentNullException(nameof(stateBucketService)); } if (themeProvider == null) { throw new ArgumentNullException(nameof(themeProvider)); } if (textFormatter == null) { throw new ArgumentNullException(nameof(textFormatter)); } if (lineMatches == null) { throw new ArgumentNullException(nameof(lineMatches)); } if (objectProvider == null) { throw new ArgumentNullException(nameof(objectProvider)); } if (dialogCoordinator == null) { throw new ArgumentNullException(nameof(dialogCoordinator)); } if (combinedSearchMetadataCollection == null) { throw new ArgumentNullException(nameof(combinedSearchMetadataCollection)); } Name = fileWatcher.FullName; SelectionMonitor = selectionMonitor ?? throw new ArgumentNullException(nameof(selectionMonitor)); GeneralOptionBindings = generalOptionBindings; SearchHints = searchHints ?? throw new ArgumentNullException(nameof(searchHints)); CopyToClipboardCommand = new Command(() => clipboardHandler.WriteToClipboard(selectionMonitor.GetSelectedText())); OpenFileCommand = new Command(() => Process.Start(fileWatcher.FullName)); OpenFolderCommand = new Command(() => Process.Start(fileWatcher.Folder)); CopyPathToClipboardCommand = new Command(() => clipboardHandler.WriteToClipboard(fileWatcher.FullName)); UnClearCommand = new Command(fileWatcher.Reset); ClearCommand = new Command(fileWatcher.Clear); KeyAutoTail = new Command(() => { AutoTail = true; }); OpenSearchOptionsCommand = new Command(async() => { await Task.Run(() => { var content = objectProvider.Get <SearchOptionsViewModel>(new Argument <ICombinedSearchMetadataCollection>(combinedSearchMetadataCollection)); dialogCoordinator.Show(this, content, x => content.Dispose()); }); }); var closeOnDeselect = this.WhenValueChanged(vm => vm.IsSelected, false) .Where(selected => !selected) .Subscribe(_ => dialogCoordinator.Close()); SearchCollection = searchCollection ?? throw new ArgumentNullException(nameof(searchCollection)); SearchMetadataCollection = combinedSearchMetadataCollection.Local; var horizonalScrollArgs = new ReplaySubject <TextScrollInfo>(1); HorizonalScrollChanged = args => horizonalScrollArgs.OnNext(args); _tailViewStateControllerFactory = tailViewStateControllerFactory; //this deals with state when loading the system at start up and at shut-down _persister = new TailViewPersister(this, restorer); FileStatus = fileWatcher.Status.ForBinding(); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested.Subscribe(request => searchInfoCollection.Add(request.Text, request.UseRegEx)); //An observable which acts as a scroll command var autoChanged = this.WhenValueChanged(vm => vm.AutoTail); var scroller = _userScrollRequested.CombineLatest(autoChanged, (user, auto) => { var mode = AutoTail ? ScrollReason.Tail : ScrollReason.User; return(new ScrollRequest(mode, user.PageSize, user.FirstIndex)); }) .Do(x => logger.Info("Scrolling to {0}/{1}", x.FirstIndex, x.PageSize)) .DistinctUntilChanged(); //User feedback to show file size FileSizeText = fileWatcher.Latest.Select(fn => fn.Size) .Select(size => size.FormatWithAbbreviation()) .DistinctUntilChanged() .ForBinding(); //tailer is the main object used to tail, scroll and filter in a file var selectedProvider = SearchCollection.Latest.ObserveOn(schedulerProvider.Background); var lineScroller = new LineScroller(selectedProvider, scroller); MaximumChars = lineScroller.MaximumLines() .ObserveOn(schedulerProvider.MainThread) .ForBinding(); var lineProxyFactory = new LineProxyFactory(textFormatter, lineMatches, horizonalScrollArgs.DistinctUntilChanged(), themeProvider); var loader = lineScroller.Lines.Connect() .LogChanges(logger, "Received") .Transform(lineProxyFactory.Create) .LogChanges(logger, "Sorting") .Sort(SortExpressionComparer <LineProxy> .Ascending(proxy => proxy)) .ObserveOn(schedulerProvider.MainThread) .Bind(out _data, 100) .LogChanges(logger, "Bound") .DisposeMany() .LogErrors(logger) .Subscribe(); //monitor matching lines and start index, Count = searchInfoCollection.All.Select(latest => latest.Count).ForBinding(); CountText = searchInfoCollection.All.Select(latest => $"{latest.Count:##,###} lines").ForBinding(); LatestCount = SearchCollection.Latest.Select(latest => latest.Count).ForBinding(); ////track first visible index var firstIndexMonitor = lineScroller.Lines.Connect() .Buffer(TimeSpan.FromMilliseconds(25)).FlattenBufferResult() .ToCollection() .Select(lines => lines.Count == 0 ? 0 : lines.Select(l => l.Index).Max() - lines.Count + 1) .ObserveOn(schedulerProvider.MainThread) .Subscribe(first => { FirstIndex = first; }); //Create objects required for inline viewing var isUserDefinedChanged = SearchCollection.WhenValueChanged(sc => sc.Selected) .Where(selected => selected != null) .Select(selected => selected.IsUserDefined) .DistinctUntilChanged() .Replay(1) .RefCount(); var showInline = this.WhenValueChanged(vm => vm.ShowInline); var inlineViewerVisible = isUserDefinedChanged.CombineLatest(showInline, (userDefined, showInlne) => userDefined && showInlne); CanViewInline = isUserDefinedChanged.ForBinding(); InlineViewerVisible = inlineViewerVisible.ForBinding(); //return an empty line provider unless user is viewing inline - this saves needless trips to the file var inline = searchInfoCollection.All.CombineLatest(inlineViewerVisible, (index, ud) => ud ? index : EmptyLineProvider.Instance); InlineViewer = inlineViewerFactory.Create(combinedSearchMetadataCollection, inline, this.WhenValueChanged(vm => vm.SelectedItem)); _cleanUp = new CompositeDisposable(lineScroller, loader, firstIndexMonitor, FileStatus, Count, CountText, LatestCount, FileSizeText, CanViewInline, InlineViewer, InlineViewerVisible, SearchCollection, searchInfoCollection, searchHints, SelectionMonitor, closeOnDeselect, Disposable.Create(dialogCoordinator.Close), searchInvoker, MaximumChars, _stateMonitor, combinedSearchMetadataCollection, horizonalScrollArgs.SetAsComplete(), _userScrollRequested.SetAsComplete()); }
public InlineViewer([NotNull] IObservable <ILineProvider> lineProvider, [NotNull] IObservable <LineProxy> selectedChanged, [NotNull] IClipboardHandler clipboardHandler, [NotNull] ISchedulerProvider schedulerProvider, [NotNull] ISelectionMonitor selectionMonitor, [NotNull] ILogger logger, [NotNull] IThemeProvider themeProvider, [NotNull] ITextFormatter textFormatter, [NotNull] ILineMatches lineMatches) { if (lineProvider == null) { throw new ArgumentNullException(nameof(lineProvider)); } if (selectedChanged == null) { throw new ArgumentNullException(nameof(selectedChanged)); } if (clipboardHandler == null) { throw new ArgumentNullException(nameof(clipboardHandler)); } if (schedulerProvider == null) { throw new ArgumentNullException(nameof(schedulerProvider)); } if (selectionMonitor == null) { throw new ArgumentNullException(nameof(selectionMonitor)); } if (themeProvider == null) { throw new ArgumentNullException(nameof(themeProvider)); } SelectionMonitor = selectionMonitor; CopyToClipboardCommand = new Command(() => clipboardHandler.WriteToClipboard(selectionMonitor.GetSelectedText())); _isSettingScrollPosition = false; var pageSize = this.WhenValueChanged(vm => vm.PageSize); //if use selection is null, tail the file var scrollSelected = selectedChanged .CombineLatest(lineProvider, pageSize, (proxy, lp, pge) => proxy == null ? new ScrollRequest(pge, 0) : new ScrollRequest(pge, proxy.Start)) .DistinctUntilChanged(); var horizonalScrollArgs = new ReplaySubject <TextScrollInfo>(1); HorizonalScrollChanged = hargs => { horizonalScrollArgs.OnNext(hargs); }; var scrollUser = _userScrollRequested .Where(x => !_isSettingScrollPosition) .Select(request => new ScrollRequest(ScrollReason.User, request.PageSize, request.FirstIndex)); var scroller = scrollSelected.Merge(scrollUser) .ObserveOn(schedulerProvider.Background) .DistinctUntilChanged(); var lineScroller = new LineScroller(lineProvider, scroller); Count = lineProvider.Select(lp => lp.Count).ForBinding(); MaximumChars = lineScroller.MaximumLines() .ObserveOn(schedulerProvider.MainThread) .ForBinding(); var proxyFactory = new LineProxyFactory(textFormatter, lineMatches, horizonalScrollArgs.DistinctUntilChanged(), themeProvider); //load lines into observable collection var loader = lineScroller.Lines.Connect() .Transform(proxyFactory.Create, new ParallelisationOptions(ParallelType.Ordered, 3)) .Sort(SortExpressionComparer <LineProxy> .Ascending(proxy => proxy)) .ObserveOn(schedulerProvider.MainThread) .Bind(out _data) .DisposeMany() .LogErrors(logger) .Subscribe(); // track first visible index [required to set scroll extent] var firstIndexMonitor = lineScroller.Lines.Connect() .Buffer(TimeSpan.FromMilliseconds(250)).FlattenBufferResult() .ToCollection() .Select(lines => lines.Count == 0 ? 0 : lines.Select(l => l.Index).Max() - lines.Count + 1) .ObserveOn(schedulerProvider.MainThread) .Subscribe(first => { try { _isSettingScrollPosition = true; FirstIndex = first; } finally { _isSettingScrollPosition = false; } }); _cleanUp = new CompositeDisposable(lineScroller, loader, Count, firstIndexMonitor, SelectionMonitor, MaximumChars, horizonalScrollArgs.SetAsComplete(), _userScrollRequested.SetAsComplete()); }
protected override void Run(IClipboardHandler editable) { editable.SelectAll(); }
protected abstract void Run(IClipboardHandler editable);
protected override void Run(IClipboardHandler editable) { editable.Copy(); }
public InlineViewer([NotNull] InlineViewerArgs args, [NotNull] IClipboardHandler clipboardHandler, [NotNull] ISchedulerProvider schedulerProvider, [NotNull] ISelectionMonitor selectionMonitor) { if (args == null) { throw new ArgumentNullException(nameof(args)); } if (clipboardHandler == null) { throw new ArgumentNullException(nameof(clipboardHandler)); } if (schedulerProvider == null) { throw new ArgumentNullException(nameof(schedulerProvider)); } if (selectionMonitor == null) { throw new ArgumentNullException(nameof(selectionMonitor)); } SelectionMonitor = selectionMonitor; CopyToClipboardCommand = new Command(() => clipboardHandler.WriteToClipboard(selectionMonitor.GetSelectedText())); _isSettingScrollPosition = false; var lineProvider = args.LineProvider; var selectedChanged = args.SelectedChanged; var pageSize = this.WhenValueChanged(vm => vm.PageSize); var scrollSelected = selectedChanged.Where(proxy => proxy != null) .CombineLatest(lineProvider, pageSize, (proxy, lp, pge) => new ScrollRequest(pge, (int)proxy.Start, true)); var scrollUser = _userScrollRequested .Where(x => !_isSettingScrollPosition) .Select(request => new ScrollRequest(ScrollReason.User, request.PageSize, request.FirstIndex)); var scroller = scrollSelected.Merge(scrollUser) .ObserveOn(schedulerProvider.Background) .DistinctUntilChanged(); var lineScroller = new LineScroller(lineProvider, scroller); Count = lineProvider.Select(lp => lp.Count).ForBinding(); //load lines into observable collection var loader = lineScroller.Lines.Connect() .Transform(line => new LineProxy(line)) .Sort(SortExpressionComparer <LineProxy> .Ascending(proxy => proxy)) .ObserveOn(schedulerProvider.MainThread) .Bind(out _data) .Subscribe(); // track first visible index[required to set scroll extent] var firstIndexMonitor = lineScroller.Lines.Connect() .Buffer(TimeSpan.FromMilliseconds(250)).FlattenBufferResult() .ToCollection() .Select(lines => lines.Count == 0 ? 0 : lines.Select(l => l.Index).Max() - lines.Count + 1) .ObserveOn(schedulerProvider.MainThread) .Subscribe(first => { try { _isSettingScrollPosition = true; FirstIndex = first; } finally { _isSettingScrollPosition = false; } }); _cleanUp = new CompositeDisposable(lineScroller, loader, Count, firstIndexMonitor, SelectionMonitor, Disposable.Create(() => { _userScrollRequested.OnCompleted(); })); }
public Clipboard(IClipboardHandler handler) { this.handler = handler; handler.Initialize(OnReadText); }
public TailViewModel([NotNull] ILogger logger, [NotNull] ISchedulerProvider schedulerProvider, [NotNull] IFileWatcher fileWatcher, [NotNull] ISelectionMonitor selectionMonitor, [NotNull] IClipboardHandler clipboardHandler, [NotNull] ISearchInfoCollection searchInfoCollection, [NotNull] IInlineViewerFactory inlineViewerFactory, [NotNull] ISetting <GeneralOptions> generalOptions, [NotNull] ISearchMetadataCollection searchMetadataCollection, [NotNull] IStateBucketService stateBucketService, [NotNull] SearchOptionsViewModel searchOptionsViewModel, [NotNull] ITailViewStateRestorer restorer, [NotNull] SearchHints searchHints, [NotNull] ITailViewStateControllerFactory tailViewStateControllerFactory) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } if (schedulerProvider == null) { throw new ArgumentNullException(nameof(schedulerProvider)); } if (fileWatcher == null) { throw new ArgumentNullException(nameof(fileWatcher)); } if (selectionMonitor == null) { throw new ArgumentNullException(nameof(selectionMonitor)); } if (clipboardHandler == null) { throw new ArgumentNullException(nameof(clipboardHandler)); } if (searchInfoCollection == null) { throw new ArgumentNullException(nameof(searchInfoCollection)); } if (inlineViewerFactory == null) { throw new ArgumentNullException(nameof(inlineViewerFactory)); } if (generalOptions == null) { throw new ArgumentNullException(nameof(generalOptions)); } if (searchMetadataCollection == null) { throw new ArgumentNullException(nameof(searchMetadataCollection)); } if (stateBucketService == null) { throw new ArgumentNullException(nameof(stateBucketService)); } if (searchOptionsViewModel == null) { throw new ArgumentNullException(nameof(searchOptionsViewModel)); } if (searchHints == null) { throw new ArgumentNullException(nameof(searchHints)); } Name = fileWatcher.FullName; SelectionMonitor = selectionMonitor; SearchOptions = searchOptionsViewModel; SearchHints = searchHints; SearchCollection = new SearchCollection(searchInfoCollection, schedulerProvider); CopyToClipboardCommand = new Command(() => clipboardHandler.WriteToClipboard(selectionMonitor.GetSelectedText())); OpenFileCommand = new Command(() => Process.Start(fileWatcher.FullName)); OpenFolderCommand = new Command(() => Process.Start(fileWatcher.Folder)); SearchMetadataCollection = searchMetadataCollection; var horizonalScrollArgs = new ReplaySubject <TextScrollInfo>(1); HorizonalScrollChanged = args => { horizonalScrollArgs.OnNext(args); }; _tailViewStateControllerFactory = tailViewStateControllerFactory; //Move these 2 highlight fields to a service as all views require them UsingDarkTheme = generalOptions.Value .ObserveOn(schedulerProvider.MainThread) .Select(options => options.Theme == Theme.Dark) .ForBinding(); HighlightTail = generalOptions.Value .ObserveOn(schedulerProvider.MainThread) .Select(options => options.HighlightTail) .ForBinding(); //this deals with state when loading the system at start up and at shut-down _persister = new TailViewPersister(this, restorer); //An observable which acts as a scroll command var autoChanged = this.WhenValueChanged(vm => vm.AutoTail); var scroller = _userScrollRequested.CombineLatest(autoChanged, (user, auto) => { var mode = AutoTail ? ScrollReason.Tail : ScrollReason.User; return(new ScrollRequest(mode, user.PageSize, user.FirstIndex)); }) .Do(x => logger.Info("Scrolling to {0}/{1}", x.FirstIndex, x.PageSize)) .DistinctUntilChanged(); FileStatus = fileWatcher.Status.ForBinding(); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested.Subscribe(request => { searchInfoCollection.Add(request.Text, request.UseRegEx); }); //User feedback to show file size FileSizeText = fileWatcher.Latest.Select(fn => fn.Size) .Select(size => size.FormatWithAbbreviation()) .DistinctUntilChanged() .ForBinding(); //tailer is the main object used to tail, scroll and filter in a file var lineScroller = new LineScroller(SearchCollection.Latest.ObserveOn(schedulerProvider.Background), scroller); MaximumChars = lineScroller.MaximumLines() .ObserveOn(schedulerProvider.MainThread) .ForBinding(); //load lines into observable collection var lineProxyFactory = new LineProxyFactory(new TextFormatter(searchMetadataCollection), new LineMatches(searchMetadataCollection), horizonalScrollArgs.DistinctUntilChanged()); var loader = lineScroller.Lines.Connect() .LogChanges(logger, "Received") .Transform(lineProxyFactory.Create, new ParallelisationOptions(ParallelType.Ordered, 3)) .LogChanges(logger, "Sorting") .Sort(SortExpressionComparer <LineProxy> .Ascending(proxy => proxy)) .ObserveOn(schedulerProvider.MainThread) .Bind(out _data, 100) .LogChanges(logger, "Bound") .DisposeMany() .LogErrors(logger) .Subscribe(); //monitor matching lines and start index, Count = searchInfoCollection.All.Select(latest => latest.Count).ForBinding(); CountText = searchInfoCollection.All.Select(latest => $"{latest.Count.ToString("##,###")} lines").ForBinding(); LatestCount = SearchCollection.Latest.Select(latest => latest.Count).ForBinding(); ////track first visible index var firstIndexMonitor = lineScroller.Lines.Connect() .Buffer(TimeSpan.FromMilliseconds(25)).FlattenBufferResult() .ToCollection() .Select(lines => lines.Count == 0 ? 0 : lines.Select(l => l.Index).Max() - lines.Count + 1) .ObserveOn(schedulerProvider.MainThread) .Subscribe(first => { FirstIndex = first; }); //Create objects required for inline viewing var isUserDefinedChanged = SearchCollection.WhenValueChanged(sc => sc.Selected) .Where(selected => selected != null) .Select(selected => selected.IsUserDefined) .DistinctUntilChanged() .Replay(1) .RefCount(); var inlineViewerVisible = isUserDefinedChanged.CombineLatest(this.WhenValueChanged(vm => vm.ShowInline), (userDefined, showInline) => userDefined && showInline); CanViewInline = isUserDefinedChanged.ForBinding(); InlineViewerVisible = inlineViewerVisible.ForBinding(); //return an empty line provider unless user is viewing inline - this saves needless trips to the file var inline = searchInfoCollection.All.CombineLatest(inlineViewerVisible, (index, ud) => ud ? index : new EmptyLineProvider()); InlineViewer = inlineViewerFactory.Create(inline, this.WhenValueChanged(vm => vm.SelectedItem), searchMetadataCollection); _cleanUp = new CompositeDisposable(lineScroller, loader, firstIndexMonitor, FileStatus, Count, LatestCount, FileSizeText, CanViewInline, InlineViewer, InlineViewerVisible, SearchCollection, searchInfoCollection, HighlightTail, UsingDarkTheme, searchHints, searchMetadataCollection, SelectionMonitor, SearchOptions, searchInvoker, MaximumChars, _stateMonitor, horizonalScrollArgs.SetAsComplete(), _userScrollRequested.SetAsComplete()); }
protected override void Run(IClipboardHandler editable) { editable.Delete(); }
protected override bool GetEnabled(IClipboardHandler editable) { return editable.EnableDelete; }
protected override bool GetEnabled(IClipboardHandler editable) { return(editable.EnableDelete); }
public FileTailerViewModel([NotNull] ILogger logger, [NotNull] ISchedulerProvider schedulerProvider, [NotNull] IFileWatcher fileWatcher, [NotNull] ISelectionMonitor selectionMonitor, [NotNull] IClipboardHandler clipboardHandler, [NotNull] ISearchInfoCollection searchInfoCollection, [NotNull] IInlineViewerFactory inlineViewerFactory, [NotNull] ISetting <GeneralOptions> generalOptions, [NotNull] IRecentSearchCollection recentSearchCollection, [NotNull] SearchHints searchHints) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } if (schedulerProvider == null) { throw new ArgumentNullException(nameof(schedulerProvider)); } if (fileWatcher == null) { throw new ArgumentNullException(nameof(fileWatcher)); } if (selectionMonitor == null) { throw new ArgumentNullException(nameof(selectionMonitor)); } if (clipboardHandler == null) { throw new ArgumentNullException(nameof(clipboardHandler)); } if (searchInfoCollection == null) { throw new ArgumentNullException(nameof(searchInfoCollection)); } if (inlineViewerFactory == null) { throw new ArgumentNullException(nameof(inlineViewerFactory)); } if (generalOptions == null) { throw new ArgumentNullException(nameof(generalOptions)); } if (searchHints == null) { throw new ArgumentNullException(nameof(searchHints)); } SelectionMonitor = selectionMonitor; SearchHints = searchHints; CopyToClipboardCommand = new Command(() => clipboardHandler.WriteToClipboard(selectionMonitor.GetSelectedText())); SelectedItemsCount = selectionMonitor.Selected.Connect().QueryWhenChanged(collection => collection.Count).ForBinding(); SearchCollection = new SearchCollection(searchInfoCollection, schedulerProvider); UsingDarkTheme = generalOptions.Value .ObserveOn(schedulerProvider.MainThread) .Select(options => options.Theme == Theme.Dark) .ForBinding(); HighlightTail = generalOptions.Value .ObserveOn(schedulerProvider.MainThread) .Select(options => options.HighlightTail) .ForBinding(); HighlightDuration = generalOptions.Value .ObserveOn(schedulerProvider.MainThread) .Select(options => new Duration(TimeSpan.FromSeconds(options.HighlightDuration))) .ForBinding(); //An observable which acts as a scroll command var autoChanged = this.WhenValueChanged(vm => vm.AutoTail); var scroller = _userScrollRequested.CombineLatest(autoChanged, (user, auto) => { var mode = AutoTail ? ScrollReason.Tail : ScrollReason.User; return(new ScrollRequest(mode, user.PageSize, user.FirstIndex)); }) .ObserveOn(schedulerProvider.Background) .DistinctUntilChanged(); //tailer is the main object used to tail, scroll and filter in a file var lineScroller = new LineScroller(SearchCollection.Latest.ObserveOn(schedulerProvider.Background), scroller); //Add a complete file display [No search info here] var indexed = fileWatcher.Latest.Index() .Replay(1).RefCount(); IsLoading = indexed.Take(1).Select(_ => false).StartWith(true).ForBinding(); searchInfoCollection.Add("<All>", indexed, SearchType.All); //command to add the current search to the tail collection KeepSearchCommand = new Command(() => { var text = SearchHints.SearchText; var latest = fileWatcher.Latest .Search(s => s.Contains(text, StringComparison.OrdinalIgnoreCase)) .Replay(1).RefCount(); searchInfoCollection.Add(text, latest); recentSearchCollection.Add(new RecentSearch(text)); SearchHints.SearchText = string.Empty; }, () => SearchHints.SearchText.IsLongerThanOrEqualTo(3)); //User feedback to show file size FileSizeText = fileWatcher.Latest.Select(fn => fn.Size) .Select(size => size.FormatWithAbbreviation()) .DistinctUntilChanged() .ForBinding(); //User feedback to guide them whilst typing SearchHint = this.WhenValueChanged(vm => vm.SearchHints.SearchText) .Select(text => { if (string.IsNullOrEmpty(text)) { return("Type to search"); } return(text.Length < 3 ? "Enter at least 3 characters" : "Hit enter to search"); }).ForBinding(); //load lines into observable collection var lineProxyFactory = new LineProxyFactory(new TextFormatter(searchInfoCollection)); var loader = lineScroller.Lines.Connect() .Transform(lineProxyFactory.Create, new ParallelisationOptions(ParallelType.Ordered, 5)) .Sort(SortExpressionComparer <LineProxy> .Ascending(proxy => proxy)) .ObserveOn(schedulerProvider.MainThread) .Bind(out _data) .DisposeMany() .Subscribe(changes => logger.Info($"Rows changed. {changes.Adds} adds, {changes.Removes} removed"), ex => logger.Error(ex, "There is a problem with bind data")); //monitor matching lines and start index, Count = indexed.Select(latest => latest.Count).ForBinding(); CountText = indexed.Select(latest => $"{latest.Count.ToString("##,###")} lines").ForBinding(); LatestCount = SearchCollection.Latest.Select(latest => latest.Count).ForBinding(); //track first visible index var firstIndexMonitor = lineScroller.Lines.Connect() .Buffer(TimeSpan.FromMilliseconds(250)).FlattenBufferResult() .ToCollection() .Select(lines => lines.Count == 0 ? 0 : lines.Select(l => l.Index).Max() - lines.Count + 1) .ObserveOn(schedulerProvider.MainThread) .Subscribe(first => FirstIndex = first); //Create objects required for inline viewing var isUserDefinedChanged = SearchCollection.WhenValueChanged(sc => sc.Selected) .Select(selected => selected.IsUserDefined) .DistinctUntilChanged(); var inlineViewerVisible = isUserDefinedChanged.CombineLatest(this.WhenValueChanged(vm => vm.ShowInline), (userDefined, showInline) => userDefined && showInline); CanViewInline = isUserDefinedChanged.ForBinding(); InlineViewerVisible = inlineViewerVisible.ForBinding(); //return an empty line provider unless user is viewing inline - this saves needless trips to the file var inline = indexed.CombineLatest(inlineViewerVisible, (index, ud) => ud ? index : new EmptyLineProvider()); InlineViewer = inlineViewerFactory.Create(inline, this.WhenValueChanged(vm => vm.SelectedItem), lineProxyFactory); _cleanUp = new CompositeDisposable(lineScroller, loader, firstIndexMonitor, IsLoading, Count, LatestCount, FileSizeText, SearchHint, SelectedItemsCount, CanViewInline, InlineViewer, InlineViewerVisible, SearchCollection, searchInfoCollection, HighlightTail, UsingDarkTheme, searchHints, Disposable.Create(() => { _userScrollRequested.OnCompleted(); SelectionMonitor?.Dispose(); })); }