blob: 29e7c2eea79f9e9724e013932b28b1567d546ef3 [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 Zhanga688a042015-11-09 13:57:49 -08007#include "core/include/fxcrt/fx_safe_types.h"
8#include "core/include/fxcrt/fx_xml.h"
Lei Zhangbde53d22015-11-12 22:21:30 -08009#include "fpdfsdk/include/pdfwindow/PDFWindow.h"
10#include "fpdfsdk/include/pdfwindow/PWL_Caret.h"
11#include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
12#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"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070017
18/* ---------------------------- CPWL_Edit ------------------------------ */
19
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,
104 FX_BOOL bPaint /* = TRUE*/) {
105 m_pEdit->SetAlignmentH((int32_t)nFormat, bPaint);
106}
107
108void CPWL_Edit::SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat,
109 FX_BOOL bPaint /* = TRUE*/) {
110 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,
373 CPDF_Matrix* pUser2Device) {
374 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
523 CFX_ByteStringArray sSuggestWords;
524 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);
530
531 if (!m_pSpellCheck->CheckWord(sLatin)) {
532 m_pSpellCheck->SuggestWords(sLatin, sSuggestWords);
533
534 int32_t nSuggest = sSuggestWords.GetSize();
535
536 for (int32_t nWord = 0; nWord < nSuggest; nWord++) {
537 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_SUGGEST + nWord,
538 sSuggestWords[nWord].UTF8Decode());
539 }
540
541 if (nSuggest > 0)
542 pSH->AppendMenuItem(hPopup, 0, L"");
543
544 ptPopup = GetWordRightBottomPoint(wrLatin.EndPos);
545 }
546 }
547 }
548 }
549
550 IPWL_Provider* pProvider = GetProvider();
551
552 if (HasFlag(PES_UNDO)) {
553 pSH->AppendMenuItem(
554 hPopup, WM_PWLEDIT_UNDO,
555 pProvider ? pProvider->LoadPopupMenuString(0) : L"&Undo");
556 pSH->AppendMenuItem(
557 hPopup, WM_PWLEDIT_REDO,
558 pProvider ? pProvider->LoadPopupMenuString(1) : L"&Redo");
559 pSH->AppendMenuItem(hPopup, 0, L"");
560
561 if (!m_pEdit->CanUndo())
562 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_UNDO, FALSE);
563 if (!m_pEdit->CanRedo())
564 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_REDO, FALSE);
565 }
566
567 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_CUT,
568 pProvider ? pProvider->LoadPopupMenuString(2) : L"Cu&t");
569 pSH->AppendMenuItem(hPopup, WM_PWLEDIT_COPY,
570 pProvider ? pProvider->LoadPopupMenuString(3) : L"&Copy");
571 pSH->AppendMenuItem(
572 hPopup, WM_PWLEDIT_PASTE,
573 pProvider ? pProvider->LoadPopupMenuString(4) : L"&Paste");
574 pSH->AppendMenuItem(
575 hPopup, WM_PWLEDIT_DELETE,
576 pProvider ? pProvider->LoadPopupMenuString(5) : L"&Delete");
577
578 CFX_WideString swText = pSH->GetClipboardText(GetAttachedHWnd());
579 if (swText.IsEmpty())
580 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE);
581
582 if (!m_pEdit->IsSelected()) {
583 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
584 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
585 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE);
586 }
587
588 if (IsReadOnly()) {
589 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
590 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE);
591 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE);
592 }
593
594 if (HasFlag(PES_PASSWORD)) {
595 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
596 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
597 }
598
599 if (HasFlag(PES_NOREAD)) {
600 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
601 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
602 }
603
604 pSH->AppendMenuItem(hPopup, 0, L"");
605 pSH->AppendMenuItem(
606 hPopup, WM_PWLEDIT_SELECTALL,
607 pProvider ? pProvider->LoadPopupMenuString(6) : L"&Select All");
608
609 if (m_pEdit->GetTotalWords() == 0) {
610 pSH->EnableMenuItem(hPopup, WM_PWLEDIT_SELECTALL, FALSE);
611 }
612
613 int32_t x, y;
614 PWLtoWnd(ptPopup, x, y);
615 pSH->ClientToScreen(GetAttachedHWnd(), x, y);
616 pSH->SetCursor(FXCT_ARROW);
617 int32_t nCmd = pSH->TrackPopupMenu(hPopup, x, y, GetAttachedHWnd());
618
619 switch (nCmd) {
620 case WM_PWLEDIT_UNDO:
621 Undo();
622 break;
623 case WM_PWLEDIT_REDO:
624 Redo();
625 break;
626 case WM_PWLEDIT_CUT:
627 CutText();
628 break;
629 case WM_PWLEDIT_COPY:
630 CopyText();
631 break;
632 case WM_PWLEDIT_PASTE:
633 PasteText();
634 break;
635 case WM_PWLEDIT_DELETE:
636 Clear();
637 break;
638 case WM_PWLEDIT_SELECTALL:
639 SelectAll();
640 break;
641 case WM_PWLEDIT_SUGGEST + 0:
642 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
643 m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
644 ReplaceSel(sSuggestWords[0].UTF8Decode().c_str());
645 break;
646 case WM_PWLEDIT_SUGGEST + 1:
647 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
648 m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
649 ReplaceSel(sSuggestWords[1].UTF8Decode().c_str());
650 break;
651 case WM_PWLEDIT_SUGGEST + 2:
652 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
653 m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
654 ReplaceSel(sSuggestWords[2].UTF8Decode().c_str());
655 break;
656 case WM_PWLEDIT_SUGGEST + 3:
657 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
658 m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
659 ReplaceSel(sSuggestWords[3].UTF8Decode().c_str());
660 break;
661 case WM_PWLEDIT_SUGGEST + 4:
662 SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
663 m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
664 ReplaceSel(sSuggestWords[4].UTF8Decode().c_str());
665 break;
666 default:
667 break;
668 }
669
670 pSH->DestroyMenu(hPopup);
671
672 return TRUE;
673}
674
675void CPWL_Edit::OnSetFocus() {
676 SetEditCaret(TRUE);
677
678 if (!IsReadOnly()) {
679 if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
680 pFocusHandler->OnSetFocus(this);
681 }
682
683 m_bFocus = TRUE;
684}
685
686void CPWL_Edit::OnKillFocus() {
687 ShowVScrollBar(FALSE);
688
689 m_pEdit->SelectNone();
690 SetCaret(FALSE, CPDF_Point(0.0f, 0.0f), CPDF_Point(0.0f, 0.0f));
691
692 SetCharSet(0);
693
694 if (!IsReadOnly()) {
695 if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
696 pFocusHandler->OnKillFocus(this);
697 }
698
699 m_bFocus = FALSE;
700}
701
702void CPWL_Edit::SetHorzScale(int32_t nHorzScale, FX_BOOL bPaint /* = TRUE*/) {
703 m_pEdit->SetHorzScale(nHorzScale, bPaint);
704}
705
706void CPWL_Edit::SetCharSpace(FX_FLOAT fCharSpace, FX_BOOL bPaint /* = TRUE*/) {
707 m_pEdit->SetCharSpace(fCharSpace, bPaint);
708}
709
710void CPWL_Edit::SetLineLeading(FX_FLOAT fLineLeading,
711 FX_BOOL bPaint /* = TRUE*/) {
712 m_pEdit->SetLineLeading(fLineLeading, bPaint);
713}
714
715CFX_ByteString CPWL_Edit::GetSelectAppearanceStream(
716 const CPDF_Point& ptOffset) const {
717 CPVT_WordRange wr = GetSelectWordRange();
718 return CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset, &wr);
719}
720
721CPVT_WordRange CPWL_Edit::GetSelectWordRange() const {
722 if (m_pEdit->IsSelected()) {
723 int32_t nStart = -1;
724 int32_t nEnd = -1;
725
726 m_pEdit->GetSel(nStart, nEnd);
727
728 CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStart);
729 CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEnd);
730
731 return CPVT_WordRange(wpStart, wpEnd);
732 }
733
734 return CPVT_WordRange();
735}
736
737CFX_ByteString CPWL_Edit::GetTextAppearanceStream(
738 const CPDF_Point& ptOffset) const {
739 CFX_ByteTextBuf sRet;
740 CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset);
741
742 if (sEdit.GetLength() > 0) {
743 sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEdit
744 << "ET\n";
745 }
746
747 return sRet.GetByteString();
748}
749
750CFX_ByteString CPWL_Edit::GetCaretAppearanceStream(
751 const CPDF_Point& ptOffset) const {
752 if (m_pEditCaret)
753 return m_pEditCaret->GetCaretAppearanceStream(ptOffset);
754
755 return CFX_ByteString();
756}
757
758CPDF_Point CPWL_Edit::GetWordRightBottomPoint(const CPVT_WordPlace& wpWord) {
759 CPDF_Point pt(0.0f, 0.0f);
760
761 if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
762 CPVT_WordPlace wpOld = pIterator->GetAt();
763 pIterator->SetAt(wpWord);
764 CPVT_Word word;
765 if (pIterator->GetWord(word)) {
766 pt = CPDF_Point(word.ptWord.x + word.fWidth,
767 word.ptWord.y + word.fDescent);
Lei Zhang60f507b2015-06-13 00:41:00 -0700768 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700769
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700770 pIterator->SetAt(wpOld);
771 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700772
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700773 return pt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700774}
775
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700776FX_BOOL CPWL_Edit::IsTextFull() const {
777 return m_pEdit->IsTextFull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700778}
779
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700780FX_FLOAT CPWL_Edit::GetCharArrayAutoFontSize(CPDF_Font* pFont,
781 const CPDF_Rect& rcPlate,
782 int32_t nCharArray) {
783 if (pFont && !pFont->IsStandardFont()) {
784 FX_RECT rcBBox;
785 pFont->GetFontBBox(rcBBox);
786
787 CPDF_Rect rcCell = rcPlate;
788 FX_FLOAT xdiv = rcCell.Width() / nCharArray * 1000.0f / rcBBox.Width();
789 FX_FLOAT ydiv = -rcCell.Height() * 1000.0f / rcBBox.Height();
790
791 return xdiv < ydiv ? xdiv : ydiv;
792 }
793
794 return 0.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700795}
796
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700797void CPWL_Edit::SetCharArray(int32_t nCharArray) {
798 if (HasFlag(PES_CHARARRAY) && nCharArray > 0) {
799 m_pEdit->SetCharArray(nCharArray);
800 m_pEdit->SetTextOverflow(TRUE);
801
802 if (HasFlag(PWS_AUTOFONTSIZE)) {
803 if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
804 FX_FLOAT fFontSize = GetCharArrayAutoFontSize(
805 pFontMap->GetPDFFont(0), GetClientRect(), nCharArray);
806 if (fFontSize > 0.0f) {
807 m_pEdit->SetAutoFontSize(FALSE);
808 m_pEdit->SetFontSize(fFontSize);
809 }
810 }
811 }
812 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700813}
814
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700815void CPWL_Edit::SetLimitChar(int32_t nLimitChar) {
816 m_pEdit->SetLimitChar(nLimitChar);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700817}
818
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700819void CPWL_Edit::ReplaceSel(const FX_WCHAR* csText) {
820 m_pEdit->Clear();
821 m_pEdit->InsertText(csText);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700822}
823
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700824CPDF_Rect CPWL_Edit::GetFocusRect() const {
825 return CPDF_Rect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700826}
827
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700828void CPWL_Edit::ShowVScrollBar(FX_BOOL bShow) {
829 if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
830 if (bShow) {
831 if (!pScroll->IsVisible()) {
832 pScroll->SetVisible(TRUE);
833 CPDF_Rect rcWindow = GetWindowRect();
834 m_rcOldWindow = rcWindow;
835 rcWindow.right += PWL_SCROLLBAR_WIDTH;
836 Move(rcWindow, TRUE, TRUE);
837 }
838 } else {
839 if (pScroll->IsVisible()) {
840 pScroll->SetVisible(FALSE);
841 Move(m_rcOldWindow, TRUE, TRUE);
842 }
843 }
844 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700845}
846
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700847FX_BOOL CPWL_Edit::IsVScrollBarVisible() const {
848 if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
849 return pScroll->IsVisible();
850 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700851
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700852 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700853}
854
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700855void CPWL_Edit::EnableSpellCheck(FX_BOOL bEnabled) {
856 if (bEnabled)
857 AddFlag(PES_SPELLCHECK);
858 else
859 RemoveFlag(PES_SPELLCHECK);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700860}
861
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700862FX_BOOL CPWL_Edit::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
863 if (m_bMouseDown)
864 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700865
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700866 if (nChar == FWL_VKEY_Delete) {
867 if (m_pFillerNotify) {
868 FX_BOOL bRC = TRUE;
869 FX_BOOL bExit = FALSE;
870 CFX_WideString strChange;
871 CFX_WideString strChangeEx;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700872
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700873 int nSelStart = 0;
874 int nSelEnd = 0;
875 GetSel(nSelStart, nSelEnd);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700876
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700877 if (nSelStart == nSelEnd)
878 nSelEnd = nSelStart + 1;
Lei Zhanga5b47042015-10-19 14:32:16 -0700879 m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), strChange,
880 strChangeEx, nSelStart, nSelEnd, TRUE,
881 bRC, bExit, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700882 if (!bRC)
883 return FALSE;
884 if (bExit)
885 return FALSE;
886 }
887 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700888
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700889 FX_BOOL bRet = CPWL_EditCtrl::OnKeyDown(nChar, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700890
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700891 // In case of implementation swallow the OnKeyDown event.
892 if (IsProceedtoOnChar(nChar, nFlag))
893 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700894
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700895 return bRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700896}
897
898/**
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700899*In case of implementation swallow the OnKeyDown event.
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700900*If the event is swallowed, implementation may do other unexpected things, which
901*is not the control means to do.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700902*/
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700903FX_BOOL CPWL_Edit::IsProceedtoOnChar(FX_WORD nKeyCode, FX_DWORD nFlag) {
904 FX_BOOL bCtrl = IsCTRLpressed(nFlag);
905 FX_BOOL bAlt = IsALTpressed(nFlag);
906 if (bCtrl && !bAlt) {
907 // hot keys for edit control.
908 switch (nKeyCode) {
909 case 'C':
910 case 'V':
911 case 'X':
912 case 'A':
913 case 'Z':
914 return TRUE;
915 default:
916 break;
917 }
918 }
919 // control characters.
920 switch (nKeyCode) {
921 case FWL_VKEY_Escape:
922 case FWL_VKEY_Back:
923 case FWL_VKEY_Return:
924 case FWL_VKEY_Space:
925 return TRUE;
926 default:
Lei Zhanga5b47042015-10-19 14:32:16 -0700927 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700928 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700929}
930
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700931FX_BOOL CPWL_Edit::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
932 if (m_bMouseDown)
933 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700934
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700935 FX_BOOL bRC = TRUE;
936 FX_BOOL bExit = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700937
Lei Zhanga5b47042015-10-19 14:32:16 -0700938 if (!IsCTRLpressed(nFlag)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700939 if (m_pFillerNotify) {
940 CFX_WideString swChange;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700941
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700942 int nSelStart = 0;
943 int nSelEnd = 0;
944 GetSel(nSelStart, nSelEnd);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700945
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700946 switch (nChar) {
947 case FWL_VKEY_Back:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700948 if (nSelStart == nSelEnd)
949 nSelStart = nSelEnd - 1;
950 break;
951 case FWL_VKEY_Return:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700952 break;
953 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700954 swChange += nChar;
955 break;
956 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700957
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700958 CFX_WideString strChangeEx;
Lei Zhanga5b47042015-10-19 14:32:16 -0700959 m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swChange,
960 strChangeEx, nSelStart, nSelEnd, TRUE,
961 bRC, bExit, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700962 }
963 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700964
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700965 if (!bRC)
966 return TRUE;
967 if (bExit)
968 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700969
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700970 if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
971 int32_t nOldCharSet = GetCharSet();
972 int32_t nNewCharSet = pFontMap->CharSetFromUnicode(nChar, DEFAULT_CHARSET);
973 if (nOldCharSet != nNewCharSet) {
974 SetCharSet(nNewCharSet);
975 }
976 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700977
Lei Zhanga5b47042015-10-19 14:32:16 -0700978 return CPWL_EditCtrl::OnChar(nChar, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700979}
980
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700981FX_BOOL CPWL_Edit::OnMouseWheel(short zDelta,
982 const CPDF_Point& point,
983 FX_DWORD nFlag) {
984 if (HasFlag(PES_MULTILINE)) {
985 CPDF_Point ptScroll = GetScrollPos();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700986
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700987 if (zDelta > 0) {
988 ptScroll.y += GetFontSize();
989 } else {
990 ptScroll.y -= GetFontSize();
991 }
992 SetScrollPos(ptScroll);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700993
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700994 return TRUE;
995 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700996
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700997 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700998}
999
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001000void CPWL_Edit::OnInsertReturn(const CPVT_WordPlace& place,
1001 const CPVT_WordPlace& oldplace) {
1002 if (HasFlag(PES_SPELLCHECK)) {
1003 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1004 GetLatinWordsRange(place)));
1005 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001006
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001007 if (m_pEditNotify) {
1008 m_pEditNotify->OnInsertReturn(place, oldplace);
1009 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001010}
1011
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001012void CPWL_Edit::OnBackSpace(const CPVT_WordPlace& place,
1013 const CPVT_WordPlace& oldplace) {
1014 if (HasFlag(PES_SPELLCHECK)) {
1015 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1016 GetLatinWordsRange(place)));
1017 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001018
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001019 if (m_pEditNotify) {
1020 m_pEditNotify->OnBackSpace(place, oldplace);
1021 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001022}
1023
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001024void CPWL_Edit::OnDelete(const CPVT_WordPlace& place,
1025 const CPVT_WordPlace& oldplace) {
1026 if (HasFlag(PES_SPELLCHECK)) {
1027 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1028 GetLatinWordsRange(place)));
1029 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001030
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001031 if (m_pEditNotify) {
1032 m_pEditNotify->OnDelete(place, oldplace);
1033 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001034}
1035
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001036void CPWL_Edit::OnClear(const CPVT_WordPlace& place,
1037 const CPVT_WordPlace& oldplace) {
1038 if (HasFlag(PES_SPELLCHECK)) {
1039 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1040 GetLatinWordsRange(place)));
1041 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001042
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001043 if (m_pEditNotify) {
1044 m_pEditNotify->OnClear(place, oldplace);
1045 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001046}
1047
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001048void CPWL_Edit::OnInsertWord(const CPVT_WordPlace& place,
1049 const CPVT_WordPlace& oldplace) {
1050 if (HasFlag(PES_SPELLCHECK)) {
1051 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1052 GetLatinWordsRange(place)));
1053 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001054
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001055 if (m_pEditNotify) {
1056 m_pEditNotify->OnInsertWord(place, oldplace);
1057 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001058}
1059
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001060void CPWL_Edit::OnSetText(const CPVT_WordPlace& place,
1061 const CPVT_WordPlace& oldplace) {}
1062
1063void CPWL_Edit::OnInsertText(const CPVT_WordPlace& place,
1064 const CPVT_WordPlace& oldplace) {
1065 if (HasFlag(PES_SPELLCHECK)) {
1066 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
1067 GetLatinWordsRange(place)));
1068 }
1069
1070 if (m_pEditNotify) {
1071 m_pEditNotify->OnInsertText(place, oldplace);
1072 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001073}
1074
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001075void CPWL_Edit::OnAddUndo(IFX_Edit_UndoItem* pUndoItem) {
1076 if (m_pEditNotify) {
1077 m_pEditNotify->OnAddUndo(this);
1078 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001079}
1080
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001081CPVT_WordRange CPWL_Edit::CombineWordRange(const CPVT_WordRange& wr1,
1082 const CPVT_WordRange& wr2) {
1083 CPVT_WordRange wrRet;
1084
1085 if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0) {
1086 wrRet.BeginPos = wr1.BeginPos;
1087 } else {
1088 wrRet.BeginPos = wr2.BeginPos;
1089 }
1090
1091 if (wr1.EndPos.WordCmp(wr2.EndPos) < 0) {
1092 wrRet.EndPos = wr2.EndPos;
1093 } else {
1094 wrRet.EndPos = wr1.EndPos;
1095 }
1096
1097 return wrRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001098}
1099
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001100CPVT_WordRange CPWL_Edit::GetLatinWordsRange(const CPDF_Point& point) const {
1101 return GetSameWordsRange(m_pEdit->SearchWordPlace(point), TRUE, FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001102}
1103
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001104CPVT_WordRange CPWL_Edit::GetLatinWordsRange(
1105 const CPVT_WordPlace& place) const {
1106 return GetSameWordsRange(place, TRUE, FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001107}
1108
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001109CPVT_WordRange CPWL_Edit::GetArabicWordsRange(
1110 const CPVT_WordPlace& place) const {
1111 return GetSameWordsRange(place, FALSE, TRUE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001112}
1113
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001114#define PWL_ISARABICWORD(word) \
1115 ((word >= 0x0600 && word <= 0x06FF) || (word >= 0xFB50 && word <= 0xFEFC))
1116
1117CPVT_WordRange CPWL_Edit::GetSameWordsRange(const CPVT_WordPlace& place,
1118 FX_BOOL bLatin,
1119 FX_BOOL bArabic) const {
1120 CPVT_WordRange range;
1121
1122 if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
1123 CPVT_Word wordinfo;
1124 CPVT_WordPlace wpStart(place), wpEnd(place);
1125 pIterator->SetAt(place);
1126
1127 if (bLatin) {
1128 while (pIterator->NextWord()) {
1129 if (pIterator->GetWord(wordinfo) &&
1130 FX_EDIT_ISLATINWORD(wordinfo.Word)) {
1131 wpEnd = pIterator->GetAt();
1132 continue;
1133 } else
1134 break;
1135 };
1136 } else if (bArabic) {
1137 while (pIterator->NextWord()) {
1138 if (pIterator->GetWord(wordinfo) && PWL_ISARABICWORD(wordinfo.Word)) {
1139 wpEnd = pIterator->GetAt();
1140 continue;
1141 } else
1142 break;
1143 };
1144 }
1145
1146 pIterator->SetAt(place);
1147
1148 if (bLatin) {
1149 do {
1150 if (pIterator->GetWord(wordinfo) &&
1151 FX_EDIT_ISLATINWORD(wordinfo.Word)) {
1152 continue;
1153 } else {
1154 wpStart = pIterator->GetAt();
1155 break;
1156 }
1157 } while (pIterator->PrevWord());
1158 } else if (bArabic) {
1159 do {
1160 if (pIterator->GetWord(wordinfo) && PWL_ISARABICWORD(wordinfo.Word)) {
1161 continue;
1162 } else {
1163 wpStart = pIterator->GetAt();
1164 break;
1165 }
1166 } while (pIterator->PrevWord());
1167 }
1168
1169 range.Set(wpStart, wpEnd);
1170 }
1171
1172 return range;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001173}
1174
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001175void CPWL_Edit::GeneratePageObjects(
1176 CPDF_PageObjects* pPageObjects,
1177 const CPDF_Point& ptOffset,
1178 CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
1179 IFX_Edit::GeneratePageObjects(
1180 pPageObjects, m_pEdit, ptOffset, NULL,
1181 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
1182 ObjArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001183}
1184
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001185void CPWL_Edit::GeneratePageObjects(CPDF_PageObjects* pPageObjects,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001186 const CPDF_Point& ptOffset) {
1187 CFX_ArrayTemplate<CPDF_TextObject*> ObjArray;
1188 IFX_Edit::GeneratePageObjects(
1189 pPageObjects, m_pEdit, ptOffset, NULL,
1190 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
1191 ObjArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001192}