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 "fpdfsdk/include/pdfwindow/PWL_ComboBox.h"
8
9 #include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
10 #include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
11 #include "fpdfsdk/include/pdfwindow/PWL_ListBox.h"
12 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
13 #include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
14 #include "public/fpdf_fwlevent.h"
15
16 #define PWLCB_DEFAULTFONTSIZE 12.0f
17
18 #define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
19 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
20 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
21 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
22
OnLButtonUp(const CPDF_Point & point,FX_DWORD nFlag)23 FX_BOOL CPWL_CBListBox::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
24 CPWL_Wnd::OnLButtonUp(point, nFlag);
25
26 if (m_bMouseDown) {
27 ReleaseCapture();
28 m_bMouseDown = FALSE;
29
30 if (ClientHitTest(point)) {
31 if (CPWL_Wnd* pParent = GetParentWindow()) {
32 pParent->OnNotify(this, PNM_LBUTTONUP, 0,
33 PWL_MAKEDWORD(point.x, point.y));
34 }
35
36 FX_BOOL bExit = FALSE;
37 OnNotifySelChanged(FALSE, bExit, nFlag);
38 if (bExit)
39 return FALSE;
40 }
41 }
42
43 return TRUE;
44 }
45
OnKeyDownWithExit(FX_WORD nChar,FX_BOOL & bExit,FX_DWORD nFlag)46 FX_BOOL CPWL_CBListBox::OnKeyDownWithExit(FX_WORD nChar,
47 FX_BOOL& bExit,
48 FX_DWORD nFlag) {
49 if (!m_pList)
50 return FALSE;
51
52 switch (nChar) {
53 default:
54 return FALSE;
55 case FWL_VKEY_Up:
56 case FWL_VKEY_Down:
57 case FWL_VKEY_Home:
58 case FWL_VKEY_Left:
59 case FWL_VKEY_End:
60 case FWL_VKEY_Right:
61 break;
62 }
63
64 switch (nChar) {
65 case FWL_VKEY_Up:
66 m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
67 break;
68 case FWL_VKEY_Down:
69 m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
70 break;
71 case FWL_VKEY_Home:
72 m_pList->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
73 break;
74 case FWL_VKEY_Left:
75 m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
76 break;
77 case FWL_VKEY_End:
78 m_pList->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
79 break;
80 case FWL_VKEY_Right:
81 m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
82 break;
83 case FWL_VKEY_Delete:
84 break;
85 }
86
87 OnNotifySelChanged(TRUE, bExit, nFlag);
88
89 return TRUE;
90 }
91
OnCharWithExit(FX_WORD nChar,FX_BOOL & bExit,FX_DWORD nFlag)92 FX_BOOL CPWL_CBListBox::OnCharWithExit(FX_WORD nChar,
93 FX_BOOL& bExit,
94 FX_DWORD nFlag) {
95 if (!m_pList)
96 return FALSE;
97
98 if (!m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag)))
99 return FALSE;
100
101 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetParentWindow()) {
102 pComboBox->SetSelectText();
103 }
104
105 OnNotifySelChanged(TRUE, bExit, nFlag);
106
107 return TRUE;
108 }
109
GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)110 void CPWL_CBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
111 CPWL_Wnd::GetThisAppearanceStream(sAppStream);
112
113 CPDF_Rect rectWnd = CPWL_Wnd::GetWindowRect();
114
115 if (IsVisible() && !rectWnd.IsEmpty()) {
116 CFX_ByteTextBuf sButton;
117
118 CPDF_Point ptCenter = GetCenterPoint();
119
120 CPDF_Point pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
121 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
122 CPDF_Point pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
123 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
124 CPDF_Point pt3(ptCenter.x,
125 ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
126
127 if (IsFloatBigger(rectWnd.right - rectWnd.left,
128 PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
129 IsFloatBigger(rectWnd.top - rectWnd.bottom,
130 PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
131 sButton << "0 g\n";
132 sButton << pt1.x << " " << pt1.y << " m\n";
133 sButton << pt2.x << " " << pt2.y << " l\n";
134 sButton << pt3.x << " " << pt3.y << " l\n";
135 sButton << pt1.x << " " << pt1.y << " l f\n";
136
137 sAppStream << "q\n" << sButton << "Q\n";
138 }
139 }
140 }
141
DrawThisAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)142 void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
143 CFX_Matrix* pUser2Device) {
144 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
145
146 CPDF_Rect rectWnd = CPWL_Wnd::GetWindowRect();
147
148 if (IsVisible() && !rectWnd.IsEmpty()) {
149 CPDF_Point ptCenter = GetCenterPoint();
150
151 CPDF_Point pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
152 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
153 CPDF_Point pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
154 ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
155 CPDF_Point pt3(ptCenter.x,
156 ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
157
158 if (IsFloatBigger(rectWnd.right - rectWnd.left,
159 PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
160 IsFloatBigger(rectWnd.top - rectWnd.bottom,
161 PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
162 CFX_PathData path;
163
164 path.SetPointCount(4);
165 path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
166 path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
167 path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
168 path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
169
170 pDevice->DrawPath(&path, pUser2Device, NULL,
171 CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_BLACKCOLOR,
172 GetTransparency()),
173 0, FXFILL_ALTERNATE);
174 }
175 }
176 }
177
OnLButtonDown(const CPDF_Point & point,FX_DWORD nFlag)178 FX_BOOL CPWL_CBButton::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
179 CPWL_Wnd::OnLButtonDown(point, nFlag);
180
181 SetCapture();
182
183 if (CPWL_Wnd* pParent = GetParentWindow()) {
184 pParent->OnNotify(this, PNM_LBUTTONDOWN, 0,
185 PWL_MAKEDWORD(point.x, point.y));
186 }
187
188 return TRUE;
189 }
190
OnLButtonUp(const CPDF_Point & point,FX_DWORD nFlag)191 FX_BOOL CPWL_CBButton::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
192 CPWL_Wnd::OnLButtonUp(point, nFlag);
193
194 ReleaseCapture();
195
196 return TRUE;
197 }
198
CPWL_ComboBox()199 CPWL_ComboBox::CPWL_ComboBox()
200 : m_pEdit(NULL),
201 m_pButton(NULL),
202 m_pList(NULL),
203 m_bPopup(FALSE),
204 m_nPopupWhere(0),
205 m_nSelectItem(-1),
206 m_pFillerNotify(NULL) {}
207
GetClassName() const208 CFX_ByteString CPWL_ComboBox::GetClassName() const {
209 return "CPWL_ComboBox";
210 }
211
OnCreate(PWL_CREATEPARAM & cp)212 void CPWL_ComboBox::OnCreate(PWL_CREATEPARAM& cp) {
213 cp.dwFlags &= ~PWS_HSCROLL;
214 cp.dwFlags &= ~PWS_VSCROLL;
215 }
216
SetFocus()217 void CPWL_ComboBox::SetFocus() {
218 if (m_pEdit)
219 m_pEdit->SetFocus();
220 }
221
KillFocus()222 void CPWL_ComboBox::KillFocus() {
223 SetPopup(FALSE);
224 CPWL_Wnd::KillFocus();
225 }
226
GetText() const227 CFX_WideString CPWL_ComboBox::GetText() const {
228 if (m_pEdit) {
229 return m_pEdit->GetText();
230 }
231 return CFX_WideString();
232 }
233
SetText(const FX_WCHAR * text)234 void CPWL_ComboBox::SetText(const FX_WCHAR* text) {
235 if (m_pEdit)
236 m_pEdit->SetText(text);
237 }
238
AddString(const FX_WCHAR * string)239 void CPWL_ComboBox::AddString(const FX_WCHAR* string) {
240 if (m_pList)
241 m_pList->AddString(string);
242 }
243
GetSelect() const244 int32_t CPWL_ComboBox::GetSelect() const {
245 return m_nSelectItem;
246 }
247
SetSelect(int32_t nItemIndex)248 void CPWL_ComboBox::SetSelect(int32_t nItemIndex) {
249 if (m_pList)
250 m_pList->Select(nItemIndex);
251
252 m_pEdit->SetText(m_pList->GetText().c_str());
253
254 m_nSelectItem = nItemIndex;
255 }
256
SetEditSel(int32_t nStartChar,int32_t nEndChar)257 void CPWL_ComboBox::SetEditSel(int32_t nStartChar, int32_t nEndChar) {
258 if (m_pEdit) {
259 m_pEdit->SetSel(nStartChar, nEndChar);
260 }
261 }
262
GetEditSel(int32_t & nStartChar,int32_t & nEndChar) const263 void CPWL_ComboBox::GetEditSel(int32_t& nStartChar, int32_t& nEndChar) const {
264 nStartChar = -1;
265 nEndChar = -1;
266
267 if (m_pEdit) {
268 m_pEdit->GetSel(nStartChar, nEndChar);
269 }
270 }
271
Clear()272 void CPWL_ComboBox::Clear() {
273 if (m_pEdit) {
274 m_pEdit->Clear();
275 }
276 }
277
CreateChildWnd(const PWL_CREATEPARAM & cp)278 void CPWL_ComboBox::CreateChildWnd(const PWL_CREATEPARAM& cp) {
279 CreateEdit(cp);
280 CreateButton(cp);
281 CreateListBox(cp);
282 }
283
CreateEdit(const PWL_CREATEPARAM & cp)284 void CPWL_ComboBox::CreateEdit(const PWL_CREATEPARAM& cp) {
285 if (!m_pEdit) {
286 m_pEdit = new CPWL_CBEdit;
287 m_pEdit->AttachFFLData(m_pFormFiller);
288
289 PWL_CREATEPARAM ecp = cp;
290 ecp.pParentWnd = this;
291 ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PES_CENTER |
292 PES_AUTOSCROLL | PES_UNDO;
293
294 if (HasFlag(PWS_AUTOFONTSIZE))
295 ecp.dwFlags |= PWS_AUTOFONTSIZE;
296
297 if (!HasFlag(PCBS_ALLOWCUSTOMTEXT))
298 ecp.dwFlags |= PWS_READONLY;
299
300 ecp.rcRectWnd = CPDF_Rect(0, 0, 0, 0);
301 ecp.dwBorderWidth = 0;
302 ecp.nBorderStyle = PBS_SOLID;
303
304 m_pEdit->Create(ecp);
305 }
306 }
307
CreateButton(const PWL_CREATEPARAM & cp)308 void CPWL_ComboBox::CreateButton(const PWL_CREATEPARAM& cp) {
309 if (!m_pButton) {
310 m_pButton = new CPWL_CBButton;
311
312 PWL_CREATEPARAM bcp = cp;
313 bcp.pParentWnd = this;
314 bcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND;
315 bcp.sBackgroundColor = PWL_SCROLLBAR_BKCOLOR;
316 bcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
317 bcp.dwBorderWidth = 2;
318 bcp.nBorderStyle = PBS_BEVELED;
319 bcp.eCursorType = FXCT_ARROW;
320
321 m_pButton->Create(bcp);
322 }
323 }
324
CreateListBox(const PWL_CREATEPARAM & cp)325 void CPWL_ComboBox::CreateListBox(const PWL_CREATEPARAM& cp) {
326 if (!m_pList) {
327 m_pList = new CPWL_CBListBox;
328 m_pList->AttachFFLData(m_pFormFiller);
329 PWL_CREATEPARAM lcp = cp;
330 lcp.pParentWnd = this;
331 lcp.dwFlags =
332 PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PLBS_HOVERSEL | PWS_VSCROLL;
333 lcp.nBorderStyle = PBS_SOLID;
334 lcp.dwBorderWidth = 1;
335 lcp.eCursorType = FXCT_ARROW;
336 lcp.rcRectWnd = CPDF_Rect(0, 0, 0, 0);
337
338 if (cp.dwFlags & PWS_AUTOFONTSIZE)
339 lcp.fFontSize = PWLCB_DEFAULTFONTSIZE;
340 else
341 lcp.fFontSize = cp.fFontSize;
342
343 if (cp.sBorderColor.nColorType == COLORTYPE_TRANSPARENT)
344 lcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
345
346 if (cp.sBackgroundColor.nColorType == COLORTYPE_TRANSPARENT)
347 lcp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
348
349 m_pList->Create(lcp);
350 }
351 }
352
RePosChildWnd()353 void CPWL_ComboBox::RePosChildWnd() {
354 CPDF_Rect rcClient = GetClientRect();
355
356 if (m_bPopup) {
357 CPDF_Rect rclient = GetClientRect();
358 CPDF_Rect rcButton = rclient;
359 CPDF_Rect rcEdit = rcClient;
360 CPDF_Rect rcList = CPWL_Wnd::GetWindowRect();
361
362 FX_FLOAT fOldWindowHeight = m_rcOldWindow.Height();
363 FX_FLOAT fOldClientHeight = fOldWindowHeight - GetBorderWidth() * 2;
364
365 switch (m_nPopupWhere) {
366 case 0:
367 rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
368
369 if (rcButton.left < rclient.left)
370 rcButton.left = rclient.left;
371
372 rcButton.bottom = rcButton.top - fOldClientHeight;
373
374 rcEdit.right = rcButton.left - 1.0f;
375
376 if (rcEdit.left < rclient.left)
377 rcEdit.left = rclient.left;
378
379 if (rcEdit.right < rcEdit.left)
380 rcEdit.right = rcEdit.left;
381
382 rcEdit.bottom = rcEdit.top - fOldClientHeight;
383
384 rcList.top -= fOldWindowHeight;
385
386 break;
387 case 1:
388 rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
389
390 if (rcButton.left < rclient.left)
391 rcButton.left = rclient.left;
392
393 rcButton.top = rcButton.bottom + fOldClientHeight;
394
395 rcEdit.right = rcButton.left - 1.0f;
396
397 if (rcEdit.left < rclient.left)
398 rcEdit.left = rclient.left;
399
400 if (rcEdit.right < rcEdit.left)
401 rcEdit.right = rcEdit.left;
402
403 rcEdit.top = rcEdit.bottom + fOldClientHeight;
404
405 rcList.bottom += fOldWindowHeight;
406
407 break;
408 }
409
410 if (m_pButton)
411 m_pButton->Move(rcButton, TRUE, FALSE);
412
413 if (m_pEdit)
414 m_pEdit->Move(rcEdit, TRUE, FALSE);
415
416 if (m_pList) {
417 m_pList->SetVisible(TRUE);
418 m_pList->Move(rcList, TRUE, FALSE);
419 m_pList->ScrollToListItem(m_nSelectItem);
420 }
421 } else {
422 CPDF_Rect rcButton = rcClient;
423
424 rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
425
426 if (rcButton.left < rcClient.left)
427 rcButton.left = rcClient.left;
428
429 if (m_pButton)
430 m_pButton->Move(rcButton, TRUE, FALSE);
431
432 CPDF_Rect rcEdit = rcClient;
433 rcEdit.right = rcButton.left - 1.0f;
434
435 if (rcEdit.left < rcClient.left)
436 rcEdit.left = rcClient.left;
437
438 if (rcEdit.right < rcEdit.left)
439 rcEdit.right = rcEdit.left;
440
441 if (m_pEdit)
442 m_pEdit->Move(rcEdit, TRUE, FALSE);
443
444 if (m_pList)
445 m_pList->SetVisible(FALSE);
446 }
447 }
448
SelectAll()449 void CPWL_ComboBox::SelectAll() {
450 if (m_pEdit && HasFlag(PCBS_ALLOWCUSTOMTEXT))
451 m_pEdit->SelectAll();
452 }
453
GetFocusRect() const454 CPDF_Rect CPWL_ComboBox::GetFocusRect() const {
455 return CPDF_Rect();
456 }
457
SetPopup(FX_BOOL bPopup)458 void CPWL_ComboBox::SetPopup(FX_BOOL bPopup) {
459 if (!m_pList)
460 return;
461 if (bPopup == m_bPopup)
462 return;
463 FX_FLOAT fListHeight = m_pList->GetContentRect().Height();
464 if (!IsFloatBigger(fListHeight, 0.0f))
465 return;
466
467 if (bPopup) {
468 if (m_pFillerNotify) {
469 #ifdef PDF_ENABLE_XFA
470 FX_BOOL bExit = FALSE;
471 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, 0);
472 if (bExit)
473 return;
474 #endif // PDF_ENABLE_XFA
475 int32_t nWhere = 0;
476 FX_FLOAT fPopupRet = 0.0f;
477 FX_FLOAT fPopupMin = 0.0f;
478 if (m_pList->GetCount() > 3)
479 fPopupMin =
480 m_pList->GetFirstHeight() * 3 + m_pList->GetBorderWidth() * 2;
481 FX_FLOAT fPopupMax = fListHeight + m_pList->GetBorderWidth() * 2;
482 m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin, fPopupMax,
483 nWhere, fPopupRet);
484
485 if (IsFloatBigger(fPopupRet, 0.0f)) {
486 m_bPopup = bPopup;
487
488 CPDF_Rect rcWindow = CPWL_Wnd::GetWindowRect();
489 m_rcOldWindow = rcWindow;
490 switch (nWhere) {
491 default:
492 case 0:
493 rcWindow.bottom -= fPopupRet;
494 break;
495 case 1:
496 rcWindow.top += fPopupRet;
497 break;
498 }
499
500 m_nPopupWhere = nWhere;
501 Move(rcWindow, TRUE, TRUE);
502 #ifdef PDF_ENABLE_XFA
503 bExit = FALSE;
504 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, 0);
505 if (bExit)
506 return;
507 #endif // PDF_ENABLE_XFA
508 }
509 }
510 } else {
511 m_bPopup = bPopup;
512 Move(m_rcOldWindow, TRUE, TRUE);
513 }
514 }
515
OnKeyDown(FX_WORD nChar,FX_DWORD nFlag)516 FX_BOOL CPWL_ComboBox::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
517 if (!m_pList)
518 return FALSE;
519 if (!m_pEdit)
520 return FALSE;
521
522 m_nSelectItem = -1;
523
524 switch (nChar) {
525 case FWL_VKEY_Up:
526 if (m_pList->GetCurSel() > 0) {
527 FX_BOOL bExit = FALSE;
528 #ifdef PDF_ENABLE_XFA
529 if (m_pFillerNotify) {
530 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
531 if (bExit)
532 return FALSE;
533 bExit = FALSE;
534 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
535 if (bExit)
536 return FALSE;
537 }
538 #endif // PDF_ENABLE_XFA
539 if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
540 if (bExit)
541 return FALSE;
542 SetSelectText();
543 }
544 }
545 return TRUE;
546 case FWL_VKEY_Down:
547 if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
548 FX_BOOL bExit = FALSE;
549 #ifdef PDF_ENABLE_XFA
550 if (m_pFillerNotify) {
551 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
552 if (bExit)
553 return FALSE;
554 bExit = FALSE;
555 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
556 if (bExit)
557 return FALSE;
558 }
559 #endif // PDF_ENABLE_XFA
560 if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
561 if (bExit)
562 return FALSE;
563 SetSelectText();
564 }
565 }
566 return TRUE;
567 }
568
569 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
570 return m_pEdit->OnKeyDown(nChar, nFlag);
571
572 return FALSE;
573 }
574
OnChar(FX_WORD nChar,FX_DWORD nFlag)575 FX_BOOL CPWL_ComboBox::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
576 if (!m_pList)
577 return FALSE;
578
579 if (!m_pEdit)
580 return FALSE;
581
582 m_nSelectItem = -1;
583 if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
584 return m_pEdit->OnChar(nChar, nFlag);
585
586 FX_BOOL bExit = FALSE;
587 #ifdef PDF_ENABLE_XFA
588 if (m_pFillerNotify) {
589 m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
590 if (bExit)
591 return FALSE;
592
593 m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
594 if (bExit)
595 return FALSE;
596 }
597 #endif // PDF_ENABLE_XFA
598 return m_pList->OnCharWithExit(nChar, bExit, nFlag) ? bExit : FALSE;
599 }
600
OnNotify(CPWL_Wnd * pWnd,FX_DWORD msg,intptr_t wParam,intptr_t lParam)601 void CPWL_ComboBox::OnNotify(CPWL_Wnd* pWnd,
602 FX_DWORD msg,
603 intptr_t wParam,
604 intptr_t lParam) {
605 switch (msg) {
606 case PNM_LBUTTONDOWN:
607 if (pWnd == m_pButton) {
608 SetPopup(!m_bPopup);
609 return;
610 }
611 break;
612 case PNM_LBUTTONUP:
613 if (m_pEdit && m_pList) {
614 if (pWnd == m_pList) {
615 SetSelectText();
616 SelectAll();
617 m_pEdit->SetFocus();
618 SetPopup(FALSE);
619 return;
620 }
621 }
622 }
623
624 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
625 }
626
IsPopup() const627 FX_BOOL CPWL_ComboBox::IsPopup() const {
628 return m_bPopup;
629 }
630
SetSelectText()631 void CPWL_ComboBox::SetSelectText() {
632 CFX_WideString swText = m_pList->GetText();
633 m_pEdit->SelectAll();
634 m_pEdit->ReplaceSel(m_pList->GetText().c_str());
635 m_pEdit->SelectAll();
636
637 m_nSelectItem = m_pList->GetCurSel();
638 }
639
SetFillerNotify(IPWL_Filler_Notify * pNotify)640 void CPWL_ComboBox::SetFillerNotify(IPWL_Filler_Notify* pNotify) {
641 m_pFillerNotify = pNotify;
642
643 if (m_pEdit)
644 m_pEdit->SetFillerNotify(pNotify);
645
646 if (m_pList)
647 m_pList->SetFillerNotify(pNotify);
648 }
649