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/pdfwindow/PDFWindow.h" 8 #include "../../include/pdfwindow/PWL_Wnd.h" 9 #include "../../include/pdfwindow/PWL_EditCtrl.h" 10 #include "../../include/pdfwindow/PWL_Edit.h" 11 #include "../../include/pdfwindow/PWL_ScrollBar.h" 12 #include "../../include/pdfwindow/PWL_Utils.h" 13 #include "../../include/pdfwindow/PWL_Caret.h" 14 #include "../../include/pdfwindow/PWL_FontMap.h" 15 #include "../../../core/src/fxcrt/fx_safe_types.h" 16 17 /* ---------------------------- CPWL_Edit ------------------------------ */ 18 19 CPWL_Edit::CPWL_Edit() : m_pFillerNotify(NULL), 20 m_pSpellCheck(NULL), 21 m_bFocus(FALSE) 22 { 23 m_pFormFiller = NULL; 24 } 25 26 CPWL_Edit::~CPWL_Edit() 27 { 28 ASSERT(m_bFocus == FALSE); 29 } 30 31 CFX_ByteString CPWL_Edit::GetClassName() const 32 { 33 return PWL_CLASSNAME_EDIT; 34 } 35 36 void CPWL_Edit::OnDestroy() 37 { 38 } 39 40 void CPWL_Edit::SetText(FX_LPCWSTR csText) 41 { 42 CFX_WideString swText = csText; 43 44 if (HasFlag(PES_RICH)) 45 { 46 CFX_ByteString sValue = CFX_ByteString::FromUnicode(swText); 47 48 if (CXML_Element * pXML = CXML_Element::Parse(sValue.c_str(), sValue.GetLength())) 49 { 50 FX_INT32 nCount = pXML->CountChildren(); 51 FX_BOOL bFirst = TRUE; 52 53 swText.Empty(); 54 55 for (FX_INT32 i=0; i<nCount; i++) 56 { 57 if (CXML_Element * pSubElement = pXML->GetElement(i)) 58 { 59 CFX_ByteString tag=pSubElement->GetTagName(); 60 if (tag.EqualNoCase("p")) 61 { 62 int nChild = pSubElement->CountChildren(); 63 CFX_WideString swSection; 64 for(FX_INT32 j=0; j<nChild; j++) 65 { 66 swSection += pSubElement->GetContent(j); 67 } 68 69 if (bFirst)bFirst = FALSE; 70 else 71 swText += FWL_VKEY_Return; 72 swText += swSection; 73 } 74 } 75 } 76 77 delete pXML; 78 } 79 } 80 81 m_pEdit->SetText(swText.c_str()); 82 } 83 84 void CPWL_Edit::RePosChildWnd() 85 { 86 if (CPWL_ScrollBar * pVSB = this->GetVScrollBar()) 87 { 88 //if (pVSB->IsVisible()) 89 { 90 CPDF_Rect rcWindow = m_rcOldWindow; 91 CPDF_Rect rcVScroll = CPDF_Rect(rcWindow.right, 92 rcWindow.bottom, 93 rcWindow.right + PWL_SCROLLBAR_WIDTH, 94 rcWindow.top); 95 pVSB->Move(rcVScroll, TRUE, FALSE); 96 } 97 } 98 99 if (m_pEditCaret && !HasFlag(PES_TEXTOVERFLOW)) 100 m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(GetClientRect(),1.0f)); //+1 for caret beside border 101 102 CPWL_EditCtrl::RePosChildWnd(); 103 } 104 105 CPDF_Rect CPWL_Edit::GetClientRect() const 106 { 107 CPDF_Rect rcClient = CPWL_Utils::DeflateRect(GetWindowRect(),(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth())); 108 109 if (CPWL_ScrollBar * pVSB = this->GetVScrollBar()) 110 { 111 if (pVSB->IsVisible()) 112 { 113 rcClient.right -= PWL_SCROLLBAR_WIDTH; 114 } 115 } 116 117 return rcClient; 118 } 119 120 void CPWL_Edit::SetAlignFormatH(PWL_EDIT_ALIGNFORMAT_H nFormat, FX_BOOL bPaint/* = TRUE*/) 121 { 122 m_pEdit->SetAlignmentH((FX_INT32)nFormat, bPaint); 123 } 124 125 void CPWL_Edit::SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat, FX_BOOL bPaint/* = TRUE*/) 126 { 127 m_pEdit->SetAlignmentV((FX_INT32)nFormat, bPaint); 128 } 129 130 FX_BOOL CPWL_Edit::CanSelectAll() const 131 { 132 return GetSelectWordRange() != m_pEdit->GetWholeWordRange(); 133 } 134 135 FX_BOOL CPWL_Edit::CanClear() const 136 { 137 return !IsReadOnly() && m_pEdit->IsSelected(); 138 } 139 140 FX_BOOL CPWL_Edit::CanCopy() const 141 { 142 return !HasFlag(PES_PASSWORD) && !HasFlag(PES_NOREAD) && m_pEdit->IsSelected(); 143 } 144 145 FX_BOOL CPWL_Edit::CanCut() const 146 { 147 return CanCopy() && !IsReadOnly(); 148 } 149 150 FX_BOOL CPWL_Edit::CanPaste() const 151 { 152 if (IsReadOnly()) return FALSE; 153 154 CFX_WideString swClipboard; 155 if (IFX_SystemHandler* pSH = GetSystemHandler()) 156 swClipboard = pSH->GetClipboardText(GetAttachedHWnd()); 157 158 return !swClipboard.IsEmpty(); 159 } 160 161 void CPWL_Edit::CopyText() 162 { 163 if (!CanCopy()) return; 164 165 CFX_WideString str = m_pEdit->GetSelText(); 166 167 if (IFX_SystemHandler* pSH = GetSystemHandler()) 168 pSH->SetClipboardText(GetAttachedHWnd(), str); 169 } 170 171 void CPWL_Edit::PasteText() 172 { 173 if (!CanPaste()) return; 174 175 CFX_WideString swClipboard; 176 if (IFX_SystemHandler* pSH = GetSystemHandler()) 177 swClipboard = pSH->GetClipboardText(GetAttachedHWnd()); 178 179 if (m_pFillerNotify) 180 { 181 FX_BOOL bRC = TRUE; 182 FX_BOOL bExit = FALSE; 183 CFX_WideString strChangeEx; 184 int nSelStart = 0; 185 int nSelEnd = 0; 186 GetSel(nSelStart, nSelEnd); 187 m_pFillerNotify->OnBeforeKeyStroke(TRUE, GetAttachedData(), 0 , swClipboard, strChangeEx, nSelStart, nSelEnd, TRUE, bRC, bExit, 0); 188 if (!bRC) return; 189 if (bExit) return; 190 } 191 192 if (swClipboard.GetLength() > 0) 193 { 194 Clear(); 195 InsertText(swClipboard.c_str()); 196 } 197 198 if (m_pFillerNotify) 199 { 200 FX_BOOL bExit = FALSE; 201 m_pFillerNotify->OnAfterKeyStroke(TRUE, GetAttachedData(), bExit,0); 202 if (bExit) return; 203 } 204 } 205 206 void CPWL_Edit::CutText() 207 { 208 if (!CanCut()) return; 209 210 CFX_WideString str = m_pEdit->GetSelText(); 211 212 if (IFX_SystemHandler* pSH = GetSystemHandler()) 213 pSH->SetClipboardText(GetAttachedHWnd(), str); 214 215 m_pEdit->Clear(); 216 } 217 218 void CPWL_Edit::OnCreated() 219 { 220 CPWL_EditCtrl::OnCreated(); 221 222 if (CPWL_ScrollBar * pScroll = GetVScrollBar()) 223 { 224 pScroll->RemoveFlag(PWS_AUTOTRANSPARENT); 225 pScroll->SetTransparency(255); 226 } 227 228 SetParamByFlag(); 229 230 m_rcOldWindow = GetWindowRect(); 231 232 m_pEdit->SetOprNotify(this); 233 m_pEdit->EnableOprNotify(TRUE); 234 } 235 236 void CPWL_Edit::SetParamByFlag() 237 { 238 if (HasFlag(PES_RIGHT)) 239 { 240 m_pEdit->SetAlignmentH(2, FALSE); 241 } 242 else if (HasFlag(PES_MIDDLE)) 243 { 244 m_pEdit->SetAlignmentH(1, FALSE); 245 } 246 else 247 { 248 m_pEdit->SetAlignmentH(0, FALSE); 249 } 250 251 if (HasFlag(PES_BOTTOM)) 252 { 253 m_pEdit->SetAlignmentV(2, FALSE); 254 } 255 else if (HasFlag(PES_CENTER)) 256 { 257 m_pEdit->SetAlignmentV(1, FALSE); 258 } 259 else 260 { 261 m_pEdit->SetAlignmentV(0, FALSE); 262 } 263 264 if (HasFlag(PES_PASSWORD)) 265 { 266 m_pEdit->SetPasswordChar('*', FALSE); 267 } 268 269 m_pEdit->SetMultiLine(HasFlag(PES_MULTILINE), FALSE); 270 m_pEdit->SetAutoReturn(HasFlag(PES_AUTORETURN), FALSE); 271 m_pEdit->SetAutoFontSize(HasFlag(PWS_AUTOFONTSIZE), FALSE); 272 m_pEdit->SetAutoScroll(HasFlag(PES_AUTOSCROLL), FALSE); 273 m_pEdit->EnableUndo(HasFlag(PES_UNDO)); 274 275 if (HasFlag(PES_TEXTOVERFLOW)) 276 { 277 SetClipRect(CPDF_Rect(0.0f,0.0f,0.0f,0.0f)); 278 m_pEdit->SetTextOverflow(TRUE, FALSE); 279 } 280 else 281 { 282 if (m_pEditCaret) 283 { 284 m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(GetClientRect(),1.0f)); //+1 for caret beside border 285 } 286 } 287 288 if (HasFlag(PES_SPELLCHECK)) 289 { 290 m_pSpellCheck = GetCreationParam().pSpellCheck; 291 } 292 } 293 294 void CPWL_Edit::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream) 295 { 296 CPWL_Wnd::GetThisAppearanceStream(sAppStream); 297 298 CPDF_Rect rcClient = GetClientRect(); 299 CFX_ByteTextBuf sLine; 300 301 FX_INT32 nCharArray = m_pEdit->GetCharArray(); 302 303 if (nCharArray > 0) 304 { 305 switch (GetBorderStyle()) 306 { 307 case PBS_SOLID: 308 { 309 sLine << "q\n" << GetBorderWidth() << " w\n" 310 << CPWL_Utils::GetColorAppStream(GetBorderColor(),FALSE) << " 2 J 0 j\n"; 311 312 for (FX_INT32 i=1;i<nCharArray;i++) 313 { 314 sLine << rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*i << " " 315 << rcClient.bottom << " m\n" 316 << rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*i << " " 317 << rcClient.top << " l S\n"; 318 } 319 320 sLine << "Q\n"; 321 } 322 break; 323 case PBS_DASH: 324 { 325 sLine << "q\n" << GetBorderWidth() << " w\n" 326 << CPWL_Utils::GetColorAppStream(GetBorderColor(),FALSE) << " 2 J 0 j\n" 327 << "[" << GetBorderDash().nDash << " " 328 << GetBorderDash().nGap << "] " 329 << GetBorderDash().nPhase << " d\n"; 330 331 for (FX_INT32 i=1;i<nCharArray;i++) 332 { 333 sLine << rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*i << " " 334 << rcClient.bottom << " m\n" 335 << rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*i << " " 336 << rcClient.top << " l S\n"; 337 } 338 339 sLine << "Q\n"; 340 } 341 break; 342 } 343 } 344 345 sAppStream << sLine; 346 347 CFX_ByteTextBuf sText; 348 349 CPDF_Point ptOffset = CPDF_Point(0.0f,0.0f); 350 351 CPVT_WordRange wrWhole = m_pEdit->GetWholeWordRange(); 352 CPVT_WordRange wrSelect = GetSelectWordRange(); 353 CPVT_WordRange wrVisible = (HasFlag(PES_TEXTOVERFLOW) ? wrWhole : m_pEdit->GetVisibleWordRange()); 354 CPVT_WordRange wrSelBefore(wrWhole.BeginPos,wrSelect.BeginPos); 355 CPVT_WordRange wrSelAfter(wrSelect.EndPos,wrWhole.EndPos); 356 357 CPVT_WordRange wrTemp = CPWL_Utils::OverlapWordRange(GetSelectWordRange(),wrVisible); 358 CFX_ByteString sEditSel = CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset, 359 &wrTemp); 360 361 if (sEditSel.GetLength() > 0) 362 sText << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELBACKCOLOR) << sEditSel ; 363 364 wrTemp = CPWL_Utils::OverlapWordRange(wrVisible,wrSelBefore); 365 CFX_ByteString sEditBefore = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset, 366 &wrTemp, !HasFlag(PES_CHARARRAY), m_pEdit->GetPasswordChar()); 367 368 if (sEditBefore.GetLength() > 0) 369 sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEditBefore << "ET\n"; 370 371 wrTemp = CPWL_Utils::OverlapWordRange(wrVisible,wrSelect); 372 CFX_ByteString sEditMid = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset, 373 &wrTemp, !HasFlag(PES_CHARARRAY), m_pEdit->GetPasswordChar()); 374 375 if (sEditMid.GetLength() > 0) 376 sText << "BT\n" << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY,1)) << sEditMid << "ET\n"; 377 378 wrTemp = CPWL_Utils::OverlapWordRange(wrVisible,wrSelAfter); 379 CFX_ByteString sEditAfter = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset, 380 &wrTemp, !HasFlag(PES_CHARARRAY), m_pEdit->GetPasswordChar()); 381 382 if (sEditAfter.GetLength() > 0) 383 sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEditAfter<< "ET\n"; 384 385 if (HasFlag(PES_SPELLCHECK)) 386 { 387 CFX_ByteString sSpellCheck = CPWL_Utils::GetSpellCheckAppStream(m_pEdit, m_pSpellCheck, ptOffset, &wrVisible); 388 if (sSpellCheck.GetLength() > 0) 389 sText << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_RGB,1,0,0),FALSE) << sSpellCheck; 390 } 391 392 if (sText.GetLength() > 0) 393 { 394 CPDF_Rect rcClient = this->GetClientRect(); 395 sAppStream << "q\n/Tx BMC\n"; 396 397 if (!HasFlag(PES_TEXTOVERFLOW)) 398 sAppStream << rcClient.left << " " << rcClient.bottom << " " 399 << rcClient.right - rcClient.left << " " << rcClient.top - rcClient.bottom << " re W n\n"; 400 401 sAppStream << sText; 402 403 sAppStream << "EMC\nQ\n"; 404 } 405 } 406 407 void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device) 408 { 409 CPWL_Wnd::DrawThisAppearance(pDevice,pUser2Device); 410 411 CPDF_Rect rcClient = GetClientRect(); 412 CFX_ByteTextBuf sLine; 413 414 FX_INT32 nCharArray = m_pEdit->GetCharArray(); 415 FX_SAFE_INT32 nCharArraySafe = nCharArray; 416 nCharArraySafe -= 1; 417 nCharArraySafe *= 2; 418 419 if (nCharArray > 0 && nCharArraySafe.IsValid()) 420 { 421 switch (GetBorderStyle()) 422 { 423 case PBS_SOLID: 424 { 425 CFX_GraphStateData gsd; 426 gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth(); 427 428 CFX_PathData path; 429 path.SetPointCount(nCharArraySafe.ValueOrDie()); 430 431 for (FX_INT32 i=0; i<nCharArray-1; i++) 432 { 433 path.SetPoint(i*2, rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*(i+1), 434 rcClient.bottom, FXPT_MOVETO); 435 path.SetPoint(i*2+1, rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*(i+1), 436 rcClient.top, FXPT_LINETO); 437 } 438 if (path.GetPointCount() > 0) 439 pDevice->DrawPath(&path, pUser2Device, &gsd,0, 440 CPWL_Utils::PWLColorToFXColor(GetBorderColor(),255), FXFILL_ALTERNATE); 441 } 442 break; 443 case PBS_DASH: 444 { 445 CFX_GraphStateData gsd; 446 gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth(); 447 448 gsd.SetDashCount(2); 449 gsd.m_DashArray[0] = (FX_FLOAT)GetBorderDash().nDash; 450 gsd.m_DashArray[1] = (FX_FLOAT)GetBorderDash().nGap; 451 gsd.m_DashPhase = (FX_FLOAT)GetBorderDash().nPhase; 452 453 CFX_PathData path; 454 path.SetPointCount(nCharArraySafe.ValueOrDie()); 455 456 for (FX_INT32 i=0; i<nCharArray-1; i++) 457 { 458 path.SetPoint(i*2, rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*(i+1), 459 rcClient.bottom, FXPT_MOVETO); 460 path.SetPoint(i*2+1, rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*(i+1), 461 rcClient.top, FXPT_LINETO); 462 } 463 if (path.GetPointCount() > 0) 464 pDevice->DrawPath(&path, pUser2Device, &gsd,0, 465 CPWL_Utils::PWLColorToFXColor(GetBorderColor(),255), FXFILL_ALTERNATE); 466 } 467 break; 468 } 469 } 470 471 CPDF_Rect rcClip; 472 CPVT_WordRange wrRange = m_pEdit->GetVisibleWordRange(); 473 CPVT_WordRange* pRange = NULL; 474 475 if (!HasFlag(PES_TEXTOVERFLOW)) 476 { 477 rcClip = GetClientRect(); 478 pRange = &wrRange; 479 } 480 IFX_SystemHandler* pSysHandler = GetSystemHandler(); 481 IFX_Edit::DrawEdit(pDevice,pUser2Device,m_pEdit, 482 CPWL_Utils::PWLColorToFXColor(GetTextColor(),this->GetTransparency()), 483 CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(),this->GetTransparency()), 484 rcClip,CPDF_Point(0.0f,0.0f),pRange, pSysHandler, m_pFormFiller); 485 486 if (HasFlag(PES_SPELLCHECK)) 487 { 488 CPWL_Utils::DrawEditSpellCheck(pDevice,pUser2Device,m_pEdit,rcClip, 489 CPDF_Point(0.0f,0.0f),pRange, this->GetCreationParam().pSpellCheck); 490 } 491 } 492 493 FX_BOOL CPWL_Edit::OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag) 494 { 495 CPWL_Wnd::OnLButtonDown(point,nFlag); 496 497 if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) 498 { 499 if (m_bMouseDown) 500 this->InvalidateRect(); 501 502 m_bMouseDown = TRUE; 503 SetCapture(); 504 505 m_pEdit->OnMouseDown(point,IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag)); 506 } 507 508 return TRUE; 509 } 510 511 FX_BOOL CPWL_Edit::OnLButtonDblClk(const CPDF_Point & point, FX_DWORD nFlag) 512 { 513 CPWL_Wnd::OnLButtonDblClk(point, nFlag); 514 515 if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) 516 { 517 m_pEdit->SelectAll(); 518 } 519 520 return TRUE; 521 } 522 523 #define WM_PWLEDIT_UNDO 0x01 524 #define WM_PWLEDIT_REDO 0x02 525 #define WM_PWLEDIT_CUT 0x03 526 #define WM_PWLEDIT_COPY 0x04 527 #define WM_PWLEDIT_PASTE 0x05 528 #define WM_PWLEDIT_DELETE 0x06 529 #define WM_PWLEDIT_SELECTALL 0x07 530 #define WM_PWLEDIT_SUGGEST 0x08 531 532 FX_BOOL CPWL_Edit::OnRButtonUp(const CPDF_Point & point, FX_DWORD nFlag) 533 { 534 if (m_bMouseDown) return FALSE; 535 536 CPWL_Wnd::OnRButtonUp(point, nFlag); 537 538 if (!HasFlag(PES_TEXTOVERFLOW) && !ClientHitTest(point)) return TRUE; 539 540 IFX_SystemHandler* pSH = GetSystemHandler(); 541 if (!pSH) return FALSE; 542 543 this->SetFocus(); 544 545 CPVT_WordRange wrLatin = GetLatinWordsRange(point); 546 CFX_WideString swLatin = m_pEdit->GetRangeText(wrLatin); 547 548 FX_HMENU hPopup = pSH->CreatePopupMenu(); 549 if (!hPopup) return FALSE; 550 551 CFX_ByteStringArray sSuggestWords; 552 CPDF_Point ptPopup = point; 553 554 if (!IsReadOnly()) 555 { 556 if (HasFlag(PES_SPELLCHECK) && !swLatin.IsEmpty()) 557 { 558 if (m_pSpellCheck) 559 { 560 CFX_ByteString sLatin = CFX_ByteString::FromUnicode(swLatin); 561 562 if (!m_pSpellCheck->CheckWord(sLatin)) 563 { 564 m_pSpellCheck->SuggestWords(sLatin,sSuggestWords); 565 566 FX_INT32 nSuggest = sSuggestWords.GetSize(); 567 568 for (FX_INT32 nWord=0; nWord<nSuggest; nWord++) 569 { 570 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_SUGGEST+nWord, sSuggestWords[nWord].UTF8Decode()); 571 } 572 573 if (nSuggest > 0) 574 pSH->AppendMenuItem(hPopup, 0, L""); 575 576 ptPopup = GetWordRightBottomPoint(wrLatin.EndPos); 577 } 578 } 579 } 580 } 581 582 IPWL_Provider* pProvider = this->GetProvider(); 583 584 if (HasFlag(PES_UNDO)) 585 { 586 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_UNDO, 587 pProvider ? pProvider->LoadPopupMenuString(0) : L"&Undo"); 588 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_REDO, 589 pProvider ? pProvider->LoadPopupMenuString(1) : L"&Redo"); 590 pSH->AppendMenuItem(hPopup, 0, L""); 591 592 if (!m_pEdit->CanUndo()) 593 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_UNDO, FALSE); 594 if (!m_pEdit->CanRedo()) 595 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_REDO, FALSE); 596 } 597 598 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_CUT, 599 pProvider ? pProvider->LoadPopupMenuString(2) : L"Cu&t"); 600 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_COPY, 601 pProvider ? pProvider->LoadPopupMenuString(3) : L"&Copy"); 602 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_PASTE, 603 pProvider ? pProvider->LoadPopupMenuString(4) : L"&Paste"); 604 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_DELETE, 605 pProvider ? pProvider->LoadPopupMenuString(5) : L"&Delete"); 606 607 CFX_WideString swText = pSH->GetClipboardText(this->GetAttachedHWnd()); 608 if (swText.IsEmpty()) 609 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE); 610 611 if (!m_pEdit->IsSelected()) 612 { 613 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE); 614 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE); 615 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE); 616 } 617 618 if (IsReadOnly()) 619 { 620 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE); 621 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE); 622 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE); 623 } 624 625 if (HasFlag(PES_PASSWORD)) 626 { 627 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE); 628 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE); 629 } 630 631 if (HasFlag(PES_NOREAD)) 632 { 633 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE); 634 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE); 635 } 636 637 pSH->AppendMenuItem(hPopup, 0, L""); 638 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_SELECTALL, 639 pProvider ? pProvider->LoadPopupMenuString(6) : L"&Select All"); 640 641 if (m_pEdit->GetTotalWords() == 0) 642 { 643 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_SELECTALL, FALSE); 644 } 645 646 FX_INT32 x, y; 647 PWLtoWnd(ptPopup, x, y); 648 pSH->ClientToScreen(GetAttachedHWnd(), x, y); 649 pSH->SetCursor(FXCT_ARROW); 650 FX_INT32 nCmd = pSH->TrackPopupMenu(hPopup, 651 x, 652 y, 653 GetAttachedHWnd()); 654 655 656 switch (nCmd) 657 { 658 case WM_PWLEDIT_UNDO: 659 Undo(); 660 break; 661 case WM_PWLEDIT_REDO: 662 Redo(); 663 break; 664 case WM_PWLEDIT_CUT: 665 this->CutText(); 666 break; 667 case WM_PWLEDIT_COPY: 668 this->CopyText(); 669 break; 670 case WM_PWLEDIT_PASTE: 671 this->PasteText(); 672 break; 673 case WM_PWLEDIT_DELETE: 674 this->Clear(); 675 break; 676 case WM_PWLEDIT_SELECTALL: 677 this->SelectAll(); 678 break; 679 case WM_PWLEDIT_SUGGEST + 0: 680 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos)); 681 ReplaceSel(sSuggestWords[0].UTF8Decode().c_str()); 682 break; 683 case WM_PWLEDIT_SUGGEST + 1: 684 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos)); 685 ReplaceSel(sSuggestWords[1].UTF8Decode().c_str()); 686 break; 687 case WM_PWLEDIT_SUGGEST + 2: 688 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos)); 689 ReplaceSel(sSuggestWords[2].UTF8Decode().c_str()); 690 break; 691 case WM_PWLEDIT_SUGGEST + 3: 692 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos)); 693 ReplaceSel(sSuggestWords[3].UTF8Decode().c_str()); 694 break; 695 case WM_PWLEDIT_SUGGEST + 4: 696 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos)); 697 ReplaceSel(sSuggestWords[4].UTF8Decode().c_str()); 698 break; 699 default: 700 break; 701 } 702 703 pSH->DestroyMenu(hPopup); 704 705 return TRUE; 706 } 707 708 void CPWL_Edit::OnSetFocus() 709 { 710 SetEditCaret(TRUE); 711 712 if (!IsReadOnly()) 713 { 714 if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler()) 715 pFocusHandler->OnSetFocus(this); 716 } 717 718 m_bFocus = TRUE; 719 } 720 721 void CPWL_Edit::OnKillFocus() 722 { 723 ShowVScrollBar(FALSE); 724 725 m_pEdit->SelectNone(); 726 SetCaret(FALSE, CPDF_Point(0.0f,0.0f), CPDF_Point(0.0f,0.0f)); 727 728 SetCharSet(0); 729 730 if (!IsReadOnly()) 731 { 732 if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler()) 733 pFocusHandler->OnKillFocus(this); 734 } 735 736 m_bFocus = FALSE; 737 } 738 739 void CPWL_Edit::SetHorzScale(FX_INT32 nHorzScale, FX_BOOL bPaint/* = TRUE*/) 740 { 741 m_pEdit->SetHorzScale(nHorzScale, bPaint); 742 } 743 744 void CPWL_Edit::SetCharSpace(FX_FLOAT fCharSpace, FX_BOOL bPaint/* = TRUE*/) 745 { 746 m_pEdit->SetCharSpace(fCharSpace, bPaint); 747 } 748 749 void CPWL_Edit::SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint/* = TRUE*/) 750 { 751 m_pEdit->SetLineLeading(fLineLeading, bPaint); 752 } 753 754 CFX_ByteString CPWL_Edit::GetSelectAppearanceStream(const CPDF_Point & ptOffset) const 755 { 756 CPVT_WordRange wr = GetSelectWordRange(); 757 return CPWL_Utils::GetEditSelAppStream(m_pEdit,ptOffset,&wr); 758 } 759 760 CPVT_WordRange CPWL_Edit::GetSelectWordRange() const 761 { 762 if (m_pEdit->IsSelected()) 763 { 764 FX_INT32 nStart = -1; 765 FX_INT32 nEnd = -1; 766 767 m_pEdit->GetSel(nStart, nEnd); 768 769 CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStart); 770 CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEnd); 771 772 return CPVT_WordRange(wpStart,wpEnd); 773 } 774 775 return CPVT_WordRange(); 776 } 777 778 CFX_ByteString CPWL_Edit::GetTextAppearanceStream(const CPDF_Point & ptOffset) const 779 { 780 CFX_ByteTextBuf sRet; 781 CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit,ptOffset); 782 783 if (sEdit.GetLength() > 0) 784 { 785 sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEdit << "ET\n"; 786 } 787 788 return sRet.GetByteString(); 789 } 790 791 CFX_ByteString CPWL_Edit::GetCaretAppearanceStream(const CPDF_Point & ptOffset) const 792 { 793 if (m_pEditCaret) 794 return m_pEditCaret->GetCaretAppearanceStream(ptOffset); 795 796 return CFX_ByteString(); 797 } 798 799 CPDF_Point CPWL_Edit::GetWordRightBottomPoint(const CPVT_WordPlace& wpWord) 800 { 801 CPDF_Point pt(0.0f, 0.0f); 802 803 if (IFX_Edit_Iterator * pIterator = m_pEdit->GetIterator()) 804 { 805 CPVT_WordPlace wpOld = pIterator->GetAt(); 806 pIterator->SetAt(wpWord); 807 CPVT_Word word; 808 if (pIterator->GetWord(word)) 809 { 810 pt = CPDF_Point(word.ptWord.x + word.fWidth, word.ptWord.y + word.fDescent); 811 } 812 813 pIterator->SetAt(wpOld); 814 } 815 816 return pt; 817 } 818 819 FX_BOOL CPWL_Edit::IsTextFull() const 820 { 821 return m_pEdit->IsTextFull(); 822 } 823 824 FX_FLOAT CPWL_Edit::GetCharArrayAutoFontSize(CPDF_Font* pFont, const CPDF_Rect& rcPlate, FX_INT32 nCharArray) 825 { 826 if (pFont && !pFont->IsStandardFont()) 827 { 828 FX_RECT rcBBox; 829 pFont->GetFontBBox(rcBBox); 830 831 CPDF_Rect rcCell = rcPlate; 832 FX_FLOAT xdiv = rcCell.Width() / nCharArray * 1000.0f / rcBBox.Width(); 833 FX_FLOAT ydiv = - rcCell.Height() * 1000.0f / rcBBox.Height(); 834 835 return xdiv < ydiv ? xdiv : ydiv; 836 } 837 838 return 0.0f; 839 } 840 841 void CPWL_Edit::SetCharArray(FX_INT32 nCharArray) 842 { 843 if (HasFlag(PES_CHARARRAY) && nCharArray > 0) 844 { 845 m_pEdit->SetCharArray(nCharArray); 846 m_pEdit->SetTextOverflow(TRUE); 847 848 if (HasFlag(PWS_AUTOFONTSIZE)) 849 { 850 if (IFX_Edit_FontMap* pFontMap = this->GetFontMap()) 851 { 852 FX_FLOAT fFontSize = GetCharArrayAutoFontSize(pFontMap->GetPDFFont(0), GetClientRect(), nCharArray); 853 if (fFontSize > 0.0f) 854 { 855 m_pEdit->SetAutoFontSize(FALSE); 856 m_pEdit->SetFontSize(fFontSize); 857 } 858 } 859 } 860 } 861 } 862 863 void CPWL_Edit::SetLimitChar(FX_INT32 nLimitChar) 864 { 865 m_pEdit->SetLimitChar(nLimitChar); 866 } 867 868 void CPWL_Edit::ReplaceSel(FX_LPCWSTR csText) 869 { 870 m_pEdit->Clear(); 871 m_pEdit->InsertText(csText); 872 } 873 874 CPDF_Rect CPWL_Edit::GetFocusRect() const 875 { 876 return CPDF_Rect(); 877 } 878 879 void CPWL_Edit::ShowVScrollBar(FX_BOOL bShow) 880 { 881 if (CPWL_ScrollBar * pScroll = GetVScrollBar()) 882 { 883 if (bShow) 884 { 885 if (!pScroll->IsVisible()) 886 { 887 pScroll->SetVisible(TRUE); 888 CPDF_Rect rcWindow = GetWindowRect(); 889 m_rcOldWindow = rcWindow; 890 rcWindow.right += PWL_SCROLLBAR_WIDTH; 891 Move(rcWindow, TRUE, TRUE); 892 } 893 } 894 else 895 { 896 if (pScroll->IsVisible()) 897 { 898 pScroll->SetVisible(FALSE); 899 Move(m_rcOldWindow, TRUE, TRUE); 900 } 901 } 902 } 903 } 904 905 FX_BOOL CPWL_Edit::IsVScrollBarVisible() const 906 { 907 if (CPWL_ScrollBar * pScroll = GetVScrollBar()) 908 { 909 return pScroll->IsVisible(); 910 } 911 912 return FALSE; 913 } 914 915 void CPWL_Edit::EnableSpellCheck(FX_BOOL bEnabled) 916 { 917 if (bEnabled) 918 AddFlag(PES_SPELLCHECK); 919 else 920 RemoveFlag(PES_SPELLCHECK); 921 } 922 923 FX_BOOL CPWL_Edit::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) 924 { 925 if (m_bMouseDown) return TRUE; 926 927 if (nChar == FWL_VKEY_Delete) 928 { 929 if (m_pFillerNotify) 930 { 931 FX_BOOL bRC = TRUE; 932 FX_BOOL bExit = FALSE; 933 CFX_WideString strChange; 934 CFX_WideString strChangeEx; 935 936 int nSelStart = 0; 937 int nSelEnd = 0; 938 GetSel(nSelStart, nSelEnd); 939 940 if (nSelStart == nSelEnd) 941 nSelEnd = nSelStart + 1; 942 m_pFillerNotify->OnBeforeKeyStroke(TRUE, GetAttachedData(), FWL_VKEY_Delete, strChange, strChangeEx, nSelStart, nSelEnd, TRUE, bRC, bExit, nFlag); 943 if (!bRC) return FALSE; 944 if (bExit) return FALSE; 945 } 946 } 947 948 FX_BOOL bRet = CPWL_EditCtrl::OnKeyDown(nChar, nFlag); 949 950 if (nChar == FWL_VKEY_Delete) 951 { 952 if (m_pFillerNotify) 953 { 954 FX_BOOL bExit = FALSE; 955 m_pFillerNotify->OnAfterKeyStroke(TRUE, GetAttachedData(), bExit,nFlag); 956 if (bExit) return FALSE; 957 } 958 } 959 960 //In case of implementation swallow the OnKeyDown event. 961 if(IsProceedtoOnChar(nChar, nFlag)) 962 return TRUE; 963 964 return bRet; 965 } 966 967 /** 968 *In case of implementation swallow the OnKeyDown event. 969 *If the event is swallowed, implementation may do other unexpected things, which is not the control means to do. 970 */ 971 FX_BOOL CPWL_Edit::IsProceedtoOnChar(FX_WORD nKeyCode, FX_DWORD nFlag) 972 { 973 974 FX_BOOL bCtrl = IsCTRLpressed(nFlag); 975 FX_BOOL bAlt = IsALTpressed(nFlag); 976 if(bCtrl && !bAlt) 977 { 978 //hot keys for edit control. 979 switch(nKeyCode) 980 { 981 case 'C': 982 case 'V': 983 case 'X': 984 case 'A': 985 case 'Z': 986 return TRUE; 987 default: 988 break; 989 } 990 } 991 //control characters. 992 switch(nKeyCode) 993 { 994 case FWL_VKEY_Escape: 995 case FWL_VKEY_Back: 996 case FWL_VKEY_Return: 997 case FWL_VKEY_Space: 998 return TRUE; 999 default: 1000 break; 1001 } 1002 return FALSE; 1003 1004 } 1005 1006 FX_BOOL CPWL_Edit::OnChar(FX_WORD nChar, FX_DWORD nFlag) 1007 { 1008 if (m_bMouseDown) return TRUE; 1009 1010 FX_BOOL bRC = TRUE; 1011 FX_BOOL bExit = FALSE; 1012 1013 FX_BOOL bCtrl = IsCTRLpressed(nFlag); 1014 if (!bCtrl) 1015 { 1016 if (m_pFillerNotify) 1017 { 1018 CFX_WideString swChange; 1019 FX_INT32 nKeyCode; 1020 1021 int nSelStart = 0; 1022 int nSelEnd = 0; 1023 GetSel(nSelStart, nSelEnd); 1024 1025 switch (nChar) 1026 { 1027 case FWL_VKEY_Back: 1028 nKeyCode = nChar; 1029 if (nSelStart == nSelEnd) 1030 nSelStart = nSelEnd - 1; 1031 break; 1032 case FWL_VKEY_Return: 1033 nKeyCode = nChar; 1034 break; 1035 default: 1036 nKeyCode = 0; 1037 swChange += nChar; 1038 break; 1039 } 1040 1041 CFX_WideString strChangeEx; 1042 m_pFillerNotify->OnBeforeKeyStroke(TRUE, GetAttachedData(), nKeyCode, swChange, strChangeEx, nSelStart, nSelEnd, TRUE, bRC, bExit, nFlag); 1043 } 1044 } 1045 1046 if (!bRC) return TRUE; 1047 if (bExit) return FALSE; 1048 1049 if (IFX_Edit_FontMap * pFontMap = GetFontMap()) 1050 { 1051 FX_INT32 nOldCharSet = GetCharSet(); 1052 FX_INT32 nNewCharSet = pFontMap->CharSetFromUnicode(nChar, DEFAULT_CHARSET); 1053 if(nOldCharSet != nNewCharSet) 1054 { 1055 SetCharSet(nNewCharSet); 1056 } 1057 } 1058 FX_BOOL bRet = CPWL_EditCtrl::OnChar(nChar,nFlag); 1059 1060 if (!bCtrl) 1061 { 1062 if (m_pFillerNotify) 1063 { 1064 m_pFillerNotify->OnAfterKeyStroke(TRUE, GetAttachedData(), bExit,nFlag); 1065 if (bExit) return FALSE; 1066 } 1067 } 1068 1069 return bRet; 1070 } 1071 1072 FX_BOOL CPWL_Edit::OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag) 1073 { 1074 if (HasFlag(PES_MULTILINE)) 1075 { 1076 CPDF_Point ptScroll = GetScrollPos(); 1077 1078 if (zDelta > 0) 1079 { 1080 ptScroll.y += this->GetFontSize(); 1081 } 1082 else 1083 { 1084 ptScroll.y -= this->GetFontSize(); 1085 } 1086 this->SetScrollPos(ptScroll); 1087 1088 return TRUE; 1089 } 1090 1091 return FALSE; 1092 } 1093 1094 void CPWL_Edit::OnInsertReturn(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace) 1095 { 1096 if (HasFlag(PES_SPELLCHECK)) 1097 { 1098 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place))); 1099 } 1100 1101 if (m_pEditNotify) 1102 { 1103 m_pEditNotify->OnInsertReturn(place, oldplace); 1104 } 1105 } 1106 1107 void CPWL_Edit::OnBackSpace(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace) 1108 { 1109 if (HasFlag(PES_SPELLCHECK)) 1110 { 1111 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place))); 1112 } 1113 1114 if (m_pEditNotify) 1115 { 1116 m_pEditNotify->OnBackSpace(place, oldplace); 1117 } 1118 } 1119 1120 void CPWL_Edit::OnDelete(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace) 1121 { 1122 if (HasFlag(PES_SPELLCHECK)) 1123 { 1124 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place))); 1125 } 1126 1127 if (m_pEditNotify) 1128 { 1129 m_pEditNotify->OnDelete(place, oldplace); 1130 } 1131 } 1132 1133 void CPWL_Edit::OnClear(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace) 1134 { 1135 if (HasFlag(PES_SPELLCHECK)) 1136 { 1137 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place))); 1138 } 1139 1140 if (m_pEditNotify) 1141 { 1142 m_pEditNotify->OnClear(place, oldplace); 1143 } 1144 } 1145 1146 void CPWL_Edit::OnInsertWord(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace) 1147 { 1148 if (HasFlag(PES_SPELLCHECK)) 1149 { 1150 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place))); 1151 } 1152 1153 if (m_pEditNotify) 1154 { 1155 m_pEditNotify->OnInsertWord(place, oldplace); 1156 } 1157 } 1158 1159 void CPWL_Edit::OnSetText(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace) 1160 { 1161 } 1162 1163 void CPWL_Edit::OnInsertText(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace) 1164 { 1165 if (HasFlag(PES_SPELLCHECK)) 1166 { 1167 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place))); 1168 } 1169 1170 if (m_pEditNotify) 1171 { 1172 m_pEditNotify->OnInsertText(place, oldplace); 1173 } 1174 } 1175 1176 void CPWL_Edit::OnAddUndo(IFX_Edit_UndoItem* pUndoItem) 1177 { 1178 if (m_pEditNotify) 1179 { 1180 m_pEditNotify->OnAddUndo(this); 1181 } 1182 } 1183 1184 CPVT_WordRange CPWL_Edit::CombineWordRange(const CPVT_WordRange& wr1, const CPVT_WordRange& wr2) 1185 { 1186 CPVT_WordRange wrRet; 1187 1188 if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0) 1189 { 1190 wrRet.BeginPos = wr1.BeginPos; 1191 } 1192 else 1193 { 1194 wrRet.BeginPos = wr2.BeginPos; 1195 } 1196 1197 if (wr1.EndPos.WordCmp(wr2.EndPos) < 0) 1198 { 1199 wrRet.EndPos = wr2.EndPos; 1200 } 1201 else 1202 { 1203 wrRet.EndPos = wr1.EndPos; 1204 } 1205 1206 return wrRet; 1207 } 1208 1209 CPVT_WordRange CPWL_Edit::GetLatinWordsRange(const CPDF_Point& point) const 1210 { 1211 return GetSameWordsRange(m_pEdit->SearchWordPlace(point), TRUE, FALSE); 1212 } 1213 1214 CPVT_WordRange CPWL_Edit::GetLatinWordsRange(const CPVT_WordPlace & place) const 1215 { 1216 return GetSameWordsRange(place, TRUE, FALSE); 1217 } 1218 1219 CPVT_WordRange CPWL_Edit::GetArabicWordsRange(const CPVT_WordPlace & place) const 1220 { 1221 return GetSameWordsRange(place, FALSE, TRUE); 1222 } 1223 1224 #define PWL_ISARABICWORD(word) ((word >= 0x0600 && word <= 0x06FF) || (word >= 0xFB50 && word <= 0xFEFC)) 1225 1226 CPVT_WordRange CPWL_Edit::GetSameWordsRange(const CPVT_WordPlace & place, FX_BOOL bLatin, FX_BOOL bArabic) const 1227 { 1228 CPVT_WordRange range; 1229 1230 if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) 1231 { 1232 CPVT_Word wordinfo; 1233 CPVT_WordPlace wpStart(place),wpEnd(place); 1234 pIterator->SetAt(place); 1235 1236 if (bLatin) 1237 { 1238 while (pIterator->NextWord()) 1239 { 1240 if (pIterator->GetWord(wordinfo) && FX_EDIT_ISLATINWORD(wordinfo.Word)) 1241 { 1242 wpEnd = pIterator->GetAt(); 1243 continue; 1244 } 1245 else 1246 break; 1247 }; 1248 } 1249 else if (bArabic) 1250 { 1251 while (pIterator->NextWord()) 1252 { 1253 if (pIterator->GetWord(wordinfo) && PWL_ISARABICWORD(wordinfo.Word)) 1254 { 1255 wpEnd = pIterator->GetAt(); 1256 continue; 1257 } 1258 else 1259 break; 1260 }; 1261 } 1262 1263 pIterator->SetAt(place); 1264 1265 if (bLatin) 1266 { 1267 do 1268 { 1269 if (pIterator->GetWord(wordinfo) && FX_EDIT_ISLATINWORD(wordinfo.Word)) 1270 { 1271 continue; 1272 } 1273 else 1274 { 1275 wpStart = pIterator->GetAt(); 1276 break; 1277 } 1278 } 1279 while (pIterator->PrevWord()); 1280 } 1281 else if (bArabic) 1282 { 1283 do 1284 { 1285 if (pIterator->GetWord(wordinfo) && PWL_ISARABICWORD(wordinfo.Word)) 1286 { 1287 continue; 1288 } 1289 else 1290 { 1291 wpStart = pIterator->GetAt(); 1292 break; 1293 } 1294 } 1295 while (pIterator->PrevWord()); 1296 } 1297 1298 range.Set(wpStart,wpEnd); 1299 } 1300 1301 return range; 1302 } 1303 1304 void CPWL_Edit::AjustArabicWords(const CPVT_WordRange& wr) 1305 { 1306 } 1307 1308 void CPWL_Edit::GeneratePageObjects(CPDF_PageObjects* pPageObjects, 1309 const CPDF_Point& ptOffset, CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) 1310 { 1311 IFX_Edit::GeneratePageObjects(pPageObjects, m_pEdit, ptOffset, NULL, CPWL_Utils::PWLColorToFXColor(GetTextColor(),GetTransparency()), ObjArray); 1312 } 1313 1314 void CPWL_Edit::GeneratePageObjects(CPDF_PageObjects* pPageObjects, 1315 const CPDF_Point& ptOffset) 1316 { 1317 CFX_ArrayTemplate<CPDF_TextObject*> ObjArray; 1318 IFX_Edit::GeneratePageObjects(pPageObjects, m_pEdit, ptOffset, NULL, CPWL_Utils::PWLColorToFXColor(GetTextColor(),GetTransparency()), ObjArray); 1319 } 1320 1321