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