Cleanup: Remove more checks for new returning NULL.
[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     delete m_pVTProvide;
975     m_pVTProvide = NULL;
976     delete m_pIterator;
977     m_pIterator = NULL;
978     ASSERT(m_pGroupUndoItem == NULL);
979 }
980
981 // public methods
982
983 void CFX_Edit::Initialize()
984 {
985         m_pVT->Initialize();
986         SetCaret(m_pVT->GetBeginWordPlace());
987         SetCaretOrigin();
988 }
989
990 void CFX_Edit::SetFontMap(IFX_Edit_FontMap * pFontMap)
991 {
992     delete m_pVTProvide;
993     m_pVT->SetProvider(m_pVTProvide = new CFX_Edit_Provider(pFontMap));
994 }
995
996 void CFX_Edit::SetVTProvider(IPDF_VariableText_Provider* pProvider)
997 {
998         m_pVT->SetProvider(pProvider);
999 }
1000
1001 void CFX_Edit::SetNotify(IFX_Edit_Notify* pNotify)
1002 {
1003         m_pNotify = pNotify;
1004 }
1005
1006 void CFX_Edit::SetOprNotify(IFX_Edit_OprNotify* pOprNotify)
1007 {
1008         m_pOprNotify = pOprNotify;
1009 }
1010
1011 IFX_Edit_Iterator * CFX_Edit::GetIterator()
1012 {
1013         if (!m_pIterator)
1014                 m_pIterator = new CFX_Edit_Iterator(this,m_pVT->GetIterator());
1015
1016         return m_pIterator;
1017 }
1018
1019 IPDF_VariableText *     CFX_Edit::GetVariableText()
1020 {
1021         return m_pVT;
1022 }
1023
1024 IFX_Edit_FontMap* CFX_Edit::GetFontMap()
1025 {
1026         if (m_pVTProvide)
1027                 return m_pVTProvide->GetFontMap();
1028
1029         return NULL;
1030 }
1031
1032 void CFX_Edit::SetPlateRect(const CPDF_Rect & rect, FX_BOOL bPaint/* = TRUE*/)
1033 {
1034         m_pVT->SetPlateRect(rect);
1035         m_ptScrollPos = CPDF_Point(rect.left,rect.top);
1036         if (bPaint) Paint();
1037 }
1038
1039 void CFX_Edit::SetAlignmentH(int32_t nFormat/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1040 {
1041         m_pVT->SetAlignment(nFormat);
1042         if (bPaint) Paint();
1043 }
1044
1045 void CFX_Edit::SetAlignmentV(int32_t nFormat/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1046 {
1047         m_nAlignment = nFormat;
1048         if (bPaint) Paint();
1049 }
1050
1051 void CFX_Edit::SetPasswordChar(FX_WORD wSubWord/* ='*' */, FX_BOOL bPaint/* = TRUE*/)
1052 {
1053         m_pVT->SetPasswordChar(wSubWord);
1054         if (bPaint) Paint();
1055 }
1056
1057 void CFX_Edit::SetLimitChar(int32_t nLimitChar/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1058 {
1059         m_pVT->SetLimitChar(nLimitChar);
1060         if (bPaint) Paint();
1061 }
1062
1063 void CFX_Edit::SetCharArray(int32_t nCharArray/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1064 {
1065         m_pVT->SetCharArray(nCharArray);
1066         if (bPaint) Paint();
1067 }
1068
1069 void CFX_Edit::SetCharSpace(FX_FLOAT fCharSpace/* =0.0f */, FX_BOOL bPaint/* = TRUE*/)
1070 {
1071         m_pVT->SetCharSpace(fCharSpace);
1072         if (bPaint) Paint();
1073 }
1074
1075 void CFX_Edit::SetHorzScale(int32_t nHorzScale/* =100 */, FX_BOOL bPaint/* = TRUE*/)
1076 {
1077         m_pVT->SetHorzScale(nHorzScale);
1078         if (bPaint) Paint();
1079 }
1080
1081 void CFX_Edit::SetMultiLine(FX_BOOL bMultiLine/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1082 {
1083         m_pVT->SetMultiLine(bMultiLine);
1084         if (bPaint) Paint();
1085 }
1086
1087 void CFX_Edit::SetAutoReturn(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1088 {
1089         m_pVT->SetAutoReturn(bAuto);
1090         if (bPaint) Paint();
1091 }
1092
1093 void CFX_Edit::SetLineLeading(FX_FLOAT fLineLeading/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1094 {
1095         m_pVT->SetLineLeading(fLineLeading);
1096         if (bPaint) Paint();
1097 }
1098
1099 void CFX_Edit::SetAutoFontSize(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1100 {
1101         m_pVT->SetAutoFontSize(bAuto);
1102         if (bPaint) Paint();
1103 }
1104
1105 void CFX_Edit::SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint/* = TRUE*/)
1106 {
1107         m_pVT->SetFontSize(fFontSize);
1108         if (bPaint) Paint();
1109 }
1110
1111 void CFX_Edit::SetAutoScroll(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1112 {
1113         m_bEnableScroll = bAuto;
1114         if (bPaint) Paint();
1115 }
1116
1117 void CFX_Edit::SetTextOverflow(FX_BOOL bAllowed /*= FALSE*/, FX_BOOL bPaint/* = TRUE*/)
1118 {
1119         m_bEnableOverflow = bAllowed;
1120         if (bPaint) Paint();
1121 }
1122
1123 void CFX_Edit::SetSel(int32_t nStartChar,int32_t nEndChar)
1124 {
1125         if (m_pVT->IsValid())
1126         {
1127                 if (nStartChar == 0 && nEndChar < 0)
1128                 {
1129                         SelectAll();
1130                 }
1131                 else if (nStartChar < 0)
1132                 {
1133                         SelectNone();
1134                 }
1135                 else
1136                 {
1137                         if (nStartChar < nEndChar)
1138                         {
1139                                 SetSel(m_pVT->WordIndexToWordPlace(nStartChar),m_pVT->WordIndexToWordPlace(nEndChar));
1140                         }
1141                         else
1142                         {
1143                                 SetSel(m_pVT->WordIndexToWordPlace(nEndChar),m_pVT->WordIndexToWordPlace(nStartChar));
1144                         }
1145                 }
1146         }
1147 }
1148
1149 void CFX_Edit::SetSel(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)
1150 {
1151         if (m_pVT->IsValid())
1152         {
1153                 SelectNone();
1154
1155                 m_SelState.Set(begin,end);
1156
1157                 SetCaret(m_SelState.EndPos);
1158
1159                 if (m_SelState.IsExist())
1160                 {
1161                         ScrollToCaret();
1162                         CPVT_WordRange wr(m_SelState.BeginPos,m_SelState.EndPos);
1163                         Refresh(RP_OPTIONAL,&wr);
1164                         SetCaretInfo();
1165                 }
1166                 else
1167                 {
1168                         ScrollToCaret();
1169                         SetCaretInfo();
1170                 }
1171         }
1172 }
1173
1174 void CFX_Edit::GetSel(int32_t & nStartChar, int32_t & nEndChar) const
1175 {
1176         nStartChar = -1;
1177         nEndChar = -1;
1178
1179         if (m_pVT->IsValid())
1180         {
1181                 if (m_SelState.IsExist())
1182                 {
1183                         if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
1184                         {
1185                                 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
1186                                 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
1187                         }
1188                         else
1189                         {
1190                                 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
1191                                 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
1192                         }
1193                 }
1194                 else
1195                 {
1196                         nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
1197                         nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
1198                 }
1199         }
1200 }
1201
1202 int32_t CFX_Edit::GetCaret() const
1203 {
1204         if (m_pVT->IsValid())
1205                 return m_pVT->WordPlaceToWordIndex(m_wpCaret);
1206
1207         return -1;
1208 }
1209
1210 CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const
1211 {
1212         return m_wpCaret;
1213 }
1214
1215 CFX_WideString CFX_Edit::GetText() const
1216 {
1217         CFX_WideString swRet;
1218
1219         if (m_pVT->IsValid())
1220         {
1221                 if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1222                 {
1223                         FX_BOOL bRich = m_pVT->IsRichText();
1224
1225                         pIterator->SetAt(0);
1226
1227                         CPVT_Word wordinfo;
1228                         CPVT_WordPlace oldplace = pIterator->GetAt();
1229                         while (pIterator->NextWord())
1230                         {
1231                                 CPVT_WordPlace place = pIterator->GetAt();
1232
1233                                 if (pIterator->GetWord(wordinfo))
1234                                 {
1235                                         if (bRich)
1236                                         {
1237                                                 swRet += wordinfo.Word;
1238                                         }
1239                                         else
1240                                         {
1241                                                 swRet += wordinfo.Word;
1242                                         }
1243                                 }
1244
1245                                 if (oldplace.SecCmp(place) != 0)
1246                                 {
1247                                         swRet += 0x0D;
1248                                         swRet += 0x0A;
1249                                 }
1250
1251                                 oldplace = place;
1252                         }
1253                 }
1254         }
1255
1256         return swRet;
1257 }
1258
1259 CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange & range) const
1260 {
1261         CFX_WideString swRet;
1262
1263         if (m_pVT->IsValid())
1264         {
1265                 FX_BOOL bRich = m_pVT->IsRichText();
1266
1267                 if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1268                 {
1269                         CPVT_WordRange wrTemp = range;
1270                         m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1271                         m_pVT->UpdateWordPlace(wrTemp.EndPos);
1272                         pIterator->SetAt(wrTemp.BeginPos);
1273
1274                         CPVT_Word wordinfo;
1275                         CPVT_WordPlace oldplace = wrTemp.BeginPos;
1276                         while (pIterator->NextWord())
1277                         {
1278                                 CPVT_WordPlace place = pIterator->GetAt();
1279                                 if (place.WordCmp(wrTemp.EndPos) > 0)break;
1280
1281                                 if (pIterator->GetWord(wordinfo))
1282                                 {
1283                                         if (bRich)
1284                                         {
1285                                                 swRet += wordinfo.Word;
1286                                         }
1287                                         else
1288                                         {
1289                                                 swRet += wordinfo.Word;
1290                                         }
1291                                 }
1292
1293                                 if (oldplace.SecCmp(place) != 0)
1294                                 {
1295                                         swRet += 0x0D;
1296                                         swRet += 0x0A;
1297                                 }
1298
1299                                 oldplace = place;
1300                         }
1301                 }
1302         }
1303
1304         return swRet;
1305 }
1306
1307 CFX_WideString CFX_Edit::GetSelText() const
1308 {
1309         return GetRangeText(m_SelState.ConvertToWordRange());
1310 }
1311
1312 int32_t CFX_Edit::GetTotalWords() const
1313 {
1314         return m_pVT->GetTotalWords();
1315 }
1316
1317 int32_t CFX_Edit::GetTotalLines() const
1318 {
1319         int32_t nLines = 0;
1320
1321         if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1322         {
1323                 pIterator->SetAt(0);
1324                 while (pIterator->NextLine())
1325                         nLines++;
1326         }
1327
1328         return nLines+1;
1329 }
1330
1331 CPVT_WordRange CFX_Edit::GetSelectWordRange() const
1332 {
1333         return m_SelState.ConvertToWordRange();
1334 }
1335
1336 CPVT_WordRange CFX_Edit::CombineWordRange(const CPVT_WordRange & wr1, const CPVT_WordRange & wr2)
1337 {
1338         CPVT_WordRange wrRet;
1339
1340         if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0)
1341         {
1342                 wrRet.BeginPos = wr1.BeginPos;
1343         }
1344         else
1345         {
1346                 wrRet.BeginPos = wr2.BeginPos;
1347         }
1348
1349         if (wr1.EndPos.WordCmp(wr2.EndPos) < 0)
1350         {
1351                 wrRet.EndPos = wr2.EndPos;
1352         }
1353         else
1354         {
1355                 wrRet.EndPos = wr1.EndPos;
1356         }
1357
1358         return wrRet;
1359 }
1360
1361 FX_BOOL CFX_Edit::IsRichText() const
1362 {
1363         return m_pVT->IsRichText();
1364 }
1365
1366 void CFX_Edit::SetRichText(FX_BOOL bRichText/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1367 {
1368         m_pVT->SetRichText(bRichText);
1369         if (bPaint) Paint();
1370 }
1371
1372 FX_BOOL CFX_Edit::SetRichFontIndex(int32_t nFontIndex)
1373 {
1374         CPVT_WordProps WordProps;
1375         WordProps.nFontIndex = nFontIndex;
1376         return SetRichTextProps(EP_FONTINDEX,NULL,&WordProps);
1377 }
1378
1379 FX_BOOL CFX_Edit::SetRichFontSize(FX_FLOAT fFontSize)
1380 {
1381         CPVT_WordProps WordProps;
1382         WordProps.fFontSize = fFontSize;
1383         return SetRichTextProps(EP_FONTSIZE,NULL,&WordProps);
1384 }
1385
1386 FX_BOOL CFX_Edit::SetRichTextColor(FX_COLORREF dwColor)
1387 {
1388         CPVT_WordProps WordProps;
1389         WordProps.dwWordColor = dwColor;
1390         return SetRichTextProps(EP_WORDCOLOR,NULL,&WordProps);
1391 }
1392
1393 FX_BOOL CFX_Edit::SetRichTextScript(int32_t nScriptType)
1394 {
1395         CPVT_WordProps WordProps;
1396         WordProps.nScriptType = nScriptType;
1397         return SetRichTextProps(EP_SCRIPTTYPE,NULL,&WordProps);
1398 }
1399
1400 FX_BOOL CFX_Edit::SetRichTextBold(FX_BOOL bBold)
1401 {
1402         CPVT_WordProps WordProps;
1403         if (bBold)
1404                 WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
1405         return SetRichTextProps(EP_BOLD,NULL,&WordProps);
1406 }
1407
1408 FX_BOOL CFX_Edit::SetRichTextItalic(FX_BOOL bItalic)
1409 {
1410         CPVT_WordProps WordProps;
1411         if (bItalic)
1412                 WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
1413         return SetRichTextProps(EP_ITALIC,NULL,&WordProps);
1414 }
1415
1416 FX_BOOL CFX_Edit::SetRichTextUnderline(FX_BOOL bUnderline)
1417 {
1418         CPVT_WordProps WordProps;
1419         if (bUnderline)
1420                 WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
1421         return SetRichTextProps(EP_UNDERLINE,NULL,&WordProps);
1422 }
1423
1424 FX_BOOL CFX_Edit::SetRichTextCrossout(FX_BOOL bCrossout)
1425 {
1426         CPVT_WordProps WordProps;
1427         if (bCrossout)
1428                 WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
1429         return SetRichTextProps(EP_CROSSOUT,NULL,&WordProps);
1430 }
1431
1432 FX_BOOL CFX_Edit::SetRichTextCharSpace(FX_FLOAT fCharSpace)
1433 {
1434         CPVT_WordProps WordProps;
1435         WordProps.fCharSpace = fCharSpace;
1436         return SetRichTextProps(EP_CHARSPACE,NULL,&WordProps);
1437 }
1438
1439 FX_BOOL CFX_Edit::SetRichTextHorzScale(int32_t nHorzScale /*= 100*/)
1440 {
1441         CPVT_WordProps WordProps;
1442         WordProps.nHorzScale = nHorzScale;
1443         return SetRichTextProps(EP_HORZSCALE,NULL,&WordProps);
1444 }
1445
1446 FX_BOOL CFX_Edit::SetRichTextLineLeading(FX_FLOAT fLineLeading)
1447 {
1448         CPVT_SecProps SecProps;
1449         SecProps.fLineLeading = fLineLeading;
1450         return SetRichTextProps(EP_LINELEADING,&SecProps,NULL);
1451 }
1452
1453 FX_BOOL CFX_Edit::SetRichTextLineIndent(FX_FLOAT fLineIndent)
1454 {
1455         CPVT_SecProps SecProps;
1456         SecProps.fLineIndent = fLineIndent;
1457         return SetRichTextProps(EP_LINEINDENT,&SecProps,NULL);
1458 }
1459
1460 FX_BOOL CFX_Edit::SetRichTextAlignment(int32_t nAlignment)
1461 {
1462         CPVT_SecProps SecProps;
1463         SecProps.nAlignment = nAlignment;
1464         return SetRichTextProps(EP_ALIGNMENT,&SecProps,NULL);
1465 }
1466
1467 FX_BOOL CFX_Edit::SetRichTextProps(EDIT_PROPS_E eProps, const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps)
1468 {
1469         FX_BOOL bSet = FALSE;
1470         FX_BOOL bSet1,bSet2;
1471         if (m_pVT->IsValid() && m_pVT->IsRichText())
1472         {
1473                 if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1474                 {
1475                         CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
1476
1477                         m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1478                         m_pVT->UpdateWordPlace(wrTemp.EndPos);
1479                         pIterator->SetAt(wrTemp.BeginPos);
1480
1481                         BeginGroupUndo(L"");;
1482
1483                         bSet = SetSecProps(eProps,wrTemp.BeginPos,pSecProps,pWordProps,wrTemp,TRUE);
1484
1485                         while (pIterator->NextWord())
1486                         {
1487                                 CPVT_WordPlace place = pIterator->GetAt();
1488                                 if (place.WordCmp(wrTemp.EndPos) > 0) break;
1489                                 bSet1 = SetSecProps(eProps,place,pSecProps,pWordProps,wrTemp,TRUE);
1490                                 bSet2 = SetWordProps(eProps,place,pWordProps,wrTemp,TRUE);
1491
1492                                 if (!bSet)
1493                                         bSet = (bSet1 || bSet2);
1494                         }
1495
1496                         EndGroupUndo();
1497
1498                         if (bSet)
1499                         {
1500                                 PaintSetProps(eProps,wrTemp);
1501                         }
1502                 }
1503         }
1504
1505         return bSet;
1506 }
1507
1508 void CFX_Edit::PaintSetProps(EDIT_PROPS_E eProps, const CPVT_WordRange & wr)
1509 {
1510         switch(eProps)
1511         {
1512         case EP_LINELEADING:
1513         case EP_LINEINDENT:
1514         case EP_ALIGNMENT:
1515                 RearrangePart(wr);
1516                 ScrollToCaret();
1517                 Refresh(RP_ANALYSE);
1518                 SetCaretOrigin();
1519                 SetCaretInfo();
1520                 break;
1521         case EP_WORDCOLOR:
1522         case EP_UNDERLINE:
1523         case EP_CROSSOUT:
1524                 Refresh(RP_OPTIONAL,&wr);
1525                 break;
1526         case EP_FONTINDEX:
1527         case EP_FONTSIZE:
1528         case EP_SCRIPTTYPE:
1529         case EP_CHARSPACE:
1530         case EP_HORZSCALE:
1531         case EP_BOLD:
1532         case EP_ITALIC:
1533                 RearrangePart(wr);
1534                 ScrollToCaret();
1535
1536                 CPVT_WordRange wrRefresh(m_pVT->GetSectionBeginPlace(wr.BeginPos),
1537                         m_pVT->GetSectionEndPlace(wr.EndPos));
1538                 Refresh(RP_ANALYSE,&wrRefresh);
1539
1540                 SetCaretOrigin();
1541                 SetCaretInfo();
1542                 break;
1543         }
1544 }
1545
1546 FX_BOOL CFX_Edit::SetSecProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place,
1547                                                            const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps,
1548                                                            const CPVT_WordRange & wr, FX_BOOL bAddUndo)
1549 {
1550         if (m_pVT->IsValid() && m_pVT->IsRichText())
1551         {
1552                 if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1553                 {
1554                         FX_BOOL bSet = FALSE;
1555                         CPVT_Section secinfo;
1556                         CPVT_Section OldSecinfo;
1557
1558                         CPVT_WordPlace oldplace = pIterator->GetAt();
1559
1560                         if (eProps == EP_LINELEADING || eProps == EP_LINEINDENT || eProps == EP_ALIGNMENT)
1561                         {
1562                                 if (pSecProps)
1563                                 {
1564                                         pIterator->SetAt(place);
1565                                         if (pIterator->GetSection(secinfo))
1566                                         {
1567                                                 if (bAddUndo) OldSecinfo = secinfo;
1568
1569                                                 switch(eProps)
1570                                                 {
1571                                                 case EP_LINELEADING:
1572                                                         if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineLeading,pSecProps->fLineLeading))
1573                                                         {
1574                                                                 secinfo.SecProps.fLineLeading = pSecProps->fLineLeading;
1575                                                                 bSet = TRUE;
1576                                                         }
1577                                                         break;
1578                                                 case EP_LINEINDENT:
1579                                                         if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineIndent,pSecProps->fLineIndent))
1580                                                         {
1581                                                                 secinfo.SecProps.fLineIndent = pSecProps->fLineIndent;
1582                                                                 bSet = TRUE;
1583                                                         }
1584                                                         break;
1585                                                 case EP_ALIGNMENT:
1586                                                         if (secinfo.SecProps.nAlignment != pSecProps->nAlignment)
1587                                                         {
1588                                                                 secinfo.SecProps.nAlignment = pSecProps->nAlignment;
1589                                                                 bSet = TRUE;
1590                                                         }
1591                                                         break;
1592                                                 default:
1593                                                         break;
1594                                                 }
1595                                         }
1596                                 }
1597                         }
1598                         else
1599                         {
1600                                 if (pWordProps && place == m_pVT->GetSectionBeginPlace(place))
1601                                 {
1602                                         pIterator->SetAt(place);
1603                                         if (pIterator->GetSection(secinfo))
1604                                         {
1605                                                 if (bAddUndo) OldSecinfo = secinfo;
1606
1607                                                 switch(eProps)
1608                                                 {
1609                                                 case EP_FONTINDEX:
1610                                                         if (secinfo.WordProps.nFontIndex != pWordProps->nFontIndex)
1611                                                         {
1612                                                                 secinfo.WordProps.nFontIndex = pWordProps->nFontIndex;
1613                                                                 bSet = TRUE;
1614                                                         }
1615                                                         break;
1616                                                 case EP_FONTSIZE:
1617                                                         if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fFontSize,pWordProps->fFontSize))
1618                                                         {
1619                                                                 secinfo.WordProps.fFontSize = pWordProps->fFontSize;
1620                                                                 bSet = TRUE;
1621                                                         }
1622                                                         break;
1623                                                 case EP_WORDCOLOR:
1624                                                         if (secinfo.WordProps.dwWordColor != pWordProps->dwWordColor)
1625                                                         {
1626                                                                 secinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
1627                                                                 bSet = TRUE;
1628                                                         }
1629                                                         break;
1630                                                 case EP_SCRIPTTYPE:
1631                                                         if (secinfo.WordProps.nScriptType != pWordProps->nScriptType)
1632                                                         {
1633                                                                 secinfo.WordProps.nScriptType = pWordProps->nScriptType;
1634                                                                 bSet = TRUE;
1635                                                         }
1636                                                         break;
1637                                                 case EP_CHARSPACE:
1638                                                         if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fCharSpace,pWordProps->fCharSpace))
1639                                                         {
1640                                                                 secinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
1641                                                                 bSet = TRUE;
1642                                                         }
1643                                                         break;
1644                                                 case EP_HORZSCALE:
1645                                                         if (secinfo.WordProps.nHorzScale != pWordProps->nHorzScale)
1646                                                         {
1647                                                                 secinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
1648                                                                 bSet = TRUE;
1649                                                         }
1650                                                         break;
1651                                                 case EP_UNDERLINE:
1652                                                         if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE)
1653                                                         {
1654                                                                 if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) == 0)
1655                                                                 {
1656                                                                         secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
1657                                                                         bSet = TRUE;
1658                                                                 }
1659                                                         }
1660                                                         else
1661                                                         {
1662                                                                 if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) != 0)
1663                                                                 {
1664                                                                         secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
1665                                                                         bSet = TRUE;
1666                                                                 }
1667                                                         }
1668                                                         break;
1669                                                 case EP_CROSSOUT:
1670                                                         if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT)
1671                                                         {
1672                                                                 if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) == 0)
1673                                                                 {
1674                                                                         secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
1675                                                                         bSet = TRUE;
1676                                                                 }
1677                                                         }
1678                                                         else
1679                                                         {
1680                                                                 if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) != 0)
1681                                                                 {
1682                                                                         secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
1683                                                                         bSet = TRUE;
1684                                                                 }
1685                                                         }
1686                                                         break;
1687                                                 case EP_BOLD:
1688                                                         if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD)
1689                                                         {
1690                                                                 if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0)
1691                                                                 {
1692                                                                         secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
1693                                                                         bSet = TRUE;
1694                                                                 }
1695                                                         }
1696                                                         else
1697                                                         {
1698                                                                 if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0)
1699                                                                 {
1700                                                                         secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
1701                                                                         bSet = TRUE;
1702                                                                 }
1703                                                         }
1704                                                         break;
1705                                                 case EP_ITALIC:
1706                                                         if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC)
1707                                                         {
1708                                                                 if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) == 0)
1709                                                                 {
1710                                                                         secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
1711                                                                         bSet = TRUE;
1712                                                                 }
1713                                                         }
1714                                                         else
1715                                                         {
1716                                                                 if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) != 0)
1717                                                                 {
1718                                                                         secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
1719                                                                         bSet = TRUE;
1720                                                                 }
1721                                                         }
1722                                                         break;
1723                                                 default:
1724                                                         break;
1725                                                 }
1726                                         }
1727                                 }
1728                         }
1729
1730                         if (bSet)
1731                         {
1732                                 pIterator->SetSection(secinfo);
1733
1734                                 if (bAddUndo && m_bEnableUndo)
1735                                 {
1736                                         AddEditUndoItem(new CFXEU_SetSecProps
1737                                                 (this,place,eProps,OldSecinfo.SecProps,OldSecinfo.WordProps,secinfo.SecProps,secinfo.WordProps,wr));
1738                                 }
1739                         }
1740
1741                         pIterator->SetAt(oldplace);
1742
1743                         return bSet;
1744                 }
1745         }
1746
1747         return FALSE;
1748 }
1749
1750 FX_BOOL CFX_Edit::SetWordProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place,
1751                                                                 const CPVT_WordProps * pWordProps, const CPVT_WordRange & wr, FX_BOOL bAddUndo)
1752 {
1753         if (m_pVT->IsValid() && m_pVT->IsRichText())
1754         {
1755                 if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1756                 {
1757                         FX_BOOL bSet = FALSE;
1758                         CPVT_Word wordinfo;
1759                         CPVT_Word OldWordinfo;
1760
1761                         CPVT_WordPlace oldplace = pIterator->GetAt();
1762
1763                         if (pWordProps)
1764                         {
1765                                 pIterator->SetAt(place);
1766                                 if (pIterator->GetWord(wordinfo))
1767                                 {
1768                                         if (bAddUndo) OldWordinfo = wordinfo;
1769
1770                                         switch(eProps)
1771                                         {
1772                                         case EP_FONTINDEX:
1773                                                 if (wordinfo.WordProps.nFontIndex != pWordProps->nFontIndex)
1774                                                 {
1775                                                         if (IFX_Edit_FontMap* pFontMap = GetFontMap())
1776                                                         {
1777                                                                 wordinfo.WordProps.nFontIndex = pFontMap->GetWordFontIndex(wordinfo.Word,wordinfo.nCharset,pWordProps->nFontIndex);
1778                                                         }
1779                                                         bSet = TRUE;
1780                                                 }
1781                                                 break;
1782                                         case EP_FONTSIZE:
1783                                                 if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fFontSize,pWordProps->fFontSize))
1784                                                 {
1785                                                         wordinfo.WordProps.fFontSize = pWordProps->fFontSize;
1786                                                         bSet = TRUE;
1787                                                 }
1788                                                 break;
1789                                         case EP_WORDCOLOR:
1790                                                 if (wordinfo.WordProps.dwWordColor != pWordProps->dwWordColor)
1791                                                 {
1792                                                         wordinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
1793                                                         bSet = TRUE;
1794                                                 }
1795                                                 break;
1796                                         case EP_SCRIPTTYPE:
1797                                                 if (wordinfo.WordProps.nScriptType != pWordProps->nScriptType)
1798                                                 {
1799                                                         wordinfo.WordProps.nScriptType = pWordProps->nScriptType;
1800                                                         bSet = TRUE;
1801                                                 }
1802                                                 break;
1803                                         case EP_CHARSPACE:
1804                                                 if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fCharSpace,pWordProps->fCharSpace))
1805                                                 {
1806                                                         wordinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
1807                                                         bSet = TRUE;
1808                                                 }
1809                                                 break;
1810                                         case EP_HORZSCALE:
1811                                                 if (wordinfo.WordProps.nHorzScale != pWordProps->nHorzScale)
1812                                                 {
1813                                                         wordinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
1814                                                         bSet = TRUE;
1815                                                 }
1816                                                 break;
1817                                         case EP_UNDERLINE:
1818                                                 if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE)
1819                                                 {
1820                                                         if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) == 0)
1821                                                         {
1822                                                                 wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
1823                                                                 bSet = TRUE;
1824                                                         }
1825                                                 }
1826                                                 else
1827                                                 {
1828                                                         if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) != 0)
1829                                                         {
1830                                                                 wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
1831                                                                 bSet = TRUE;
1832                                                         }
1833                                                 }
1834                                                 break;
1835                                         case EP_CROSSOUT:
1836                                                 if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT)
1837                                                 {
1838                                                         if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) == 0)
1839                                                         {
1840                                                                 wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
1841                                                                 bSet = TRUE;
1842                                                         }
1843                                                 }
1844                                                 else
1845                                                 {
1846                                                         if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) != 0)
1847                                                         {
1848                                                                 wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
1849                                                                 bSet = TRUE;
1850                                                         }
1851                                                 }
1852                                                 break;
1853                                         case EP_BOLD:
1854                                                 if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD)
1855                                                 {
1856                                                         if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0)
1857                                                         {
1858                                                                 wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
1859                                                                 bSet = TRUE;
1860                                                         }
1861                                                 }
1862                                                 else
1863                                                 {
1864                                                         if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0)
1865                                                         {
1866                                                                 wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
1867                                                                 bSet = TRUE;
1868                                                         }
1869                                                 }
1870                                                 break;
1871                                         case EP_ITALIC:
1872                                                 if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC)
1873                                                 {
1874                                                         if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) == 0)
1875                                                         {
1876                                                                 wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
1877                                                                 bSet = TRUE;
1878                                                         }
1879                                                 }
1880                                                 else
1881                                                 {
1882                                                         if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) != 0)
1883                                                         {
1884                                                                 wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
1885                                                                 bSet = TRUE;
1886                                                         }
1887                                                 }
1888                                                 break;
1889                                         default:
1890                                                 break;
1891                                         }
1892                                 }
1893                         }
1894
1895                         if (bSet)
1896                         {
1897                                 pIterator->SetWord(wordinfo);
1898
1899                                 if (bAddUndo && m_bEnableUndo)
1900                                 {
1901                                         AddEditUndoItem(new CFXEU_SetWordProps
1902                                                 (this,place,eProps,OldWordinfo.WordProps,wordinfo.WordProps,wr));
1903                                 }
1904                         }
1905
1906                         pIterator->SetAt(oldplace);
1907                         return bSet;
1908                 }
1909         }
1910
1911         return FALSE;
1912 }
1913
1914 void CFX_Edit::SetText(const FX_WCHAR* text,int32_t charset /*= DEFAULT_CHARSET*/,
1915                                                 const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
1916 {
1917         SetText(text,charset,pSecProps,pWordProps,TRUE,TRUE);
1918 }
1919
1920 FX_BOOL CFX_Edit::InsertWord(FX_WORD word, int32_t charset /*= DEFAULT_CHARSET*/, const CPVT_WordProps * pWordProps /*= NULL*/)
1921 {
1922         return InsertWord(word,charset,pWordProps,TRUE,TRUE);
1923 }
1924
1925 FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
1926 {
1927         return InsertReturn(pSecProps,pWordProps,TRUE,TRUE);
1928 }
1929
1930 FX_BOOL CFX_Edit::Backspace()
1931 {
1932         return Backspace(TRUE,TRUE);
1933 }
1934
1935 FX_BOOL CFX_Edit::Delete()
1936 {
1937         return Delete(TRUE,TRUE);
1938 }
1939
1940 FX_BOOL CFX_Edit::Clear()
1941 {
1942         return Clear(TRUE,TRUE);
1943 }
1944
1945 FX_BOOL CFX_Edit::InsertText(const FX_WCHAR* text, int32_t charset /*= DEFAULT_CHARSET*/,
1946                                                                 const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
1947 {
1948         return InsertText(text,charset,pSecProps,pWordProps,TRUE,TRUE);
1949 }
1950
1951 FX_FLOAT CFX_Edit::GetFontSize() const
1952 {
1953         return m_pVT->GetFontSize();
1954 }
1955
1956 FX_WORD CFX_Edit::GetPasswordChar() const
1957 {
1958         return m_pVT->GetPasswordChar();
1959 }
1960
1961 int32_t CFX_Edit::GetCharArray() const
1962 {
1963         return m_pVT->GetCharArray();
1964 }
1965
1966 CPDF_Rect CFX_Edit::GetPlateRect() const
1967 {
1968         return m_pVT->GetPlateRect();
1969 }
1970
1971 CPDF_Rect CFX_Edit::GetContentRect() const
1972 {
1973         return VTToEdit(m_pVT->GetContentRect());
1974 }
1975
1976 int32_t CFX_Edit::GetHorzScale() const
1977 {
1978         return m_pVT->GetHorzScale();
1979 }
1980
1981 FX_FLOAT CFX_Edit::GetCharSpace() const
1982 {
1983         return m_pVT->GetCharSpace();
1984 }
1985
1986 // inner methods
1987
1988 CPVT_WordRange CFX_Edit::GetWholeWordRange() const
1989 {
1990         if (m_pVT->IsValid())
1991                 return CPVT_WordRange(m_pVT->GetBeginWordPlace(),m_pVT->GetEndWordPlace());
1992
1993         return CPVT_WordRange();
1994 }
1995
1996 CPVT_WordRange CFX_Edit::GetVisibleWordRange() const
1997 {
1998         if (m_bEnableOverflow) return GetWholeWordRange();
1999
2000         if (m_pVT->IsValid())
2001         {
2002                 CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2003
2004                 CPVT_WordPlace place1 = m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.left,rcPlate.top)));
2005                 CPVT_WordPlace place2 = m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.right,rcPlate.bottom)));
2006
2007                 return CPVT_WordRange(place1,place2);
2008         }
2009
2010         return CPVT_WordRange();
2011 }
2012
2013 CPVT_WordPlace CFX_Edit::SearchWordPlace(const CPDF_Point& point) const
2014 {
2015         if (m_pVT->IsValid())
2016         {
2017                 return m_pVT->SearchWordPlace(EditToVT(point));
2018         }
2019
2020         return CPVT_WordPlace();
2021 }
2022
2023 void CFX_Edit::Paint()
2024 {
2025         if (m_pVT->IsValid())
2026         {
2027                 RearrangeAll();
2028                 ScrollToCaret();
2029                 Refresh(RP_NOANALYSE);
2030                 SetCaretOrigin();
2031                 SetCaretInfo();
2032         }
2033 }
2034
2035 void CFX_Edit::RearrangeAll()
2036 {
2037         if (m_pVT->IsValid())
2038         {
2039                 m_pVT->UpdateWordPlace(m_wpCaret);
2040                 m_pVT->RearrangeAll();
2041                 m_pVT->UpdateWordPlace(m_wpCaret);
2042                 SetScrollInfo();
2043                 SetContentChanged();
2044         }
2045 }
2046
2047 void CFX_Edit::RearrangePart(const CPVT_WordRange & range)
2048 {
2049         if (m_pVT->IsValid())
2050         {
2051                 m_pVT->UpdateWordPlace(m_wpCaret);
2052                 m_pVT->RearrangePart(range);
2053                 m_pVT->UpdateWordPlace(m_wpCaret);
2054                 SetScrollInfo();
2055                 SetContentChanged();
2056         }
2057 }
2058
2059 void CFX_Edit::SetContentChanged()
2060 {
2061         if (m_bNotify && m_pNotify)
2062         {
2063                 CPDF_Rect rcContent = m_pVT->GetContentRect();
2064                 if (rcContent.Width() != m_rcOldContent.Width() ||
2065                         rcContent.Height() != m_rcOldContent.Height())
2066                 {
2067                         if (!m_bNotifyFlag)
2068                         {
2069                                 m_bNotifyFlag = TRUE;
2070                                 m_pNotify->IOnContentChange(rcContent);
2071                                 m_bNotifyFlag = FALSE;
2072                         }
2073                         m_rcOldContent = rcContent;
2074                 }
2075         }
2076 }
2077
2078 void CFX_Edit::SelectAll()
2079 {
2080         if (m_pVT->IsValid())
2081         {
2082                 m_SelState = GetWholeWordRange();
2083                 SetCaret(m_SelState.EndPos);
2084
2085                 ScrollToCaret();
2086                 CPVT_WordRange wrVisible = GetVisibleWordRange();
2087                 Refresh(RP_OPTIONAL,&wrVisible);
2088                 SetCaretInfo();
2089         }
2090 }
2091
2092 void CFX_Edit::SelectNone()
2093 {
2094         if (m_pVT->IsValid())
2095         {
2096                 if (m_SelState.IsExist())
2097                 {
2098                         CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
2099                         m_SelState.Default();
2100                         Refresh(RP_OPTIONAL,&wrTemp);
2101                 }
2102         }
2103 }
2104
2105 FX_BOOL CFX_Edit::IsSelected() const
2106 {
2107         return m_SelState.IsExist();
2108 }
2109
2110 CPDF_Point CFX_Edit::VTToEdit(const CPDF_Point & point) const
2111 {
2112         CPDF_Rect rcContent = m_pVT->GetContentRect();
2113         CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2114
2115         FX_FLOAT fPadding = 0.0f;
2116
2117         switch (m_nAlignment)
2118         {
2119         case 0:
2120                 fPadding = 0.0f;
2121                 break;
2122         case 1:
2123                 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
2124                 break;
2125         case 2:
2126                 fPadding = rcPlate.Height() - rcContent.Height();
2127                 break;
2128         }
2129
2130         return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left),
2131                 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
2132 }
2133
2134 CPDF_Point CFX_Edit::EditToVT(const CPDF_Point & point) const
2135 {
2136         CPDF_Rect rcContent = m_pVT->GetContentRect();
2137         CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2138
2139         FX_FLOAT fPadding = 0.0f;
2140
2141         switch (m_nAlignment)
2142         {
2143         case 0:
2144                 fPadding = 0.0f;
2145                 break;
2146         case 1:
2147                 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
2148                 break;
2149         case 2:
2150                 fPadding = rcPlate.Height() - rcContent.Height();
2151                 break;
2152         }
2153
2154         return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left),
2155                 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
2156 }
2157
2158 CPDF_Rect CFX_Edit::VTToEdit(const CPDF_Rect & rect) const
2159 {
2160         CPDF_Point ptLeftBottom = VTToEdit(CPDF_Point(rect.left,rect.bottom));
2161         CPDF_Point ptRightTop = VTToEdit(CPDF_Point(rect.right,rect.top));
2162
2163         return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
2164 }
2165
2166 CPDF_Rect CFX_Edit::EditToVT(const CPDF_Rect & rect) const
2167 {
2168         CPDF_Point ptLeftBottom = EditToVT(CPDF_Point(rect.left,rect.bottom));
2169         CPDF_Point ptRightTop = EditToVT(CPDF_Point(rect.right,rect.top));
2170
2171         return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
2172 }
2173
2174 void CFX_Edit::SetScrollInfo()
2175 {
2176         if (m_bNotify && m_pNotify)
2177         {
2178                 CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2179                 CPDF_Rect rcContent = m_pVT->GetContentRect();
2180
2181                 if (!m_bNotifyFlag)
2182                 {
2183                         m_bNotifyFlag = TRUE;
2184                         m_pNotify->IOnSetScrollInfoX(rcPlate.left, rcPlate.right,
2185                                                                 rcContent.left, rcContent.right, rcPlate.Width() / 3, rcPlate.Width());
2186
2187                         m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
2188                                         rcContent.bottom, rcContent.top, rcPlate.Height() / 3, rcPlate.Height());
2189                         m_bNotifyFlag = FALSE;
2190                 }
2191         }
2192 }
2193
2194 void CFX_Edit::SetScrollPosX(FX_FLOAT fx)
2195 {
2196         if (!m_bEnableScroll) return;
2197
2198         if (m_pVT->IsValid())
2199         {
2200                 if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.x,fx))
2201                 {
2202                         m_ptScrollPos.x = fx;
2203                         Refresh(RP_NOANALYSE);
2204
2205                         if (m_bNotify && m_pNotify)
2206                         {
2207                                 if (!m_bNotifyFlag)
2208                                 {
2209                                         m_bNotifyFlag = TRUE;
2210                                         m_pNotify->IOnSetScrollPosX(fx);
2211                                         m_bNotifyFlag = FALSE;
2212                                 }
2213                         }
2214                 }
2215         }
2216 }
2217
2218 void CFX_Edit::SetScrollPosY(FX_FLOAT fy)
2219 {
2220         if (!m_bEnableScroll) return;
2221
2222         if (m_pVT->IsValid())
2223         {
2224                 if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y,fy))
2225                 {
2226                         m_ptScrollPos.y = fy;
2227                         Refresh(RP_NOANALYSE);
2228
2229                         if (m_bNotify && m_pNotify)
2230                         {
2231                                 if (!m_bNotifyFlag)
2232                                 {
2233                                         m_bNotifyFlag = TRUE;
2234                                         m_pNotify->IOnSetScrollPosY(fy);
2235                                         m_bNotifyFlag = FALSE;
2236                                 }
2237                         }
2238                 }
2239         }
2240 }
2241
2242 void CFX_Edit::SetScrollPos(const CPDF_Point & point)
2243 {
2244         SetScrollPosX(point.x);
2245         SetScrollPosY(point.y);
2246         SetScrollLimit();
2247         SetCaretInfo();
2248 }
2249
2250 CPDF_Point CFX_Edit::GetScrollPos() const
2251 {
2252         return m_ptScrollPos;
2253 }
2254
2255 void CFX_Edit::SetScrollLimit()
2256 {
2257         if (m_pVT->IsValid())
2258         {
2259                 CPDF_Rect rcContent = m_pVT->GetContentRect();
2260                 CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2261
2262                 if (rcPlate.Width() > rcContent.Width())
2263                 {
2264                         SetScrollPosX(rcPlate.left);
2265                 }
2266                 else
2267                 {
2268                         if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.x, rcContent.left))
2269                         {
2270                                 SetScrollPosX(rcContent.left);
2271                         }
2272                         else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.x, rcContent.right - rcPlate.Width()))
2273                         {
2274                                 SetScrollPosX(rcContent.right - rcPlate.Width());
2275                         }
2276                 }
2277
2278                 if (rcPlate.Height() > rcContent.Height())
2279                 {
2280                         SetScrollPosY(rcPlate.top);
2281                 }
2282                 else
2283                 {
2284                         if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.y, rcContent.bottom + rcPlate.Height()))
2285                         {
2286                                 SetScrollPosY(rcContent.bottom + rcPlate.Height());
2287                         }
2288                         else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.y, rcContent.top))
2289                         {
2290                                 SetScrollPosY(rcContent.top);
2291                         }
2292                 }
2293         }
2294 }
2295
2296 void CFX_Edit::ScrollToCaret()
2297 {
2298         SetScrollLimit();
2299
2300         if (m_pVT->IsValid())
2301         {
2302                 CPDF_Point ptHead(0,0);
2303                 CPDF_Point ptFoot(0,0);
2304
2305                 if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2306                 {
2307                         pIterator->SetAt(m_wpCaret);
2308
2309                         CPVT_Word word;
2310                         CPVT_Line line;
2311                         if (pIterator->GetWord(word))
2312                         {
2313                                 ptHead.x = word.ptWord.x + word.fWidth;
2314                                 ptHead.y = word.ptWord.y + word.fAscent;
2315                                 ptFoot.x = word.ptWord.x + word.fWidth;
2316                                 ptFoot.y = word.ptWord.y + word.fDescent;
2317                         }
2318                         else if (pIterator->GetLine(line))
2319                         {
2320                                 ptHead.x = line.ptLine.x;
2321                                 ptHead.y = line.ptLine.y + line.fLineAscent;
2322                                 ptFoot.x = line.ptLine.x;
2323                                 ptFoot.y = line.ptLine.y + line.fLineDescent;
2324                         }
2325                 }
2326
2327                 CPDF_Point ptHeadEdit = VTToEdit(ptHead);
2328                 CPDF_Point ptFootEdit = VTToEdit(ptFoot);
2329
2330                 CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2331
2332                 if (!FX_EDIT_IsFloatEqual(rcPlate.left,rcPlate.right))
2333                 {
2334                         if (FX_EDIT_IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
2335                                 FX_EDIT_IsFloatEqual(ptHeadEdit.x, rcPlate.left))
2336                         {
2337                                 SetScrollPosX(ptHead.x);
2338                         }
2339                         else if (FX_EDIT_IsFloatBigger(ptHeadEdit.x, rcPlate.right))
2340                         {
2341                                 SetScrollPosX(ptHead.x - rcPlate.Width());
2342                         }
2343                 }
2344
2345                 if (!FX_EDIT_IsFloatEqual(rcPlate.top,rcPlate.bottom))
2346                 {
2347                         if (FX_EDIT_IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
2348                                 FX_EDIT_IsFloatEqual(ptFootEdit.y, rcPlate.bottom))
2349                         {
2350                                 if (FX_EDIT_IsFloatSmaller(ptHeadEdit.y, rcPlate.top))
2351                                 {
2352                                         SetScrollPosY(ptFoot.y + rcPlate.Height());
2353                                 }
2354                         }
2355                         else if (FX_EDIT_IsFloatBigger(ptHeadEdit.y, rcPlate.top))
2356                         {
2357                                 if (FX_EDIT_IsFloatBigger(ptFootEdit.y, rcPlate.bottom))
2358                                 {
2359                                         SetScrollPosY(ptHead.y);
2360                                 }
2361                         }
2362                 }
2363         }
2364 }
2365
2366 void CFX_Edit::Refresh(REFRESH_PLAN_E ePlan,const CPVT_WordRange * pRange1,const CPVT_WordRange * pRange2)
2367 {
2368         if (m_bEnableRefresh && m_pVT->IsValid())
2369         {
2370                 m_Refresh.BeginRefresh();
2371                 RefreshPushLineRects(GetVisibleWordRange());
2372
2373 //              if (!FX_EDIT_IsFloatEqual(m_ptRefreshScrollPos.x,m_ptScrollPos.x) ||
2374 //                      !FX_EDIT_IsFloatEqual(m_ptRefreshScrollPos.y,m_ptScrollPos.y))
2375 //              {
2376                         m_Refresh.NoAnalyse();
2377                         m_ptRefreshScrollPos = m_ptScrollPos;
2378 //              }
2379 //              else
2380 //              {
2381 //                      switch (ePlan)
2382 //                      {
2383 //                      case RP_ANALYSE:
2384 //                              m_Refresh.Analyse(m_pVT->GetAlignment());
2385 //
2386 //                              if (pRange1) RefreshPushRandomRects(*pRange1);
2387 //                              if (pRange2) RefreshPushRandomRects(*pRange2);
2388 //                              break;
2389 //                      case RP_NOANALYSE:
2390 //                              m_Refresh.NoAnalyse();
2391 //                              break;
2392 //                      case RP_OPTIONAL:
2393 //                              if (pRange1) RefreshPushRandomRects(*pRange1);
2394 //                              if (pRange2) RefreshPushRandomRects(*pRange2);
2395 //                              break;
2396 //                      }
2397 //              }
2398
2399                 if (m_bNotify && m_pNotify)
2400                 {
2401                         if (!m_bNotifyFlag)
2402                         {
2403                                 m_bNotifyFlag = TRUE;
2404                                 if (const CFX_Edit_RectArray * pRects = m_Refresh.GetRefreshRects())
2405                                 {
2406                                         for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
2407                                                 m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
2408                                 }
2409                                 m_bNotifyFlag = FALSE;
2410                         }
2411                 }
2412
2413                 m_Refresh.EndRefresh();
2414         }
2415 }
2416
2417 void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange & wr)
2418 {
2419         if (m_pVT->IsValid())
2420         {
2421                 if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2422                 {
2423                         CPVT_WordPlace wpBegin = wr.BeginPos;
2424                         m_pVT->UpdateWordPlace(wpBegin);
2425                         CPVT_WordPlace wpEnd = wr.EndPos;
2426                         m_pVT->UpdateWordPlace(wpEnd);
2427                         pIterator->SetAt(wpBegin);
2428
2429                         CPVT_Line lineinfo;
2430                         do
2431                         {
2432                                 if (!pIterator->GetLine(lineinfo))break;
2433                                 if (lineinfo.lineplace.LineCmp(wpEnd) > 0)break;
2434
2435                                 CPDF_Rect rcLine(lineinfo.ptLine.x,
2436                                                                         lineinfo.ptLine.y + lineinfo.fLineDescent,
2437                                                                         lineinfo.ptLine.x + lineinfo.fLineWidth,
2438                                                                         lineinfo.ptLine.y + lineinfo.fLineAscent);
2439
2440                                 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace,lineinfo.lineEnd),VTToEdit(rcLine));
2441
2442                         }while (pIterator->NextLine());
2443                 }
2444         }
2445 }
2446
2447 void CFX_Edit::RefreshPushRandomRects(const CPVT_WordRange & wr)
2448 {
2449         if (m_pVT->IsValid())
2450         {
2451                 if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2452                 {
2453                         CPVT_WordRange wrTemp = wr;
2454
2455                         m_pVT->UpdateWordPlace(wrTemp.BeginPos);
2456                         m_pVT->UpdateWordPlace(wrTemp.EndPos);
2457                         pIterator->SetAt(wrTemp.BeginPos);
2458
2459                         CPVT_Word wordinfo;
2460                         CPVT_Line lineinfo;
2461                         CPVT_WordPlace place;
2462
2463                         while (pIterator->NextWord())
2464                         {
2465                                 place = pIterator->GetAt();
2466                                 if (place.WordCmp(wrTemp.EndPos) > 0) break;
2467
2468                                 pIterator->GetWord(wordinfo);
2469                                 pIterator->GetLine(lineinfo);
2470
2471                                 if (place.LineCmp(wrTemp.BeginPos) == 0 || place.LineCmp(wrTemp.EndPos) == 0)
2472                                 {
2473                                         CPDF_Rect rcWord(wordinfo.ptWord.x,
2474                                                                                 lineinfo.ptLine.y + lineinfo.fLineDescent,
2475                                                                                 wordinfo.ptWord.x + wordinfo.fWidth,
2476                                                                                 lineinfo.ptLine.y + lineinfo.fLineAscent);
2477
2478                                         m_Refresh.AddRefresh(VTToEdit(rcWord));
2479                                 }
2480                                 else
2481                                 {
2482                                         CPDF_Rect rcLine(lineinfo.ptLine.x,
2483                                                                                 lineinfo.ptLine.y + lineinfo.fLineDescent,
2484                                                                                 lineinfo.ptLine.x + lineinfo.fLineWidth,
2485                                                                                 lineinfo.ptLine.y + lineinfo.fLineAscent);
2486
2487                                         m_Refresh.AddRefresh(VTToEdit(rcLine));
2488
2489                                         pIterator->NextLine();
2490                                 }
2491                         }
2492                 }
2493         }
2494 }
2495
2496 void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr)
2497 {
2498         if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2499         {
2500                 CPVT_WordRange wrTemp = wr;
2501
2502                 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
2503                 m_pVT->UpdateWordPlace(wrTemp.EndPos);
2504                 pIterator->SetAt(wrTemp.BeginPos);
2505
2506                 CPVT_Word wordinfo;
2507                 CPVT_Line lineinfo;
2508                 CPVT_WordPlace place;
2509
2510                 while (pIterator->NextWord())
2511                 {
2512                         place = pIterator->GetAt();
2513                         if (place.WordCmp(wrTemp.EndPos) > 0) break;
2514
2515                         pIterator->GetWord(wordinfo);
2516                         pIterator->GetLine(lineinfo);
2517
2518                         if (place.LineCmp(wrTemp.BeginPos) == 0 || place.LineCmp(wrTemp.EndPos) == 0)
2519                         {
2520                                 CPDF_Rect rcWord(wordinfo.ptWord.x,
2521                                                                         lineinfo.ptLine.y + lineinfo.fLineDescent,
2522                                                                         wordinfo.ptWord.x + wordinfo.fWidth,
2523                                                                         lineinfo.ptLine.y + lineinfo.fLineAscent);
2524
2525                                 if (m_bNotify && m_pNotify)
2526                                 {
2527                                         if (!m_bNotifyFlag)
2528                                         {
2529                                                 m_bNotifyFlag = TRUE;
2530                                                 CPDF_Rect rcRefresh = VTToEdit(rcWord);
2531                                                 m_pNotify->IOnInvalidateRect(&rcRefresh);
2532                                                 m_bNotifyFlag = FALSE;
2533                                         }
2534                                 }
2535                         }
2536                         else
2537                         {
2538                                 CPDF_Rect rcLine(lineinfo.ptLine.x,
2539                                                                         lineinfo.ptLine.y + lineinfo.fLineDescent,
2540                                                                         lineinfo.ptLine.x + lineinfo.fLineWidth,
2541                                                                         lineinfo.ptLine.y + lineinfo.fLineAscent);
2542
2543                                 if (m_bNotify && m_pNotify)
2544                                 {
2545                                         if (!m_bNotifyFlag)
2546                                         {
2547                                                 m_bNotifyFlag = TRUE;
2548                                                 CPDF_Rect rcRefresh = VTToEdit(rcLine);
2549                                                 m_pNotify->IOnInvalidateRect(&rcRefresh);
2550                                                 m_bNotifyFlag = FALSE;
2551                                         }
2552                                 }
2553
2554                                 pIterator->NextLine();
2555                         }
2556                 }
2557         }
2558 }
2559
2560 void CFX_Edit::SetCaret(const CPVT_WordPlace & place)
2561 {
2562         m_wpOldCaret = m_wpCaret;
2563         m_wpCaret = place;
2564 }
2565
2566 void CFX_Edit::SetCaretInfo()
2567 {
2568         if (m_bNotify && m_pNotify)
2569         {
2570                 if (!m_bNotifyFlag)
2571                 {
2572                         CPDF_Point ptHead(0.0f,0.0f),ptFoot(0.0f,0.0f);
2573
2574                         if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2575                         {
2576                                 pIterator->SetAt(m_wpCaret);
2577                                 CPVT_Word word;
2578                                 CPVT_Line line;
2579                                 if (pIterator->GetWord(word))
2580                                 {
2581                                         ptHead.x = word.ptWord.x + word.fWidth;
2582                                         ptHead.y = word.ptWord.y + word.fAscent;
2583                                         ptFoot.x = word.ptWord.x + word.fWidth;
2584                                         ptFoot.y = word.ptWord.y + word.fDescent;
2585                                 }
2586                                 else if (pIterator->GetLine(line))
2587                                 {
2588                                         ptHead.x = line.ptLine.x;
2589                                         ptHead.y = line.ptLine.y + line.fLineAscent;
2590                                         ptFoot.x = line.ptLine.x;
2591                                         ptFoot.y = line.ptLine.y + line.fLineDescent;
2592                                 }
2593                         }
2594
2595                         m_bNotifyFlag = TRUE;
2596                         m_pNotify->IOnSetCaret(!m_SelState.IsExist(),VTToEdit(ptHead),VTToEdit(ptFoot), m_wpCaret);
2597                         m_bNotifyFlag = FALSE;
2598                 }
2599         }
2600
2601         SetCaretChange();
2602 }
2603
2604 void CFX_Edit::SetCaretChange()
2605 {
2606         if (m_wpCaret == m_wpOldCaret) return;
2607
2608         if (m_bNotify && m_pVT->IsRichText() && m_pNotify)
2609         {
2610                 CPVT_SecProps SecProps;
2611                 CPVT_WordProps WordProps;
2612
2613                 if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2614                 {
2615                         pIterator->SetAt(m_wpCaret);
2616                         CPVT_Word word;
2617                         CPVT_Section section;
2618
2619                         if (pIterator->GetSection(section))
2620                         {
2621                                 SecProps = section.SecProps;
2622                                 WordProps = section.WordProps;
2623                         }
2624
2625                         if (pIterator->GetWord(word))
2626                         {
2627                                 WordProps = word.WordProps;
2628                         }
2629                 }
2630
2631                 if (!m_bNotifyFlag)
2632                 {
2633                         m_bNotifyFlag = TRUE;
2634                         m_pNotify->IOnCaretChange(SecProps,WordProps);
2635                         m_bNotifyFlag = FALSE;
2636                 }
2637         }
2638 }
2639
2640 void CFX_Edit::SetCaret(int32_t nPos)
2641 {
2642         if (m_pVT->IsValid())
2643         {
2644                 SelectNone();
2645                 SetCaret(m_pVT->WordIndexToWordPlace(nPos));
2646                 m_SelState.Set(m_wpCaret,m_wpCaret);
2647
2648                 ScrollToCaret();
2649                 SetCaretOrigin();
2650                 SetCaretInfo();
2651         }
2652 }
2653
2654 void CFX_Edit::OnMouseDown(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)
2655 {
2656         if (m_pVT->IsValid())
2657         {
2658                 SelectNone();
2659                 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
2660                 m_SelState.Set(m_wpCaret,m_wpCaret);
2661
2662                 ScrollToCaret();
2663                 SetCaretOrigin();
2664                 SetCaretInfo();
2665         }
2666 }
2667
2668 void CFX_Edit::OnMouseMove(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)
2669 {
2670         if (m_pVT->IsValid())
2671         {
2672                 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
2673
2674                 if (m_wpCaret != m_wpOldCaret)
2675                 {
2676                         m_SelState.SetEndPos(m_wpCaret);
2677
2678                         ScrollToCaret();
2679                         CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2680                         Refresh(RP_OPTIONAL,&wr);
2681                         SetCaretOrigin();
2682                         SetCaretInfo();
2683                 }
2684         }
2685 }
2686
2687 void CFX_Edit::OnVK_UP(FX_BOOL bShift,FX_BOOL bCtrl)
2688 {
2689         if (m_pVT->IsValid())
2690         {
2691                 SetCaret(m_pVT->GetUpWordPlace(m_wpCaret,m_ptCaret));
2692
2693                 if (bShift)
2694                 {
2695                         if (m_SelState.IsExist())
2696                                 m_SelState.SetEndPos(m_wpCaret);
2697                         else
2698                                 m_SelState.Set(m_wpOldCaret,m_wpCaret);
2699
2700                         if (m_wpOldCaret != m_wpCaret)
2701                         {
2702                                 ScrollToCaret();
2703                                 CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
2704                                 Refresh(RP_OPTIONAL, &wr);
2705                                 SetCaretInfo();
2706                         }
2707                 }
2708                 else
2709                 {
2710                         SelectNone();
2711
2712                         ScrollToCaret();
2713                         SetCaretInfo();
2714                 }
2715         }
2716 }
2717
2718 void CFX_Edit::OnVK_DOWN(FX_BOOL bShift,FX_BOOL bCtrl)
2719 {
2720         if (m_pVT->IsValid())
2721         {
2722                 SetCaret(m_pVT->GetDownWordPlace(m_wpCaret,m_ptCaret));
2723
2724                 if (bShift)
2725                 {
2726                         if (m_SelState.IsExist())
2727                                 m_SelState.SetEndPos(m_wpCaret);
2728                         else
2729                                 m_SelState.Set(m_wpOldCaret,m_wpCaret);
2730
2731                         if (m_wpOldCaret != m_wpCaret)
2732                         {
2733                                 ScrollToCaret();
2734                                 CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2735                                 Refresh(RP_OPTIONAL, &wr);
2736                                 SetCaretInfo();
2737                         }
2738                 }
2739                 else
2740                 {
2741                         SelectNone();
2742
2743                         ScrollToCaret();
2744                         SetCaretInfo();
2745                 }
2746         }
2747 }
2748
2749 void CFX_Edit::OnVK_LEFT(FX_BOOL bShift,FX_BOOL bCtrl)
2750 {
2751         if (m_pVT->IsValid())
2752         {
2753                 if (bShift)
2754                 {
2755                         if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
2756                                 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
2757                                 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2758
2759                         SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2760
2761                         if (m_SelState.IsExist())
2762                                 m_SelState.SetEndPos(m_wpCaret);
2763                         else
2764                                 m_SelState.Set(m_wpOldCaret, m_wpCaret);
2765
2766                         if (m_wpOldCaret != m_wpCaret)
2767                         {
2768                                 ScrollToCaret();
2769                                 CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2770                                 Refresh(RP_OPTIONAL,&wr);
2771                                 SetCaretInfo();
2772                         }
2773                 }
2774                 else
2775                 {
2776                         if (m_SelState.IsExist())
2777                         {
2778                                 if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
2779                                         SetCaret(m_SelState.BeginPos);
2780                                 else
2781                                         SetCaret(m_SelState.EndPos);
2782
2783                                 SelectNone();
2784                                 ScrollToCaret();
2785                                 SetCaretInfo();
2786                         }
2787                         else
2788                         {
2789                                 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
2790                                         m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
2791                                         SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2792
2793                                 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2794
2795                                 ScrollToCaret();
2796                                 SetCaretOrigin();
2797                                 SetCaretInfo();
2798                         }
2799                 }
2800         }
2801 }
2802
2803 void CFX_Edit::OnVK_RIGHT(FX_BOOL bShift,FX_BOOL bCtrl)
2804 {
2805         if (m_pVT->IsValid())
2806         {
2807                 if (bShift)
2808                 {
2809                         SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2810
2811                         if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
2812                                 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
2813                                 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2814
2815                         if (m_SelState.IsExist())
2816                                 m_SelState.SetEndPos(m_wpCaret);
2817                         else
2818                                 m_SelState.Set(m_wpOldCaret,m_wpCaret);
2819
2820                         if (m_wpOldCaret != m_wpCaret)
2821                         {
2822                                 ScrollToCaret();
2823                                 CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2824                                 Refresh(RP_OPTIONAL,&wr);
2825                                 SetCaretInfo();
2826                         }
2827                 }
2828                 else
2829                 {
2830                         if (m_SelState.IsExist())
2831                         {
2832                                 if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)>0)
2833                                         SetCaret(m_SelState.BeginPos);
2834                                 else
2835                                         SetCaret(m_SelState.EndPos);
2836
2837                                 SelectNone();
2838                                 ScrollToCaret();
2839                                 SetCaretInfo();
2840                         }
2841                         else
2842                         {
2843                                 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2844
2845                                 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
2846                                         m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
2847                                         SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2848
2849                                 ScrollToCaret();
2850                                 SetCaretOrigin();
2851                                 SetCaretInfo();
2852                         }
2853                 }
2854         }
2855 }
2856
2857 void CFX_Edit::OnVK_HOME(FX_BOOL bShift,FX_BOOL bCtrl)
2858 {
2859         if (m_pVT->IsValid())
2860         {
2861                 if (bShift)
2862                 {
2863                         if (bCtrl)
2864                                 SetCaret(m_pVT->GetBeginWordPlace());
2865                         else
2866                                 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
2867
2868                         if (m_SelState.IsExist())
2869                                 m_SelState.SetEndPos(m_wpCaret);
2870                         else
2871                                 m_SelState.Set(m_wpOldCaret,m_wpCaret);
2872
2873                         ScrollToCaret();
2874                         CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
2875                         Refresh(RP_OPTIONAL, &wr);
2876                         SetCaretInfo();
2877                 }
2878                 else
2879                 {
2880                         if (m_SelState.IsExist())
2881                         {
2882                                 if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
2883                                         SetCaret(m_SelState.BeginPos);
2884                                 else
2885                                         SetCaret(m_SelState.EndPos);
2886
2887                                 SelectNone();
2888                                 ScrollToCaret();
2889                                 SetCaretInfo();
2890                         }
2891                         else
2892                         {
2893                                 if (bCtrl)
2894                                         SetCaret(m_pVT->GetBeginWordPlace());
2895                                 else
2896                                         SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
2897
2898                                 ScrollToCaret();
2899                                 SetCaretOrigin();
2900                                 SetCaretInfo();
2901                         }
2902                 }
2903         }
2904 }
2905
2906 void CFX_Edit::OnVK_END(FX_BOOL bShift,FX_BOOL bCtrl)
2907 {
2908         if (m_pVT->IsValid())
2909         {
2910                 if (bShift)
2911                 {
2912                         if (bCtrl)
2913                                 SetCaret(m_pVT->GetEndWordPlace());
2914                         else
2915                                 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
2916
2917                         if (m_SelState.IsExist())
2918                                 m_SelState.SetEndPos(m_wpCaret);
2919                         else
2920                                 m_SelState.Set(m_wpOldCaret, m_wpCaret);
2921
2922                         ScrollToCaret();
2923                         CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
2924                         Refresh(RP_OPTIONAL, &wr);
2925                         SetCaretInfo();
2926                 }
2927                 else
2928                 {
2929                         if (m_SelState.IsExist())
2930                         {
2931                                 if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)>0)
2932                                         SetCaret(m_SelState.BeginPos);
2933                                 else
2934                                         SetCaret(m_SelState.EndPos);
2935
2936                                 SelectNone();
2937                                 ScrollToCaret();
2938                                 SetCaretInfo();
2939                         }
2940                         else
2941                         {
2942                                 if (bCtrl)
2943                                         SetCaret(m_pVT->GetEndWordPlace());
2944                                 else
2945                                         SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
2946
2947                                 ScrollToCaret();
2948                                 SetCaretOrigin();
2949                                 SetCaretInfo();
2950                         }
2951                 }
2952         }
2953 }
2954
2955 void CFX_Edit::SetText(const FX_WCHAR* text,int32_t charset,
2956                                                 const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
2957 {
2958         Empty();
2959         DoInsertText(CPVT_WordPlace(0,0,-1), text, charset, pSecProps, pWordProps);
2960         if (bPaint) Paint();
2961         if (m_bOprNotify && m_pOprNotify)
2962                 m_pOprNotify->OnSetText(m_wpCaret, m_wpOldCaret);
2963         //if (bAddUndo)
2964 }
2965
2966 FX_BOOL CFX_Edit::InsertWord(FX_WORD word, int32_t charset, const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
2967 {
2968         if (IsTextOverflow()) return FALSE;
2969
2970         if (m_pVT->IsValid())
2971         {
2972                 m_pVT->UpdateWordPlace(m_wpCaret);
2973
2974                 SetCaret(m_pVT->InsertWord(m_wpCaret,word,GetCharSetFromUnicode(word, charset),pWordProps));
2975                 m_SelState.Set(m_wpCaret,m_wpCaret);
2976
2977                 if (m_wpCaret != m_wpOldCaret)
2978                 {
2979                         if (bAddUndo && m_bEnableUndo)
2980                         {
2981                                 AddEditUndoItem(new CFXEU_InsertWord(this,m_wpOldCaret,m_wpCaret,word,charset,pWordProps));
2982                         }
2983
2984                         if (bPaint)
2985                                 PaintInsertText(m_wpOldCaret, m_wpCaret);
2986
2987                         if (m_bOprNotify && m_pOprNotify)
2988                                 m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
2989
2990                         return TRUE;
2991                 }
2992         }
2993
2994         return FALSE;
2995 }
2996
2997 FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,
2998                                                            FX_BOOL bAddUndo, FX_BOOL bPaint)
2999 {
3000         if (IsTextOverflow()) return FALSE;
3001
3002         if (m_pVT->IsValid())
3003         {
3004                 m_pVT->UpdateWordPlace(m_wpCaret);
3005                 SetCaret(m_pVT->InsertSection(m_wpCaret,pSecProps,pWordProps));
3006                 m_SelState.Set(m_wpCaret,m_wpCaret);
3007
3008                 if (m_wpCaret != m_wpOldCaret)
3009                 {
3010                         if (bAddUndo && m_bEnableUndo)
3011                         {
3012                                 AddEditUndoItem(new CFXEU_InsertReturn(this,m_wpOldCaret,m_wpCaret,pSecProps,pWordProps));
3013                         }
3014
3015                         if (bPaint)
3016                         {
3017                                 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
3018                               &n