1 // TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2003-2014 - 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 void ClearStepModifiedMark() { m_pState
->modifies
= false; }
137 void SetInlineWordDiff(bool bWord
) {m_bInlineWordDiff
= bWord
;}
138 void SetInlineDiff(bool bDiff
) {m_bShowInlineDiff
= bDiff
;}
139 void SetMarkedWord(const CString
& word
) {m_sMarkedWord
= word
; BuildMarkedWordArray();}
140 LPCTSTR
GetMarkedWord() {return (LPCTSTR
)m_sMarkedWord
;}
141 LPCTSTR
GetFindString() {return (LPCTSTR
)m_sFindText
;}
143 // Selection methods; all public methods dealing with selection go here
144 static void ClearSelection();
145 BOOL
GetViewSelection(int& start
, int& end
) const;
146 BOOL
HasSelection() const { return (!((m_nSelViewBlockEnd
< 0)||(m_nSelViewBlockStart
< 0)||(m_nSelViewBlockStart
> m_nSelViewBlockEnd
))); }
147 BOOL
HasTextSelection() const { return ((m_ptSelectionViewPosStart
.x
!= m_ptSelectionViewPosEnd
.x
) || (m_ptSelectionViewPosStart
.y
!= m_ptSelectionViewPosEnd
.y
)); }
148 BOOL
HasTextLineSelection() const { return m_ptSelectionViewPosStart
.y
!= m_ptSelectionViewPosEnd
.y
; }
149 static void SetupAllViewSelection(int start
, int end
);
150 static void SetupAllSelection(int start
, int end
);
151 void SetupSelection(int start
, int end
);
152 static void SetupViewSelection(CBaseView
* view
, int start
, int end
);
153 void SetupViewSelection(int start
, int end
);
154 CString
GetSelectedText() const;
155 void CheckModifications(bool& hasMods
, bool& hasConflicts
, bool& hasWhitespaceMods
);
157 // state classifying methods; note: state may belong to more classes
158 static bool IsStateConflicted(DiffStates state
);
159 static bool IsStateEmpty(DiffStates state
);
160 static bool IsStateRemoved(DiffStates state
);
161 static DiffStates
ResolveState(DiffStates state
);
163 bool IsLineEmpty(int nLineIndex
);
164 bool IsViewLineEmpty(int nViewLine
);
165 bool IsLineRemoved(int nLineIndex
);
166 bool IsViewLineRemoved(int nViewLine
);
167 bool IsBlockWhitespaceOnly(int nLineIndex
, bool& bIdentical
, int& blockstart
, int& blockend
);
168 bool IsViewLineConflicted(int nLineIndex
);
169 bool HasNextConflict();
170 bool HasPrevConflict();
173 bool GetNextInlineDiff(int & nPos
);
174 bool GetPrevInlineDiff(int & nPos
);
175 bool HasNextInlineDiff();
176 bool HasPrevInlineDiff();
178 static const viewdata
& GetEmptyLineData();
179 void InsertViewEmptyLines(int nFirstView
, int nCount
);
181 virtual void UseBothLeftFirst() {return UseBothBlocks(m_pwndLeft
, m_pwndRight
); }
182 virtual void UseBothRightFirst() {return UseBothBlocks(m_pwndRight
, m_pwndLeft
); }
183 void UseTheirAndYourBlock() {return UseBothLeftFirst(); } ///< ! for backward compatibility
184 void UseYourAndTheirBlock() {return UseBothRightFirst(); } ///< ! for backward compatibility
186 virtual void UseLeftBlock() {return UseViewBlock(m_pwndLeft
); }
187 virtual void UseLeftFile() {return UseViewFile(m_pwndLeft
); }
188 virtual void UseRightBlock() {return UseViewBlock(m_pwndRight
); }
189 virtual void UseRightFile() {return UseViewFile(m_pwndRight
); }
190 virtual void UseLeftFileExceptMarked() { return UseViewFileExceptMarked(m_pwndLeft
); }
193 void InsertViewData(int index
, const CString
& sLine
, DiffStates state
, int linenumber
, EOL ending
, HIDESTATE hide
, int movedline
);
194 void InsertViewData(int index
, const viewdata
& data
);
195 void RemoveViewData(int index
);
197 const viewdata
& GetViewData(int index
) const {return m_pViewData
->GetData(index
); }
198 const CString
& GetViewLine(int index
) const {return m_pViewData
->GetLine(index
); }
199 DiffStates
GetViewState(int index
) const {return m_pViewData
->GetState(index
); }
200 HIDESTATE
GetViewHideState(int index
) {return m_pViewData
->GetHideState(index
); }
201 int GetViewLineNumber(int index
) {return m_pViewData
->GetLineNumber(index
); }
202 int GetViewMovedIndex(int index
) {return m_pViewData
->GetMovedIndex(index
); }
203 int FindViewLineNumber(int number
) {return m_pViewData
->FindLineNumber(number
); }
204 EOL
GetViewLineEnding(int index
) const {return m_pViewData
->GetLineEnding(index
); }
205 bool GetViewMarked(int index
) const {return m_pViewData
->GetMarked(index
); }
207 int GetViewCount() const {return m_pViewData
? m_pViewData
->GetCount() : -1; }
209 void SetViewData(int index
, const viewdata
& data
);
210 void SetViewState(int index
, DiffStates state
);
211 void SetViewLine(int index
, const CString
& sLine
);
212 void SetViewLineNumber(int index
, int linenumber
);
213 void SetViewLineEnding(int index
, EOL ending
);
214 void SetViewMarked(int index
, bool marked
);
216 static bool IsViewGood(const CBaseView
* view
) { return (view
!= 0) && view
->IsWindowVisible(); }
217 static CBaseView
* GetFirstGoodView();
219 int GetIndentCharsForLine(int x
, int y
);
220 void AddIndentationForSelectedBlock();
221 void RemoveIndentationForSelectedBlock();
222 void ConvertTabToSpaces();
224 void RemoveTrailWhiteChars();
226 struct TWhitecharsProperties
229 bool HasTrailWhiteChars
;
230 bool HasSpacesToConvert
;
231 bool HasTabsToConvert
;
234 TWhitecharsProperties
GetWhitecharsProperties();
237 CViewData
* m_pViewData
;
238 CViewData
* m_pOtherViewData
;
239 CBaseView
* m_pOtherView
;
241 CString m_sWindowName
; ///< The name of the view which is shown as a window title to the user
242 CString m_sFullFilePath
; ///< The full path of the file shown
243 CString m_sConvertedFilePath
; ///< the path to the converted file that's shown in the view
244 CString m_sReflectedName
; ///< The reflected name of file
246 BOOL m_bViewWhitespace
; ///< If TRUE, then SPACE and TAB are shown as special characters
247 BOOL m_bShowInlineDiff
; ///< If TRUE, diffs in lines are marked colored
248 bool m_bShowSelection
; ///< If true, selection bars are shown and selected text darkened
249 bool m_bWhitespaceInlineDiffs
; ///< if true, inline diffs are shown for identical lines only differing in whitespace
250 int m_nTopLine
; ///< The topmost text line in the view
251 std::vector
<int> m_arMarkedWordLines
; ///< which lines contain a marked word
252 std::vector
<int> m_arFindStringLines
; ///< which lines contain a found string
254 static CLocatorBar
* m_pwndLocator
; ///< Pointer to the locator bar on the left
255 static CLineDiffBar
* m_pwndLineDiffBar
; ///< Pointer to the line diff bar at the bottom
256 static CMFCStatusBar
* m_pwndStatusBar
;///< Pointer to the status bar
257 static CMFCRibbonStatusBar
* m_pwndRibbonStatusBar
;///< Pointer to the status bar
258 static CMainFrame
* m_pMainFrame
; ///< Pointer to the mainframe
261 bool m_bEditorConfigEnabled
;
262 BOOL m_bEditorConfigLoaded
;
264 void GoToFirstDifference();
265 void GoToFirstConflict();
266 void AddEmptyViewLine(int nLineIndex
);
267 #define SAVE_REMOVEDLINES 1
268 int SaveFile(int Flags
= 0);
269 int SaveFileTo(CString FileName
, int Flags
= 0);
271 EOL
GetLineEndings(); ///< Get Line endings on view from lineendings or "mixed"
272 EOL
GetLineEndings(bool MixelEols
);
273 void ReplaceLineEndings(EOL
); ///< Set AUTO lineending and replaces all EOLs
274 void SetLineEndingStyle(EOL
); ///< Set AUTO lineending
275 UnicodeType
GetTextType() { return m_texttype
; }
276 void SetTextType(UnicodeType
); ///< Changes TextType
277 void AskUserForNewLineEndingsAndTextType(int); ///< Open gui
278 int GetTabMode() { return m_nTabMode
; }
279 void SetTabMode(int nTabMode
) { m_nTabMode
= nTabMode
; }
280 int GetTabSize() { return m_nTabSize
; }
281 void SetTabSize(int nTabSize
) { m_nTabSize
= nTabSize
; }
282 bool GetEditorConfigEnabled() { return m_bEditorConfigEnabled
; }
283 void SetEditorConfigEnabled(bool bEditorConfigEnabled
);
284 BOOL
GetEditorConfigLoaded() { return m_bEditorConfigLoaded
; }
286 CWorkingFile
* m_pWorkingFile
; ///< pointer to source/destination file parametrers
288 protected: // methods
294 virtual BOOL
PreCreateWindow(CREATESTRUCT
& cs
);
295 virtual void OnDraw(CDC
* pDC
);
296 virtual INT_PTR
OnToolHitTest(CPoint point
, TOOLINFO
* pTI
) const;
297 virtual BOOL
PreTranslateMessage(MSG
* pMsg
);
298 BOOL
OnToolTipNotify(UINT id
, NMHDR
*pNMHDR
, LRESULT
*pResult
);
299 afx_msg
void OnHScroll(UINT nSBCode
, UINT nPos
, CScrollBar
* pScrollBar
);
300 afx_msg
void OnVScroll(UINT nSBCode
, UINT nPos
, CScrollBar
* pScrollBar
);
301 afx_msg BOOL
OnEraseBkgnd(CDC
* pDC
);
302 afx_msg
int OnCreate(LPCREATESTRUCT lpCreateStruct
);
303 afx_msg
void OnDestroy();
304 afx_msg
void OnSize(UINT nType
, int cx
, int cy
);
305 afx_msg BOOL
OnMouseWheel(UINT nFlags
, short zDelta
, CPoint pt
);
306 afx_msg
void OnMouseHWheel(UINT nFlags
, short zDelta
, CPoint pt
);
307 afx_msg BOOL
OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
);
308 afx_msg
void OnKillFocus(CWnd
* pNewWnd
);
309 afx_msg
void OnSetFocus(CWnd
* pOldWnd
);
310 afx_msg
void OnContextMenu(CWnd
* pWnd
, CPoint point
);
311 afx_msg
void OnMergeNextdifference();
312 afx_msg
void OnMergePreviousdifference();
313 afx_msg
void OnMergePreviousconflict();
314 afx_msg
void OnMergeNextconflict();
315 afx_msg
void OnNavigateNextinlinediff();
316 afx_msg
void OnNavigatePrevinlinediff();
317 afx_msg
void OnKeyDown(UINT nChar
, UINT nRepCnt
, UINT nFlags
);
318 afx_msg
void OnLButtonDown(UINT nFlags
, CPoint point
);
319 afx_msg
void OnLButtonUp(UINT nFlags
, CPoint point
);
320 afx_msg
void OnLButtonDblClk(UINT nFlags
, CPoint point
);
321 virtual void OnLButtonTrippleClick(UINT nFlags
, CPoint point
) override
;
322 afx_msg
void OnEditCopy();
323 afx_msg
void OnMouseMove(UINT nFlags
, CPoint point
);
324 afx_msg
void OnTimer(UINT_PTR nIDEvent
);
325 afx_msg
void OnChar(UINT nChar
, UINT nRepCnt
, UINT nFlags
);
326 afx_msg
void OnCaretDown();
327 afx_msg
void OnCaretLeft();
328 afx_msg
void OnCaretRight();
329 afx_msg
void OnCaretUp();
330 afx_msg
void OnCaretWordleft();
331 afx_msg
void OnCaretWordright();
332 afx_msg
void OnEditCut();
333 afx_msg
void OnEditPaste();
334 afx_msg
void OnEditSelectall();
335 afx_msg LRESULT
OnFindDialogMessage(WPARAM wParam
, LPARAM lParam
);
336 afx_msg
void OnEditFind();
337 afx_msg
void OnEditFindnext();
338 afx_msg
void OnEditFindprev();
339 afx_msg
void OnEditFindnextStart();
340 afx_msg
void OnEditFindprevStart();
341 afx_msg
void OnEditGotoline();
342 afx_msg
void OnToggleReadonly();
344 DECLARE_MESSAGE_MAP()
346 void DrawHeader(CDC
*pdc
, const CRect
&rect
);
347 void DrawMargin(CDC
*pdc
, const CRect
&rect
, int nLineIndex
);
348 void DrawSingleLine(CDC
*pDC
, const CRect
&rc
, int nLineIndex
);
350 * Draws the horizontal lines around current diff block or selection block.
352 void DrawBlockLine(CDC
*pDC
, const CRect
&rc
, int nLineIndex
);
354 * Draws the line ending 'char'.
356 void DrawLineEnding(CDC
*pDC
, const CRect
&rc
, int nLineIndex
, const CPoint
& origin
);
357 void ExpandChars(const CString
&sLine
, int nOffset
, int nCount
, CString
&line
);
358 CString
ExpandChars(const CString
&sLine
, int nOffset
= 0);
359 int CountExpandedChars(const CString
&sLine
, int nLength
);
361 void RecalcVertScrollBar(BOOL bPositionOnly
= FALSE
);
362 void RecalcHorzScrollBar(BOOL bPositionOnly
= FALSE
);
364 void OnDoMouseWheel(UINT nFlags
, short zDelta
, CPoint pt
);
365 void OnDoMouseHWheel(UINT nFlags
, short zDelta
, CPoint pt
);
366 void OnDoHScroll(UINT nSBCode
, UINT nPos
, CScrollBar
* pScrollBar
, CBaseView
* master
);
367 void OnDoVScroll(UINT nSBCode
, UINT nPos
, CScrollBar
* pScrollBar
, CBaseView
* master
);
369 void ShowDiffLines(int nLine
);
371 int GetTabSize() const {return m_nTabSize
;}
374 void CalcLineCharDim();
377 int GetMaxLineLength();
378 int GetLineLength(int index
);
379 int GetViewLineLength(int index
) const;
380 int GetScreenChars();
381 int GetAllMinScreenChars() const;
382 int GetAllMaxLineLength() const;
383 int GetAllLineCount() const;
384 int GetAllMinScreenLines() const;
385 CString
GetViewLineChars(int index
) const;
386 CString
GetLineChars(int index
);
387 int GetLineNumber(int index
) const;
388 CFont
* GetFont(BOOL bItalic
= FALSE
, BOOL bBold
= FALSE
);
389 int GetLineFromPoint(CPoint point
);
390 int GetMarginWidth();
391 COLORREF
InlineDiffColor(int nLineIndex
);
392 COLORREF
InlineViewLineDiffColor(int nLineIndex
);
393 bool GetInlineDiffPositions(int lineIndex
, std::vector
<inlineDiffPos
>& positions
);
394 void CheckOtherView();
395 void GetWhitespaceBlock(CViewData
*viewData
, int nLineIndex
, int & nStartBlock
, int & nEndBlock
);
396 CString
GetWhitespaceString(CViewData
*viewData
, int nStartBlock
, int nEndBlock
);
397 bool IsViewLineHidden(int nViewLine
);
398 static bool IsViewLineHidden(CViewData
* pViewData
, int nViewLine
);
400 void OnContextMenu(CPoint point
, DiffStates state
);
402 * Updates the status bar pane. Call this if the document changed.
404 void UpdateStatusBar();
406 static bool IsLeftViewGood() {return IsViewGood(m_pwndLeft
);}
407 static bool IsRightViewGood() {return IsViewGood(m_pwndRight
);}
408 static bool IsBottomViewGood() {return IsViewGood(m_pwndBottom
);}
410 int CalculateActualOffset(const POINT
& point
);
411 int CalculateCharIndex(int nLineIndex
, int nActualOffset
);
412 int CalcColFromPoint(int xpos
, int lineIndex
);
413 POINT
TextToClient(const POINT
& point
);
414 void DrawTextLine(CDC
* pDC
, const CRect
&rc
, int nLineIndex
, POINT
& coords
);
415 void ClearCurrentSelection();
416 void AdjustSelection(bool bMoveLeft
);
417 bool SelectNextBlock(int nDirection
, bool bConflict
, bool bSkipEndOfCurrentBlock
= true, bool dryrun
= false);
419 enum SearchDirection
{SearchNext
=0, SearchPrevious
=1};
420 bool StringFound(const CString
& str
, SearchDirection srchDir
, int& start
, int& end
) const;
421 bool Search(SearchDirection srchDir
, bool useStart
, bool flashIfNotFound
, bool stopEof
);
422 void BuildFindStringArray();
424 void RemoveLine(int nLineIndex
);
425 void RemoveSelectedText();
427 void InsertText(const CString
& sText
);
428 void AddUndoViewLine(int nViewLine
, bool bAddEmptyLine
= false);
430 bool MoveCaretLeft();
431 bool MoveCaretRight();
432 void MoveCaretWordLeft();
433 void MoveCaretWordRight();
434 void OnCaretMove(bool bMoveLeft
);
435 void OnCaretMove(bool bMoveLeft
, bool isShiftPressed
);
436 void UpdateGoalPos();
438 ECharGroup
GetCharGroup(const CString
&str
, int index
) const { return index
>= 0 && index
< str
.GetLength() ? GetCharGroup(str
[index
]) : CHG_UNKNOWN
; }
439 ECharGroup
GetCharGroup(const wchar_t zChar
) const;
440 bool IsWordSeparator(const wchar_t ch
) const;
441 bool IsCaretAtWordBoundary();
442 void UpdateViewsCaretPosition();
443 void BuildMarkedWordArray();
445 virtual void UseBothBlocks(CBaseView
* /*pwndFirst*/, CBaseView
* /*pwndLast*/) {};
446 virtual void UseViewBlock(CBaseView
* /*pwndView*/) {}
447 void UseViewBlock(CBaseView
* pwndView
, int nFirstViewLine
, int nLastViewLine
, bool skipMarked
= false);
448 virtual void UseViewFile(CBaseView
* /*pwndView*/) {}
449 virtual void MarkBlock(bool /*marked*/) {}
450 void MarkBlock(bool marked
, int nFirstViewLine
, int nLastViewLine
);
451 void UseViewFileExceptMarked(CBaseView
*pwndView
);
453 virtual void AddContextItems(CIconMenu
& popup
, DiffStates state
);
454 void AddCutCopyAndPaste(CIconMenu
& popup
);
455 void CompensateForKeyboard(CPoint
& point
);
456 static HICON
LoadIcon(WORD iconId
);
457 void ReleaseBitmap();
458 static bool LinesInOneChange( int direction
, DiffStates firstLineState
, DiffStates currentLineState
);
459 static void FilterWhitespaces(CString
& first
, CString
& second
);
460 static void FilterWhitespaces(CString
& line
);
461 int GetButtonEventLineIndex(const POINT
& point
);
463 static void ResetUndoStep();
465 protected: // variables
466 COLORREF m_InlineRemovedBk
;
467 COLORREF m_InlineAddedBk
;
468 COLORREF m_ModifiedBk
;
469 COLORREF m_WhiteSpaceFg
;
470 UINT m_nStatusBarID
; ///< The ID of the status bar pane used by this view. Must be set by the parent class.
472 SVNLineDiff m_svnlinediff
;
473 DWORD m_nInlineDiffMaxLineLength
;
474 BOOL m_bOtherDiffChecked
;
477 BOOL m_bViewLinenumbers
;
482 int m_nMaxLineLength
;
485 int m_nLastScreenChars
;
489 bool m_bInlineWordDiff
;
491 // Block selection attributes
492 int m_nSelViewBlockStart
;
493 int m_nSelViewBlockEnd
;
496 bool m_mouseInMargin
;
497 HCURSOR m_margincursor
;
501 bool m_bReadonlyIsChangable
;
502 bool m_bTarget
; ///< view intended as result
503 POINT m_ptCaretViewPos
;
506 // Text selection attributes
507 POINT m_ptSelectionViewPosStart
;
508 POINT m_ptSelectionViewPosEnd
;
509 POINT m_ptSelectionViewPosOrigin
;
511 static const UINT m_FindDialogMessage
;
512 CFindDlg
* m_pFindDialog
;
520 HICON m_hRemovedIcon
;
521 HICON m_hConflictedIcon
;
522 HICON m_hConflictedIgnoredIcon
;
523 HICON m_hWhitespaceBlockIcon
;
527 HICON m_hLineEndingCR
;
528 HICON m_hLineEndingCRLF
;
529 HICON m_hLineEndingLF
;
534 LOGFONT m_lfBaseFont
;
535 static const int fontsCount
= 4;
536 CFont
* m_apFonts
[fontsCount
];
537 CString m_sConflictedText
;
539 CString m_sMarkedWord
;
540 CString m_sPreviousMarkedWord
;
542 CBitmap
* m_pCacheBitmap
;
544 CScrollTool m_ScrollTool
;
545 CString m_sWordSeparators
;
546 CString m_Eols
[EOL__COUNT
];
548 UnicodeType m_texttype
; ///< the text encoding this view uses
549 EOL m_lineendings
; ///< the line endings the view uses
552 char m_szTip
[MAX_PATH
*2+1];
553 wchar_t m_wszTip
[MAX_PATH
*2+1];
554 // These three pointers lead to the three parent
555 // classes CLeftView, CRightView and CBottomView
556 // and are used for the communication between
557 // the views (e.g. synchronized scrolling, ...)
558 // To find out which parent class this object
559 // is made of just compare e.g. (m_pwndLeft==this).
560 static CBaseView
* m_pwndLeft
; ///< Pointer to the left view. Must be set by the CLeftView parent class.
561 static CBaseView
* m_pwndRight
; ///< Pointer to the right view. Must be set by the CRightView parent class.
562 static CBaseView
* m_pwndBottom
; ///< Pointer to the bottom view. Must be set by the CBottomView parent class.
564 struct TScreenLineInfo
569 class TScreenedViewLine
579 bSublinesSet
= false;
581 bLineColorsSet
= false;
582 bLineColorsSetWhiteSpace
= false;
586 std::vector
<CString
> SubLines
;
603 bool bLineColorsSetWhiteSpace
;
604 LineColors lineColorsWhiteSpace
;
606 LineColors lineColors
;
608 std::vector
<TScreenedViewLine
> m_ScreenedViewLine
; ///< cached data for screening
610 static allviewstate m_AllState
;
611 viewstate
* m_pState
;
615 POPUPCOMMAND_DISMISSED
= 0,
616 // 2-pane view commands
617 POPUPCOMMAND_USELEFTBLOCK
,
618 POPUPCOMMAND_USELEFTFILE
,
619 POPUPCOMMAND_USEBOTHLEFTFIRST
,
620 POPUPCOMMAND_USEBOTHRIGHTFIRST
,
621 POPUPCOMMAND_MARKBLOCK
,
622 POPUPCOMMAND_UNMARKBLOCK
,
623 POPUPCOMMAND_USELEFTFILEEXCEPTMARKED
,
624 // multiple writable views
625 POPUPCOMMAND_PREPENDFROMRIGHT
,
626 POPUPCOMMAND_REPLACEBYRIGHT
,
627 POPUPCOMMAND_APPENDFROMRIGHT
,
628 POPUPCOMMAND_USERIGHTFILE
,
629 // 3-pane view commands
630 POPUPCOMMAND_USEYOURANDTHEIRBLOCK
,
631 POPUPCOMMAND_USETHEIRANDYOURBLOCK
,
632 POPUPCOMMAND_USEYOURBLOCK
,
633 POPUPCOMMAND_USEYOURFILE
,
634 POPUPCOMMAND_USETHEIRBLOCK
,
635 POPUPCOMMAND_USETHEIRFILE
,
637 POPUPCOMMAND_TABTOSPACES
,
638 POPUPCOMMAND_SPACESTOTABS
,
639 POPUPCOMMAND_REMOVETRAILWHITES
,
651 int GetViewLineForScreen(int screenLine
);
652 int GetSubLineOffset(int screenLine
);
653 TScreenLineInfo
GetScreenLineInfo(int screenLine
);
654 int FindScreenLineForViewLine(int viewLine
);
655 void ScheduleFullRebuild(CViewData
* ViewData
);
656 void ScheduleRangeRebuild(CViewData
* ViewData
, int FirstViewLine
, int LastViewLine
);
666 bool FixScreenedCacheSize(CBaseView
* View
);
667 void RebuildIfNecessary();
668 bool ResetScreenedViewLineCache(CBaseView
* View
) const;
669 bool ResetScreenedViewLineCache(CBaseView
* View
, const TRebuildRange
& Range
) const;
671 CViewData
* m_pViewData
;
673 std::vector
<TScreenLineInfo
> m_Screen2View
;
674 std::vector
<TRebuildRange
> m_RebuildRanges
;
677 static Screen2View m_Screen2View
;
678 CFileTextLines::SaveParams m_SaveParams
; ///< encoding and new line style for saving