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