1 /////////////////////////////////////////////////////////////////////////////
2 // WinMerge: an interactive diff/merge utility
3 // Copyright (C) 1997 Dean P. Grimm
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (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
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /////////////////////////////////////////////////////////////////////////////
21 * @file MergeEditView.h
23 * @brief Declaration file for CMergeEditView
29 * @brief Non-diff lines shown above diff when scrolling to it
31 const UINT CONTEXT_LINES_ABOVE = 5;
34 * @brief Non-diff lines shown below diff when scrolling to it
36 const UINT CONTEXT_LINES_BELOW = 3;
39 #define FLAG_RESCAN_WAITS_FOR_IDLE 1
42 /////////////////////////////////////////////////////////////////////////////
43 // CMergeEditView view
45 #include "GhostTextView.h"
46 #include "OptionsDiffColors.h"
48 class IMergeEditStatus;
54 This class is the base class for WinMerge editor panels.
55 It hooks the painting of ghost lines (GetLineColors), the shared
56 scrollbar (OnUpdateSibling...).
57 It offers the UI interface commands to work with diffs
60 If we keep GetLineColors here, we should clear DIFF flag here
61 and not in CGhostTextBuffer (when insertText/deleteText).
62 Small problem... This class doesn't derives from CGhostTextBuffer...
63 We could define a new class which derives from CGhostTextBuffer to clear the DIFF flag.
64 and calls a virtual function for additional things to do on the flag.
65 Maybe in the future...
67 class CMergeEditView : public CGhostTextView
70 CMergeEditView(); // protected constructor used by dynamic creation
71 DECLARE_DYNCREATE(CMergeEditView)
72 CCrystalParser m_xParser; /**< Syntax parser used for syntax highlighting. */
77 * Index of pane this view is attached to.
78 * This indicates the pane number the view is attached to. If we swap panes
79 * then these indexes are changed.
84 IMergeEditStatus * m_piMergeEditStatus; /**< interface to status bar */
88 * Are automatic rescans enabled?
89 * If automatic rescans are enabled then we rescan files after edit
90 * events, unless timer suppresses rescan. We suppress rescans within
91 * certain time from previous rescan.
93 bool m_bAutomaticRescan;
94 /// first line of diff (first displayable line)
96 /// last line of diff (last displayable line)
101 This flag is set when we receive an OnTimer command, and we want
102 to wait for theApp::OnIdle before processing it
104 unsigned fTimerWaitingForIdle;
105 COLORSETTINGS m_cachedColors; /**< Cached color settings */
107 /// active prediffer ID : helper to check the radio button
108 int m_CurrentPredifferID;
110 bool m_bCurrentLineIsDiff; /**< TRUE if cursor is in diff line */
114 void RefreshOptions();
115 bool EnableRescan(bool bEnable);
116 bool IsReadOnly(int pane) const;
117 void ShowDiff(bool bScroll, bool bSelectText);
118 virtual void OnEditOperation(int nAction, LPCTSTR pszText, size_t cchText) override;
119 void UpdateLineLengths();
120 bool IsLineInCurrentDiff(int nLine) const;
122 void SelectDiff(int nDiff, bool bScroll = true, bool bSelectText = true);
123 virtual CCrystalTextBuffer *LocateTextBuffer ();
124 const CCrystalTextBuffer *LocateTextBuffer () const { return const_cast<CMergeEditView *>(this)->LocateTextBuffer(); };
125 void GetFullySelectedDiffs(int & firstDiff, int & lastDiff);
126 CString GetSelectedText();
127 CString GetLineText(int idx);
128 CMergeDoc* GetDocument();
129 const CMergeDoc *GetDocument() const { return const_cast<CMergeEditView *>(this)->GetDocument(); }
130 void UpdateResources();
131 BOOL IsModified() { return (LocateTextBuffer()->IsModified()); }
132 void PrimeListWithFile();
133 void SetStatusInterface(IMergeEditStatus * piMergeEditStatus);
134 void SelectArea(const CPoint & ptStart, const CPoint & ptEnd) { SetSelection(ptStart, ptEnd); } // make public
135 void GetSelection(CPoint &ptStart, CPoint &ptEnd) { CCrystalTextView::GetSelection(ptStart, ptEnd); }
136 virtual void UpdateSiblingScrollPos (bool bHorz) override;
137 virtual std::vector<TEXTBLOCK> GetAdditionalTextBlocks (int nLineIndex) override;
138 virtual COLORREF GetColor(int nColorIndex) override;
139 virtual void GetLineColors (int nLineIndex, COLORREF & crBkgnd,
140 COLORREF & crText, bool & bDrawWhitespace) override;
141 virtual void GetLineColors2 (int nLineIndex, DWORD ignoreFlags
142 , COLORREF & crBkgnd, COLORREF & crText, bool & bDrawWhitespace);
143 void WMGoto() { OnWMGoto(); };
144 void GotoLine(UINT nLine, bool bRealLine, int pane);
145 int GetTopLine() const { return m_nTopLine; }
146 int GetScreenLines() { return CCrystalTextView::GetScreenLines(); }
147 int GetTopSubLine() const { return m_nTopSubLine; }
148 int GetSubLines(int nLineIndex) { return CCrystalTextView::GetSubLines(nLineIndex); }
149 virtual int GetSubLineCount() { return CCrystalTextView::GetSubLineCount(); }
150 virtual int GetSubLineIndex(int nLineIndex) override { return CCrystalTextView::GetSubLineIndex(nLineIndex); }
151 virtual void GetLineBySubLine(int nSubLineIndex, int &nLine, int &nSubLine) override {
152 CCrystalTextView::GetLineBySubLine(nSubLineIndex, nLine, nSubLine);
154 virtual int GetEmptySubLines( int nLineIndex ) override;
155 virtual void InvalidateSubLineIndexCache( int nLineIndex ) override;
156 void RepaintLocationPane();
157 bool SetPredifferByName(const CString & prediffer);
158 void SetPredifferByMenu(UINT nID);
159 void DocumentsLoaded();
160 void SetLocationView(const CLocationView * pView = NULL);
161 void UpdateLocationViewPosition(int nTopLine = -1, int nBottomLine = -1);
162 virtual void RecalcPageLayouts(CDC * pdc, CPrintInfo * pInfo) override;
163 virtual void GetPrintHeaderText(int nPageNum, CString & text) override;
164 virtual void PrintHeader(CDC * pdc, int nPageNum) override;
165 virtual void PrintFooter(CDC * pdc, int nPageNum) override;
166 virtual void SetWordWrapping( bool bWordWrap ) override;
167 void UpdateStatusbar();
168 CMergeEditView *GetGroupView(int nPane) const;
170 virtual void OnDisplayDiff(int nDiff=0);
172 // to customize the mergeview menu
173 static HMENU createScriptsSubmenu(HMENU hMenu);
174 HMENU createPrediffersSubmenu(HMENU hMenu);
176 bool IsInitialized() const;
177 bool IsCursorInDiff() const;
178 bool IsDiffVisible(int nDiff);
179 void ZoomText(short amount);
182 // ClassWizard generated virtual function overrides
183 //{{AFX_VIRTUAL(CMergeEditView)
185 virtual void OnInitialUpdate();
187 virtual void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView);
188 virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
189 virtual BOOL PreTranslateMessage(MSG* pMsg);
190 virtual void OnBeginPrinting (CDC * pDC, CPrintInfo * pInfo);
191 virtual void OnEndPrinting (CDC * pDC, CPrintInfo * pInfo);
192 virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);
197 virtual ~CMergeEditView();
198 virtual void OnUpdateSibling (CCrystalTextView * pUpdateSource, BOOL bHorz);
199 virtual void OnUpdateCaret();
200 bool MergeModeKeyDown(MSG* pMsg);
201 int FindPrediffer(LPCTSTR prediffer) const;
202 bool IsDiffVisible(const DIFFRANGE& diff, int nLinesBelow = 0);
203 void OnNext3wayDiff(int type);
204 void OnUpdateNext3wayDiff(CCmdUI* pCmdUI, int type);
205 void OnPrev3wayDiff(int type);
206 void OnUpdatePrev3wayDiff(CCmdUI* pCmdUI, int type);
207 void OnDropFiles(const std::vector<String>& files);
209 // Generated message map functions
211 //{{AFX_MSG(CMergeEditView)
212 afx_msg void OnCurdiff();
213 afx_msg void OnUpdateCurdiff(CCmdUI* pCmdUI);
214 afx_msg void OnEditCopy();
215 afx_msg void OnUpdateEditCopy(CCmdUI* pCmdUI);
216 afx_msg void OnEditCut();
217 afx_msg void OnUpdateEditCut(CCmdUI* pCmdUI);
218 afx_msg void OnEditPaste();
219 afx_msg void OnUpdateEditPaste(CCmdUI* pCmdUI);
220 afx_msg void OnEditUndo();
221 afx_msg void OnFirstdiff();
222 afx_msg void OnUpdateFirstdiff(CCmdUI* pCmdUI);
223 afx_msg void OnLastdiff();
224 afx_msg void OnUpdateLastdiff(CCmdUI* pCmdUI);
225 afx_msg void OnNextdiff();
226 afx_msg void OnUpdateNextdiff(CCmdUI* pCmdUI);
227 afx_msg void OnPrevdiff();
228 afx_msg void OnUpdatePrevdiff(CCmdUI* pCmdUI);
229 afx_msg void OnNextConflict();
230 afx_msg void OnUpdateNextConflict(CCmdUI* pCmdUI);
231 afx_msg void OnPrevConflict();
232 afx_msg void OnUpdatePrevConflict(CCmdUI* pCmdUI);
233 afx_msg void OnNextdiffLM();
234 afx_msg void OnUpdateNextdiffLM(CCmdUI* pCmdUI);
235 afx_msg void OnPrevdiffLM();
236 afx_msg void OnUpdatePrevdiffLM(CCmdUI* pCmdUI);
237 afx_msg void OnNextdiffLR();
238 afx_msg void OnUpdateNextdiffLR(CCmdUI* pCmdUI);
239 afx_msg void OnPrevdiffLR();
240 afx_msg void OnUpdatePrevdiffLR(CCmdUI* pCmdUI);
241 afx_msg void OnNextdiffMR();
242 afx_msg void OnUpdateNextdiffMR(CCmdUI* pCmdUI);
243 afx_msg void OnPrevdiffMR();
244 afx_msg void OnUpdatePrevdiffMR(CCmdUI* pCmdUI);
245 afx_msg void OnNextdiffLO();
246 afx_msg void OnUpdateNextdiffLO(CCmdUI* pCmdUI);
247 afx_msg void OnPrevdiffLO();
248 afx_msg void OnUpdatePrevdiffLO(CCmdUI* pCmdUI);
249 afx_msg void OnNextdiffMO();
250 afx_msg void OnUpdateNextdiffMO(CCmdUI* pCmdUI);
251 afx_msg void OnPrevdiffMO();
252 afx_msg void OnUpdatePrevdiffMO(CCmdUI* pCmdUI);
253 afx_msg void OnNextdiffRO();
254 afx_msg void OnUpdateNextdiffRO(CCmdUI* pCmdUI);
255 afx_msg void OnPrevdiffRO();
256 afx_msg void OnUpdatePrevdiffRO(CCmdUI* pCmdUI);
257 afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
258 afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
259 afx_msg void OnAllLeft();
260 afx_msg void OnUpdateAllLeft(CCmdUI* pCmdUI);
261 afx_msg void OnAllRight();
262 afx_msg void OnUpdateAllRight(CCmdUI* pCmdUI);
263 afx_msg void OnAutoMerge();
264 afx_msg void OnUpdateAutoMerge(CCmdUI* pCmdUI);
265 afx_msg void OnX2Y(int srcPane, int dstPane);
266 afx_msg void OnUpdateX2Y(int dstPane, CCmdUI* pCmdUI);
267 afx_msg void OnL2r();
268 afx_msg void OnUpdateL2r(CCmdUI* pCmdUI);
269 afx_msg void OnR2l();
270 afx_msg void OnUpdateR2l(CCmdUI* pCmdUI);
271 afx_msg void OnCopyFromLeft();
272 afx_msg void OnUpdateCopyFromLeft(CCmdUI* pCmdUI);
273 afx_msg void OnCopyFromRight();
274 afx_msg void OnUpdateCopyFromRight(CCmdUI* pCmdUI);
275 afx_msg void OnAddSyncPoint();
276 afx_msg void OnUpdateAddSyncPoint(CCmdUI* pCmdUI);
277 afx_msg void OnClearSyncPoints();
278 afx_msg void OnUpdateClearSyncPoints(CCmdUI* pCmdUI);
279 afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
280 afx_msg void OnEditRedo();
281 afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI);
282 afx_msg void OnTimer(UINT_PTR nIDEvent);
283 afx_msg void OnUpdateFileSaveLeft(CCmdUI* pCmdUI);
284 afx_msg void OnUpdateFileSaveMiddle(CCmdUI* pCmdUI);
285 afx_msg void OnUpdateFileSaveRight(CCmdUI* pCmdUI);
286 afx_msg void OnRefresh();
287 afx_msg void OnUpdateFileSave(CCmdUI* pCmdUI);
288 template<bool reversed>
289 afx_msg void OnSelectLineDiff();
290 afx_msg void OnUpdateSelectLineDiff(CCmdUI* pCmdUI);
291 afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
292 afx_msg void OnUpdateEditReplace(CCmdUI* pCmdUI);
293 afx_msg void OnLeftReadOnly();
294 afx_msg void OnUpdateLeftReadOnly(CCmdUI* pCmdUI);
295 afx_msg void OnMiddleReadOnly();
296 afx_msg void OnUpdateMiddleReadOnly(CCmdUI* pCmdUI);
297 afx_msg void OnRightReadOnly();
298 afx_msg void OnUpdateRightReadOnly(CCmdUI* pCmdUI);
299 afx_msg void OnUpdateStatusRO(CCmdUI* pCmdUI);
300 afx_msg void OnConvertEolTo(UINT nID );
301 afx_msg void OnUpdateConvertEolTo(CCmdUI* pCmdUI);
302 afx_msg void OnUpdateStatusEOL(CCmdUI* pCmdUI);
303 afx_msg void OnL2RNext();
304 afx_msg void OnUpdateL2RNext(CCmdUI* pCmdUI);
305 afx_msg void OnR2LNext();
306 afx_msg void OnUpdateR2LNext(CCmdUI* pCmdUI);
307 afx_msg void OnChangePane();
308 afx_msg void OnUpdateChangePane(CCmdUI* pCmdUI);
309 afx_msg void OnWMGoto();
310 afx_msg void OnUpdateWMGoto(CCmdUI* pCmdUI);
311 afx_msg void OnUpdateScripts(CCmdUI* pCmdUI);
312 afx_msg void OnScripts(UINT nID );
313 afx_msg void OnUpdateNoPrediffer(CCmdUI* pCmdUI);
314 afx_msg void OnUpdatePrediffer(CCmdUI* pCmdUI);
315 afx_msg void OnNoPrediffer();
316 afx_msg void OnPrediffer(UINT nID );
317 afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar);
318 afx_msg void OnVScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar);
319 afx_msg void OnEditCopyLineNumbers();
320 afx_msg void OnUpdateEditCopyLinenumbers(CCmdUI* pCmdUI);
321 afx_msg void OnViewLineDiffs();
322 afx_msg void OnUpdateViewLineDiffs(CCmdUI* pCmdUI);
323 afx_msg void OnViewLineNumbers();
324 afx_msg void OnUpdateViewLineNumbers(CCmdUI* pCmdUI);
325 afx_msg void OnViewWordWrap();
326 afx_msg void OnUpdateViewWordWrap(CCmdUI* pCmdUI);
327 afx_msg void OnViewWhitespace();
328 afx_msg void OnUpdateViewWhitespace(CCmdUI* pCmdUI);
329 afx_msg void OnOpenFile();
330 afx_msg void OnOpenFileWith();
331 afx_msg void OnOpenFileWithEditor();
332 afx_msg void OnViewSwapPanes();
333 afx_msg void OnUpdateViewSwapPanes(CCmdUI* pCmdUI);
334 afx_msg void OnUpdateNoEditScripts(CCmdUI* pCmdUI);
335 afx_msg void OnSize(UINT nType, int cx, int cy);
336 afx_msg void OnHelp();
337 afx_msg void OnViewMargin();
338 afx_msg void OnUpdateViewMargin(CCmdUI* pCmdUI);
339 afx_msg void OnUpdateViewChangeScheme(CCmdUI *pCmdUI);
340 afx_msg void OnChangeScheme(UINT nID);
341 afx_msg void OnUpdateChangeScheme(CCmdUI* pCmdUI);
342 afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
343 afx_msg void OnViewZoomIn();
344 afx_msg void OnViewZoomOut();
345 afx_msg void OnViewZoomNormal();
346 afx_msg void OnWindowSplit();
347 afx_msg void OnUpdateWindowSplit(CCmdUI* pCmdUI);
349 DECLARE_MESSAGE_MAP()
352 #ifndef _DEBUG // debug version in DiffView.cpp
353 inline CMergeDoc* CMergeEditView::GetDocument()
354 { return reinterpret_cast<CMergeDoc*>(m_pDocument); }