Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DiffPlex.App/DiffPlex.App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<None Remove="DiffTextView.xaml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\DiffPlex.Windows\Internals.cs" Link="Internals.cs" />
<Compile Include="..\DiffPlex.Windows\Helper.cs" Link="Helper.cs" />
<Compile Include="..\DiffPlex.Wpf.Demo\TestData.cs" Link="TestData.cs" />
</ItemGroup>

Expand Down
82 changes: 71 additions & 11 deletions DiffPlex.Windows/Converters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,13 @@ namespace DiffPlex.UI;
/// <summary>
/// The base converter for change type.
/// </summary>
public class DiffChangeTypeConverter : IValueConverter
/// <param name="defaultChangeType">The default chagne type.</param>
public class DiffChangeTypeConverter(ChangeType defaultChangeType) : IValueConverter
{
/// <summary>
/// Initializes a new instance of the DiffChangeTypeConverter class.
/// </summary>
/// <param name="defaultChangeType">The default chagne type.</param>
public DiffChangeTypeConverter(ChangeType defaultChangeType)
{
ModifyChangeType = defaultChangeType;
}

/// <summary>
/// Gets or sets the default change type for modify.
/// </summary>
public ChangeType ModifyChangeType { get; set; }
public ChangeType ModifyChangeType { get; set; } = defaultChangeType;

/// <summary>
/// Gets or sets the default change type for modify.
Expand Down Expand Up @@ -129,3 +121,71 @@ public NewDiffChangeTypeConverter()
{
}
}

/// <summary>
/// The base converter for change type.
/// </summary>
/// <param name="defaultChangeType">The default chagne type.</param>
public class DiffTextHighlighterConverter(ChangeType defaultChangeType) : IValueConverter
{
/// <summary>
/// Gets or sets the default change type for modify.
/// </summary>
public ChangeType ModifyChangeType { get; set; } = defaultChangeType;

/// <summary>
/// Gets or sets the foreground.
/// </summary>
public Brush Foreground { get; set; }

/// <summary>
/// Converts a source to target.
/// </summary>
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is FrameworkElement element) value = element.DataContext;
if (value is not List<DiffPiece> sub)
{
if (value is DiffPiece p) sub = p.SubPieces;
else return null;
}

return InternalUtilities.GetTextHighlighter(sub, ModifyChangeType, Foreground ?? (parameter as Brush));
}

/// <summary>
/// Converts the source back.
/// </summary>
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return null;
}
}

/// <summary>
/// The diff change type converter for old text.
/// </summary>
public class DeletedDiffTextHighlighterConverter : DiffTextHighlighterConverter
{
/// <summary>
/// Initializes a new instance of the DeletedDiffTextHighlighterConverter class.
/// </summary>
public DeletedDiffTextHighlighterConverter()
: base(ChangeType.Deleted)
{
}
}

/// <summary>
/// The diff change type converter for new text.
/// </summary>
public class InsertedDiffTextHighlighterConverter : DiffTextHighlighterConverter
{
/// <summary>
/// Initializes a new instance of the InsertedDiffTextHighlighterConverter class.
/// </summary>
public InsertedDiffTextHighlighterConverter()
: base(ChangeType.Inserted)
{
}
}
2 changes: 1 addition & 1 deletion DiffPlex.Windows/DiffPlex.Windows.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.241114003" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.1742" />
<PackageReference Include="Trivial.WindowsKit" Version="9.0.0" />
<PackageReference Include="Trivial.WindowsKit" Version="9.2.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
</ItemGroup>

Expand Down
63 changes: 60 additions & 3 deletions DiffPlex.Windows/DiffTextView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -545,13 +545,13 @@ public void ScrollNextDiffIntoView()
/// </summary>
/// <param name="q">The string to seek.</param>
/// <returns>All line numbers with the given string.</returns>
public IEnumerable<int> Find(string q)
public IEnumerable<DiffTextViewInfo> Find(string q)
{
var list = GetActiveListView();
foreach (var item in list.Items)
{
if (!GetItemFromList(list, item, out var container, out var model)) continue;
if (model.Contains(q)) yield return model.LineNumber;
if (item is not BaseDiffTextViewModel m) continue;
if (m.Contains(q)) yield return m.ToInfo();
}
}

Expand All @@ -577,6 +577,28 @@ public bool Focus(int lineNumber, FocusState focusState)
}
}

/// <summary>
/// Attempts to set focus to a specific line.
/// </summary>
/// <param name="info">The line.</param>
/// <param name="focusState">How this element obtains focus.</param>
/// <returns>true if keyboard focus and logical focus were set to the specific line; otherwise, false, if only logical focus was set to the specific line, or if the call to this method did not force the focus to change.</returns>
public bool Focus(DiffTextViewInfo info, FocusState focusState)
{
if (!info.Position.HasValue) return false;
switch (info.ViewType)
{
case DiffTextViewType.Inline:
return FocusInUnifiedView(info.Position.Value, focusState);
case DiffTextViewType.Left:
return FocusInSplitView(info.Position.Value, true, focusState);
case DiffTextViewType.Right:
return FocusInSplitView(info.Position.Value, false, focusState);
}

return false;
}

/// <summary>
/// Attempts to set focus to a specific line.
/// </summary>
Expand Down Expand Up @@ -636,6 +658,41 @@ public void ScrollIntoView(int lineNumber, ScrollIntoViewAlignment alignment = S
}
}

/// <summary>
/// Scrolls the list to bring the specified line number into view with the specified alignment.
/// </summary>
/// <param name="info">The line info.</param>
/// <param name="alignment">An enumeration value that specifies whether the item uses default or leading alignment.</param>
public void ScrollIntoView(DiffTextViewInfo info, ScrollIntoViewAlignment alignment = ScrollIntoViewAlignment.Default)
{
if (info.Position == null) return;
var lineNumber = info.Position.Value;
switch (info.ViewType)
{
case DiffTextViewType.Inline:
{
var line = inlines.FirstOrDefault(ele => ele?.Position == lineNumber);
if (line is null) return;
UnifiedElement.ScrollIntoView(line, alignment);
break;
}
case DiffTextViewType.Left:
{
var line = sideBySide.FirstOrDefault(ele => ele?.Left?.Position == lineNumber);
if (line is null) return;
SplitElement.ScrollIntoView(line, alignment);
break;
}
case DiffTextViewType.Right:
{
var line = sideBySide.FirstOrDefault(ele => ele?.Right?.Position == lineNumber);
if (line is null) return;
SplitElement.ScrollIntoView(line, alignment);
break;
}
}
}

/// <summary>
/// Collapses unchanged sections.
/// </summary>
Expand Down
136 changes: 0 additions & 136 deletions DiffPlex.Windows/Internals.cs → DiffPlex.Windows/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,139 +166,3 @@ public static async Task<string> TryGetFileTextAsync(Window window, Action<Excep
return null;
}
}

/// <summary>
/// The base view model for diff text.
/// </summary>
internal abstract class BaseDiffTextViewModel
{
/// <summary>
/// Get or set the line number.
/// </summary>
public int LineNumber { get; set; }

/// <summary>
/// Gets a value indicating whether the line is unchanged.
/// </summary>
public abstract bool IsUnchanged { get; }

/// <summary>
/// Gets a value indicating whether the current line is null.
/// </summary>
public abstract bool IsNullLine { get; }

/// <summary>
/// Returns a value indicating whether a specified substring occurs within the text in this view model.
/// </summary>
/// <param name="q">The string to seek.</param>
/// <returns>true if the value parameter occurs within the text in this view model; otherwise, false.</returns>
public abstract bool Contains(string q);
}

/// <summary>
/// The diff text view model of split mode.
/// </summary>
internal class DiffTextViewModel : BaseDiffTextViewModel
{
public DiffTextViewModel()
{
}

public DiffTextViewModel(int number, DiffPiece left, DiffPiece right)
: this(number, left, right, null)
{
}

public DiffTextViewModel(int number, DiffPiece left, DiffPiece right, DiffTextViewReference reference)
{
LineNumber = number;
Left = left;
Right = right;
Reference = reference;
}

public DiffPiece Left { get; private set; }

public DiffPiece Right { get; private set; }

public DiffTextViewReference Reference { get; private set; }

public string LeftText => Left?.Text;

public string RightText => Right?.Text;

/// <inheritdoc />
public override bool IsUnchanged => Right?.Type == ChangeType.Unchanged;

/// <inheritdoc />
public override bool IsNullLine => Right is null;

public IEnumerable<TextHighlighter> GetLeftHighlighter()
=> InternalUtilities.GetTextHighlighter(Left?.SubPieces, ChangeType.Deleted, Reference?.Element?.Foreground);

public IEnumerable<TextHighlighter> GetRightHighlighter()
=> InternalUtilities.GetTextHighlighter(Right?.SubPieces, ChangeType.Inserted, Reference?.Element?.Foreground);

/// <inheritdoc />
public override bool Contains(string q)
{
if (string.IsNullOrEmpty(q)) return false;
var v = Right?.Text;
if (v != null && v.Contains(q)) return true;
v = Left?.Text;
if (v != null && v.Contains(q)) return true;
return false;
}
}

/// <summary>
/// The diff text view model of unified mode.
/// </summary>
internal class InlineDiffTextViewModel : BaseDiffTextViewModel
{
public InlineDiffTextViewModel()
{
}

public InlineDiffTextViewModel(int number, DiffPiece line)
: this(number, line, null)
{
}

public InlineDiffTextViewModel(int number, DiffPiece line, DiffTextViewReference reference)
{
LineNumber = number;
Line = line;
Reference = reference;
}

public DiffPiece Line { get; private set; }

public string Text => Line?.Text;

public int? Position => Line?.Position;

public DiffTextViewReference Reference { get; private set; }

/// <inheritdoc />
public override bool IsUnchanged => Line?.Type == ChangeType.Unchanged;

/// <inheritdoc />
public override bool IsNullLine => Line is null;

public IEnumerable<TextHighlighter> GetTextHighlighter()
=> InternalUtilities.GetTextHighlighter(Line?.SubPieces, ChangeType.Deleted, Reference?.Element?.Foreground);

/// <inheritdoc />
public override bool Contains(string q)
{
if (string.IsNullOrEmpty(q)) return false;
var v = Line?.Text;
return v != null && v.Contains(q);
}
}

internal class DiffTextViewReference(DiffTextView element)
{
public DiffTextView Element { get; set; } = element;
}
Loading
Loading