blob: 90572746dafbe4320d7945e99b520321a16f647e [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
dan sinclair89e904b2016-03-23 19:29:15 -04007#include "fpdfsdk/pdfwindow/PWL_Edit.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -08008
Tom Sepez52f69b32017-03-21 13:42:38 -07009#include <algorithm>
Lei Zhanga99de0e2017-02-27 14:45:56 -080010#include <memory>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050011#include <vector>
12
dsinclairbc5e6d22016-10-04 11:08:49 -070013#include "core/fpdfapi/font/cpdf_font.h"
dsinclair1727aee2016-09-29 13:12:56 -070014#include "core/fpdfdoc/cpvt_word.h"
dsinclaira52ab742016-09-29 13:59:29 -070015#include "core/fxcrt/fx_safe_types.h"
Tom Sepez8a6fdad2017-05-09 15:03:33 -070016#include "core/fxcrt/xml/cxml_content.h"
Dan Sinclair908c8482017-03-30 14:33:28 -040017#include "core/fxcrt/xml/cxml_element.h"
dsinclair74a34fc2016-09-29 16:41:42 -070018#include "core/fxge/cfx_graphstatedata.h"
19#include "core/fxge/cfx_pathdata.h"
20#include "core/fxge/cfx_renderdevice.h"
21#include "core/fxge/fx_font.h"
dsinclair0bb385b2016-09-29 17:03:59 -070022#include "fpdfsdk/fxedit/fxet_edit.h"
dan sinclair89e904b2016-03-23 19:29:15 -040023#include "fpdfsdk/pdfwindow/PWL_Caret.h"
24#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
25#include "fpdfsdk/pdfwindow/PWL_FontMap.h"
26#include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
27#include "fpdfsdk/pdfwindow/PWL_Utils.h"
28#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080029#include "public/fpdf_fwlevent.h"
Tom Sepezab277682016-02-17 10:07:21 -080030#include "third_party/base/stl_util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070031
Nico Weber9d8ec5a2015-08-04 13:00:21 -070032CPWL_Edit::CPWL_Edit()
tsepez4cf55152016-11-02 14:37:54 -070033 : m_pFillerNotify(nullptr), m_bFocus(false), m_pFormFiller(nullptr) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070034
Nico Weber9d8ec5a2015-08-04 13:00:21 -070035CPWL_Edit::~CPWL_Edit() {
tsepez4cf55152016-11-02 14:37:54 -070036 ASSERT(m_bFocus == false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070037}
38
Nico Weber9d8ec5a2015-08-04 13:00:21 -070039CFX_ByteString CPWL_Edit::GetClassName() const {
40 return PWL_CLASSNAME_EDIT;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070041}
42
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043void CPWL_Edit::OnDestroy() {}
44
tsepez067990c2016-09-13 06:46:40 -070045void CPWL_Edit::SetText(const CFX_WideString& csText) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046 CFX_WideString swText = csText;
Lei Zhanga99de0e2017-02-27 14:45:56 -080047 if (!HasFlag(PES_RICH)) {
48 m_pEdit->SetText(swText);
49 return;
50 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070051
Lei Zhanga99de0e2017-02-27 14:45:56 -080052 CFX_ByteString sValue = CFX_ByteString::FromUnicode(swText);
53 std::unique_ptr<CXML_Element> pXML(
54 CXML_Element::Parse(sValue.c_str(), sValue.GetLength()));
55 if (!pXML) {
56 m_pEdit->SetText(swText);
57 return;
58 }
Lei Zhanga99de0e2017-02-27 14:45:56 -080059 swText.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060
Tom Sepez8a6fdad2017-05-09 15:03:33 -070061 bool bFirst = true;
62 int32_t nCount = pXML->CountChildren();
Lei Zhanga99de0e2017-02-27 14:45:56 -080063 for (int32_t i = 0; i < nCount; i++) {
Tom Sepez8a6fdad2017-05-09 15:03:33 -070064 CXML_Element* pSubElement = ToElement(pXML->GetChild(i));
65 if (!pSubElement || !pSubElement->GetTagName().EqualNoCase("p"))
Lei Zhanga99de0e2017-02-27 14:45:56 -080066 continue;
67
Tom Sepez8a6fdad2017-05-09 15:03:33 -070068 CFX_WideString swSection;
69 int nSubChild = pSubElement->CountChildren();
70 for (int32_t j = 0; j < nSubChild; j++) {
71 CXML_Content* pSubContent = ToContent(pSubElement->GetChild(j));
72 if (pSubContent)
73 swSection += pSubContent->m_Content;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070074 }
Tom Sepez8a6fdad2017-05-09 15:03:33 -070075 if (bFirst)
76 bFirst = false;
77 else
78 swText += FWL_VKEY_Return;
79 swText += swSection;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080 }
81
tsepez067990c2016-09-13 06:46:40 -070082 m_pEdit->SetText(swText);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070083}
84
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085void CPWL_Edit::RePosChildWnd() {
86 if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -080087 CFX_FloatRect rcWindow = m_rcOldWindow;
88 CFX_FloatRect rcVScroll =
89 CFX_FloatRect(rcWindow.right, rcWindow.bottom,
90 rcWindow.right + PWL_SCROLLBAR_WIDTH, rcWindow.top);
tsepez4cf55152016-11-02 14:37:54 -070091 pVSB->Move(rcVScroll, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070093
Nico Weber9d8ec5a2015-08-04 13:00:21 -070094 if (m_pEditCaret && !HasFlag(PES_TEXTOVERFLOW))
95 m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(
Dan Sinclair50cce602016-02-24 09:51:16 -050096 GetClientRect(), 1.0f)); // +1 for caret beside border
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070097
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098 CPWL_EditCtrl::RePosChildWnd();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070099}
100
Tom Sepez281a9ea2016-02-26 14:24:28 -0800101CFX_FloatRect CPWL_Edit::GetClientRect() const {
102 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(
Dan Sinclair05df0752017-03-14 14:43:42 -0400103 GetWindowRect(), (float)(GetBorderWidth() + GetInnerBorderWidth()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104
105 if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
106 if (pVSB->IsVisible()) {
107 rcClient.right -= PWL_SCROLLBAR_WIDTH;
108 }
109 }
110
111 return rcClient;
112}
113
tsepez4cf55152016-11-02 14:37:54 -0700114void CPWL_Edit::SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700115 m_pEdit->SetAlignmentV((int32_t)nFormat, bPaint);
116}
117
tsepez4cf55152016-11-02 14:37:54 -0700118bool CPWL_Edit::CanSelectAll() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119 return GetSelectWordRange() != m_pEdit->GetWholeWordRange();
120}
121
tsepez4cf55152016-11-02 14:37:54 -0700122bool CPWL_Edit::CanClear() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 return !IsReadOnly() && m_pEdit->IsSelected();
124}
125
tsepez4cf55152016-11-02 14:37:54 -0700126bool CPWL_Edit::CanCopy() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 return !HasFlag(PES_PASSWORD) && !HasFlag(PES_NOREAD) &&
128 m_pEdit->IsSelected();
129}
130
tsepez4cf55152016-11-02 14:37:54 -0700131bool CPWL_Edit::CanCut() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 return CanCopy() && !IsReadOnly();
133}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134void CPWL_Edit::CutText() {
135 if (!CanCut())
136 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137 m_pEdit->Clear();
138}
139
140void CPWL_Edit::OnCreated() {
141 CPWL_EditCtrl::OnCreated();
142
143 if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
144 pScroll->RemoveFlag(PWS_AUTOTRANSPARENT);
145 pScroll->SetTransparency(255);
146 }
147
148 SetParamByFlag();
149
150 m_rcOldWindow = GetWindowRect();
151
152 m_pEdit->SetOprNotify(this);
tsepez4cf55152016-11-02 14:37:54 -0700153 m_pEdit->EnableOprNotify(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700154}
155
156void CPWL_Edit::SetParamByFlag() {
157 if (HasFlag(PES_RIGHT)) {
tsepez4cf55152016-11-02 14:37:54 -0700158 m_pEdit->SetAlignmentH(2, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 } else if (HasFlag(PES_MIDDLE)) {
tsepez4cf55152016-11-02 14:37:54 -0700160 m_pEdit->SetAlignmentH(1, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 } else {
tsepez4cf55152016-11-02 14:37:54 -0700162 m_pEdit->SetAlignmentH(0, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 }
164
165 if (HasFlag(PES_BOTTOM)) {
tsepez4cf55152016-11-02 14:37:54 -0700166 m_pEdit->SetAlignmentV(2, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 } else if (HasFlag(PES_CENTER)) {
tsepez4cf55152016-11-02 14:37:54 -0700168 m_pEdit->SetAlignmentV(1, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700169 } else {
tsepez4cf55152016-11-02 14:37:54 -0700170 m_pEdit->SetAlignmentV(0, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 }
172
173 if (HasFlag(PES_PASSWORD)) {
tsepez4cf55152016-11-02 14:37:54 -0700174 m_pEdit->SetPasswordChar('*', false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 }
176
tsepez4cf55152016-11-02 14:37:54 -0700177 m_pEdit->SetMultiLine(HasFlag(PES_MULTILINE), false);
178 m_pEdit->SetAutoReturn(HasFlag(PES_AUTORETURN), false);
179 m_pEdit->SetAutoFontSize(HasFlag(PWS_AUTOFONTSIZE), false);
180 m_pEdit->SetAutoScroll(HasFlag(PES_AUTOSCROLL), false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181 m_pEdit->EnableUndo(HasFlag(PES_UNDO));
182
183 if (HasFlag(PES_TEXTOVERFLOW)) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800184 SetClipRect(CFX_FloatRect(0.0f, 0.0f, 0.0f, 0.0f));
tsepez4cf55152016-11-02 14:37:54 -0700185 m_pEdit->SetTextOverflow(true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186 } else {
187 if (m_pEditCaret) {
188 m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(
Dan Sinclair50cce602016-02-24 09:51:16 -0500189 GetClientRect(), 1.0f)); // +1 for caret beside border
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190 }
191 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700192}
193
194void CPWL_Edit::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
195 CPWL_Wnd::GetThisAppearanceStream(sAppStream);
196
Tom Sepez281a9ea2016-02-26 14:24:28 -0800197 CFX_FloatRect rcClient = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700198 CFX_ByteTextBuf sLine;
199
200 int32_t nCharArray = m_pEdit->GetCharArray();
201
202 if (nCharArray > 0) {
203 switch (GetBorderStyle()) {
dsinclair92cb5e52016-05-16 11:38:28 -0700204 case BorderStyle::SOLID: {
tsepez4cf55152016-11-02 14:37:54 -0700205 sLine << "q\n"
206 << GetBorderWidth() << " w\n"
207 << CPWL_Utils::GetColorAppStream(GetBorderColor(), false)
tsepez4c3debb2016-04-08 12:20:38 -0700208 .AsStringC()
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700209 << " 2 J 0 j\n";
210
211 for (int32_t i = 1; i < nCharArray; i++) {
212 sLine << rcClient.left +
213 ((rcClient.right - rcClient.left) / nCharArray) * i
214 << " " << rcClient.bottom << " m\n"
215 << rcClient.left +
216 ((rcClient.right - rcClient.left) / nCharArray) * i
217 << " " << rcClient.top << " l S\n";
218 }
219
220 sLine << "Q\n";
dsinclair92cb5e52016-05-16 11:38:28 -0700221 break;
222 }
223 case BorderStyle::DASH: {
tsepez4cf55152016-11-02 14:37:54 -0700224 sLine << "q\n"
225 << GetBorderWidth() << " w\n"
226 << CPWL_Utils::GetColorAppStream(GetBorderColor(), false)
tsepez4c3debb2016-04-08 12:20:38 -0700227 .AsStringC()
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228 << " 2 J 0 j\n"
229 << "[" << GetBorderDash().nDash << " " << GetBorderDash().nGap
230 << "] " << GetBorderDash().nPhase << " d\n";
231
232 for (int32_t i = 1; i < nCharArray; i++) {
233 sLine << rcClient.left +
234 ((rcClient.right - rcClient.left) / nCharArray) * i
235 << " " << rcClient.bottom << " m\n"
236 << rcClient.left +
237 ((rcClient.right - rcClient.left) / nCharArray) * i
238 << " " << rcClient.top << " l S\n";
239 }
240
241 sLine << "Q\n";
dsinclair92cb5e52016-05-16 11:38:28 -0700242 break;
243 }
244 default:
245 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 }
247 }
248
249 sAppStream << sLine;
250
251 CFX_ByteTextBuf sText;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500252 CFX_PointF ptOffset;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700253 CPVT_WordRange wrWhole = m_pEdit->GetWholeWordRange();
254 CPVT_WordRange wrSelect = GetSelectWordRange();
255 CPVT_WordRange wrVisible =
tsepez63f545c2016-09-13 16:08:49 -0700256 HasFlag(PES_TEXTOVERFLOW) ? wrWhole : m_pEdit->GetVisibleWordRange();
257
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258 CPVT_WordRange wrSelBefore(wrWhole.BeginPos, wrSelect.BeginPos);
259 CPVT_WordRange wrSelAfter(wrSelect.EndPos, wrWhole.EndPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260 CPVT_WordRange wrTemp =
261 CPWL_Utils::OverlapWordRange(GetSelectWordRange(), wrVisible);
262 CFX_ByteString sEditSel =
dsinclaire35af1e2016-07-13 11:26:20 -0700263 CPWL_Utils::GetEditSelAppStream(m_pEdit.get(), ptOffset, &wrTemp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700264
265 if (sEditSel.GetLength() > 0)
tsepez4c3debb2016-04-08 12:20:38 -0700266 sText << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELBACKCOLOR).AsStringC()
267 << sEditSel.AsStringC();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268
269 wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelBefore);
270 CFX_ByteString sEditBefore = CPWL_Utils::GetEditAppStream(
dsinclaire35af1e2016-07-13 11:26:20 -0700271 m_pEdit.get(), ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700272 m_pEdit->GetPasswordChar());
273
274 if (sEditBefore.GetLength() > 0)
Dan Sinclaira0061af2017-02-23 09:25:17 -0500275 sText << "BT\n"
276 << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC()
tsepez4c3debb2016-04-08 12:20:38 -0700277 << sEditBefore.AsStringC() << "ET\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278
279 wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelect);
280 CFX_ByteString sEditMid = CPWL_Utils::GetEditAppStream(
dsinclaire35af1e2016-07-13 11:26:20 -0700281 m_pEdit.get(), ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282 m_pEdit->GetPasswordChar());
283
284 if (sEditMid.GetLength() > 0)
285 sText << "BT\n"
286 << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1))
tsepez4c3debb2016-04-08 12:20:38 -0700287 .AsStringC()
288 << sEditMid.AsStringC() << "ET\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700289
290 wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelAfter);
291 CFX_ByteString sEditAfter = CPWL_Utils::GetEditAppStream(
dsinclaire35af1e2016-07-13 11:26:20 -0700292 m_pEdit.get(), ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293 m_pEdit->GetPasswordChar());
294
295 if (sEditAfter.GetLength() > 0)
Dan Sinclaira0061af2017-02-23 09:25:17 -0500296 sText << "BT\n"
297 << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC()
tsepez4c3debb2016-04-08 12:20:38 -0700298 << sEditAfter.AsStringC() << "ET\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700299
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300 if (sText.GetLength() > 0) {
weilidb444d22016-06-02 15:48:15 -0700301 CFX_FloatRect rect = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700302 sAppStream << "q\n/Tx BMC\n";
303
304 if (!HasFlag(PES_TEXTOVERFLOW))
weilidb444d22016-06-02 15:48:15 -0700305 sAppStream << rect.left << " " << rect.bottom << " "
306 << rect.right - rect.left << " " << rect.top - rect.bottom
307 << " re W n\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700308
309 sAppStream << sText;
310
311 sAppStream << "EMC\nQ\n";
312 }
313}
314
315void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800316 CFX_Matrix* pUser2Device) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
318
Tom Sepez281a9ea2016-02-26 14:24:28 -0800319 CFX_FloatRect rcClient = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700320 CFX_ByteTextBuf sLine;
321
322 int32_t nCharArray = m_pEdit->GetCharArray();
323 FX_SAFE_INT32 nCharArraySafe = nCharArray;
324 nCharArraySafe -= 1;
325 nCharArraySafe *= 2;
326
327 if (nCharArray > 0 && nCharArraySafe.IsValid()) {
328 switch (GetBorderStyle()) {
dsinclair92cb5e52016-05-16 11:38:28 -0700329 case BorderStyle::SOLID: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700330 CFX_GraphStateData gsd;
Dan Sinclair05df0752017-03-14 14:43:42 -0400331 gsd.m_LineWidth = (float)GetBorderWidth();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700332
333 CFX_PathData path;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700334
335 for (int32_t i = 0; i < nCharArray - 1; i++) {
Dan Sinclaire4602322017-02-15 11:07:32 -0500336 path.AppendPoint(
dan sinclairb147e072017-02-22 19:56:15 -0500337 CFX_PointF(
338 rcClient.left +
339 ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
340 rcClient.bottom),
341 FXPT_TYPE::MoveTo, false);
Dan Sinclaire4602322017-02-15 11:07:32 -0500342 path.AppendPoint(
dan sinclairb147e072017-02-22 19:56:15 -0500343 CFX_PointF(
344 rcClient.left +
345 ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
346 rcClient.top),
347 FXPT_TYPE::LineTo, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700348 }
Dan Sinclaire4602322017-02-15 11:07:32 -0500349 if (!path.GetPoints().empty()) {
Dan Sinclairfc54e052017-02-23 09:59:05 -0500350 pDevice->DrawPath(&path, pUser2Device, &gsd, 0,
351 GetBorderColor().ToFXColor(255), FXFILL_ALTERNATE);
dsinclair92cb5e52016-05-16 11:38:28 -0700352 }
353 break;
354 }
355 case BorderStyle::DASH: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700356 CFX_GraphStateData gsd;
Dan Sinclair05df0752017-03-14 14:43:42 -0400357 gsd.m_LineWidth = (float)GetBorderWidth();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700358
359 gsd.SetDashCount(2);
Dan Sinclair05df0752017-03-14 14:43:42 -0400360 gsd.m_DashArray[0] = (float)GetBorderDash().nDash;
361 gsd.m_DashArray[1] = (float)GetBorderDash().nGap;
362 gsd.m_DashPhase = (float)GetBorderDash().nPhase;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363
364 CFX_PathData path;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700365 for (int32_t i = 0; i < nCharArray - 1; i++) {
Dan Sinclaire4602322017-02-15 11:07:32 -0500366 path.AppendPoint(
dan sinclairb147e072017-02-22 19:56:15 -0500367 CFX_PointF(
368 rcClient.left +
369 ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
370 rcClient.bottom),
371 FXPT_TYPE::MoveTo, false);
Dan Sinclaire4602322017-02-15 11:07:32 -0500372 path.AppendPoint(
dan sinclairb147e072017-02-22 19:56:15 -0500373 CFX_PointF(
374 rcClient.left +
375 ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
376 rcClient.top),
377 FXPT_TYPE::LineTo, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700378 }
Dan Sinclaire4602322017-02-15 11:07:32 -0500379 if (!path.GetPoints().empty()) {
Dan Sinclairfc54e052017-02-23 09:59:05 -0500380 pDevice->DrawPath(&path, pUser2Device, &gsd, 0,
381 GetBorderColor().ToFXColor(255), FXFILL_ALTERNATE);
dsinclair92cb5e52016-05-16 11:38:28 -0700382 }
383 break;
384 }
385 default:
386 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700387 }
388 }
389
Tom Sepez281a9ea2016-02-26 14:24:28 -0800390 CFX_FloatRect rcClip;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700391 CPVT_WordRange wrRange = m_pEdit->GetVisibleWordRange();
thestig1cd352e2016-06-07 17:53:06 -0700392 CPVT_WordRange* pRange = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700393 if (!HasFlag(PES_TEXTOVERFLOW)) {
394 rcClip = GetClientRect();
395 pRange = &wrRange;
396 }
tsepez63f545c2016-09-13 16:08:49 -0700397
dsinclairb9590102016-04-27 06:38:59 -0700398 CFX_SystemHandler* pSysHandler = GetSystemHandler();
Dan Sinclairfc54e052017-02-23 09:59:05 -0500399 CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pEdit.get(),
400 GetTextColor().ToFXColor(GetTransparency()), rcClip,
401 CFX_PointF(), pRange, pSysHandler, m_pFormFiller);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700402}
403
Dan Sinclairf528eee2017-02-14 11:52:07 -0500404bool CPWL_Edit::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700405 CPWL_Wnd::OnLButtonDown(point, nFlag);
406
407 if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
408 if (m_bMouseDown)
409 InvalidateRect();
410
tsepez4cf55152016-11-02 14:37:54 -0700411 m_bMouseDown = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700412 SetCapture();
413
414 m_pEdit->OnMouseDown(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
415 }
416
tsepez4cf55152016-11-02 14:37:54 -0700417 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700418}
419
Dan Sinclairf528eee2017-02-14 11:52:07 -0500420bool CPWL_Edit::OnLButtonDblClk(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700421 CPWL_Wnd::OnLButtonDblClk(point, nFlag);
422
423 if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
424 m_pEdit->SelectAll();
425 }
426
tsepez4cf55152016-11-02 14:37:54 -0700427 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700428}
429
Dan Sinclairf528eee2017-02-14 11:52:07 -0500430bool CPWL_Edit::OnRButtonUp(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700431 if (m_bMouseDown)
tsepez4cf55152016-11-02 14:37:54 -0700432 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700433
434 CPWL_Wnd::OnRButtonUp(point, nFlag);
435
436 if (!HasFlag(PES_TEXTOVERFLOW) && !ClientHitTest(point))
tsepez4cf55152016-11-02 14:37:54 -0700437 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700438
dsinclairb9590102016-04-27 06:38:59 -0700439 CFX_SystemHandler* pSH = GetSystemHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700440 if (!pSH)
tsepez4cf55152016-11-02 14:37:54 -0700441 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700442
443 SetFocus();
444
tsepez4cf55152016-11-02 14:37:54 -0700445 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700446}
447
448void CPWL_Edit::OnSetFocus() {
tsepez4cf55152016-11-02 14:37:54 -0700449 SetEditCaret(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700450 if (!IsReadOnly()) {
451 if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
452 pFocusHandler->OnSetFocus(this);
453 }
tsepez4cf55152016-11-02 14:37:54 -0700454 m_bFocus = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700455}
456
457void CPWL_Edit::OnKillFocus() {
tsepez4cf55152016-11-02 14:37:54 -0700458 ShowVScrollBar(false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700459 m_pEdit->SelectNone();
Dan Sinclairf528eee2017-02-14 11:52:07 -0500460 SetCaret(false, CFX_PointF(), CFX_PointF());
Dan Sinclairf51a02a2017-04-19 12:46:53 -0400461 SetCharSet(FX_CHARSET_ANSI);
tsepez4cf55152016-11-02 14:37:54 -0700462 m_bFocus = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700463}
464
Dan Sinclair05df0752017-03-14 14:43:42 -0400465void CPWL_Edit::SetCharSpace(float fCharSpace) {
dsinclairefd5a992016-07-18 10:04:07 -0700466 m_pEdit->SetCharSpace(fCharSpace);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700467}
468
469CFX_ByteString CPWL_Edit::GetSelectAppearanceStream(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500470 const CFX_PointF& ptOffset) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700471 CPVT_WordRange wr = GetSelectWordRange();
dsinclaire35af1e2016-07-13 11:26:20 -0700472 return CPWL_Utils::GetEditSelAppStream(m_pEdit.get(), ptOffset, &wr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700473}
474
475CPVT_WordRange CPWL_Edit::GetSelectWordRange() const {
476 if (m_pEdit->IsSelected()) {
477 int32_t nStart = -1;
478 int32_t nEnd = -1;
479
480 m_pEdit->GetSel(nStart, nEnd);
481
482 CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStart);
483 CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEnd);
484
485 return CPVT_WordRange(wpStart, wpEnd);
486 }
487
488 return CPVT_WordRange();
489}
490
491CFX_ByteString CPWL_Edit::GetTextAppearanceStream(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500492 const CFX_PointF& ptOffset) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700493 CFX_ByteTextBuf sRet;
dsinclaire35af1e2016-07-13 11:26:20 -0700494 CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit.get(), ptOffset);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700495 if (sEdit.GetLength() > 0) {
Dan Sinclaira0061af2017-02-23 09:25:17 -0500496 sRet << "BT\n"
497 << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC()
tsepez4c3debb2016-04-08 12:20:38 -0700498 << sEdit.AsStringC() << "ET\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700499 }
tsepez71a452f2016-05-13 17:51:27 -0700500 return sRet.MakeString();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700501}
502
503CFX_ByteString CPWL_Edit::GetCaretAppearanceStream(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500504 const CFX_PointF& ptOffset) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700505 if (m_pEditCaret)
506 return m_pEditCaret->GetCaretAppearanceStream(ptOffset);
507
508 return CFX_ByteString();
509}
510
Dan Sinclairf528eee2017-02-14 11:52:07 -0500511CFX_PointF CPWL_Edit::GetWordRightBottomPoint(const CPVT_WordPlace& wpWord) {
dsinclaire35af1e2016-07-13 11:26:20 -0700512 CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
thestig821d59e2016-05-11 12:59:22 -0700513 CPVT_WordPlace wpOld = pIterator->GetAt();
514 pIterator->SetAt(wpWord);
tsepez63f545c2016-09-13 16:08:49 -0700515
Dan Sinclairf528eee2017-02-14 11:52:07 -0500516 CFX_PointF pt;
thestig821d59e2016-05-11 12:59:22 -0700517 CPVT_Word word;
518 if (pIterator->GetWord(word)) {
Dan Sinclairf528eee2017-02-14 11:52:07 -0500519 pt = CFX_PointF(word.ptWord.x + word.fWidth, word.ptWord.y + word.fDescent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700520 }
thestig821d59e2016-05-11 12:59:22 -0700521 pIterator->SetAt(wpOld);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700522 return pt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700523}
524
tsepez4cf55152016-11-02 14:37:54 -0700525bool CPWL_Edit::IsTextFull() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700526 return m_pEdit->IsTextFull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700527}
528
Dan Sinclair05df0752017-03-14 14:43:42 -0400529float CPWL_Edit::GetCharArrayAutoFontSize(CPDF_Font* pFont,
530 const CFX_FloatRect& rcPlate,
531 int32_t nCharArray) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700532 if (pFont && !pFont->IsStandardFont()) {
533 FX_RECT rcBBox;
534 pFont->GetFontBBox(rcBBox);
535
Tom Sepez281a9ea2016-02-26 14:24:28 -0800536 CFX_FloatRect rcCell = rcPlate;
Dan Sinclair05df0752017-03-14 14:43:42 -0400537 float xdiv = rcCell.Width() / nCharArray * 1000.0f / rcBBox.Width();
538 float ydiv = -rcCell.Height() * 1000.0f / rcBBox.Height();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700539
540 return xdiv < ydiv ? xdiv : ydiv;
541 }
542
543 return 0.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700544}
545
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700546void CPWL_Edit::SetCharArray(int32_t nCharArray) {
547 if (HasFlag(PES_CHARARRAY) && nCharArray > 0) {
548 m_pEdit->SetCharArray(nCharArray);
tsepez4cf55152016-11-02 14:37:54 -0700549 m_pEdit->SetTextOverflow(true, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700550
551 if (HasFlag(PWS_AUTOFONTSIZE)) {
dsinclairc7a73492016-04-05 12:01:42 -0700552 if (IPVT_FontMap* pFontMap = GetFontMap()) {
Dan Sinclair05df0752017-03-14 14:43:42 -0400553 float fFontSize = GetCharArrayAutoFontSize(pFontMap->GetPDFFont(0),
554 GetClientRect(), nCharArray);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700555 if (fFontSize > 0.0f) {
tsepez4cf55152016-11-02 14:37:54 -0700556 m_pEdit->SetAutoFontSize(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700557 m_pEdit->SetFontSize(fFontSize);
558 }
559 }
560 }
561 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700562}
563
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700564void CPWL_Edit::SetLimitChar(int32_t nLimitChar) {
565 m_pEdit->SetLimitChar(nLimitChar);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700566}
567
tsepez067990c2016-09-13 06:46:40 -0700568void CPWL_Edit::ReplaceSel(const CFX_WideString& wsText) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700569 m_pEdit->Clear();
Dan Sinclairf51a02a2017-04-19 12:46:53 -0400570 m_pEdit->InsertText(wsText, FX_CHARSET_Default);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700571}
572
Tom Sepez281a9ea2016-02-26 14:24:28 -0800573CFX_FloatRect CPWL_Edit::GetFocusRect() const {
574 return CFX_FloatRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700575}
576
tsepez4cf55152016-11-02 14:37:54 -0700577void CPWL_Edit::ShowVScrollBar(bool bShow) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700578 if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
579 if (bShow) {
580 if (!pScroll->IsVisible()) {
tsepez4cf55152016-11-02 14:37:54 -0700581 pScroll->SetVisible(true);
Tom Sepez281a9ea2016-02-26 14:24:28 -0800582 CFX_FloatRect rcWindow = GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700583 m_rcOldWindow = rcWindow;
584 rcWindow.right += PWL_SCROLLBAR_WIDTH;
tsepez4cf55152016-11-02 14:37:54 -0700585 Move(rcWindow, true, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700586 }
587 } else {
588 if (pScroll->IsVisible()) {
tsepez4cf55152016-11-02 14:37:54 -0700589 pScroll->SetVisible(false);
590 Move(m_rcOldWindow, true, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700591 }
592 }
593 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700594}
595
tsepez4cf55152016-11-02 14:37:54 -0700596bool CPWL_Edit::IsVScrollBarVisible() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700597 if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
598 return pScroll->IsVisible();
599 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700600
tsepez4cf55152016-11-02 14:37:54 -0700601 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700602}
603
tsepez4cf55152016-11-02 14:37:54 -0700604bool CPWL_Edit::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700605 if (m_bMouseDown)
tsepez4cf55152016-11-02 14:37:54 -0700606 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700607
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700608 if (nChar == FWL_VKEY_Delete) {
609 if (m_pFillerNotify) {
tsepez4cf55152016-11-02 14:37:54 -0700610 bool bRC = true;
611 bool bExit = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700612 CFX_WideString strChange;
613 CFX_WideString strChangeEx;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700614
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700615 int nSelStart = 0;
616 int nSelEnd = 0;
617 GetSel(nSelStart, nSelEnd);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700618
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700619 if (nSelStart == nSelEnd)
620 nSelEnd = nSelStart + 1;
Lei Zhanga5b47042015-10-19 14:32:16 -0700621 m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), strChange,
tsepez4cf55152016-11-02 14:37:54 -0700622 strChangeEx, nSelStart, nSelEnd, true,
Lei Zhanga5b47042015-10-19 14:32:16 -0700623 bRC, bExit, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700624 if (!bRC)
tsepez4cf55152016-11-02 14:37:54 -0700625 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700626 if (bExit)
tsepez4cf55152016-11-02 14:37:54 -0700627 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700628 }
629 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700630
tsepez4cf55152016-11-02 14:37:54 -0700631 bool bRet = CPWL_EditCtrl::OnKeyDown(nChar, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700632
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700633 // In case of implementation swallow the OnKeyDown event.
634 if (IsProceedtoOnChar(nChar, nFlag))
tsepez4cf55152016-11-02 14:37:54 -0700635 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700636
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700637 return bRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700638}
639
640/**
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700641*In case of implementation swallow the OnKeyDown event.
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700642*If the event is swallowed, implementation may do other unexpected things, which
643*is not the control means to do.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700644*/
tsepez4cf55152016-11-02 14:37:54 -0700645bool CPWL_Edit::IsProceedtoOnChar(uint16_t nKeyCode, uint32_t nFlag) {
646 bool bCtrl = IsCTRLpressed(nFlag);
647 bool bAlt = IsALTpressed(nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700648 if (bCtrl && !bAlt) {
649 // hot keys for edit control.
650 switch (nKeyCode) {
651 case 'C':
652 case 'V':
653 case 'X':
654 case 'A':
655 case 'Z':
tsepez4cf55152016-11-02 14:37:54 -0700656 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700657 default:
658 break;
659 }
660 }
661 // control characters.
662 switch (nKeyCode) {
663 case FWL_VKEY_Escape:
664 case FWL_VKEY_Back:
665 case FWL_VKEY_Return:
666 case FWL_VKEY_Space:
tsepez4cf55152016-11-02 14:37:54 -0700667 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700668 default:
tsepez4cf55152016-11-02 14:37:54 -0700669 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700670 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700671}
672
tsepez4cf55152016-11-02 14:37:54 -0700673bool CPWL_Edit::OnChar(uint16_t nChar, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700674 if (m_bMouseDown)
tsepez4cf55152016-11-02 14:37:54 -0700675 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700676
tsepez4cf55152016-11-02 14:37:54 -0700677 bool bRC = true;
678 bool bExit = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700679
Lei Zhanga5b47042015-10-19 14:32:16 -0700680 if (!IsCTRLpressed(nFlag)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700681 if (m_pFillerNotify) {
682 CFX_WideString swChange;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700683
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700684 int nSelStart = 0;
685 int nSelEnd = 0;
686 GetSel(nSelStart, nSelEnd);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700687
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700688 switch (nChar) {
689 case FWL_VKEY_Back:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700690 if (nSelStart == nSelEnd)
691 nSelStart = nSelEnd - 1;
692 break;
693 case FWL_VKEY_Return:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700694 break;
695 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700696 swChange += nChar;
697 break;
698 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700699
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700700 CFX_WideString strChangeEx;
Lei Zhanga5b47042015-10-19 14:32:16 -0700701 m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swChange,
tsepez4cf55152016-11-02 14:37:54 -0700702 strChangeEx, nSelStart, nSelEnd, true,
Lei Zhanga5b47042015-10-19 14:32:16 -0700703 bRC, bExit, nFlag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700704 }
705 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700706
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700707 if (!bRC)
tsepez4cf55152016-11-02 14:37:54 -0700708 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700709 if (bExit)
tsepez4cf55152016-11-02 14:37:54 -0700710 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700711
dsinclairc7a73492016-04-05 12:01:42 -0700712 if (IPVT_FontMap* pFontMap = GetFontMap()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700713 int32_t nOldCharSet = GetCharSet();
npmea3c3be2016-09-19 07:24:33 -0700714 int32_t nNewCharSet =
Dan Sinclairf51a02a2017-04-19 12:46:53 -0400715 pFontMap->CharSetFromUnicode(nChar, FX_CHARSET_Default);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700716 if (nOldCharSet != nNewCharSet) {
717 SetCharSet(nNewCharSet);
718 }
719 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700720
Lei Zhanga5b47042015-10-19 14:32:16 -0700721 return CPWL_EditCtrl::OnChar(nChar, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700722}
723
tsepez4cf55152016-11-02 14:37:54 -0700724bool CPWL_Edit::OnMouseWheel(short zDelta,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500725 const CFX_PointF& point,
tsepez4cf55152016-11-02 14:37:54 -0700726 uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700727 if (HasFlag(PES_MULTILINE)) {
Dan Sinclairf528eee2017-02-14 11:52:07 -0500728 CFX_PointF ptScroll = GetScrollPos();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700729
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700730 if (zDelta > 0) {
731 ptScroll.y += GetFontSize();
732 } else {
733 ptScroll.y -= GetFontSize();
734 }
735 SetScrollPos(ptScroll);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700736
tsepez4cf55152016-11-02 14:37:54 -0700737 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700738 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700739
tsepez4cf55152016-11-02 14:37:54 -0700740 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700741}
742
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700743void CPWL_Edit::OnInsertReturn(const CPVT_WordPlace& place,
744 const CPVT_WordPlace& oldplace) {
745 if (HasFlag(PES_SPELLCHECK)) {
746 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
747 GetLatinWordsRange(place)));
748 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700749}
750
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700751void CPWL_Edit::OnBackSpace(const CPVT_WordPlace& place,
752 const CPVT_WordPlace& oldplace) {
753 if (HasFlag(PES_SPELLCHECK)) {
754 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
755 GetLatinWordsRange(place)));
756 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700757}
758
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700759void CPWL_Edit::OnDelete(const CPVT_WordPlace& place,
760 const CPVT_WordPlace& oldplace) {
761 if (HasFlag(PES_SPELLCHECK)) {
762 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
763 GetLatinWordsRange(place)));
764 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700765}
766
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700767void CPWL_Edit::OnClear(const CPVT_WordPlace& place,
768 const CPVT_WordPlace& oldplace) {
769 if (HasFlag(PES_SPELLCHECK)) {
770 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
771 GetLatinWordsRange(place)));
772 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700773}
774
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700775void CPWL_Edit::OnInsertWord(const CPVT_WordPlace& place,
776 const CPVT_WordPlace& oldplace) {
777 if (HasFlag(PES_SPELLCHECK)) {
778 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
779 GetLatinWordsRange(place)));
780 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700781}
782
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700783void CPWL_Edit::OnInsertText(const CPVT_WordPlace& place,
784 const CPVT_WordPlace& oldplace) {
785 if (HasFlag(PES_SPELLCHECK)) {
786 m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
787 GetLatinWordsRange(place)));
788 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700789}
790
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700791CPVT_WordRange CPWL_Edit::CombineWordRange(const CPVT_WordRange& wr1,
792 const CPVT_WordRange& wr2) {
Tom Sepez52f69b32017-03-21 13:42:38 -0700793 return CPVT_WordRange(std::min(wr1.BeginPos, wr2.BeginPos),
794 std::max(wr1.EndPos, wr2.EndPos));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700795}
796
Dan Sinclairf528eee2017-02-14 11:52:07 -0500797CPVT_WordRange CPWL_Edit::GetLatinWordsRange(const CFX_PointF& point) const {
tsepez4cf55152016-11-02 14:37:54 -0700798 return GetSameWordsRange(m_pEdit->SearchWordPlace(point), true, false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700799}
800
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700801CPVT_WordRange CPWL_Edit::GetLatinWordsRange(
802 const CPVT_WordPlace& place) const {
tsepez4cf55152016-11-02 14:37:54 -0700803 return GetSameWordsRange(place, true, false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700804}
805
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700806CPVT_WordRange CPWL_Edit::GetArabicWordsRange(
807 const CPVT_WordPlace& place) const {
tsepez4cf55152016-11-02 14:37:54 -0700808 return GetSameWordsRange(place, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700809}
810
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700811#define PWL_ISARABICWORD(word) \
812 ((word >= 0x0600 && word <= 0x06FF) || (word >= 0xFB50 && word <= 0xFEFC))
813
814CPVT_WordRange CPWL_Edit::GetSameWordsRange(const CPVT_WordPlace& place,
tsepez4cf55152016-11-02 14:37:54 -0700815 bool bLatin,
816 bool bArabic) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700817 CPVT_WordRange range;
818
dsinclaire35af1e2016-07-13 11:26:20 -0700819 CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
thestig821d59e2016-05-11 12:59:22 -0700820 CPVT_Word wordinfo;
821 CPVT_WordPlace wpStart(place), wpEnd(place);
822 pIterator->SetAt(place);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700823
thestig821d59e2016-05-11 12:59:22 -0700824 if (bLatin) {
825 while (pIterator->NextWord()) {
826 if (!pIterator->GetWord(wordinfo) ||
827 !FX_EDIT_ISLATINWORD(wordinfo.Word)) {
828 break;
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800829 }
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800830
thestig821d59e2016-05-11 12:59:22 -0700831 wpEnd = pIterator->GetAt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700832 }
thestig821d59e2016-05-11 12:59:22 -0700833 } else if (bArabic) {
834 while (pIterator->NextWord()) {
835 if (!pIterator->GetWord(wordinfo) || !PWL_ISARABICWORD(wordinfo.Word))
836 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700837
thestig821d59e2016-05-11 12:59:22 -0700838 wpEnd = pIterator->GetAt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700839 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700840 }
841
thestig821d59e2016-05-11 12:59:22 -0700842 pIterator->SetAt(place);
843
844 if (bLatin) {
845 do {
846 if (!pIterator->GetWord(wordinfo) ||
847 !FX_EDIT_ISLATINWORD(wordinfo.Word)) {
848 break;
849 }
850
851 wpStart = pIterator->GetAt();
852 } while (pIterator->PrevWord());
853 } else if (bArabic) {
854 do {
855 if (!pIterator->GetWord(wordinfo) || !PWL_ISARABICWORD(wordinfo.Word))
856 break;
857
858 wpStart = pIterator->GetAt();
859 } while (pIterator->PrevWord());
860 }
861
862 range.Set(wpStart, wpEnd);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700863 return range;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700864}