OSDN Git Service

Fix 64-bit typecast warning
[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
7 #ifndef __GHOSTTEXTBUFFER_H__
8 #define __GHOSTTEXTBUFFER_H__
9
10
11 #include "ccrystaltextbuffer.h"
12
13
14 /////////////////////////////////////////////////////////////////////////////
15
16 /** 
17 We use the current ccrystalEditor flags 
18
19 This flag must be cleared and set in GhostTextBuffer.cpp 
20 and MergeDoc.cpp (Rescan) only.
21
22 GetLineColors (in MergeEditView) reads it to choose the line color.
23 */
24
25 enum GHOST_LINEFLAGS
26 {
27         LF_GHOST = 0x00400000L,
28 };
29
30
31
32
33 /////////////////////////////////////////////////////////////////////////////
34 // CCrystalTextBuffer command target
35
36 /**
37 Features offered with this class : 
38 <ul>
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 
43 </ul>
44 */
45 class EDITPADC_CLASS CGhostTextBuffer : public CCrystalTextBuffer
46 {
47 public:
48         DECLARE_DYNCREATE (CGhostTextBuffer)
49
50 protected :
51 #pragma pack(push, 1)
52         //  Nested class declarations
53         struct SLineInfo
54         {
55                 TCHAR *m_pcLine;
56                 int m_nLength, m_nMax;
57                 int m_nEolChars; // # of eolchars
58                 DWORD m_dwFlags;
59                 DWORD m_dwRevisionNumber;
60
61                 int FullLength() const { return m_nLength+m_nEolChars; }
62                 int Length() const { return m_nLength; }
63
64                 SLineInfo ()
65                 {
66                         memset (this, 0, sizeof (SLineInfo));
67                 };
68         };
69
70         enum
71         {
72                 UNDO_INSERT = 0x0001,
73                 UNDO_BEGINGROUP = 0x0100
74         };
75
76         /** 
77         Support For Descriptions On Undo/Redo Actions
78
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)
81
82         This flags are parameters of AddUndoRecord ; so AddUndoRecord
83         is not the virtual version of CCrystalTextBuffer::AddUndoRecord
84
85         The text is duplicated (already in CCrystalTextBuffer::SUndoRecord),
86         and it is not useful. If someone finds a clean way to correct this...
87         */
88         struct SUndoRecord
89         {
90                 DWORD m_dwFlags;
91
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 !
97
98                 CPoint m_ptStartPos, m_ptEndPos;  // Block of text participating
99                 int m_ptStartPos_nGhost, m_ptEndPos_nGhost;
100
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))
104
105                 CPoint m_redo_ptStartPos, m_redo_ptEndPos;  // Block of text participating
106                 int    m_redo_ptStartPos_nGhost, m_redo_ptEndPos_nGhost;
107
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;
115
116 private :
117                 // TCHAR   *m_pcText;
118                 // Since in most cases we have 1 character here,
119                 // we should invent a better way. Note: 2 * sizeof(WORD) <= sizeof(TCHAR*)
120                 //
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.
124                 //
125
126                 union
127                 {
128                         TCHAR *m_pszText;     // For cases when we have > 1 character strings
129
130                         TCHAR m_szText[2];    // For single-character strings
131
132                 };
133
134 public :
135                 SUndoRecord () // default constructor
136                 {
137                         memset (this, 0, sizeof (SUndoRecord));
138                 }
139                 SUndoRecord (const SUndoRecord & src) // copy constructor
140                 {
141                         memset (this, 0, sizeof (SUndoRecord));
142                         (*this)=src;
143                 }
144                 SUndoRecord & operator=(const SUndoRecord & src) // copy assignment
145                 {
146                         m_dwFlags = src.m_dwFlags;
147                         m_ptStartPos = src.m_ptStartPos;
148                         m_ptStartPos_nGhost = src.m_ptStartPos_nGhost;
149                         m_ptEndPos = src.m_ptEndPos;
150                         m_ptEndPos_nGhost = src.m_ptEndPos_nGhost;
151                         m_nAction = src.m_nAction;
152                         m_redo_ptStartPos = src.m_redo_ptStartPos;
153                         m_redo_ptStartPos_nGhost = src.m_redo_ptStartPos_nGhost;
154                         m_redo_ptEndPos = src.m_redo_ptEndPos;
155                         m_redo_ptEndPos_nGhost = src.m_redo_ptEndPos_nGhost;
156                         m_nRealLinesCreated = src.m_nRealLinesCreated;
157                         m_nRealLinesInDeletedBlock = src.m_nRealLinesInDeletedBlock;
158                         SetText(src.GetText());
159                         INT_PTR size = src.m_paSavedRevisonNumbers->GetSize();
160                         m_paSavedRevisonNumbers = new CDWordArray();
161                         m_paSavedRevisonNumbers->SetSize(size);
162                         INT_PTR i;
163                         for (i = 0; i < size; i++)
164                                 (*m_paSavedRevisonNumbers)[i] = (*src.m_paSavedRevisonNumbers)[i];
165                         return *this;
166                 }
167                 ~SUndoRecord () // destructor
168                 {
169                         FreeText();
170                         if (m_paSavedRevisonNumbers)
171                                 delete m_paSavedRevisonNumbers;
172                 }
173
174                 void SetText (LPCTSTR pszText);
175                 void FreeText ();
176
177                 LPCTSTR GetText () const
178                 {
179                         // see the m_szText/m_pszText definition about the use of HIWORD
180                         if (HIWORD ((DWORD) m_pszText) != 0)
181                                 return m_pszText;
182                         return m_szText;
183                 };
184         };
185
186 #pragma pack(pop)
187
188 protected:
189         /** 
190         We need another array with our richer structure.
191
192         We share the positions with the CCrystalTextBuffer object. 
193         We share m_bUndoGroup, its utility is to check we opened the UndoBeginGroup.
194         We share m_nUndoBufSize which is the max buffer size.
195         */
196         CArray < SUndoRecord, SUndoRecord & >m_aUndoBuf;
197         /** 
198         This one must be duplicated because the flag UNDO_BEGINGROUP needs to be set in both 
199         CGhostTextBuffer::m_aUndoBuf and CCrystalTextBuffer::m_aUndoBuf CArrays 
200         */
201         BOOL m_bUndoBeginGroup;
202
203         // [JRT] Support For Descriptions On Undo/Redo Actions
204         virtual void AddUndoRecord (BOOL bInsert, const CPoint & ptStartPos, const CPoint & ptEndPos,
205                               LPCTSTR pszText, int nRealLinesChanged, int nActionType = CE_ACTION_UNKNOWN, CDWordArray *paSavedRevisonNumbers = NULL);
206
207 private:
208         // A RealityBlock is a block of lines with no ghost lines
209         struct RealityBlock { int nStartReal; int nStartApparent; int nCount; };
210         // The array of reality blocks is kept in order
211         CArray < RealityBlock, RealityBlock& > m_RealityBlocks;
212
213
214
215         // Operations
216 private:
217         BOOL InternalInsertGhostLine (CCrystalTextView * pSource, int nLine);
218         BOOL InternalDeleteGhostLine (CCrystalTextView * pSource, int nLine, int nCount);
219 public :
220         // Construction/destruction code
221         CGhostTextBuffer ();
222         virtual BOOL InitNew (int nCrlfStyle = CRLF_STYLE_DOS);
223
224         /** 
225         This should work in base code as ghost lines are real empty lines
226         but maybe it doesn't (if there is an assert to check there is an EOL,
227         or if it adds the default EOL)
228         */
229         virtual void GetTextWithoutEmptys (int nStartLine, int nStartChar, int nEndLine, int nEndChar, CString &text, int nCrlfStyle =CRLF_STYLE_AUTOMATIC );
230
231
232         // Text modification functions
233         virtual BOOL InsertText (CCrystalTextView * pSource, int nLine, int nPos, LPCTSTR pszText, int &nEndLine, int &nEndChar, int nAction = CE_ACTION_UNKNOWN, BOOL bHistory =TRUE);
234         virtual BOOL DeleteText (CCrystalTextView * pSource, int nStartLine, int nStartPos, int nEndLine, int nEndPos, int nAction = CE_ACTION_UNKNOWN, BOOL bHistory =TRUE);
235         BOOL InsertGhostLine (CCrystalTextView * pSource, int nLine);
236
237         // Undo/Redo
238         virtual BOOL Undo (CCrystalTextView * pSource, CPoint & ptCursorPos);
239         virtual BOOL Redo (CCrystalTextView * pSource, CPoint & ptCursorPos);
240
241         // Undo grouping
242         virtual void BeginUndoGroup (BOOL bMergeWithPrevious = FALSE);
243         virtual void FlushUndoGroup (CCrystalTextView * pSource);
244
245 public:
246         /** 
247         Code for mapping between file line numbers (real line numbers)
248         and screen line numbers (apparent line numbers).
249
250         This is needed to handle ghost lines (ones with no text or EOL chars)
251         which WinMerge uses for left-only or right-only lines.
252         */
253         int ApparentLastRealLine() const;
254         int ComputeRealLine(int nApparentLine) const;
255         int ComputeApparentLine(int nRealLine) const;
256         /** richer position information   yApparent = apparent(yReal) - yGhost */
257         int ComputeRealLineAndGhostAdjustment(int nApparentLine, int& decToReal) const;
258         /** richer position information   yApparent = apparent(yReal) - yGhost */
259         int ComputeApparentLine(int nRealLine, int decToReal) const;
260
261         /** for loading file */
262         void FinishLoading();
263         /** for saving file */ 
264         void RemoveAllGhostLines();
265
266
267 private:
268         void RecomputeRealityMapping();
269         /** 
270         Code to set EOL, if the status ghost/real of the line changes 
271
272         We should call a CCrystalTextBuffer function to add the correct EOL
273         (if CCrystalTextBuffer keeps the default EOL for the file)
274         */
275         void RecomputeEOL(CCrystalTextView * pSource, int nStartLine, int nEndLine);
276         /** For debugging purpose */
277         void checkFlagsFromReality(BOOL bFlag) const;
278
279 protected:
280         virtual void OnNotifyLineHasBeenEdited(int nLine);
281
282
283 protected:
284         // Overrides
285         // ClassWizard generated virtual function overrides
286         //{{AFX_VIRTUAL(CCrystalTextBuffer)
287         //}}AFX_VIRTUAL
288
289         // Generated message map functions
290         //{{AFX_MSG(CCrystalTextBuffer)
291         //}}AFX_MSG
292
293         DECLARE_MESSAGE_MAP ()
294 };
295
296 /////////////////////////////////////////////////////////////////////////////
297
298 //{{AFX_INSERT_LOCATION}}
299 // Microsoft Developer Studio will insert additional declarations immediately before the previous line.
300
301
302 #endif //__GHOSTTEXTBUFFER_H__