1 // TortoiseMerge - a Diff/Patch program
\r
3 // Copyright (C) 2003-2008 - TortoiseSVN
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
20 #include "DiffData.h"
\r
21 #include "SVNLineDiff.h"
\r
22 #include "ScrollTool.h"
\r
24 #include "LocatorBar.h"
\r
27 * \ingroup TortoiseMerge
\r
29 * View class providing the basic functionality for
\r
30 * showing diffs. Has three parent classes which inherit
\r
31 * from this base class: CLeftView, CRightView and CBottomView.
\r
33 class CBaseView : public CView
\r
35 DECLARE_DYNCREATE(CBaseView)
\r
36 friend class CLineDiffBar;
\r
39 virtual ~CBaseView();
\r
43 * Indicates that the underlying document has been updated. Reloads all
\r
44 * data and redraws the view.
\r
46 virtual void DocumentUpdated();
\r
48 * Returns the number of lines visible on the view.
\r
50 int GetScreenLines();
\r
52 * Scrolls the view to the given line.
\r
53 * \param nNewTopLine The new top line to scroll the view to
\r
54 * \param bTrackScrollBar If TRUE, then the scrollbars are affected too.
\r
56 void ScrollToLine(int nNewTopLine, BOOL bTrackScrollBar = TRUE);
\r
57 void ScrollAllToLine(int nNewTopLine, BOOL bTrackScrollBar = TRUE);
\r
58 void ScrollSide(int delta);
\r
59 void GoToLine(int nNewLine, BOOL bAll = TRUE);
\r
60 void ScrollToChar(int nNewOffsetChar, BOOL bTrackScrollBar = TRUE);
\r
61 void UseCaret(bool bUse = true) {m_bCaretHidden = !bUse;}
\r
62 bool HasCaret() {return !m_bCaretHidden;}
\r
63 void SetCaretPosition(POINT pt) {m_ptCaretPos = pt ; m_nCaretGoalPos = pt.x; UpdateCaret();}
\r
64 void EnsureCaretVisible();
\r
66 void ClearSelection();
\r
67 void RefreshViews();
\r
69 void SelectLines(int nLine1, int nLine2 = -1);
\r
70 void HiglightLines(int start, int end = -1);
\r
71 inline BOOL IsHidden() const {return m_bIsHidden;}
\r
72 inline void SetHidden(BOOL bHidden) {m_bIsHidden = bHidden;}
\r
73 inline BOOL IsModified() const {return m_bModified;}
\r
74 void SetModified(BOOL bModified = TRUE) {m_bModified = bModified;}
\r
75 BOOL HasSelection() {return (!((m_nSelBlockEnd < 0)||(m_nSelBlockStart < 0)||(m_nSelBlockStart > m_nSelBlockEnd)));}
\r
76 BOOL HasTextSelection() {return ((m_ptSelectionStartPos.x != m_ptSelectionEndPos.x)||(m_ptSelectionStartPos.y != m_ptSelectionEndPos.y));}
\r
77 BOOL GetSelection(int& start, int& end) {start=m_nSelBlockStart; end=m_nSelBlockEnd; return HasSelection();}
\r
78 void SetInlineWordDiff(bool bWord) {m_bInlineWordDiff = bWord;}
\r
80 BOOL IsLineRemoved(int nLineIndex);
\r
81 bool IsBlockWhitespaceOnly(int nLineIndex, bool& bIdentical);
\r
82 bool IsLineConflicted(int nLineIndex);
\r
84 CViewData * m_pViewData;
\r
85 CViewData * m_pOtherViewData;
\r
87 CString m_sWindowName; ///< The name of the view which is shown as a window title to the user
\r
88 CString m_sFullFilePath; ///< The full path of the file shown
\r
89 CFileTextLines::UnicodeType texttype; ///< the text encoding this view uses
\r
90 EOL lineendings; ///< the line endings the view uses
\r
92 BOOL m_bViewWhitespace; ///< If TRUE, then SPACE and TAB are shown as special characters
\r
93 BOOL m_bShowInlineDiff; ///< If TRUE, diffs in lines are marked colored
\r
94 bool m_bShowSelection; ///< If true, selection bars are shown and selected text darkened
\r
95 int m_nTopLine; ///< The topmost text line in the view
\r
97 static CLocatorBar * m_pwndLocator; ///< Pointer to the locator bar on the left
\r
98 static CLineDiffBar * m_pwndLineDiffBar; ///< Pointer to the line diff bar at the bottom
\r
99 static CMFCStatusBar * m_pwndStatusBar;///< Pointer to the status bar
\r
100 static CMainFrame * m_pMainFrame; ///< Pointer to the mainframe
\r
102 void GoToFirstDifference();
\r
103 void AddEmptyLine(int nLineIndex);
\r
105 virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
\r
106 virtual void OnDraw(CDC * pDC);
\r
107 virtual INT_PTR OnToolHitTest(CPoint point, TOOLINFO* pTI) const;
\r
108 BOOL OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult);
\r
109 afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
\r
110 afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
\r
111 afx_msg BOOL OnEraseBkgnd(CDC* pDC);
\r
112 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
\r
113 afx_msg void OnDestroy();
\r
114 afx_msg void OnSize(UINT nType, int cx, int cy);
\r
115 afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
\r
116 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
\r
117 afx_msg void OnKillFocus(CWnd* pNewWnd);
\r
118 afx_msg void OnSetFocus(CWnd* pOldWnd);
\r
119 afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
\r
120 afx_msg void OnMergeNextdifference();
\r
121 afx_msg void OnMergePreviousdifference();
\r
122 afx_msg void OnMergePreviousconflict();
\r
123 afx_msg void OnMergeNextconflict();
\r
124 afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
\r
125 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
\r
126 afx_msg void OnEditCopy();
\r
127 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
\r
128 afx_msg void OnTimer(UINT_PTR nIDEvent);
\r
129 afx_msg void OnMouseLeave();
\r
130 afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
\r
131 afx_msg void OnCaretDown();
\r
132 afx_msg void OnCaretLeft();
\r
133 afx_msg void OnCaretRight();
\r
134 afx_msg void OnCaretUp();
\r
135 afx_msg void OnCaretWordleft();
\r
136 afx_msg void OnCaretWordright();
\r
137 afx_msg void OnEditCut();
\r
138 afx_msg void OnEditPaste();
\r
140 DECLARE_MESSAGE_MAP()
\r
143 void DrawHeader(CDC *pdc, const CRect &rect);
\r
144 void DrawMargin(CDC *pdc, const CRect &rect, int nLineIndex);
\r
145 void DrawSingleLine(CDC *pDC, const CRect &rc, int nLineIndex);
\r
146 bool DrawInlineDiff(CDC *pDC, const CRect &rc, int nLineIndex, const CString &line, CPoint &origin);
\r
148 * Draws the horizontal lines around current diff block or selection block.
\r
150 void DrawBlockLine(CDC *pDC, const CRect &rc, int nLineIndex);
\r
152 * Draws the line ending 'char'.
\r
154 void DrawLineEnding(CDC *pDC, const CRect &rc, int nLineIndex, const CPoint& origin);
\r
155 void ExpandChars(LPCTSTR pszChars, int nOffset, int nCount, CString &line);
\r
157 void RecalcVertScrollBar(BOOL bPositionOnly = FALSE);
\r
158 void RecalcAllVertScrollBars(BOOL bPositionOnly = FALSE);
\r
159 void RecalcHorzScrollBar(BOOL bPositionOnly = FALSE);
\r
160 void RecalcAllHorzScrollBars(BOOL bPositionOnly = FALSE);
\r
162 void OnDoMouseWheel(UINT nFlags, short zDelta, CPoint pt);
\r
163 void OnDoHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar, CBaseView * master);
\r
164 void OnDoVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar, CBaseView * master);
\r
166 void SetupSelection(int start, int end);
\r
167 void ShowDiffLines(int nLine);
\r
169 int GetTabSize() const {return m_nTabSize;}
\r
171 int GetLineActualLength(int index) const;
\r
172 int GetLineCount() const;
\r
173 void CalcLineCharDim();
\r
174 int GetLineHeight();
\r
175 int GetCharWidth();
\r
176 int GetMaxLineLength();
\r
177 int GetLineLength(int index) const;
\r
178 int GetScreenChars();
\r
179 int GetAllMinScreenChars() const;
\r
180 int GetAllMaxLineLength() const;
\r
181 int GetAllLineCount() const;
\r
182 int GetAllMinScreenLines() const;
\r
183 LPCTSTR GetLineChars(int index) const;
\r
184 int GetLineNumber(int index) const;
\r
185 CFont * GetFont(BOOL bItalic = FALSE, BOOL bBold = FALSE, BOOL bStrikeOut = FALSE);
\r
186 int GetLineFromPoint(CPoint point);
\r
187 int GetMarginWidth();
\r
188 COLORREF IntenseColor(long scale, COLORREF col);
\r
189 COLORREF InlineDiffColor(int nLineIndex);
\r
190 void CheckOtherView();
\r
191 static CString GetWhitespaceBlock(CViewData *viewData, int nLineIndex);
\r
193 /// Returns true if selection should be kept
\r
194 virtual bool OnContextMenu(CPoint point, int nLine, DiffStates state);
\r
196 * Updates the status bar pane. Call this if the document changed.
\r
198 void UpdateStatusBar();
\r
200 void UseTheirAndYourBlock(viewstate &rightstate, viewstate &bottomstate, viewstate &leftstate);
\r
201 void UseYourAndTheirBlock(viewstate &rightstate, viewstate &bottomstate, viewstate &leftstate);
\r
202 void UseBothLeftFirst(viewstate &rightstate, viewstate &leftstate);
\r
203 void UseBothRightFirst(viewstate &rightstate, viewstate &leftstate);
\r
205 bool IsLeftViewGood() const {return ((m_pwndLeft)&&(m_pwndLeft->IsWindowVisible()));}
\r
206 bool IsRightViewGood() const {return ((m_pwndRight)&&(m_pwndRight->IsWindowVisible()));}
\r
207 bool IsBottomViewGood() const {return ((m_pwndBottom)&&(m_pwndBottom->IsWindowVisible()));}
\r
209 int CalculateActualOffset(int nLineIndex, int nCharIndex) const;
\r
210 int CalculateCharIndex(int nLineIndex, int nActualOffset) const;
\r
211 POINT TextToClient(const POINT& point);
\r
212 void DrawText(CDC * pDC, const CRect &rc, LPCTSTR text, int textlength, int nLineIndex, POINT coords, bool bModified, bool bInlineDiff);
\r
213 void ClearCurrentSelection();
\r
214 void AdjustSelection();
\r
215 void SelectNextBlock(int nDirection, bool bConflict, bool bSkipEndOfCurrentBlock = true);
\r
217 void RemoveLine(int nLineIndex);
\r
218 void RemoveSelectedText();
\r
220 void AddUndoLine(int nLine, bool bAddEmptyLine = false);
\r
222 bool MoveCaretLeft();
\r
223 bool MoveCaretRight();
\r
224 void UpdateGoalPos();
\r
226 bool IsWordSeparator(wchar_t ch) const;
\r
227 bool IsCaretAtWordBoundary() const;
\r
230 COLORREF m_InlineRemovedBk;
\r
231 COLORREF m_InlineAddedBk;
\r
232 COLORREF m_ModifiedBk;
\r
233 COLORREF m_WhiteSpaceFg;
\r
234 UINT m_nStatusBarID; ///< The ID of the status bar pane used by this view. Must be set by the parent class.
\r
236 SVNLineDiff m_svnlinediff;
\r
237 BOOL m_bOtherDiffChecked;
\r
240 BOOL m_bViewLinenumbers;
\r
242 BOOL m_bMouseWithin;
\r
246 int m_nMaxLineLength;
\r
247 int m_nScreenLines;
\r
248 int m_nScreenChars;
\r
252 bool m_bInlineWordDiff;
\r
254 int m_nSelBlockStart;
\r
255 int m_nSelBlockEnd;
\r
259 bool m_bCaretHidden;
\r
260 POINT m_ptCaretPos;
\r
261 int m_nCaretGoalPos;
\r
262 POINT m_ptSelectionStartPos;
\r
263 POINT m_ptSelectionEndPos;
\r
264 POINT m_ptSelectionOrigin;
\r
267 HICON m_hAddedIcon;
\r
268 HICON m_hRemovedIcon;
\r
269 HICON m_hConflictedIcon;
\r
270 HICON m_hConflictedIgnoredIcon;
\r
271 HICON m_hWhitespaceBlockIcon;
\r
272 HICON m_hEqualIcon;
\r
273 HICON m_hEditedIcon;
\r
275 HICON m_hLineEndingCR;
\r
276 HICON m_hLineEndingCRLF;
\r
277 HICON m_hLineEndingLF;
\r
279 LOGFONT m_lfBaseFont;
\r
280 CFont * m_apFonts[8];
\r
281 CString m_sConflictedText;
\r
282 CString m_sNoLineNr;
\r
284 CBitmap * m_pCacheBitmap;
\r
286 CScrollTool m_ScrollTool;
\r
287 CString m_sWordSeparators;
\r
289 char m_szTip[MAX_PATH*2+1];
\r
290 wchar_t m_wszTip[MAX_PATH*2+1];
\r
291 // These three pointers lead to the three parent
\r
292 // classes CLeftView, CRightView and CBottomView
\r
293 // and are used for the communication between
\r
294 // the views (e.g. synchronized scrolling, ...)
\r
295 // To find out which parent class this object
\r
296 // is made of just compare e.g. (m_pwndLeft==this).
\r
297 static CBaseView * m_pwndLeft; ///< Pointer to the left view. Must be set by the CLeftView parent class.
\r
298 static CBaseView * m_pwndRight; ///< Pointer to the right view. Must be set by the CRightView parent class.
\r
299 static CBaseView * m_pwndBottom; ///< Pointer to the bottom view. Must be set by the CBottomView parent class.
\r