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