1 ////////////////////////////////////////////////////////////////////////////
2 // File: GhostTextView.h
4 // Created: 31-Jul-2003
6 /////////////////////////////////////////////////////////////////////////////
7 // WinMerge: an interactive diff/merge utility
8 // Copyright (C) 1997-2000 Thingamahoochie Software
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /////////////////////////////////////////////////////////////////////////////
29 #include "GhostTextView.h"
30 #include "GhostTextBuffer.h"
35 static char THIS_FILE[] = __FILE__;
39 IMPLEMENT_DYNCREATE (CGhostTextView, CCrystalEditViewEx)
42 * @brief Constructor, initializes members.
44 CGhostTextView::CGhostTextView()
45 : m_pGhostTextBuffer(NULL)
50 ReAttachToBuffer (CCrystalTextBuffer * pBuf /*= NULL*/ )
54 pBuf = LocateTextBuffer ();
57 m_pGhostTextBuffer = dynamic_cast<CGhostTextBuffer*> (pBuf);
58 CCrystalEditViewEx::ReAttachToBuffer(pBuf);
62 AttachToBuffer (CCrystalTextBuffer * pBuf /*= NULL*/ )
66 pBuf = LocateTextBuffer ();
69 m_pGhostTextBuffer = dynamic_cast<CGhostTextBuffer*> (pBuf);
70 CCrystalEditViewEx::AttachToBuffer(pBuf);
76 if (m_pGhostTextBuffer != NULL)
77 m_pGhostTextBuffer = NULL;
78 CCrystalEditViewEx::DetachFromBuffer();
81 void CGhostTextView::popPosition(SCursorPushed Ssrc, CPoint & pt)
84 pt.y = m_pGhostTextBuffer->ComputeApparentLine(Ssrc.y, Ssrc.nToFirstReal);
85 // if the cursor was in a trailing ghost line, and this disappeared,
86 // got at the end of the last line
87 if (pt.y >= GetLineCount())
89 pt.y = GetLineCount()-1;
90 pt.x = GetLineLength(pt.y);
94 void CGhostTextView::pushPosition(SCursorPushed & Sdest, CPoint pt)
97 Sdest.y = m_pGhostTextBuffer->ComputeRealLineAndGhostAdjustment(pt.y, Sdest.nToFirstReal);
100 void CGhostTextView::PopCursors ()
102 CPoint ptCursorLast = m_ptCursorLast;
103 popPosition(m_ptCursorPosPushed, ptCursorLast);
105 ASSERT_VALIDTEXTPOS (ptCursorLast);
106 SetCursorPos (ptCursorLast);
108 popPosition(m_ptSelStartPushed, m_ptSelStart);
109 ASSERT_VALIDTEXTPOS (m_ptSelStart);
110 popPosition(m_ptSelEndPushed, m_ptSelEnd);
111 ASSERT_VALIDTEXTPOS (m_ptSelEnd);
112 popPosition(m_ptAnchorPushed, m_ptAnchor);
113 ASSERT_VALIDTEXTPOS (m_ptAnchor);
115 // here is what we did before, maybe we have to do it, but test with pushed positions
116 // SetSelection (ptCursorLast, ptCursorLast);
117 // SetAnchor (ptCursorLast);
119 if (m_bDraggingText == TRUE)
121 popPosition(m_ptDraggedTextBeginPushed, m_ptDraggedTextBegin);
122 ASSERT_VALIDTEXTPOS(m_ptDraggedTextBegin);
123 popPosition(m_ptDraggedTextEndPushed, m_ptDraggedTextEnd);
124 ASSERT_VALIDTEXTPOS(m_ptDraggedTextEnd);
126 if (m_bDropPosVisible == TRUE)
128 popPosition(m_ptSavedCaretPosPushed, m_ptSavedCaretPos);
129 ASSERT_VALIDTEXTPOS(m_ptSavedCaretPos);
131 if (m_bSelectionPushed == TRUE)
133 popPosition(m_ptSavedSelStartPushed, m_ptSavedSelStart);
134 ASSERT_VALIDTEXTPOS(m_ptSavedSelStart);
135 popPosition(m_ptSavedSelEndPushed, m_ptSavedSelEnd);
136 ASSERT_VALIDTEXTPOS(m_ptSavedSelEnd);
140 if (m_ptLastChangePushed.y == 0 && m_ptLastChangePushed.nToFirstReal > 0)
141 ptLastChange = CPoint(-1,-1);
144 popPosition(m_ptLastChangePushed, ptLastChange);
145 ASSERT_VALIDTEXTPOS(ptLastChange);
147 m_pGhostTextBuffer->RestoreLastChangePos(ptLastChange);
149 // restore the scrolling position
151 popPosition(m_nTopLinePushed, temp);
152 ASSERT_VALIDTEXTPOS(temp);
153 ScrollToLine(temp.y);
156 void CGhostTextView::PushCursors ()
158 pushPosition(m_ptCursorPosPushed, m_ptCursorPos);
159 pushPosition(m_ptSelStartPushed, m_ptSelStart);
160 pushPosition(m_ptSelEndPushed, m_ptSelEnd);
161 pushPosition(m_ptAnchorPushed, m_ptAnchor);
162 if (m_bDraggingText == TRUE)
164 pushPosition(m_ptDraggedTextBeginPushed, m_ptDraggedTextBegin);
165 pushPosition(m_ptDraggedTextEndPushed, m_ptDraggedTextEnd);
167 if (m_bDropPosVisible == TRUE)
169 pushPosition(m_ptSavedCaretPosPushed, m_ptSavedCaretPos);
171 if (m_bSelectionPushed == TRUE)
173 pushPosition(m_ptSavedSelStartPushed, m_ptSavedSelStart);
174 pushPosition(m_ptSavedSelEndPushed, m_ptSavedSelEnd);
177 pushPosition(m_ptLastChangePushed, m_pGhostTextBuffer->GetLastChangePos());
179 // and top line positions
180 pushPosition(m_nTopLinePushed, CPoint(0, m_nTopLine));
186 int CGhostTextView::ComputeRealLine (int nApparentLine) const
188 if (!m_pGhostTextBuffer)
190 return m_pGhostTextBuffer->ComputeRealLine(nApparentLine);
193 int CGhostTextView::ComputeApparentLine (int nRealLine) const
195 return m_pGhostTextBuffer->ComputeApparentLine(nRealLine);
198 void CGhostTextView::GetTextWithoutEmptys (int nStartLine, int nStartChar, int nEndLine, int nEndChar, CString &text, int nCrlfStyle /*=CRLF_STYLE_AUTOMATIC*/ )
200 if (m_pGhostTextBuffer != NULL)
201 m_pGhostTextBuffer->GetTextWithoutEmptys (nStartLine, nStartChar, nEndLine, nEndChar, text, nCrlfStyle);
206 HGLOBAL CGhostTextView::PrepareDragData ()
209 if (m_ptDrawSelStart == m_ptDrawSelEnd)
213 GetTextWithoutEmptys (m_ptDrawSelStart.y, m_ptDrawSelStart.x, m_ptDrawSelEnd.y, m_ptDrawSelEnd.x, text);
214 HGLOBAL hData =::GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, (_tcslen (text)+1)*sizeof(TCHAR));
218 LPTSTR pszData = (LPTSTR)::GlobalLock (hData);
219 _tcscpy (pszData, text.GetBuffer (0));
220 text.ReleaseBuffer ();
221 ::GlobalUnlock (hData);
223 m_ptDraggedTextBegin = m_ptDrawSelStart;
224 m_ptDraggedTextEnd = m_ptDrawSelEnd;
229 * @brief Draw selection margin.
230 * @param [in] pdc Pointer to draw context.
231 * @param [in] rect The rectangle to draw.
232 * @param [in] nLineIndex Index of line in view.
233 * @param [in] nLineNumber Line number to display. if -1, it's not displayed.
235 void CGhostTextView::DrawMargin (CDC * pdc, const CRect & rect, int nLineIndex, int nLineNumber)
238 if (nLineIndex < 0 || GetLineFlags(nLineIndex) & LF_GHOST)
239 nRealLineNumber = -1;
241 nRealLineNumber = ComputeRealLine(nLineIndex) + 1;
242 CCrystalTextView::DrawMargin(pdc, rect, nLineIndex, nRealLineNumber);