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 36 CPWL_Note_Options::CPWL_Note_Options() : m_pText(NULL) 37 { 38 } 39 40 CPWL_Note_Options::~CPWL_Note_Options() 41 { 42 } 43 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 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 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 83 void CPWL_Note_Options::SetText(const CFX_WideString& sText) 84 { 85 m_pText->SetText(sText); 86 } 87 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 114 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 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 133 CPWL_Note_Edit::~CPWL_Note_Edit() 134 { 135 } 136 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 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 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 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 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 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 265 FX_FLOAT CPWL_Note_Edit::GetItemLeftMargin() 266 { 267 return POPUP_ITEM_TEXT_INDENT; 268 } 269 270 FX_FLOAT CPWL_Note_Edit::GetItemRightMargin() 271 { 272 return POPUP_ITEM_TEXT_INDENT; 273 } 274 275 /* -------------------------------- CPWL_Note_LBBox --------------------------------*/ 276 277 CPWL_Note_LBBox::CPWL_Note_LBBox() 278 { 279 } 280 281 CPWL_Note_LBBox::~CPWL_Note_LBBox() 282 { 283 } 284 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 306 CPWL_Note_RBBox::CPWL_Note_RBBox() 307 { 308 } 309 310 CPWL_Note_RBBox::~CPWL_Note_RBBox() 311 { 312 } 313 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 335 CPWL_Note_Icon::CPWL_Note_Icon() : m_nType(0) 336 { 337 } 338 339 CPWL_Note_Icon::~CPWL_Note_Icon() 340 { 341 } 342 343 void CPWL_Note_Icon::SetIconType(FX_INT32 nType) 344 { 345 m_nType = nType; 346 } 347 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 356 CPWL_Note_CloseBox::CPWL_Note_CloseBox() : m_bMouseDown(FALSE) 357 { 358 } 359 360 CPWL_Note_CloseBox::~CPWL_Note_CloseBox() 361 { 362 } 363 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 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 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 416 CPWL_Note_Contents::CPWL_Note_Contents() : m_pEdit(NULL) 417 { 418 } 419 420 CPWL_Note_Contents::~CPWL_Note_Contents() 421 { 422 } 423 424 CFX_ByteString CPWL_Note_Contents::GetClassName() const 425 { 426 return "CPWL_Note_Contents"; 427 } 428 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 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); 447 m_pEdit->EnableNotify(TRUE); 448 OnNotify(m_pEdit, PNM_NOTEEDITCHANGED, 0, 0); 449 } 450 } 451 452 CFX_WideString CPWL_Note_Contents::GetText() const 453 { 454 if (m_pEdit) 455 return m_pEdit->GetText(); 456 457 return L""; 458 } 459 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 484 FX_INT32 CPWL_Note_Contents::CountSubItems() const 485 { 486 return m_aChildren.GetSize() - 1; 487 } 488 489 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 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 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 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 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 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 636 CPWL_Edit* CPWL_Note_Contents::GetEdit() const 637 { 638 return m_pEdit; 639 } 640 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 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 683 CPWL_NoteItem::CPWL_NoteItem() : 684 m_pPrivateData(NULL), 685 m_pSubject(NULL), 686 m_pDateTime(NULL), 687 m_pContents(NULL), 688 m_sAuthor(L""), 689 m_fOldItemHeight(0.0f), 690 m_bSizeChanged(FALSE), 691 m_bAllowModify(TRUE) 692 { 693 } 694 695 CPWL_NoteItem::~CPWL_NoteItem() 696 { 697 } 698 699 CFX_ByteString CPWL_NoteItem::GetClassName() const 700 { 701 return "CPWL_NoteItem"; 702 } 703 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 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 779 void CPWL_NoteItem::SetPrivateData(void* pData) 780 { 781 m_pPrivateData = pData; 782 } 783 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 810 void CPWL_NoteItem::SetSubjectName(const CFX_WideString& sName) 811 { 812 if (m_pSubject) 813 { 814 m_pSubject->SetText(sName); 815 } 816 817 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) 818 { 819 pNotify->OnSetSubjectName(this); 820 } 821 } 822 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 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(), nItemIndex); 852 853 if (!m_sAuthor.IsEmpty()) 854 { 855 856 sSubject += L" - "; 857 sSubject += m_sAuthor; 858 } 859 this->SetSubjectName(sSubject); 860 this->RePosChildWnd(); 861 } 862 863 void CPWL_NoteItem::SetDateTime(FX_SYSTEMTIME time) 864 { 865 m_dtNote = time; 866 867 CFX_WideString swTime; 868 swTime.Format((FX_LPCWSTR)L"%04d-%02d-%02d %02d:%02d:%02d", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond); 869 if (m_pDateTime) 870 { 871 m_pDateTime->SetText(swTime); 872 } 873 874 this->RePosChildWnd(); 875 876 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) 877 { 878 pNotify->OnSetDateTime(this); 879 } 880 } 881 882 void CPWL_NoteItem::SetContents(const CFX_WideString& sContents) 883 { 884 if (m_pContents) 885 { 886 m_pContents->SetText(sContents); 887 } 888 889 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) 890 { 891 pNotify->OnSetContents(this); 892 } 893 } 894 895 CPWL_NoteItem* CPWL_NoteItem::GetParentNoteItem() const 896 { 897 if (CPWL_Wnd* pParent = this->GetParentWindow()) 898 { 899 if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) 900 { 901 ASSERT(pGrand->GetClassName() == "CPWL_NoteItem"); 902 return (CPWL_NoteItem*)pGrand; 903 } 904 } 905 906 return NULL; 907 } 908 909 IPWL_NoteItem* CPWL_NoteItem::GetParentItem() const 910 { 911 return GetParentNoteItem(); 912 } 913 914 CPWL_Edit* CPWL_NoteItem::GetEdit() const 915 { 916 if (m_pContents) 917 return m_pContents->GetEdit(); 918 return NULL; 919 } 920 921 void* CPWL_NoteItem::GetPrivateData() const 922 { 923 return m_pPrivateData; 924 } 925 926 CFX_WideString CPWL_NoteItem::GetAuthorName() const 927 { 928 return m_sAuthor; 929 } 930 931 CPWL_Color CPWL_NoteItem::GetBkColor() const 932 { 933 return this->GetBackgroundColor(); 934 } 935 936 CFX_WideString CPWL_NoteItem::GetContents() const 937 { 938 if (m_pContents) 939 return m_pContents->GetText(); 940 941 return L""; 942 } 943 944 FX_SYSTEMTIME CPWL_NoteItem::GetDateTime() const 945 { 946 return m_dtNote; 947 } 948 949 CFX_WideString CPWL_NoteItem::GetSubjectName() const 950 { 951 if (m_pSubject) 952 return m_pSubject->GetText(); 953 954 return L""; 955 } 956 957 CPWL_NoteItem* CPWL_NoteItem::CreateNoteItem() 958 { 959 if (m_pContents) 960 return m_pContents->CreateSubItem(); 961 962 return NULL; 963 } 964 965 IPWL_NoteItem* CPWL_NoteItem::CreateSubItem() 966 { 967 return CreateNoteItem(); 968 } 969 970 FX_INT32 CPWL_NoteItem::CountSubItems() const 971 { 972 if (m_pContents) 973 return m_pContents->CountSubItems(); 974 975 return 0; 976 } 977 978 IPWL_NoteItem* CPWL_NoteItem::GetSubItems(FX_INT32 index) const 979 { 980 if (m_pContents) 981 return m_pContents->GetSubItems(index); 982 983 return NULL; 984 } 985 986 void CPWL_NoteItem::DeleteSubItem(IPWL_NoteItem* pNoteItem) 987 { 988 this->KillFocus(); 989 990 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) 991 { 992 pNotify->OnItemDelete(pNoteItem); 993 } 994 995 if (m_pContents) 996 m_pContents->DeleteSubItem(pNoteItem); 997 } 998 999 IPWL_NoteItem* CPWL_NoteItem::GetHitNoteItem(const CPDF_Point& point) 1000 { 1001 CPDF_Point pt = this->ParentToChild(point); 1002 1003 if (this->WndHitTest(pt)) 1004 { 1005 if (m_pContents) 1006 { 1007 if (IPWL_NoteItem* pNoteItem = m_pContents->GetHitNoteItem(pt)) 1008 return pNoteItem; 1009 } 1010 1011 return this; 1012 } 1013 1014 return NULL; 1015 } 1016 1017 IPWL_NoteItem* CPWL_NoteItem::GetFocusedNoteItem() const 1018 { 1019 if (const CPWL_Wnd* pWnd = this->GetFocused()) 1020 { 1021 if (pWnd->GetClassName() == "CPWL_Edit") 1022 { 1023 if (CPWL_Wnd* pParent = pWnd->GetParentWindow()) 1024 { 1025 ASSERT(pParent->GetClassName() == "CPWL_Note_Contents"); 1026 1027 if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) 1028 { 1029 ASSERT(pGrand->GetClassName() == "CPWL_NoteItem"); 1030 return (CPWL_NoteItem*)pGrand; 1031 } 1032 } 1033 } 1034 } 1035 1036 return NULL; 1037 } 1038 1039 FX_FLOAT CPWL_NoteItem::GetItemHeight(FX_FLOAT fLimitWidth) 1040 { 1041 if (fLimitWidth > 0) 1042 { 1043 if (!m_bSizeChanged) 1044 return m_fOldItemHeight; 1045 1046 m_bSizeChanged = FALSE; 1047 1048 ASSERT(m_pSubject != NULL); 1049 ASSERT(m_pDateTime != NULL); 1050 ASSERT(m_pContents != NULL); 1051 1052 FX_FLOAT fRet = m_pDateTime->GetContentRect().Height(); 1053 FX_FLOAT fBorderWidth = (FX_FLOAT)this->GetBorderWidth(); 1054 if (fLimitWidth > fBorderWidth * 2) 1055 fRet += m_pContents->GetContentsHeight(fLimitWidth - fBorderWidth * 2); 1056 fRet += POPUP_ITEM_HEAD_BOTTOM + POPUP_ITEM_BOTTOMWIDTH + fBorderWidth * 2; 1057 1058 return m_fOldItemHeight = fRet; 1059 } 1060 1061 return 0; 1062 } 1063 1064 FX_FLOAT CPWL_NoteItem::GetItemLeftMargin() 1065 { 1066 return POPUP_ITEM_SIDEMARGIN; 1067 } 1068 1069 FX_FLOAT CPWL_NoteItem::GetItemRightMargin() 1070 { 1071 return POPUP_ITEM_SIDEMARGIN; 1072 } 1073 1074 FX_BOOL CPWL_NoteItem::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) 1075 { 1076 if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) 1077 { 1078 SetNoteFocus(FALSE); 1079 } 1080 1081 CPWL_Wnd::OnLButtonDown(point,nFlag); 1082 1083 return TRUE; 1084 } 1085 1086 FX_BOOL CPWL_NoteItem::OnRButtonUp(const CPDF_Point & point, FX_DWORD nFlag) 1087 { 1088 if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) 1089 { 1090 SetNoteFocus(FALSE); 1091 PopupNoteItemMenu(point); 1092 1093 return TRUE; 1094 } 1095 1096 return CPWL_Wnd::OnRButtonUp(point,nFlag); 1097 } 1098 1099 void CPWL_NoteItem::OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam, FX_INTPTR lParam) 1100 { 1101 switch (msg) 1102 { 1103 case PNM_NOTEEDITCHANGED: 1104 m_bSizeChanged = TRUE; 1105 1106 if (CPWL_Wnd* pParent = this->GetParentWindow()) 1107 { 1108 pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0); 1109 } 1110 return; 1111 case PNM_SETCARETINFO: 1112 if (PWL_CARET_INFO * pInfo = (PWL_CARET_INFO*)wParam) 1113 { 1114 PWL_CARET_INFO newInfo = *pInfo; 1115 newInfo.bVisible = TRUE; 1116 newInfo.ptHead = this->ChildToParent(pInfo->ptHead); 1117 newInfo.ptFoot = this->ChildToParent(pInfo->ptFoot); 1118 1119 if (CPWL_Wnd * pParent = this->GetParentWindow()) 1120 { 1121 pParent->OnNotify(this, PNM_SETCARETINFO, (FX_INTPTR)&newInfo, 0); 1122 } 1123 } 1124 return; 1125 case PNM_NOTERESET: 1126 m_bSizeChanged = TRUE; 1127 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); 1128 1129 return; 1130 } 1131 1132 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam); 1133 } 1134 1135 void CPWL_NoteItem::PopupNoteItemMenu(const CPDF_Point& point) 1136 { 1137 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) 1138 { 1139 FX_INT32 x,y; 1140 PWLtoWnd(point, x, y); 1141 if (IFX_SystemHandler* pSH = GetSystemHandler()) 1142 pSH->ClientToScreen(GetAttachedHWnd(), x, y); 1143 pNotify->OnPopupMenu(this, x, y); 1144 } 1145 } 1146 1147 const CPWL_Note* CPWL_NoteItem::GetNote() const 1148 { 1149 if (const CPWL_Wnd* pRoot = this->GetRootWnd()) 1150 { 1151 ASSERT(pRoot->GetClassName() == "CPWL_NoteItem"); 1152 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pRoot; 1153 if (pNoteItem->IsTopItem()) 1154 { 1155 return (CPWL_Note*)pNoteItem; 1156 } 1157 } 1158 1159 return NULL; 1160 } 1161 1162 IPWL_NoteNotify* CPWL_NoteItem::GetNoteNotify() const 1163 { 1164 if (const CPWL_Note* pNote = GetNote()) 1165 return pNote->GetNoteNotify(); 1166 1167 return NULL; 1168 } 1169 1170 void CPWL_NoteItem::OnCreateNoteItem() 1171 { 1172 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) 1173 { 1174 pNotify->OnItemCreate(this); 1175 } 1176 } 1177 1178 void CPWL_NoteItem::OnContentsValidate() 1179 { 1180 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) 1181 { 1182 pNotify->OnSetContents(this); 1183 } 1184 } 1185 1186 void CPWL_NoteItem::SetNoteFocus(FX_BOOL bLast) 1187 { 1188 m_pContents->SetEditFocus(bLast); 1189 } 1190 1191 void CPWL_NoteItem::EnableModify(FX_BOOL bEnabled) 1192 { 1193 m_pContents->EnableModify(bEnabled); 1194 m_bAllowModify = bEnabled; 1195 } 1196 1197 void CPWL_NoteItem::EnableRead(FX_BOOL bEnabled) 1198 { 1199 m_pContents->EnableRead(bEnabled); 1200 } 1201 1202 /* ---------------------------------- CPWL_Note ---------------------------------- */ 1203 1204 CPWL_Note::CPWL_Note(IPopup_Note* pPopupNote, IPWL_NoteNotify* pNoteNotify, IPWL_NoteHandler* pNoteHandler) : 1205 m_pAuthor(NULL), 1206 m_pIcon(NULL), 1207 m_pCloseBox(NULL), 1208 m_pContentsBar(NULL), 1209 m_pLBBox(NULL), 1210 m_pRBBox(NULL), 1211 m_pOptions(NULL), 1212 m_bResizing(FALSE), 1213 m_rcCaption(0,0,0,0), 1214 m_pNoteNotify(pNoteNotify), 1215 m_bEnalbleNotify(TRUE), 1216 m_pPopupNote(pPopupNote), 1217 m_pNoteHandler(pNoteHandler) 1218 { 1219 } 1220 1221 CPWL_Note::~CPWL_Note() 1222 { 1223 } 1224 1225 IPWL_NoteItem* CPWL_Note::Reply() 1226 { 1227 return CreateNoteItem(); 1228 } 1229 1230 void CPWL_Note::EnableNotify(FX_BOOL bEnabled) 1231 { 1232 m_bEnalbleNotify = bEnabled; 1233 } 1234 1235 void CPWL_Note::RePosChildWnd() 1236 { 1237 RePosNoteChildren(); 1238 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); 1239 ResetScrollBar(); 1240 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); 1241 this->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0); 1242 // 1243 if (const CPWL_Wnd* pWnd = this->GetFocused()) 1244 { 1245 if (pWnd->GetClassName() == "CPWL_Edit") 1246 { 1247 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd; 1248 pEdit->SetCaret(pEdit->GetCaret()); 1249 } 1250 } 1251 //CPDF_Point ptNew = m_pContents->GetScrollPos(); 1252 //m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, (FX_INTPTR)&ptNew.y); 1253 } 1254 1255 FX_BOOL CPWL_Note::ResetScrollBar() 1256 { 1257 FX_BOOL bScrollChanged = FALSE; 1258 1259 if (ScrollBarShouldVisible()) 1260 { 1261 if (!m_pContentsBar->IsVisible()) 1262 { 1263 m_pContentsBar->SetVisible(TRUE); 1264 if (m_pContentsBar->IsVisible()) 1265 { 1266 m_pContentsBar->InvalidateRect(NULL); 1267 bScrollChanged = TRUE; 1268 } 1269 } 1270 } 1271 else 1272 { 1273 if (m_pContentsBar->IsVisible()) 1274 { 1275 m_pContentsBar->SetVisible(FALSE); 1276 m_pContentsBar->InvalidateRect(NULL); 1277 1278 bScrollChanged = TRUE; 1279 } 1280 } 1281 1282 if (bScrollChanged) 1283 { 1284 CPDF_Rect rcNote = this->GetClientRect(); 1285 CPDF_Rect rcContents = m_pContents->GetWindowRect(); 1286 rcContents.right = rcNote.right - 3.0f; 1287 if (m_pContentsBar->IsVisible()) 1288 rcContents.right -= PWL_SCROLLBAR_WIDTH; 1289 m_pContents->Move(rcContents, TRUE, TRUE); 1290 m_pContents->SetScrollPos(CPDF_Point(0.0f,0.0f)); 1291 m_pContents->InvalidateRect(NULL); 1292 } 1293 1294 return bScrollChanged; 1295 } 1296 1297 FX_BOOL CPWL_Note::ScrollBarShouldVisible() 1298 { 1299 CPDF_Rect rcContentsFact = m_pContents->GetScrollArea(); 1300 CPDF_Rect rcContentsClient = m_pContents->GetClientRect(); 1301 1302 return rcContentsFact.Height() > rcContentsClient.Height(); 1303 } 1304 1305 void CPWL_Note::SetOptionsText(const CFX_WideString& sText) 1306 { 1307 if (m_pOptions) 1308 m_pOptions->SetText(sText); 1309 1310 RePosNoteChildren(); 1311 } 1312 1313 void CPWL_Note::RePosNoteChildren() 1314 { 1315 if (m_bResizing) return; 1316 1317 m_bResizing = TRUE; 1318 1319 if (this->IsValid()) 1320 { 1321 ASSERT(m_pSubject != NULL); 1322 ASSERT(m_pDateTime != NULL); 1323 ASSERT(m_pContents != NULL); 1324 ASSERT(m_pAuthor != NULL); 1325 ASSERT(m_pCloseBox != NULL); 1326 ASSERT(m_pIcon != NULL); 1327 ASSERT(m_pLBBox != NULL); 1328 ASSERT(m_pRBBox != NULL); 1329 ASSERT(m_pContentsBar != NULL); 1330 ASSERT(m_pOptions != NULL); 1331 1332 CPDF_Rect rcClient = GetClientRect(); 1333 1334 CPDF_Rect rcIcon = rcClient; 1335 rcIcon.top -= 2.0f; 1336 rcIcon.right = rcIcon.left + 14.0f; 1337 rcIcon.bottom = rcIcon.top - 14.0f; 1338 rcIcon.Normalize(); 1339 m_pIcon->Move(rcIcon, TRUE, FALSE); 1340 m_pIcon->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcIcon)); 1341 1342 CPDF_Rect rcCloseBox = rcClient; 1343 rcCloseBox.right -= 1.0f; 1344 rcCloseBox.top -= 1.0f; 1345 rcCloseBox.left = rcCloseBox.right - 14.0f; 1346 rcCloseBox.bottom = rcCloseBox.top - 14.0f; 1347 rcCloseBox.Normalize(); 1348 m_pCloseBox->Move(rcCloseBox, TRUE, FALSE); 1349 m_pCloseBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcCloseBox)); 1350 1351 CPDF_Rect rcDate = rcClient; 1352 rcDate.right = rcCloseBox.left - POPUP_ITEM_TEXT_INDENT; 1353 rcDate.left = PWL_MAX(rcDate.right - m_pDateTime->GetContentRect().Width() - 1.0f, rcIcon.right + 1.0f); 1354 rcDate.top = rcClient.top - 2.0f; 1355 rcDate.bottom = rcDate.top - m_pDateTime->GetContentRect().Height(); 1356 rcDate.Normalize(); 1357 m_pDateTime->Move(rcDate, TRUE, FALSE); 1358 m_pDateTime->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcDate)); 1359 1360 CPDF_Rect rcSubject = rcClient; 1361 rcSubject.top = rcClient.top - 2.0f; 1362 rcSubject.left = rcIcon.right + POPUP_ITEM_TEXT_INDENT; 1363 rcSubject.right = PWL_MIN(rcSubject.left + m_pSubject->GetContentRect().Width() + 1.0f, rcDate.left - 1.0f); 1364 rcSubject.bottom = rcSubject.top - m_pSubject->GetContentRect().Height(); 1365 rcSubject.Normalize(); 1366 m_pSubject->Move(rcSubject, TRUE, FALSE); 1367 m_pSubject->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcSubject)); 1368 1369 CPDF_Rect rcOptions = rcClient; 1370 rcOptions.left = PWL_MAX(rcOptions.right - m_pOptions->GetContentRect().Width(), rcIcon.right + 1.0f); 1371 rcOptions.top = rcSubject.bottom - 4.0f; 1372 rcOptions.bottom = rcOptions.top - m_pOptions->GetContentRect().Height(); 1373 rcOptions.Normalize(); 1374 m_pOptions->Move(rcOptions, TRUE, FALSE); 1375 m_pOptions->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcOptions)); 1376 1377 CPDF_Rect rcAuthor = rcClient; 1378 rcAuthor.top = rcSubject.bottom - 4.0f; 1379 rcAuthor.left = rcSubject.left; 1380 rcAuthor.right = PWL_MIN(rcSubject.left + m_pAuthor->GetContentRect().Width() + 1.0f, rcOptions.left - 1.0f); 1381 rcAuthor.bottom = rcAuthor.top - m_pAuthor->GetContentRect().Height(); 1382 rcAuthor.Normalize(); 1383 m_pAuthor->Move(rcAuthor, TRUE, FALSE); 1384 m_pAuthor->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcAuthor)); 1385 1386 CPDF_Rect rcLBBox = rcClient; 1387 rcLBBox.top = rcLBBox.bottom + 7.0f; 1388 rcLBBox.right = rcLBBox.left + 7.0f; 1389 rcLBBox.Normalize(); 1390 m_pLBBox->Move(rcLBBox, TRUE, FALSE); 1391 m_pLBBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcLBBox)); 1392 1393 CPDF_Rect rcRBBox = rcClient; 1394 rcRBBox.top = rcRBBox.bottom + 7.0f; 1395 rcRBBox.left = rcRBBox.right - 7.0f; 1396 rcRBBox.Normalize(); 1397 m_pRBBox->Move(rcRBBox, TRUE, FALSE); 1398 m_pRBBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcRBBox)); 1399 1400 CPDF_Rect rcContents = rcClient; 1401 rcContents.top = rcAuthor.bottom - POPUP_ITEM_HEAD_BOTTOM; 1402 rcContents.left += 3.0f; 1403 rcContents.right -= 3.0f; 1404 if (m_pContentsBar->IsVisible()) 1405 rcContents.right -= PWL_SCROLLBAR_WIDTH; 1406 rcContents.bottom += 14.0f; 1407 rcContents.Normalize(); 1408 m_pContents->Move(rcContents, FALSE, FALSE); 1409 m_pContents->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcContents)); 1410 1411 CPDF_Rect rcContentsBar = rcContents; 1412 rcContentsBar.right = rcClient.right - 3.0f; 1413 rcContentsBar.left = rcContentsBar.right - PWL_SCROLLBAR_WIDTH; 1414 rcContentsBar.Normalize(); 1415 m_pContentsBar->Move(rcContentsBar, TRUE, FALSE); 1416 1417 m_rcCaption = rcClient; 1418 m_rcCaption.bottom = rcContents.top; 1419 } 1420 1421 m_bResizing = FALSE; 1422 } 1423 1424 //0-normal / 1-caption / 2-leftbottom corner / 3-rightbottom corner / 4-close / 5-options 1425 FX_INT32 CPWL_Note::NoteHitTest(const CPDF_Point& point) const 1426 { 1427 ASSERT(m_pSubject != NULL); 1428 ASSERT(m_pDateTime != NULL); 1429 ASSERT(m_pContents != NULL); 1430 ASSERT(m_pAuthor != NULL); 1431 ASSERT(m_pIcon != NULL); 1432 ASSERT(m_pContentsBar != NULL); 1433 1434 ASSERT(m_pCloseBox != NULL); 1435 ASSERT(m_pLBBox != NULL); 1436 ASSERT(m_pRBBox != NULL); 1437 ASSERT(m_pOptions != NULL); 1438 1439 GetClientRect(); 1440 1441 if (m_pSubject->WndHitTest(m_pSubject->ParentToChild(point))) return 1; 1442 if (m_pDateTime->WndHitTest(m_pDateTime->ParentToChild(point))) return 1; 1443 if (m_pAuthor->WndHitTest(m_pAuthor->ParentToChild(point))) return 1; 1444 if (m_pIcon->WndHitTest(m_pIcon->ParentToChild(point))) return 1; 1445 1446 if (m_pContents->WndHitTest(m_pContents->ParentToChild(point))) return 0; 1447 if (m_pContentsBar->WndHitTest(m_pContentsBar->ParentToChild(point))) return 0; 1448 1449 if (m_pCloseBox->WndHitTest(m_pCloseBox->ParentToChild(point))) return 4; 1450 if (m_pLBBox->WndHitTest(m_pLBBox->ParentToChild(point))) return 2; 1451 if (m_pRBBox->WndHitTest(m_pRBBox->ParentToChild(point))) return 3; 1452 if (m_pOptions->WndHitTest(m_pOptions->ParentToChild(point))) return 5; 1453 1454 return 1; 1455 } 1456 1457 void CPWL_Note::CreateChildWnd(const PWL_CREATEPARAM & cp) 1458 { 1459 CPWL_NoteItem::CreateChildWnd(cp); 1460 1461 CPWL_Color sTextColor; 1462 1463 if (CPWL_Utils::IsBlackOrWhite(this->GetBackgroundColor())) 1464 sTextColor = PWL_DEFAULT_WHITECOLOR; 1465 else 1466 sTextColor = PWL_DEFAULT_BLACKCOLOR; 1467 1468 m_pAuthor = new CPWL_Label; 1469 PWL_CREATEPARAM acp = cp; 1470 acp.pParentWnd = this; 1471 acp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_LEFT | PES_TOP; 1472 acp.sTextColor = sTextColor; 1473 m_pAuthor->Create(acp); 1474 1475 m_pCloseBox = new CPWL_Note_CloseBox; 1476 PWL_CREATEPARAM ccp = cp; 1477 ccp.pParentWnd = this; 1478 ccp.dwBorderWidth = 2; 1479 ccp.nBorderStyle = PBS_BEVELED; 1480 ccp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER; 1481 ccp.sTextColor = sTextColor; 1482 m_pCloseBox->Create(ccp); 1483 1484 m_pIcon = new CPWL_Note_Icon; 1485 PWL_CREATEPARAM icp = cp; 1486 icp.pParentWnd = this; 1487 icp.dwFlags = PWS_VISIBLE | PWS_CHILD; 1488 m_pIcon->Create(icp); 1489 1490 m_pOptions = new CPWL_Note_Options; 1491 PWL_CREATEPARAM ocp = cp; 1492 ocp.pParentWnd = this; 1493 ocp.dwFlags = PWS_CHILD | PWS_VISIBLE; 1494 ocp.sTextColor = sTextColor; 1495 m_pOptions->Create(ocp); 1496 1497 m_pLBBox = new CPWL_Note_LBBox; 1498 PWL_CREATEPARAM lcp = cp; 1499 lcp.pParentWnd = this; 1500 lcp.dwFlags = PWS_VISIBLE | PWS_CHILD; 1501 lcp.eCursorType = FXCT_NESW; 1502 lcp.sTextColor = sTextColor; 1503 m_pLBBox->Create(lcp); 1504 1505 m_pRBBox = new CPWL_Note_RBBox; 1506 PWL_CREATEPARAM rcp = cp; 1507 rcp.pParentWnd = this; 1508 rcp.dwFlags = PWS_VISIBLE | PWS_CHILD; 1509 rcp.eCursorType = FXCT_NWSE; 1510 rcp.sTextColor = sTextColor; 1511 m_pRBBox->Create(rcp); 1512 1513 m_pContentsBar = new CPWL_ScrollBar(SBT_VSCROLL); 1514 PWL_CREATEPARAM scp = cp; 1515 scp.pParentWnd = this; 1516 scp.sBackgroundColor = CPWL_Color(COLORTYPE_RGB, 240/255.0f, 240/255.0f, 240/255.0f); 1517 scp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_BACKGROUND; 1518 m_pContentsBar->Create(scp); 1519 m_pContentsBar->SetNotifyForever(TRUE); 1520 } 1521 1522 void CPWL_Note::SetSubjectName(const CFX_WideString& sName) 1523 { 1524 CPWL_NoteItem::SetSubjectName(sName); 1525 RePosChildWnd(); 1526 } 1527 1528 void CPWL_Note::SetAuthorName(const CFX_WideString& sName) 1529 { 1530 if (m_pAuthor) 1531 { 1532 m_pAuthor->SetText(sName); 1533 RePosChildWnd(); 1534 } 1535 1536 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) 1537 { 1538 pNotify->OnSetAuthorName(this); 1539 } 1540 } 1541 1542 CFX_WideString CPWL_Note::GetAuthorName() const 1543 { 1544 if (m_pAuthor) 1545 return m_pAuthor->GetText(); 1546 1547 return L""; 1548 } 1549 1550 FX_BOOL CPWL_Note::OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag) 1551 { 1552 CPDF_Point ptScroll = m_pContents->GetScrollPos(); 1553 CPDF_Rect rcScroll = m_pContents->GetScrollArea(); 1554 CPDF_Rect rcContents = m_pContents->GetClientRect(); 1555 1556 if (rcScroll.top - rcScroll.bottom > rcContents.Height()) 1557 { 1558 CPDF_Point ptNew = ptScroll; 1559 1560 if (zDelta > 0) 1561 ptNew.y += 30; 1562 else 1563 ptNew.y -= 30; 1564 1565 if (ptNew.y > rcScroll.top) 1566 ptNew.y = rcScroll.top; 1567 if (ptNew.y < rcScroll.bottom + rcContents.Height()) 1568 ptNew.y = rcScroll.bottom + rcContents.Height(); 1569 if (ptNew.y < rcScroll.bottom) 1570 ptNew.y = rcScroll.bottom; 1571 1572 if (ptNew.y != ptScroll.y) 1573 { 1574 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); 1575 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL, (FX_INTPTR)&ptNew.y); 1576 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, (FX_INTPTR)&ptNew.y); 1577 1578 return TRUE; 1579 } 1580 } 1581 1582 return FALSE; 1583 } 1584 1585 void CPWL_Note::OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam, FX_INTPTR lParam) 1586 { 1587 switch (msg) 1588 { 1589 case PNM_NOTEEDITCHANGED: 1590 { 1591 CPDF_Rect rcScroll = m_pContents->GetScrollArea(); 1592 1593 1594 PWL_SCROLL_INFO sInfo; 1595 sInfo.fContentMin = rcScroll.bottom; 1596 sInfo.fContentMax = rcScroll.top; 1597 sInfo.fPlateWidth = m_pContents->GetClientRect().Height(); 1598 sInfo.fSmallStep = 13.0f; 1599 sInfo.fBigStep = sInfo.fPlateWidth; 1600 1601 if (FXSYS_memcmp(&m_OldScrollInfo, &sInfo, sizeof(PWL_SCROLL_INFO)) != 0) 1602 { 1603 FX_BOOL bScrollChanged = FALSE; 1604 1605 if (lParam < 3) // mantis:15759 1606 { 1607 bScrollChanged = ResetScrollBar(); 1608 if (bScrollChanged) 1609 { 1610 lParam++; 1611 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); 1612 this->OnNotify(this, PNM_NOTEEDITCHANGED, 0, lParam); 1613 } 1614 } 1615 1616 if (!bScrollChanged) 1617 { 1618 if (m_pContentsBar->IsVisible()) 1619 { 1620 m_pContentsBar->OnNotify(pWnd, PNM_SETSCROLLINFO, SBT_VSCROLL, (FX_INTPTR)&sInfo); 1621 m_OldScrollInfo = sInfo; 1622 1623 CPDF_Point ptScroll = m_pContents->GetScrollPos(); 1624 CPDF_Point ptOld = ptScroll; 1625 1626 if (ptScroll.y > sInfo.fContentMax) 1627 ptScroll.y = sInfo.fContentMax; 1628 if (ptScroll.y < sInfo.fContentMin + sInfo.fPlateWidth) 1629 ptScroll.y = sInfo.fContentMin + sInfo.fPlateWidth; 1630 if (ptScroll.y < sInfo.fContentMin) 1631 ptScroll.y = sInfo.fContentMin; 1632 1633 if (ptOld.y != ptScroll.y) 1634 { 1635 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, (FX_INTPTR)&ptScroll.y); 1636 m_pContentsBar->InvalidateRect(NULL); 1637 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL, (FX_INTPTR)&ptScroll.y); 1638 } 1639 } 1640 } 1641 } 1642 } 1643 1644 m_pContents->InvalidateRect(NULL); 1645 1646 return; 1647 case PNM_SCROLLWINDOW: 1648 if (m_pContents) 1649 m_pContents->OnNotify(pWnd, msg, wParam, lParam); 1650 return; 1651 case PNM_SETSCROLLPOS: 1652 if (m_pContentsBar) 1653 m_pContentsBar->OnNotify(pWnd,PNM_SETSCROLLPOS,wParam,lParam); 1654 return; 1655 } 1656 1657 if (msg == PNM_SETCARETINFO && IsValid()) 1658 { 1659 if (PWL_CARET_INFO * pInfo = (PWL_CARET_INFO*)wParam) 1660 { 1661 if (m_pContents) 1662 { 1663 CPDF_Rect rcClient = m_pContents->GetClientRect(); 1664 if (pInfo->ptHead.y > rcClient.top) 1665 { 1666 CPDF_Point pt = m_pContents->OutToIn(pInfo->ptHead); 1667 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL, (FX_INTPTR)&pt.y); 1668 1669 CPDF_Point ptScroll = m_pContents->GetScrollPos(); 1670 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, (FX_INTPTR)&ptScroll.y); 1671 1672 return; 1673 } 1674 1675 if (pInfo->ptFoot.y < rcClient.bottom) 1676 { 1677 CPDF_Point pt = m_pContents->OutToIn(pInfo->ptFoot); 1678 pt.y += rcClient.Height(); 1679 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL, (FX_INTPTR)&pt.y); 1680 1681 CPDF_Point ptScroll = m_pContents->GetScrollPos(); 1682 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, (FX_INTPTR)&ptScroll.y); 1683 1684 return; 1685 } 1686 } 1687 } 1688 } 1689 1690 CPWL_NoteItem::OnNotify(pWnd, msg, wParam, lParam); 1691 } 1692 1693 void CPWL_Note::SetBkColor(const CPWL_Color& color) 1694 { 1695 CPWL_NoteItem::SetBkColor(color); 1696 1697 CPWL_Color sBK = color; 1698 CPWL_Color sTextColor; 1699 if (CPWL_Utils::IsBlackOrWhite(sBK)) 1700 sTextColor = PWL_DEFAULT_WHITECOLOR; 1701 else 1702 sTextColor = PWL_DEFAULT_BLACKCOLOR; 1703 1704 if (m_pCloseBox) 1705 m_pCloseBox->SetTextColor(sTextColor); 1706 if (m_pAuthor) 1707 m_pAuthor->SetTextColor(sTextColor); 1708 if (m_pOptions) 1709 m_pOptions->SetTextColor(sTextColor); 1710 if (m_pLBBox) 1711 m_pLBBox->SetTextColor(sTextColor); 1712 if (m_pRBBox) 1713 m_pRBBox->SetTextColor(sTextColor); 1714 } 1715 1716 FX_BOOL CPWL_Note::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) 1717 { 1718 if (m_pOptions->WndHitTest(m_pOptions->ParentToChild(point))) 1719 { 1720 if (IPWL_NoteNotify* pNotify = this->GetNoteNotify()) 1721 { 1722 FX_INT32 x, y; 1723 PWLtoWnd(point, x, y); 1724 if (IFX_SystemHandler* pSH = GetSystemHandler()) 1725 pSH->ClientToScreen(GetAttachedHWnd(), x, y); 1726 this->KillFocus(); 1727 pNotify->OnPopupMenu(x, y); 1728 1729 return TRUE; 1730 } 1731 } 1732 1733 return CPWL_Wnd::OnLButtonDown(point,nFlag); 1734 } 1735 1736 FX_BOOL CPWL_Note::OnRButtonUp(const CPDF_Point & point, FX_DWORD nFlag) 1737 { 1738 return CPWL_Wnd::OnRButtonUp(point,nFlag); 1739 } 1740 1741 const CPWL_Note* CPWL_Note::GetNote() const 1742 { 1743 return this; 1744 } 1745 1746 IPWL_NoteNotify* CPWL_Note::GetNoteNotify() const 1747 { 1748 if (m_bEnalbleNotify) 1749 return m_pNoteNotify; 1750 1751 return NULL; 1752 } 1753 1754 void CPWL_Note::SetIconType(FX_INT32 nType) 1755 { 1756 if (m_pIcon) 1757 m_pIcon->SetIconType(nType); 1758 } 1759 1760 void CPWL_Note::EnableModify(FX_BOOL bEnabled) 1761 { 1762 m_pContents->EnableModify(bEnabled); 1763 } 1764 1765 void CPWL_Note::EnableRead(FX_BOOL bEnabled) 1766 { 1767 m_pContents->EnableRead(bEnabled); 1768 } 1769 1770 CFX_WideString CPWL_Note::GetReplyString() const 1771 { 1772 return m_sReplyString; 1773 } 1774 1775 void CPWL_Note::SetReplyString(const CFX_WideString& string) 1776 { 1777 m_sReplyString = string; 1778 } 1779 1780