OSDN Git Service

Trivial cleanups and commenting additions and fixes.
[winmerge-jp/winmerge-jp.git] / Src / GhostTextBuffer.h
1 /**
2  * @file  GhostTextBuffer.h
3  *
4  * @brief Declaration of CGhostTextBuffer (subclasses CCrystalTextBuffer to handle ghost lines)
5  */
6 // ID line follows -- this is updated by SVN
7 // $Id$
8
9 #ifndef __GHOSTTEXTBUFFER_H__
10 #define __GHOSTTEXTBUFFER_H__
11
12 #include "ccrystaltextbuffer.h"
13
14
15 /////////////////////////////////////////////////////////////////////////////
16
17 /**
18  * We use the current ccrystalEditor flags 
19  *
20  * This flag must be cleared and set in GhostTextBuffer.cpp 
21  * and MergeDoc.cpp (Rescan) only.
22  *
23  * GetLineColors (in MergeEditView) reads it to choose the line color.
24  */
25 enum GHOST_LINEFLAGS
26 {
27         LF_GHOST = 0x00400000L, /**< Ghost line. */
28 };
29
30 /////////////////////////////////////////////////////////////////////////////
31 // CCrystalTextBuffer command target
32
33 /**
34  * @brief A class handling ghost lines.
35  * Features offered with this class : 
36  * <ul>
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 
41  * </ul>
42  */
43 class EDITPADC_CLASS CGhostTextBuffer : public CCrystalTextBuffer
44 {
45 public:
46         DECLARE_DYNCREATE (CGhostTextBuffer)
47
48 protected :
49 #pragma pack(push, 1)
50         //  Nested class declarations
51         struct SLineInfo
52         {
53                 TCHAR *m_pcLine;
54                 int m_nLength, m_nMax;
55                 int m_nEolChars; // # of eolchars
56                 DWORD m_dwFlags;
57                 DWORD m_dwRevisionNumber;
58
59                 int FullLength() const { return m_nLength + m_nEolChars; }
60                 int Length() const { return m_nLength; }
61
62                 SLineInfo ()
63                 {
64                         memset (this, 0, sizeof (SLineInfo));
65                 };
66         };
67
68         enum
69         {
70                 UNDO_INSERT = 0x0001,
71                 UNDO_BEGINGROUP = 0x0100
72         };
73
74         /** 
75         Support For Descriptions On Undo/Redo Actions
76
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)
79
80         This flags are parameters of AddUndoRecord ; so AddUndoRecord
81         is not the virtual version of CCrystalTextBuffer::AddUndoRecord
82
83         The text is duplicated (already in CCrystalTextBuffer::SUndoRecord),
84         and it is not useful. If someone finds a clean way to correct this...
85         */
86         struct SUndoRecord
87         {
88                 DWORD m_dwFlags;
89
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 !
95
96                 CPoint m_ptStartPos, m_ptEndPos;  // Block of text participating
97                 int m_ptStartPos_nGhost, m_ptEndPos_nGhost;
98
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))
102
103                 CPoint m_redo_ptStartPos, m_redo_ptEndPos;  // Block of text participating
104                 int m_redo_ptStartPos_nGhost, m_redo_ptEndPos_nGhost;
105
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;
113
114 private :
115                 // TCHAR   *m_pcText;
116                 // Since in most cases we have 1 character here,
117                 // we should invent a better way. Note: 2 * sizeof(WORD) <= sizeof(TCHAR*)
118                 //
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.
122                 //
123                 struct TextBuffer
124                 {
125                         int size;
126                         TCHAR data[1];
127                 };
128                 union
129                 {
130                         TextBuffer *m_pszText; // For cases when we have > 1 character strings
131                         TCHAR m_szText[2];     // For single-character strings
132
133                 };
134
135 public :
136                 SUndoRecord () // default constructor
137                 {
138                         memset (this, 0, sizeof (SUndoRecord));
139                 }
140                 SUndoRecord (const SUndoRecord & src) // copy constructor
141                 {
142                         memset (this, 0, sizeof (SUndoRecord));
143                         (*this)=src;
144                 }
145                 SUndoRecord & operator=(const SUndoRecord & src) // copy assignment
146                 {
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);
164                         INT_PTR i;
165                         for (i = 0; i < size; i++)
166                                 (*m_paSavedRevisonNumbers)[i] = (*src.m_paSavedRevisonNumbers)[i];
167                         return *this;
168                 }
169                 ~SUndoRecord () // destructor
170                 {
171                         FreeText();
172                         if (m_paSavedRevisonNumbers)
173                                 delete m_paSavedRevisonNumbers;
174                 }
175
176                 void SetText (LPCTSTR pszText, int cchText);
177                 void FreeText ();
178
179                 LPCTSTR GetText () const
180                 {
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;
186                         return m_szText;
187                 }
188                 int GetTextLength () const
189                 {
190                         if (((INT_PTR)m_pszText >> 16) != 0)
191                                 return m_pszText->size;
192                         return 1;
193                 }
194         };
195
196 #pragma pack(pop)
197
198 protected:
199         /** 
200         We need another array with our richer structure.
201
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.
205         */
206         CArray < SUndoRecord, SUndoRecord & >m_aUndoBuf;
207         /** 
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 
210         */
211         BOOL m_bUndoBeginGroup;
212
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);
216
217 private:
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;
222
223         // Operations
224 private:
225         BOOL InternalInsertGhostLine (CCrystalTextView * pSource, int nLine);
226         BOOL InternalDeleteGhostLine (CCrystalTextView * pSource, int nLine, int nCount);
227 public :
228         // Construction/destruction code
229         CGhostTextBuffer ();
230         virtual BOOL InitNew (CRLFSTYLE nCrlfStyle = CRLF_STYLE_DOS);
231
232         /** 
233         This should work in base code as ghost lines are real empty lines
234         but maybe it doesn't (if there is an assert to check there is an EOL,
235         or if it adds the default EOL)
236         */
237         virtual void GetTextWithoutEmptys (int nStartLine, int nStartChar,
238                         int nEndLine, int nEndChar, CString &text,
239                         CRLFSTYLE nCrlfStyle =CRLF_STYLE_AUTOMATIC);
240
241
242         // Text modification functions
243         virtual BOOL InsertText (CCrystalTextView * pSource, int nLine, int nPos,
244                 LPCTSTR pszText, int cchText, int &nEndLine, int &nEndChar,
245                 int nAction = CE_ACTION_UNKNOWN, BOOL bHistory = TRUE);
246         virtual BOOL DeleteText (CCrystalTextView * pSource, int nStartLine,
247                 int nStartPos, int nEndLine, int nEndPos,
248                 int nAction = CE_ACTION_UNKNOWN, BOOL bHistory = TRUE);
249         BOOL InsertGhostLine (CCrystalTextView * pSource, int nLine);
250
251         // Undo/Redo
252         virtual BOOL Undo (CCrystalTextView * pSource, CPoint & ptCursorPos);
253         virtual BOOL Redo (CCrystalTextView * pSource, CPoint & ptCursorPos);
254
255         // Undo grouping
256         virtual void BeginUndoGroup (BOOL bMergeWithPrevious = FALSE);
257         virtual void FlushUndoGroup (CCrystalTextView * pSource);
258
259 public:
260         //@{
261         /**
262          * @name Real/apparent line number conversion functions.
263          * These functions convert line numbers between file line numbers
264          * (real line numbers) and screen line numbers (apparent line numbers).
265          *
266          * This mapping is needed to handle ghost lines (ones with no text or
267          * EOL chars) which WinMerge uses for left-only or right-only lines.
268         */
269         int ApparentLastRealLine() const;
270         int ComputeRealLine(int nApparentLine) const;
271         int ComputeApparentLine(int nRealLine) const;
272         /** richer position information   yApparent = apparent(yReal) - yGhost */
273         int ComputeRealLineAndGhostAdjustment(int nApparentLine, int& decToReal) const;
274         /** richer position information   yApparent = apparent(yReal) - yGhost */
275         int ComputeApparentLine(int nRealLine, int decToReal) const;
276         //@}
277
278         /** for loading file */
279         void FinishLoading();
280         /** for saving file */ 
281         void RemoveAllGhostLines();
282
283
284 private:
285         void RecomputeRealityMapping();
286         /** 
287         Code to set EOL, if the status ghost/real of the line changes 
288
289         We should call a CCrystalTextBuffer function to add the correct EOL
290         (if CCrystalTextBuffer keeps the default EOL for the file)
291         */
292         void RecomputeEOL(CCrystalTextView * pSource, int nStartLine, int nEndLine);
293         /** For debugging purpose */
294         void checkFlagsFromReality(BOOL bFlag) const;
295
296 protected:
297         virtual void OnNotifyLineHasBeenEdited(int nLine);
298
299
300 protected:
301         // Overrides
302         // ClassWizard generated virtual function overrides
303         //{{AFX_VIRTUAL(CCrystalTextBuffer)
304         //}}AFX_VIRTUAL
305
306         // Generated message map functions
307         //{{AFX_MSG(CCrystalTextBuffer)
308         //}}AFX_MSG
309
310         DECLARE_MESSAGE_MAP ()
311 };
312
313 /////////////////////////////////////////////////////////////////////////////
314
315 //{{AFX_INSERT_LOCATION}}
316 // Microsoft Developer Studio will insert additional declarations immediately before the previous line.
317
318
319 #endif //__GHOSTTEXTBUFFER_H__