2 * @file GhostTextBuffer.h
4 * @brief Declaration of CGhostTextBuffer (subclasses CCrystalTextBuffer to handle ghost lines)
7 #ifndef __GHOSTTEXTBUFFER_H__
8 #define __GHOSTTEXTBUFFER_H__
11 #include "ccrystaltextbuffer.h"
14 /////////////////////////////////////////////////////////////////////////////
17 We use the current ccrystalEditor flags
19 This flag must be cleared and set in GhostTextBuffer.cpp
20 and MergeDoc.cpp (Rescan) only.
22 GetLineColors (in MergeEditView) reads it to choose the line color.
27 LF_GHOST = 0x00400000L,
33 /////////////////////////////////////////////////////////////////////////////
34 // CCrystalTextBuffer command target
37 Features offered with this class :
39 <li> apparent/real line conversion
40 <li> insertText/deleteText working with ghost lines
41 <li> AddUndoRecord/Undo/Redo working with ghost lines
42 <li> insertGhostLine function
45 class EDITPADC_CLASS CGhostTextBuffer : public CCrystalTextBuffer
48 DECLARE_DYNCREATE (CGhostTextBuffer)
52 // Nested class declarations
56 int m_nLength, m_nMax;
57 int m_nEolChars; // # of eolchars
59 DWORD m_dwRevisionNumber;
61 int FullLength() const { return m_nLength+m_nEolChars; }
62 int Length() const { return m_nLength; }
66 memset (this, 0, sizeof (SLineInfo));
73 UNDO_BEGINGROUP = 0x0100
77 Support For Descriptions On Undo/Redo Actions
79 We need a structure to remember richer information position
80 and the number of real lines inserted/deleted (to set ghost lines during undo)
82 This flags are parameters of AddUndoRecord ; so AddUndoRecord
83 is not the virtual version of CCrystalTextBuffer::AddUndoRecord
85 The text is duplicated (already in CCrystalTextBuffer::SUndoRecord),
86 and it is not useful. If someone finds a clean way to correct this...
92 // Undo records store file line numbers, not screen line numbers
93 // File line numbers do not count ghost lines
94 // (ghost lines are lines with no text and no EOL chars, which are
95 // used by WinMerge as left-only or right-only placeholders)
96 // All the stored line number needed are real !
98 CPoint m_ptStartPos, m_ptEndPos; // Block of text participating
99 int m_ptStartPos_nGhost, m_ptEndPos_nGhost;
101 // Redo records store file line numbers, not screen line numbers
102 // they store the file number of the previous real line
103 // and (apparentLine - ComputeApparentLine(previousRealLine))
105 CPoint m_redo_ptStartPos, m_redo_ptEndPos; // Block of text participating
106 int m_redo_ptStartPos_nGhost, m_redo_ptEndPos_nGhost;
108 int m_nRealLinesCreated; // number of lines created during insertion
109 // (= total of real lines after - total before)
110 int m_nRealLinesInDeletedBlock; // number of real lines in the deleted block
111 // (<> total of real lines after - total before
112 // as first/end line may be just truncated, not removed)
113 int m_nAction; // For information only: action type
114 CDWordArray *m_paSavedRevisonNumbers;
118 // Since in most cases we have 1 character here,
119 // we should invent a better way. Note: 2 * sizeof(WORD) <= sizeof(TCHAR*)
121 // Here we will use the following trick: on Win32 platforms high-order word
122 // of any pointer will be != 0. So we can store 1 character strings without
123 // allocating memory.
132 TextBuffer *m_pszText; // For cases when we have > 1 character strings
133 TCHAR m_szText[2]; // For single-character strings
138 SUndoRecord () // default constructor
140 memset (this, 0, sizeof (SUndoRecord));
142 SUndoRecord (const SUndoRecord & src) // copy constructor
144 memset (this, 0, sizeof (SUndoRecord));
147 SUndoRecord & operator=(const SUndoRecord & src) // copy assignment
149 m_dwFlags = src.m_dwFlags;
150 m_ptStartPos = src.m_ptStartPos;
151 m_ptStartPos_nGhost = src.m_ptStartPos_nGhost;
152 m_ptEndPos = src.m_ptEndPos;
153 m_ptEndPos_nGhost = src.m_ptEndPos_nGhost;
154 m_nAction = src.m_nAction;
155 m_redo_ptStartPos = src.m_redo_ptStartPos;
156 m_redo_ptStartPos_nGhost = src.m_redo_ptStartPos_nGhost;
157 m_redo_ptEndPos = src.m_redo_ptEndPos;
158 m_redo_ptEndPos_nGhost = src.m_redo_ptEndPos_nGhost;
159 m_nRealLinesCreated = src.m_nRealLinesCreated;
160 m_nRealLinesInDeletedBlock = src.m_nRealLinesInDeletedBlock;
161 SetText(src.GetText(), src.GetTextLength());
162 INT_PTR size = src.m_paSavedRevisonNumbers->GetSize();
163 if (!m_paSavedRevisonNumbers)
164 m_paSavedRevisonNumbers = new CDWordArray();
165 m_paSavedRevisonNumbers->SetSize(size);
167 for (i = 0; i < size; i++)
168 (*m_paSavedRevisonNumbers)[i] = (*src.m_paSavedRevisonNumbers)[i];
171 ~SUndoRecord () // destructor
174 if (m_paSavedRevisonNumbers)
175 delete m_paSavedRevisonNumbers;
178 void SetText (LPCTSTR pszText, int cchText);
181 LPCTSTR GetText () const
183 // See the m_szText/m_pszText definition
184 // Check if m_pszText is a pointer by removing bits having
185 // possible char value
186 if (((INT_PTR)m_pszText >> 16) != 0)
187 return m_pszText->data;
190 int GetTextLength () const
192 if (((INT_PTR)m_pszText >> 16) != 0)
193 return m_pszText->size;
202 We need another array with our richer structure.
204 We share the positions with the CCrystalTextBuffer object.
205 We share m_bUndoGroup, its utility is to check we opened the UndoBeginGroup.
206 We share m_nUndoBufSize which is the max buffer size.
208 CArray < SUndoRecord, SUndoRecord & >m_aUndoBuf;
210 This one must be duplicated because the flag UNDO_BEGINGROUP needs to be set in both
211 CGhostTextBuffer::m_aUndoBuf and CCrystalTextBuffer::m_aUndoBuf CArrays
213 BOOL m_bUndoBeginGroup;
215 // [JRT] Support For Descriptions On Undo/Redo Actions
216 virtual void AddUndoRecord (BOOL bInsert, const CPoint & ptStartPos, const CPoint & ptEndPos,
217 LPCTSTR pszText, int cchText, int nRealLinesChanged, int nActionType = CE_ACTION_UNKNOWN, CDWordArray *paSavedRevisonNumbers = NULL);
220 // A RealityBlock is a block of lines with no ghost lines
221 struct RealityBlock { int nStartReal; int nStartApparent; int nCount; };
222 // The array of reality blocks is kept in order
223 CArray < RealityBlock, RealityBlock& > m_RealityBlocks;
229 BOOL InternalInsertGhostLine (CCrystalTextView * pSource, int nLine);
230 BOOL InternalDeleteGhostLine (CCrystalTextView * pSource, int nLine, int nCount);
232 // Construction/destruction code
234 virtual BOOL InitNew (int nCrlfStyle = CRLF_STYLE_DOS);
237 This should work in base code as ghost lines are real empty lines
238 but maybe it doesn't (if there is an assert to check there is an EOL,
239 or if it adds the default EOL)
241 virtual void GetTextWithoutEmptys (int nStartLine, int nStartChar, int nEndLine, int nEndChar, CString &text, int 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__