22using System . IO ;
33using System . Threading . Tasks ;
44
5+ using Avalonia ;
56using Avalonia . Threading ;
67
78using CommunityToolkit . Mvvm . ComponentModel ;
@@ -24,7 +25,64 @@ public bool IgnoreWhitespace
2425 {
2526 Preferences . Instance . IgnoreWhitespaceChangesInDiff = value ;
2627 OnPropertyChanged ( ) ;
27- LoadDiffContent ( ) ;
28+
29+ if ( _isTextDiff )
30+ LoadContent ( ) ;
31+ }
32+ }
33+ }
34+
35+ public bool ShowEntireFile
36+ {
37+ get => Preferences . Instance . UseFullTextDiff ;
38+ set
39+ {
40+ if ( value != Preferences . Instance . UseFullTextDiff )
41+ {
42+ Preferences . Instance . UseFullTextDiff = value ;
43+ OnPropertyChanged ( ) ;
44+
45+ if ( _isTextDiff )
46+ {
47+ if ( Content is CombinedTextDiff combined )
48+ combined . ScrollOffset = Vector . Zero ;
49+ else if ( Content is TwoSideTextDiff twoSide )
50+ twoSide . Data . File = string . Empty ;
51+
52+ LoadContent ( ) ;
53+ }
54+ }
55+ }
56+ }
57+
58+ public bool UseBlockNavigation
59+ {
60+ get => Preferences . Instance . UseBlockNavigationInDiffView ;
61+ set
62+ {
63+ if ( value != Preferences . Instance . UseBlockNavigationInDiffView )
64+ {
65+ Preferences . Instance . UseBlockNavigationInDiffView = value ;
66+ OnPropertyChanged ( ) ;
67+
68+ if ( Content is CombinedTextDiff combined )
69+ combined . BlockNavigation = value ? new BlockNavigation ( combined ) : null ;
70+ else if ( Content is TwoSideTextDiff twoSide )
71+ twoSide . BlockNavigation = value ? new BlockNavigation ( twoSide ) : null ;
72+ }
73+ }
74+ }
75+
76+ public bool UseSideBySide
77+ {
78+ get => Preferences . Instance . UseSideBySideDiff ;
79+ set
80+ {
81+ if ( value != Preferences . Instance . UseSideBySideDiff )
82+ {
83+ Preferences . Instance . UseSideBySideDiff = value ;
84+ OnPropertyChanged ( ) ;
85+ SwitchTextDiffMode ( value ) ;
2886 }
2987 }
3088 }
@@ -72,33 +130,76 @@ public DiffContext(string repo, Models.DiffOption option, DiffContext previous =
72130 else
73131 Title = $ "{ _option . OrgPath } → { _option . Path } ";
74132
75- LoadDiffContent ( ) ;
76- }
77-
78- public void ToggleFullTextDiff ( )
79- {
80- Preferences . Instance . UseFullTextDiff = ! Preferences . Instance . UseFullTextDiff ;
81- LoadDiffContent ( ) ;
133+ LoadContent ( ) ;
82134 }
83135
84136 public void IncrUnified ( )
85137 {
86138 UnifiedLines = _unifiedLines + 1 ;
87- LoadDiffContent ( ) ;
139+ LoadContent ( ) ;
88140 }
89141
90142 public void DecrUnified ( )
91143 {
92144 UnifiedLines = Math . Max ( 4 , _unifiedLines - 1 ) ;
93- LoadDiffContent ( ) ;
145+ LoadContent ( ) ;
94146 }
95147
96148 public void OpenExternalMergeTool ( )
97149 {
98150 new Commands . DiffTool ( _repo , _option ) . Open ( ) ;
99151 }
100152
101- private void LoadDiffContent ( )
153+ public void CheckSettings ( )
154+ {
155+ if ( _isTextDiff )
156+ {
157+ if ( ( ShowEntireFile && _info . UnifiedLines != _entireFileLine ) ||
158+ ( ! ShowEntireFile && _info . UnifiedLines == _entireFileLine ) ||
159+ ( IgnoreWhitespace != _info . IgnoreWhitespace ) )
160+ {
161+ LoadContent ( ) ;
162+ return ;
163+ }
164+ }
165+
166+ if ( Content is CombinedTextDiff combined )
167+ {
168+ if ( UseSideBySide )
169+ {
170+ SwitchTextDiffMode ( true ) ;
171+ return ;
172+ }
173+
174+ if ( UseBlockNavigation && combined . BlockNavigation == null )
175+ combined . BlockNavigation = new BlockNavigation ( combined ) ;
176+ else if ( ! UseBlockNavigation && combined . BlockNavigation != null )
177+ combined . BlockNavigation = null ;
178+ }
179+ else if ( Content is TwoSideTextDiff twoSide )
180+ {
181+ if ( ! UseSideBySide )
182+ {
183+ SwitchTextDiffMode ( false ) ;
184+ return ;
185+ }
186+
187+ if ( UseBlockNavigation && twoSide . BlockNavigation == null )
188+ twoSide . BlockNavigation = new BlockNavigation ( twoSide ) ;
189+ else if ( ! UseBlockNavigation && twoSide . BlockNavigation != null )
190+ twoSide . BlockNavigation = null ;
191+ }
192+ }
193+
194+ private void SwitchTextDiffMode ( bool sideBySide )
195+ {
196+ if ( sideBySide && _content is CombinedTextDiff combined )
197+ Content = new TwoSideTextDiff ( combined . Data , UseBlockNavigation ) ;
198+ else if ( ! sideBySide && _content is TwoSideTextDiff twoSide )
199+ Content = new CombinedTextDiff ( twoSide . Data , UseBlockNavigation ) ;
200+ }
201+
202+ private void LoadContent ( )
102203 {
103204 if ( _option . Path . EndsWith ( '/' ) )
104205 {
@@ -109,7 +210,7 @@ private void LoadDiffContent()
109210
110211 Task . Run ( async ( ) =>
111212 {
112- var numLines = Preferences . Instance . UseFullTextDiff ? 999999999 : _unifiedLines ;
213+ var numLines = Preferences . Instance . UseFullTextDiff ? _entireFileLine : _unifiedLines ;
113214 var ignoreWhitespace = Preferences . Instance . IgnoreWhitespaceChangesInDiff ;
114215
115216 var latest = await new Commands . Diff ( _repo , _option , numLines , ignoreWhitespace )
@@ -228,12 +329,23 @@ private void LoadDiffContent()
228329
229330 Dispatcher . UIThread . Post ( ( ) =>
230331 {
231- if ( _content is Models . TextDiff old && rs is Models . TextDiff cur && old . File == cur . File )
232- cur . ScrollOffset = old . ScrollOffset ;
233-
234332 FileModeChange = latest . FileModeChange ;
235- Content = rs ;
236- IsTextDiff = rs is Models . TextDiff ;
333+
334+ if ( rs is Models . TextDiff cur )
335+ {
336+ IsTextDiff = true ;
337+
338+ var hasBlockNavigation = Preferences . Instance . UseBlockNavigationInDiffView ;
339+ if ( Preferences . Instance . UseSideBySideDiff )
340+ Content = new TwoSideTextDiff ( cur , hasBlockNavigation , _content as TwoSideTextDiff ) ;
341+ else
342+ Content = new CombinedTextDiff ( cur , hasBlockNavigation , _content as CombinedTextDiff ) ;
343+ }
344+ else
345+ {
346+ IsTextDiff = false ;
347+ Content = rs ;
348+ }
237349 } ) ;
238350 } ) ;
239351 }
@@ -279,6 +391,7 @@ public bool IsSame(Info other)
279391 }
280392 }
281393
394+ private readonly int _entireFileLine = 999999999 ;
282395 private readonly string _repo ;
283396 private readonly Models . DiffOption _option = null ;
284397 private string _fileModeChange = string . Empty ;
0 commit comments