OSDN Git Service

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