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