2 * @file GhostTextBuffer.h
4 * @brief Declaration of CGhostTextBuffer (subclasses CCrystalTextBuffer to handle ghost lines)
6 // ID line follows -- this is updated by SVN
9 #ifndef __GHOSTTEXTBUFFER_H__
10 #define __GHOSTTEXTBUFFER_H__
12 #include "ccrystaltextbuffer.h"
15 /////////////////////////////////////////////////////////////////////////////
18 * We use the current ccrystalEditor flags
20 * This flag must be cleared and set in GhostTextBuffer.cpp
21 * and MergeDoc.cpp (Rescan) only.
23 * GetLineColors (in MergeEditView) reads it to choose the line color.
27 LF_GHOST = 0x00400000L, /**< Ghost line. */
30 /////////////////////////////////////////////////////////////////////////////
31 // CCrystalTextBuffer command target
34 * @brief A class handling ghost lines.
35 * Features offered with this class :
37 * <li> apparent/real line conversion
38 * <li> insertText/deleteText working with ghost lines
39 * <li> AddUndoRecord/Undo/Redo working with ghost lines
40 * <li> insertGhostLine function
43 class EDITPADC_CLASS CGhostTextBuffer : public CCrystalTextBuffer
46 DECLARE_DYNCREATE (CGhostTextBuffer)
50 // Nested class declarations
54 int m_nLength, m_nMax;
55 int m_nEolChars; // # of eolchars
57 DWORD m_dwRevisionNumber;
59 int FullLength() const { return m_nLength + m_nEolChars; }
60 int Length() const { return m_nLength; }
64 memset (this, 0, sizeof (SLineInfo));
71 UNDO_BEGINGROUP = 0x0100
75 Support For Descriptions On Undo/Redo Actions
77 We need a structure to remember richer information position
78 and the number of real lines inserted/deleted (to set ghost lines during undo)
80 This flags are parameters of AddUndoRecord ; so AddUndoRecord
81 is not the virtual version of CCrystalTextBuffer::AddUndoRecord
83 The text is duplicated (already in CCrystalTextBuffer::SUndoRecord),
84 and it is not useful. If someone finds a clean way to correct this...
90 // Undo records store file line numbers, not screen line numbers
91 // File line numbers do not count ghost lines
92 // (ghost lines are lines with no text and no EOL chars, which are
93 // used by WinMerge as left-only or right-only placeholders)
94 // All the stored line number needed are real !
96 CPoint m_ptStartPos, m_ptEndPos; // Block of text participating
97 int m_ptStartPos_nGhost, m_ptEndPos_nGhost;
99 // Redo records store file line numbers, not screen line numbers
100 // they store the file number of the previous real line
101 // and (apparentLine - ComputeApparentLine(previousRealLine))
103 CPoint m_redo_ptStartPos, m_redo_ptEndPos; // Block of text participating
104 int m_redo_ptStartPos_nGhost, m_redo_ptEndPos_nGhost;
106 int m_nRealLinesCreated; // number of lines created during insertion
107 // (= total of real lines after - total before)
108 int m_nRealLinesInDeletedBlock; // number of real lines in the deleted block
109 // (<> total of real lines after - total before
110 // as first/end line may be just truncated, not removed)
111 int m_nAction; // For information only: action type
112 CDWordArray *m_paSavedRevisonNumbers;
116 // Since in most cases we have 1 character here,
117 // we should invent a better way. Note: 2 * sizeof(WORD) <= sizeof(TCHAR*)
119 // Here we will use the following trick: on Win32 platforms high-order word
120 // of any pointer will be != 0. So we can store 1 character strings without
121 // allocating memory.
130 TextBuffer *m_pszText; // For cases when we have > 1 character strings
131 TCHAR m_szText[2]; // For single-character strings
136 SUndoRecord () // default constructor
138 memset (this, 0, sizeof (SUndoRecord));
140 SUndoRecord (const SUndoRecord & src) // copy constructor
142 memset (this, 0, sizeof (SUndoRecord));
145 SUndoRecord & operator=(const SUndoRecord & src) // copy assignment
147 m_dwFlags = src.m_dwFlags;
148 m_ptStartPos = src.m_ptStartPos;
149 m_ptStartPos_nGhost = src.m_ptStartPos_nGhost;
150 m_ptEndPos = src.m_ptEndPos;
151 m_ptEndPos_nGhost = src.m_ptEndPos_nGhost;
152 m_nAction = src.m_nAction;
153 m_redo_ptStartPos = src.m_redo_ptStartPos;
154 m_redo_ptStartPos_nGhost = src.m_redo_ptStartPos_nGhost;
155 m_redo_ptEndPos = src.m_redo_ptEndPos;
156 m_redo_ptEndPos_nGhost = src.m_redo_ptEndPos_nGhost;
157 m_nRealLinesCreated = src.m_nRealLinesCreated;
158 m_nRealLinesInDeletedBlock = src.m_nRealLinesInDeletedBlock;
159 SetText(src.GetText(), src.GetTextLength());
160 INT_PTR size = src.m_paSavedRevisonNumbers->GetSize();
161 if (!m_paSavedRevisonNumbers)
162 m_paSavedRevisonNumbers = new CDWordArray();
163 m_paSavedRevisonNumbers->SetSize(size);
165 for (i = 0; i < size; i++)
166 (*m_paSavedRevisonNumbers)[i] = (*src.m_paSavedRevisonNumbers)[i];
169 ~SUndoRecord () // destructor
172 if (m_paSavedRevisonNumbers)
173 delete m_paSavedRevisonNumbers;
176 void SetText (LPCTSTR pszText, int cchText);
179 LPCTSTR GetText () const
181 // See the m_szText/m_pszText definition
182 // Check if m_pszText is a pointer by removing bits having
183 // possible char value
184 if (((INT_PTR)m_pszText >> 16) != 0)
185 return m_pszText->data;
188 int GetTextLength () const
190 if (((INT_PTR)m_pszText >> 16) != 0)
191 return m_pszText->size;
200 We need another array with our richer structure.
202 We share the positions with the CCrystalTextBuffer object.
203 We share m_bUndoGroup, its utility is to check we opened the UndoBeginGroup.
204 We share m_nUndoBufSize which is the max buffer size.
206 CArray < SUndoRecord, SUndoRecord & >m_aUndoBuf;
208 This one must be duplicated because the flag UNDO_BEGINGROUP needs to be set in both
209 CGhostTextBuffer::m_aUndoBuf and CCrystalTextBuffer::m_aUndoBuf CArrays
211 BOOL m_bUndoBeginGroup;
213 // [JRT] Support For Descriptions On Undo/Redo Actions
214 virtual void AddUndoRecord (BOOL bInsert, const CPoint & ptStartPos, const CPoint & ptEndPos,
215 LPCTSTR pszText, int cchText, int nRealLinesChanged, int nActionType = CE_ACTION_UNKNOWN, CDWordArray *paSavedRevisonNumbers = NULL);
218 // A RealityBlock is a block of lines with no ghost lines
219 struct RealityBlock { int nStartReal; int nStartApparent; int nCount; };
220 // The array of reality blocks is kept in order
221 CArray < RealityBlock, RealityBlock& > m_RealityBlocks;
227 BOOL InternalInsertGhostLine (CCrystalTextView * pSource, int nLine);
228 BOOL InternalDeleteGhostLine (CCrystalTextView * pSource, int nLine, int nCount);
230 // Construction/destruction code
232 virtual BOOL InitNew (CRLFSTYLE nCrlfStyle = CRLF_STYLE_DOS);
235 This should work in base code as ghost lines are real empty lines
236 but maybe it doesn't (if there is an assert to check there is an EOL,
237 or if it adds the default EOL)
239 virtual void GetTextWithoutEmptys (int nStartLine, int nStartChar,
240 int nEndLine, int nEndChar, CString &text,
241 CRLFSTYLE nCrlfStyle =CRLF_STYLE_AUTOMATIC);
244 // Text modification functions
245 virtual BOOL InsertText (CCrystalTextView * pSource, int nLine, int nPos, LPCTSTR pszText, int cchText, int &nEndLine, int &nEndChar, int nAction = CE_ACTION_UNKNOWN, BOOL bHistory =TRUE);
246 virtual BOOL DeleteText (CCrystalTextView * pSource, int nStartLine, int nStartPos, int nEndLine, int nEndPos, int nAction = CE_ACTION_UNKNOWN, BOOL bHistory =TRUE);
247 BOOL InsertGhostLine (CCrystalTextView * pSource, int nLine);
250 virtual BOOL Undo (CCrystalTextView * pSource, CPoint & ptCursorPos);
251 virtual BOOL Redo (CCrystalTextView * pSource, CPoint & ptCursorPos);
254 virtual void BeginUndoGroup (BOOL bMergeWithPrevious = FALSE);
255 virtual void FlushUndoGroup (CCrystalTextView * pSource);
259 Code for mapping between file line numbers (real line numbers)
260 and screen line numbers (apparent line numbers).
262 This is needed to handle ghost lines (ones with no text or EOL chars)
263 which WinMerge uses for left-only or right-only lines.
265 int ApparentLastRealLine() const;
266 int ComputeRealLine(int nApparentLine) const;
267 int ComputeApparentLine(int nRealLine) const;
268 /** richer position information yApparent = apparent(yReal) - yGhost */
269 int ComputeRealLineAndGhostAdjustment(int nApparentLine, int& decToReal) const;
270 /** richer position information yApparent = apparent(yReal) - yGhost */
271 int ComputeApparentLine(int nRealLine, int decToReal) const;
273 /** for loading file */
274 void FinishLoading();
275 /** for saving file */
276 void RemoveAllGhostLines();
280 void RecomputeRealityMapping();
282 Code to set EOL, if the status ghost/real of the line changes
284 We should call a CCrystalTextBuffer function to add the correct EOL
285 (if CCrystalTextBuffer keeps the default EOL for the file)
287 void RecomputeEOL(CCrystalTextView * pSource, int nStartLine, int nEndLine);
288 /** For debugging purpose */
289 void checkFlagsFromReality(BOOL bFlag) const;
292 virtual void OnNotifyLineHasBeenEdited(int nLine);
297 // ClassWizard generated virtual function overrides
298 //{{AFX_VIRTUAL(CCrystalTextBuffer)
301 // Generated message map functions
302 //{{AFX_MSG(CCrystalTextBuffer)
305 DECLARE_MESSAGE_MAP ()
308 /////////////////////////////////////////////////////////////////////////////
310 //{{AFX_INSERT_LOCATION}}
311 // Microsoft Developer Studio will insert additional declarations immediately before the previous line.
314 #endif //__GHOSTTEXTBUFFER_H__