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