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