• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "../../include/fxedit/fxet_stub.h"
8 #include "../../include/fxedit/fxet_edit.h"
9 
10 #define FX_EDIT_UNDO_MAXITEM				10000
11 
12 /* ---------------------------- CFX_Edit_Iterator ---------------------------- */
13 
CFX_Edit_Iterator(CFX_Edit * pEdit,IPDF_VariableText_Iterator * pVTIterator)14 CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit * pEdit,IPDF_VariableText_Iterator * pVTIterator) :
15 	m_pEdit(pEdit),
16 	m_pVTIterator(pVTIterator)
17 {
18 }
19 
~CFX_Edit_Iterator()20 CFX_Edit_Iterator::~CFX_Edit_Iterator()
21 {
22 }
23 
NextWord()24 FX_BOOL	CFX_Edit_Iterator::NextWord()
25 {
26 	ASSERT(m_pVTIterator != NULL);
27 
28 	return m_pVTIterator->NextWord();
29 }
30 
NextLine()31 FX_BOOL CFX_Edit_Iterator::NextLine()
32 {
33 	ASSERT(m_pVTIterator != NULL);
34 
35 	return m_pVTIterator->NextLine();
36 }
37 
NextSection()38 FX_BOOL CFX_Edit_Iterator::NextSection()
39 {
40 	ASSERT(m_pVTIterator != NULL);
41 
42 	return m_pVTIterator->NextSection();
43 }
44 
PrevWord()45 FX_BOOL	CFX_Edit_Iterator::PrevWord()
46 {
47 	ASSERT(m_pVTIterator != NULL);
48 
49 	return m_pVTIterator->PrevWord();
50 }
51 
PrevLine()52 FX_BOOL	CFX_Edit_Iterator::PrevLine()
53 {
54 	ASSERT(m_pVTIterator != NULL);
55 
56 	return m_pVTIterator->PrevLine();
57 }
58 
PrevSection()59 FX_BOOL	CFX_Edit_Iterator::PrevSection()
60 {
61 	ASSERT(m_pVTIterator != NULL);
62 
63 	return m_pVTIterator->PrevSection();
64 }
65 
GetWord(CPVT_Word & word) const66 FX_BOOL CFX_Edit_Iterator::GetWord(CPVT_Word & word) const
67 {
68 	ASSERT(m_pEdit != NULL);
69 	ASSERT(m_pVTIterator != NULL);
70 
71 	if (m_pVTIterator->GetWord(word))
72 	{
73 		word.ptWord = m_pEdit->VTToEdit(word.ptWord);
74 		return TRUE;
75 	}
76 
77 	return FALSE;
78 }
79 
GetLine(CPVT_Line & line) const80 FX_BOOL CFX_Edit_Iterator::GetLine(CPVT_Line & line) const
81 {
82 	ASSERT(m_pEdit != NULL);
83 	ASSERT(m_pVTIterator != NULL);
84 
85 	if (m_pVTIterator->GetLine(line))
86 	{
87 		line.ptLine = m_pEdit->VTToEdit(line.ptLine);
88 		return TRUE;
89 	}
90 
91 	return FALSE;
92 }
93 
GetSection(CPVT_Section & section) const94 FX_BOOL CFX_Edit_Iterator::GetSection(CPVT_Section & section) const
95 {
96 	ASSERT(m_pEdit != NULL);
97 	ASSERT(m_pVTIterator != NULL);
98 
99 	if (m_pVTIterator->GetSection(section))
100 	{
101 		section.rcSection = m_pEdit->VTToEdit(section.rcSection);
102 		return TRUE;
103 	}
104 
105 	return FALSE;
106 }
107 
SetAt(FX_INT32 nWordIndex)108 void CFX_Edit_Iterator::SetAt(FX_INT32 nWordIndex)
109 {
110 	ASSERT(m_pVTIterator != NULL);
111 
112 	m_pVTIterator->SetAt(nWordIndex);
113 }
114 
SetAt(const CPVT_WordPlace & place)115 void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace & place)
116 {
117 	ASSERT(m_pVTIterator != NULL);
118 
119 	m_pVTIterator->SetAt(place);
120 }
121 
GetAt() const122 const CPVT_WordPlace & CFX_Edit_Iterator::GetAt() const
123 {
124 	ASSERT(m_pVTIterator != NULL);
125 
126 	return m_pVTIterator->GetAt();
127 }
128 
GetEdit() const129 IFX_Edit* CFX_Edit_Iterator::GetEdit() const
130 {
131 	return m_pEdit;
132 }
133 
134 /* --------------------------- CFX_Edit_Provider ------------------------------- */
135 
CFX_Edit_Provider(IFX_Edit_FontMap * pFontMap)136 CFX_Edit_Provider::CFX_Edit_Provider(IFX_Edit_FontMap * pFontMap) : m_pFontMap(pFontMap)
137 {
138 	ASSERT(m_pFontMap != NULL);
139 }
140 
~CFX_Edit_Provider()141 CFX_Edit_Provider::~CFX_Edit_Provider()
142 {
143 }
144 
GetFontMap()145 IFX_Edit_FontMap* CFX_Edit_Provider::GetFontMap()
146 {
147 	return m_pFontMap;
148 }
149 
GetCharWidth(FX_INT32 nFontIndex,FX_WORD word,FX_INT32 nWordStyle)150 FX_INT32 CFX_Edit_Provider::GetCharWidth(FX_INT32 nFontIndex, FX_WORD word, FX_INT32 nWordStyle)
151 {
152 	if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
153 	{
154 		FX_DWORD charcode = word;
155 
156 		if (pPDFFont->IsUnicodeCompatible())
157 			charcode = pPDFFont->CharCodeFromUnicode(word);
158 		else
159 			charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);
160 
161 		if (charcode != -1)
162 			return pPDFFont->GetCharWidthF(charcode);
163 	}
164 
165 	return 0;
166 }
167 
GetTypeAscent(FX_INT32 nFontIndex)168 FX_INT32 CFX_Edit_Provider::GetTypeAscent(FX_INT32 nFontIndex)
169 {
170 	if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
171 		return pPDFFont->GetTypeAscent();
172 
173 	return 0;
174 }
175 
GetTypeDescent(FX_INT32 nFontIndex)176 FX_INT32 CFX_Edit_Provider::GetTypeDescent(FX_INT32 nFontIndex)
177 {
178 	if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
179 		return pPDFFont->GetTypeDescent();
180 
181 	return 0;
182 }
183 
GetWordFontIndex(FX_WORD word,FX_INT32 charset,FX_INT32 nFontIndex)184 FX_INT32 CFX_Edit_Provider::GetWordFontIndex(FX_WORD word, FX_INT32 charset, FX_INT32 nFontIndex)
185 {
186 	return m_pFontMap->GetWordFontIndex(word,charset,nFontIndex);
187 }
188 
GetDefaultFontIndex()189 FX_INT32 CFX_Edit_Provider::GetDefaultFontIndex()
190 {
191 	return 0;
192 }
193 
IsLatinWord(FX_WORD word)194 FX_BOOL	CFX_Edit_Provider::IsLatinWord(FX_WORD word)
195 {
196 	return FX_EDIT_ISLATINWORD(word);
197 }
198 
199 /* --------------------------------- CFX_Edit_Refresh --------------------------------- */
200 
CFX_Edit_Refresh()201 CFX_Edit_Refresh::CFX_Edit_Refresh()
202 {
203 }
204 
~CFX_Edit_Refresh()205 CFX_Edit_Refresh::~CFX_Edit_Refresh()
206 {
207 }
208 
BeginRefresh()209 void CFX_Edit_Refresh::BeginRefresh()
210 {
211 	m_RefreshRects.Empty();
212 	m_OldLineRects = m_NewLineRects;
213 }
214 
Push(const CPVT_WordRange & linerange,const CPDF_Rect & rect)215 void CFX_Edit_Refresh::Push(const CPVT_WordRange & linerange,const CPDF_Rect & rect)
216 {
217 	m_NewLineRects.Add(linerange,rect);
218 }
219 
NoAnalyse()220 void CFX_Edit_Refresh::NoAnalyse()
221 {
222 	{
223 		for (FX_INT32 i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
224 			if (CFX_Edit_LineRect * pOldRect = m_OldLineRects.GetAt(i))
225 				m_RefreshRects.Add(pOldRect->m_rcLine);
226 	}
227 
228 	{
229 		for (FX_INT32 i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
230 			if (CFX_Edit_LineRect * pNewRect = m_NewLineRects.GetAt(i))
231 				m_RefreshRects.Add(pNewRect->m_rcLine);
232 	}
233 }
234 
Analyse(FX_INT32 nAlignment)235 void CFX_Edit_Refresh::Analyse(FX_INT32 nAlignment)
236 {
237 	FX_BOOL bLineTopChanged = FALSE;
238 	CPDF_Rect rcResult;
239 	FX_FLOAT fWidthDiff;
240 
241 	FX_INT32 szMax = FX_EDIT_MAX(m_OldLineRects.GetSize(),m_NewLineRects.GetSize());
242 	FX_INT32 i = 0;
243 
244 	while (i < szMax)
245 	{
246 		CFX_Edit_LineRect * pOldRect = m_OldLineRects.GetAt(i);
247 		CFX_Edit_LineRect * pNewRect = m_NewLineRects.GetAt(i);
248 
249 		if (pOldRect)
250 		{
251 			if (pNewRect)
252 			{
253 				if (bLineTopChanged)
254 				{
255 					rcResult = pOldRect->m_rcLine;
256 					rcResult.Union(pNewRect->m_rcLine);
257 					m_RefreshRects.Add(rcResult);
258 				}
259 				else
260 				{
261 					if (*pNewRect != *pOldRect)
262 					{
263 						if (!pNewRect->IsSameTop(*pOldRect) || !pNewRect->IsSameHeight(*pOldRect))
264 						{
265 							bLineTopChanged = TRUE;
266 							continue;
267 						}
268 
269 						if (nAlignment == 0)
270 						{
271 							if (pNewRect->m_wrLine.BeginPos != pOldRect->m_wrLine.BeginPos)
272 							{
273 								rcResult = pOldRect->m_rcLine;
274 								rcResult.Union(pNewRect->m_rcLine);
275 								m_RefreshRects.Add(rcResult);
276 							}
277 							else
278 							{
279 								if (!pNewRect->IsSameLeft(*pOldRect))
280 								{
281 									rcResult = pOldRect->m_rcLine;
282 									rcResult.Union(pNewRect->m_rcLine);
283 								}
284 								else
285 								{
286 									fWidthDiff = pNewRect->m_rcLine.Width() - pOldRect->m_rcLine.Width();
287 									rcResult = pNewRect->m_rcLine;
288 									if (fWidthDiff > 0.0f)
289 										rcResult.left = rcResult.right - fWidthDiff;
290 									else
291 									{
292 										rcResult.left = rcResult.right;
293 										rcResult.right += (-fWidthDiff);
294 									}
295 								}
296 								m_RefreshRects.Add(rcResult);
297 							}
298 						}
299 						else
300 						{
301 							rcResult = pOldRect->m_rcLine;
302 							rcResult.Union(pNewRect->m_rcLine);
303 							m_RefreshRects.Add(rcResult);
304 						}
305 					}
306 					else
307 					{
308 						//don't need to do anything
309 					}
310 				}
311 			}
312 			else
313 			{
314 				m_RefreshRects.Add(pOldRect->m_rcLine);
315 			}
316 		}
317 		else
318 		{
319 			if (pNewRect)
320 			{
321 				m_RefreshRects.Add(pNewRect->m_rcLine);
322 			}
323 			else
324 			{
325 				//error
326 			}
327 		}
328 		i++;
329 	}
330 }
331 
AddRefresh(const CPDF_Rect & rect)332 void CFX_Edit_Refresh::AddRefresh(const CPDF_Rect & rect)
333 {
334 	m_RefreshRects.Add(rect);
335 }
336 
GetRefreshRects() const337 const CFX_Edit_RectArray * CFX_Edit_Refresh::GetRefreshRects() const
338 {
339 	return &m_RefreshRects;
340 }
341 
EndRefresh()342 void CFX_Edit_Refresh::EndRefresh()
343 {
344 	m_RefreshRects.Empty();
345 }
346 
347 /* ------------------------------------- CFX_Edit_Undo ------------------------------------- */
348 
CFX_Edit_Undo(FX_INT32 nBufsize)349 CFX_Edit_Undo::CFX_Edit_Undo(FX_INT32 nBufsize) : m_nCurUndoPos(0),
350 	m_nBufSize(nBufsize),
351 	m_bModified(FALSE),
352 	m_bVirgin(TRUE),
353 	m_bWorking(FALSE)
354 {
355 }
356 
~CFX_Edit_Undo()357 CFX_Edit_Undo::~CFX_Edit_Undo()
358 {
359 	Reset();
360 }
361 
CanUndo() const362 FX_BOOL CFX_Edit_Undo::CanUndo() const
363 {
364 	return m_nCurUndoPos > 0;
365 }
366 
Undo()367 void CFX_Edit_Undo::Undo()
368 {
369 	m_bWorking = TRUE;
370 
371 	if (m_nCurUndoPos > 0)
372 	{
373 		IFX_Edit_UndoItem * pItem = m_UndoItemStack.GetAt(m_nCurUndoPos-1);
374 		ASSERT(pItem != NULL);
375 
376 		pItem->Undo();
377 
378 		m_nCurUndoPos--;
379 		m_bModified = (m_nCurUndoPos != 0);
380 	}
381 
382 	m_bWorking = FALSE;
383 }
384 
CanRedo() const385 FX_BOOL	CFX_Edit_Undo::CanRedo() const
386 {
387 	return m_nCurUndoPos < m_UndoItemStack.GetSize();
388 }
389 
Redo()390 void CFX_Edit_Undo::Redo()
391 {
392 	m_bWorking = TRUE;
393 
394 	FX_INT32 nStackSize = m_UndoItemStack.GetSize();
395 
396 	if (m_nCurUndoPos < nStackSize)
397 	{
398 		IFX_Edit_UndoItem * pItem = m_UndoItemStack.GetAt(m_nCurUndoPos);
399 		ASSERT(pItem != NULL);
400 
401 		pItem->Redo();
402 
403 		m_nCurUndoPos++;
404 		m_bModified = (m_nCurUndoPos != 0);
405 	}
406 
407 	m_bWorking = FALSE;
408 }
409 
IsWorking() const410 FX_BOOL	CFX_Edit_Undo::IsWorking() const
411 {
412 	return m_bWorking;
413 }
414 
AddItem(IFX_Edit_UndoItem * pItem)415 void CFX_Edit_Undo::AddItem(IFX_Edit_UndoItem* pItem)
416 {
417 	ASSERT(!m_bWorking);
418 	ASSERT(pItem != NULL);
419 	ASSERT(m_nBufSize > 1);
420 
421 	if (m_nCurUndoPos < m_UndoItemStack.GetSize())
422 		RemoveTails();
423 
424 	if (m_UndoItemStack.GetSize() >= m_nBufSize)
425 	{
426 		RemoveHeads();
427 		m_bVirgin = FALSE;
428 	}
429 
430 	m_UndoItemStack.Add(pItem);
431 	m_nCurUndoPos = m_UndoItemStack.GetSize();
432 
433 	m_bModified = (m_nCurUndoPos != 0);
434 }
435 
IsModified() const436 FX_BOOL	CFX_Edit_Undo::IsModified() const
437 {
438 	if (m_bVirgin)
439 		return m_bModified;
440 	else
441 		return TRUE;
442 }
443 
GetItem(FX_INT32 nIndex)444 IFX_Edit_UndoItem* CFX_Edit_Undo::GetItem(FX_INT32 nIndex)
445 {
446 	if (nIndex>=0 && nIndex < m_UndoItemStack.GetSize())
447 		return m_UndoItemStack.GetAt(nIndex);
448 
449 	return NULL;
450 }
451 
RemoveHeads()452 void CFX_Edit_Undo::RemoveHeads()
453 {
454 	ASSERT(m_UndoItemStack.GetSize() > 1);
455 
456 	IFX_Edit_UndoItem* pItem = m_UndoItemStack.GetAt(0);
457 	ASSERT(pItem != NULL);
458 
459 	pItem->Release();
460 	m_UndoItemStack.RemoveAt(0);
461 }
462 
RemoveTails()463 void CFX_Edit_Undo::RemoveTails()
464 {
465 	for (FX_INT32 i = m_UndoItemStack.GetSize()-1; i >= m_nCurUndoPos; i--)
466 	{
467 		IFX_Edit_UndoItem* pItem = m_UndoItemStack.GetAt(i);
468 		ASSERT(pItem != NULL);
469 
470 		pItem->Release();
471 		m_UndoItemStack.RemoveAt(i);
472 	}
473 }
474 
Reset()475 void CFX_Edit_Undo::Reset()
476 {
477 	for (FX_INT32 i=0, sz=m_UndoItemStack.GetSize(); i < sz; i++)
478 	{
479 		IFX_Edit_UndoItem * pItem = m_UndoItemStack.GetAt(i);
480 		ASSERT(pItem != NULL);
481 
482 		pItem->Release();
483 	}
484 	m_nCurUndoPos = 0;
485 	m_UndoItemStack.RemoveAll();
486 }
487 
488 /* -------------------------------- CFX_Edit_GroupUndoItem -------------------------------- */
489 
CFX_Edit_GroupUndoItem(const CFX_WideString & sTitle)490 CFX_Edit_GroupUndoItem::CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle) : m_sTitle(sTitle)
491 {
492 }
493 
~CFX_Edit_GroupUndoItem()494 CFX_Edit_GroupUndoItem::~CFX_Edit_GroupUndoItem()
495 {
496 	for (int i=0,sz=m_Items.GetSize(); i<sz; i++)
497 	{
498 		CFX_Edit_UndoItem* pUndoItem = m_Items[i];
499 		ASSERT(pUndoItem != NULL);
500 
501 		pUndoItem->Release();
502 	}
503 
504 	m_Items.RemoveAll();
505 }
506 
AddUndoItem(CFX_Edit_UndoItem * pUndoItem)507 void CFX_Edit_GroupUndoItem::AddUndoItem(CFX_Edit_UndoItem* pUndoItem)
508 {
509 	ASSERT(pUndoItem != NULL);
510 
511 	pUndoItem->SetFirst(FALSE);
512 	pUndoItem->SetLast(FALSE);
513 
514 	m_Items.Add(pUndoItem);
515 
516 	if (m_sTitle.IsEmpty())
517 		m_sTitle = pUndoItem->GetUndoTitle();
518 }
519 
UpdateItems()520 void CFX_Edit_GroupUndoItem::UpdateItems()
521 {
522 	if (m_Items.GetSize() > 0)
523 	{
524 		CFX_Edit_UndoItem* pFirstItem = m_Items[0];
525 		ASSERT(pFirstItem != NULL);
526 		pFirstItem->SetFirst(TRUE);
527 
528 		CFX_Edit_UndoItem* pLastItem = m_Items[m_Items.GetSize() - 1];
529 		ASSERT(pLastItem != NULL);
530 		pLastItem->SetLast(TRUE);
531 	}
532 }
533 
Undo()534 void CFX_Edit_GroupUndoItem::Undo()
535 {
536 	for (int i=m_Items.GetSize()-1; i>=0; i--)
537 	{
538 		CFX_Edit_UndoItem* pUndoItem = m_Items[i];
539 		ASSERT(pUndoItem != NULL);
540 
541 		pUndoItem->Undo();
542 	}
543 }
544 
Redo()545 void CFX_Edit_GroupUndoItem::Redo()
546 {
547 	for (int i=0,sz=m_Items.GetSize(); i<sz; i++)
548 	{
549 		CFX_Edit_UndoItem* pUndoItem = m_Items[i];
550 		ASSERT(pUndoItem != NULL);
551 
552 		pUndoItem->Redo();
553 	}
554 }
555 
GetUndoTitle()556 CFX_WideString CFX_Edit_GroupUndoItem::GetUndoTitle()
557 {
558 	return m_sTitle;
559 }
560 
Release()561 void CFX_Edit_GroupUndoItem::Release()
562 {
563 	delete this;
564 }
565 
566 /* ------------------------------------- CFX_Edit_UndoItem derived classes ------------------------------------- */
567 
CFXEU_InsertWord(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,FX_WORD word,FX_INT32 charset,const CPVT_WordProps * pWordProps)568 CFXEU_InsertWord::CFXEU_InsertWord(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
569 								 FX_WORD word, FX_INT32 charset, const CPVT_WordProps * pWordProps)
570 	: m_pEdit(pEdit), m_wpOld(wpOldPlace), m_wpNew(wpNewPlace), m_Word(word), m_nCharset(charset), m_WordProps()
571 {
572 	if (pWordProps)
573 		m_WordProps = *pWordProps;
574 }
575 
~CFXEU_InsertWord()576 CFXEU_InsertWord::~CFXEU_InsertWord()
577 {
578 }
579 
Redo()580 void CFXEU_InsertWord::Redo()
581 {
582 	if (m_pEdit)
583 	{
584 		m_pEdit->SelectNone();
585 		m_pEdit->SetCaret(m_wpOld);
586 		m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,TRUE);
587 	}
588 }
589 
Undo()590 void CFXEU_InsertWord::Undo()
591 {
592 	if (m_pEdit)
593 	{
594 		m_pEdit->SelectNone();
595 		m_pEdit->SetCaret(m_wpNew);
596 		m_pEdit->Backspace(FALSE,TRUE);
597 	}
598 }
599 
600 /* -------------------------------------------------------------------------- */
601 
CFXEU_InsertReturn(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)602 CFXEU_InsertReturn::CFXEU_InsertReturn(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
603 			 const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps) :
604 			m_pEdit(pEdit),
605 			m_wpOld(wpOldPlace),
606 			m_wpNew(wpNewPlace),
607 			m_SecProps(),
608 			m_WordProps()
609 {
610 	if (pSecProps)
611 		m_SecProps = *pSecProps;
612 	if (pWordProps)
613 		m_WordProps = *pWordProps;
614 }
615 
~CFXEU_InsertReturn()616 CFXEU_InsertReturn::~CFXEU_InsertReturn()
617 {
618 }
619 
Redo()620 void CFXEU_InsertReturn::Redo()
621 {
622 	if (m_pEdit)
623 	{
624 		m_pEdit->SelectNone();
625 		m_pEdit->SetCaret(m_wpOld);
626 		m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,TRUE);
627 	}
628 }
629 
Undo()630 void CFXEU_InsertReturn::Undo()
631 {
632 	if (m_pEdit)
633 	{
634 		m_pEdit->SelectNone();
635 		m_pEdit->SetCaret(m_wpNew);
636 		m_pEdit->Backspace(FALSE,TRUE);
637 	}
638 }
639 
640 /* -------------------------------------------------------------------------- */
641 //CFXEU_Backspace
642 
CFXEU_Backspace(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,FX_WORD word,FX_INT32 charset,const CPVT_SecProps & SecProps,const CPVT_WordProps & WordProps)643 CFXEU_Backspace::CFXEU_Backspace(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
644 							   FX_WORD word, FX_INT32 charset,
645 							   const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps) :
646 			m_pEdit(pEdit),
647 			m_wpOld(wpOldPlace),
648 			m_wpNew(wpNewPlace),
649 			m_Word(word),
650 			m_nCharset(charset),
651 			m_SecProps(SecProps),
652 			m_WordProps(WordProps)
653 {
654 }
655 
~CFXEU_Backspace()656 CFXEU_Backspace::~CFXEU_Backspace()
657 {
658 }
659 
Redo()660 void CFXEU_Backspace::Redo()
661 {
662 	if (m_pEdit)
663 	{
664 		m_pEdit->SelectNone();
665 		m_pEdit->SetCaret(m_wpOld);
666 		m_pEdit->Backspace(FALSE,TRUE);
667 	}
668 }
669 
Undo()670 void CFXEU_Backspace::Undo()
671 {
672 	if (m_pEdit)
673 	{
674 		m_pEdit->SelectNone();
675 		m_pEdit->SetCaret(m_wpNew);
676 		if (m_wpNew.SecCmp(m_wpOld) != 0)
677 		{
678 			m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,TRUE);
679 		}
680 		else
681 		{
682 			m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,TRUE);
683 		}
684 	}
685 }
686 
687 /* -------------------------------------------------------------------------- */
688 //CFXEU_Delete
689 
CFXEU_Delete(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,FX_WORD word,FX_INT32 charset,const CPVT_SecProps & SecProps,const CPVT_WordProps & WordProps,FX_BOOL bSecEnd)690 CFXEU_Delete::CFXEU_Delete(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
691 							   FX_WORD word, FX_INT32 charset,
692 							   const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps, FX_BOOL bSecEnd) :
693 			m_pEdit(pEdit),
694 			m_wpOld(wpOldPlace),
695 			m_wpNew(wpNewPlace),
696 			m_Word(word),
697 			m_nCharset(charset),
698 			m_SecProps(SecProps),
699 			m_WordProps(WordProps),
700 			m_bSecEnd(bSecEnd)
701 {
702 }
703 
~CFXEU_Delete()704 CFXEU_Delete::~CFXEU_Delete()
705 {
706 }
707 
Redo()708 void CFXEU_Delete::Redo()
709 {
710 	if (m_pEdit)
711 	{
712 		m_pEdit->SelectNone();
713 		m_pEdit->SetCaret(m_wpOld);
714 		m_pEdit->Delete(FALSE,TRUE);
715 	}
716 }
717 
Undo()718 void CFXEU_Delete::Undo()
719 {
720 	if (m_pEdit)
721 	{
722 		m_pEdit->SelectNone();
723 		m_pEdit->SetCaret(m_wpNew);
724 		if (m_bSecEnd)
725 		{
726 			m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,TRUE);
727 		}
728 		else
729 		{
730 			m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,TRUE);
731 		}
732 	}
733 }
734 
735 /* -------------------------------------------------------------------------- */
736 //CFXEU_Clear
737 
CFXEU_Clear(CFX_Edit * pEdit,const CPVT_WordRange & wrSel,const CFX_WideString & swText)738 CFXEU_Clear::CFXEU_Clear(CFX_Edit * pEdit,  const CPVT_WordRange & wrSel, const CFX_WideString & swText) :
739 			m_pEdit(pEdit),
740 			m_wrSel(wrSel),
741 			m_swText(swText)
742 {
743 }
744 
~CFXEU_Clear()745 CFXEU_Clear::~CFXEU_Clear()
746 {
747 }
748 
Redo()749 void CFXEU_Clear::Redo()
750 {
751 	if (m_pEdit)
752 	{
753 		m_pEdit->SelectNone();
754 		m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
755 		m_pEdit->Clear(FALSE,TRUE);
756 	}
757 }
758 
Undo()759 void CFXEU_Clear::Undo()
760 {
761 	if (m_pEdit)
762 	{
763 		m_pEdit->SelectNone();
764 		m_pEdit->SetCaret(m_wrSel.BeginPos);
765 		m_pEdit->InsertText(m_swText, DEFAULT_CHARSET, NULL,NULL,FALSE,TRUE);
766 		m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
767 	}
768 }
769 
770 /* -------------------------------------------------------------------------- */
771 //CFXEU_ClearRich
772 
CFXEU_ClearRich(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,const CPVT_WordRange & wrSel,FX_WORD word,FX_INT32 charset,const CPVT_SecProps & SecProps,const CPVT_WordProps & WordProps)773 CFXEU_ClearRich::CFXEU_ClearRich(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
774 							   const CPVT_WordRange & wrSel, FX_WORD word, FX_INT32 charset,
775 							   const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps) :
776 			m_pEdit(pEdit),
777 			m_wpOld(wpOldPlace),
778 			m_wpNew(wpNewPlace),
779 			m_wrSel(wrSel),
780 			m_Word(word),
781 			m_nCharset(charset),
782 			m_SecProps(SecProps),
783 			m_WordProps(WordProps)
784 {
785 }
786 
~CFXEU_ClearRich()787 CFXEU_ClearRich::~CFXEU_ClearRich()
788 {
789 }
790 
Redo()791 void CFXEU_ClearRich::Redo()
792 {
793 	if (m_pEdit && IsLast())
794 	{
795 		m_pEdit->SelectNone();
796 		m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
797 		m_pEdit->Clear(FALSE,TRUE);
798 	}
799 }
800 
Undo()801 void CFXEU_ClearRich::Undo()
802 {
803 	if (m_pEdit)
804 	{
805 		m_pEdit->SelectNone();
806 		m_pEdit->SetCaret(m_wpOld);
807 		if (m_wpNew.SecCmp(m_wpOld) != 0)
808 		{
809 			m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,FALSE);
810 		}
811 		else
812 		{
813 			m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,FALSE);
814 		}
815 
816 		if (IsFirst())
817 		{
818 			m_pEdit->PaintInsertText(m_wrSel.BeginPos,m_wrSel.EndPos);
819 			m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
820 		}
821 	}
822 }
823 /* -------------------------------------------------------------------------- */
824 //CFXEU_InsertText
825 
CFXEU_InsertText(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,const CFX_WideString & swText,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)826 CFXEU_InsertText::CFXEU_InsertText(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
827 							   const CFX_WideString & swText, FX_INT32 charset,
828 							   const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps) :
829 			m_pEdit(pEdit),
830 			m_wpOld(wpOldPlace),
831 			m_wpNew(wpNewPlace),
832 			m_swText(swText),
833 			m_nCharset(charset),
834 			m_SecProps(),
835 			m_WordProps()
836 {
837 	if (pSecProps)
838 		m_SecProps = *pSecProps;
839 	if (pWordProps)
840 		m_WordProps = *pWordProps;
841 }
842 
~CFXEU_InsertText()843 CFXEU_InsertText::~CFXEU_InsertText()
844 {
845 }
846 
Redo()847 void CFXEU_InsertText::Redo()
848 {
849 	if (m_pEdit && IsLast())
850 	{
851 		m_pEdit->SelectNone();
852 		m_pEdit->SetCaret(m_wpOld);
853 		m_pEdit->InsertText(m_swText, m_nCharset,&m_SecProps, &m_WordProps,FALSE,TRUE);
854 	}
855 }
856 
Undo()857 void CFXEU_InsertText::Undo()
858 {
859 	if (m_pEdit)
860 	{
861 		m_pEdit->SelectNone();
862 		m_pEdit->SetSel(m_wpOld,m_wpNew);
863 		m_pEdit->Clear(FALSE,TRUE);
864 	}
865 }
866 
867 /* -------------------------------------------------------------------------- */
868 
CFXEU_SetSecProps(CFX_Edit * pEdit,const CPVT_WordPlace & place,EDIT_PROPS_E ep,const CPVT_SecProps & oldsecprops,const CPVT_WordProps & oldwordprops,const CPVT_SecProps & newsecprops,const CPVT_WordProps & newwordprops,const CPVT_WordRange & range)869 CFXEU_SetSecProps::CFXEU_SetSecProps(CFX_Edit * pEdit, const CPVT_WordPlace & place, EDIT_PROPS_E ep,
870 		const CPVT_SecProps & oldsecprops, const CPVT_WordProps & oldwordprops,
871 		const CPVT_SecProps & newsecprops, const CPVT_WordProps & newwordprops, const CPVT_WordRange & range)
872 		: m_pEdit(pEdit),
873 		m_wpPlace(place),
874 		m_eProps(ep),
875 		m_OldSecProps(oldsecprops),
876 		m_NewSecProps(newsecprops),
877 		m_OldWordProps(oldwordprops),
878 		m_NewWordProps(newwordprops),
879 		m_wrPlace(range)
880 {
881 }
882 
~CFXEU_SetSecProps()883 CFXEU_SetSecProps::~CFXEU_SetSecProps()
884 {
885 }
886 
Redo()887 void CFXEU_SetSecProps::Redo()
888 {
889 	if (m_pEdit)
890 	{
891 		m_pEdit->SetSecProps(m_eProps,m_wpPlace,&m_NewSecProps,&m_NewWordProps,m_wrPlace,FALSE);
892 		if (IsLast())
893 		{
894 			m_pEdit->SelectNone();
895 			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
896 			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
897 		}
898 	}
899 }
900 
Undo()901 void CFXEU_SetSecProps::Undo()
902 {
903 	if (m_pEdit)
904 	{
905 		m_pEdit->SetSecProps(m_eProps,m_wpPlace,&m_OldSecProps,&m_OldWordProps,m_wrPlace,FALSE);
906 		if (IsFirst())
907 		{
908 			m_pEdit->SelectNone();
909 			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
910 			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
911 		}
912 	}
913 }
914 
915 /* -------------------------------------------------------------------------- */
916 
CFXEU_SetWordProps(CFX_Edit * pEdit,const CPVT_WordPlace & place,EDIT_PROPS_E ep,const CPVT_WordProps & oldprops,const CPVT_WordProps & newprops,const CPVT_WordRange & range)917 CFXEU_SetWordProps::CFXEU_SetWordProps(CFX_Edit * pEdit, const CPVT_WordPlace & place, EDIT_PROPS_E ep,
918 		const CPVT_WordProps & oldprops, const CPVT_WordProps & newprops, const CPVT_WordRange & range)
919 		: m_pEdit(pEdit),
920 		m_wpPlace(place),
921 		m_eProps(ep),
922 		m_OldWordProps(oldprops),
923 		m_NewWordProps(newprops),
924 		m_wrPlace(range)
925 {
926 }
927 
~CFXEU_SetWordProps()928 CFXEU_SetWordProps::~CFXEU_SetWordProps()
929 {
930 }
931 
Redo()932 void CFXEU_SetWordProps::Redo()
933 {
934 	if (m_pEdit)
935 	{
936 		m_pEdit->SetWordProps(m_eProps,m_wpPlace,&m_NewWordProps,m_wrPlace,FALSE);
937 		if (IsLast())
938 		{
939 			m_pEdit->SelectNone();
940 			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
941 			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
942 		}
943 	}
944 }
945 
Undo()946 void CFXEU_SetWordProps::Undo()
947 {
948 	if (m_pEdit)
949 	{
950 		m_pEdit->SetWordProps(m_eProps,m_wpPlace,&m_OldWordProps,m_wrPlace,FALSE);
951 		if (IsFirst())
952 		{
953 			m_pEdit->SelectNone();
954 			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
955 			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
956 		}
957 	}
958 }
959 
960 /* ------------------------------------- CFX_Edit ------------------------------------- */
961 
CFX_Edit(IPDF_VariableText * pVT)962 CFX_Edit::CFX_Edit(IPDF_VariableText * pVT) :
963 	m_pVT(pVT),
964 	m_pNotify(NULL),
965 	m_pOprNotify(NULL),
966 	m_wpCaret(-1,-1,-1),
967 	m_wpOldCaret(-1,-1,-1),
968 	m_ptScrollPos(0,0),
969 	m_ptRefreshScrollPos(0,0),
970 	m_bEnableScroll(FALSE),
971 	m_bEnableOverflow(FALSE),
972 	m_pVTProvide(NULL),
973 	m_pIterator(NULL),
974 	m_SelState(),
975 	m_ptCaret(0.0f,0.0f),
976 	m_Undo(FX_EDIT_UNDO_MAXITEM),
977 	m_nAlignment(0),
978 	m_bNotifyFlag(FALSE),
979 	m_bEnableRefresh(TRUE),
980 	m_rcOldContent(0.0f,0.0f,0.0f,0.0f),
981 	m_bEnableUndo(TRUE),
982 	m_bNotify(TRUE),
983 	m_bOprNotify(FALSE),
984 	m_pGroupUndoItem(NULL)
985 {
986 	ASSERT(pVT != NULL);
987 }
988 
~CFX_Edit()989 CFX_Edit::~CFX_Edit()
990 {
991 	if (m_pVTProvide)
992 	{
993 		delete m_pVTProvide;
994 		m_pVTProvide = NULL;
995 	}
996 
997 	if (m_pIterator)
998 	{
999 		delete m_pIterator;
1000 		m_pIterator = NULL;
1001 	}
1002 
1003 	ASSERT(m_pGroupUndoItem == NULL);
1004 }
1005 
1006 // public methods
1007 
Initialize()1008 void CFX_Edit::Initialize()
1009 {
1010 	m_pVT->Initialize();
1011 	SetCaret(m_pVT->GetBeginWordPlace());
1012 	SetCaretOrigin();
1013 }
1014 
SetFontMap(IFX_Edit_FontMap * pFontMap)1015 void CFX_Edit::SetFontMap(IFX_Edit_FontMap * pFontMap)
1016 {
1017 	if (m_pVTProvide)
1018 		delete m_pVTProvide;
1019 
1020 	m_pVT->SetProvider(m_pVTProvide = new CFX_Edit_Provider(pFontMap));
1021 }
1022 
SetVTProvider(IPDF_VariableText_Provider * pProvider)1023 void CFX_Edit::SetVTProvider(IPDF_VariableText_Provider* pProvider)
1024 {
1025 	m_pVT->SetProvider(pProvider);
1026 }
1027 
SetNotify(IFX_Edit_Notify * pNotify)1028 void CFX_Edit::SetNotify(IFX_Edit_Notify* pNotify)
1029 {
1030 	m_pNotify = pNotify;
1031 }
1032 
SetOprNotify(IFX_Edit_OprNotify * pOprNotify)1033 void CFX_Edit::SetOprNotify(IFX_Edit_OprNotify* pOprNotify)
1034 {
1035 	m_pOprNotify = pOprNotify;
1036 }
1037 
GetIterator()1038 IFX_Edit_Iterator * CFX_Edit::GetIterator()
1039 {
1040 	if (!m_pIterator)
1041 		m_pIterator = new CFX_Edit_Iterator(this,m_pVT->GetIterator());
1042 
1043 	return m_pIterator;
1044 }
1045 
GetVariableText()1046 IPDF_VariableText *	CFX_Edit::GetVariableText()
1047 {
1048 	return m_pVT;
1049 }
1050 
GetFontMap()1051 IFX_Edit_FontMap* CFX_Edit::GetFontMap()
1052 {
1053 	if (m_pVTProvide)
1054 		return m_pVTProvide->GetFontMap();
1055 
1056 	return NULL;
1057 }
1058 
SetPlateRect(const CPDF_Rect & rect,FX_BOOL bPaint)1059 void CFX_Edit::SetPlateRect(const CPDF_Rect & rect, FX_BOOL bPaint/* = TRUE*/)
1060 {
1061 	m_pVT->SetPlateRect(rect);
1062 	m_ptScrollPos = CPDF_Point(rect.left,rect.top);
1063 	if (bPaint) Paint();
1064 }
1065 
SetAlignmentH(FX_INT32 nFormat,FX_BOOL bPaint)1066 void CFX_Edit::SetAlignmentH(FX_INT32 nFormat/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1067 {
1068 	m_pVT->SetAlignment(nFormat);
1069 	if (bPaint) Paint();
1070 }
1071 
SetAlignmentV(FX_INT32 nFormat,FX_BOOL bPaint)1072 void CFX_Edit::SetAlignmentV(FX_INT32 nFormat/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1073 {
1074 	m_nAlignment = nFormat;
1075 	if (bPaint) Paint();
1076 }
1077 
SetPasswordChar(FX_WORD wSubWord,FX_BOOL bPaint)1078 void CFX_Edit::SetPasswordChar(FX_WORD wSubWord/* ='*' */, FX_BOOL bPaint/* = TRUE*/)
1079 {
1080 	m_pVT->SetPasswordChar(wSubWord);
1081 	if (bPaint) Paint();
1082 }
1083 
SetLimitChar(FX_INT32 nLimitChar,FX_BOOL bPaint)1084 void CFX_Edit::SetLimitChar(FX_INT32 nLimitChar/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1085 {
1086 	m_pVT->SetLimitChar(nLimitChar);
1087 	if (bPaint) Paint();
1088 }
1089 
SetCharArray(FX_INT32 nCharArray,FX_BOOL bPaint)1090 void CFX_Edit::SetCharArray(FX_INT32 nCharArray/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1091 {
1092 	m_pVT->SetCharArray(nCharArray);
1093 	if (bPaint) Paint();
1094 }
1095 
SetCharSpace(FX_FLOAT fCharSpace,FX_BOOL bPaint)1096 void CFX_Edit::SetCharSpace(FX_FLOAT fCharSpace/* =0.0f */, FX_BOOL bPaint/* = TRUE*/)
1097 {
1098 	m_pVT->SetCharSpace(fCharSpace);
1099 	if (bPaint) Paint();
1100 }
1101 
SetHorzScale(FX_INT32 nHorzScale,FX_BOOL bPaint)1102 void CFX_Edit::SetHorzScale(FX_INT32 nHorzScale/* =100 */, FX_BOOL bPaint/* = TRUE*/)
1103 {
1104 	m_pVT->SetHorzScale(nHorzScale);
1105 	if (bPaint) Paint();
1106 }
1107 
SetMultiLine(FX_BOOL bMultiLine,FX_BOOL bPaint)1108 void CFX_Edit::SetMultiLine(FX_BOOL bMultiLine/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1109 {
1110 	m_pVT->SetMultiLine(bMultiLine);
1111 	if (bPaint) Paint();
1112 }
1113 
SetAutoReturn(FX_BOOL bAuto,FX_BOOL bPaint)1114 void CFX_Edit::SetAutoReturn(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1115 {
1116 	m_pVT->SetAutoReturn(bAuto);
1117 	if (bPaint) Paint();
1118 }
1119 
SetLineLeading(FX_FLOAT fLineLeading,FX_BOOL bPaint)1120 void CFX_Edit::SetLineLeading(FX_FLOAT fLineLeading/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1121 {
1122 	m_pVT->SetLineLeading(fLineLeading);
1123 	if (bPaint) Paint();
1124 }
1125 
SetAutoFontSize(FX_BOOL bAuto,FX_BOOL bPaint)1126 void CFX_Edit::SetAutoFontSize(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1127 {
1128 	m_pVT->SetAutoFontSize(bAuto);
1129 	if (bPaint) Paint();
1130 }
1131 
SetFontSize(FX_FLOAT fFontSize,FX_BOOL bPaint)1132 void CFX_Edit::SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint/* = TRUE*/)
1133 {
1134 	m_pVT->SetFontSize(fFontSize);
1135 	if (bPaint) Paint();
1136 }
1137 
SetAutoScroll(FX_BOOL bAuto,FX_BOOL bPaint)1138 void CFX_Edit::SetAutoScroll(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1139 {
1140 	m_bEnableScroll = bAuto;
1141 	if (bPaint) Paint();
1142 }
1143 
SetTextOverflow(FX_BOOL bAllowed,FX_BOOL bPaint)1144 void CFX_Edit::SetTextOverflow(FX_BOOL bAllowed /*= FALSE*/, FX_BOOL bPaint/* = TRUE*/)
1145 {
1146 	m_bEnableOverflow = bAllowed;
1147 	if (bPaint) Paint();
1148 }
1149 
SetSel(FX_INT32 nStartChar,FX_INT32 nEndChar)1150 void CFX_Edit::SetSel(FX_INT32 nStartChar,FX_INT32 nEndChar)
1151 {
1152 	if (m_pVT->IsValid())
1153 	{
1154 		if (nStartChar == 0 && nEndChar < 0)
1155 		{
1156 			SelectAll();
1157 		}
1158 		else if (nStartChar < 0)
1159 		{
1160 			this->SelectNone();
1161 		}
1162 		else
1163 		{
1164 			if (nStartChar < nEndChar)
1165 			{
1166 				SetSel(m_pVT->WordIndexToWordPlace(nStartChar),m_pVT->WordIndexToWordPlace(nEndChar));
1167 			}
1168 			else
1169 			{
1170 				SetSel(m_pVT->WordIndexToWordPlace(nEndChar),m_pVT->WordIndexToWordPlace(nStartChar));
1171 			}
1172 		}
1173 	}
1174 }
1175 
SetSel(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)1176 void CFX_Edit::SetSel(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)
1177 {
1178 	if (m_pVT->IsValid())
1179 	{
1180 		SelectNone();
1181 
1182 		m_SelState.Set(begin,end);
1183 
1184 		SetCaret(m_SelState.EndPos);
1185 
1186 		if (m_SelState.IsExist())
1187 		{
1188 			ScrollToCaret();
1189 			CPVT_WordRange wr(m_SelState.BeginPos,m_SelState.EndPos);
1190 			Refresh(RP_OPTIONAL,&wr);
1191 			SetCaretInfo();
1192 		}
1193 		else
1194 		{
1195 			ScrollToCaret();
1196 			SetCaretInfo();
1197 		}
1198 	}
1199 }
1200 
GetSel(FX_INT32 & nStartChar,FX_INT32 & nEndChar) const1201 void CFX_Edit::GetSel(FX_INT32 & nStartChar, FX_INT32 & nEndChar) const
1202 {
1203 	nStartChar = -1;
1204 	nEndChar = -1;
1205 
1206 	if (m_pVT->IsValid())
1207 	{
1208 		if (m_SelState.IsExist())
1209 		{
1210 			if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
1211 			{
1212 				nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
1213 				nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
1214 			}
1215 			else
1216 			{
1217 				nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
1218 				nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
1219 			}
1220 		}
1221 		else
1222 		{
1223 			nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
1224 			nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
1225 		}
1226 	}
1227 }
1228 
GetCaret() const1229 FX_INT32 CFX_Edit::GetCaret() const
1230 {
1231 	if (m_pVT->IsValid())
1232 		return m_pVT->WordPlaceToWordIndex(m_wpCaret);
1233 
1234 	return -1;
1235 }
1236 
GetCaretWordPlace() const1237 CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const
1238 {
1239 	return m_wpCaret;
1240 }
1241 
GetText() const1242 CFX_WideString CFX_Edit::GetText() const
1243 {
1244 	CFX_WideString swRet;
1245 
1246 	if (m_pVT->IsValid())
1247 	{
1248 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1249 		{
1250 			FX_BOOL bRich = m_pVT->IsRichText();
1251 
1252 			pIterator->SetAt(0);
1253 
1254 			CPVT_Word wordinfo;
1255 			CPVT_WordPlace oldplace = pIterator->GetAt();
1256 			while (pIterator->NextWord())
1257 			{
1258 				CPVT_WordPlace place = pIterator->GetAt();
1259 
1260 				if (pIterator->GetWord(wordinfo))
1261 				{
1262 					if (bRich)
1263 					{
1264 						swRet += wordinfo.Word;
1265 					}
1266 					else
1267 					{
1268 						swRet += wordinfo.Word;
1269 					}
1270 				}
1271 
1272 				if (oldplace.SecCmp(place) != 0)
1273 				{
1274 					swRet += 0x0D;
1275 					swRet += 0x0A;
1276 				}
1277 
1278 				oldplace = place;
1279 			}
1280 		}
1281 	}
1282 
1283 	return swRet;
1284 }
1285 
GetRangeText(const CPVT_WordRange & range) const1286 CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange & range) const
1287 {
1288 	CFX_WideString swRet;
1289 
1290 	if (m_pVT->IsValid())
1291 	{
1292 		FX_BOOL bRich = m_pVT->IsRichText();
1293 
1294 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1295 		{
1296 			CPVT_WordRange wrTemp = range;
1297 			m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1298 			m_pVT->UpdateWordPlace(wrTemp.EndPos);
1299 			pIterator->SetAt(wrTemp.BeginPos);
1300 
1301 			CPVT_Word wordinfo;
1302 			CPVT_WordPlace oldplace = wrTemp.BeginPos;
1303 			while (pIterator->NextWord())
1304 			{
1305 				CPVT_WordPlace place = pIterator->GetAt();
1306 				if (place.WordCmp(wrTemp.EndPos) > 0)break;
1307 
1308 				if (pIterator->GetWord(wordinfo))
1309 				{
1310 					if (bRich)
1311 					{
1312 						swRet += wordinfo.Word;
1313 					}
1314 					else
1315 					{
1316 						swRet += wordinfo.Word;
1317 					}
1318 				}
1319 
1320 				if (oldplace.SecCmp(place) != 0)
1321 				{
1322 					swRet += 0x0D;
1323 					swRet += 0x0A;
1324 				}
1325 
1326 				oldplace = place;
1327 			}
1328 		}
1329 	}
1330 
1331 	return swRet;
1332 }
1333 
GetSelText() const1334 CFX_WideString CFX_Edit::GetSelText() const
1335 {
1336 	return GetRangeText(m_SelState.ConvertToWordRange());
1337 }
1338 
GetTotalWords() const1339 FX_INT32 CFX_Edit::GetTotalWords() const
1340 {
1341 	return m_pVT->GetTotalWords();
1342 }
1343 
GetTotalLines() const1344 FX_INT32 CFX_Edit::GetTotalLines() const
1345 {
1346 	FX_INT32 nLines = 0;
1347 
1348 	if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1349 	{
1350 		pIterator->SetAt(0);
1351 		while (pIterator->NextLine())
1352 			nLines++;
1353 	}
1354 
1355 	return nLines+1;
1356 }
1357 
GetSelectWordRange() const1358 CPVT_WordRange CFX_Edit::GetSelectWordRange() const
1359 {
1360 	return m_SelState.ConvertToWordRange();
1361 }
1362 
CombineWordRange(const CPVT_WordRange & wr1,const CPVT_WordRange & wr2)1363 CPVT_WordRange CFX_Edit::CombineWordRange(const CPVT_WordRange & wr1, const CPVT_WordRange & wr2)
1364 {
1365 	CPVT_WordRange wrRet;
1366 
1367 	if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0)
1368 	{
1369 		wrRet.BeginPos = wr1.BeginPos;
1370 	}
1371 	else
1372 	{
1373 		wrRet.BeginPos = wr2.BeginPos;
1374 	}
1375 
1376 	if (wr1.EndPos.WordCmp(wr2.EndPos) < 0)
1377 	{
1378 		wrRet.EndPos = wr2.EndPos;
1379 	}
1380 	else
1381 	{
1382 		wrRet.EndPos = wr1.EndPos;
1383 	}
1384 
1385 	return wrRet;
1386 }
1387 
IsRichText() const1388 FX_BOOL	CFX_Edit::IsRichText() const
1389 {
1390 	return m_pVT->IsRichText();
1391 }
1392 
SetRichText(FX_BOOL bRichText,FX_BOOL bPaint)1393 void CFX_Edit::SetRichText(FX_BOOL bRichText/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1394 {
1395 	m_pVT->SetRichText(bRichText);
1396 	if (bPaint) Paint();
1397 }
1398 
SetRichFontIndex(FX_INT32 nFontIndex)1399 FX_BOOL CFX_Edit::SetRichFontIndex(FX_INT32 nFontIndex)
1400 {
1401 	CPVT_WordProps WordProps;
1402 	WordProps.nFontIndex = nFontIndex;
1403 	return SetRichTextProps(EP_FONTINDEX,NULL,&WordProps);
1404 }
1405 
SetRichFontSize(FX_FLOAT fFontSize)1406 FX_BOOL CFX_Edit::SetRichFontSize(FX_FLOAT fFontSize)
1407 {
1408 	CPVT_WordProps WordProps;
1409 	WordProps.fFontSize = fFontSize;
1410 	return SetRichTextProps(EP_FONTSIZE,NULL,&WordProps);
1411 }
1412 
SetRichTextColor(FX_COLORREF dwColor)1413 FX_BOOL CFX_Edit::SetRichTextColor(FX_COLORREF dwColor)
1414 {
1415 	CPVT_WordProps WordProps;
1416 	WordProps.dwWordColor = dwColor;
1417 	return SetRichTextProps(EP_WORDCOLOR,NULL,&WordProps);
1418 }
1419 
SetRichTextScript(FX_INT32 nScriptType)1420 FX_BOOL CFX_Edit::SetRichTextScript(FX_INT32 nScriptType)
1421 {
1422 	CPVT_WordProps WordProps;
1423 	WordProps.nScriptType = nScriptType;
1424 	return SetRichTextProps(EP_SCRIPTTYPE,NULL,&WordProps);
1425 }
1426 
SetRichTextBold(FX_BOOL bBold)1427 FX_BOOL CFX_Edit::SetRichTextBold(FX_BOOL bBold)
1428 {
1429 	CPVT_WordProps WordProps;
1430 	if (bBold)
1431 		WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
1432 	return SetRichTextProps(EP_BOLD,NULL,&WordProps);
1433 }
1434 
SetRichTextItalic(FX_BOOL bItalic)1435 FX_BOOL CFX_Edit::SetRichTextItalic(FX_BOOL bItalic)
1436 {
1437 	CPVT_WordProps WordProps;
1438 	if (bItalic)
1439 		WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
1440 	return SetRichTextProps(EP_ITALIC,NULL,&WordProps);
1441 }
1442 
SetRichTextUnderline(FX_BOOL bUnderline)1443 FX_BOOL CFX_Edit::SetRichTextUnderline(FX_BOOL bUnderline)
1444 {
1445 	CPVT_WordProps WordProps;
1446 	if (bUnderline)
1447 		WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
1448 	return SetRichTextProps(EP_UNDERLINE,NULL,&WordProps);
1449 }
1450 
SetRichTextCrossout(FX_BOOL bCrossout)1451 FX_BOOL CFX_Edit::SetRichTextCrossout(FX_BOOL bCrossout)
1452 {
1453 	CPVT_WordProps WordProps;
1454 	if (bCrossout)
1455 		WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
1456 	return SetRichTextProps(EP_CROSSOUT,NULL,&WordProps);
1457 }
1458 
SetRichTextCharSpace(FX_FLOAT fCharSpace)1459 FX_BOOL CFX_Edit::SetRichTextCharSpace(FX_FLOAT fCharSpace)
1460 {
1461 	CPVT_WordProps WordProps;
1462 	WordProps.fCharSpace = fCharSpace;
1463 	return SetRichTextProps(EP_CHARSPACE,NULL,&WordProps);
1464 }
1465 
SetRichTextHorzScale(FX_INT32 nHorzScale)1466 FX_BOOL CFX_Edit::SetRichTextHorzScale(FX_INT32 nHorzScale /*= 100*/)
1467 {
1468 	CPVT_WordProps WordProps;
1469 	WordProps.nHorzScale = nHorzScale;
1470 	return SetRichTextProps(EP_HORZSCALE,NULL,&WordProps);
1471 }
1472 
SetRichTextLineLeading(FX_FLOAT fLineLeading)1473 FX_BOOL CFX_Edit::SetRichTextLineLeading(FX_FLOAT fLineLeading)
1474 {
1475 	CPVT_SecProps SecProps;
1476 	SecProps.fLineLeading = fLineLeading;
1477 	return SetRichTextProps(EP_LINELEADING,&SecProps,NULL);
1478 }
1479 
SetRichTextLineIndent(FX_FLOAT fLineIndent)1480 FX_BOOL CFX_Edit::SetRichTextLineIndent(FX_FLOAT fLineIndent)
1481 {
1482 	CPVT_SecProps SecProps;
1483 	SecProps.fLineIndent = fLineIndent;
1484 	return SetRichTextProps(EP_LINEINDENT,&SecProps,NULL);
1485 }
1486 
SetRichTextAlignment(FX_INT32 nAlignment)1487 FX_BOOL	CFX_Edit::SetRichTextAlignment(FX_INT32 nAlignment)
1488 {
1489 	CPVT_SecProps SecProps;
1490 	SecProps.nAlignment = nAlignment;
1491 	return SetRichTextProps(EP_ALIGNMENT,&SecProps,NULL);
1492 }
1493 
SetRichTextProps(EDIT_PROPS_E eProps,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)1494 FX_BOOL CFX_Edit::SetRichTextProps(EDIT_PROPS_E eProps, const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps)
1495 {
1496 	FX_BOOL bSet = FALSE;
1497 	FX_BOOL bSet1,bSet2;
1498 	if (m_pVT->IsValid() && m_pVT->IsRichText())
1499 	{
1500 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1501 		{
1502 			CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
1503 
1504 			m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1505 			m_pVT->UpdateWordPlace(wrTemp.EndPos);
1506 			pIterator->SetAt(wrTemp.BeginPos);
1507 
1508 			BeginGroupUndo(L"");;
1509 
1510 			bSet = SetSecProps(eProps,wrTemp.BeginPos,pSecProps,pWordProps,wrTemp,TRUE);
1511 
1512 			while (pIterator->NextWord())
1513 			{
1514 				CPVT_WordPlace place = pIterator->GetAt();
1515 				if (place.WordCmp(wrTemp.EndPos) > 0) break;
1516 				bSet1 = SetSecProps(eProps,place,pSecProps,pWordProps,wrTemp,TRUE);
1517 				bSet2 = SetWordProps(eProps,place,pWordProps,wrTemp,TRUE);
1518 
1519 				if (!bSet)
1520 					bSet = (bSet1 || bSet2);
1521 			}
1522 
1523 			EndGroupUndo();
1524 
1525 			if (bSet)
1526 			{
1527 				PaintSetProps(eProps,wrTemp);
1528 			}
1529 		}
1530 	}
1531 
1532 	return bSet;
1533 }
1534 
PaintSetProps(EDIT_PROPS_E eProps,const CPVT_WordRange & wr)1535 void CFX_Edit::PaintSetProps(EDIT_PROPS_E eProps, const CPVT_WordRange & wr)
1536 {
1537 	switch(eProps)
1538 	{
1539 	case EP_LINELEADING:
1540 	case EP_LINEINDENT:
1541 	case EP_ALIGNMENT:
1542 		RearrangePart(wr);
1543 		ScrollToCaret();
1544 		Refresh(RP_ANALYSE);
1545 		SetCaretOrigin();
1546 		SetCaretInfo();
1547 		break;
1548 	case EP_WORDCOLOR:
1549 	case EP_UNDERLINE:
1550 	case EP_CROSSOUT:
1551 		Refresh(RP_OPTIONAL,&wr);
1552 		break;
1553 	case EP_FONTINDEX:
1554 	case EP_FONTSIZE:
1555 	case EP_SCRIPTTYPE:
1556 	case EP_CHARSPACE:
1557 	case EP_HORZSCALE:
1558 	case EP_BOLD:
1559 	case EP_ITALIC:
1560 		RearrangePart(wr);
1561 		ScrollToCaret();
1562 
1563 		CPVT_WordRange wrRefresh(m_pVT->GetSectionBeginPlace(wr.BeginPos),
1564 			m_pVT->GetSectionEndPlace(wr.EndPos));
1565 		Refresh(RP_ANALYSE,&wrRefresh);
1566 
1567 		SetCaretOrigin();
1568 		SetCaretInfo();
1569 		break;
1570 	}
1571 }
1572 
SetSecProps(EDIT_PROPS_E eProps,const CPVT_WordPlace & place,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,const CPVT_WordRange & wr,FX_BOOL bAddUndo)1573 FX_BOOL CFX_Edit::SetSecProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place,
1574 							   const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps,
1575 							   const CPVT_WordRange & wr, FX_BOOL bAddUndo)
1576 {
1577 	if (m_pVT->IsValid() && m_pVT->IsRichText())
1578 	{
1579 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1580 		{
1581 			FX_BOOL bSet = FALSE;
1582 			CPVT_Section secinfo;
1583 			CPVT_Section OldSecinfo;
1584 
1585 			CPVT_WordPlace oldplace = pIterator->GetAt();
1586 
1587 			if (eProps == EP_LINELEADING || eProps == EP_LINEINDENT || eProps == EP_ALIGNMENT)
1588 			{
1589 				if (pSecProps)
1590 				{
1591 					pIterator->SetAt(place);
1592 					if (pIterator->GetSection(secinfo))
1593 					{
1594 						if (bAddUndo) OldSecinfo = secinfo;
1595 
1596 						switch(eProps)
1597 						{
1598 						case EP_LINELEADING:
1599 							if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineLeading,pSecProps->fLineLeading))
1600 							{
1601 								secinfo.SecProps.fLineLeading = pSecProps->fLineLeading;
1602 								bSet = TRUE;
1603 							}
1604 							break;
1605 						case EP_LINEINDENT:
1606 							if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineIndent,pSecProps->fLineIndent))
1607 							{
1608 								secinfo.SecProps.fLineIndent = pSecProps->fLineIndent;
1609 								bSet = TRUE;
1610 							}
1611 							break;
1612 						case EP_ALIGNMENT:
1613 							if (secinfo.SecProps.nAlignment != pSecProps->nAlignment)
1614 							{
1615 								secinfo.SecProps.nAlignment = pSecProps->nAlignment;
1616 								bSet = TRUE;
1617 							}
1618 							break;
1619 						default:
1620 							break;
1621 						}
1622 					}
1623 				}
1624 			}
1625 			else
1626 			{
1627 				if (pWordProps && place == m_pVT->GetSectionBeginPlace(place))
1628 				{
1629 					pIterator->SetAt(place);
1630 					if (pIterator->GetSection(secinfo))
1631 					{
1632 						if (bAddUndo) OldSecinfo = secinfo;
1633 
1634 						switch(eProps)
1635 						{
1636 						case EP_FONTINDEX:
1637 							if (secinfo.WordProps.nFontIndex != pWordProps->nFontIndex)
1638 							{
1639 								secinfo.WordProps.nFontIndex = pWordProps->nFontIndex;
1640 								bSet = TRUE;
1641 							}
1642 							break;
1643 						case EP_FONTSIZE:
1644 							if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fFontSize,pWordProps->fFontSize))
1645 							{
1646 								secinfo.WordProps.fFontSize = pWordProps->fFontSize;
1647 								bSet = TRUE;
1648 							}
1649 							break;
1650 						case EP_WORDCOLOR:
1651 							if (secinfo.WordProps.dwWordColor != pWordProps->dwWordColor)
1652 							{
1653 								secinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
1654 								bSet = TRUE;
1655 							}
1656 							break;
1657 						case EP_SCRIPTTYPE:
1658 							if (secinfo.WordProps.nScriptType != pWordProps->nScriptType)
1659 							{
1660 								secinfo.WordProps.nScriptType = pWordProps->nScriptType;
1661 								bSet = TRUE;
1662 							}
1663 							break;
1664 						case EP_CHARSPACE:
1665 							if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fCharSpace,pWordProps->fCharSpace))
1666 							{
1667 								secinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
1668 								bSet = TRUE;
1669 							}
1670 							break;
1671 						case EP_HORZSCALE:
1672 							if (secinfo.WordProps.nHorzScale != pWordProps->nHorzScale)
1673 							{
1674 								secinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
1675 								bSet = TRUE;
1676 							}
1677 							break;
1678 						case EP_UNDERLINE:
1679 							if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE)
1680 							{
1681 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) == 0)
1682 								{
1683 									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
1684 									bSet = TRUE;
1685 								}
1686 							}
1687 							else
1688 							{
1689 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) != 0)
1690 								{
1691 									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
1692 									bSet = TRUE;
1693 								}
1694 							}
1695 							break;
1696 						case EP_CROSSOUT:
1697 							if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT)
1698 							{
1699 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) == 0)
1700 								{
1701 									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
1702 									bSet = TRUE;
1703 								}
1704 							}
1705 							else
1706 							{
1707 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) != 0)
1708 								{
1709 									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
1710 									bSet = TRUE;
1711 								}
1712 							}
1713 							break;
1714 						case EP_BOLD:
1715 							if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD)
1716 							{
1717 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0)
1718 								{
1719 									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
1720 									bSet = TRUE;
1721 								}
1722 							}
1723 							else
1724 							{
1725 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0)
1726 								{
1727 									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
1728 									bSet = TRUE;
1729 								}
1730 							}
1731 							break;
1732 						case EP_ITALIC:
1733 							if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC)
1734 							{
1735 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) == 0)
1736 								{
1737 									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
1738 									bSet = TRUE;
1739 								}
1740 							}
1741 							else
1742 							{
1743 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) != 0)
1744 								{
1745 									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
1746 									bSet = TRUE;
1747 								}
1748 							}
1749 							break;
1750 						default:
1751 							break;
1752 						}
1753 					}
1754 				}
1755 			}
1756 
1757 			if (bSet)
1758 			{
1759 				pIterator->SetSection(secinfo);
1760 
1761 				if (bAddUndo && m_bEnableUndo)
1762 				{
1763 					AddEditUndoItem(new CFXEU_SetSecProps
1764 						(this,place,eProps,OldSecinfo.SecProps,OldSecinfo.WordProps,secinfo.SecProps,secinfo.WordProps,wr));
1765 				}
1766 			}
1767 
1768 			pIterator->SetAt(oldplace);
1769 
1770 			return bSet;
1771 		}
1772 	}
1773 
1774 	return FALSE;
1775 }
1776 
SetWordProps(EDIT_PROPS_E eProps,const CPVT_WordPlace & place,const CPVT_WordProps * pWordProps,const CPVT_WordRange & wr,FX_BOOL bAddUndo)1777 FX_BOOL CFX_Edit::SetWordProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place,
1778 								const CPVT_WordProps * pWordProps, const CPVT_WordRange & wr, FX_BOOL bAddUndo)
1779 {
1780 	if (m_pVT->IsValid() && m_pVT->IsRichText())
1781 	{
1782 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1783 		{
1784 			FX_BOOL bSet = FALSE;
1785 			CPVT_Word wordinfo;
1786 			CPVT_Word OldWordinfo;
1787 
1788 			CPVT_WordPlace oldplace = pIterator->GetAt();
1789 
1790 			if (pWordProps)
1791 			{
1792 				pIterator->SetAt(place);
1793 				if (pIterator->GetWord(wordinfo))
1794 				{
1795 					if (bAddUndo) OldWordinfo = wordinfo;
1796 
1797 					switch(eProps)
1798 					{
1799 					case EP_FONTINDEX:
1800 						if (wordinfo.WordProps.nFontIndex != pWordProps->nFontIndex)
1801 						{
1802 							if (IFX_Edit_FontMap* pFontMap = this->GetFontMap())
1803 							{
1804 								wordinfo.WordProps.nFontIndex = pFontMap->GetWordFontIndex(wordinfo.Word,wordinfo.nCharset,pWordProps->nFontIndex);
1805 							}
1806 							bSet = TRUE;
1807 						}
1808 						break;
1809 					case EP_FONTSIZE:
1810 						if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fFontSize,pWordProps->fFontSize))
1811 						{
1812 							wordinfo.WordProps.fFontSize = pWordProps->fFontSize;
1813 							bSet = TRUE;
1814 						}
1815 						break;
1816 					case EP_WORDCOLOR:
1817 						if (wordinfo.WordProps.dwWordColor != pWordProps->dwWordColor)
1818 						{
1819 							wordinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
1820 							bSet = TRUE;
1821 						}
1822 						break;
1823 					case EP_SCRIPTTYPE:
1824 						if (wordinfo.WordProps.nScriptType != pWordProps->nScriptType)
1825 						{
1826 							wordinfo.WordProps.nScriptType = pWordProps->nScriptType;
1827 							bSet = TRUE;
1828 						}
1829 						break;
1830 					case EP_CHARSPACE:
1831 						if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fCharSpace,pWordProps->fCharSpace))
1832 						{
1833 							wordinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
1834 							bSet = TRUE;
1835 						}
1836 						break;
1837 					case EP_HORZSCALE:
1838 						if (wordinfo.WordProps.nHorzScale != pWordProps->nHorzScale)
1839 						{
1840 							wordinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
1841 							bSet = TRUE;
1842 						}
1843 						break;
1844 					case EP_UNDERLINE:
1845 						if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE)
1846 						{
1847 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) == 0)
1848 							{
1849 								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
1850 								bSet = TRUE;
1851 							}
1852 						}
1853 						else
1854 						{
1855 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) != 0)
1856 							{
1857 								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
1858 								bSet = TRUE;
1859 							}
1860 						}
1861 						break;
1862 					case EP_CROSSOUT:
1863 						if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT)
1864 						{
1865 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) == 0)
1866 							{
1867 								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
1868 								bSet = TRUE;
1869 							}
1870 						}
1871 						else
1872 						{
1873 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) != 0)
1874 							{
1875 								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
1876 								bSet = TRUE;
1877 							}
1878 						}
1879 						break;
1880 					case EP_BOLD:
1881 						if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD)
1882 						{
1883 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0)
1884 							{
1885 								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
1886 								bSet = TRUE;
1887 							}
1888 						}
1889 						else
1890 						{
1891 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0)
1892 							{
1893 								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
1894 								bSet = TRUE;
1895 							}
1896 						}
1897 						break;
1898 					case EP_ITALIC:
1899 						if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC)
1900 						{
1901 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) == 0)
1902 							{
1903 								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
1904 								bSet = TRUE;
1905 							}
1906 						}
1907 						else
1908 						{
1909 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) != 0)
1910 							{
1911 								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
1912 								bSet = TRUE;
1913 							}
1914 						}
1915 						break;
1916 					default:
1917 						break;
1918 					}
1919 				}
1920 			}
1921 
1922 			if (bSet)
1923 			{
1924 				pIterator->SetWord(wordinfo);
1925 
1926 				if (bAddUndo && m_bEnableUndo)
1927 				{
1928 					AddEditUndoItem(new CFXEU_SetWordProps
1929 						(this,place,eProps,OldWordinfo.WordProps,wordinfo.WordProps,wr));
1930 				}
1931 			}
1932 
1933 			pIterator->SetAt(oldplace);
1934 			return bSet;
1935 		}
1936 	}
1937 
1938 	return FALSE;
1939 }
1940 
SetText(FX_LPCWSTR text,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)1941 void CFX_Edit::SetText(FX_LPCWSTR text,FX_INT32 charset /*= DEFAULT_CHARSET*/,
1942 						const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
1943 {
1944 	SetText(text,charset,pSecProps,pWordProps,TRUE,TRUE);
1945 }
1946 
InsertWord(FX_WORD word,FX_INT32 charset,const CPVT_WordProps * pWordProps)1947 FX_BOOL CFX_Edit::InsertWord(FX_WORD word, FX_INT32 charset /*= DEFAULT_CHARSET*/, const CPVT_WordProps * pWordProps /*= NULL*/)
1948 {
1949 	return InsertWord(word,charset,pWordProps,TRUE,TRUE);
1950 }
1951 
InsertReturn(const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)1952 FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
1953 {
1954 	return InsertReturn(pSecProps,pWordProps,TRUE,TRUE);
1955 }
1956 
Backspace()1957 FX_BOOL CFX_Edit::Backspace()
1958 {
1959 	return Backspace(TRUE,TRUE);
1960 }
1961 
Delete()1962 FX_BOOL CFX_Edit::Delete()
1963 {
1964 	return Delete(TRUE,TRUE);
1965 }
1966 
Clear()1967 FX_BOOL CFX_Edit::Clear()
1968 {
1969 	return Clear(TRUE,TRUE);
1970 }
1971 
InsertText(FX_LPCWSTR text,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)1972 FX_BOOL CFX_Edit::InsertText(FX_LPCWSTR text, FX_INT32 charset /*= DEFAULT_CHARSET*/,
1973 								const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
1974 {
1975 	return InsertText(text,charset,pSecProps,pWordProps,TRUE,TRUE);
1976 }
1977 
GetFontSize() const1978 FX_FLOAT CFX_Edit::GetFontSize() const
1979 {
1980 	return m_pVT->GetFontSize();
1981 }
1982 
GetPasswordChar() const1983 FX_WORD CFX_Edit::GetPasswordChar() const
1984 {
1985 	return m_pVT->GetPasswordChar();
1986 }
1987 
GetCharArray() const1988 FX_INT32 CFX_Edit::GetCharArray() const
1989 {
1990 	return m_pVT->GetCharArray();
1991 }
1992 
GetPlateRect() const1993 CPDF_Rect CFX_Edit::GetPlateRect() const
1994 {
1995 	return m_pVT->GetPlateRect();
1996 }
1997 
GetContentRect() const1998 CPDF_Rect CFX_Edit::GetContentRect() const
1999 {
2000 	return VTToEdit(m_pVT->GetContentRect());
2001 }
2002 
GetHorzScale() const2003 FX_INT32 CFX_Edit::GetHorzScale() const
2004 {
2005 	return m_pVT->GetHorzScale();
2006 }
2007 
GetCharSpace() const2008 FX_FLOAT CFX_Edit::GetCharSpace() const
2009 {
2010 	return m_pVT->GetCharSpace();
2011 }
2012 
2013 // inner methods
2014 
GetWholeWordRange() const2015 CPVT_WordRange CFX_Edit::GetWholeWordRange() const
2016 {
2017 	if (m_pVT->IsValid())
2018 		return CPVT_WordRange(m_pVT->GetBeginWordPlace(),m_pVT->GetEndWordPlace());
2019 
2020 	return CPVT_WordRange();
2021 }
2022 
GetVisibleWordRange() const2023 CPVT_WordRange CFX_Edit::GetVisibleWordRange() const
2024 {
2025 	if (m_bEnableOverflow) return GetWholeWordRange();
2026 
2027 	if (m_pVT->IsValid())
2028 	{
2029 		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2030 
2031 		CPVT_WordPlace place1 = m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.left,rcPlate.top)));
2032 		CPVT_WordPlace place2 = m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.right,rcPlate.bottom)));
2033 
2034 		return CPVT_WordRange(place1,place2);
2035 	}
2036 
2037 	return CPVT_WordRange();
2038 }
2039 
SearchWordPlace(const CPDF_Point & point) const2040 CPVT_WordPlace CFX_Edit::SearchWordPlace(const CPDF_Point& point) const
2041 {
2042 	if (m_pVT->IsValid())
2043 	{
2044 		return m_pVT->SearchWordPlace(EditToVT(point));
2045 	}
2046 
2047 	return CPVT_WordPlace();
2048 }
2049 
Paint()2050 void CFX_Edit::Paint()
2051 {
2052 	if (m_pVT->IsValid())
2053 	{
2054 		RearrangeAll();
2055 		ScrollToCaret();
2056 		Refresh(RP_NOANALYSE);
2057 		SetCaretOrigin();
2058 		SetCaretInfo();
2059 	}
2060 }
2061 
RearrangeAll()2062 void CFX_Edit::RearrangeAll()
2063 {
2064 	if (m_pVT->IsValid())
2065 	{
2066 		m_pVT->UpdateWordPlace(m_wpCaret);
2067 		m_pVT->RearrangeAll();
2068 		m_pVT->UpdateWordPlace(m_wpCaret);
2069 		SetScrollInfo();
2070 		SetContentChanged();
2071 	}
2072 }
2073 
RearrangePart(const CPVT_WordRange & range)2074 void CFX_Edit::RearrangePart(const CPVT_WordRange & range)
2075 {
2076 	if (m_pVT->IsValid())
2077 	{
2078 		m_pVT->UpdateWordPlace(m_wpCaret);
2079 		m_pVT->RearrangePart(range);
2080 		m_pVT->UpdateWordPlace(m_wpCaret);
2081 		SetScrollInfo();
2082 		SetContentChanged();
2083 	}
2084 }
2085 
SetContentChanged()2086 void CFX_Edit::SetContentChanged()
2087 {
2088 	if (m_bNotify && m_pNotify)
2089 	{
2090 		CPDF_Rect rcContent = m_pVT->GetContentRect();
2091 		if (rcContent.Width() != m_rcOldContent.Width() ||
2092 			rcContent.Height() != m_rcOldContent.Height())
2093 		{
2094 			if (!m_bNotifyFlag)
2095 			{
2096 				m_bNotifyFlag = TRUE;
2097 				m_pNotify->IOnContentChange(rcContent);
2098 				m_bNotifyFlag = FALSE;
2099 			}
2100 			m_rcOldContent = rcContent;
2101 		}
2102 	}
2103 }
2104 
SelectAll()2105 void CFX_Edit::SelectAll()
2106 {
2107 	if (m_pVT->IsValid())
2108 	{
2109 		m_SelState = GetWholeWordRange();
2110 		SetCaret(m_SelState.EndPos);
2111 
2112 		ScrollToCaret();
2113 		CPVT_WordRange wrVisible = GetVisibleWordRange();
2114 		Refresh(RP_OPTIONAL,&wrVisible);
2115 		SetCaretInfo();
2116 	}
2117 }
2118 
SelectNone()2119 void CFX_Edit::SelectNone()
2120 {
2121 	if (m_pVT->IsValid())
2122 	{
2123 		if (m_SelState.IsExist())
2124 		{
2125 			CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
2126 			m_SelState.Default();
2127 			Refresh(RP_OPTIONAL,&wrTemp);
2128 		}
2129 	}
2130 }
2131 
IsSelected() const2132 FX_BOOL	CFX_Edit::IsSelected() const
2133 {
2134 	return m_SelState.IsExist();
2135 }
2136 
VTToEdit(const CPDF_Point & point) const2137 CPDF_Point CFX_Edit::VTToEdit(const CPDF_Point & point) const
2138 {
2139 	CPDF_Rect rcContent = m_pVT->GetContentRect();
2140 	CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2141 
2142 	FX_FLOAT fPadding = 0.0f;
2143 
2144 	switch (m_nAlignment)
2145 	{
2146 	case 0:
2147 		fPadding = 0.0f;
2148 		break;
2149 	case 1:
2150 		fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
2151 		break;
2152 	case 2:
2153 		fPadding = rcPlate.Height() - rcContent.Height();
2154 		break;
2155 	}
2156 
2157 	return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left),
2158 		point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
2159 }
2160 
EditToVT(const CPDF_Point & point) const2161 CPDF_Point CFX_Edit::EditToVT(const CPDF_Point & point) const
2162 {
2163 	CPDF_Rect rcContent = m_pVT->GetContentRect();
2164 	CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2165 
2166 	FX_FLOAT fPadding = 0.0f;
2167 
2168 	switch (m_nAlignment)
2169 	{
2170 	case 0:
2171 		fPadding = 0.0f;
2172 		break;
2173 	case 1:
2174 		fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
2175 		break;
2176 	case 2:
2177 		fPadding = rcPlate.Height() - rcContent.Height();
2178 		break;
2179 	}
2180 
2181 	return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left),
2182 		point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
2183 }
2184 
VTToEdit(const CPDF_Rect & rect) const2185 CPDF_Rect CFX_Edit::VTToEdit(const CPDF_Rect & rect) const
2186 {
2187 	CPDF_Point ptLeftBottom = VTToEdit(CPDF_Point(rect.left,rect.bottom));
2188 	CPDF_Point ptRightTop = VTToEdit(CPDF_Point(rect.right,rect.top));
2189 
2190 	return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
2191 }
2192 
EditToVT(const CPDF_Rect & rect) const2193 CPDF_Rect CFX_Edit::EditToVT(const CPDF_Rect & rect) const
2194 {
2195 	CPDF_Point ptLeftBottom = EditToVT(CPDF_Point(rect.left,rect.bottom));
2196 	CPDF_Point ptRightTop = EditToVT(CPDF_Point(rect.right,rect.top));
2197 
2198 	return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
2199 }
2200 
SetScrollInfo()2201 void CFX_Edit::SetScrollInfo()
2202 {
2203 	if (m_bNotify && m_pNotify)
2204 	{
2205 		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2206 		CPDF_Rect rcContent = m_pVT->GetContentRect();
2207 
2208 		if (!m_bNotifyFlag)
2209 		{
2210 			m_bNotifyFlag = TRUE;
2211 			m_pNotify->IOnSetScrollInfoX(rcPlate.left, rcPlate.right,
2212 								rcContent.left, rcContent.right, rcPlate.Width() / 3, rcPlate.Width());
2213 
2214 			m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
2215 					rcContent.bottom, rcContent.top, rcPlate.Height() / 3, rcPlate.Height());
2216 			m_bNotifyFlag = FALSE;
2217 		}
2218 	}
2219 }
2220 
SetScrollPosX(FX_FLOAT fx)2221 void CFX_Edit::SetScrollPosX(FX_FLOAT fx)
2222 {
2223 	if (!m_bEnableScroll) return;
2224 
2225 	if (m_pVT->IsValid())
2226 	{
2227 		if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.x,fx))
2228 		{
2229 			m_ptScrollPos.x = fx;
2230 			Refresh(RP_NOANALYSE);
2231 
2232 			if (m_bNotify && m_pNotify)
2233 			{
2234 				if (!m_bNotifyFlag)
2235 				{
2236 					m_bNotifyFlag = TRUE;
2237 					m_pNotify->IOnSetScrollPosX(fx);
2238 					m_bNotifyFlag = FALSE;
2239 				}
2240 			}
2241 		}
2242 	}
2243 }
2244 
SetScrollPosY(FX_FLOAT fy)2245 void CFX_Edit::SetScrollPosY(FX_FLOAT fy)
2246 {
2247 	if (!m_bEnableScroll) return;
2248 
2249 	if (m_pVT->IsValid())
2250 	{
2251 		if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y,fy))
2252 		{
2253 			m_ptScrollPos.y = fy;
2254 			Refresh(RP_NOANALYSE);
2255 
2256 			if (m_bNotify && m_pNotify)
2257 			{
2258 				if (!m_bNotifyFlag)
2259 				{
2260 					m_bNotifyFlag = TRUE;
2261 					m_pNotify->IOnSetScrollPosY(fy);
2262 					m_bNotifyFlag = FALSE;
2263 				}
2264 			}
2265 		}
2266 	}
2267 }
2268 
SetScrollPos(const CPDF_Point & point)2269 void CFX_Edit::SetScrollPos(const CPDF_Point & point)
2270 {
2271 	SetScrollPosX(point.x);
2272 	SetScrollPosY(point.y);
2273 	SetScrollLimit();
2274 	SetCaretInfo();
2275 }
2276 
GetScrollPos() const2277 CPDF_Point CFX_Edit::GetScrollPos() const
2278 {
2279 	return m_ptScrollPos;
2280 }
2281 
SetScrollLimit()2282 void CFX_Edit::SetScrollLimit()
2283 {
2284 	if (m_pVT->IsValid())
2285 	{
2286 		CPDF_Rect rcContent = m_pVT->GetContentRect();
2287 		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2288 
2289 		if (rcPlate.Width() > rcContent.Width())
2290 		{
2291 			SetScrollPosX(rcPlate.left);
2292 		}
2293 		else
2294 		{
2295 			if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.x, rcContent.left))
2296 			{
2297 				SetScrollPosX(rcContent.left);
2298 			}
2299 			else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.x, rcContent.right - rcPlate.Width()))
2300 			{
2301 				SetScrollPosX(rcContent.right - rcPlate.Width());
2302 			}
2303 		}
2304 
2305 		if (rcPlate.Height() > rcContent.Height())
2306 		{
2307 			SetScrollPosY(rcPlate.top);
2308 		}
2309 		else
2310 		{
2311 			if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.y, rcContent.bottom + rcPlate.Height()))
2312 			{
2313 				SetScrollPosY(rcContent.bottom + rcPlate.Height());
2314 			}
2315 			else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.y, rcContent.top))
2316 			{
2317 				SetScrollPosY(rcContent.top);
2318 			}
2319 		}
2320 	}
2321 }
2322 
ScrollToCaret()2323 void CFX_Edit::ScrollToCaret()
2324 {
2325 	SetScrollLimit();
2326 
2327 	if (m_pVT->IsValid())
2328 	{
2329 		CPDF_Point ptHead(0,0);
2330 		CPDF_Point ptFoot(0,0);
2331 
2332 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2333 		{
2334 			pIterator->SetAt(m_wpCaret);
2335 
2336 			CPVT_Word word;
2337 			CPVT_Line line;
2338 			if (pIterator->GetWord(word))
2339 			{
2340 				ptHead.x = word.ptWord.x + word.fWidth;
2341 				ptHead.y = word.ptWord.y + word.fAscent;
2342 				ptFoot.x = word.ptWord.x + word.fWidth;
2343 				ptFoot.y = word.ptWord.y + word.fDescent;
2344 			}
2345 			else if (pIterator->GetLine(line))
2346 			{
2347 				ptHead.x = line.ptLine.x;
2348 				ptHead.y = line.ptLine.y + line.fLineAscent;
2349 				ptFoot.x = line.ptLine.x;
2350 				ptFoot.y = line.ptLine.y + line.fLineDescent;
2351 			}
2352 		}
2353 
2354 		CPDF_Point ptHeadEdit = VTToEdit(ptHead);
2355 		CPDF_Point ptFootEdit = VTToEdit(ptFoot);
2356 
2357 		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2358 
2359 		if (!FX_EDIT_IsFloatEqual(rcPlate.left,rcPlate.right))
2360 		{
2361 			if (FX_EDIT_IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
2362 				FX_EDIT_IsFloatEqual(ptHeadEdit.x, rcPlate.left))
2363 			{
2364 				SetScrollPosX(ptHead.x);
2365 			}
2366 			else if (FX_EDIT_IsFloatBigger(ptHeadEdit.x, rcPlate.right))
2367 			{
2368 				SetScrollPosX(ptHead.x - rcPlate.Width());
2369 			}
2370 		}
2371 
2372 		if (!FX_EDIT_IsFloatEqual(rcPlate.top,rcPlate.bottom))
2373 		{
2374 			if (FX_EDIT_IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
2375 				FX_EDIT_IsFloatEqual(ptFootEdit.y, rcPlate.bottom))
2376 			{
2377 				if (FX_EDIT_IsFloatSmaller(ptHeadEdit.y, rcPlate.top))
2378 				{
2379 					SetScrollPosY(ptFoot.y + rcPlate.Height());
2380 				}
2381 			}
2382 			else if (FX_EDIT_IsFloatBigger(ptHeadEdit.y, rcPlate.top))
2383 			{
2384 				if (FX_EDIT_IsFloatBigger(ptFootEdit.y, rcPlate.bottom))
2385 				{
2386 					SetScrollPosY(ptHead.y);
2387 				}
2388 			}
2389 		}
2390 	}
2391 }
2392 
Refresh(REFRESH_PLAN_E ePlan,const CPVT_WordRange * pRange1,const CPVT_WordRange * pRange2)2393 void CFX_Edit::Refresh(REFRESH_PLAN_E ePlan,const CPVT_WordRange * pRange1,const CPVT_WordRange * pRange2)
2394 {
2395 	if (m_bEnableRefresh && m_pVT->IsValid())
2396 	{
2397 		m_Refresh.BeginRefresh();
2398 		RefreshPushLineRects(GetVisibleWordRange());
2399 
2400 // 		if (!FX_EDIT_IsFloatEqual(m_ptRefreshScrollPos.x,m_ptScrollPos.x) ||
2401 // 			!FX_EDIT_IsFloatEqual(m_ptRefreshScrollPos.y,m_ptScrollPos.y))
2402 // 		{
2403 			m_Refresh.NoAnalyse();
2404 			m_ptRefreshScrollPos = m_ptScrollPos;
2405 // 		}
2406 // 		else
2407 // 		{
2408 // 			switch (ePlan)
2409 // 			{
2410 // 			case RP_ANALYSE:
2411 // 				m_Refresh.Analyse(m_pVT->GetAlignment());
2412 //
2413 // 				if (pRange1) RefreshPushRandomRects(*pRange1);
2414 // 				if (pRange2) RefreshPushRandomRects(*pRange2);
2415 // 				break;
2416 // 			case RP_NOANALYSE:
2417 // 				m_Refresh.NoAnalyse();
2418 // 				break;
2419 // 			case RP_OPTIONAL:
2420 // 				if (pRange1) RefreshPushRandomRects(*pRange1);
2421 // 				if (pRange2) RefreshPushRandomRects(*pRange2);
2422 // 				break;
2423 // 			}
2424 // 		}
2425 
2426 		if (m_bNotify && m_pNotify)
2427 		{
2428 			if (!m_bNotifyFlag)
2429 			{
2430 				m_bNotifyFlag = TRUE;
2431 				if (const CFX_Edit_RectArray * pRects = m_Refresh.GetRefreshRects())
2432 				{
2433 					for (FX_INT32 i = 0, sz = pRects->GetSize(); i < sz; i++)
2434 						m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
2435 				}
2436 				m_bNotifyFlag = FALSE;
2437 			}
2438 		}
2439 
2440 		m_Refresh.EndRefresh();
2441 	}
2442 }
2443 
RefreshPushLineRects(const CPVT_WordRange & wr)2444 void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange & wr)
2445 {
2446 	if (m_pVT->IsValid())
2447 	{
2448 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2449 		{
2450 			CPVT_WordPlace wpBegin = wr.BeginPos;
2451 			m_pVT->UpdateWordPlace(wpBegin);
2452 			CPVT_WordPlace wpEnd = wr.EndPos;
2453 			m_pVT->UpdateWordPlace(wpEnd);
2454 			pIterator->SetAt(wpBegin);
2455 
2456 			CPVT_Line lineinfo;
2457 			do
2458 			{
2459 				if (!pIterator->GetLine(lineinfo))break;
2460 				if (lineinfo.lineplace.LineCmp(wpEnd) > 0)break;
2461 
2462 				CPDF_Rect rcLine(lineinfo.ptLine.x,
2463 									lineinfo.ptLine.y + lineinfo.fLineDescent,
2464 									lineinfo.ptLine.x + lineinfo.fLineWidth,
2465 									lineinfo.ptLine.y + lineinfo.fLineAscent);
2466 
2467 				m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace,lineinfo.lineEnd),VTToEdit(rcLine));
2468 
2469 			}while (pIterator->NextLine());
2470 		}
2471 	}
2472 }
2473 
RefreshPushRandomRects(const CPVT_WordRange & wr)2474 void CFX_Edit::RefreshPushRandomRects(const CPVT_WordRange & wr)
2475 {
2476 	if (m_pVT->IsValid())
2477 	{
2478 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2479 		{
2480 			CPVT_WordRange wrTemp = wr;
2481 
2482 			m_pVT->UpdateWordPlace(wrTemp.BeginPos);
2483 			m_pVT->UpdateWordPlace(wrTemp.EndPos);
2484 			pIterator->SetAt(wrTemp.BeginPos);
2485 
2486 			CPVT_Word wordinfo;
2487 			CPVT_Line lineinfo;
2488 			CPVT_WordPlace place;
2489 
2490 			while (pIterator->NextWord())
2491 			{
2492 				place = pIterator->GetAt();
2493 				if (place.WordCmp(wrTemp.EndPos) > 0) break;
2494 
2495 				pIterator->GetWord(wordinfo);
2496 				pIterator->GetLine(lineinfo);
2497 
2498 				if (place.LineCmp(wrTemp.BeginPos) == 0 || place.LineCmp(wrTemp.EndPos) == 0)
2499 				{
2500 					CPDF_Rect rcWord(wordinfo.ptWord.x,
2501 										lineinfo.ptLine.y + lineinfo.fLineDescent,
2502 										wordinfo.ptWord.x + wordinfo.fWidth,
2503 										lineinfo.ptLine.y + lineinfo.fLineAscent);
2504 
2505 					m_Refresh.AddRefresh(VTToEdit(rcWord));
2506 				}
2507 				else
2508 				{
2509 					CPDF_Rect rcLine(lineinfo.ptLine.x,
2510 										lineinfo.ptLine.y + lineinfo.fLineDescent,
2511 										lineinfo.ptLine.x + lineinfo.fLineWidth,
2512 										lineinfo.ptLine.y + lineinfo.fLineAscent);
2513 
2514 					m_Refresh.AddRefresh(VTToEdit(rcLine));
2515 
2516 					pIterator->NextLine();
2517 				}
2518 			}
2519 		}
2520 	}
2521 }
2522 
RefreshWordRange(const CPVT_WordRange & wr)2523 void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr)
2524 {
2525 	if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2526 	{
2527 		CPVT_WordRange wrTemp = wr;
2528 
2529 		m_pVT->UpdateWordPlace(wrTemp.BeginPos);
2530 		m_pVT->UpdateWordPlace(wrTemp.EndPos);
2531 		pIterator->SetAt(wrTemp.BeginPos);
2532 
2533 		CPVT_Word wordinfo;
2534 		CPVT_Line lineinfo;
2535 		CPVT_WordPlace place;
2536 
2537 		while (pIterator->NextWord())
2538 		{
2539 			place = pIterator->GetAt();
2540 			if (place.WordCmp(wrTemp.EndPos) > 0) break;
2541 
2542 			pIterator->GetWord(wordinfo);
2543 			pIterator->GetLine(lineinfo);
2544 
2545 			if (place.LineCmp(wrTemp.BeginPos) == 0 || place.LineCmp(wrTemp.EndPos) == 0)
2546 			{
2547 				CPDF_Rect rcWord(wordinfo.ptWord.x,
2548 									lineinfo.ptLine.y + lineinfo.fLineDescent,
2549 									wordinfo.ptWord.x + wordinfo.fWidth,
2550 									lineinfo.ptLine.y + lineinfo.fLineAscent);
2551 
2552 				if (m_bNotify && m_pNotify)
2553 				{
2554 					if (!m_bNotifyFlag)
2555 					{
2556 						m_bNotifyFlag = TRUE;
2557 						CPDF_Rect rcRefresh = VTToEdit(rcWord);
2558 						m_pNotify->IOnInvalidateRect(&rcRefresh);
2559 						m_bNotifyFlag = FALSE;
2560 					}
2561 				}
2562 			}
2563 			else
2564 			{
2565 				CPDF_Rect rcLine(lineinfo.ptLine.x,
2566 									lineinfo.ptLine.y + lineinfo.fLineDescent,
2567 									lineinfo.ptLine.x + lineinfo.fLineWidth,
2568 									lineinfo.ptLine.y + lineinfo.fLineAscent);
2569 
2570 				if (m_bNotify && m_pNotify)
2571 				{
2572 					if (!m_bNotifyFlag)
2573 					{
2574 						m_bNotifyFlag = TRUE;
2575 						CPDF_Rect rcRefresh = VTToEdit(rcLine);
2576 						m_pNotify->IOnInvalidateRect(&rcRefresh);
2577 						m_bNotifyFlag = FALSE;
2578 					}
2579 				}
2580 
2581 				pIterator->NextLine();
2582 			}
2583 		}
2584 	}
2585 }
2586 
SetCaret(const CPVT_WordPlace & place)2587 void CFX_Edit::SetCaret(const CPVT_WordPlace & place)
2588 {
2589 	m_wpOldCaret = m_wpCaret;
2590 	m_wpCaret = place;
2591 }
2592 
SetCaretInfo()2593 void CFX_Edit::SetCaretInfo()
2594 {
2595 	if (m_bNotify && m_pNotify)
2596 	{
2597 		if (!m_bNotifyFlag)
2598 		{
2599 			CPDF_Point ptHead(0.0f,0.0f),ptFoot(0.0f,0.0f);
2600 
2601 			if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2602 			{
2603 				pIterator->SetAt(m_wpCaret);
2604 				CPVT_Word word;
2605 				CPVT_Line line;
2606 				if (pIterator->GetWord(word))
2607 				{
2608 					ptHead.x = word.ptWord.x + word.fWidth;
2609 					ptHead.y = word.ptWord.y + word.fAscent;
2610 					ptFoot.x = word.ptWord.x + word.fWidth;
2611 					ptFoot.y = word.ptWord.y + word.fDescent;
2612 				}
2613 				else if (pIterator->GetLine(line))
2614 				{
2615 					ptHead.x = line.ptLine.x;
2616 					ptHead.y = line.ptLine.y + line.fLineAscent;
2617 					ptFoot.x = line.ptLine.x;
2618 					ptFoot.y = line.ptLine.y + line.fLineDescent;
2619 				}
2620 			}
2621 
2622 			m_bNotifyFlag = TRUE;
2623 			m_pNotify->IOnSetCaret(!m_SelState.IsExist(),VTToEdit(ptHead),VTToEdit(ptFoot), m_wpCaret);
2624 			m_bNotifyFlag = FALSE;
2625 		}
2626 	}
2627 
2628 	SetCaretChange();
2629 }
2630 
SetCaretChange()2631 void CFX_Edit::SetCaretChange()
2632 {
2633 	if (this->m_wpCaret == this->m_wpOldCaret) return;
2634 
2635 	if (m_bNotify && m_pVT->IsRichText() && m_pNotify)
2636 	{
2637 		CPVT_SecProps SecProps;
2638 		CPVT_WordProps WordProps;
2639 
2640 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2641 		{
2642 			pIterator->SetAt(m_wpCaret);
2643 			CPVT_Word word;
2644 			CPVT_Section section;
2645 
2646 			if (pIterator->GetSection(section))
2647 			{
2648 				SecProps = section.SecProps;
2649 				WordProps = section.WordProps;
2650 			}
2651 
2652 			if (pIterator->GetWord(word))
2653 			{
2654 				WordProps = word.WordProps;
2655 			}
2656 		}
2657 
2658 		if (!m_bNotifyFlag)
2659 		{
2660 			m_bNotifyFlag = TRUE;
2661 			m_pNotify->IOnCaretChange(SecProps,WordProps);
2662 			m_bNotifyFlag = FALSE;
2663 		}
2664 	}
2665 }
2666 
SetCaret(FX_INT32 nPos)2667 void CFX_Edit::SetCaret(FX_INT32 nPos)
2668 {
2669 	if (m_pVT->IsValid())
2670 	{
2671 		SelectNone();
2672 		SetCaret(m_pVT->WordIndexToWordPlace(nPos));
2673 		m_SelState.Set(m_wpCaret,m_wpCaret);
2674 
2675 		ScrollToCaret();
2676 		SetCaretOrigin();
2677 		SetCaretInfo();
2678 	}
2679 }
2680 
OnMouseDown(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)2681 void CFX_Edit::OnMouseDown(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)
2682 {
2683 	if (m_pVT->IsValid())
2684 	{
2685 		SelectNone();
2686 		SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
2687 		m_SelState.Set(m_wpCaret,m_wpCaret);
2688 
2689 		ScrollToCaret();
2690 		SetCaretOrigin();
2691 		SetCaretInfo();
2692 	}
2693 }
2694 
OnMouseMove(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)2695 void CFX_Edit::OnMouseMove(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)
2696 {
2697 	if (m_pVT->IsValid())
2698 	{
2699 		SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
2700 
2701 		if (m_wpCaret != m_wpOldCaret)
2702 		{
2703 			m_SelState.SetEndPos(m_wpCaret);
2704 
2705 			ScrollToCaret();
2706 			CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2707 			Refresh(RP_OPTIONAL,&wr);
2708 			SetCaretOrigin();
2709 			SetCaretInfo();
2710 		}
2711 	}
2712 }
2713 
OnVK_UP(FX_BOOL bShift,FX_BOOL bCtrl)2714 void CFX_Edit::OnVK_UP(FX_BOOL bShift,FX_BOOL bCtrl)
2715 {
2716 	if (m_pVT->IsValid())
2717 	{
2718 		SetCaret(m_pVT->GetUpWordPlace(m_wpCaret,m_ptCaret));
2719 
2720 		if (bShift)
2721 		{
2722 			if (m_SelState.IsExist())
2723 				m_SelState.SetEndPos(m_wpCaret);
2724 			else
2725 				m_SelState.Set(m_wpOldCaret,m_wpCaret);
2726 
2727 			if (m_wpOldCaret != m_wpCaret)
2728 			{
2729 				ScrollToCaret();
2730 				CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
2731 				Refresh(RP_OPTIONAL, &wr);
2732 				SetCaretInfo();
2733 			}
2734 		}
2735 		else
2736 		{
2737 			SelectNone();
2738 
2739 			ScrollToCaret();
2740 			SetCaretInfo();
2741 		}
2742 	}
2743 }
2744 
OnVK_DOWN(FX_BOOL bShift,FX_BOOL bCtrl)2745 void CFX_Edit::OnVK_DOWN(FX_BOOL bShift,FX_BOOL bCtrl)
2746 {
2747 	if (m_pVT->IsValid())
2748 	{
2749 		SetCaret(m_pVT->GetDownWordPlace(m_wpCaret,m_ptCaret));
2750 
2751 		if (bShift)
2752 		{
2753 			if (m_SelState.IsExist())
2754 				m_SelState.SetEndPos(m_wpCaret);
2755 			else
2756 				m_SelState.Set(m_wpOldCaret,m_wpCaret);
2757 
2758 			if (m_wpOldCaret != m_wpCaret)
2759 			{
2760 				ScrollToCaret();
2761 				CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2762 				Refresh(RP_OPTIONAL, &wr);
2763 				SetCaretInfo();
2764 			}
2765 		}
2766 		else
2767 		{
2768 			SelectNone();
2769 
2770 			ScrollToCaret();
2771 			SetCaretInfo();
2772 		}
2773 	}
2774 }
2775 
OnVK_LEFT(FX_BOOL bShift,FX_BOOL bCtrl)2776 void CFX_Edit::OnVK_LEFT(FX_BOOL bShift,FX_BOOL bCtrl)
2777 {
2778 	if (m_pVT->IsValid())
2779 	{
2780 		if (bShift)
2781 		{
2782 			if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
2783 				m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
2784 				SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2785 
2786 			SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2787 
2788 			if (m_SelState.IsExist())
2789 				m_SelState.SetEndPos(m_wpCaret);
2790 			else
2791 				m_SelState.Set(m_wpOldCaret, m_wpCaret);
2792 
2793 			if (m_wpOldCaret != m_wpCaret)
2794 			{
2795 				ScrollToCaret();
2796 				CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2797 				Refresh(RP_OPTIONAL,&wr);
2798 				SetCaretInfo();
2799 			}
2800 		}
2801 		else
2802 		{
2803 			if (m_SelState.IsExist())
2804 			{
2805 				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
2806 					SetCaret(m_SelState.BeginPos);
2807 				else
2808 					SetCaret(m_SelState.EndPos);
2809 
2810 				SelectNone();
2811 				ScrollToCaret();
2812 				SetCaretInfo();
2813 			}
2814 			else
2815 			{
2816 				if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
2817 					m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
2818 					SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2819 
2820 				SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2821 
2822 				ScrollToCaret();
2823 				SetCaretOrigin();
2824 				SetCaretInfo();
2825 			}
2826 		}
2827 	}
2828 }
2829 
OnVK_RIGHT(FX_BOOL bShift,FX_BOOL bCtrl)2830 void CFX_Edit::OnVK_RIGHT(FX_BOOL bShift,FX_BOOL bCtrl)
2831 {
2832 	if (m_pVT->IsValid())
2833 	{
2834 		if (bShift)
2835 		{
2836 			SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2837 
2838 			if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
2839 				m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
2840 				SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2841 
2842 			if (m_SelState.IsExist())
2843 				m_SelState.SetEndPos(m_wpCaret);
2844 			else
2845 				m_SelState.Set(m_wpOldCaret,m_wpCaret);
2846 
2847 			if (m_wpOldCaret != m_wpCaret)
2848 			{
2849 				ScrollToCaret();
2850 				CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2851 				Refresh(RP_OPTIONAL,&wr);
2852 				SetCaretInfo();
2853 			}
2854 		}
2855 		else
2856 		{
2857 			if (m_SelState.IsExist())
2858 			{
2859 				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)>0)
2860 					SetCaret(m_SelState.BeginPos);
2861 				else
2862 					SetCaret(m_SelState.EndPos);
2863 
2864 				SelectNone();
2865 				ScrollToCaret();
2866 				SetCaretInfo();
2867 			}
2868 			else
2869 			{
2870 				SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2871 
2872 				if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
2873 					m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
2874 					SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2875 
2876 				ScrollToCaret();
2877 				SetCaretOrigin();
2878 				SetCaretInfo();
2879 			}
2880 		}
2881 	}
2882 }
2883 
OnVK_HOME(FX_BOOL bShift,FX_BOOL bCtrl)2884 void CFX_Edit::OnVK_HOME(FX_BOOL bShift,FX_BOOL bCtrl)
2885 {
2886 	if (m_pVT->IsValid())
2887 	{
2888 		if (bShift)
2889 		{
2890 			if (bCtrl)
2891 				SetCaret(m_pVT->GetBeginWordPlace());
2892 			else
2893 				SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
2894 
2895 			if (m_SelState.IsExist())
2896 				m_SelState.SetEndPos(m_wpCaret);
2897 			else
2898 				m_SelState.Set(m_wpOldCaret,m_wpCaret);
2899 
2900 			ScrollToCaret();
2901 			CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
2902 			Refresh(RP_OPTIONAL, &wr);
2903 			SetCaretInfo();
2904 		}
2905 		else
2906 		{
2907 			if (m_SelState.IsExist())
2908 			{
2909 				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
2910 					SetCaret(m_SelState.BeginPos);
2911 				else
2912 					SetCaret(m_SelState.EndPos);
2913 
2914 				SelectNone();
2915 				ScrollToCaret();
2916 				SetCaretInfo();
2917 			}
2918 			else
2919 			{
2920 				if (bCtrl)
2921 					SetCaret(m_pVT->GetBeginWordPlace());
2922 				else
2923 					SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
2924 
2925 				ScrollToCaret();
2926 				SetCaretOrigin();
2927 				SetCaretInfo();
2928 			}
2929 		}
2930 	}
2931 }
2932 
OnVK_END(FX_BOOL bShift,FX_BOOL bCtrl)2933 void CFX_Edit::OnVK_END(FX_BOOL bShift,FX_BOOL bCtrl)
2934 {
2935 	if (m_pVT->IsValid())
2936 	{
2937 		if (bShift)
2938 		{
2939 			if (bCtrl)
2940 				SetCaret(m_pVT->GetEndWordPlace());
2941 			else
2942 				SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
2943 
2944 			if (m_SelState.IsExist())
2945 				m_SelState.SetEndPos(m_wpCaret);
2946 			else
2947 				m_SelState.Set(m_wpOldCaret, m_wpCaret);
2948 
2949 			ScrollToCaret();
2950 			CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
2951 			Refresh(RP_OPTIONAL, &wr);
2952 			SetCaretInfo();
2953 		}
2954 		else
2955 		{
2956 			if (m_SelState.IsExist())
2957 			{
2958 				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)>0)
2959 					SetCaret(m_SelState.BeginPos);
2960 				else
2961 					SetCaret(m_SelState.EndPos);
2962 
2963 				SelectNone();
2964 				ScrollToCaret();
2965 				SetCaretInfo();
2966 			}
2967 			else
2968 			{
2969 				if (bCtrl)
2970 					SetCaret(m_pVT->GetEndWordPlace());
2971 				else
2972 					SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
2973 
2974 				ScrollToCaret();
2975 				SetCaretOrigin();
2976 				SetCaretInfo();
2977 			}
2978 		}
2979 	}
2980 }
2981 
SetText(FX_LPCWSTR text,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo,FX_BOOL bPaint)2982 void CFX_Edit::SetText(FX_LPCWSTR text,FX_INT32 charset,
2983 						const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
2984 {
2985 	Empty();
2986 	DoInsertText(CPVT_WordPlace(0,0,-1), text, charset, pSecProps, pWordProps);
2987 	if (bPaint) Paint();
2988 	if (m_bOprNotify && m_pOprNotify)
2989 		m_pOprNotify->OnSetText(m_wpCaret, m_wpOldCaret);
2990 	//if (bAddUndo)
2991 }
2992 
InsertWord(FX_WORD word,FX_INT32 charset,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo,FX_BOOL bPaint)2993 FX_BOOL CFX_Edit::InsertWord(FX_WORD word, FX_INT32 charset, const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
2994 {
2995 	if (IsTextOverflow()) return FALSE;
2996 
2997 	if (m_pVT->IsValid())
2998 	{
2999 		m_pVT->UpdateWordPlace(m_wpCaret);
3000 
3001 		SetCaret(m_pVT->InsertWord(m_wpCaret,word,GetCharSetFromUnicode(word, charset),pWordProps));
3002 		m_SelState.Set(m_wpCaret,m_wpCaret);
3003 
3004 		if (m_wpCaret != m_wpOldCaret)
3005 		{
3006 			if (bAddUndo && m_bEnableUndo)
3007 			{
3008 				AddEditUndoItem(new CFXEU_InsertWord(this,m_wpOldCaret,m_wpCaret,word,charset,pWordProps));
3009 			}
3010 
3011 			if (bPaint)
3012 				PaintInsertText(m_wpOldCaret, m_wpCaret);
3013 
3014 			if (m_bOprNotify && m_pOprNotify)
3015 				m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
3016 
3017 			return TRUE;
3018 		}
3019 	}
3020 
3021 	return FALSE;
3022 }
3023 
InsertReturn(const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo,FX_BOOL bPaint)3024 FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,
3025 							   FX_BOOL bAddUndo, FX_BOOL bPaint)
3026 {
3027 	if (IsTextOverflow()) return FALSE;
3028 
3029 	if (m_pVT->IsValid())
3030 	{
3031 		m_pVT->UpdateWordPlace(m_wpCaret);
3032 		SetCaret(m_pVT->InsertSection(m_wpCaret,pSecProps,pWordProps));
3033 		m_SelState.Set(m_wpCaret,m_wpCaret);
3034 
3035 		if (m_wpCaret != m_wpOldCaret)
3036 		{
3037 			if (bAddUndo && m_bEnableUndo)
3038 			{
3039 				AddEditUndoItem(new CFXEU_InsertReturn(this,m_wpOldCaret,m_wpCaret,pSecProps,pWordProps));
3040 			}
3041 
3042 			if (bPaint)
3043 			{
3044 				RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
3045 				ScrollToCaret();
3046 				CPVT_WordRange wr(m_wpOldCaret, GetVisibleWordRange().EndPos);
3047 				Refresh(RP_ANALYSE, &wr);
3048 				SetCaretOrigin();
3049 				SetCaretInfo();
3050 			}
3051 
3052 			if (m_bOprNotify && m_pOprNotify)
3053 				m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
3054 
3055 			return TRUE;
3056 		}
3057 	}
3058 
3059 	return FALSE;
3060 }
3061 
Backspace(FX_BOOL bAddUndo,FX_BOOL bPaint)3062 FX_BOOL CFX_Edit::Backspace(FX_BOOL bAddUndo, FX_BOOL bPaint)
3063 {
3064 	if (m_pVT->IsValid())
3065 	{
3066 		if (m_wpCaret == m_pVT->GetBeginWordPlace()) return FALSE;
3067 
3068 		CPVT_Section section;
3069 		CPVT_Word word;
3070 
3071 		if (bAddUndo)
3072 		{
3073 			if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
3074 			{
3075 				pIterator->SetAt(m_wpCaret);
3076 				pIterator->GetSection(section);
3077 				pIterator->GetWord(word);
3078 			}
3079 		}
3080 
3081 		m_pVT->UpdateWordPlace(m_wpCaret);
3082 		SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
3083 		m_SelState.Set(m_wpCaret,m_wpCaret);
3084 
3085 		if (m_wpCaret != m_wpOldCaret)
3086 		{
3087 			if (bAddUndo && m_bEnableUndo)
3088 			{
3089 				if (m_wpCaret.SecCmp(m_wpOldCaret) != 0)
3090 					AddEditUndoItem(new CFXEU_Backspace(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
3091 						section.SecProps,section.WordProps));
3092 				else
3093 					AddEditUndoItem(new CFXEU_Backspace(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
3094 						section.SecProps,word.WordProps));
3095 			}
3096 
3097 			if (bPaint)
3098 			{
3099 				RearrangePart(CPVT_WordRange(m_wpCaret,m_wpOldCaret));
3100 				ScrollToCaret();
3101 
3102 				CPVT_WordRange wr;
3103 				if (m_wpCaret.SecCmp(m_wpOldCaret) !=0)
3104 					wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpCaret),GetVisibleWordRange().EndPos);
3105 				else if (m_wpCaret.LineCmp(m_wpOldCaret) !=0)
3106 					wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
3107 				else
3108 					wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
3109 
3110 				Refresh(RP_ANALYSE, &wr);
3111 
3112 				SetCaretOrigin();
3113 				SetCaretInfo();
3114 			}
3115 
3116 			if (m_bOprNotify && m_pOprNotify)
3117 				m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
3118 
3119 			return TRUE;
3120 		}
3121 	}
3122 
3123 	return FALSE;
3124 }
3125 
Delete(FX_BOOL bAddUndo,FX_BOOL bPaint)3126 FX_BOOL CFX_Edit::Delete(FX_BOOL bAddUndo, FX_BOOL bPaint)
3127 {
3128 	if (m_pVT->IsValid())
3129 	{
3130 		if (m_wpCaret == m_pVT->GetEndWordPlace()) return FALSE;
3131 
3132 		CPVT_Section section;
3133 		CPVT_Word word;
3134 
3135 		if (bAddUndo)
3136 		{
3137 			if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
3138 			{
3139 				pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
3140 				pIterator->GetSection(section);
3141 				pIterator->GetWord(word);
3142 			}
3143 		}
3144 
3145 		m_pVT->UpdateWordPlace(m_wpCaret);
3146 		FX_BOOL bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
3147 
3148 		SetCaret(m_pVT->DeleteWord(m_wpCaret));
3149 		m_SelState.Set(m_wpCaret,m_wpCaret);
3150 
3151 		if (bAddUndo && m_bEnableUndo)
3152 		{
3153 			if (bSecEnd)
3154 				AddEditUndoItem(new CFXEU_Delete(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
3155 					section.SecProps,section.WordProps,bSecEnd));
3156 			else
3157 				AddEditUndoItem(new CFXEU_Delete(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
3158 					section.SecProps,word.WordProps,bSecEnd));
3159 		}
3160 
3161 		if (bPaint)
3162 		{
3163 			RearrangePart(CPVT_WordRange(m_wpOldCaret,m_wpCaret));
3164 			ScrollToCaret();
3165 
3166 			CPVT_WordRange wr;
3167 			if (bSecEnd)
3168 				wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpOldCaret),GetVisibleWordRange().EndPos);
3169 			else if (m_wpCaret.LineCmp(m_wpOldCaret) !=0)
3170 				wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
3171 			else
3172 				wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpOldCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
3173 
3174 			Refresh(RP_ANALYSE, &wr);
3175 
3176 			SetCaretOrigin();
3177 			SetCaretInfo();
3178 		}
3179 
3180 		if (m_bOprNotify && m_pOprNotify)
3181 			m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);
3182 
3183 		return TRUE;
3184 	}
3185 
3186 	return FALSE;
3187 }
3188 
Empty()3189 FX_BOOL	CFX_Edit::Empty()
3190 {
3191 	if (m_pVT->IsValid())
3192 	{
3193 		m_pVT->DeleteWords(GetWholeWordRange());
3194 		SetCaret(m_pVT->GetBeginWordPlace());
3195 
3196 		return TRUE;
3197 	}
3198 
3199 	return FALSE;
3200 }
3201 
Clear(FX_BOOL bAddUndo,FX_BOOL bPaint)3202 FX_BOOL CFX_Edit::Clear(FX_BOOL bAddUndo, FX_BOOL bPaint)
3203 {
3204 	if (m_pVT->IsValid())
3205 	{
3206 		if (m_SelState.IsExist())
3207 		{
3208 			CPVT_WordRange range = m_SelState.ConvertToWordRange();
3209 
3210 			if (bAddUndo && m_bEnableUndo)
3211 			{
3212 				if (m_pVT->IsRichText())
3213 				{
3214 					BeginGroupUndo(L"");
3215 
3216 					if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
3217 					{
3218 						pIterator->SetAt(range.EndPos);
3219 
3220 						CPVT_Word wordinfo;
3221 						CPVT_Section secinfo;
3222 						do
3223 						{
3224 							CPVT_WordPlace place = pIterator->GetAt();
3225 							if (place.WordCmp(range.BeginPos) <= 0)break;
3226 
3227 							CPVT_WordPlace oldplace = m_pVT->GetPrevWordPlace(place);
3228 
3229 							if (oldplace.SecCmp(place) != 0)
3230 							{
3231 								if (pIterator->GetSection(secinfo))
3232 								{
3233 									AddEditUndoItem(new CFXEU_ClearRich(this,oldplace,place,range,wordinfo.Word,
3234 										wordinfo.nCharset,secinfo.SecProps,secinfo.WordProps));
3235 								}
3236 							}
3237 							else
3238 							{
3239 								if (pIterator->GetWord(wordinfo))
3240 								{
3241 									oldplace = m_pVT->AjustLineHeader(oldplace,TRUE);
3242 									place = m_pVT->AjustLineHeader(place,TRUE);
3243 
3244 									AddEditUndoItem(new CFXEU_ClearRich(this,oldplace,place,range,wordinfo.Word,
3245 										wordinfo.nCharset,secinfo.SecProps,wordinfo.WordProps));
3246 								}
3247 							}
3248 						}while (pIterator->PrevWord());
3249 					}
3250 					EndGroupUndo();
3251 				}
3252 				else
3253 				{
3254 					AddEditUndoItem(new CFXEU_Clear(this,range,GetSelText()));
3255 				}
3256 			}
3257 
3258 			SelectNone();
3259 			SetCaret(m_pVT->DeleteWords(range));
3260 			m_SelState.Set(m_wpCaret,m_wpCaret);
3261 
3262 			if (bPaint)
3263 			{
3264 				RearrangePart(range);
3265 				ScrollToCaret();
3266 
3267 				CPVT_WordRange wr(m_wpOldCaret, GetVisibleWordRange().EndPos);
3268 				Refresh(RP_ANALYSE, &wr);
3269 
3270 				SetCaretOrigin();
3271 				SetCaretInfo();
3272 			}
3273 
3274 			if (m_bOprNotify && m_pOprNotify)
3275 				m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);
3276 
3277 			return TRUE;
3278 		}
3279 	}
3280 
3281 	return FALSE;
3282 }
3283 
InsertText(FX_LPCWSTR text,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo,FX_BOOL bPaint)3284 FX_BOOL CFX_Edit::InsertText(FX_LPCWSTR text, FX_INT32 charset,
3285 					const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
3286 {
3287 	if (IsTextOverflow()) return FALSE;
3288 
3289 	m_pVT->UpdateWordPlace(m_wpCaret);
3290 	SetCaret(DoInsertText(m_wpCaret, text, charset, pSecProps, pWordProps));
3291 	m_SelState.Set(m_wpCaret,m_wpCaret);
3292 
3293 	if (m_wpCaret != m_wpOldCaret)
3294 	{
3295 		if (bAddUndo && m_bEnableUndo)
3296 		{
3297 			AddEditUndoItem(new CFXEU_InsertText(this,m_wpOldCaret,m_wpCaret,text,charset,pSecProps,pWordProps));
3298 		}
3299 
3300 		if (bPaint)
3301 			PaintInsertText(m_wpOldCaret, m_wpCaret);
3302 
3303 		if (m_bOprNotify && m_pOprNotify)
3304 			m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
3305 
3306 		return TRUE;
3307 	}
3308 	return FALSE;
3309 }
3310 
PaintInsertText(const CPVT_WordPlace & wpOld,const CPVT_WordPlace & wpNew)3311 void CFX_Edit::PaintInsertText(const CPVT_WordPlace & wpOld, const CPVT_WordPlace & wpNew)
3312 {
3313 	if (m_pVT->IsValid())
3314 	{
3315 		RearrangePart(CPVT_WordRange(wpOld,wpNew));
3316 		ScrollToCaret();
3317 
3318 		CPVT_WordRange wr;
3319 		if (m_wpCaret.LineCmp(wpOld) !=0)
3320 			wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(wpOld),m_pVT->GetSectionEndPlace(wpNew));
3321 		else
3322 			wr = CPVT_WordRange(wpOld,m_pVT->GetSectionEndPlace(wpNew));
3323 		Refresh(RP_ANALYSE, &wr);
3324 		SetCaretOrigin();
3325 		SetCaretInfo();
3326 	}
3327 }
3328 
Redo()3329 FX_BOOL CFX_Edit::Redo()
3330 {
3331 	if (m_bEnableUndo)
3332 	{
3333 		if (m_Undo.CanRedo())
3334 		{
3335 			m_Undo.Redo();
3336 			return TRUE;
3337 		}
3338 	}
3339 
3340 	return FALSE;
3341 }
3342 
Undo()3343 FX_BOOL CFX_Edit::Undo()
3344 {
3345 	if (m_bEnableUndo)
3346 	{
3347 		if (m_Undo.CanUndo())
3348 		{
3349 			m_Undo.Undo();
3350 			return TRUE;
3351 		}
3352 	}
3353 
3354 	return FALSE;
3355 }
3356 
SetCaretOrigin()3357 void CFX_Edit::SetCaretOrigin()
3358 {
3359 	if (m_pVT->IsValid())
3360 	{
3361 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
3362 		{
3363 			pIterator->SetAt(m_wpCaret);
3364 			CPVT_Word word;
3365 			CPVT_Line line;
3366 			if (pIterator->GetWord(word))
3367 			{
3368 				m_ptCaret.x = word.ptWord.x + word.fWidth;
3369 				m_ptCaret.y = word.ptWord.y;
3370 			}
3371 			else if (pIterator->GetLine(line))
3372 			{
3373 				m_ptCaret.x = line.ptLine.x;
3374 				m_ptCaret.y = line.ptLine.y;
3375 			}
3376 		}
3377 	}
3378 }
3379 
WordPlaceToWordIndex(const CPVT_WordPlace & place) const3380 FX_INT32 CFX_Edit::WordPlaceToWordIndex(const CPVT_WordPlace & place) const
3381 {
3382 	if (m_pVT->IsValid())
3383 		return m_pVT->WordPlaceToWordIndex(place);
3384 
3385 	return -1;
3386 }
3387 
WordIndexToWordPlace(FX_INT32 index) const3388 CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(FX_INT32 index) const
3389 {
3390 	if (m_pVT->IsValid())
3391 		return m_pVT->WordIndexToWordPlace(index);
3392 
3393 	return CPVT_WordPlace();
3394 }
3395 
IsTextFull() const3396 FX_BOOL	CFX_Edit::IsTextFull() const
3397 {
3398 	FX_INT32 nTotalWords = m_pVT->GetTotalWords();
3399 	FX_INT32 nLimitChar = m_pVT->GetLimitChar();
3400 	FX_INT32 nCharArray = m_pVT->GetCharArray();
3401 
3402 	return IsTextOverflow() || (nLimitChar>0 && nTotalWords >= nLimitChar)
3403 		|| (nCharArray>0 && nTotalWords >= nCharArray);
3404 }
3405 
IsTextOverflow() const3406 FX_BOOL	CFX_Edit::IsTextOverflow() const
3407 {
3408 	if (!m_bEnableScroll && !m_bEnableOverflow)
3409 	{
3410 		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
3411 		CPDF_Rect rcContent = m_pVT->GetContentRect();
3412 
3413 		if (m_pVT->IsMultiLine() && GetTotalLines() > 1)
3414 		{
3415 			if (FX_EDIT_IsFloatBigger(rcContent.Height(),rcPlate.Height())) return TRUE;
3416 		}
3417 
3418 		if (FX_EDIT_IsFloatBigger(rcContent.Width(),rcPlate.Width())) return TRUE;
3419 	}
3420 
3421 	return FALSE;
3422 }
3423 
GetLineBeginPlace(const CPVT_WordPlace & place) const3424 CPVT_WordPlace CFX_Edit::GetLineBeginPlace(const CPVT_WordPlace & place) const
3425 {
3426 	return m_pVT->GetLineBeginPlace(place);
3427 }
3428 
GetLineEndPlace(const CPVT_WordPlace & place) const3429 CPVT_WordPlace CFX_Edit::GetLineEndPlace(const CPVT_WordPlace & place) const
3430 {
3431 	return m_pVT->GetLineEndPlace(place);
3432 }
3433 
GetSectionBeginPlace(const CPVT_WordPlace & place) const3434 CPVT_WordPlace CFX_Edit::GetSectionBeginPlace(const CPVT_WordPlace & place) const
3435 {
3436 	return m_pVT->GetSectionBeginPlace(place);
3437 }
3438 
GetSectionEndPlace(const CPVT_WordPlace & place) const3439 CPVT_WordPlace CFX_Edit::GetSectionEndPlace(const CPVT_WordPlace & place) const
3440 {
3441 	return m_pVT->GetSectionEndPlace(place);
3442 }
3443 
CanUndo() const3444 FX_BOOL	CFX_Edit::CanUndo() const
3445 {
3446 	if (m_bEnableUndo)
3447 	{
3448 		return m_Undo.CanUndo();
3449 	}
3450 
3451 	return FALSE;
3452 }
3453 
CanRedo() const3454 FX_BOOL	CFX_Edit::CanRedo() const
3455 {
3456 	if (m_bEnableUndo)
3457 	{
3458 		return m_Undo.CanRedo();
3459 	}
3460 
3461 	return FALSE;
3462 }
3463 
IsModified() const3464 FX_BOOL	CFX_Edit::IsModified() const
3465 {
3466 	if (m_bEnableUndo)
3467 	{
3468 		return m_Undo.IsModified();
3469 	}
3470 
3471 	return FALSE;
3472 }
3473 
EnableRefresh(FX_BOOL bRefresh)3474 void CFX_Edit::EnableRefresh(FX_BOOL bRefresh)
3475 {
3476 	m_bEnableRefresh = bRefresh;
3477 }
3478 
EnableUndo(FX_BOOL bUndo)3479 void CFX_Edit::EnableUndo(FX_BOOL bUndo)
3480 {
3481 	this->m_bEnableUndo = bUndo;
3482 }
3483 
EnableNotify(FX_BOOL bNotify)3484 void CFX_Edit::EnableNotify(FX_BOOL bNotify)
3485 {
3486 	this->m_bNotify = bNotify;
3487 }
3488 
EnableOprNotify(FX_BOOL bNotify)3489 void CFX_Edit::EnableOprNotify(FX_BOOL bNotify)
3490 {
3491 	this->m_bOprNotify = bNotify;
3492 }
3493 
GetLineTop(const CPVT_WordPlace & place) const3494 FX_FLOAT CFX_Edit::GetLineTop(const CPVT_WordPlace& place) const
3495 {
3496 	if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator())
3497 	{
3498 		CPVT_WordPlace wpOld = pIterator->GetAt();
3499 
3500 		pIterator->SetAt(place);
3501 		CPVT_Line line;
3502 		pIterator->GetLine(line);
3503 
3504 		pIterator->SetAt(wpOld);
3505 
3506 		return line.ptLine.y + line.fLineAscent;
3507 	}
3508 
3509 	return 0.0f;
3510 }
3511 
GetLineBottom(const CPVT_WordPlace & place) const3512 FX_FLOAT CFX_Edit::GetLineBottom(const CPVT_WordPlace& place) const
3513 {
3514 	if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator())
3515 	{
3516 		CPVT_WordPlace wpOld = pIterator->GetAt();
3517 
3518 		pIterator->SetAt(place);
3519 		CPVT_Line line;
3520 		pIterator->GetLine(line);
3521 
3522 		pIterator->SetAt(wpOld);
3523 
3524 		return line.ptLine.y + line.fLineDescent;
3525 	}
3526 
3527 	return 0.0f;
3528 }
3529 
DoInsertText(const CPVT_WordPlace & place,FX_LPCWSTR text,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)3530 CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place, FX_LPCWSTR text, FX_INT32 charset,
3531 									  const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps)
3532 {
3533 	CPVT_WordPlace wp = place;
3534 
3535 	if (m_pVT->IsValid())
3536 	{
3537 		CFX_WideString sText = text;
3538 
3539 		for (FX_INT32 i = 0, sz = sText.GetLength(); i < sz; i++)
3540 		{
3541 			FX_WORD word = sText[i];
3542 			switch (word)
3543 			{
3544 			case 0x0D:
3545 				wp = m_pVT->InsertSection(wp,pSecProps,pWordProps);
3546 				if (sText[i+1] == 0x0A)
3547 					i++;
3548 				break;
3549 			case 0x0A:
3550 				wp = m_pVT->InsertSection(wp,pSecProps,pWordProps);
3551 				if (sText[i+1] == 0x0D)
3552 					i++;
3553 				break;
3554 			case 0x09:
3555 				word = 0x20;
3556 			default:
3557 				wp = m_pVT->InsertWord(wp,word,GetCharSetFromUnicode(word, charset),pWordProps);
3558 				break;
3559 			}
3560 		}
3561 	}
3562 
3563 	return wp;
3564 }
3565 
GetCharSetFromUnicode(FX_WORD word,FX_INT32 nOldCharset)3566 FX_INT32 CFX_Edit::GetCharSetFromUnicode(FX_WORD word, FX_INT32 nOldCharset)
3567 {
3568 	if (IFX_Edit_FontMap* pFontMap = this->GetFontMap())
3569 		return pFontMap->CharSetFromUnicode(word, nOldCharset);
3570 	else
3571 		return nOldCharset;
3572 }
3573 
BeginGroupUndo(const CFX_WideString & sTitle)3574 void CFX_Edit::BeginGroupUndo(const CFX_WideString& sTitle)
3575 {
3576 	ASSERT(m_pGroupUndoItem == NULL);
3577 
3578 	m_pGroupUndoItem = new CFX_Edit_GroupUndoItem(sTitle);
3579 }
3580 
EndGroupUndo()3581 void CFX_Edit::EndGroupUndo()
3582 {
3583 	ASSERT(m_pGroupUndoItem != NULL);
3584 
3585 	m_pGroupUndoItem->UpdateItems();
3586 	m_Undo.AddItem(m_pGroupUndoItem);
3587 	if (m_bOprNotify && m_pOprNotify)
3588 		m_pOprNotify->OnAddUndo(m_pGroupUndoItem);
3589 	m_pGroupUndoItem = NULL;
3590 }
3591 
AddEditUndoItem(CFX_Edit_UndoItem * pEditUndoItem)3592 void CFX_Edit::AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem)
3593 {
3594 	if (m_pGroupUndoItem)
3595 		m_pGroupUndoItem->AddUndoItem(pEditUndoItem);
3596 	else
3597 	{
3598 		m_Undo.AddItem(pEditUndoItem);
3599 		if (m_bOprNotify && m_pOprNotify)
3600 			m_pOprNotify->OnAddUndo(pEditUndoItem);
3601 	}
3602 }
3603 
AddUndoItem(IFX_Edit_UndoItem * pUndoItem)3604 void CFX_Edit::AddUndoItem(IFX_Edit_UndoItem* pUndoItem)
3605 {
3606 	m_Undo.AddItem(pUndoItem);
3607 	if (m_bOprNotify && m_pOprNotify)
3608 		m_pOprNotify->OnAddUndo(pUndoItem);
3609 }
3610 
3611