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 32 CPWL_Note_Options::CPWL_Note_Options() : m_pText(NULL) {} 33 34 CPWL_Note_Options::~CPWL_Note_Options() {} 35 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 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 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 66 void CPWL_Note_Options::SetText(const CFX_WideString& sText) { 67 m_pText->SetText(sText.c_str()); 68 } 69 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 98 CPDF_Rect CPWL_Note_Options::GetContentRect() const { 99 CPDF_Rect rcText = m_pText->GetContentRect(); 100 rcText.right += 15.0f; 101 return rcText; 102 } 103 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 111 CPWL_Note_Edit::~CPWL_Note_Edit() {} 112 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 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 128 void CPWL_Note_Edit::OnSetFocus() { 129 m_bEnableNotify = FALSE; 130 CPWL_Edit::OnSetFocus(); 131 m_bEnableNotify = TRUE; 132 133 EnableSpellCheck(TRUE); 134 } 135 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 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 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 221 FX_FLOAT CPWL_Note_Edit::GetItemLeftMargin() { 222 return POPUP_ITEM_TEXT_INDENT; 223 } 224 225 FX_FLOAT CPWL_Note_Edit::GetItemRightMargin() { 226 return POPUP_ITEM_TEXT_INDENT; 227 } 228 229 CPWL_Note_LBBox::CPWL_Note_LBBox() {} 230 231 CPWL_Note_LBBox::~CPWL_Note_LBBox() {} 232 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 256 CPWL_Note_RBBox::CPWL_Note_RBBox() {} 257 258 CPWL_Note_RBBox::~CPWL_Note_RBBox() {} 259 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 283 CPWL_Note_Icon::CPWL_Note_Icon() : m_nType(0) {} 284 285 CPWL_Note_Icon::~CPWL_Note_Icon() {} 286 287 void CPWL_Note_Icon::SetIconType(int32_t nType) { 288 m_nType = nType; 289 } 290 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 298 CPWL_Note_CloseBox::CPWL_Note_CloseBox() : m_bMouseDown(FALSE) {} 299 300 CPWL_Note_CloseBox::~CPWL_Note_CloseBox() {} 301 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 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 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 353 CPWL_Note_Contents::CPWL_Note_Contents() : m_pEdit(NULL) {} 354 355 CPWL_Note_Contents::~CPWL_Note_Contents() {} 356 357 CFX_ByteString CPWL_Note_Contents::GetClassName() const { 358 return "CPWL_Note_Contents"; 359 } 360 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 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 382 CFX_WideString CPWL_Note_Contents::GetText() const { 383 if (m_pEdit) 384 return m_pEdit->GetText(); 385 386 return L""; 387 } 388 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 412 int32_t CPWL_Note_Contents::CountSubItems() const { 413 return m_aChildren.GetSize() - 1; 414 } 415 416 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 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 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 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 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 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 546 CPWL_Edit* CPWL_Note_Contents::GetEdit() const { 547 return m_pEdit; 548 } 549 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 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 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 592 CPWL_NoteItem::~CPWL_NoteItem() {} 593 594 CFX_ByteString CPWL_NoteItem::GetClassName() const { 595 return "CPWL_NoteItem"; 596 } 597 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 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 670 void CPWL_NoteItem::SetPrivateData(void* pData) { 671 m_pPrivateData = pData; 672 } 673 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 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 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 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 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 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 766 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 777 IPWL_NoteItem* CPWL_NoteItem::GetParentItem() const { 778 return GetParentNoteItem(); 779 } 780 781 CPWL_Edit* CPWL_NoteItem::GetEdit() const { 782 if (m_pContents) 783 return m_pContents->GetEdit(); 784 return NULL; 785 } 786 787 void* CPWL_NoteItem::GetPrivateData() const { 788 return m_pPrivateData; 789 } 790 791 CFX_WideString CPWL_NoteItem::GetAuthorName() const { 792 return m_sAuthor; 793 } 794 795 CPWL_Color CPWL_NoteItem::GetBkColor() const { 796 return GetBackgroundColor(); 797 } 798 799 CFX_WideString CPWL_NoteItem::GetContents() const { 800 if (m_pContents) 801 return m_pContents->GetText(); 802 803 return L""; 804 } 805 806 FX_SYSTEMTIME CPWL_NoteItem::GetDateTime() const { 807 return m_dtNote; 808 } 809 810 CFX_WideString CPWL_NoteItem::GetSubjectName() const { 811 if (m_pSubject) 812 return m_pSubject->GetText(); 813 814 return L""; 815 } 816 817 CPWL_NoteItem* CPWL_NoteItem::CreateNoteItem() { 818 if (m_pContents) 819 return m_pContents->CreateSubItem(); 820 821 return NULL; 822 } 823 824 IPWL_NoteItem* CPWL_NoteItem::CreateSubItem() { 825 return CreateNoteItem(); 826 } 827 828 int32_t CPWL_NoteItem::CountSubItems() const { 829 if (m_pContents) 830 return m_pContents->CountSubItems(); 831 832 return 0; 833 } 834 835 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 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 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 868 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 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 904 FX_FLOAT CPWL_NoteItem::GetItemLeftMargin() { 905 return POPUP_ITEM_SIDEMARGIN; 906 } 907 908 FX_FLOAT CPWL_NoteItem::GetItemRightMargin() { 909 return POPUP_ITEM_SIDEMARGIN; 910 } 911 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 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 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 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 977 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 989 IPWL_NoteNotify* CPWL_NoteItem::GetNoteNotify() const { 990 if (const CPWL_Note* pNote = GetNote()) 991 return pNote->GetNoteNotify(); 992 993 return NULL; 994 } 995 996 void CPWL_NoteItem::OnCreateNoteItem() { 997 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { 998 pNotify->OnItemCreate(this); 999 } 1000 } 1001 1002 void CPWL_NoteItem::OnContentsValidate() { 1003 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { 1004 pNotify->OnSetContents(this); 1005 } 1006 } 1007 1008 void CPWL_NoteItem::SetNoteFocus(FX_BOOL bLast) { 1009 m_pContents->SetEditFocus(bLast); 1010 } 1011 1012 void CPWL_NoteItem::EnableModify(FX_BOOL bEnabled) { 1013 m_pContents->EnableModify(bEnabled); 1014 m_bAllowModify = bEnabled; 1015 } 1016 1017 void CPWL_NoteItem::EnableRead(FX_BOOL bEnabled) { 1018 m_pContents->EnableRead(bEnabled); 1019 } 1020 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 1035 CPWL_Note::~CPWL_Note() {} 1036 1037 IPWL_NoteItem* CPWL_Note::Reply() { 1038 return CreateNoteItem(); 1039 } 1040 1041 void CPWL_Note::EnableNotify(FX_BOOL bEnabled) { 1042 m_bEnableNotify = bEnabled; 1043 } 1044 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 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 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 1100 void CPWL_Note::SetOptionsText(const CFX_WideString& sText) { 1101 if (m_pOptions) 1102 m_pOptions->SetText(sText); 1103 1104 RePosNoteChildren(); 1105 } 1106 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 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 1276 void CPWL_Note::SetSubjectName(const CFX_WideString& sName) { 1277 CPWL_NoteItem::SetSubjectName(sName); 1278 RePosChildWnd(); 1279 } 1280 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 1292 CFX_WideString CPWL_Note::GetAuthorName() const { 1293 if (m_pAuthor) 1294 return m_pAuthor->GetText(); 1295 1296 return L""; 1297 } 1298 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 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 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 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 1478 FX_BOOL CPWL_Note::OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) { 1479 return CPWL_Wnd::OnRButtonUp(point, nFlag); 1480 } 1481 1482 const CPWL_Note* CPWL_Note::GetNote() const { 1483 return this; 1484 } 1485 1486 IPWL_NoteNotify* CPWL_Note::GetNoteNotify() const { 1487 return m_bEnableNotify ? m_pNoteNotify : nullptr; 1488 } 1489 1490 void CPWL_Note::SetIconType(int32_t nType) { 1491 if (m_pIcon) 1492 m_pIcon->SetIconType(nType); 1493 } 1494 1495 void CPWL_Note::EnableModify(FX_BOOL bEnabled) { 1496 m_pContents->EnableModify(bEnabled); 1497 } 1498 1499 void CPWL_Note::EnableRead(FX_BOOL bEnabled) { 1500 m_pContents->EnableRead(bEnabled); 1501 } 1502 1503 CFX_WideString CPWL_Note::GetReplyString() const { 1504 return m_sReplyString; 1505 } 1506 1507 void CPWL_Note::SetReplyString(const CFX_WideString& string) { 1508 m_sReplyString = string; 1509 } 1510