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_Note.h"
8
9 #include "fpdfsdk/include/pdfwindow/PWL_Button.h"
10 #include "fpdfsdk/include/pdfwindow/PWL_Caret.h"
11 #include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
12 #include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
13 #include "fpdfsdk/include/pdfwindow/PWL_Label.h"
14 #include "fpdfsdk/include/pdfwindow/PWL_ListCtrl.h"
15 #include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
16 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
17 #include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
18
19 #define POPUP_ITEM_HEAD_BOTTOM 3.0f
20 #define POPUP_ITEM_BOTTOMWIDTH 1.0f
21 #define POPUP_ITEM_SIDEMARGIN 3.0f
22 #define POPUP_ITEM_SPACE 4.0f
23 #define POPUP_ITEM_TEXT_INDENT 2.0f
24 #define POPUP_ITEM_BORDERCOLOR \
25 CPWL_Color(COLORTYPE_RGB, 80 / 255.0f, 80 / 255.0f, 80 / 255.0f)
26
27 #define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
28 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
29 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
30 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
31
CPWL_Note_Options()32 CPWL_Note_Options::CPWL_Note_Options() : m_pText(NULL) {}
33
~CPWL_Note_Options()34 CPWL_Note_Options::~CPWL_Note_Options() {}
35
SetTextColor(const CPWL_Color & color)36 void CPWL_Note_Options::SetTextColor(const CPWL_Color& color) {
37 CPWL_Wnd::SetTextColor(color);
38
39 if (m_pText)
40 m_pText->SetTextColor(color);
41 }
42
RePosChildWnd()43 void CPWL_Note_Options::RePosChildWnd() {
44 if (IsValid()) {
45 CPDF_Rect rcClient = GetClientRect();
46
47 if (rcClient.Width() > 15.0f) {
48 rcClient.right -= 15.0f;
49 m_pText->Move(rcClient, TRUE, FALSE);
50 m_pText->SetVisible(TRUE);
51 } else {
52 m_pText->Move(CPDF_Rect(0, 0, 0, 0), TRUE, FALSE);
53 m_pText->SetVisible(FALSE);
54 }
55 }
56 }
57
CreateChildWnd(const PWL_CREATEPARAM & cp)58 void CPWL_Note_Options::CreateChildWnd(const PWL_CREATEPARAM& cp) {
59 m_pText = new CPWL_Label;
60 PWL_CREATEPARAM tcp = cp;
61 tcp.pParentWnd = this;
62 tcp.dwFlags = PWS_CHILD | PWS_VISIBLE;
63 m_pText->Create(tcp);
64 }
65
SetText(const CFX_WideString & sText)66 void CPWL_Note_Options::SetText(const CFX_WideString& sText) {
67 m_pText->SetText(sText.c_str());
68 }
69
DrawThisAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)70 void CPWL_Note_Options::DrawThisAppearance(CFX_RenderDevice* pDevice,
71 CFX_Matrix* pUser2Device) {
72 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
73
74 CPDF_Rect rcClient = GetClientRect();
75 rcClient.left = rcClient.right - 15.0f;
76
77 CPDF_Point ptCenter = CPDF_Point((rcClient.left + rcClient.right) * 0.5f,
78 (rcClient.top + rcClient.bottom) * 0.5f);
79
80 CPDF_Point pt1(ptCenter.x - 2.0f, ptCenter.y + 2.0f * 0.5f);
81 CPDF_Point pt2(ptCenter.x + 2.0f, ptCenter.y + 2.0f * 0.5f);
82 CPDF_Point pt3(ptCenter.x, ptCenter.y - 3.0f * 0.5f);
83
84 CFX_PathData path;
85
86 path.SetPointCount(4);
87 path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
88 path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
89 path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
90 path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
91
92 pDevice->DrawPath(
93 &path, pUser2Device, NULL,
94 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), 0,
95 FXFILL_ALTERNATE);
96 }
97
GetContentRect() const98 CPDF_Rect CPWL_Note_Options::GetContentRect() const {
99 CPDF_Rect rcText = m_pText->GetContentRect();
100 rcText.right += 15.0f;
101 return rcText;
102 }
103
CPWL_Note_Edit()104 CPWL_Note_Edit::CPWL_Note_Edit()
105 : m_bEnableNotify(TRUE),
106 m_fOldItemHeight(0.0f),
107 m_bSizeChanged(FALSE),
108 m_fOldMin(0.0f),
109 m_fOldMax(0.0f) {}
110
~CPWL_Note_Edit()111 CPWL_Note_Edit::~CPWL_Note_Edit() {}
112
RePosChildWnd()113 void CPWL_Note_Edit::RePosChildWnd() {
114 m_bEnableNotify = FALSE;
115 CPWL_Edit::RePosChildWnd();
116 m_bEnableNotify = TRUE;
117
118 m_fOldItemHeight = GetContentRect().Height();
119 }
120
SetText(const FX_WCHAR * csText)121 void CPWL_Note_Edit::SetText(const FX_WCHAR* csText) {
122 m_bEnableNotify = FALSE;
123 CPWL_Edit::SetText(csText);
124 m_bEnableNotify = TRUE;
125 m_fOldItemHeight = GetContentRect().Height();
126 }
127
OnSetFocus()128 void CPWL_Note_Edit::OnSetFocus() {
129 m_bEnableNotify = FALSE;
130 CPWL_Edit::OnSetFocus();
131 m_bEnableNotify = TRUE;
132
133 EnableSpellCheck(TRUE);
134 }
135
OnKillFocus()136 void CPWL_Note_Edit::OnKillFocus() {
137 EnableSpellCheck(FALSE);
138
139 if (CPWL_Wnd* pParent = GetParentWindow()) {
140 if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) {
141 ASSERT(pGrand->GetClassName() == "CPWL_NoteItem");
142
143 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pGrand;
144
145 pNoteItem->OnContentsValidate();
146 }
147 }
148
149 CPWL_Edit::OnKillFocus();
150 }
151
OnNotify(CPWL_Wnd * pWnd,FX_DWORD msg,intptr_t wParam,intptr_t lParam)152 void CPWL_Note_Edit::OnNotify(CPWL_Wnd* pWnd,
153 FX_DWORD msg,
154 intptr_t wParam,
155 intptr_t lParam) {
156 if (m_bEnableNotify) {
157 if (wParam == SBT_VSCROLL) {
158 switch (msg) {
159 case PNM_SETSCROLLINFO:
160 if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) {
161 if (!IsFloatEqual(pInfo->fContentMax, m_fOldMax) ||
162 !IsFloatEqual(pInfo->fContentMin, m_fOldMin)) {
163 m_bSizeChanged = TRUE;
164 if (CPWL_Wnd* pParent = GetParentWindow()) {
165 pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
166 }
167
168 m_fOldMax = pInfo->fContentMax;
169 m_fOldMin = pInfo->fContentMin;
170 return;
171 }
172 }
173 }
174 }
175 }
176
177 CPWL_Edit::OnNotify(pWnd, msg, wParam, lParam);
178
179 if (m_bEnableNotify) {
180 switch (msg) {
181 case PNM_SETCARETINFO:
182 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
183 PWL_CARET_INFO newInfo = *pInfo;
184 newInfo.bVisible = TRUE;
185 newInfo.ptHead = ChildToParent(pInfo->ptHead);
186 newInfo.ptFoot = ChildToParent(pInfo->ptFoot);
187
188 if (CPWL_Wnd* pParent = GetParentWindow()) {
189 pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0);
190 }
191 }
192 break;
193 }
194 }
195 }
196
GetItemHeight(FX_FLOAT fLimitWidth)197 FX_FLOAT CPWL_Note_Edit::GetItemHeight(FX_FLOAT fLimitWidth) {
198 if (fLimitWidth > 0) {
199 if (!m_bSizeChanged)
200 return m_fOldItemHeight;
201
202 m_bSizeChanged = FALSE;
203
204 EnableNotify(FALSE);
205 EnableRefresh(FALSE);
206 m_pEdit->EnableNotify(FALSE);
207
208 Move(CPDF_Rect(0, 0, fLimitWidth, 0), TRUE, FALSE);
209 FX_FLOAT fRet = GetContentRect().Height();
210
211 m_pEdit->EnableNotify(TRUE);
212 EnableNotify(TRUE);
213 EnableRefresh(TRUE);
214
215 return fRet;
216 }
217
218 return 0;
219 }
220
GetItemLeftMargin()221 FX_FLOAT CPWL_Note_Edit::GetItemLeftMargin() {
222 return POPUP_ITEM_TEXT_INDENT;
223 }
224
GetItemRightMargin()225 FX_FLOAT CPWL_Note_Edit::GetItemRightMargin() {
226 return POPUP_ITEM_TEXT_INDENT;
227 }
228
CPWL_Note_LBBox()229 CPWL_Note_LBBox::CPWL_Note_LBBox() {}
230
~CPWL_Note_LBBox()231 CPWL_Note_LBBox::~CPWL_Note_LBBox() {}
232
DrawThisAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)233 void CPWL_Note_LBBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
234 CFX_Matrix* pUser2Device) {
235 CPDF_Rect rcClient = GetClientRect();
236
237 CFX_GraphStateData gsd;
238 gsd.m_LineWidth = 1.0f;
239
240 CFX_PathData pathCross;
241
242 pathCross.SetPointCount(4);
243 pathCross.SetPoint(0, rcClient.left, rcClient.top, FXPT_MOVETO);
244 pathCross.SetPoint(1, rcClient.right, rcClient.bottom, FXPT_LINETO);
245 pathCross.SetPoint(2, rcClient.left,
246 rcClient.bottom + rcClient.Height() * 0.5f, FXPT_MOVETO);
247 pathCross.SetPoint(3, rcClient.left + rcClient.Width() * 0.5f,
248 rcClient.bottom, FXPT_LINETO);
249
250 pDevice->DrawPath(
251 &pathCross, pUser2Device, &gsd, 0,
252 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
253 FXFILL_ALTERNATE);
254 }
255
CPWL_Note_RBBox()256 CPWL_Note_RBBox::CPWL_Note_RBBox() {}
257
~CPWL_Note_RBBox()258 CPWL_Note_RBBox::~CPWL_Note_RBBox() {}
259
DrawThisAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)260 void CPWL_Note_RBBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
261 CFX_Matrix* pUser2Device) {
262 CPDF_Rect rcClient = GetClientRect();
263
264 CFX_GraphStateData gsd;
265 gsd.m_LineWidth = 1.0f;
266
267 CFX_PathData pathCross;
268
269 pathCross.SetPointCount(4);
270 pathCross.SetPoint(0, rcClient.right, rcClient.top, FXPT_MOVETO);
271 pathCross.SetPoint(1, rcClient.left, rcClient.bottom, FXPT_LINETO);
272 pathCross.SetPoint(2, rcClient.right,
273 rcClient.bottom + rcClient.Height() * 0.5f, FXPT_MOVETO);
274 pathCross.SetPoint(3, rcClient.left + rcClient.Width() * 0.5f,
275 rcClient.bottom, FXPT_LINETO);
276
277 pDevice->DrawPath(
278 &pathCross, pUser2Device, &gsd, 0,
279 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
280 FXFILL_ALTERNATE);
281 }
282
CPWL_Note_Icon()283 CPWL_Note_Icon::CPWL_Note_Icon() : m_nType(0) {}
284
~CPWL_Note_Icon()285 CPWL_Note_Icon::~CPWL_Note_Icon() {}
286
SetIconType(int32_t nType)287 void CPWL_Note_Icon::SetIconType(int32_t nType) {
288 m_nType = nType;
289 }
290
DrawThisAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)291 void CPWL_Note_Icon::DrawThisAppearance(CFX_RenderDevice* pDevice,
292 CFX_Matrix* pUser2Device) {
293 CPWL_Utils::DrawIconAppStream(pDevice, pUser2Device, m_nType, GetClientRect(),
294 GetBackgroundColor(), PWL_DEFAULT_BLACKCOLOR,
295 GetTransparency());
296 }
297
CPWL_Note_CloseBox()298 CPWL_Note_CloseBox::CPWL_Note_CloseBox() : m_bMouseDown(FALSE) {}
299
~CPWL_Note_CloseBox()300 CPWL_Note_CloseBox::~CPWL_Note_CloseBox() {}
301
DrawThisAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)302 void CPWL_Note_CloseBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
303 CFX_Matrix* pUser2Device) {
304 CPWL_Button::DrawThisAppearance(pDevice, pUser2Device);
305
306 CPDF_Rect rcClient = GetClientRect();
307 rcClient = CPWL_Utils::DeflateRect(rcClient, 2.0f);
308
309 CFX_GraphStateData gsd;
310 gsd.m_LineWidth = 1.0f;
311
312 CFX_PathData pathCross;
313
314 if (m_bMouseDown) {
315 rcClient.left += 0.5f;
316 rcClient.right += 0.5f;
317 rcClient.top -= 0.5f;
318 rcClient.bottom -= 0.5f;
319 }
320
321 pathCross.SetPointCount(4);
322 pathCross.SetPoint(0, rcClient.left, rcClient.bottom, FXPT_MOVETO);
323 pathCross.SetPoint(1, rcClient.right, rcClient.top, FXPT_LINETO);
324 pathCross.SetPoint(2, rcClient.left, rcClient.top, FXPT_MOVETO);
325 pathCross.SetPoint(3, rcClient.right, rcClient.bottom, FXPT_LINETO);
326
327 pDevice->DrawPath(
328 &pathCross, pUser2Device, &gsd, 0,
329 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
330 FXFILL_ALTERNATE);
331 }
332
OnLButtonDown(const CPDF_Point & point,FX_DWORD nFlag)333 FX_BOOL CPWL_Note_CloseBox::OnLButtonDown(const CPDF_Point& point,
334 FX_DWORD nFlag) {
335 SetBorderStyle(PBS_INSET);
336 InvalidateRect(NULL);
337
338 m_bMouseDown = TRUE;
339
340 return CPWL_Button::OnLButtonDown(point, nFlag);
341 }
342
OnLButtonUp(const CPDF_Point & point,FX_DWORD nFlag)343 FX_BOOL CPWL_Note_CloseBox::OnLButtonUp(const CPDF_Point& point,
344 FX_DWORD nFlag) {
345 m_bMouseDown = FALSE;
346
347 SetBorderStyle(PBS_BEVELED);
348 InvalidateRect(NULL);
349
350 return CPWL_Button::OnLButtonUp(point, nFlag);
351 }
352
CPWL_Note_Contents()353 CPWL_Note_Contents::CPWL_Note_Contents() : m_pEdit(NULL) {}
354
~CPWL_Note_Contents()355 CPWL_Note_Contents::~CPWL_Note_Contents() {}
356
GetClassName() const357 CFX_ByteString CPWL_Note_Contents::GetClassName() const {
358 return "CPWL_Note_Contents";
359 }
360
CreateChildWnd(const PWL_CREATEPARAM & cp)361 void CPWL_Note_Contents::CreateChildWnd(const PWL_CREATEPARAM& cp) {
362 m_pEdit = new CPWL_Note_Edit;
363 PWL_CREATEPARAM ecp = cp;
364 ecp.pParentWnd = this;
365 ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_MULTILINE | PES_AUTORETURN |
366 PES_TEXTOVERFLOW | PES_UNDO | PES_SPELLCHECK;
367
368 m_pEdit->EnableNotify(FALSE);
369 m_pEdit->Create(ecp);
370 m_pEdit->EnableNotify(TRUE);
371 }
372
SetText(const CFX_WideString & sText)373 void CPWL_Note_Contents::SetText(const CFX_WideString& sText) {
374 if (m_pEdit) {
375 m_pEdit->EnableNotify(FALSE);
376 m_pEdit->SetText(sText.c_str());
377 m_pEdit->EnableNotify(TRUE);
378 OnNotify(m_pEdit, PNM_NOTEEDITCHANGED, 0, 0);
379 }
380 }
381
GetText() const382 CFX_WideString CPWL_Note_Contents::GetText() const {
383 if (m_pEdit)
384 return m_pEdit->GetText();
385
386 return L"";
387 }
388
CreateSubItem()389 CPWL_NoteItem* CPWL_Note_Contents::CreateSubItem() {
390 CPWL_NoteItem* pNoteItem = new CPWL_NoteItem;
391 PWL_CREATEPARAM icp = GetCreationParam();
392 icp.pParentWnd = this;
393 icp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_BACKGROUND;
394 pNoteItem->Create(icp);
395
396 pNoteItem->OnCreateNoteItem();
397
398 pNoteItem->ResetSubjectName(m_aChildren.GetSize() - 1);
399
400 FX_SYSTEMTIME st;
401 if (IFX_SystemHandler* pSH = GetSystemHandler())
402 st = pSH->GetLocalTime();
403 pNoteItem->SetDateTime(st);
404
405 pNoteItem->SetContents(L"");
406
407 OnNotify(pNoteItem, PNM_NOTEEDITCHANGED, 0, 0);
408
409 return pNoteItem;
410 }
411
CountSubItems() const412 int32_t CPWL_Note_Contents::CountSubItems() const {
413 return m_aChildren.GetSize() - 1;
414 }
415
GetSubItems(int32_t index) const416 IPWL_NoteItem* CPWL_Note_Contents::GetSubItems(int32_t index) const {
417 int32_t nIndex = index + 1;
418
419 if (nIndex > 0 && nIndex < m_aChildren.GetSize()) {
420 if (CPWL_Wnd* pChild = m_aChildren.GetAt(nIndex)) {
421 ASSERT(pChild->GetClassName() == "CPWL_NoteItem");
422 CPWL_NoteItem* pItem = (CPWL_NoteItem*)pChild;
423 return pItem;
424 }
425 }
426 return NULL;
427 }
428
DeleteSubItem(IPWL_NoteItem * pNoteItem)429 void CPWL_Note_Contents::DeleteSubItem(IPWL_NoteItem* pNoteItem) {
430 int32_t nIndex = GetItemIndex((CPWL_NoteItem*)pNoteItem);
431
432 if (nIndex > 0) {
433 if (CPWL_NoteItem* pPWLNoteItem = (CPWL_NoteItem*)pNoteItem) {
434 pPWLNoteItem->KillFocus();
435 pPWLNoteItem->Destroy();
436 delete pPWLNoteItem;
437 }
438
439 for (int32_t i = nIndex, sz = m_aChildren.GetSize(); i < sz; i++) {
440 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
441 ASSERT(pChild->GetClassName() == "CPWL_NoteItem");
442 CPWL_NoteItem* pItem = (CPWL_NoteItem*)pChild;
443 pItem->ResetSubjectName(i);
444 }
445 }
446
447 OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
448 }
449 }
450
GetHitNoteItem(const CPDF_Point & point)451 IPWL_NoteItem* CPWL_Note_Contents::GetHitNoteItem(const CPDF_Point& point) {
452 CPDF_Point pt = ParentToChild(point);
453
454 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
455 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
456 if (pChild->GetClassName() == "CPWL_NoteItem") {
457 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild;
458 if (IPWL_NoteItem* pRet = pNoteItem->GetHitNoteItem(pt))
459 return pRet;
460 }
461 }
462 }
463 return NULL;
464 }
465
OnNotify(CPWL_Wnd * pWnd,FX_DWORD msg,intptr_t wParam,intptr_t lParam)466 void CPWL_Note_Contents::OnNotify(CPWL_Wnd* pWnd,
467 FX_DWORD msg,
468 intptr_t wParam,
469 intptr_t lParam) {
470 switch (msg) {
471 case PNM_NOTEEDITCHANGED: {
472 int32_t nIndex = GetItemIndex(pWnd);
473 if (nIndex < 0)
474 nIndex = 0;
475
476 m_pEdit->EnableNotify(FALSE);
477 ResetContent(nIndex);
478 m_pEdit->EnableNotify(TRUE);
479
480 for (int32_t i = nIndex + 1, sz = m_aChildren.GetSize(); i < sz; i++) {
481 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
482 pChild->OnNotify(this, PNM_NOTERESET, 0, 0);
483 }
484
485 if (CPWL_Wnd* pParent = GetParentWindow()) {
486 pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
487 }
488 }
489 return;
490 case PNM_SCROLLWINDOW:
491 SetScrollPos(CPDF_Point(0.0f, *(FX_FLOAT*)lParam));
492 ResetFace();
493 InvalidateRect(NULL);
494 return;
495 case PNM_SETCARETINFO:
496 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
497 PWL_CARET_INFO newInfo = *pInfo;
498 newInfo.bVisible = TRUE;
499 newInfo.ptHead = ChildToParent(pInfo->ptHead);
500 newInfo.ptFoot = ChildToParent(pInfo->ptFoot);
501
502 if (CPWL_Wnd* pParent = GetParentWindow()) {
503 pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0);
504 }
505 }
506 return;
507 case PNM_NOTERESET: {
508 m_pEdit->EnableNotify(FALSE);
509 ResetContent(0);
510 m_pEdit->EnableNotify(TRUE);
511
512 for (int32_t i = 1, sz = m_aChildren.GetSize(); i < sz; i++) {
513 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
514 pChild->OnNotify(this, PNM_NOTERESET, 0, 0);
515 }
516
517 m_pEdit->EnableNotify(FALSE);
518 ResetContent(0);
519 m_pEdit->EnableNotify(TRUE);
520 }
521 return;
522 }
523
524 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
525 }
526
OnLButtonDown(const CPDF_Point & point,FX_DWORD nFlag)527 FX_BOOL CPWL_Note_Contents::OnLButtonDown(const CPDF_Point& point,
528 FX_DWORD nFlag) {
529 if (CPWL_Wnd::OnLButtonDown(point, nFlag))
530 return TRUE;
531
532 if (!m_pEdit->IsFocused()) {
533 m_pEdit->SetFocus();
534 }
535
536 return TRUE;
537 }
538
SetEditFocus(FX_BOOL bLast)539 void CPWL_Note_Contents::SetEditFocus(FX_BOOL bLast) {
540 if (!m_pEdit->IsFocused()) {
541 m_pEdit->SetFocus();
542 m_pEdit->SetCaret(bLast ? m_pEdit->GetTotalWords() : 0);
543 }
544 }
545
GetEdit() const546 CPWL_Edit* CPWL_Note_Contents::GetEdit() const {
547 return m_pEdit;
548 }
549
EnableModify(FX_BOOL bEnabled)550 void CPWL_Note_Contents::EnableModify(FX_BOOL bEnabled) {
551 if (!bEnabled)
552 m_pEdit->AddFlag(PWS_READONLY);
553 else
554 m_pEdit->RemoveFlag(PWS_READONLY);
555
556 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
557 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
558 if (pChild->GetClassName() == "CPWL_NoteItem") {
559 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild;
560 pNoteItem->EnableModify(bEnabled);
561 }
562 }
563 }
564 }
565
EnableRead(FX_BOOL bEnabled)566 void CPWL_Note_Contents::EnableRead(FX_BOOL bEnabled) {
567 if (!bEnabled)
568 m_pEdit->AddFlag(PES_NOREAD);
569 else
570 m_pEdit->RemoveFlag(PES_NOREAD);
571
572 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
573 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
574 if (pChild->GetClassName() == "CPWL_NoteItem") {
575 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild;
576 pNoteItem->EnableRead(bEnabled);
577 }
578 }
579 }
580 }
581
CPWL_NoteItem()582 CPWL_NoteItem::CPWL_NoteItem()
583 : m_pSubject(NULL),
584 m_pDateTime(NULL),
585 m_pContents(NULL),
586 m_pPrivateData(NULL),
587 m_sAuthor(L""),
588 m_fOldItemHeight(0.0f),
589 m_bSizeChanged(FALSE),
590 m_bAllowModify(TRUE) {}
591
~CPWL_NoteItem()592 CPWL_NoteItem::~CPWL_NoteItem() {}
593
GetClassName() const594 CFX_ByteString CPWL_NoteItem::GetClassName() const {
595 return "CPWL_NoteItem";
596 }
597
CreateChildWnd(const PWL_CREATEPARAM & cp)598 void CPWL_NoteItem::CreateChildWnd(const PWL_CREATEPARAM& cp) {
599 CPWL_Color sTextColor;
600
601 if (CPWL_Utils::IsBlackOrWhite(GetBackgroundColor()))
602 sTextColor = PWL_DEFAULT_WHITECOLOR;
603 else
604 sTextColor = PWL_DEFAULT_BLACKCOLOR;
605
606 m_pSubject = new CPWL_Label;
607 PWL_CREATEPARAM scp = cp;
608 scp.pParentWnd = this;
609 scp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_LEFT | PES_TOP;
610 scp.sTextColor = sTextColor;
611 m_pSubject->Create(scp);
612
613 m_pDateTime = new CPWL_Label;
614 PWL_CREATEPARAM dcp = cp;
615 dcp.pParentWnd = this;
616 dcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_RIGHT | PES_TOP;
617 dcp.sTextColor = sTextColor;
618 m_pDateTime->Create(dcp);
619
620 m_pContents = new CPWL_Note_Contents;
621 PWL_CREATEPARAM ccp = cp;
622 ccp.pParentWnd = this;
623 ccp.sBackgroundColor =
624 CPWL_Color(COLORTYPE_RGB, 240 / 255.0f, 240 / 255.0f, 240 / 255.0f);
625 ccp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BACKGROUND;
626 m_pContents->Create(ccp);
627 m_pContents->SetItemSpace(POPUP_ITEM_SPACE);
628 m_pContents->SetTopSpace(POPUP_ITEM_SPACE);
629 m_pContents->SetBottomSpace(POPUP_ITEM_SPACE);
630 }
631
RePosChildWnd()632 void CPWL_NoteItem::RePosChildWnd() {
633 if (IsValid()) {
634 CPDF_Rect rcClient = GetClientRect();
635
636 CPDF_Rect rcSubject = rcClient;
637 rcSubject.left += POPUP_ITEM_TEXT_INDENT;
638 rcSubject.top = rcClient.top;
639 rcSubject.right =
640 PWL_MIN(rcSubject.left + m_pSubject->GetContentRect().Width() + 1.0f,
641 rcClient.right);
642 rcSubject.bottom = rcSubject.top - m_pSubject->GetContentRect().Height();
643 rcSubject.Normalize();
644 m_pSubject->Move(rcSubject, TRUE, FALSE);
645 m_pSubject->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcSubject));
646
647 CPDF_Rect rcDate = rcClient;
648 rcDate.right -= POPUP_ITEM_TEXT_INDENT;
649 rcDate.left =
650 PWL_MAX(rcDate.right - m_pDateTime->GetContentRect().Width() - 1.0f,
651 rcSubject.right);
652 rcDate.bottom = rcDate.top - m_pDateTime->GetContentRect().Height();
653 rcDate.Normalize();
654 m_pDateTime->Move(rcDate, TRUE, FALSE);
655 m_pDateTime->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcDate));
656
657 CPDF_Rect rcContents = rcClient;
658 rcContents.left += 1.0f;
659 rcContents.right -= 1.0f;
660 rcContents.top = rcDate.bottom - POPUP_ITEM_HEAD_BOTTOM;
661 rcContents.bottom += POPUP_ITEM_BOTTOMWIDTH;
662 rcContents.Normalize();
663 m_pContents->Move(rcContents, TRUE, FALSE);
664 m_pContents->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcContents));
665 }
666
667 SetClipRect(CPWL_Utils::InflateRect(GetWindowRect(), 1.0f));
668 }
669
SetPrivateData(void * pData)670 void CPWL_NoteItem::SetPrivateData(void* pData) {
671 m_pPrivateData = pData;
672 }
673
SetBkColor(const CPWL_Color & color)674 void CPWL_NoteItem::SetBkColor(const CPWL_Color& color) {
675 CPWL_Color sBK = color;
676 SetBackgroundColor(sBK);
677
678 CPWL_Color sTextColor;
679
680 if (CPWL_Utils::IsBlackOrWhite(sBK))
681 sTextColor = PWL_DEFAULT_WHITECOLOR;
682 else
683 sTextColor = PWL_DEFAULT_BLACKCOLOR;
684
685 SetTextColor(sTextColor);
686 if (m_pSubject)
687 m_pSubject->SetTextColor(sTextColor);
688 if (m_pDateTime)
689 m_pDateTime->SetTextColor(sTextColor);
690
691 InvalidateRect(nullptr);
692
693 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
694 pNotify->OnSetBkColor(this);
695 }
696 }
697
SetSubjectName(const CFX_WideString & sName)698 void CPWL_NoteItem::SetSubjectName(const CFX_WideString& sName) {
699 if (m_pSubject) {
700 m_pSubject->SetText(sName.c_str());
701 }
702
703 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
704 pNotify->OnSetSubjectName(this);
705 }
706 }
707
SetAuthorName(const CFX_WideString & sName)708 void CPWL_NoteItem::SetAuthorName(const CFX_WideString& sName) {
709 m_sAuthor = sName;
710 ResetSubjectName(-1);
711
712 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
713 pNotify->OnSetAuthorName(this);
714 }
715 }
716
ResetSubjectName(int32_t nItemIndex)717 void CPWL_NoteItem::ResetSubjectName(int32_t nItemIndex) {
718 if (nItemIndex < 0) {
719 if (CPWL_Wnd* pParent = GetParentWindow()) {
720 ASSERT(pParent->GetClassName() == "CPWL_Note_Contents");
721
722 CPWL_Note_Contents* pContents = (CPWL_Note_Contents*)pParent;
723 nItemIndex = pContents->GetItemIndex(this);
724 }
725 }
726
727 const CPWL_Note* pNote = GetNote();
728 CFX_WideString sSubject;
729 sSubject.Format(pNote->GetReplyString().c_str(), nItemIndex);
730
731 if (!m_sAuthor.IsEmpty()) {
732 sSubject += L" - ";
733 sSubject += m_sAuthor;
734 }
735 SetSubjectName(sSubject);
736 RePosChildWnd();
737 }
738
SetDateTime(FX_SYSTEMTIME time)739 void CPWL_NoteItem::SetDateTime(FX_SYSTEMTIME time) {
740 m_dtNote = time;
741
742 CFX_WideString swTime;
743 swTime.Format(L"%04d-%02d-%02d %02d:%02d:%02d", time.wYear, time.wMonth,
744 time.wDay, time.wHour, time.wMinute, time.wSecond);
745 if (m_pDateTime) {
746 m_pDateTime->SetText(swTime.c_str());
747 }
748
749 RePosChildWnd();
750
751 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
752 pNotify->OnSetDateTime(this);
753 }
754 }
755
SetContents(const CFX_WideString & sContents)756 void CPWL_NoteItem::SetContents(const CFX_WideString& sContents) {
757 if (m_pContents) {
758 m_pContents->SetText(sContents);
759 }
760
761 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
762 pNotify->OnSetContents(this);
763 }
764 }
765
GetParentNoteItem() const766 CPWL_NoteItem* CPWL_NoteItem::GetParentNoteItem() const {
767 if (CPWL_Wnd* pParent = GetParentWindow()) {
768 if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) {
769 ASSERT(pGrand->GetClassName() == "CPWL_NoteItem");
770 return (CPWL_NoteItem*)pGrand;
771 }
772 }
773
774 return NULL;
775 }
776
GetParentItem() const777 IPWL_NoteItem* CPWL_NoteItem::GetParentItem() const {
778 return GetParentNoteItem();
779 }
780
GetEdit() const781 CPWL_Edit* CPWL_NoteItem::GetEdit() const {
782 if (m_pContents)
783 return m_pContents->GetEdit();
784 return NULL;
785 }
786
GetPrivateData() const787 void* CPWL_NoteItem::GetPrivateData() const {
788 return m_pPrivateData;
789 }
790
GetAuthorName() const791 CFX_WideString CPWL_NoteItem::GetAuthorName() const {
792 return m_sAuthor;
793 }
794
GetBkColor() const795 CPWL_Color CPWL_NoteItem::GetBkColor() const {
796 return GetBackgroundColor();
797 }
798
GetContents() const799 CFX_WideString CPWL_NoteItem::GetContents() const {
800 if (m_pContents)
801 return m_pContents->GetText();
802
803 return L"";
804 }
805
GetDateTime() const806 FX_SYSTEMTIME CPWL_NoteItem::GetDateTime() const {
807 return m_dtNote;
808 }
809
GetSubjectName() const810 CFX_WideString CPWL_NoteItem::GetSubjectName() const {
811 if (m_pSubject)
812 return m_pSubject->GetText();
813
814 return L"";
815 }
816
CreateNoteItem()817 CPWL_NoteItem* CPWL_NoteItem::CreateNoteItem() {
818 if (m_pContents)
819 return m_pContents->CreateSubItem();
820
821 return NULL;
822 }
823
CreateSubItem()824 IPWL_NoteItem* CPWL_NoteItem::CreateSubItem() {
825 return CreateNoteItem();
826 }
827
CountSubItems() const828 int32_t CPWL_NoteItem::CountSubItems() const {
829 if (m_pContents)
830 return m_pContents->CountSubItems();
831
832 return 0;
833 }
834
GetSubItems(int32_t index) const835 IPWL_NoteItem* CPWL_NoteItem::GetSubItems(int32_t index) const {
836 if (m_pContents)
837 return m_pContents->GetSubItems(index);
838
839 return NULL;
840 }
841
DeleteSubItem(IPWL_NoteItem * pNoteItem)842 void CPWL_NoteItem::DeleteSubItem(IPWL_NoteItem* pNoteItem) {
843 KillFocus();
844
845 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
846 pNotify->OnItemDelete(pNoteItem);
847 }
848
849 if (m_pContents)
850 m_pContents->DeleteSubItem(pNoteItem);
851 }
852
GetHitNoteItem(const CPDF_Point & point)853 IPWL_NoteItem* CPWL_NoteItem::GetHitNoteItem(const CPDF_Point& point) {
854 CPDF_Point pt = ParentToChild(point);
855
856 if (WndHitTest(pt)) {
857 if (m_pContents) {
858 if (IPWL_NoteItem* pNoteItem = m_pContents->GetHitNoteItem(pt))
859 return pNoteItem;
860 }
861
862 return this;
863 }
864
865 return NULL;
866 }
867
GetFocusedNoteItem() const868 IPWL_NoteItem* CPWL_NoteItem::GetFocusedNoteItem() const {
869 if (const CPWL_Wnd* pWnd = GetFocused()) {
870 if (pWnd->GetClassName() == "CPWL_Edit") {
871 if (CPWL_Wnd* pParent = pWnd->GetParentWindow()) {
872 ASSERT(pParent->GetClassName() == "CPWL_Note_Contents");
873
874 if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) {
875 ASSERT(pGrand->GetClassName() == "CPWL_NoteItem");
876 return (CPWL_NoteItem*)pGrand;
877 }
878 }
879 }
880 }
881
882 return NULL;
883 }
884
GetItemHeight(FX_FLOAT fLimitWidth)885 FX_FLOAT CPWL_NoteItem::GetItemHeight(FX_FLOAT fLimitWidth) {
886 if (fLimitWidth > 0) {
887 if (!m_bSizeChanged)
888 return m_fOldItemHeight;
889
890 m_bSizeChanged = FALSE;
891
892 FX_FLOAT fRet = m_pDateTime->GetContentRect().Height();
893 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
894 if (fLimitWidth > fBorderWidth * 2)
895 fRet += m_pContents->GetContentsHeight(fLimitWidth - fBorderWidth * 2);
896 fRet += POPUP_ITEM_HEAD_BOTTOM + POPUP_ITEM_BOTTOMWIDTH + fBorderWidth * 2;
897
898 return m_fOldItemHeight = fRet;
899 }
900
901 return 0;
902 }
903
GetItemLeftMargin()904 FX_FLOAT CPWL_NoteItem::GetItemLeftMargin() {
905 return POPUP_ITEM_SIDEMARGIN;
906 }
907
GetItemRightMargin()908 FX_FLOAT CPWL_NoteItem::GetItemRightMargin() {
909 return POPUP_ITEM_SIDEMARGIN;
910 }
911
OnLButtonDown(const CPDF_Point & point,FX_DWORD nFlag)912 FX_BOOL CPWL_NoteItem::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
913 if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) {
914 SetNoteFocus(FALSE);
915 }
916
917 CPWL_Wnd::OnLButtonDown(point, nFlag);
918
919 return TRUE;
920 }
921
OnRButtonUp(const CPDF_Point & point,FX_DWORD nFlag)922 FX_BOOL CPWL_NoteItem::OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
923 if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) {
924 SetNoteFocus(FALSE);
925 PopupNoteItemMenu(point);
926
927 return TRUE;
928 }
929
930 return CPWL_Wnd::OnRButtonUp(point, nFlag);
931 }
932
OnNotify(CPWL_Wnd * pWnd,FX_DWORD msg,intptr_t wParam,intptr_t lParam)933 void CPWL_NoteItem::OnNotify(CPWL_Wnd* pWnd,
934 FX_DWORD msg,
935 intptr_t wParam,
936 intptr_t lParam) {
937 switch (msg) {
938 case PNM_NOTEEDITCHANGED:
939 m_bSizeChanged = TRUE;
940
941 if (CPWL_Wnd* pParent = GetParentWindow()) {
942 pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
943 }
944 return;
945 case PNM_SETCARETINFO:
946 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
947 PWL_CARET_INFO newInfo = *pInfo;
948 newInfo.bVisible = TRUE;
949 newInfo.ptHead = ChildToParent(pInfo->ptHead);
950 newInfo.ptFoot = ChildToParent(pInfo->ptFoot);
951
952 if (CPWL_Wnd* pParent = GetParentWindow()) {
953 pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0);
954 }
955 }
956 return;
957 case PNM_NOTERESET:
958 m_bSizeChanged = TRUE;
959 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
960
961 return;
962 }
963
964 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
965 }
966
PopupNoteItemMenu(const CPDF_Point & point)967 void CPWL_NoteItem::PopupNoteItemMenu(const CPDF_Point& point) {
968 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
969 int32_t x, y;
970 PWLtoWnd(point, x, y);
971 if (IFX_SystemHandler* pSH = GetSystemHandler())
972 pSH->ClientToScreen(GetAttachedHWnd(), x, y);
973 pNotify->OnPopupMenu(this, x, y);
974 }
975 }
976
GetNote() const977 const CPWL_Note* CPWL_NoteItem::GetNote() const {
978 if (const CPWL_Wnd* pRoot = GetRootWnd()) {
979 ASSERT(pRoot->GetClassName() == "CPWL_NoteItem");
980 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pRoot;
981 if (pNoteItem->IsTopItem()) {
982 return (CPWL_Note*)pNoteItem;
983 }
984 }
985
986 return NULL;
987 }
988
GetNoteNotify() const989 IPWL_NoteNotify* CPWL_NoteItem::GetNoteNotify() const {
990 if (const CPWL_Note* pNote = GetNote())
991 return pNote->GetNoteNotify();
992
993 return NULL;
994 }
995
OnCreateNoteItem()996 void CPWL_NoteItem::OnCreateNoteItem() {
997 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
998 pNotify->OnItemCreate(this);
999 }
1000 }
1001
OnContentsValidate()1002 void CPWL_NoteItem::OnContentsValidate() {
1003 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
1004 pNotify->OnSetContents(this);
1005 }
1006 }
1007
SetNoteFocus(FX_BOOL bLast)1008 void CPWL_NoteItem::SetNoteFocus(FX_BOOL bLast) {
1009 m_pContents->SetEditFocus(bLast);
1010 }
1011
EnableModify(FX_BOOL bEnabled)1012 void CPWL_NoteItem::EnableModify(FX_BOOL bEnabled) {
1013 m_pContents->EnableModify(bEnabled);
1014 m_bAllowModify = bEnabled;
1015 }
1016
EnableRead(FX_BOOL bEnabled)1017 void CPWL_NoteItem::EnableRead(FX_BOOL bEnabled) {
1018 m_pContents->EnableRead(bEnabled);
1019 }
1020
CPWL_Note(IPopup_Note * pPopupNote,IPWL_NoteNotify * pNoteNotify,IPWL_NoteHandler * pNoteHandler)1021 CPWL_Note::CPWL_Note(IPopup_Note* pPopupNote,
1022 IPWL_NoteNotify* pNoteNotify,
1023 IPWL_NoteHandler* pNoteHandler)
1024 : m_pAuthor(NULL),
1025 m_pIcon(NULL),
1026 m_pCloseBox(NULL),
1027 m_pLBBox(NULL),
1028 m_pRBBox(NULL),
1029 m_pContentsBar(NULL),
1030 m_pOptions(NULL),
1031 m_pNoteNotify(pNoteNotify),
1032 m_bResizing(FALSE),
1033 m_bEnableNotify(TRUE) {}
1034
~CPWL_Note()1035 CPWL_Note::~CPWL_Note() {}
1036
Reply()1037 IPWL_NoteItem* CPWL_Note::Reply() {
1038 return CreateNoteItem();
1039 }
1040
EnableNotify(FX_BOOL bEnabled)1041 void CPWL_Note::EnableNotify(FX_BOOL bEnabled) {
1042 m_bEnableNotify = bEnabled;
1043 }
1044
RePosChildWnd()1045 void CPWL_Note::RePosChildWnd() {
1046 RePosNoteChildren();
1047 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
1048 ResetScrollBar();
1049 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
1050 OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
1051 if (const CPWL_Wnd* pWnd = GetFocused()) {
1052 if (pWnd->GetClassName() == "CPWL_Edit") {
1053 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
1054 pEdit->SetCaret(pEdit->GetCaret());
1055 }
1056 }
1057 }
1058
ResetScrollBar()1059 FX_BOOL CPWL_Note::ResetScrollBar() {
1060 FX_BOOL bScrollChanged = FALSE;
1061
1062 if (ScrollBarShouldVisible()) {
1063 if (!m_pContentsBar->IsVisible()) {
1064 m_pContentsBar->SetVisible(TRUE);
1065 if (m_pContentsBar->IsVisible()) {
1066 m_pContentsBar->InvalidateRect(NULL);
1067 bScrollChanged = TRUE;
1068 }
1069 }
1070 } else {
1071 if (m_pContentsBar->IsVisible()) {
1072 m_pContentsBar->SetVisible(FALSE);
1073 m_pContentsBar->InvalidateRect(NULL);
1074
1075 bScrollChanged = TRUE;
1076 }
1077 }
1078
1079 if (bScrollChanged) {
1080 CPDF_Rect rcNote = GetClientRect();
1081 CPDF_Rect rcContents = m_pContents->GetWindowRect();
1082 rcContents.right = rcNote.right - 3.0f;
1083 if (m_pContentsBar->IsVisible())
1084 rcContents.right -= PWL_SCROLLBAR_WIDTH;
1085 m_pContents->Move(rcContents, TRUE, TRUE);
1086 m_pContents->SetScrollPos(CPDF_Point(0.0f, 0.0f));
1087 m_pContents->InvalidateRect(NULL);
1088 }
1089
1090 return bScrollChanged;
1091 }
1092
ScrollBarShouldVisible()1093 FX_BOOL CPWL_Note::ScrollBarShouldVisible() {
1094 CPDF_Rect rcContentsFact = m_pContents->GetScrollArea();
1095 CPDF_Rect rcContentsClient = m_pContents->GetClientRect();
1096
1097 return rcContentsFact.Height() > rcContentsClient.Height();
1098 }
1099
SetOptionsText(const CFX_WideString & sText)1100 void CPWL_Note::SetOptionsText(const CFX_WideString& sText) {
1101 if (m_pOptions)
1102 m_pOptions->SetText(sText);
1103
1104 RePosNoteChildren();
1105 }
1106
RePosNoteChildren()1107 void CPWL_Note::RePosNoteChildren() {
1108 if (m_bResizing)
1109 return;
1110
1111 m_bResizing = TRUE;
1112
1113 if (IsValid()) {
1114 CPDF_Rect rcClient = GetClientRect();
1115
1116 CPDF_Rect rcIcon = rcClient;
1117 rcIcon.top -= 2.0f;
1118 rcIcon.right = rcIcon.left + 14.0f;
1119 rcIcon.bottom = rcIcon.top - 14.0f;
1120 rcIcon.Normalize();
1121 m_pIcon->Move(rcIcon, TRUE, FALSE);
1122 m_pIcon->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcIcon));
1123
1124 CPDF_Rect rcCloseBox = rcClient;
1125 rcCloseBox.right -= 1.0f;
1126 rcCloseBox.top -= 1.0f;
1127 rcCloseBox.left = rcCloseBox.right - 14.0f;
1128 rcCloseBox.bottom = rcCloseBox.top - 14.0f;
1129 rcCloseBox.Normalize();
1130 m_pCloseBox->Move(rcCloseBox, TRUE, FALSE);
1131 m_pCloseBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcCloseBox));
1132
1133 CPDF_Rect rcDate = rcClient;
1134 rcDate.right = rcCloseBox.left - POPUP_ITEM_TEXT_INDENT;
1135 rcDate.left =
1136 PWL_MAX(rcDate.right - m_pDateTime->GetContentRect().Width() - 1.0f,
1137 rcIcon.right + 1.0f);
1138 rcDate.top = rcClient.top - 2.0f;
1139 rcDate.bottom = rcDate.top - m_pDateTime->GetContentRect().Height();
1140 rcDate.Normalize();
1141 m_pDateTime->Move(rcDate, TRUE, FALSE);
1142 m_pDateTime->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcDate));
1143
1144 CPDF_Rect rcSubject = rcClient;
1145 rcSubject.top = rcClient.top - 2.0f;
1146 rcSubject.left = rcIcon.right + POPUP_ITEM_TEXT_INDENT;
1147 rcSubject.right =
1148 PWL_MIN(rcSubject.left + m_pSubject->GetContentRect().Width() + 1.0f,
1149 rcDate.left - 1.0f);
1150 rcSubject.bottom = rcSubject.top - m_pSubject->GetContentRect().Height();
1151 rcSubject.Normalize();
1152 m_pSubject->Move(rcSubject, TRUE, FALSE);
1153 m_pSubject->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcSubject));
1154
1155 CPDF_Rect rcOptions = rcClient;
1156 rcOptions.left =
1157 PWL_MAX(rcOptions.right - m_pOptions->GetContentRect().Width(),
1158 rcIcon.right + 1.0f);
1159 rcOptions.top = rcSubject.bottom - 4.0f;
1160 rcOptions.bottom = rcOptions.top - m_pOptions->GetContentRect().Height();
1161 rcOptions.Normalize();
1162 m_pOptions->Move(rcOptions, TRUE, FALSE);
1163 m_pOptions->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcOptions));
1164
1165 CPDF_Rect rcAuthor = rcClient;
1166 rcAuthor.top = rcSubject.bottom - 4.0f;
1167 rcAuthor.left = rcSubject.left;
1168 rcAuthor.right =
1169 PWL_MIN(rcSubject.left + m_pAuthor->GetContentRect().Width() + 1.0f,
1170 rcOptions.left - 1.0f);
1171 rcAuthor.bottom = rcAuthor.top - m_pAuthor->GetContentRect().Height();
1172 rcAuthor.Normalize();
1173 m_pAuthor->Move(rcAuthor, TRUE, FALSE);
1174 m_pAuthor->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcAuthor));
1175
1176 CPDF_Rect rcLBBox = rcClient;
1177 rcLBBox.top = rcLBBox.bottom + 7.0f;
1178 rcLBBox.right = rcLBBox.left + 7.0f;
1179 rcLBBox.Normalize();
1180 m_pLBBox->Move(rcLBBox, TRUE, FALSE);
1181 m_pLBBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcLBBox));
1182
1183 CPDF_Rect rcRBBox = rcClient;
1184 rcRBBox.top = rcRBBox.bottom + 7.0f;
1185 rcRBBox.left = rcRBBox.right - 7.0f;
1186 rcRBBox.Normalize();
1187 m_pRBBox->Move(rcRBBox, TRUE, FALSE);
1188 m_pRBBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcRBBox));
1189
1190 CPDF_Rect rcContents = rcClient;
1191 rcContents.top = rcAuthor.bottom - POPUP_ITEM_HEAD_BOTTOM;
1192 rcContents.left += 3.0f;
1193 rcContents.right -= 3.0f;
1194 if (m_pContentsBar->IsVisible())
1195 rcContents.right -= PWL_SCROLLBAR_WIDTH;
1196 rcContents.bottom += 14.0f;
1197 rcContents.Normalize();
1198 m_pContents->Move(rcContents, FALSE, FALSE);
1199 m_pContents->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcContents));
1200
1201 CPDF_Rect rcContentsBar = rcContents;
1202 rcContentsBar.right = rcClient.right - 3.0f;
1203 rcContentsBar.left = rcContentsBar.right - PWL_SCROLLBAR_WIDTH;
1204 rcContentsBar.Normalize();
1205 m_pContentsBar->Move(rcContentsBar, TRUE, FALSE);
1206 }
1207
1208 m_bResizing = FALSE;
1209 }
1210
CreateChildWnd(const PWL_CREATEPARAM & cp)1211 void CPWL_Note::CreateChildWnd(const PWL_CREATEPARAM& cp) {
1212 CPWL_NoteItem::CreateChildWnd(cp);
1213
1214 CPWL_Color sTextColor;
1215
1216 if (CPWL_Utils::IsBlackOrWhite(GetBackgroundColor()))
1217 sTextColor = PWL_DEFAULT_WHITECOLOR;
1218 else
1219 sTextColor = PWL_DEFAULT_BLACKCOLOR;
1220
1221 m_pAuthor = new CPWL_Label;
1222 PWL_CREATEPARAM acp = cp;
1223 acp.pParentWnd = this;
1224 acp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_LEFT | PES_TOP;
1225 acp.sTextColor = sTextColor;
1226 m_pAuthor->Create(acp);
1227
1228 m_pCloseBox = new CPWL_Note_CloseBox;
1229 PWL_CREATEPARAM ccp = cp;
1230 ccp.pParentWnd = this;
1231 ccp.dwBorderWidth = 2;
1232 ccp.nBorderStyle = PBS_BEVELED;
1233 ccp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER;
1234 ccp.sTextColor = sTextColor;
1235 m_pCloseBox->Create(ccp);
1236
1237 m_pIcon = new CPWL_Note_Icon;
1238 PWL_CREATEPARAM icp = cp;
1239 icp.pParentWnd = this;
1240 icp.dwFlags = PWS_VISIBLE | PWS_CHILD;
1241 m_pIcon->Create(icp);
1242
1243 m_pOptions = new CPWL_Note_Options;
1244 PWL_CREATEPARAM ocp = cp;
1245 ocp.pParentWnd = this;
1246 ocp.dwFlags = PWS_CHILD | PWS_VISIBLE;
1247 ocp.sTextColor = sTextColor;
1248 m_pOptions->Create(ocp);
1249
1250 m_pLBBox = new CPWL_Note_LBBox;
1251 PWL_CREATEPARAM lcp = cp;
1252 lcp.pParentWnd = this;
1253 lcp.dwFlags = PWS_VISIBLE | PWS_CHILD;
1254 lcp.eCursorType = FXCT_NESW;
1255 lcp.sTextColor = sTextColor;
1256 m_pLBBox->Create(lcp);
1257
1258 m_pRBBox = new CPWL_Note_RBBox;
1259 PWL_CREATEPARAM rcp = cp;
1260 rcp.pParentWnd = this;
1261 rcp.dwFlags = PWS_VISIBLE | PWS_CHILD;
1262 rcp.eCursorType = FXCT_NWSE;
1263 rcp.sTextColor = sTextColor;
1264 m_pRBBox->Create(rcp);
1265
1266 m_pContentsBar = new CPWL_ScrollBar(SBT_VSCROLL);
1267 PWL_CREATEPARAM scp = cp;
1268 scp.pParentWnd = this;
1269 scp.sBackgroundColor =
1270 CPWL_Color(COLORTYPE_RGB, 240 / 255.0f, 240 / 255.0f, 240 / 255.0f);
1271 scp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_BACKGROUND;
1272 m_pContentsBar->Create(scp);
1273 m_pContentsBar->SetNotifyForever(TRUE);
1274 }
1275
SetSubjectName(const CFX_WideString & sName)1276 void CPWL_Note::SetSubjectName(const CFX_WideString& sName) {
1277 CPWL_NoteItem::SetSubjectName(sName);
1278 RePosChildWnd();
1279 }
1280
SetAuthorName(const CFX_WideString & sName)1281 void CPWL_Note::SetAuthorName(const CFX_WideString& sName) {
1282 if (m_pAuthor) {
1283 m_pAuthor->SetText(sName.c_str());
1284 RePosChildWnd();
1285 }
1286
1287 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
1288 pNotify->OnSetAuthorName(this);
1289 }
1290 }
1291
GetAuthorName() const1292 CFX_WideString CPWL_Note::GetAuthorName() const {
1293 if (m_pAuthor)
1294 return m_pAuthor->GetText();
1295
1296 return L"";
1297 }
1298
OnMouseWheel(short zDelta,const CPDF_Point & point,FX_DWORD nFlag)1299 FX_BOOL CPWL_Note::OnMouseWheel(short zDelta,
1300 const CPDF_Point& point,
1301 FX_DWORD nFlag) {
1302 CPDF_Point ptScroll = m_pContents->GetScrollPos();
1303 CPDF_Rect rcScroll = m_pContents->GetScrollArea();
1304 CPDF_Rect rcContents = m_pContents->GetClientRect();
1305
1306 if (rcScroll.top - rcScroll.bottom > rcContents.Height()) {
1307 CPDF_Point ptNew = ptScroll;
1308
1309 if (zDelta > 0)
1310 ptNew.y += 30;
1311 else
1312 ptNew.y -= 30;
1313
1314 if (ptNew.y > rcScroll.top)
1315 ptNew.y = rcScroll.top;
1316 if (ptNew.y < rcScroll.bottom + rcContents.Height())
1317 ptNew.y = rcScroll.bottom + rcContents.Height();
1318 if (ptNew.y < rcScroll.bottom)
1319 ptNew.y = rcScroll.bottom;
1320
1321 if (ptNew.y != ptScroll.y) {
1322 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
1323 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
1324 (intptr_t)&ptNew.y);
1325 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
1326 (intptr_t)&ptNew.y);
1327
1328 return TRUE;
1329 }
1330 }
1331
1332 return FALSE;
1333 }
1334
OnNotify(CPWL_Wnd * pWnd,FX_DWORD msg,intptr_t wParam,intptr_t lParam)1335 void CPWL_Note::OnNotify(CPWL_Wnd* pWnd,
1336 FX_DWORD msg,
1337 intptr_t wParam,
1338 intptr_t lParam) {
1339 switch (msg) {
1340 case PNM_NOTEEDITCHANGED: {
1341 CPDF_Rect rcScroll = m_pContents->GetScrollArea();
1342
1343 PWL_SCROLL_INFO sInfo;
1344 sInfo.fContentMin = rcScroll.bottom;
1345 sInfo.fContentMax = rcScroll.top;
1346 sInfo.fPlateWidth = m_pContents->GetClientRect().Height();
1347 sInfo.fSmallStep = 13.0f;
1348 sInfo.fBigStep = sInfo.fPlateWidth;
1349
1350 if (FXSYS_memcmp(&m_OldScrollInfo, &sInfo, sizeof(PWL_SCROLL_INFO)) !=
1351 0) {
1352 FX_BOOL bScrollChanged = FALSE;
1353
1354 if (lParam < 3) {
1355 bScrollChanged = ResetScrollBar();
1356 if (bScrollChanged) {
1357 lParam++;
1358 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
1359 OnNotify(this, PNM_NOTEEDITCHANGED, 0, lParam);
1360 }
1361 }
1362
1363 if (!bScrollChanged) {
1364 if (m_pContentsBar->IsVisible()) {
1365 m_pContentsBar->OnNotify(pWnd, PNM_SETSCROLLINFO, SBT_VSCROLL,
1366 (intptr_t)&sInfo);
1367 m_OldScrollInfo = sInfo;
1368
1369 CPDF_Point ptScroll = m_pContents->GetScrollPos();
1370 CPDF_Point ptOld = ptScroll;
1371
1372 if (ptScroll.y > sInfo.fContentMax)
1373 ptScroll.y = sInfo.fContentMax;
1374 if (ptScroll.y < sInfo.fContentMin + sInfo.fPlateWidth)
1375 ptScroll.y = sInfo.fContentMin + sInfo.fPlateWidth;
1376 if (ptScroll.y < sInfo.fContentMin)
1377 ptScroll.y = sInfo.fContentMin;
1378
1379 if (ptOld.y != ptScroll.y) {
1380 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
1381 (intptr_t)&ptScroll.y);
1382 m_pContentsBar->InvalidateRect(NULL);
1383 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
1384 (intptr_t)&ptScroll.y);
1385 }
1386 }
1387 }
1388 }
1389 }
1390
1391 m_pContents->InvalidateRect(NULL);
1392
1393 return;
1394 case PNM_SCROLLWINDOW:
1395 if (m_pContents)
1396 m_pContents->OnNotify(pWnd, msg, wParam, lParam);
1397 return;
1398 case PNM_SETSCROLLPOS:
1399 if (m_pContentsBar)
1400 m_pContentsBar->OnNotify(pWnd, PNM_SETSCROLLPOS, wParam, lParam);
1401 return;
1402 }
1403
1404 if (msg == PNM_SETCARETINFO && IsValid()) {
1405 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
1406 if (m_pContents) {
1407 CPDF_Rect rcClient = m_pContents->GetClientRect();
1408 if (pInfo->ptHead.y > rcClient.top) {
1409 CPDF_Point pt = m_pContents->OutToIn(pInfo->ptHead);
1410 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
1411 (intptr_t)&pt.y);
1412
1413 CPDF_Point ptScroll = m_pContents->GetScrollPos();
1414 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
1415 (intptr_t)&ptScroll.y);
1416
1417 return;
1418 }
1419
1420 if (pInfo->ptFoot.y < rcClient.bottom) {
1421 CPDF_Point pt = m_pContents->OutToIn(pInfo->ptFoot);
1422 pt.y += rcClient.Height();
1423 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
1424 (intptr_t)&pt.y);
1425
1426 CPDF_Point ptScroll = m_pContents->GetScrollPos();
1427 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
1428 (intptr_t)&ptScroll.y);
1429
1430 return;
1431 }
1432 }
1433 }
1434 }
1435
1436 CPWL_NoteItem::OnNotify(pWnd, msg, wParam, lParam);
1437 }
1438
SetBkColor(const CPWL_Color & color)1439 void CPWL_Note::SetBkColor(const CPWL_Color& color) {
1440 CPWL_NoteItem::SetBkColor(color);
1441
1442 CPWL_Color sBK = color;
1443 CPWL_Color sTextColor;
1444 if (CPWL_Utils::IsBlackOrWhite(sBK))
1445 sTextColor = PWL_DEFAULT_WHITECOLOR;
1446 else
1447 sTextColor = PWL_DEFAULT_BLACKCOLOR;
1448
1449 if (m_pCloseBox)
1450 m_pCloseBox->SetTextColor(sTextColor);
1451 if (m_pAuthor)
1452 m_pAuthor->SetTextColor(sTextColor);
1453 if (m_pOptions)
1454 m_pOptions->SetTextColor(sTextColor);
1455 if (m_pLBBox)
1456 m_pLBBox->SetTextColor(sTextColor);
1457 if (m_pRBBox)
1458 m_pRBBox->SetTextColor(sTextColor);
1459 }
1460
OnLButtonDown(const CPDF_Point & point,FX_DWORD nFlag)1461 FX_BOOL CPWL_Note::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
1462 if (m_pOptions->WndHitTest(m_pOptions->ParentToChild(point))) {
1463 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
1464 int32_t x, y;
1465 PWLtoWnd(point, x, y);
1466 if (IFX_SystemHandler* pSH = GetSystemHandler())
1467 pSH->ClientToScreen(GetAttachedHWnd(), x, y);
1468 KillFocus();
1469 pNotify->OnPopupMenu(x, y);
1470
1471 return TRUE;
1472 }
1473 }
1474
1475 return CPWL_Wnd::OnLButtonDown(point, nFlag);
1476 }
1477
OnRButtonUp(const CPDF_Point & point,FX_DWORD nFlag)1478 FX_BOOL CPWL_Note::OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
1479 return CPWL_Wnd::OnRButtonUp(point, nFlag);
1480 }
1481
GetNote() const1482 const CPWL_Note* CPWL_Note::GetNote() const {
1483 return this;
1484 }
1485
GetNoteNotify() const1486 IPWL_NoteNotify* CPWL_Note::GetNoteNotify() const {
1487 return m_bEnableNotify ? m_pNoteNotify : nullptr;
1488 }
1489
SetIconType(int32_t nType)1490 void CPWL_Note::SetIconType(int32_t nType) {
1491 if (m_pIcon)
1492 m_pIcon->SetIconType(nType);
1493 }
1494
EnableModify(FX_BOOL bEnabled)1495 void CPWL_Note::EnableModify(FX_BOOL bEnabled) {
1496 m_pContents->EnableModify(bEnabled);
1497 }
1498
EnableRead(FX_BOOL bEnabled)1499 void CPWL_Note::EnableRead(FX_BOOL bEnabled) {
1500 m_pContents->EnableRead(bEnabled);
1501 }
1502
GetReplyString() const1503 CFX_WideString CPWL_Note::GetReplyString() const {
1504 return m_sReplyString;
1505 }
1506
SetReplyString(const CFX_WideString & string)1507 void CPWL_Note::SetReplyString(const CFX_WideString& string) {
1508 m_sReplyString = string;
1509 }
1510