blob: 4b3886a11d36571c2a4a37f4cbf4861d4419d941 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhangc2fb35f2016-01-05 16:46:58 -08007#include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
8
Lei Zhanga688a042015-11-09 13:57:49 -08009#include "core/include/fxcrt/fx_safe_types.h"
10#include "core/include/fxcrt/fx_xml.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080011#include "fpdfsdk/include/pdfwindow/PWL_Caret.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080012#include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
13#include "fpdfsdk/include/pdfwindow/PWL_FontMap.h"
14#include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
15#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
16#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080017#include "public/fpdf_fwlevent.h"
Tom Sepezab277682016-02-17 10:07:21 -080018#include "third_party/base/stl_util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070019
Nico Weber9d8ec5a2015-08-04 13:00:21 -070020CPWL_Edit::CPWL_Edit()
21 : m_pFillerNotify(NULL), m_pSpellCheck(NULL), m_bFocus(FALSE) {
22 m_pFormFiller = NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070023}
24
Nico Weber9d8ec5a2015-08-04 13:00:21 -070025CPWL_Edit::~CPWL_Edit() {
26 ASSERT(m_bFocus == FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070027}
28
Nico Weber9d8ec5a2015-08-04 13:00:21 -070029CFX_ByteString CPWL_Edit::GetClassName() const {
30 return PWL_CLASSNAME_EDIT;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070031}
32
Nico Weber9d8ec5a2015-08-04 13:00:21 -070033void CPWL_Edit::OnDestroy() {}
34
35void CPWL_Edit::SetText(const FX_WCHAR* csText) {
36 CFX_WideString swText = csText;
37
38 if (HasFlag(PES_RICH)) {
39 CFX_ByteString sValue = CFX_ByteString::FromUnicode(swText);
40
41 if (CXML_Element* pXML =
42 CXML_Element::Parse(sValue.c_str(), sValue.GetLength())) {
43 int32_t nCount = pXML->CountChildren();
44 FX_BOOL bFirst = TRUE;
45
46 swText.Empty();
47
48 for (int32_t i = 0; i < nCount; i++) {
49 if (CXML_Element* pSubElement = pXML->GetElement(i)) {
50 CFX_ByteString tag = pSubElement->GetTagName();
51 if (tag.EqualNoCase("p")) {
52 int nChild = pSubElement->CountChildren();
53 CFX_WideString swSection;
54 for (int32_t j = 0; j < nChild; j++) {
55 swSection += pSubElement->GetContent(j);
56 }
57
58 if (bFirst)
59 bFirst = FALSE;
60 else
61 swText += FWL_VKEY_Return;
62 swText += swSection;
63 }
64 }
65 }
66
67 delete pXML;
68 }
69 }
70
71 m_pEdit->SetText(swText.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070072}
73
Nico Weber9d8ec5a2015-08-04 13:00:21 -070074void CPWL_Edit::RePosChildWnd() {
75 if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
76 CPDF_Rect rcWindow = m_rcOldWindow;
77 CPDF_Rect rcVScroll =
78 CPDF_Rect(rcWindow.right, rcWindow.bottom,
79 rcWindow.right + PWL_SCROLLBAR_WIDTH, rcWindow.top);
80 pVSB->Move(rcVScroll, TRUE, FALSE);
81 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070082
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083 if (m_pEditCaret && !HasFlag(PES_TEXTOVERFLOW))
84 m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(
85 GetClientRect(), 1.0f)); //+1 for caret beside border
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070086
Nico Weber9d8ec5a2015-08-04 13:00:21 -070087 CPWL_EditCtrl::RePosChildWnd();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070088}
89
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090CPDF_Rect CPWL_Edit::GetClientRect() const {
91 CPDF_Rect rcClient = CPWL_Utils::DeflateRect(
92 GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
93
94 if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
95 if (pVSB->IsVisible()) {
96 rcClient.right -= PWL_SCROLLBAR_WIDTH;
97 }
98 }
99
100 return rcClient;
101}
102
103void CPWL_Edit::SetAlignFormatH(PWL_EDIT_ALIGNFORMAT_H nFormat,
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800104 FX_BOOL bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700105 m_pEdit->SetAlignmentH((int32_t)nFormat, bPaint);
106}
107
108void CPWL_Edit::SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat,
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800109 FX_BOOL bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700110 m_pEdit->SetAlignmentV((int32_t)nFormat, bPaint);
111}
112
113FX_BOOL CPWL_Edit::CanSelectAll() const {
114 return GetSelectWordRange() != m_pEdit->GetWholeWordRange();
115}
116
117FX_BOOL CPWL_Edit::CanClear() const {
118 return !IsReadOnly() && m_pEdit->IsSelected();
119}
120
121FX_BOOL CPWL_Edit::CanCopy() const {
122 return !HasFlag(PES_PASSWORD) && !HasFlag(PES_NOREAD) &&
123 m_pEdit->IsSelected();
124}
125
126FX_BOOL CPWL_Edit::CanCut() const {
127 return CanCopy() && !IsReadOnly();
128}
129
130FX_BOOL CPWL_Edit::CanPaste() const {
131 if (IsReadOnly())
132 return FALSE;
133
134 CFX_WideString swClipboard;
135 if (IFX_SystemHandler* pSH = GetSystemHandler())
136 swClipboard = pSH->GetClipboardText(GetAttachedHWnd());
137
138 return !swClipboard.IsEmpty();
139}
140
141void CPWL_Edit::CopyText() {
142 if (!CanCopy())
143 return;
144
145 CFX_WideString str = m_pEdit->GetSelText();
146
147 if (IFX_SystemHandler* pSH = GetSystemHandler())
148 pSH->SetClipboardText(GetAttachedHWnd(), str);
149}
150
151void CPWL_Edit::PasteText() {
152 if (!CanPaste())
153 return;
154
155 CFX_WideString swClipboard;
156 if (IFX_SystemHandler* pSH = GetSystemHandler())
157 swClipboard = pSH->GetClipboardText(GetAttachedHWnd());
158
159 if (m_pFillerNotify) {
160 FX_BOOL bRC = TRUE;
161 FX_BOOL bExit = FALSE;
162 CFX_WideString strChangeEx;
163 int nSelStart = 0;
164 int nSelEnd = 0;
165 GetSel(nSelStart, nSelEnd);
Lei Zhanga5b47042015-10-19 14:32:16 -0700166 m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swClipboard,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 strChangeEx, nSelStart, nSelEnd, TRUE,
168 bRC, bExit, 0);
169 if (!bRC)
170 return;
171 if (bExit)
172 return;
173 }
174
175 if (swClipboard.GetLength() > 0) {
176 Clear();
177 InsertText(swClipboard.c_str());
178 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179}
180
181void CPWL_Edit::CutText() {
182 if (!CanCut())
183 return;
184
185 CFX_WideString str = m_pEdit->GetSelText();
186
187 if (IFX_SystemHandler* pSH = GetSystemHandler())
188 pSH->SetClipboardText(GetAttachedHWnd(), str);
189
190 m_pEdit->Clear();
191}
192
193void CPWL_Edit::OnCreated() {
194 CPWL_EditCtrl::OnCreated();
195
196 if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
197 pScroll->RemoveFlag(PWS_AUTOTRANSPARENT);
198 pScroll->SetTransparency(255);
199 }
200
201 SetParamByFlag();
202
203 m_rcOldWindow = GetWindowRect();
204
205 m_pEdit->SetOprNotify(this);
206 m_pEdit->EnableOprNotify(TRUE);
207}
208
209void CPWL_Edit::SetParamByFlag() {
210 if (HasFlag(PES_RIGHT)) {
211 m_pEdit->SetAlignmentH(2, FALSE);
212 } else if (HasFlag(PES_MIDDLE)) {
213 m_pEdit->SetAlignmentH(1, FALSE);
214 } else {
215 m_pEdit->SetAlignmentH(0, FALSE);
216 }
217
218 if (HasFlag(PES_BOTTOM)) {
219 m_pEdit->SetAlignmentV(2, FALSE);
220 } else if (HasFlag(PES_CENTER)) {
221 m_pEdit->SetAlignmentV(1, FALSE);
222 } else {
223 m_pEdit->SetAlignmentV(0, FALSE);
224 }
225
226 if (HasFlag(PES_PASSWORD)) {
227 m_pEdit->SetPasswordChar('*', FALSE);
228 }
229
230 m_pEdit->SetMultiLine(HasFlag(PES_MULTILINE), FALSE);
231 m_pEdit->SetAutoReturn(HasFlag(PES_AUTORETURN), FALSE);
232 m_pEdit->SetAutoFontSize(HasFlag(PWS_AUTOFONTSIZE), FALSE);
233 m_pEdit->SetAutoScroll(HasFlag(PES_AUTOSCROLL), FALSE);
234 m_pEdit->EnableUndo(HasFlag(PES_UNDO));
235
236 if (HasFlag(PES_TEXTOVERFLOW)) {
237 SetClipRect(CPDF_Rect(0.0f, 0.0f, 0.0f, 0.0f));
238 m_pEdit->SetTextOverflow(TRUE, FALSE);
239 } else {
240 if (m_pEditCaret) {
241 m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(
242 GetClientRect(), 1.0f)); //+1 for caret beside border
243 }
244 }
245
246 if (HasFlag(PES_SPELLCHECK)) {
247 m_pSpellCheck = GetCreationParam().pSpellCheck;
248 }
249}
250
251void CPWL_Edit::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
252 CPWL_Wnd::GetThisAppearanceStream(sAppStream);
253
254 CPDF_Rect rcClient = GetClientRect();
255 CFX_ByteTextBuf sLine;
256
257 int32_t nCharArray = m_pEdit->GetCharArray();
258
259 if (nCharArray > 0) {
260 switch (GetBorderStyle()) {
261 case PBS_SOLID: {
262 sLine << "q\n" << GetBorderWidth() << " w\n"
263 << CPWL_Utils::GetColorAppStream(GetBorderColor(), FALSE)
264 << " 2 J 0 j\n";
265
266 for (int32_t i = 1; i < nCharArray; i++) {
267 sLine << rcClient.left +
268 ((rcClient.right - rcClient.left) / nCharArray) * i
269 << " " << rcClient.bottom << " m\n"
270 << rcClient.left +
271 ((rcClient.right - rcClient.left) / nCharArray) * i
272 << " " << rcClient.top << " l S\n";
273 }
274
275 sLine << "Q\n";
276 } break;
277 case PBS_DASH: {
278 sLine << "q\n" << GetBorderWidth() << " w\n"
279 << CPWL_Utils::GetColorAppStream(GetBorderColor(), FALSE)
280 << " 2 J 0 j\n"
281 << "[" << GetBorderDash().nDash << " " << GetBorderDash().nGap
282 << "] " << GetBorderDash().nPhase << " d\n";
283
284 for (int32_t i = 1; i < nCharArray; i++) {
285 sLine << rcClient.left +
286 ((rcClient.right - rcClient.left) / nCharArray) * i
287 << " " << rcClient.bottom << " m\n"
288 << rcClient.left +
289 ((rcClient.right - rcClient.left) / nCharArray) * i
290 << " " << rcClient.top << " l S\n";
291 }
292
293 sLine << "Q\n";
294 } break;
295 }
296 }
297
298 sAppStream << sLine;
299
300 CFX_ByteTextBuf sText;
301
302 CPDF_Point ptOffset = CPDF_Point(0.0f, 0.0f);
303
304 CPVT_WordRange wrWhole = m_pEdit->GetWholeWordRange();
305 CPVT_WordRange wrSelect = GetSelectWordRange();
306 CPVT_WordRange wrVisible =
307 (HasFlag(PES_TEXTOVERFLOW) ? wrWhole : m_pEdit->GetVisibleWordRange());
308 CPVT_WordRange wrSelBefore(wrWhole.BeginPos, wrSelect.BeginPos);
309 CPVT_WordRange wrSelAfter(wrSelect.EndPos, wrWhole.EndPos);
310
311 CPVT_WordRange wrTemp =
312 CPWL_Utils::OverlapWordRange(GetSelectWordRange(), wrVisible);
313 CFX_ByteString sEditSel =
314 CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset, &wrTemp);
315
316 if (sEditSel.GetLength() > 0)
317 sText << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELBACKCOLOR)
318 << sEditSel;
319
320 wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelBefore);
321 CFX_ByteString sEditBefore = CPWL_Utils::GetEditAppStream(
322 m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
323 m_pEdit->GetPasswordChar());
324
325 if (sEditBefore.GetLength() > 0)
326 sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor())
327 << sEditBefore << "ET\n";
328
329 wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelect);
330 CFX_ByteString sEditMid = CPWL_Utils::GetEditAppStream(
331 m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
332 m_pEdit->GetPasswordChar());
333
334 if (sEditMid.GetLength() > 0)
335 sText << "BT\n"
336 << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1))
337 << sEditMid << "ET\n";
338
339 wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelAfter);
340 CFX_ByteString sEditAfter = CPWL_Utils::GetEditAppStream(
341 m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
342 m_pEdit->GetPasswordChar());
343
344 if (sEditAfter.GetLength() > 0)
345 sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor())
346 << sEditAfter << "ET\n";
347
348 if (HasFlag(PES_SPELLCHECK)) {
349 CFX_ByteString sSpellCheck = CPWL_Utils::GetSpellCheckAppStream(
350 m_pEdit, m_pSpellCheck, ptOffset, &wrVisible);
351 if (sSpellCheck.GetLength() > 0)
352 sText << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_RGB, 1, 0, 0),
353 FALSE)
354 << sSpellCheck;
355 }
356
357 if (sText.GetLength() > 0) {
358 CPDF_Rect rcClient = GetClientRect();
359 sAppStream << "q\n/Tx BMC\n";
360
361 if (!HasFlag(PES_TEXTOVERFLOW))
362 sAppStream << rcClient.left << " " << rcClient.bottom << " "
363 << rcClient.right - rcClient.left << " "
364 << rcClient.top - rcClient.bottom << " re W n\n";
365
366 sAppStream << sText;
367
368 sAppStream << "EMC\nQ\n";
369 }
370}
371
372void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800373 CFX_Matrix* pUser2Device) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700374 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
375
376 CPDF_Rect rcClient = GetClientRect();
377 CFX_ByteTextBuf sLine;
378
379 int32_t nCharArray = m_pEdit->GetCharArray();
380 FX_SAFE_INT32 nCharArraySafe = nCharArray;
381 nCharArraySafe -= 1;
382 nCharArraySafe *= 2;
383
384 if (nCharArray > 0 && nCharArraySafe.IsValid()) {
385 switch (GetBorderStyle()) {
386 case PBS_SOLID: {
387 CFX_GraphStateData gsd;
388 gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();
389
390 CFX_PathData path;
391 path.SetPointCount(nCharArraySafe.ValueOrDie());
392
393 for (int32_t i = 0; i < nCharArray - 1; i++) {
394 path.SetPoint(
395 i * 2,
396 rcClient.left +
397 ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
398 rcClient.bottom, FXPT_MOVETO);
399 path.SetPoint(
400 i * 2 + 1,
401 rcClient.left +
402 ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
403 rcClient.top, FXPT_LINETO);
404 }
405 if (path.GetPointCount() > 0)
406 pDevice->DrawPath(
407 &path, pUser2Device, &gsd, 0,
408 CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255),
409 FXFILL_ALTERNATE);
410 } break;
411 case PBS_DASH: {
412 CFX_GraphStateData gsd;
413 gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();
414
415 gsd.SetDashCount(2);
416 gsd.m_DashArray[0] = (FX_FLOAT)GetBorderDash().nDash;
417 gsd.m_DashArray[1] = (FX_FLOAT)GetBorderDash().nGap;
418 gsd.m_DashPhase = (FX_FLOAT)GetBorderDash().nPhase;
419
420 CFX_PathData path;
421 path.SetPointCount(nCharArraySafe.ValueOrDie());
422
423 for (int32_t i = 0; i < nCharArray - 1; i++) {
424 path.SetPoint(
425 i * 2,
426 rcClient.left +
427 ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
428 rcClient.bottom, FXPT_MOVETO);
429 path.SetPoint(
430 i * 2 + 1,
431 rcClient.left +
432 ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
433 rcClient.top, FXPT_LINETO);
434 }
435 if (path.GetPointCount() > 0)
436 pDevice->DrawPath(
437 &path, pUser2Device, &gsd, 0,
438 CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255),
439 FXFILL_ALTERNATE);
440 } break;
441 }
442 }
443
444 CPDF_Rect rcClip;
445 CPVT_WordRange wrRange = m_pEdit->GetVisibleWordRange();
446 CPVT_WordRange* pRange = NULL;
447
448 if (!HasFlag(PES_TEXTOVERFLOW)) {
449 rcClip = GetClientRect();
450 pRange = &wrRange;
451 }
452 IFX_SystemHandler* pSysHandler = GetSystemHandler();
453 IFX_Edit::DrawEdit(
454 pDevice, pUser2Device, m_pEdit,
455 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
456 CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(), GetTransparency()),
457 rcClip, CPDF_Point(0.0f, 0.0f), pRange, pSysHandler, m_pFormFiller);
458
459 if (HasFlag(PES_SPELLCHECK)) {
460 CPWL_Utils::DrawEditSpellCheck(pDevice, pUser2Device, m_pEdit, rcClip,
461 CPDF_Point(0.0f, 0.0f), pRange,
462 GetCreationParam().pSpellCheck);
463 }
464}
465
466FX_BOOL CPWL_Edit::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
467 CPWL_Wnd::OnLButtonDown(point, nFlag);
468
469 if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
470 if (m_bMouseDown)
471 InvalidateRect();
472
473 m_bMouseDown = TRUE;
474 SetCapture();
475
476 m_pEdit->OnMouseDown(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
477 }
478
479 return TRUE;
480}
481
482FX_BOOL CPWL_Edit::OnLButtonDblClk(const CPDF_Point& point, FX_DWORD nFlag) {
483 CPWL_Wnd::OnLButtonDblClk(point, nFlag);
484
485 if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
486 m_pEdit->SelectAll();
487 }
488
489 return TRUE;
490}
491
492#define WM_PWLEDIT_UNDO 0x01
493#define WM_PWLEDIT_REDO 0x02
494#define WM_PWLEDIT_CUT 0x03
495#define WM_PWLEDIT_COPY 0x04
496#define WM_PWLEDIT_PASTE 0x05
497#define WM_PWLEDIT_DELETE 0x06
498#define WM_PWLEDIT_SELECTALL 0x07
499#define WM_PWLEDIT_SUGGEST 0x08
500
501FX_BOOL CPWL_Edit::OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
502 if (m_bMouseDown)
503 return FALSE;
504
505 CPWL_Wnd::OnRButtonUp(point, nFlag);
506
507 if (!HasFlag(PES_TEXTOVERFLOW) && !ClientHitTest(point))
508 return TRUE;
509
510 IFX_SystemHandler* pSH = GetSystemHandler();
511 if (!pSH)
512 return FALSE;
513
514 SetFocus();
515
516 CPVT_WordRange wrLatin = GetLatinWordsRange(point);
517 CFX_WideString swLatin = m_pEdit->GetRangeText(wrLatin);
518
519 FX_HMENU hPopup = pSH->CreatePopupMenu();
520 if (!hPopup)
521 return FALSE;
522
Tom Sepezab277682016-02-17 10:07:21 -0800523 std::vector<CFX_ByteString> sSuggestWords;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700524 CPDF_Point ptPopup = point;
525
526 if (!IsReadOnly()) {
527 if (HasFlag(PES_SPELLCHECK) && !swLatin.IsEmpty()) {
528 if (m_pSpellCheck) {
529 CFX_ByteString sLatin = CFX_ByteString::FromUnicode(swLatin);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700530 if (!m_pSpellCheck->CheckWord(sLatin)) {
531 m_pSpellCheck->SuggestWords(sLatin, sSuggestWords);
532
Tom Sepezab277682016-02-17 10:07:21 -0800533 int32_t nSuggest = pdfium::CollectionSize<int32_t>(sSuggestWords);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700534 for (int32_t nWord = 0; nWord < nSuggest; nWord++) {
535 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_SUGGEST + nWord,
536 sSuggestWords[nWord].UTF8Decode());
537 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700538 if (nSuggest > 0)
539 pSH->AppendMenuItem(hPopup, 0, L"");
540
541 ptPopup = GetWordRightBottomPoint(wrLatin.EndPos);
542 }
543 }
544 }
545 }
546
547 IPWL_Provider* pProvider = GetProvider();
548
549 if (HasFlag(PES_UNDO)) {
550 pSH->AppendMenuItem(
551 hPopup, WM_PWLEDIT_UNDO,
552 pProvider ? pProvider->LoadPopupMenuString(0) : L"&Undo");
553 pSH->AppendMenuItem(
554 hPopup, WM_PWLEDIT_REDO,
555 pProvider ? pProvider->LoadPopupMenuString(1) : L"&Redo");
556 pSH->AppendMenuItem(hPopup, 0, L"");
557
558 if (!m_pEdit->CanUndo())
559 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_UNDO, FALSE);
560 if (!m_pEdit->CanRedo())
561 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_REDO, FALSE);
562 }
563
564 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_CUT,
565 pProvider ? pProvider->LoadPopupMenuString(2) : L"Cu&t");
566 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_COPY,
567 pProvider ? pProvider->LoadPopupMenuString(3) : L"&Copy");
568 pSH->AppendMenuItem(
569 hPopup, WM_PWLEDIT_PASTE,
570 pProvider ? pProvider->LoadPopupMenuString(4) : L"&Paste");
571 pSH->AppendMenuItem(
572 hPopup, WM_PWLEDIT_DELETE,
573 pProvider ? pProvider->LoadPopupMenuString(5) : L"&Delete");
574
575 CFX_WideString swText = pSH->GetClipboardText(GetAttachedHWnd());
576 if (swText.IsEmpty())
577 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE);
578
579 if (!m_pEdit->IsSelected()) {
580 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
581 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
582 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE);
583 }
584
585 if (IsReadOnly()) {
586 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
587 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE);
588 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE);
589 }
590
591 if (HasFlag(PES_PASSWORD)) {
592 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
593 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
594 }
595
596 if (HasFlag(PES_NOREAD)) {
597 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
598 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
599 }
600
601 pSH->AppendMenuItem(hPopup, 0, L"");
602 pSH->AppendMenuItem(
603 hPopup, WM_PWLEDIT_SELECTALL,
604 pProvider ? pProvider->LoadPopupMenuString(6) : L"&Select All");
605
606 if (m_pEdit->GetTotalWords() == 0) {
607 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_SELECTALL, FALSE);
608 }
609
610 int32_t x, y;
611 PWLtoWnd(ptPopup, x, y);
612 pSH->ClientToScreen(GetAttachedHWnd(), x, y);
613 pSH->SetCursor(FXCT_ARROW);
614 int32_t nCmd = pSH->TrackPopupMenu(hPopup, x, y, GetAttachedHWnd());
615
616 switch (nCmd) {
617 case WM_PWLEDIT_UNDO:
618 Undo();
619 break;
620 case WM_PWLEDIT_REDO:
621 Redo();
622 break;
623 case WM_PWLEDIT_CUT:
624 CutText();
625 break;
626 case WM_PWLEDIT_COPY:
627 CopyText();
628 break;
629 case WM_PWLEDIT_PASTE:
630 PasteText();
631 break;
632 case WM_PWLEDIT_DELETE:
633 Clear();
634 break;
635 case WM_PWLEDIT_SELECTALL:
636 SelectAll();
637 break;
638 case WM_PWLEDIT_SUGGEST + 0:
639 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
640 m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
641 ReplaceSel(sSuggestWords[0].UTF8Decode().c_str());
642 break;
643 case WM_PWLEDIT_SUGGEST + 1:
644 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
645 m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
646 ReplaceSel(sSuggestWords[1].UTF8Decode().c_str());
647 break;
648 case WM_PWLEDIT_SUGGEST + 2:
649 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
650 m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
651 ReplaceSel(sSuggestWords[2].UTF8Decode().c_str());
652 break;
653 case WM_PWLEDIT_SUGGEST + 3:
654 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
655 m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
656 ReplaceSel(sSuggestWords[3].UTF8Decode().c_str());
657 break;
658 case WM_PWLEDIT_SUGGEST + 4:
659 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
660 m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
661 ReplaceSel(sSuggestWords[4].UTF8Decode().c_str());
662 break;
663 default:
664 break;
665 }
666
667 pSH->DestroyMenu(hPopup);
668
669 return TRUE;
670}
671
672void CPWL_Edit::OnSetFocus() {
673 SetEditCaret(TRUE);
674
675 if (!IsReadOnly()) {
676 if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
677 pFocusHandler->OnSetFocus(this);
678 }
679
680 m_bFocus = TRUE;
681}
682
683void CPWL_Edit::OnKillFocus() {
684 ShowVScrollBar(FALSE);
685
686 m_pEdit->SelectNone();
687 SetCaret(FALSE, CPDF_Point(0.0f, 0.0f), CPDF_Point(0.0f, 0.0f));
688
689 SetCharSet(0);
690
691 if (!IsReadOnly()) {
692 if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
693 pFocusHandler->OnKillFocus(this);
694 }
695
696 m_bFocus = FALSE;
697}
698
699void CPWL_Edit::SetHorzScale(int32_t nHorzScale, FX_BOOL bPaint /* = TRUE*/) {
700 m_pEdit->SetHorzScale(nHorzScale, bPaint);
701}
702
703void CPWL_Edit::SetCharSpace(FX_FLOAT fCharSpace, FX_BOOL bPaint /* = TRUE*/) {
704 m_pEdit->SetCharSpace(fCharSpace, bPaint);
705}
706
707void CPWL_Edit::SetLineLeading(FX_FLOAT fLineLeading,
708 FX_BOOL bPaint /* = TRUE*/) {
709 m_pEdit->SetLineLeading(fLineLeading, bPaint);
710}
711
712CFX_ByteString CPWL_Edit::GetSelectAppearanceStream(
713 const CPDF_Point& ptOffset) const {
714 CPVT_WordRange wr = GetSelectWordRange();
715 return CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset, &wr);
716}
717
718CPVT_WordRange CPWL_Edit::GetSelectWordRange() const {
719 if (m_pEdit->IsSelected()) {
720 int32_t nStart = -1;
721 int32_t nEnd = -1;
722
723 m_pEdit->GetSel(nStart, nEnd);
724
725 CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStart);
726 CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEnd);
727
728 return CPVT_WordRange(wpStart, wpEnd);
729 }
730
731 return CPVT_WordRange();
732}
733
734CFX_ByteString CPWL_Edit::GetTextAppearanceStream(
735 const CPDF_Point& ptOffset) const {
736 CFX_ByteTextBuf sRet;
737 CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset);
738
739 if (sEdit.GetLength() > 0) {
740 sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEdit
741 << "ET\n";
742 }
743
744 return sRet.GetByteString();
745}
746
747CFX_ByteString CPWL_Edit::GetCaretAppearanceStream(
748 const CPDF_Point& ptOffset) const {
749 if (m_pEditCaret)
750 return m_pEditCaret->GetCaretAppearanceStream(ptOffset);
751
752 return CFX_ByteString();
753}
754
755CPDF_Point CPWL_Edit::GetWordRightBottomPoint(const CPVT_WordPlace& wpWord) {
756 CPDF_Point pt(0.0f, 0.0f);
757
758 if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
759 CPVT_WordPlace wpOld = pIterator->GetAt();
760 pIterator->SetAt(wpWord);
761 CPVT_Word word;
762 if (pIterator->GetWord(word)) {
763 pt = CPDF_Point(word.ptWord.x + word.fWidth,
764 word.ptWord.y + word.fDescent);
Lei Zhang60f507b2015-06-13 00:41:00 -0700765 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700766
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700767 pIterator->SetAt(wpOld);
768 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700769
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700770 return pt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700771}
772
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700773FX_BOOL CPWL_Edit::IsTextFull() const {
774 return m_pEdit->IsTextFull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700775}
776
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700777FX_FLOAT CPWL_Edit::GetCharArrayAutoFontSize(CPDF_Font* pFont,
778 const CPDF_Rect& rcPlate,
779 int32_t nCharArray) {
780 if (pFont && !pFont->IsStandardFont()) {
781 FX_RECT rcBBox;
782 pFont->GetFontBBox(rcBBox);
783
784 CPDF_Rect rcCell = rcPlate;
785 FX_FLOAT xdiv = rcCell.Width() / nCharArray * 1000.0f / rcBBox.Width();
786 FX_FLOAT ydiv = -rcCell.Height() * 1000.0f / rcBBox.Height();
787
788 return xdiv < ydiv ? xdiv : ydiv;
789 }
790
791 return 0.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700792}
793
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700794void CPWL_Edit::SetCharArray(int32_t nCharArray) {
795 if (HasFlag(PES_CHARARRAY) && nCharArray > 0) {
796 m_pEdit->SetCharArray(nCharArray);
797 m_pEdit->SetTextOverflow(TRUE);
798
799 if (HasFlag(PWS_AUTOFONTSIZE)) {
800 if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
801 FX_FLOAT fFontSize = GetCharArrayAutoFontSize(
802 pFontMap->GetPDFFont(0), GetClientRect(), nCharArray);
803 if (fFontSize > 0.0f) {
804 m_pEdit->SetAutoFontSize(FALSE);
805 m_pEdit->SetFontSize(fFontSize);
806 }
807 }
808 }
809 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700810}
811
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700812void CPWL_Edit::SetLimitChar(int32_t nLimitChar) {
813 m_pEdit->SetLimitChar(nLimitChar);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700814}
815
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700816void CPWL_Edit::ReplaceSel(const FX_WCHAR* csText) {
817 m_pEdit->Clear();
818 m_pEdit->InsertText(csText);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700819}
820
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700821CPDF_Rect CPWL_Edit::GetFocusRect() const {
822 return CPDF_Rect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700823}
824
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700825void CPWL_Edit::ShowVScrollBar(FX_BOOL bShow) {
826 if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
827 if (bShow) {
828 if (!pScroll->IsVisible()) {
829 pScroll->SetVisible(TRUE);
830 CPDF_Rect rcWindow = GetWindowRect();
831 m_rcOldWindow = rcWindow;
832 rcWindow.right += PWL_SCROLLBAR_WIDTH;
833 Move(rcWindow, TRUE, TRUE);
834 }
835 } else {
836 if (pScroll->IsVisible()) {
837 pScroll->SetVisible(FALSE);
838 Move(m_rcOldWindow, TRUE, TRUE);
839 }
840 }
841 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700842}
843
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700844FX_BOOL CPWL_Edit::IsVScrollBarVisible() const {
845 if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
846 return pScroll->IsVisible();
847 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700848
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700849 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700850}
851
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700852void CPWL_Edit::EnableSpellCheck(FX_BOOL bEnabled) {
853 if (bEnabled)
854 AddFlag(PES_SPELLCHECK);
855 else
856 RemoveFlag(PES_SPELLCHECK);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700857}
858
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700859FX_BOOL CPWL_Edit::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
860 if (m_bMouseDown)
861 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700862
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700863 if (nChar == FWL_VKEY_Delete) {
864 if (m_pFillerNotify) {
865 FX_BOOL bRC = TRUE;
866 FX_BOOL bExit = FALSE;
867 CFX_WideString strChange;
868 CFX_WideString strChangeEx;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700869
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700870 int nSelStart = 0;
871 int nSelEnd = 0;
872 GetSel(nSelStart, nSelEnd);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700873
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700874 if (nSelStart == nSelEnd)
875 nSelEnd = nSelStart + 1;
Lei Zhanga5b47042015-10-19 14:32:16 -0700876 m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), strChange,
877 strChangeEx, nSelStart, nSelEnd, TRUE,
878 bRC, bExit, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700879 if (!bRC)
880 return FALSE;
881 if (bExit)
882 return FALSE;
883 }
884 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700885
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700886 FX_BOOL bRet = CPWL_EditCtrl::OnKeyDown(nChar, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700887
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700888 // In case of implementation swallow the OnKeyDown event.
889 if (IsProceedtoOnChar(nChar, nFlag))
890 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700891
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700892 return bRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700893}
894
895/**
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700896*In case of implementation swallow the OnKeyDown event.
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700897*If the event is swallowed, implementation may do other unexpected things, which
898*is not the control means to do.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700899*/
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700900FX_BOOL CPWL_Edit::IsProceedtoOnChar(FX_WORD nKeyCode, FX_DWORD nFlag) {
901 FX_BOOL bCtrl = IsCTRLpressed(nFlag);
902 FX_BOOL bAlt = IsALTpressed(nFlag);
903 if (bCtrl && !bAlt) {
904 // hot keys for edit control.
905 switch (nKeyCode) {
906 case 'C':
907 case 'V':
908 case 'X':
909 case 'A':
910 case 'Z':
911 return TRUE;
912 default:
913 break;
914 }
915 }
916 // control characters.
917 switch (nKeyCode) {
918 case FWL_VKEY_Escape:
919 case FWL_VKEY_Back:
920 case FWL_VKEY_Return:
921 case FWL_VKEY_Space:
922 return TRUE;
923 default:
Lei Zhanga5b47042015-10-19 14:32:16 -0700924 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700925 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700926}
927
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700928FX_BOOL CPWL_Edit::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
929 if (m_bMouseDown)
930 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700931
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700932 FX_BOOL bRC = TRUE;
933 FX_BOOL bExit = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700934
Lei Zhanga5b47042015-10-19 14:32:16 -0700935 if (!IsCTRLpressed(nFlag)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700936 if (m_pFillerNotify) {
937 CFX_WideString swChange;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700938
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700939 int nSelStart = 0;
940 int nSelEnd = 0;
941 GetSel(nSelStart, nSelEnd);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700942
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700943 switch (nChar) {
944 case FWL_VKEY_Back:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700945 if (nSelStart == nSelEnd)
946 nSelStart = nSelEnd - 1;
947 break;
948 case FWL_VKEY_Return:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700949 break;
950 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700951 swChange += nChar;
952 break;
953 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700954
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700955 CFX_WideString strChangeEx;
Lei Zhanga5b47042015-10-19 14:32:16 -0700956 m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swChange,
957 strChangeEx, nSelStart, nSelEnd, TRUE,
958 bRC, bExit, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700959 }
960 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700961
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700962 if (!bRC)
963 return TRUE;
964 if (bExit)
965 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700966
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700967 if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
968 int32_t nOldCharSet = GetCharSet();
969 int32_t nNewCharSet = pFontMap->CharSetFromUnicode(nChar, DEFAULT_CHARSET);
970 if (nOldCharSet != nNewCharSet) {
971 SetCharSet(nNewCharSet);
972 }
973 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700974
Lei Zhanga5b47042015-10-19 14:32:16 -0700975 return CPWL_EditCtrl::OnChar(nChar, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700976}
977
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700978FX_BOOL CPWL_Edit::OnMouseWheel(short zDelta,
979 const CPDF_Point& point,
980 FX_DWORD nFlag) {
981 if (HasFlag(PES_MULTILINE)) {
982 CPDF_Point ptScroll = GetScrollPos();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700983
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700984 if (zDelta > 0) {
985 ptScroll.y += GetFontSize();
986 } else {
987 ptScroll.y -= GetFontSize();
988 }
989 SetScrollPos(ptScroll);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700990
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700991 return TRUE;
992 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700993
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700994 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700995}
996
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700997void CPWL_Edit::OnInsertReturn(const CPVT_WordPlace& place,
998 const CPVT_WordPlace& oldplace) {
999 if (HasFlag(PES_SPELLCHECK)) {
1000 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1001 GetLatinWordsRange(place)));
1002 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001003
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001004 if (m_pEditNotify) {
1005 m_pEditNotify->OnInsertReturn(place, oldplace);
1006 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001007}
1008
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001009void CPWL_Edit::OnBackSpace(const CPVT_WordPlace& place,
1010 const CPVT_WordPlace& oldplace) {
1011 if (HasFlag(PES_SPELLCHECK)) {
1012 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1013 GetLatinWordsRange(place)));
1014 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001015
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001016 if (m_pEditNotify) {
1017 m_pEditNotify->OnBackSpace(place, oldplace);
1018 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001019}
1020
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001021void CPWL_Edit::OnDelete(const CPVT_WordPlace& place,
1022 const CPVT_WordPlace& oldplace) {
1023 if (HasFlag(PES_SPELLCHECK)) {
1024 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1025 GetLatinWordsRange(place)));
1026 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001027
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001028 if (m_pEditNotify) {
1029 m_pEditNotify->OnDelete(place, oldplace);
1030 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001031}
1032
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001033void CPWL_Edit::OnClear(const CPVT_WordPlace& place,
1034 const CPVT_WordPlace& oldplace) {
1035 if (HasFlag(PES_SPELLCHECK)) {
1036 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1037 GetLatinWordsRange(place)));
1038 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001039
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001040 if (m_pEditNotify) {
1041 m_pEditNotify->OnClear(place, oldplace);
1042 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001043}
1044
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001045void CPWL_Edit::OnInsertWord(const CPVT_WordPlace& place,
1046 const CPVT_WordPlace& oldplace) {
1047 if (HasFlag(PES_SPELLCHECK)) {
1048 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1049 GetLatinWordsRange(place)));
1050 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001051
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001052 if (m_pEditNotify) {
1053 m_pEditNotify->OnInsertWord(place, oldplace);
1054 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001055}
1056
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001057void CPWL_Edit::OnSetText(const CPVT_WordPlace& place,
1058 const CPVT_WordPlace& oldplace) {}
1059
1060void CPWL_Edit::OnInsertText(const CPVT_WordPlace& place,
1061 const CPVT_WordPlace& oldplace) {
1062 if (HasFlag(PES_SPELLCHECK)) {
1063 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1064 GetLatinWordsRange(place)));
1065 }
1066
1067 if (m_pEditNotify) {
1068 m_pEditNotify->OnInsertText(place, oldplace);
1069 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001070}
1071
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001072void CPWL_Edit::OnAddUndo(IFX_Edit_UndoItem* pUndoItem) {
1073 if (m_pEditNotify) {
1074 m_pEditNotify->OnAddUndo(this);
1075 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001076}
1077
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001078CPVT_WordRange CPWL_Edit::CombineWordRange(const CPVT_WordRange& wr1,
1079 const CPVT_WordRange& wr2) {
1080 CPVT_WordRange wrRet;
1081
1082 if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0) {
1083 wrRet.BeginPos = wr1.BeginPos;
1084 } else {
1085 wrRet.BeginPos = wr2.BeginPos;
1086 }
1087
1088 if (wr1.EndPos.WordCmp(wr2.EndPos) < 0) {
1089 wrRet.EndPos = wr2.EndPos;
1090 } else {
1091 wrRet.EndPos = wr1.EndPos;
1092 }
1093
1094 return wrRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001095}
1096
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001097CPVT_WordRange CPWL_Edit::GetLatinWordsRange(const CPDF_Point& point) const {
1098 return GetSameWordsRange(m_pEdit->SearchWordPlace(point), TRUE, FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001099}
1100
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001101CPVT_WordRange CPWL_Edit::GetLatinWordsRange(
1102 const CPVT_WordPlace& place) const {
1103 return GetSameWordsRange(place, TRUE, FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001104}
1105
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001106CPVT_WordRange CPWL_Edit::GetArabicWordsRange(
1107 const CPVT_WordPlace& place) const {
1108 return GetSameWordsRange(place, FALSE, TRUE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001109}
1110
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001111#define PWL_ISARABICWORD(word) \
1112 ((word >= 0x0600 && word <= 0x06FF) || (word >= 0xFB50 && word <= 0xFEFC))
1113
1114CPVT_WordRange CPWL_Edit::GetSameWordsRange(const CPVT_WordPlace& place,
1115 FX_BOOL bLatin,
1116 FX_BOOL bArabic) const {
1117 CPVT_WordRange range;
1118
1119 if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
1120 CPVT_Word wordinfo;
1121 CPVT_WordPlace wpStart(place), wpEnd(place);
1122 pIterator->SetAt(place);
1123
1124 if (bLatin) {
1125 while (pIterator->NextWord()) {
Lei Zhangc2fb35f2016-01-05 16:46:58 -08001126 if (!pIterator->GetWord(wordinfo) ||
1127 !FX_EDIT_ISLATINWORD(wordinfo.Word)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001128 break;
Lei Zhangc2fb35f2016-01-05 16:46:58 -08001129 }
1130
1131 wpEnd = pIterator->GetAt();
1132 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001133 } else if (bArabic) {
1134 while (pIterator->NextWord()) {
Lei Zhangc2fb35f2016-01-05 16:46:58 -08001135 if (!pIterator->GetWord(wordinfo) || !PWL_ISARABICWORD(wordinfo.Word))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001136 break;
Lei Zhangc2fb35f2016-01-05 16:46:58 -08001137
1138 wpEnd = pIterator->GetAt();
1139 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001140 }
1141
1142 pIterator->SetAt(place);
1143
1144 if (bLatin) {
1145 do {
Lei Zhangc2fb35f2016-01-05 16:46:58 -08001146 if (!pIterator->GetWord(wordinfo) ||
1147 !FX_EDIT_ISLATINWORD(wordinfo.Word)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001148 break;
1149 }
Lei Zhangc2fb35f2016-01-05 16:46:58 -08001150
1151 wpStart = pIterator->GetAt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001152 } while (pIterator->PrevWord());
1153 } else if (bArabic) {
1154 do {
Lei Zhangc2fb35f2016-01-05 16:46:58 -08001155 if (!pIterator->GetWord(wordinfo) || !PWL_ISARABICWORD(wordinfo.Word))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001156 break;
Lei Zhangc2fb35f2016-01-05 16:46:58 -08001157
1158 wpStart = pIterator->GetAt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001159 } while (pIterator->PrevWord());
1160 }
1161
1162 range.Set(wpStart, wpEnd);
1163 }
1164
1165 return range;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001166}
1167
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001168void CPWL_Edit::GeneratePageObjects(
Tom Sepez32c70812016-02-16 17:15:32 -08001169 CPDF_PageObjectHolder* pPageObjects,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001170 const CPDF_Point& ptOffset,
1171 CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
1172 IFX_Edit::GeneratePageObjects(
1173 pPageObjects, m_pEdit, ptOffset, NULL,
1174 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
1175 ObjArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001176}
1177
Tom Sepez32c70812016-02-16 17:15:32 -08001178void CPWL_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pPageObjects,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001179 const CPDF_Point& ptOffset) {
1180 CFX_ArrayTemplate<CPDF_TextObject*> ObjArray;
1181 IFX_Edit::GeneratePageObjects(
1182 pPageObjects, m_pEdit, ptOffset, NULL,
1183 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
1184 ObjArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001185}