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