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