diff --git a/DiffPlex.App/DiffPlex.App.csproj b/DiffPlex.App/DiffPlex.App.csproj index f29c5864..0b50c555 100644 --- a/DiffPlex.App/DiffPlex.App.csproj +++ b/DiffPlex.App/DiffPlex.App.csproj @@ -1,7 +1,7 @@  WinExe - net6.0-windows10.0.19041.0 + net7.0-windows10.0.19041.0 10.0.17763.0 DiffPlex.UI DiffPlex.App @@ -43,8 +43,8 @@ - - + + diff --git a/DiffPlex.Windows/DiffPlex.Windows.csproj b/DiffPlex.Windows/DiffPlex.Windows.csproj index cc465b33..fcdf4d8f 100644 --- a/DiffPlex.Windows/DiffPlex.Windows.csproj +++ b/DiffPlex.Windows/DiffPlex.Windows.csproj @@ -1,19 +1,19 @@  - net6.0-windows10.0.17763.0;net6.0-windows10.0.19041.0;net6.0-windows10.0.22000.0 + net6.0-windows10.0.17763.0;net6.0-windows10.0.19041.0;net6.0-windows10.0.22000.0;net7.0-windows10.0.17763.0;net7.0-windows10.0.19041.0;net7.0-windows10.0.22000.0 10.0.17763.0 DiffPlex.UI DiffPlex.Windows DiffPlex.Windows win10-x86;win10-x64;win10-arm64 true - 1.0.1 + 1.1.0 diff diffplex_icon.png DiffPlex.Windows is a Windows App SDK control library that allows you to programatically render visual text diffs in your application. 10.0 - 1.0.1.0 - 1.0.1.0 + 1.1.0.0 + 1.1.0.0 Kingcean Tuan; Matthew Manela Copyright (c) 2022 Matthew Manela. All rights reserved. Apache-2.0 @@ -35,9 +35,9 @@ - - - + + + diff --git a/DiffPlex.Wpf/Controls/DiffViewer.xaml b/DiffPlex.Wpf/Controls/DiffViewer.xaml index c20f117e..2dbeb933 100644 --- a/DiffPlex.Wpf/Controls/DiffViewer.xaml +++ b/DiffPlex.Wpf/Controls/DiffViewer.xaml @@ -4,10 +4,69 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:DiffPlex.Wpf.Controls" + x:Name="SelfControl" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> + + + + + + + + + + + + + + @@ -15,7 +74,31 @@ - + + + + + + + + + + @@ -38,12 +121,12 @@ - - - - - - - + + + + + + + diff --git a/DiffPlex.Wpf/Controls/DiffViewer.xaml.cs b/DiffPlex.Wpf/Controls/DiffViewer.xaml.cs index 3ed9afb0..eda23517 100644 --- a/DiffPlex.Wpf/Controls/DiffViewer.xaml.cs +++ b/DiffPlex.Wpf/Controls/DiffViewer.xaml.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Security; using System.Text; using System.Threading.Tasks; @@ -19,6 +20,7 @@ using DiffPlex.DiffBuilder; using DiffPlex.DiffBuilder.Model; +using DiffPlex.WindowsForms.Controls; namespace DiffPlex.Wpf.Controls; @@ -115,11 +117,41 @@ public ViewModeChangedEventArgs(bool isSideBySide) /// public static readonly DependencyProperty HeaderHeightProperty = RegisterDependencyProperty(nameof(HeaderHeight), 0, (d, e) => { - if (d is not DiffViewer c || e.OldValue == e.NewValue || e.NewValue is not double n) return; + if (d is not DiffViewer c || e.OldValue == e.NewValue) return; + if (e.NewValue is not double n) + { + if (e.NewValue is not int i) return; + n = i; + } + c.HeaderRow.Height = new GridLength(n); c.isHeaderEnabled = true; }); + public static readonly DependencyProperty IsCommandBarVisibleProperty = RegisterDependencyProperty(nameof(IsCommandBarVisible), false, (d, e) => + { + if (d is not DiffViewer c || e.OldValue == e.NewValue) return; + if (e.NewValue is not bool b) + { + if (e.NewValue is Visibility v) b = v == Visibility.Visible; + return; + } + + c.CommandRow.Height = new GridLength(30); + }); + + public static readonly DependencyProperty IsOpenFileButtonVisibleProperty = RegisterDependencyProperty(nameof(IsOpenFileButtonVisible), true, (d, e) => + { + if (d is not DiffViewer c || e.OldValue == e.NewValue) return; + if (e.NewValue is not bool b) + { + if (e.NewValue is Visibility v) b = v == Visibility.Visible; + return; + } + + c.OpenFileButton.Visibility = b ? Visibility.Visible : Visibility.Collapsed; + }); + /// /// The property of header background brush. /// @@ -281,6 +313,13 @@ public DiffViewer() CollapseUnchangedSectionsToggle.Header = Helper.GetButtonName(Resource.SkipUnchangedLines ?? "Collapse unchanged sections", "C"); ContextLinesMenuItems.Header = Helper.GetButtonName(Resource.ContextLines ?? "Lines for context", "L"); RefreshContextLinesMenuItemState(LinesContext); + OpenFileButton.Content = Resource.OpenFile; + OpenLeftFileMenuItem.Header = Resource.Left; + OpenRightFileMenuItem.Header = Resource.Right; + DiffButton.Content = Resource.SwitchViewMode; + GoToLabel.Content = Resource.GoTo; + PreviousButton.ToolTip = Resource.Previous; + NextButton.ToolTip = Resource.Next; } /// @@ -426,6 +465,26 @@ public double HeaderHeight set => SetValue(HeaderHeightProperty, value); } + /// + /// Gets or sets the foreground brush of the line added. + /// + [Bindable(true)] + [Category("Appearance")] + public bool IsCommandBarVisible + { + get => (bool)GetValue(IsCommandBarVisibleProperty); + set => SetValue(IsCommandBarVisibleProperty, value); + } + + /// + /// Gets or sets a value indicating whether show open file button. + /// + public bool IsOpenFileButtonVisible + { + get => (bool)GetValue(IsOpenFileButtonVisibleProperty); + set => SetValue(IsOpenFileButtonVisibleProperty, value); + } + /// /// Gets or sets the foreground brush of the line added. /// @@ -631,6 +690,24 @@ public object ContextLinesMenuItemsTitle set => ContextLinesMenuItems.Header = value; } + /// + /// Gets or sets the margin of the customized menu. + /// + public Thickness MenuMargin + { + get => MenuPanel.Margin; + set => MenuPanel.Margin = value; + } + + /// + /// Gets or sets the margin of the customized additional menu. + /// + public Thickness AdditionalMenuMargin + { + get => AdditionalMenuPanel.Margin; + set => AdditionalMenuPanel.Margin = value; + } + /// /// Gets a value indicating whether the grid splitter has logical focus and mouse capture and the left mouse button is pressed. /// @@ -656,6 +733,146 @@ public object ContextLinesMenuItemsTitle /// public bool IsInlineViewMode => InlineContentPanel.Visibility == Visibility.Visible; + /// + /// Gets the customized menu children. + /// + public UIElementCollection MenuChildren => MenuPanel.Children; + + /// + /// Gets the customized additional menu children. + /// + public UIElementCollection AdditionalMenuChildren => AdditionalMenuPanel.Children; + + /// + /// Gets or sets the filter of file. + /// + public string FileFilter { get; set; } = "All files|*.*|Plain text|*.txt;*.log;*.json;*.xml;*.csv;*.config;*.js;*.ts;*.jsx;*.tsx;*.py;*.cs;*.cpp;*.h;*.java;*.go;*.vb;*.vbs;*.xaml;*.md;*.svg;*.sql;*.csproj;*.cxproj;*.ini"; + + /// + /// Sets the text. + /// + /// The old text. + /// The new text. + public void SetText(string left, string right) + { + OldText = left; + NewText = right; + } + + /// + /// Sets old text. + /// + /// The old text. + /// An optional header for old text. + public void SetOldText(string value, string header = null) + { + OldText = value ?? string.Empty; + if (header != null) OldTextHeader = header; + } + + /// + /// Sets new text. + /// + /// The new text. + /// An optional header for new text. + public void SetNewText(string value, string header = null) + { + NewText = value ?? string.Empty; + if (header != null) NewTextHeader = header; + } + + /// + /// Sets file contents as old and new text. + /// + /// The old file information instance to read content. + /// The new file information instance to read content. + /// A token for the asynchronous operation. + public async Task SetFiles(FileInfo oldFile, FileInfo newFile) + { + string left = string.Empty; + OldTextHeader = GenerateHeader(oldFile); + NewTextHeader = GenerateHeader(newFile); + if (oldFile != null) + { + using var reader1 = oldFile.OpenText(); + left = await reader1.ReadToEndAsync(); + if (oldFile == newFile) + { + OldText = NewText = left; + return; + } + } + + string right = string.Empty; + if (newFile != null) + { + using var reader2 = newFile.OpenText(); + right = await reader2.ReadToEndAsync(); + } + + OldText = left; + NewText = right; + } + + /// + /// Shows the context menu to open file. + /// + public void ShowOpenFileContextMenu() + { + OpenFileContextMenu.IsOpen = true; + } + + /// + /// Pops up a file dialog to open file on both of left and right. + /// + public void OpenFileOnBoth() + { + var text = OpenFileOnLeft(null, out var file); + NewText = text; + if (text == null) return; + NewTextHeader = GenerateHeader(file); + } + + /// + /// Pops up a file dialog to open file on left. + /// + public void OpenFileOnLeft() + => OpenFileOnLeft(null, out _); + + /// + /// Pops up a file dialog to open file on left. + /// + /// The optional header. + /// The file opened. + public string OpenFileOnLeft(string header, out FileInfo file) + { + var text = OpenTextFile(out file); + if (text == null) return null; + OldText = text; + OldTextHeader = header ?? GenerateHeader(file); + return text; + } + + /// + /// Pops up a file dialog to open file on right. + /// + public void OpenFileOnRight() + => OpenFileOnRight(null, out _); + + /// + /// Pops up a file dialog to open file on right. + /// + /// The optional header. + /// The file opened. + public string OpenFileOnRight(string header, out FileInfo file) + { + var text = OpenTextFile(out file); + if (text == null) return null; + NewText = text; + NewTextHeader = header ?? GenerateHeader(file); + return text; + } + /// /// Gets the side-by-side diffs result. /// @@ -1015,6 +1232,244 @@ private void RefreshContextLinesMenuItemState(int i) } } + /// + /// Sets the style to the menu buttons. + /// The buttons in customized menu bar will not be impacted. + /// + /// The button style to set. + public void SetMenuButtonStyle(Style style) + { + OpenFileButton.Style = DiffButton.Style = FurtherActionsButton.Style = NextButton.Style = PreviousButton.Style = style; + } + + /// + /// Sets the control template to the menu buttons. + /// The buttons in customized menu bar will not be impacted. + /// + /// The control template to set. + public void SetMenuButtonTemplate(ControlTemplate template) + { + OpenFileButton.Template = DiffButton.Template = FurtherActionsButton.Template = NextButton.Template = PreviousButton.Template = template; + } + + /// + /// Sets the style to the menu text input boxes. + /// The text input boxes in customized menu bar will not be impacted. + /// + /// The button style to set. + public void SetMenuTextBoxStyle(Style style) + { + GoToText.Style = style; + } + + /// + /// Sets the control template to the menu text input boxes. + /// The text input boxes in customized menu bar will not be impacted. + /// + /// The control template to set. + public void SetMenuTextBoxTemlate(ControlTemplate template) + { + GoToText.Template = template; + } + + /// + /// Scrolls to the previous view of diff section. + /// + /// The line. + public DiffPiece PreviousDiff() + { + var isLeft = string.IsNullOrEmpty(NewText); + var pageSize = GetLinesInViewport(isLeft, VisibilityLevels.All).Count(); + var lines = GetLinesBeforeViewport(isLeft, VisibilityLevels.All).Reverse().ToList(); + if (lines.Count < pageSize) + { + var last = lines.LastOrDefault(); + GoTo(last); + return last; + } + + var line = lines.Take(pageSize).Reverse().FirstOrDefault(ele => ele.Type != ChangeType.Unchanged); + line ??= lines.FirstOrDefault(ele => ele.Type != ChangeType.Unchanged); + GoTo(line, isLeft); + return line; + } + + /// + /// Scrolls to the next view of diff section. + /// + /// The line. + public DiffPiece NextDiff() + { + var isLeft = string.IsNullOrEmpty(NewText); + var line = GetLinesAfterViewport(isLeft, VisibilityLevels.All).FirstOrDefault(ele => ele.Type != ChangeType.Unchanged); + GoTo(line, isLeft); + return line; + } + + private string GenerateHeader(FileInfo file) + { + if (file == null || !file.Exists) return Resource.Empty; + try + { + var dir = file.Directory; + if (!string.IsNullOrWhiteSpace(dir?.Name)) return string.Concat(dir.Name, '\\', file.Name); + } + catch (IOException) + { + } + catch (SecurityException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (InvalidOperationException) + { + } + catch (NotSupportedException) + { + } + catch (ExternalException) + { + } + + return file.Name; + } + + private void OpenFileButton_Click(object sender, RoutedEventArgs e) + { + if (OldText == null) + { + var text = OpenFileOnLeft(null, out var file); + if (text == null || NewText != null) return; + NewText = text; + NewTextHeader = GenerateHeader(file); + } + else if (NewText == null) + { + OpenRightFileMenuItem_Click(sender, e); + } + else + { + OpenFileContextMenu.IsOpen = true; + } + } + + private void OpenLeftFileMenuItem_Click(object sender, RoutedEventArgs e) + => OpenFileOnLeft(null, out _); + + private void OpenRightFileMenuItem_Click(object sender, RoutedEventArgs e) + => OpenFileOnRight(null, out _); + + private void DiffButton_Click(object sender, RoutedEventArgs e) + { + if (IsInlineViewMode) + { + ShowSideBySide(); + return; + } + + ShowInline(); + } + + private void FurtherActionsButton_Click(object sender, RoutedEventArgs e) + { + OpenViewModeContextMenu(); + } + + private void GoToText_TextChanged(object sender, TextChangedEventArgs e) + { + var s = GoToText.Text?.Trim(); + if (string.IsNullOrEmpty(s)) return; + if (!int.TryParse(s, out var i)) return; + GoTo(i, string.IsNullOrEmpty(NewText)); + } + + private void GoToText_LostFocus(object sender, RoutedEventArgs e) + { + GoToText.Text = null; + } + + private void PreviousButton_Click(object sender, RoutedEventArgs e) + => PreviousDiff(); + + private void NextButton_Click(object sender, RoutedEventArgs e) + => NextDiff(); + + private string OpenTextFile(out FileInfo file) + { + var dialog = new Microsoft.Win32.OpenFileDialog + { + Filter = FileFilter + }; + if (dialog.ShowDialog() != true) + { + file = null; + return null; + } + + var fileName = dialog.FileName; + if (string.IsNullOrWhiteSpace(fileName)) + { + file = null; + return null; + } + + try + { + file = new FileInfo(fileName); + } + catch (ArgumentException) + { + file = null; + } + catch (IOException) + { + file = null; + } + catch (InvalidOperationException) + { + file = null; + } + catch (UnauthorizedAccessException) + { + file = null; + } + catch (NotSupportedException) + { + file = null; + } + catch (SecurityException) + { + file = null; + } + + try + { + return File.ReadAllText(fileName); + } + catch (ArgumentException) + { + } + catch (IOException) + { + } + catch (InvalidOperationException) + { + } + catch (UnauthorizedAccessException) + { + } + catch (NotSupportedException) + { + } + catch (SecurityException) + { + } + + return null; + } + private static DependencyProperty RegisterDependencyProperty(string name) { return DependencyProperty.Register(name, typeof(T), typeof(DiffViewer), null); diff --git a/DiffPlex.Wpf/DiffPlex.Wpf.csproj b/DiffPlex.Wpf/DiffPlex.Wpf.csproj index c7746fd8..10ee3e6c 100644 --- a/DiffPlex.Wpf/DiffPlex.Wpf.csproj +++ b/DiffPlex.Wpf/DiffPlex.Wpf.csproj @@ -4,13 +4,13 @@ net6.0-windows;net46;net48 true true - 1.3.2 + 1.4.0 DiffPlex.Wpf DiffPlex.Wpf diff, wpf DiffPlex.Wpf is a WPF control library that allows you to programatically render visual text diffs in your application. It also provide a diff viewer control used in Windows Forms application. - 1.3.2.0 - 1.3.2.0 + 1.4.0.0 + 1.4.0.0 ..\DiffPlex.ico diff --git a/DiffPlex.Wpf/DiffWindow.xaml b/DiffPlex.Wpf/DiffWindow.xaml index 8d529edc..e0bf03f8 100644 --- a/DiffPlex.Wpf/DiffWindow.xaml +++ b/DiffPlex.Wpf/DiffWindow.xaml @@ -65,35 +65,5 @@ - - - - - - - - - - - - - - - - + diff --git a/DiffPlex.Wpf/DiffWindow.xaml.cs b/DiffPlex.Wpf/DiffWindow.xaml.cs index d9d74341..06e67744 100644 --- a/DiffPlex.Wpf/DiffWindow.xaml.cs +++ b/DiffPlex.Wpf/DiffWindow.xaml.cs @@ -25,32 +25,6 @@ namespace DiffPlex.Wpf /// public partial class DiffWindow : Window { - /// - /// The information for the text file. - /// - internal class TextFileInfo - { - /// - /// Gets or sets the file name. - /// - public string FileName { get; set; } - - /// - /// Gets or sets the folder name. - /// - public string FolderName { get; set; } - - /// - /// Gets or sets the value. - /// - public string Value { get; set; } - } - - private string leftFileName; - private string leftFolderName; - private string rightFileName; - private string rightFolderName; - /// /// Initializes a new instance of the DiffWindow class. /// @@ -64,13 +38,6 @@ public DiffWindow() Foreground = new SolidColorBrush(isDark ? Color.FromRgb(240, 240, 240) : Color.FromRgb(32, 32, 32)); Background = new SolidColorBrush(isDark ? Color.FromRgb(32, 32, 32) : Color.FromRgb(251, 251, 251)); DiffView.SetHeaderAsLeftToRight(); - OpenFileButton.Content = Resource.OpenFile; - OpenLeftFileMenuItem.Header = Resource.Left; - OpenRightFileMenuItem.Header = Resource.Right; - DiffButton.Content = Resource.SwitchViewMode; - GoToLabel.Content = Resource.GoTo; - PreviousButton.ToolTip = Resource.Previous; - NextButton.ToolTip = Resource.Next; } /// @@ -124,14 +91,14 @@ public string NewTextHeader /// public bool IsOpenFileButtonVisbile { - get => OpenFileButton.Visibility == Visibility.Visible; - set => OpenFileButton.Visibility = value ? Visibility.Visible : Visibility.Collapsed; + get => DiffView.IsOpenFileButtonVisible; + set => DiffView.IsOpenFileButtonVisible = value; } /// /// Gets a value indicating whether it is side-by-side (split) view mode. /// - public bool IsSideBySideViewMode => Core.IsSideBySideViewMode; + public bool IsSideBySideViewMode => DiffView.IsSideBySideViewMode; /// /// Gets or sets a value indicating whether need collapse unchanged sections. @@ -155,31 +122,38 @@ public int LinesContext /// /// Gets the customized menu children. /// - public UIElementCollection MenuChildren => MenuPanel.Children; + public UIElementCollection MenuChildren => DiffView.MenuChildren; /// /// Gets or sets the margin of the customized menu. /// public Thickness MenuMargin { - get => MenuPanel.Margin; - set => MenuPanel.Margin = value; + get => DiffView.MenuMargin; + set => DiffView.MenuMargin = value; } /// /// Gets the customized additional menu children. /// - public UIElementCollection AddtionalMenuChildren => AdditionalMenuPanel.Children; + public UIElementCollection AdditionalMenuChildren => DiffView.AdditionalMenuChildren; /// /// Gets or sets the margin of the customized additional menu. /// public Thickness AddtionalMenuMargin { - get => AdditionalMenuPanel.Margin; - set => AdditionalMenuPanel.Margin = value; + get => DiffView.AdditionalMenuMargin; + set => DiffView.AdditionalMenuMargin = value; } + /// + /// Sets the text. + /// + /// The old text. + /// The new text. + public void SetText(string left, string right) + => DiffView.SetText(left, right); /// /// Sets old text. @@ -187,11 +161,7 @@ public Thickness AddtionalMenuMargin /// The old text. /// An optional header for old text. public void SetOldText(string value, string header = null) - { - DiffView.OldText = value ?? string.Empty; - leftFolderName = null; - DiffView.OldTextHeader = leftFileName = header; - } + => DiffView.SetOldText(value, header); /// /// Sets new text. @@ -199,11 +169,7 @@ public void SetOldText(string value, string header = null) /// The new text. /// An optional header for new text. public void SetNewText(string value, string header = null) - { - DiffView.NewText = value ?? string.Empty; - rightFolderName = null; - DiffView.NewTextHeader = rightFileName = header; - } + => DiffView.SetNewText(value, header); /// /// Sets file contents as old and new text. @@ -211,144 +177,67 @@ public void SetNewText(string value, string header = null) /// The old file information instance to read content. /// The new file information instance to read content. /// A token for the asynchronous operation. - public async Task SetFiles(FileInfo oldFile, FileInfo newFile) - { - string left = string.Empty; - string leftFile = null; - string leftFolder = null; - if (oldFile != null) - { - using var reader1 = oldFile.OpenText(); - left = await reader1.ReadToEndAsync(); - try - { - leftFile = oldFile.Name; - leftFolder = oldFile.Directory?.Name; - } - catch (IOException) - { - } - catch (SecurityException) - { - } - - if (oldFile == newFile) - { - DiffView.OldText = DiffView.NewText = left; - leftFileName = rightFileName = leftFile; - leftFolderName = rightFolderName = leftFolder; - RefreshHeader(); - return; - } - } - - string right = string.Empty; - string rightFile = null; - string rightFolder = null; - if (newFile != null) - { - using var reader2 = newFile.OpenText(); - right = await reader2.ReadToEndAsync(); - try - { - rightFile = newFile.Name; - rightFolder = newFile.Directory?.Name; - } - catch (IOException) - { - } - catch (SecurityException) - { - } - } - - DiffView.OldText = left; - DiffView.NewText = right; - leftFileName = leftFile; - leftFolderName = leftFolder; - rightFileName = rightFile; - rightFolderName = rightFolder; - RefreshHeader(); - } + public Task SetFiles(FileInfo oldFile, FileInfo newFile) + => DiffView.SetFiles(oldFile, newFile); /// /// Shows the context menu to open file. /// - public void OpenOpenFileContextMenu() - { - OpenFileContextMenu.IsOpen = true; - } + public void ShowOpenFileContextMenu() + => DiffView.ShowOpenFileContextMenu(); /// /// Opens the context menu for view mode selection. /// public void OpenViewModeContextMenu() - { - DiffView.OpenViewModeContextMenu(); - } + => DiffView.OpenViewModeContextMenu(); /// /// Pops up a file dialog to open file on both of left and right. /// public void OpenFileOnBoth() - { - var text = OpenLeftFileInternal(); - DiffView.NewText = text; - rightFileName = leftFileName; - rightFolderName = leftFolderName; - RefreshHeader(); - } + => DiffView.OpenFileOnBoth(); /// /// Pops up a file dialog to open file on left. /// public void OpenFileOnLeft() - { - OpenLeftFileInternal(); - if (DiffView.NewText != null) return; - DiffView.NewText = string.Empty; - rightFileName = Resource.Empty; - rightFolderName = null; - RefreshHeader(); - } + => DiffView.OpenFileOnLeft(); + + /// + /// Pops up a file dialog to open file on left. + /// + /// The optional header. + /// The file opened. + public void OpenFileOnLeft(string header, out FileInfo file) + => DiffView.OpenFileOnLeft(header, out file); /// /// Pops up a file dialog to open file on right. /// public void OpenFileOnRight() - { - var text = OpenTextFile(); - if (text?.Value == null) return; - DiffView.NewText = text.Value; - rightFileName = text.FileName?.Trim(); - rightFolderName = text.FolderName?.Trim(); - if (DiffView.OldText != null) - { - RefreshHeader(); - return; - } - - DiffView.OldText = string.Empty; - leftFileName = Resource.Empty; - leftFolderName = null; - RefreshHeader(); - } + => DiffView.OpenFileOnRight(); + + /// + /// Pops up a file dialog to open file on right. + /// + /// The optional header. + /// The file opened. + public void OpenFileOnRight(string header, out FileInfo file) + => DiffView.OpenFileOnRight(header, out file); /// /// Switches to the view of side-by-side (split) diff mode. /// public void ShowSideBySide() - { - DiffView.ShowSideBySide(); - } + => DiffView.ShowSideBySide(); /// /// Switches to the view of inline (unified) diff mode. /// public void ShowInline() - { - DiffView.ShowInline(); - } + => DiffView.ShowInline(); + /// /// Goes to a specific line. /// @@ -356,9 +245,7 @@ public void ShowInline() /// true if goes to the line of the left panel for side-by-side (splitted) view; otherwise, false. This will be ignored when it is in inline view. /// true if it has turned to the specific line; otherwise, false. public bool GoTo(int lineIndex, bool isLeftLine = false) - { - return DiffView.GoTo(lineIndex, isLeftLine); - } + => DiffView.GoTo(lineIndex, isLeftLine); /// /// Goes to a specific line. @@ -367,9 +254,7 @@ public bool GoTo(int lineIndex, bool isLeftLine = false) /// true if goes to the line of the left panel for side-by-side (splitted) view; otherwise, false. This will be ignored when it is in inline view. /// true if it has turned to the specific line; otherwise, false. public bool GoTo(DiffPiece line, bool isLeftLine = false) - { - return DiffView.GoTo(line, isLeftLine); - } + => DiffView.GoTo(line, isLeftLine); /// /// Gets the line diff information. @@ -378,9 +263,7 @@ public bool GoTo(DiffPiece line, bool isLeftLine = false) /// true if goes to the line of the left panel for side-by-side (splitted) view; otherwise, false. This will be ignored when it is in inline view. /// The line diff information instance; or null, if non-exists. public DiffPiece GetLine(int lineIndex, bool isLeftLine = false) - { - return DiffView.GetLine(lineIndex, isLeftLine); - } + => DiffView.GetLine(lineIndex, isLeftLine); /// /// Sets the style to the menu buttons. @@ -388,9 +271,7 @@ public DiffPiece GetLine(int lineIndex, bool isLeftLine = false) /// /// The button style to set. public void SetMenuButtonStyle(Style style) - { - OpenFileButton.Style = DiffButton.Style = FurtherActionsButton.Style = NextButton.Style = PreviousButton.Style = style; - } + => DiffView.SetMenuButtonStyle(style); /// /// Sets the control template to the menu buttons. @@ -398,9 +279,7 @@ public void SetMenuButtonStyle(Style style) /// /// The control template to set. public void SetMenuButtonTemplate(ControlTemplate template) - { - OpenFileButton.Template = DiffButton.Template = FurtherActionsButton.Template = NextButton.Template = PreviousButton.Template = template; - } + => DiffView.SetMenuButtonTemplate(template); /// /// Sets the style to the menu text input boxes. @@ -408,9 +287,7 @@ public void SetMenuButtonTemplate(ControlTemplate template) /// /// The button style to set. public void SetMenuTextBoxStyle(Style style) - { - GoToText.Style = style; - } + => DiffView.SetMenuTextBoxStyle(style); /// /// Sets the control template to the menu text input boxes. @@ -418,205 +295,6 @@ public void SetMenuTextBoxStyle(Style style) /// /// The control template to set. public void SetMenuTextBoxTemlate(ControlTemplate template) - { - GoToText.Template = template; - } - - private void OpenFileButton_Click(object sender, RoutedEventArgs e) - { - if (DiffView.OldText == null) - { - var text = OpenLeftFileInternal(); - if (text == null || DiffView.NewText != null) return; - DiffView.NewText = text; - rightFileName = leftFileName; - rightFolderName = leftFolderName; - RefreshHeader(); - } - else if (DiffView.NewText == null) - { - OpenRightFileMenuItem_Click(sender, e); - } - else - { - OpenFileContextMenu.IsOpen = true; - } - } - - private string OpenLeftFileInternal() - { - var text = OpenTextFile(); - if (text?.Value == null) return null; - DiffView.OldText = text.Value; - leftFileName = text.FileName?.Trim(); - leftFolderName = text.FolderName?.Trim(); - if (DiffView.NewText != null) RefreshHeader(); - return text.Value; - } - - private void OpenLeftFileMenuItem_Click(object sender, RoutedEventArgs e) - { - OpenLeftFileInternal(); - if (DiffView.NewText != null) return; - DiffView.NewText = string.Empty; - rightFileName = Resource.Empty; - rightFolderName = null; - RefreshHeader(); - } - - private void OpenRightFileMenuItem_Click(object sender, RoutedEventArgs e) - { - var text = OpenTextFile(); - if (text?.Value == null) return; - DiffView.NewText = text.Value; - rightFileName = text.FileName?.Trim(); - rightFolderName = text.FolderName?.Trim(); - if (DiffView.OldText != null) - { - RefreshHeader(); - return; - } - - DiffView.OldText = string.Empty; - leftFileName = Resource.Empty; - leftFolderName = null; - RefreshHeader(); - } - - private void RefreshHeader() - { - if (!AutoSetHeader) return; - DiffView.SetHeaderAsLeftToRight(); - if (leftFileName != rightFileName) - { - if (!string.IsNullOrEmpty(leftFileName)) DiffView.OldTextHeader = leftFileName; - if (!string.IsNullOrEmpty(rightFileName)) DiffView.NewTextHeader = rightFileName; - return; - } - - if (leftFolderName == rightFolderName) return; - if (!string.IsNullOrEmpty(leftFolderName)) DiffView.OldTextHeader = leftFolderName; - if (!string.IsNullOrEmpty(rightFolderName)) DiffView.NewTextHeader = rightFolderName; - return; - } - - private void DiffButton_Click(object sender, RoutedEventArgs e) - { - if (DiffView.IsInlineViewMode) - { - DiffView.ShowSideBySide(); - return; - } - - DiffView.ShowInline(); - } - - private void FurtherActionsButton_Click(object sender, RoutedEventArgs e) - { - DiffView.OpenViewModeContextMenu(); - } - - private void GoToText_TextChanged(object sender, TextChangedEventArgs e) - { - var s = GoToText.Text?.Trim(); - if (string.IsNullOrEmpty(s)) return; - if (!int.TryParse(s, out var i)) return; - DiffView.GoTo(i, string.IsNullOrEmpty(DiffView.NewText)); - } - - private void GoToText_LostFocus(object sender, RoutedEventArgs e) - { - GoToText.Text = null; - } - - private void PreviousButton_Click(object sender, RoutedEventArgs e) - { - var isLeft = string.IsNullOrEmpty(DiffView.NewText); - var pageSize = DiffView.GetLinesInViewport(isLeft, VisibilityLevels.All).Count(); - var lines = DiffView.GetLinesBeforeViewport(isLeft, VisibilityLevels.All).Reverse().ToList(); - if (lines.Count < pageSize) - { - DiffView.GoTo(lines.LastOrDefault()); - return; - } - - var line = lines.Take(pageSize).Reverse().FirstOrDefault(ele => ele.Type != DiffBuilder.Model.ChangeType.Unchanged); - if (line == null) line = lines.FirstOrDefault(ele => ele.Type != DiffBuilder.Model.ChangeType.Unchanged); - DiffView.GoTo(line, isLeft); - } - - private void NextButton_Click(object sender, RoutedEventArgs e) - { - var isLeft = string.IsNullOrEmpty(DiffView.NewText); - var line = DiffView.GetLinesAfterViewport(isLeft, VisibilityLevels.All).FirstOrDefault(ele => ele.Type != DiffBuilder.Model.ChangeType.Unchanged); - DiffView.GoTo(line, isLeft); - } - - private static TextFileInfo OpenTextFile() - { - var dialog = new Microsoft.Win32.OpenFileDialog - { - Filter = "All files|*.*|Plain text|*.txt;*.log;*.json;*.xml;*.csv;*.config;*.js;*.ts;*.jsx;*.tsx;*.py;*.cs;*.cpp;*.h;*.java;*.go;*.vb;*.vbs;*.xaml;*.md;*.svg;*.sql;*.csproj;*.cxproj;*.ini" - }; - if (dialog.ShowDialog() != true) return null; - var fileName = dialog.FileName; - if (string.IsNullOrWhiteSpace(fileName)) return null; - string name = null; - string folder = null; - try - { - var file = new FileInfo(fileName); - name = file.Name; - folder = file.Directory?.Name; - } - catch (ArgumentException) - { - } - catch (IOException) - { - } - catch (InvalidOperationException) - { - } - catch (UnauthorizedAccessException) - { - } - catch (NotSupportedException) - { - } - catch (SecurityException) - { - } - - try - { - return new TextFileInfo - { - FileName = name, - FolderName = folder, - Value = File.ReadAllText(fileName) - }; - } - catch (ArgumentException) - { - } - catch (IOException) - { - } - catch (InvalidOperationException) - { - } - catch (UnauthorizedAccessException) - { - } - catch (NotSupportedException) - { - } - catch (SecurityException) - { - } - - return null; - } + => DiffView.SetMenuTextBoxTemlate(template); } } diff --git a/NuGet.props b/NuGet.props index 79f8e230..a3b29d5b 100644 --- a/NuGet.props +++ b/NuGet.props @@ -19,7 +19,7 @@ 10.0 - +