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__
13 #include "ccrystaltextbuffer.h"
16 /////////////////////////////////////////////////////////////////////////////
19 * We use the current ccrystalEditor flags
21 * This flag must be cleared and set in GhostTextBuffer.cpp
22 * and MergeDoc.cpp (Rescan) only.
24 * GetLineColors (in MergeEditView) reads it to choose the line color.
28 LF_GHOST = 0x00400000L, /**< Ghost line. */
31 /////////////////////////////////////////////////////////////////////////////
32 // CCrystalTextBuffer command target
35 * @brief A class handling ghost lines.
36 * Features offered with this class :
38 * <li> apparent/real line conversion
39 * <li> insertText/deleteText working with ghost lines
40 * <li> AddUndoRecord/Undo/Redo working with ghost lines
41 * <li> insertGhostLine function
44 class EDITPADC_CLASS CGhostTextBuffer : public CCrystalTextBuffer
47 DECLARE_DYNCREATE (CGhostTextBuffer)
51 // Nested class declarations
55 int m_nLength, m_nMax;
56 int m_nEolChars; // # of eolchars
58 DWORD m_dwRevisionNumber;
60 int FullLength() const { return m_nLength + m_nEolChars; }
61 int Length() const { return m_nLength; }
65 memset (this, 0, sizeof (SLineInfo));
72 UNDO_BEGINGROUP = 0x0100
76 Support For Descriptions On Undo/Redo Actions
78 We need a structure to remember richer information position
79 and the number of real lines inserted/deleted (to set ghost lines during undo)
81 This flags are parameters of AddUndoRecord ; so AddUndoRecord
82 is not the virtual version of CCrystalTextBuffer::AddUndoRecord
84 The text is duplicated (already in CCrystalTextBuffer::SUndoRecord),
85 and it is not useful. If someone finds a clean way to correct this...
91 // Undo records store file line numbers, not screen line numbers
92 // File line numbers do not count ghost lines
93 // (ghost lines are lines with no text and no EOL chars, which are
94 // used by WinMerge as left-only or right-only placeholders)
95 // All the stored line number needed are real !
97 CPoint m_ptStartPos, m_ptEndPos; // Block of text participating
98 int m_ptStartPos_nGhost, m_ptEndPos_nGhost;
100 // Redo records store file line numbers, not screen line numbers
101 // they store the file number of the previous real line
102 // and (apparentLine - ComputeApparentLine(previousRealLine))
104 CPoint m_redo_ptStartPos, m_redo_ptEndPos; // Block of text participating
105 int m_redo_ptStartPos_nGhost, m_redo_ptEndPos_nGhost;
107 int m_nRealLinesCreated; // number of lines created during insertion
108 // (= total of real lines after - total before)
109 int m_nRealLinesInDeletedBlock; // number of real lines in the deleted block
110 // (<> total of real lines after - total before
111 // as first/end line may be just truncated, not removed)
112 int m_nAction; // For information only: action type
113 CDWordArray *m_paSavedRevisonNumbers;
117 // Since in most cases we have 1 character here,
118 // we should invent a better way. Note: 2 * sizeof(WORD) <= sizeof(TCHAR*)
120 // Here we will use the following trick: on Win32 platforms high-order word
121 // of any pointer will be != 0. So we can store 1 character strings without
122 // allocating memory.
131 TextBuffer *m_pszText; // For cases when we have > 1 character strings
132 TCHAR m_szText[2]; // For single-character strings
137 SUndoRecord () // default constructor
139 memset (this, 0, sizeof (SUndoRecord));
141 SUndoRecord (const SUndoRecord & src) // copy constructor
143 memset (this, 0, sizeof (SUndoRecord));
146 SUndoRecord & operator=(const SUndoRecord & src) // copy assignment
148 m_dwFlags = src.m_dwFlags;
149 m_ptStartPos = src.m_ptStartPos;
150 m_ptStartPos_nGhost = src.m_ptStartPos_nGhost;
151 m_ptEndPos = src.m_ptEndPos;
152 m_ptEndPos_nGhost = src.m_ptEndPos_nGhost;
153 m_nAction = src.m_nAction;
154 m_redo_ptStartPos = src.m_redo_ptStartPos;
155 m_redo_ptStartPos_nGhost = src.m_redo_ptStartPos_nGhost;
156 m_redo_ptEndPos = src.m_redo_ptEndPos;
157 m_redo_ptEndPos_nGhost = src.m_redo_ptEndPos_nGhost;
158 m_nRealLinesCreated = src.m_nRealLinesCreated;
159 m_nRealLinesInDeletedBlock = src.m_nRealLinesInDeletedBlock;
160 SetText(src.GetText(), src.GetTextLength());
161 INT_PTR size = src.m_paSavedRevisonNumbers->GetSize();
162 if (!m_paSavedRevisonNumbers)
163 m_paSavedRevisonNumbers = new CDWordArray();
164 m_paSavedRevisonNumbers->SetSize(size);
166 for (i = 0; i < size; i++)
167 (*m_paSavedRevisonNumbers)[i] = (*src.m_paSavedRevisonNumbers)[i];
170 ~SUndoRecord () // destructor
173 if (m_paSavedRevisonNumbers)
174 delete m_paSavedRevisonNumbers;
177 void SetText (LPCTSTR pszText, int cchText);
180 LPCTSTR GetText () const
182 // See the m_szText/m_pszText definition
183 // Check if m_pszText is a pointer by removing bits having
184 // possible char value
185 if (((INT_PTR)m_pszText >> 16) != 0)
186 return m_pszText->data;
189 int GetTextLength () const
191 if (((INT_PTR)m_pszText >> 16) != 0)
192 return m_pszText->size;
201 We need another array with our richer structure.
203 We share the positions with the CCrystalTextBuffer object.
204 We share m_bUndoGroup, its utility is to check we opened the UndoBeginGroup.
205 We share m_nUndoBufSize which is the max buffer size.
207 std::vector<SUndoRecord> m_aUndoBuf;
209 This one must be duplicated because the flag UNDO_BEGINGROUP needs to be set in both
210 CGhostTextBuffer::m_aUndoBuf and CCrystalTextBuffer::m_aUndoBuf CArrays
212 BOOL m_bUndoBeginGroup;
214 // [JRT] Support For Descriptions On Undo/Redo Actions
215 virtual void AddUndoRecord (BOOL bInsert, const CPoint & ptStartPos, const CPoint & ptEndPos,
216 LPCTSTR pszText, int cchText, int nRealLinesChanged, int nActionType = CE_ACTION_UNKNOWN, CDWordArray *paSavedRevisonNumbers = NULL);
220 * @brief A struct mapping real lines and apparent (screen) lines.
221 * This struct maps lines between real lines and apparent (screen) lines.
222 * The mapping records for each text block an apparent line and matching
227 int nStartReal; /**< Start line of real block. */
228 int nStartApparent; /**< Start line of apparent block. */
229 int nCount; /**< Lines in the block. */
231 std::vector<RealityBlock> m_RealityBlocks; /**< Mapping of real and apparent lines. */
235 BOOL InternalInsertGhostLine (CCrystalTextView * pSource, int nLine);
236 BOOL InternalDeleteGhostLine (CCrystalTextView * pSource, int nLine, int nCount);
238 // Construction/destruction code
240 virtual BOOL InitNew (CRLFSTYLE nCrlfStyle = CRLF_STYLE_DOS);
243 This should work in base code as ghost lines are real empty lines
244 but maybe it doesn't (if there is an assert to check there is an EOL,
245 or if it adds the default EOL)
247 virtual void GetTextWithoutEmptys (int nStartLine, int nStartChar,
248 int nEndLine, int nEndChar, CString &text,
249 CRLFSTYLE nCrlfStyle =CRLF_STYLE_AUTOMATIC);
252 // Text modification functions
253 virtual BOOL InsertText (CCrystalTextView * pSource, int nLine, int nPos,
254 LPCTSTR pszText, int cchText, int &nEndLine, int &nEndChar,
255 int nAction = CE_ACTION_UNKNOWN, BOOL bHistory = TRUE);
256 virtual BOOL DeleteText (CCrystalTextView * pSource, int nStartLine,
257 int nStartPos, int nEndLine, int nEndPos,
258 int nAction = CE_ACTION_UNKNOWN, BOOL bHistory = TRUE);
259 BOOL InsertGhostLine (CCrystalTextView * pSource, int nLine);
262 virtual BOOL Undo (CCrystalTextView * pSource, CPoint & ptCursorPos);
263 virtual BOOL Redo (CCrystalTextView * pSource, CPoint & ptCursorPos);
266 virtual void BeginUndoGroup (BOOL bMergeWithPrevious = FALSE);
267 virtual void FlushUndoGroup (CCrystalTextView * pSource);
272 * @name Real/apparent line number conversion functions.
273 * These functions convert line numbers between file line numbers
274 * (real line numbers) and screen line numbers (apparent line numbers).
276 * This mapping is needed to handle ghost lines (ones with no text or
277 * EOL chars) which WinMerge uses for left-only or right-only lines.
279 int ApparentLastRealLine() const;
280 int ComputeRealLine(int nApparentLine) const;
281 int ComputeApparentLine(int nRealLine) const;
282 /** richer position information yApparent = apparent(yReal) - yGhost */
283 int ComputeRealLineAndGhostAdjustment(int nApparentLine, int& decToReal) const;
284 /** richer position information yApparent = apparent(yReal) - yGhost */
285 int ComputeApparentLine(int nRealLine, int decToReal) const;
288 /** for loading file */
289 void FinishLoading();
290 /** for saving file */
291 void RemoveAllGhostLines();
295 void RecomputeRealityMapping();
297 Code to set EOL, if the status ghost/real of the line changes
299 We should call a CCrystalTextBuffer function to add the correct EOL
300 (if CCrystalTextBuffer keeps the default EOL for the file)
302 void RecomputeEOL(CCrystalTextView * pSource, int nStartLine, int nEndLine);
303 /** For debugging purpose */
304 void checkFlagsFromReality(BOOL bFlag) const;
307 virtual void OnNotifyLineHasBeenEdited(int nLine);
312 // ClassWizard generated virtual function overrides
313 //{{AFX_VIRTUAL(CCrystalTextBuffer)
316 // Generated message map functions
317 //{{AFX_MSG(CCrystalTextBuffer)
320 DECLARE_MESSAGE_MAP ()
323 /////////////////////////////////////////////////////////////////////////////
325 //{{AFX_INSERT_LOCATION}}
326 // Microsoft Developer Studio will insert additional declarations immediately before the previous line.
329 #endif //__GHOSTTEXTBUFFER_H__