OSDN Git Service

Fix that the Next File or Previous File button on the toolbar did not work if the...
[winmerge-jp/winmerge-jp.git] / Src / MergeEditView.h
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 /////////////////////////////////////////////////////////////////////////////
6 /** 
7  * @file  MergeEditView.h
8  *
9  * @brief Declaration file for CMergeEditView
10  *
11  */
12 #pragma once
13
14 /** 
15  * @brief Non-diff lines shown above diff when scrolling to it
16  */
17 const UINT CONTEXT_LINES_ABOVE = 5;
18
19 /** 
20  * @brief Non-diff lines shown below diff when scrolling to it
21  */
22 const UINT CONTEXT_LINES_BELOW = 3;
23
24
25 #define FLAG_RESCAN_WAITS_FOR_IDLE   1
26
27
28 /////////////////////////////////////////////////////////////////////////////
29 // CMergeEditView view
30 #include "edtlib.h"
31 #include "GhostTextView.h"
32 #include "OptionsDiffColors.h"
33 #include <map>
34 #include <vector>
35
36 class IMergeEditStatus;
37 class CLocationView;
38 class CMergeDoc;
39 struct DIFFRANGE;
40
41 /**
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 
46
47 @todo
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...
54 */
55 class CMergeEditView : public CGhostTextView
56 {
57 protected:
58         CMergeEditView();           // protected constructor used by dynamic creation
59         DECLARE_DYNCREATE(CMergeEditView)
60         CCrystalParser m_xParser; /**< Syntax parser used for syntax highlighting. */
61
62 // Attributes
63 public:
64         /**
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.
68          */
69         int m_nThisPane;
70         int m_nThisGroup;
71         bool m_bDetailView;
72         IMergeEditStatus * m_piMergeEditStatus; /**< interface to status bar */
73
74 protected:
75         /**
76          * Are automatic rescans enabled?
77          * If automatic rescans are enabled then we rescan files after edit
78          * events, unless timer suppresses rescan. We suppress rescans within
79          * certain time from previous rescan.
80          */
81         bool m_bAutomaticRescan;
82         /// first line of diff (first displayable line)
83         int m_lineBegin;
84         /// last line of diff (last displayable line)
85         int m_lineEnd; 
86
87 private:
88         /** 
89         This flag is set when we receive an OnTimer command, and we want 
90         to wait for theApp::OnIdle before processing it 
91         */
92         unsigned fTimerWaitingForIdle;
93         COLORSETTINGS m_cachedColors; /**< Cached color settings */
94
95         /// active prediffer ID : helper to check the radio button
96         int m_CurrentPredifferID;
97
98         bool m_bCurrentLineIsDiff; /**< `true` if cursor is in diff line */
99
100         bool m_bChangedSchemeManually;  /**< `true` if the syntax highlighting scheme is changed manually */
101
102 // Operations
103 public:
104         void RefreshOptions();
105         bool EnableRescan(bool bEnable);
106         bool IsReadOnly(int pane) const;
107         void ShowDiff(bool bScroll, bool bSelectText);
108         virtual void OnEditOperation(int nAction, LPCTSTR pszText, size_t cchText) override;
109         bool IsLineInCurrentDiff(int nLine) const;
110         void SelectNone();
111         void SelectDiff(int nDiff, bool bScroll = true, bool bSelectText = true);
112         void DeselectDiffIfCursorNotInCurrentDiff();
113         virtual CCrystalTextBuffer *LocateTextBuffer ();
114         const CCrystalTextBuffer *LocateTextBuffer () const { return const_cast<CMergeEditView *>(this)->LocateTextBuffer(); };
115         void GetFullySelectedDiffs(int & firstDiff, int & lastDiff);
116         void GetFullySelectedDiffs(int & firstDiff, int & lastDiff, int & firstWordDiff,  int & lastWordDiff, const CPoint *pptStart = nullptr, const CPoint *ppEnd = nullptr);
117         void GetSelectedDiffs(int & firstDiff, int & lastDiff);
118         std::map<int, std::vector<int>> GetColumnSelectedWordDiffIndice();
119         CString GetSelectedText();
120         CString GetLineText(int idx);
121         CMergeDoc* GetDocument();
122         const CMergeDoc *GetDocument() const { return const_cast<CMergeEditView *>(this)->GetDocument(); }
123         void UpdateResources();
124         bool IsModified() { return (LocateTextBuffer()->IsModified()); }
125         void PrimeListWithFile();
126         void SetStatusInterface(IMergeEditStatus * piMergeEditStatus);
127         void SelectArea(const CPoint & ptStart, const CPoint & ptEnd) { SetSelection(ptStart, ptEnd); } // make public
128         using CGhostTextView::GetSelection;
129         virtual void UpdateSiblingScrollPos (bool bHorz) override;
130     virtual std::vector<CrystalLineParser::TEXTBLOCK> GetMarkerTextBlocks(int nLineIndex) const;
131         virtual std::vector<CrystalLineParser::TEXTBLOCK> GetAdditionalTextBlocks (int nLineIndex) override;
132         virtual COLORREF GetColor(int nColorIndex) override;
133         virtual void GetLineColors (int nLineIndex, COLORREF & crBkgnd,
134                         COLORREF & crText, bool & bDrawWhitespace) override;
135         virtual void GetLineColors2 (int nLineIndex, DWORD ignoreFlags
136                 , COLORREF & crBkgnd, COLORREF & crText, bool & bDrawWhitespace);
137         void WMGoto() { OnWMGoto(); };
138         void GotoLine(UINT nLine, bool bRealLine, int pane, bool bMoveAnchor = true);
139         int GetTopLine() const { return m_nTopLine; }
140         using CCrystalTextView::GetScreenLines;
141         int GetTopSubLine() const { return m_nTopSubLine; }
142         using CCrystalTextView::GetSubLines;
143         using CCrystalTextView::GetSubLineCount;
144         using CCrystalTextView::GetSubLineIndex;
145         using CCrystalTextView::GetLineBySubLine;
146         virtual int GetEmptySubLines( int nLineIndex ) override;
147         virtual void InvalidateSubLineIndexCache( int nLineIndex ) override;
148         void RepaintLocationPane();
149         bool SetPredifferByName(const CString & prediffer);
150         void SetPredifferByMenu(UINT nID);
151         void DocumentsLoaded();
152         void UpdateLocationViewPosition(int nTopLine = -1, int nBottomLine = -1);
153         virtual void RecalcPageLayouts(CDC * pdc, CPrintInfo * pInfo) override;
154         virtual void GetPrintHeaderText(int nPageNum, CString & text) override;
155         virtual void PrintHeader(CDC * pdc, int nPageNum) override;
156         virtual void PrintFooter(CDC * pdc, int nPageNum) override;
157         virtual void SetWordWrapping( bool bWordWrap ) override;
158         void UpdateStatusbar();
159         CMergeEditView *GetGroupView(int nPane) const;
160
161         virtual void OnDisplayDiff(int nDiff=0);
162
163         // to customize the mergeview menu
164         static HMENU createScriptsSubmenu(HMENU hMenu);
165         HMENU createPrediffersSubmenu(HMENU hMenu);
166
167         bool IsInitialized() const;
168         bool IsCursorInDiff() const;
169         bool IsDiffVisible(int nDiff);
170         void ZoomText(short amount);
171         virtual bool QueryEditable() override;
172         virtual void EnsureVisible(CPoint pt) override;
173         virtual void EnsureVisible(CPoint ptStart, CPoint ptEnd) override;
174         bool EnsureInDiff(CPoint& pt);
175         void SetSelection(const CPoint& ptStart, const CPoint& ptEnd, bool bUpdateView = true) override;
176         void ScrollToSubLine(int nNewTopLine, bool bNoSmoothScroll = false, bool bTrackScrollBar = true) override;
177         void SetActivePane();
178
179         // Overrides
180         // ClassWizard generated virtual function overrides
181         //{{AFX_VIRTUAL(CMergeEditView)
182         public:
183         virtual void OnInitialUpdate();
184         protected:
185         virtual void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView);
186         virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
187         virtual BOOL PreTranslateMessage(MSG* pMsg);
188         virtual void OnBeginPrinting (CDC * pDC, CPrintInfo * pInfo);
189         virtual void OnEndPrinting (CDC * pDC, CPrintInfo * pInfo);
190         virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);
191         //}}AFX_VIRTUAL
192
193 // Implementation
194 protected:
195         virtual ~CMergeEditView();
196         virtual void OnUpdateSibling (CCrystalTextView * pUpdateSource, bool bHorz);
197         virtual void OnUpdateCaret();
198         bool MergeModeKeyDown(MSG* pMsg);
199         int FindPrediffer(LPCTSTR prediffer) const;
200         bool IsDiffVisible(const DIFFRANGE& diff, int nLinesBelow = 0);
201         void OnNext3wayDiff(int type);
202         void OnUpdateNext3wayDiff(CCmdUI* pCmdUI, int type);
203         void OnPrev3wayDiff(int type);
204         void OnUpdatePrev3wayDiff(CCmdUI* pCmdUI, int type);
205         void OnDropFiles(const std::vector<String>& files);
206
207         // Generated message map functions
208 protected:
209         //{{AFX_MSG(CMergeEditView)
210         afx_msg void OnCurdiff();
211         afx_msg void OnUpdateCurdiff(CCmdUI* pCmdUI);
212         afx_msg void OnEditCopy();
213         afx_msg void OnUpdateEditCopy(CCmdUI* pCmdUI);
214         afx_msg void OnEditCut();
215         afx_msg void OnUpdateEditCut(CCmdUI* pCmdUI);
216         afx_msg void OnEditPaste();
217         afx_msg void OnUpdateEditPaste(CCmdUI* pCmdUI);
218         afx_msg void OnEditUndo();
219         afx_msg void OnFirstdiff();
220         afx_msg void OnUpdateFirstdiff(CCmdUI* pCmdUI);
221         afx_msg void OnLastdiff();
222         afx_msg void OnUpdateLastdiff(CCmdUI* pCmdUI);
223         afx_msg void OnNextdiff();
224         afx_msg void OnUpdateNextdiff(CCmdUI* pCmdUI);
225         afx_msg void OnPrevdiff();
226         afx_msg void OnUpdatePrevdiff(CCmdUI* pCmdUI);
227         afx_msg void OnNextConflict();
228         afx_msg void OnUpdateNextConflict(CCmdUI* pCmdUI);
229         afx_msg void OnPrevConflict();
230         afx_msg void OnUpdatePrevConflict(CCmdUI* pCmdUI);
231         afx_msg void OnNextdiffLM();
232         afx_msg void OnUpdateNextdiffLM(CCmdUI* pCmdUI);
233         afx_msg void OnPrevdiffLM();
234         afx_msg void OnUpdatePrevdiffLM(CCmdUI* pCmdUI);
235         afx_msg void OnNextdiffLR();
236         afx_msg void OnUpdateNextdiffLR(CCmdUI* pCmdUI);
237         afx_msg void OnPrevdiffLR();
238         afx_msg void OnUpdatePrevdiffLR(CCmdUI* pCmdUI);
239         afx_msg void OnNextdiffMR();
240         afx_msg void OnUpdateNextdiffMR(CCmdUI* pCmdUI);
241         afx_msg void OnPrevdiffMR();
242         afx_msg void OnUpdatePrevdiffMR(CCmdUI* pCmdUI);
243         afx_msg void OnNextdiffLO();
244         afx_msg void OnUpdateNextdiffLO(CCmdUI* pCmdUI);
245         afx_msg void OnPrevdiffLO();
246         afx_msg void OnUpdatePrevdiffLO(CCmdUI* pCmdUI);
247         afx_msg void OnNextdiffMO();
248         afx_msg void OnUpdateNextdiffMO(CCmdUI* pCmdUI);
249         afx_msg void OnPrevdiffMO();
250         afx_msg void OnUpdatePrevdiffMO(CCmdUI* pCmdUI);
251         afx_msg void OnNextdiffRO();
252         afx_msg void OnUpdateNextdiffRO(CCmdUI* pCmdUI);
253         afx_msg void OnPrevdiffRO();
254         afx_msg void OnUpdatePrevdiffRO(CCmdUI* pCmdUI);
255         afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
256         afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
257         afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
258         afx_msg void OnAllLeft();
259         afx_msg void OnUpdateAllLeft(CCmdUI* pCmdUI);
260         afx_msg void OnAllRight();
261         afx_msg void OnUpdateAllRight(CCmdUI* pCmdUI);
262         afx_msg void OnAutoMerge();
263         afx_msg void OnUpdateAutoMerge(CCmdUI* pCmdUI);
264         afx_msg void OnX2Y(int srcPane, int dstPane, bool selectedLineOnly = false);
265         afx_msg void OnUpdateX2Y(int dstPane, CCmdUI* pCmdUI);
266         afx_msg void OnL2r();
267         afx_msg void OnUpdateL2r(CCmdUI* pCmdUI);
268         afx_msg void OnLinesL2r();
269         afx_msg void OnUpdateLinesL2r(CCmdUI* pCmdUI);
270         afx_msg void OnR2l();
271         afx_msg void OnUpdateR2l(CCmdUI* pCmdUI);
272         afx_msg void OnLinesR2l();
273         afx_msg void OnUpdateLinesR2l(CCmdUI* pCmdUI);
274         afx_msg void OnCopyFromLeft();
275         afx_msg void OnUpdateCopyFromLeft(CCmdUI* pCmdUI);
276         afx_msg void OnCopyLinesFromLeft();
277         afx_msg void OnUpdateCopyLinesFromLeft(CCmdUI* pCmdUI);
278         afx_msg void OnCopyFromRight();
279         afx_msg void OnUpdateCopyFromRight(CCmdUI* pCmdUI);
280         afx_msg void OnCopyLinesFromRight();
281         afx_msg void OnUpdateCopyLinesFromRight(CCmdUI* pCmdUI);
282         afx_msg void OnAddSyncPoint();
283         afx_msg void OnClearSyncPoints();
284         afx_msg void OnUpdateClearSyncPoints(CCmdUI* pCmdUI);
285         afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
286         afx_msg void OnEditRedo();
287         afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI);
288         afx_msg void OnTimer(UINT_PTR nIDEvent);
289         afx_msg void OnUpdateFileSaveLeft(CCmdUI* pCmdUI);
290         afx_msg void OnUpdateFileSaveMiddle(CCmdUI* pCmdUI);
291         afx_msg void OnUpdateFileSaveRight(CCmdUI* pCmdUI);
292         afx_msg void OnRefresh();
293         afx_msg void OnUpdateFileSave(CCmdUI* pCmdUI);
294         template<bool reversed>
295         afx_msg void OnSelectLineDiff();
296         afx_msg void OnUpdateSelectLineDiff(CCmdUI* pCmdUI);
297         afx_msg void OnAddToSubstitutionFilters();
298         afx_msg void OnUpdateAddToSubstitutionFilters(CCmdUI* pCmdUI);
299         afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
300         afx_msg void OnUpdateEditReplace(CCmdUI* pCmdUI);
301         afx_msg void OnLeftReadOnly();
302         afx_msg void OnUpdateLeftReadOnly(CCmdUI* pCmdUI);
303         afx_msg void OnMiddleReadOnly();
304         afx_msg void OnUpdateMiddleReadOnly(CCmdUI* pCmdUI);
305         afx_msg void OnRightReadOnly();
306         afx_msg void OnUpdateRightReadOnly(CCmdUI* pCmdUI);
307         afx_msg void OnUpdateStatusRO(CCmdUI* pCmdUI);
308         afx_msg void OnConvertEolTo(UINT nID );
309         afx_msg void OnUpdateConvertEolTo(CCmdUI* pCmdUI);
310         afx_msg void OnUpdateStatusEOL(CCmdUI* pCmdUI);
311         afx_msg void OnL2RNext();
312         afx_msg void OnUpdateL2RNext(CCmdUI* pCmdUI);
313         afx_msg void OnR2LNext();
314         afx_msg void OnUpdateR2LNext(CCmdUI* pCmdUI);
315         afx_msg void OnChangePane();
316         afx_msg void OnWMGoto();
317         afx_msg void OnGotoMovedLineLM();
318         afx_msg void OnUpdateGotoMovedLineLM(CCmdUI* pCmdUI);
319         afx_msg void OnGotoMovedLineMR();
320         afx_msg void OnUpdateGotoMovedLineMR(CCmdUI* pCmdUI);
321         afx_msg void OnShellMenu();
322         afx_msg void OnUpdateShellMenu(CCmdUI* pCmdUI);
323         afx_msg void OnScripts(UINT nID );
324         afx_msg void OnUpdateNoPrediffer(CCmdUI* pCmdUI);
325         afx_msg void OnUpdatePrediffer(CCmdUI* pCmdUI);
326         afx_msg void OnNoPrediffer();
327         afx_msg void OnPrediffer(UINT nID );
328         afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar);
329         afx_msg void OnVScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar);
330         afx_msg void OnEditCopyLineNumbers();
331         afx_msg void OnUpdateEditCopyLinenumbers(CCmdUI* pCmdUI);
332         afx_msg void OnViewLineDiffs();
333         afx_msg void OnUpdateViewLineDiffs(CCmdUI* pCmdUI);
334         afx_msg void OnViewLineNumbers();
335         afx_msg void OnUpdateViewLineNumbers(CCmdUI* pCmdUI);
336         afx_msg void OnViewWordWrap();
337         afx_msg void OnUpdateViewWordWrap(CCmdUI* pCmdUI);
338         afx_msg void OnViewWhitespace();
339         afx_msg void OnUpdateViewWhitespace(CCmdUI* pCmdUI);
340         afx_msg void OnViewEOL();
341         afx_msg void OnUpdateViewEOL(CCmdUI* pCmdUI);
342         afx_msg void OnOpenFile();
343         afx_msg void OnOpenFileWith();
344         afx_msg void OnOpenFileWithEditor();
345         afx_msg void OnViewSwapPanes12();
346         afx_msg void OnViewSwapPanes23();
347         afx_msg void OnViewSwapPanes13();
348         afx_msg void OnUpdateNoEditScripts(CCmdUI* pCmdUI);
349         afx_msg void OnSize(UINT nType, int cx, int cy);
350         afx_msg void OnHelp();
351         afx_msg void OnViewMargin();
352         afx_msg void OnUpdateViewMargin(CCmdUI* pCmdUI);
353         afx_msg void OnUpdateViewChangeScheme(CCmdUI *pCmdUI);
354         afx_msg void OnChangeScheme(UINT nID);
355         afx_msg void OnUpdateChangeScheme(CCmdUI* pCmdUI);
356         afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
357         afx_msg void OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt);
358         afx_msg void OnViewZoomIn();
359         afx_msg void OnViewZoomOut();
360         afx_msg void OnViewZoomNormal();
361         afx_msg void OnWindowSplit();
362         afx_msg void OnUpdateWindowSplit(CCmdUI* pCmdUI);
363         afx_msg void OnStatusBarDblClick(NMHDR* pNMHDR, LRESULT* pResult);
364
365         //}}AFX_MSG
366         DECLARE_MESSAGE_MAP()
367 };
368
369 #ifndef _DEBUG  // debug version in DiffView.cpp
370 inline CMergeDoc* CMergeEditView::GetDocument()
371    { return reinterpret_cast<CMergeDoc*>(m_pDocument); }
372 #endif
373
374 /**
375  * @brief Enable/Disable automatic rescanning
376  */
377 inline bool CMergeEditView::EnableRescan(bool bEnable)
378 {
379         bool bOldValue = m_bAutomaticRescan;
380         m_bAutomaticRescan = bEnable;
381         return bOldValue;
382 }
383
384 /**
385  * @brief Check if cursor is inside difference.
386  * @return true if cursor is inside difference.
387  */
388 inline bool CMergeEditView::IsCursorInDiff() const
389 {
390         return m_bCurrentLineIsDiff;
391 }
392