1 /////////////////////////////////////////////////////////////////////////////
2 // WinMerge: an interactive diff/merge utility
3 // Copyright (C) 1997 Dean P. Grimm
4 // SPDX-License-Identifier: GPL-2.0-or-later
5 /////////////////////////////////////////////////////////////////////////////
7 * @file MergeEditView.h
9 * @brief Declaration file for CMergeEditView
15 * @brief Non-diff lines shown above diff when scrolling to it
17 const UINT CONTEXT_LINES_ABOVE = 5;
20 * @brief Non-diff lines shown below diff when scrolling to it
22 const UINT CONTEXT_LINES_BELOW = 3;
25 #define FLAG_RESCAN_WAITS_FOR_IDLE 1
28 /////////////////////////////////////////////////////////////////////////////
29 // CMergeEditView view
31 #include "GhostTextView.h"
32 #include "OptionsDiffColors.h"
36 class IMergeEditStatus;
42 This class is the base class for WinMerge editor panels.
43 It hooks the painting of ghost lines (GetLineColors), the shared
44 scrollbar (OnUpdateSibling...).
45 It offers the UI interface commands to work with diffs
48 If we keep GetLineColors here, we should clear DIFF flag here
49 and not in CGhostTextBuffer (when insertText/deleteText).
50 Small problem... This class doesn't derives from CGhostTextBuffer...
51 We could define a new class which derives from CGhostTextBuffer to clear the DIFF flag.
52 and calls a virtual function for additional things to do on the flag.
53 Maybe in the future...
55 class CMergeEditView : public CGhostTextView
58 CMergeEditView(); // protected constructor used by dynamic creation
59 DECLARE_DYNCREATE(CMergeEditView)
60 CCrystalParser m_xParser; /**< Syntax parser used for syntax highlighting. */
65 * Index of pane this view is attached to.
66 * This indicates the pane number the view is attached to. If we swap panes
67 * then these indexes are changed.
72 IMergeEditStatus * m_piMergeEditStatus; /**< interface to status bar */
75 /// first line of diff (first displayable line)
77 /// last line of diff (last displayable line)
82 This flag is set when we receive an OnTimer command, and we want
83 to wait for theApp::OnIdle before processing it
85 unsigned fTimerWaitingForIdle;
86 COLORSETTINGS m_cachedColors; /**< Cached color settings */
88 bool m_bCurrentLineIsDiff; /**< `true` if cursor is in diff line */
95 void RefreshOptions();
96 bool IsReadOnly(int pane) const;
97 void ShowDiff(bool bScroll, bool bSelectText);
98 virtual void OnEditOperation(int nAction, LPCTSTR pszText, size_t cchText) override;
99 bool IsLineInCurrentDiff(int nLine) const;
101 void SelectDiff(int nDiff, bool bScroll = true, bool bSelectText = true);
102 void DeselectDiffIfCursorNotInCurrentDiff();
103 virtual CCrystalTextBuffer *LocateTextBuffer () override;
104 const CCrystalTextBuffer *LocateTextBuffer () const { return const_cast<CMergeEditView *>(this)->LocateTextBuffer(); };
105 void GetFullySelectedDiffs(int & firstDiff, int & lastDiff);
106 void GetFullySelectedDiffs(int & firstDiff, int & lastDiff, int & firstWordDiff, int & lastWordDiff, const CPoint *pptStart = nullptr, const CPoint *ppEnd = nullptr);
107 void GetSelectedDiffs(int & firstDiff, int & lastDiff);
108 std::map<int, std::vector<int>> GetColumnSelectedWordDiffIndice();
109 CString GetSelectedText();
110 std::pair<int, int> GetSelectedLineAndCharacterCount();
111 CString GetLineText(int idx);
112 CMergeDoc* GetDocument();
113 const CMergeDoc *GetDocument() const { return const_cast<CMergeEditView *>(this)->GetDocument(); }
114 void UpdateResources();
115 bool IsModified() { return (LocateTextBuffer()->IsModified()); }
116 void PrimeListWithFile();
117 void SetStatusInterface(IMergeEditStatus * piMergeEditStatus);
118 void SelectArea(const CPoint & ptStart, const CPoint & ptEnd) { SetSelection(ptStart, ptEnd); } // make public
119 using CGhostTextView::GetSelection;
120 virtual void UpdateSiblingScrollPos (bool bHorz) override;
121 virtual std::vector<CrystalLineParser::TEXTBLOCK> GetMarkerTextBlocks(int nLineIndex) const override;
122 virtual std::vector<CrystalLineParser::TEXTBLOCK> GetAdditionalTextBlocks (int nLineIndex) override;
123 virtual COLORREF GetColor(int nColorIndex) const override;
124 virtual void GetLineColors (int nLineIndex, COLORREF & crBkgnd,
125 COLORREF & crText, bool & bDrawWhitespace) override;
126 virtual void GetLineColors2 (int nLineIndex, DWORD ignoreFlags
127 , COLORREF & crBkgnd, COLORREF & crText, bool & bDrawWhitespace);
128 void WMGoto() { OnWMGoto(); };
129 void GotoLine(UINT nLine, bool bRealLine, int pane, bool bMoveAnchor = true, int nChar = -1);
130 int GetTopLine() const { return m_nTopLine; }
131 using CCrystalTextView::GetScreenLines;
132 int GetTopSubLine() const { return m_nTopSubLine; }
133 using CCrystalTextView::GetSubLines;
134 using CCrystalTextView::GetSubLineCount;
135 using CCrystalTextView::GetSubLineIndex;
136 using CCrystalTextView::GetLineBySubLine;
137 virtual int GetEmptySubLines( int nLineIndex ) override;
138 virtual void InvalidateSubLineIndexCache( int nLineIndex ) override;
139 void RepaintLocationPane();
140 void DocumentsLoaded();
141 void UpdateLocationViewPosition(int nTopLine = -1, int nBottomLine = -1);
142 virtual void RecalcPageLayouts(CDC * pdc, CPrintInfo * pInfo) override;
143 virtual void GetPrintHeaderText(int nPageNum, CString & text) override;
144 virtual void PrintHeader(CDC * pdc, int nPageNum) override;
145 virtual void PrintFooter(CDC * pdc, int nPageNum) override;
146 virtual void SetWordWrapping( bool bWordWrap ) override;
147 void UpdateStatusbar();
148 CMergeEditView *GetGroupView(int nPane) const;
150 virtual void OnDisplayDiff(int nDiff=0);
152 bool IsInitialized() const;
153 bool IsCursorInDiff() const;
154 bool IsDiffVisible(int nDiff);
155 void ZoomText(short amount);
156 virtual bool QueryEditable() override;
157 virtual void EnsureVisible(CPoint pt) override;
158 virtual void EnsureVisible(CPoint ptStart, CPoint ptEnd) override;
159 bool EnsureInDiff(CPoint& pt);
160 void SetSelection(const CPoint& ptStart, const CPoint& ptEnd, bool bUpdateView = true) override;
161 void ScrollToSubLine(int nNewTopLine, bool bNoSmoothScroll = false, bool bTrackScrollBar = true) override;
162 void SetActivePane();
165 // ClassWizard generated virtual function overrides
166 //{{AFX_VIRTUAL(CMergeEditView)
168 virtual void OnInitialUpdate();
170 virtual void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView);
171 virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
172 virtual BOOL PreTranslateMessage(MSG* pMsg);
173 virtual void OnBeginPrinting (CDC * pDC, CPrintInfo * pInfo);
174 virtual void OnEndPrinting (CDC * pDC, CPrintInfo * pInfo);
175 virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);
180 virtual ~CMergeEditView();
181 virtual void OnUpdateSibling (CCrystalTextView * pUpdateSource, bool bHorz) override;
182 virtual void OnUpdateCaret() override;
183 bool MergeModeKeyDown(MSG* pMsg);
184 bool IsDiffVisible(const DIFFRANGE& diff, int nLinesBelow = 0);
185 void OnNext3wayDiff(int type);
186 void OnUpdateNext3wayDiff(CCmdUI* pCmdUI, int type);
187 void OnPrev3wayDiff(int type);
188 void OnUpdatePrev3wayDiff(CCmdUI* pCmdUI, int type);
189 void OnDropFiles(const std::vector<String>& files);
191 // Generated message map functions
193 //{{AFX_MSG(CMergeEditView)
194 afx_msg void OnCurdiff();
195 afx_msg void OnUpdateCurdiff(CCmdUI* pCmdUI);
196 afx_msg void OnEditCopy();
197 afx_msg void OnUpdateEditCopy(CCmdUI* pCmdUI);
198 afx_msg void OnEditCut();
199 afx_msg void OnUpdateEditCut(CCmdUI* pCmdUI);
200 afx_msg void OnEditPaste();
201 afx_msg void OnUpdateEditPaste(CCmdUI* pCmdUI);
202 afx_msg void OnEditUndo();
203 afx_msg void OnFirstdiff();
204 afx_msg void OnUpdateFirstdiff(CCmdUI* pCmdUI);
205 afx_msg void OnLastdiff();
206 afx_msg void OnUpdateLastdiff(CCmdUI* pCmdUI);
207 afx_msg void OnNextdiff();
208 afx_msg void OnUpdateNextdiff(CCmdUI* pCmdUI);
209 afx_msg void OnPrevdiff();
210 afx_msg void OnUpdatePrevdiff(CCmdUI* pCmdUI);
211 afx_msg void OnNextConflict();
212 afx_msg void OnUpdateNextConflict(CCmdUI* pCmdUI);
213 afx_msg void OnPrevConflict();
214 afx_msg void OnUpdatePrevConflict(CCmdUI* pCmdUI);
215 afx_msg void OnNextdiffLM();
216 afx_msg void OnUpdateNextdiffLM(CCmdUI* pCmdUI);
217 afx_msg void OnPrevdiffLM();
218 afx_msg void OnUpdatePrevdiffLM(CCmdUI* pCmdUI);
219 afx_msg void OnNextdiffLR();
220 afx_msg void OnUpdateNextdiffLR(CCmdUI* pCmdUI);
221 afx_msg void OnPrevdiffLR();
222 afx_msg void OnUpdatePrevdiffLR(CCmdUI* pCmdUI);
223 afx_msg void OnNextdiffMR();
224 afx_msg void OnUpdateNextdiffMR(CCmdUI* pCmdUI);
225 afx_msg void OnPrevdiffMR();
226 afx_msg void OnUpdatePrevdiffMR(CCmdUI* pCmdUI);
227 afx_msg void OnNextdiffLO();
228 afx_msg void OnUpdateNextdiffLO(CCmdUI* pCmdUI);
229 afx_msg void OnPrevdiffLO();
230 afx_msg void OnUpdatePrevdiffLO(CCmdUI* pCmdUI);
231 afx_msg void OnNextdiffMO();
232 afx_msg void OnUpdateNextdiffMO(CCmdUI* pCmdUI);
233 afx_msg void OnPrevdiffMO();
234 afx_msg void OnUpdatePrevdiffMO(CCmdUI* pCmdUI);
235 afx_msg void OnNextdiffRO();
236 afx_msg void OnUpdateNextdiffRO(CCmdUI* pCmdUI);
237 afx_msg void OnPrevdiffRO();
238 afx_msg void OnUpdatePrevdiffRO(CCmdUI* pCmdUI);
239 afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
240 afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
241 afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
242 afx_msg void OnAllLeft();
243 afx_msg void OnUpdateAllLeft(CCmdUI* pCmdUI);
244 afx_msg void OnAllRight();
245 afx_msg void OnUpdateAllRight(CCmdUI* pCmdUI);
246 afx_msg void OnAutoMerge();
247 afx_msg void OnUpdateAutoMerge(CCmdUI* pCmdUI);
248 afx_msg void OnX2Y(int srcPane, int dstPane, bool selectedLineOnly = false);
249 afx_msg void OnUpdateX2Y(int dstPane, CCmdUI* pCmdUI);
250 afx_msg void OnL2r();
251 afx_msg void OnUpdateL2r(CCmdUI* pCmdUI);
252 afx_msg void OnLinesL2r();
253 afx_msg void OnUpdateLinesL2r(CCmdUI* pCmdUI);
254 afx_msg void OnR2l();
255 afx_msg void OnUpdateR2l(CCmdUI* pCmdUI);
256 afx_msg void OnLinesR2l();
257 afx_msg void OnUpdateLinesR2l(CCmdUI* pCmdUI);
258 afx_msg void OnCopyFromLeft();
259 afx_msg void OnUpdateCopyFromLeft(CCmdUI* pCmdUI);
260 afx_msg void OnCopyLinesFromLeft();
261 afx_msg void OnUpdateCopyLinesFromLeft(CCmdUI* pCmdUI);
262 afx_msg void OnCopyFromRight();
263 afx_msg void OnUpdateCopyFromRight(CCmdUI* pCmdUI);
264 afx_msg void OnCopyLinesFromRight();
265 afx_msg void OnUpdateCopyLinesFromRight(CCmdUI* pCmdUI);
266 afx_msg void OnAddSyncPoint();
267 afx_msg void OnClearSyncPoints();
268 afx_msg void OnUpdateClearSyncPoints(CCmdUI* pCmdUI);
269 afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
270 afx_msg void OnEditRedo();
271 afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI);
272 afx_msg void OnTimer(UINT_PTR nIDEvent);
273 template<bool reversed>
274 afx_msg void OnSelectLineDiff();
275 afx_msg void OnUpdateSelectLineDiff(CCmdUI* pCmdUI);
276 afx_msg void OnAddToSubstitutionFilters();
277 afx_msg void OnUpdateAddToSubstitutionFilters(CCmdUI* pCmdUI);
278 afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
279 afx_msg void OnUpdateEditReplace(CCmdUI* pCmdUI);
280 afx_msg void OnConvertEolTo(UINT nID );
281 afx_msg void OnUpdateConvertEolTo(CCmdUI* pCmdUI);
282 afx_msg void OnUpdateStatusEOL(CCmdUI* pCmdUI);
283 afx_msg void OnL2RNext();
284 afx_msg void OnUpdateL2RNext(CCmdUI* pCmdUI);
285 afx_msg void OnR2LNext();
286 afx_msg void OnUpdateR2LNext(CCmdUI* pCmdUI);
287 afx_msg void OnChangePane();
288 afx_msg void OnWMGoto();
289 afx_msg void OnGotoMovedLineLM();
290 afx_msg void OnUpdateGotoMovedLineLM(CCmdUI* pCmdUI);
291 afx_msg void OnGotoMovedLineMR();
292 afx_msg void OnUpdateGotoMovedLineMR(CCmdUI* pCmdUI);
293 afx_msg void OnShellMenu();
294 afx_msg void OnUpdateShellMenu(CCmdUI* pCmdUI);
295 afx_msg void OnScripts(UINT nID );
296 afx_msg void OnTransformWithScript();
297 afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar);
298 afx_msg void OnVScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar);
299 afx_msg void OnEditCopyLineNumbers();
300 afx_msg void OnUpdateEditCopyLinenumbers(CCmdUI* pCmdUI);
301 afx_msg void OnViewLineDiffs();
302 afx_msg void OnUpdateViewLineDiffs(CCmdUI* pCmdUI);
303 afx_msg void OnViewLineNumbers();
304 afx_msg void OnUpdateViewLineNumbers(CCmdUI* pCmdUI);
305 afx_msg void OnViewWordWrap();
306 afx_msg void OnUpdateViewWordWrap(CCmdUI* pCmdUI);
307 afx_msg void OnViewWhitespace();
308 afx_msg void OnUpdateViewWhitespace(CCmdUI* pCmdUI);
309 afx_msg void OnViewEOL();
310 afx_msg void OnUpdateViewEOL(CCmdUI* pCmdUI);
311 afx_msg void OnOpenFile();
312 afx_msg void OnOpenFileWith();
313 afx_msg void OnOpenFileWithEditor();
314 afx_msg void OnOpenParentFolder();
315 afx_msg void OnSize(UINT nType, int cx, int cy);
316 afx_msg void OnHelp();
317 afx_msg void OnViewMargin();
318 afx_msg void OnUpdateViewMargin(CCmdUI* pCmdUI);
319 afx_msg void OnUpdateViewChangeScheme(CCmdUI *pCmdUI);
320 afx_msg void OnChangeScheme(UINT nID);
321 afx_msg void OnUpdateChangeScheme(CCmdUI* pCmdUI);
322 afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
323 afx_msg void OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt);
324 afx_msg void OnViewZoomIn();
325 afx_msg void OnViewZoomOut();
326 afx_msg void OnViewZoomNormal();
327 afx_msg void OnWindowSplit();
328 afx_msg void OnUpdateWindowSplit(CCmdUI* pCmdUI);
329 afx_msg void OnStatusBarDblClick(NMHDR* pNMHDR, LRESULT* pResult);
332 DECLARE_MESSAGE_MAP()
335 #ifndef _DEBUG // debug version in DiffView.cpp
336 inline CMergeDoc* CMergeEditView::GetDocument()
337 { return reinterpret_cast<CMergeDoc*>(m_pDocument); }
341 * @brief Check if cursor is inside difference.
342 * @return true if cursor is inside difference.
344 inline bool CMergeEditView::IsCursorInDiff() const
346 return m_bCurrentLineIsDiff;