1 // TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2003-2015 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "SVNLineDiff.h"
22 #include "ScrollTool.h"
24 #include "LocatorBar.h"
25 #include "LineColors.h"
26 #include "TripleClick.h"
30 typedef struct inlineDiffPos
38 * \ingroup TortoiseMerge
40 * View class providing the basic functionality for
41 * showing diffs. Has three parent classes which inherit
42 * from this base class: CLeftView, CRightView and CBottomView.
44 class CBaseView
: public CView
, public CTripleClick
46 DECLARE_DYNCREATE(CBaseView
)
47 friend class CLineDiffBar
;
49 typedef CFileTextLines::UnicodeType UnicodeType
;
50 enum ECharGroup
{ // ordered by priority low-to-hi
52 CHG_CONTROL
, // x00-x08, x0a-x1f
53 CHG_WHITESPACE
, // space, tab
54 CHG_WORDSEPARATOR
, // 0x21-2f, x3a-x40, x5b-x60, x7b-x7f .,:;!?(){}[]/\<> ...
55 CHG_WORDLETTER
, // alpha num _ (others)
63 * Indicates that the underlying document has been updated. Reloads all
64 * data and redraws the view.
66 virtual void DocumentUpdated();
68 * Returns the number of lines visible on the view.
72 * Scrolls the view to the given line.
73 * \param nNewTopLine The new top line to scroll the view to
74 * \param bTrackScrollBar If TRUE, then the scrollbars are affected too.
76 void ScrollToLine(int nNewTopLine
, BOOL bTrackScrollBar
= TRUE
);
77 void ScrollAllToLine(int nNewTopLine
, BOOL bTrackScrollBar
= TRUE
);
78 void ScrollSide(int delta
);
79 void ScrollAllSide(int delta
);
80 void ScrollVertical(short delta
);
81 static void RecalcAllVertScrollBars(BOOL bPositionOnly
= FALSE
);
82 static void RecalcAllHorzScrollBars(BOOL bPositionOnly
= FALSE
);
83 void GoToLine(int nNewLine
, BOOL bAll
= TRUE
);
84 void ScrollToChar(int nNewOffsetChar
, BOOL bTrackScrollBar
= TRUE
);
85 void ScrollAllToChar(int nNewOffsetChar
, BOOL bTrackScrollBar
= TRUE
);
86 void SetReadonly(bool bReadonly
= true) {m_bReadonly
= bReadonly
; if (m_pFindDialog
) m_pFindDialog
->SetReadonly(m_bReadonly
); }
87 void SetWritable(bool bWritable
= true) {m_bReadonly
= !bWritable
; if (m_pFindDialog
) m_pFindDialog
->SetReadonly(m_bReadonly
); }
88 void SetWritableIsChangable(bool bWritableIsChangable
= true) {m_bReadonlyIsChangable
= bWritableIsChangable
;}
89 void SetTarget(bool bTarget
= true) {m_bTarget
= bTarget
;}
90 bool IsReadonly() const {return m_bReadonly
;}
91 bool IsWritable() const {return !m_bReadonly
&& m_pViewData
;}
92 bool IsReadonlyChangable() const {return m_bReadonlyIsChangable
&& !IsModified();}
93 bool IsTarget() const {return m_bTarget
;}
94 void SetCaretAndGoalPosition(const POINT
& pt
) {UpdateCaretPosition(pt
); UpdateGoalPos(); }
95 void SetCaretAndGoalViewPosition(const POINT
& pt
) {UpdateCaretViewPosition(pt
); UpdateGoalPos(); }
96 void SetCaretPosition(const POINT
& pt
) { SetCaretViewPosition(ConvertScreenPosToView(pt
)); }
97 POINT
GetCaretPosition() { return ConvertViewPosToScreen(GetCaretViewPosition()); }
98 void SetCaretViewPosition(const POINT
& pt
) { m_ptCaretViewPos
= pt
; }
99 POINT
GetCaretViewPosition() { return m_ptCaretViewPos
; }
100 void UpdateCaretPosition(const POINT
& pt
) { SetCaretPosition(pt
); UpdateCaret(); }
101 void UpdateCaretViewPosition(const POINT
& pt
) { SetCaretViewPosition(pt
); UpdateCaret(); EnsureCaretVisible(); }
102 void SetCaretToViewStart() { SetCaretToFirstViewLine(); SetCaretToViewLineStart(); }
103 void SetCaretToFirstViewLine() { m_ptCaretViewPos
.y
=0; }
104 void SetCaretToViewLineStart() { m_ptCaretViewPos
.x
=0; }
105 void SetCaretToLineStart() { SetCaretAndGoalPosition(SetupPoint(0, GetCaretPosition().y
)); }
106 void EnsureCaretVisible();
109 bool ArePointsSame(const POINT
&pt1
, const POINT
&pt2
) {return (pt1
.x
== pt2
.x
) && (pt1
.y
== pt2
.y
); };
110 POINT
SetupPoint(int x
, int y
) {POINT ptRet
={x
, y
}; return ptRet
; };
111 POINT
ConvertScreenPosToView(const POINT
& pt
);
112 POINT
ConvertViewPosToScreen(const POINT
& pt
);
115 static void BuildAllScreen2ViewVector(); ///< schedule full screen2view rebuild
116 static void BuildAllScreen2ViewVector(int ViewLine
); ///< schedule rebuild screen2view for single line
117 static void BuildAllScreen2ViewVector(int FirstViewLine
, int LastViewLine
); ///< schedule rebuild screen2view for line range (first and last inclusive)
118 void UpdateViewLineNumbers();
119 int CleanEmptyLines(); ///< remove line empty in all views
120 int GetLineCount() const;
121 static int GetViewLineForScreen(int screenLine
) { return m_Screen2View
.GetViewLineForScreen(screenLine
); }
122 int FindScreenLineForViewLine(int viewLine
);
123 // TODO: find better consistent names for Multiline(line with sublines) and Subline, Count.. or Get..Count ?
124 int CountMultiLines(int nViewLine
);
125 int GetSubLineOffset(int index
);
126 LineColors
& GetLineColors(int nViewLine
);
127 static void UpdateLocator() { if (m_pwndLocator
) m_pwndLocator
->DocumentUpdated(); }
130 void HighlightLines(int start
, int end
= -1);
131 void HighlightViewLines(int start
, int end
= -1);
132 inline BOOL
IsHidden() const {return m_bIsHidden
;}
133 inline void SetHidden(BOOL bHidden
) {m_bIsHidden
= bHidden
;}
134 inline bool IsModified() const {return m_bModified
;}
135 void SetModified(bool bModified
= true) { m_bModified
= bModified
; m_pState
->modifies
|= bModified
; Invalidate(); }
136 bool HasMarkedBlocks() const { return m_pViewData
->HasMarkedBlocks(); }
137 void ClearStepModifiedMark() { m_pState
->modifies
= false; }
138 void SetInlineWordDiff(bool bWord
) {m_bInlineWordDiff
= bWord
;}
139 void SetInlineDiff(bool bDiff
) {m_bShowInlineDiff
= bDiff
;}
140 void SetMarkedWord(const CString
& word
) {m_sMarkedWord
= word
; BuildMarkedWordArray();}
141 LPCTSTR
GetMarkedWord() {return (LPCTSTR
)m_sMarkedWord
;}
142 LPCTSTR
GetFindString() {return (LPCTSTR
)m_sFindText
;}
144 // Selection methods; all public methods dealing with selection go here
145 static void ClearSelection();
146 BOOL
GetViewSelection(int& start
, int& end
) const;
147 BOOL
HasSelection() const { return (!((m_nSelViewBlockEnd
< 0)||(m_nSelViewBlockStart
< 0)||(m_nSelViewBlockStart
> m_nSelViewBlockEnd
))); }
148 BOOL
HasTextSelection() const { return ((m_ptSelectionViewPosStart
.x
!= m_ptSelectionViewPosEnd
.x
) || (m_ptSelectionViewPosStart
.y
!= m_ptSelectionViewPosEnd
.y
)); }
149 BOOL
HasTextLineSelection() const { return m_ptSelectionViewPosStart
.y
!= m_ptSelectionViewPosEnd
.y
; }
150 static void SetupAllViewSelection(int start
, int end
);
151 static void SetupAllSelection(int start
, int end
);
152 void SetupSelection(int start
, int end
);
153 static void SetupViewSelection(CBaseView
* view
, int start
, int end
);
154 void SetupViewSelection(int start
, int end
);
155 CString
GetSelectedText() const;
156 void CheckModifications(bool& hasMods
, bool& hasConflicts
, bool& hasWhitespaceMods
);
158 // state classifying methods; note: state may belong to more classes
159 static bool IsStateConflicted(DiffStates state
);
160 static bool IsStateEmpty(DiffStates state
);
161 static bool IsStateRemoved(DiffStates state
);
162 static DiffStates
ResolveState(DiffStates state
);
164 bool IsLineEmpty(int nLineIndex
);
165 bool IsViewLineEmpty(int nViewLine
);
166 bool IsLineRemoved(int nLineIndex
);
167 bool IsViewLineRemoved(int nViewLine
);
168 bool IsBlockWhitespaceOnly(int nLineIndex
, bool& bIdentical
, int& blockstart
, int& blockend
);
169 bool IsViewLineConflicted(int nLineIndex
);
170 bool HasNextConflict();
171 bool HasPrevConflict();
174 bool GetNextInlineDiff(int & nPos
);
175 bool GetPrevInlineDiff(int & nPos
);
176 bool HasNextInlineDiff();
177 bool HasPrevInlineDiff();
179 static const viewdata
& GetEmptyLineData();
180 void InsertViewEmptyLines(int nFirstView
, int nCount
);
182 virtual void UseBothLeftFirst() {return UseBothBlocks(m_pwndLeft
, m_pwndRight
); }
183 virtual void UseBothRightFirst() {return UseBothBlocks(m_pwndRight
, m_pwndLeft
); }
184 void UseTheirAndYourBlock() {return UseBothLeftFirst(); } ///< ! for backward compatibility
185 void UseYourAndTheirBlock() {return UseBothRightFirst(); } ///< ! for backward compatibility
187 virtual void UseLeftBlock() {return UseViewBlock(m_pwndLeft
); }
188 virtual void UseLeftFile() {return UseViewFile(m_pwndLeft
); }
189 virtual void UseRightBlock() {return UseViewBlock(m_pwndRight
); }
190 virtual void UseRightFile() {return UseViewFile(m_pwndRight
); }
191 virtual void LeaveOnlyMarkedBlocks() { return LeaveOnlyMarkedBlocks(m_pwndLeft
); }
192 virtual void UseViewFileOfMarked() { UseViewFileOfMarked(m_pwndLeft
); }
193 virtual void UseViewFileExceptEdited() { UseViewFileExceptEdited(m_pwndLeft
); }
196 void InsertViewData(int index
, const CString
& sLine
, DiffStates state
, int linenumber
, EOL ending
, HIDESTATE hide
, int movedline
);
197 void InsertViewData(int index
, const viewdata
& data
);
198 void RemoveViewData(int index
);
200 const viewdata
& GetViewData(int index
) const {return m_pViewData
->GetData(index
); }
201 const CString
& GetViewLine(int index
) const {return m_pViewData
->GetLine(index
); }
202 DiffStates
GetViewState(int index
) const {return m_pViewData
->GetState(index
); }
203 HIDESTATE
GetViewHideState(int index
) {return m_pViewData
->GetHideState(index
); }
204 int GetViewLineNumber(int index
) {return m_pViewData
->GetLineNumber(index
); }
205 int GetViewMovedIndex(int index
) {return m_pViewData
->GetMovedIndex(index
); }
206 int FindViewLineNumber(int number
) {return m_pViewData
->FindLineNumber(number
); }
207 EOL
GetViewLineEnding(int index
) const {return m_pViewData
->GetLineEnding(index
); }
208 bool GetViewMarked(int index
) const {return m_pViewData
->GetMarked(index
); }
210 int GetViewCount() const {return m_pViewData
? m_pViewData
->GetCount() : -1; }
212 void SetViewData(int index
, const viewdata
& data
);
213 void SetViewState(int index
, DiffStates state
);
214 void SetViewLine(int index
, const CString
& sLine
);
215 void SetViewLineNumber(int index
, int linenumber
);
216 void SetViewLineEnding(int index
, EOL ending
);
217 void SetViewMarked(int index
, bool marked
);
219 static bool IsViewGood(const CBaseView
* view
) { return (view
!= 0) && view
->IsWindowVisible(); }
220 static CBaseView
* GetFirstGoodView();
222 int GetIndentCharsForLine(int x
, int y
);
223 void AddIndentationForSelectedBlock();
224 void RemoveIndentationForSelectedBlock();
225 void ConvertTabToSpaces();
227 void RemoveTrailWhiteChars();
229 struct TWhitecharsProperties
232 bool HasTrailWhiteChars
;
233 bool HasSpacesToConvert
;
234 bool HasTabsToConvert
;
237 TWhitecharsProperties
GetWhitecharsProperties();
240 CViewData
* m_pViewData
;
241 CViewData
* m_pOtherViewData
;
242 CBaseView
* m_pOtherView
;
244 CString m_sWindowName
; ///< The name of the view which is shown as a window title to the user
245 CString m_sFullFilePath
; ///< The full path of the file shown
246 CString m_sConvertedFilePath
; ///< the path to the converted file that's shown in the view
247 CString m_sReflectedName
; ///< The reflected name of file
249 BOOL m_bViewWhitespace
; ///< If TRUE, then SPACE and TAB are shown as special characters
250 BOOL m_bShowInlineDiff
; ///< If TRUE, diffs in lines are marked colored
251 bool m_bShowSelection
; ///< If true, selection bars are shown and selected text darkened
252 bool m_bWhitespaceInlineDiffs
; ///< if true, inline diffs are shown for identical lines only differing in whitespace
253 int m_nTopLine
; ///< The topmost text line in the view
254 std::vector
<int> m_arMarkedWordLines
; ///< which lines contain a marked word
255 std::vector
<int> m_arFindStringLines
; ///< which lines contain a found string
257 static CLocatorBar
* m_pwndLocator
; ///< Pointer to the locator bar on the left
258 static CLineDiffBar
* m_pwndLineDiffBar
; ///< Pointer to the line diff bar at the bottom
259 static CMFCStatusBar
* m_pwndStatusBar
;///< Pointer to the status bar
260 static CMFCRibbonStatusBar
* m_pwndRibbonStatusBar
;///< Pointer to the status bar
261 static CMainFrame
* m_pMainFrame
; ///< Pointer to the mainframe
264 bool m_bEditorConfigEnabled
;
265 BOOL m_bEditorConfigLoaded
;
267 void GoToFirstDifference();
268 void GoToFirstConflict();
269 void AddEmptyViewLine(int nLineIndex
);
270 #define SAVE_REMOVEDLINES 1
271 int SaveFile(int Flags
= 0);
272 int SaveFileTo(CString FileName
, int Flags
= 0);
274 EOL
GetLineEndings(); ///< Get Line endings on view from lineendings or "mixed"
275 EOL
GetLineEndings(bool MixelEols
);
276 void ReplaceLineEndings(EOL
); ///< Set AUTO lineending and replaces all EOLs
277 void SetLineEndingStyle(EOL
); ///< Set AUTO lineending
278 UnicodeType
GetTextType() { return m_texttype
; }
279 void SetTextType(UnicodeType
); ///< Changes TextType
280 void AskUserForNewLineEndingsAndTextType(int); ///< Open gui
281 int GetTabMode() { return m_nTabMode
; }
282 void SetTabMode(int nTabMode
) { m_nTabMode
= nTabMode
; }
283 int GetTabSize() { return m_nTabSize
; }
284 void SetTabSize(int nTabSize
) { m_nTabSize
= nTabSize
; }
285 bool GetEditorConfigEnabled() { return m_bEditorConfigEnabled
; }
286 void SetEditorConfigEnabled(bool bEditorConfigEnabled
);
287 BOOL
GetEditorConfigLoaded() { return m_bEditorConfigLoaded
; }
289 CWorkingFile
* m_pWorkingFile
; ///< pointer to source/destination file parametrers
291 protected: // methods
297 virtual BOOL
PreCreateWindow(CREATESTRUCT
& cs
);
298 virtual void OnDraw(CDC
* pDC
);
299 virtual INT_PTR
OnToolHitTest(CPoint point
, TOOLINFO
* pTI
) const;
300 virtual BOOL
PreTranslateMessage(MSG
* pMsg
);
301 BOOL
OnToolTipNotify(UINT id
, NMHDR
*pNMHDR
, LRESULT
*pResult
);
302 afx_msg
void OnHScroll(UINT nSBCode
, UINT nPos
, CScrollBar
* pScrollBar
);
303 afx_msg
void OnVScroll(UINT nSBCode
, UINT nPos
, CScrollBar
* pScrollBar
);
304 afx_msg BOOL
OnEraseBkgnd(CDC
* pDC
);
305 afx_msg
int OnCreate(LPCREATESTRUCT lpCreateStruct
);
306 afx_msg
void OnDestroy();
307 afx_msg
void OnSize(UINT nType
, int cx
, int cy
);
308 afx_msg BOOL
OnMouseWheel(UINT nFlags
, short zDelta
, CPoint pt
);
309 afx_msg
void OnMouseHWheel(UINT nFlags
, short zDelta
, CPoint pt
);
310 afx_msg BOOL
OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
);
311 afx_msg
void OnKillFocus(CWnd
* pNewWnd
);
312 afx_msg
void OnSetFocus(CWnd
* pOldWnd
);
313 afx_msg
void OnContextMenu(CWnd
* pWnd
, CPoint point
);
314 afx_msg
void OnMergeNextdifference();
315 afx_msg
void OnMergePreviousdifference();
316 afx_msg
void OnMergePreviousconflict();
317 afx_msg
void OnMergeNextconflict();
318 afx_msg
void OnNavigateNextinlinediff();
319 afx_msg
void OnNavigatePrevinlinediff();
320 afx_msg
void OnKeyDown(UINT nChar
, UINT nRepCnt
, UINT nFlags
);
321 afx_msg
void OnLButtonDown(UINT nFlags
, CPoint point
);
322 afx_msg
void OnLButtonUp(UINT nFlags
, CPoint point
);
323 afx_msg
void OnLButtonDblClk(UINT nFlags
, CPoint point
);
324 virtual void OnLButtonTrippleClick(UINT nFlags
, CPoint point
) override
;
325 afx_msg
void OnEditCopy();
326 afx_msg
void OnMouseMove(UINT nFlags
, CPoint point
);
327 afx_msg
void OnTimer(UINT_PTR nIDEvent
);
328 afx_msg
void OnChar(UINT nChar
, UINT nRepCnt
, UINT nFlags
);
329 afx_msg
void OnCaretDown();
330 afx_msg
void OnCaretLeft();
331 afx_msg
void OnCaretRight();
332 afx_msg
void OnCaretUp();
333 afx_msg
void OnCaretWordleft();
334 afx_msg
void OnCaretWordright();
335 afx_msg
void OnEditCut();
336 afx_msg
void OnEditPaste();
337 afx_msg
void OnEditSelectall();
338 afx_msg LRESULT
OnFindDialogMessage(WPARAM wParam
, LPARAM lParam
);
339 afx_msg
void OnEditFind();
340 afx_msg
void OnEditFindnext();
341 afx_msg
void OnEditFindprev();
342 afx_msg
void OnEditFindnextStart();
343 afx_msg
void OnEditFindprevStart();
344 afx_msg
void OnEditGotoline();
345 afx_msg
void OnToggleReadonly();
347 DECLARE_MESSAGE_MAP()
349 void DrawHeader(CDC
*pdc
, const CRect
&rect
);
350 void DrawMargin(CDC
*pdc
, const CRect
&rect
, int nLineIndex
);
351 void DrawSingleLine(CDC
*pDC
, const CRect
&rc
, int nLineIndex
);
353 * Draws the horizontal lines around current diff block or selection block.
355 void DrawBlockLine(CDC
*pDC
, const CRect
&rc
, int nLineIndex
);
357 * Draws the line ending 'char'.
359 void DrawLineEnding(CDC
*pDC
, const CRect
&rc
, int nLineIndex
, const CPoint
& origin
);
360 void ExpandChars(const CString
&sLine
, int nOffset
, int nCount
, CString
&line
);
361 CString
ExpandChars(const CString
&sLine
, int nOffset
= 0);
362 int CountExpandedChars(const CString
&sLine
, int nLength
);
364 void RecalcVertScrollBar(BOOL bPositionOnly
= FALSE
);
365 void RecalcHorzScrollBar(BOOL bPositionOnly
= FALSE
);
367 void OnDoMouseWheel(UINT nFlags
, short zDelta
, CPoint pt
);
368 void OnDoMouseHWheel(UINT nFlags
, short zDelta
, CPoint pt
);
369 void OnDoHScroll(UINT nSBCode
, UINT nPos
, CScrollBar
* pScrollBar
, CBaseView
* master
);
370 void OnDoVScroll(UINT nSBCode
, UINT nPos
, CScrollBar
* pScrollBar
, CBaseView
* master
);
372 void ShowDiffLines(int nLine
);
374 int GetTabSize() const {return m_nTabSize
;}
377 void CalcLineCharDim();
380 int GetMaxLineLength();
381 int GetLineLength(int index
);
382 int GetLineLengthWithTabsConverted(int index
);
383 int GetViewLineLength(int index
) const;
384 int GetScreenChars();
385 int GetAllMinScreenChars() const;
386 int GetAllMaxLineLength() const;
387 int GetAllLineCount() const;
388 int GetAllMinScreenLines() const;
389 CString
GetViewLineChars(int index
) const;
390 CString
GetLineChars(int index
);
391 int GetLineNumber(int index
) const;
392 CFont
* GetFont(BOOL bItalic
= FALSE
, BOOL bBold
= FALSE
);
393 int GetLineFromPoint(CPoint point
);
394 int GetMarginWidth();
395 COLORREF
InlineDiffColor(int nLineIndex
);
396 COLORREF
InlineViewLineDiffColor(int nLineIndex
);
397 bool GetInlineDiffPositions(int lineIndex
, std::vector
<inlineDiffPos
>& positions
);
398 void CheckOtherView();
399 void GetWhitespaceBlock(CViewData
*viewData
, int nLineIndex
, int & nStartBlock
, int & nEndBlock
);
400 CString
GetWhitespaceString(CViewData
*viewData
, int nStartBlock
, int nEndBlock
);
401 bool IsViewLineHidden(int nViewLine
);
402 static bool IsViewLineHidden(CViewData
* pViewData
, int nViewLine
);
404 void OnContextMenu(CPoint point
, DiffStates state
);
406 * Updates the status bar pane. Call this if the document changed.
408 void UpdateStatusBar();
410 static bool IsLeftViewGood() {return IsViewGood(m_pwndLeft
);}
411 static bool IsRightViewGood() {return IsViewGood(m_pwndRight
);}
412 static bool IsBottomViewGood() {return IsViewGood(m_pwndBottom
);}
414 int CalculateActualOffset(const POINT
& point
);
415 int CalculateCharIndex(int nLineIndex
, int nActualOffset
);
416 int CalcColFromPoint(int xpos
, int lineIndex
);
417 POINT
TextToClient(const POINT
& point
);
418 void DrawTextLine(CDC
* pDC
, const CRect
&rc
, int nLineIndex
, POINT
& coords
);
419 void ClearCurrentSelection();
420 void AdjustSelection(bool bMoveLeft
);
421 bool SelectNextBlock(int nDirection
, bool bConflict
, bool bSkipEndOfCurrentBlock
= true, bool dryrun
= false);
423 enum SearchDirection
{SearchNext
=0, SearchPrevious
=1};
424 bool StringFound(const CString
& str
, SearchDirection srchDir
, int& start
, int& end
) const;
425 bool Search(SearchDirection srchDir
, bool useStart
, bool flashIfNotFound
, bool stopEof
);
426 void BuildFindStringArray();
428 void RemoveLine(int nLineIndex
);
429 void RemoveSelectedText();
431 void InsertText(const CString
& sText
);
432 void AddUndoViewLine(int nViewLine
, bool bAddEmptyLine
= false);
434 bool MoveCaretLeft();
435 bool MoveCaretRight();
436 void MoveCaretWordLeft();
437 void MoveCaretWordRight();
438 void OnCaretMove(bool bMoveLeft
);
439 void OnCaretMove(bool bMoveLeft
, bool isShiftPressed
);
440 void UpdateGoalPos();
442 ECharGroup
GetCharGroup(const CString
&str
, int index
) const { return index
>= 0 && index
< str
.GetLength() ? GetCharGroup(str
[index
]) : CHG_UNKNOWN
; }
443 ECharGroup
GetCharGroup(const wchar_t zChar
) const;
444 bool IsWordSeparator(const wchar_t ch
) const;
445 bool IsCaretAtWordBoundary();
446 void UpdateViewsCaretPosition();
447 void BuildMarkedWordArray();
449 virtual void UseBothBlocks(CBaseView
* /*pwndFirst*/, CBaseView
* /*pwndLast*/) {};
450 virtual void UseViewBlock(CBaseView
* /*pwndView*/) {}
451 void UseViewBlock(CBaseView
* pwndView
, int nFirstViewLine
, int nLastViewLine
, std::function
<bool(int)> fnSkip
= [] (int) -> bool { return false; });
452 virtual void UseViewFile(CBaseView
* /*pwndView*/) {}
453 virtual void MarkBlock(bool /*marked*/) {}
454 void MarkBlock(bool marked
, int nFirstViewLine
, int nLastViewLine
);
455 void LeaveOnlyMarkedBlocks(CBaseView
*pwndView
);
456 void UseViewFileOfMarked(CBaseView
*pwndView
);
457 void UseViewFileExceptEdited(CBaseView
*pwndView
);
459 virtual void AddContextItems(CIconMenu
& popup
, DiffStates state
);
460 void AddCutCopyAndPaste(CIconMenu
& popup
);
461 void CompensateForKeyboard(CPoint
& point
);
462 static HICON
LoadIcon(WORD iconId
);
463 void ReleaseBitmap();
464 static bool LinesInOneChange( int direction
, DiffStates firstLineState
, DiffStates currentLineState
);
465 static void FilterWhitespaces(CString
& first
, CString
& second
);
466 static void FilterWhitespaces(CString
& line
);
467 int GetButtonEventLineIndex(const POINT
& point
);
469 static void ResetUndoStep();
471 protected: // variables
472 COLORREF m_InlineRemovedBk
;
473 COLORREF m_InlineAddedBk
;
474 COLORREF m_ModifiedBk
;
475 COLORREF m_WhiteSpaceFg
;
476 UINT m_nStatusBarID
; ///< The ID of the status bar pane used by this view. Must be set by the parent class.
478 SVNLineDiff m_svnlinediff
;
479 DWORD m_nInlineDiffMaxLineLength
;
480 BOOL m_bOtherDiffChecked
;
483 BOOL m_bViewLinenumbers
;
488 int m_nMaxLineLength
;
491 int m_nLastScreenChars
;
495 bool m_bInlineWordDiff
;
497 // Block selection attributes
498 int m_nSelViewBlockStart
;
499 int m_nSelViewBlockEnd
;
502 bool m_mouseInMargin
;
503 HCURSOR m_margincursor
;
507 bool m_bReadonlyIsChangable
;
508 bool m_bTarget
; ///< view intended as result
509 POINT m_ptCaretViewPos
;
512 // Text selection attributes
513 POINT m_ptSelectionViewPosStart
;
514 POINT m_ptSelectionViewPosEnd
;
515 POINT m_ptSelectionViewPosOrigin
;
517 static const UINT m_FindDialogMessage
;
518 CFindDlg
* m_pFindDialog
;
526 HICON m_hRemovedIcon
;
527 HICON m_hConflictedIcon
;
528 HICON m_hConflictedIgnoredIcon
;
529 HICON m_hWhitespaceBlockIcon
;
533 HICON m_hLineEndingCR
;
534 HICON m_hLineEndingCRLF
;
535 HICON m_hLineEndingLF
;
540 LOGFONT m_lfBaseFont
;
541 static const int fontsCount
= 4;
542 CFont
* m_apFonts
[fontsCount
];
543 CString m_sConflictedText
;
545 CString m_sMarkedWord
;
546 CString m_sPreviousMarkedWord
;
548 CBitmap
* m_pCacheBitmap
;
550 CScrollTool m_ScrollTool
;
551 CString m_sWordSeparators
;
552 CString m_Eols
[EOL__COUNT
];
554 UnicodeType m_texttype
; ///< the text encoding this view uses
555 EOL m_lineendings
; ///< the line endings the view uses
558 char m_szTip
[MAX_PATH
*2+1];
559 wchar_t m_wszTip
[MAX_PATH
*2+1];
560 // These three pointers lead to the three parent
561 // classes CLeftView, CRightView and CBottomView
562 // and are used for the communication between
563 // the views (e.g. synchronized scrolling, ...)
564 // To find out which parent class this object
565 // is made of just compare e.g. (m_pwndLeft==this).
566 static CBaseView
* m_pwndLeft
; ///< Pointer to the left view. Must be set by the CLeftView parent class.
567 static CBaseView
* m_pwndRight
; ///< Pointer to the right view. Must be set by the CRightView parent class.
568 static CBaseView
* m_pwndBottom
; ///< Pointer to the bottom view. Must be set by the CBottomView parent class.
570 struct TScreenLineInfo
575 class TScreenedViewLine
585 bSublinesSet
= false;
587 bLineColorsSet
= false;
588 bLineColorsSetWhiteSpace
= false;
592 std::vector
<CString
> SubLines
;
609 bool bLineColorsSetWhiteSpace
;
610 LineColors lineColorsWhiteSpace
;
612 LineColors lineColors
;
614 std::vector
<TScreenedViewLine
> m_ScreenedViewLine
; ///< cached data for screening
616 static allviewstate m_AllState
;
617 viewstate
* m_pState
;
621 POPUPCOMMAND_DISMISSED
= 0,
622 // 2-pane view commands
623 POPUPCOMMAND_USELEFTBLOCK
,
624 POPUPCOMMAND_USELEFTFILE
,
625 POPUPCOMMAND_USEBOTHLEFTFIRST
,
626 POPUPCOMMAND_USEBOTHRIGHTFIRST
,
627 POPUPCOMMAND_MARKBLOCK
,
628 POPUPCOMMAND_UNMARKBLOCK
,
629 POPUPCOMMAND_LEAVEONLYMARKEDBLOCKS
,
630 // multiple writable views
631 POPUPCOMMAND_PREPENDFROMRIGHT
,
632 POPUPCOMMAND_REPLACEBYRIGHT
,
633 POPUPCOMMAND_APPENDFROMRIGHT
,
634 POPUPCOMMAND_USERIGHTFILE
,
635 // 3-pane view commands
636 POPUPCOMMAND_USEYOURANDTHEIRBLOCK
,
637 POPUPCOMMAND_USETHEIRANDYOURBLOCK
,
638 POPUPCOMMAND_USEYOURBLOCK
,
639 POPUPCOMMAND_USEYOURFILE
,
640 POPUPCOMMAND_USETHEIRBLOCK
,
641 POPUPCOMMAND_USETHEIRFILE
,
643 POPUPCOMMAND_TABTOSPACES
,
644 POPUPCOMMAND_SPACESTOTABS
,
645 POPUPCOMMAND_REMOVETRAILWHITES
,
654 : m_pViewData(nullptr)
657 int GetViewLineForScreen(int screenLine
);
658 int GetSubLineOffset(int screenLine
);
659 TScreenLineInfo
GetScreenLineInfo(int screenLine
);
660 int FindScreenLineForViewLine(int viewLine
);
661 void ScheduleFullRebuild(CViewData
* ViewData
);
662 void ScheduleRangeRebuild(CViewData
* ViewData
, int FirstViewLine
, int LastViewLine
);
672 bool FixScreenedCacheSize(CBaseView
* View
);
673 void RebuildIfNecessary();
674 bool ResetScreenedViewLineCache(CBaseView
* View
) const;
675 bool ResetScreenedViewLineCache(CBaseView
* View
, const TRebuildRange
& Range
) const;
677 CViewData
* m_pViewData
;
679 std::vector
<TScreenLineInfo
> m_Screen2View
;
680 std::vector
<TRebuildRange
> m_RebuildRanges
;
683 static Screen2View m_Screen2View
;
684 CFileTextLines::SaveParams m_SaveParams
; ///< encoding and new line style for saving