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 36CPWL_Note_Options::CPWL_Note_Options() : m_pText(NULL) 37{ 38} 39 40CPWL_Note_Options::~CPWL_Note_Options() 41{ 42} 43 44void 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 52void 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 74void 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 83void CPWL_Note_Options::SetText(const CFX_WideString& sText) 84{ 85 m_pText->SetText(sText); 86} 87 88void 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 114CPDF_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 125CPWL_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 133CPWL_Note_Edit::~CPWL_Note_Edit() 134{ 135} 136 137void 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 146void 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 154void CPWL_Note_Edit::OnSetFocus() 155{ 156 m_bEnableNotify = FALSE; 157 CPWL_Edit::OnSetFocus(); 158 m_bEnableNotify = TRUE; 159 160 this->EnableSpellCheck(TRUE); 161} 162 163void 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 182void 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 235FX_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 265FX_FLOAT CPWL_Note_Edit::GetItemLeftMargin() 266{ 267 return POPUP_ITEM_TEXT_INDENT; 268} 269 270FX_FLOAT CPWL_Note_Edit::GetItemRightMargin() 271{ 272 return POPUP_ITEM_TEXT_INDENT; 273} 274 275/* -------------------------------- CPWL_Note_LBBox --------------------------------*/ 276 277CPWL_Note_LBBox::CPWL_Note_LBBox() 278{ 279} 280 281CPWL_Note_LBBox::~CPWL_Note_LBBox() 282{ 283} 284 285void 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 306CPWL_Note_RBBox::CPWL_Note_RBBox() 307{ 308} 309 310CPWL_Note_RBBox::~CPWL_Note_RBBox() 311{ 312} 313 314void 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 335CPWL_Note_Icon::CPWL_Note_Icon() : m_nType(0) 336{ 337} 338 339CPWL_Note_Icon::~CPWL_Note_Icon() 340{ 341} 342 343void CPWL_Note_Icon::SetIconType(FX_INT32 nType) 344{ 345 m_nType = nType; 346} 347 348void 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 356CPWL_Note_CloseBox::CPWL_Note_CloseBox() : m_bMouseDown(FALSE) 357{ 358} 359 360CPWL_Note_CloseBox::~CPWL_Note_CloseBox() 361{ 362} 363 364void 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 394FX_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 404FX_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 416CPWL_Note_Contents::CPWL_Note_Contents() : m_pEdit(NULL) 417{ 418} 419 420CPWL_Note_Contents::~CPWL_Note_Contents() 421{ 422} 423 424CFX_ByteString CPWL_Note_Contents::GetClassName() const 425{ 426 return "CPWL_Note_Contents"; 427} 428 429void 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 441void 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 452CFX_WideString CPWL_Note_Contents::GetText() const 453{ 454 if (m_pEdit) 455 return m_pEdit->GetText(); 456 457 return L""; 458} 459 460CPWL_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 484FX_INT32 CPWL_Note_Contents::CountSubItems() const 485{ 486 return m_aChildren.GetSize() - 1; 487} 488 489IPWL_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 503void 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 530IPWL_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 549void 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 615FX_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 627void 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 636CPWL_Edit* CPWL_Note_Contents::GetEdit() const 637{ 638 return m_pEdit; 639} 640 641void 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 661void 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 683CPWL_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 695CPWL_NoteItem::~CPWL_NoteItem() 696{ 697} 698 699CFX_ByteString CPWL_NoteItem::GetClassName() const 700{ 701 return "CPWL_NoteItem"; 702} 703 704void 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 739void 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 779void CPWL_NoteItem::SetPrivateData(void* pData) 780{ 781 m_pPrivateData = pData; 782} 783 784void 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 810void 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 823void 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 834void 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 863void 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 882void 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 895CPWL_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 909IPWL_NoteItem* CPWL_NoteItem::GetParentItem() const 910{ 911 return GetParentNoteItem(); 912} 913 914CPWL_Edit* CPWL_NoteItem::GetEdit() const 915{ 916 if (m_pContents) 917 return m_pContents->GetEdit(); 918 return NULL; 919} 920 921void* CPWL_NoteItem::GetPrivateData() const 922{ 923 return m_pPrivateData; 924} 925 926CFX_WideString CPWL_NoteItem::GetAuthorName() const 927{ 928 return m_sAuthor; 929} 930 931CPWL_Color CPWL_NoteItem::GetBkColor() const 932{ 933 return this->GetBackgroundColor(); 934} 935 936CFX_WideString CPWL_NoteItem::GetContents() const 937{ 938 if (m_pContents) 939 return m_pContents->GetText(); 940 941 return L""; 942} 943 944FX_SYSTEMTIME CPWL_NoteItem::GetDateTime() const 945{ 946 return m_dtNote; 947} 948 949CFX_WideString CPWL_NoteItem::GetSubjectName() const 950{ 951 if (m_pSubject) 952 return m_pSubject->GetText(); 953 954 return L""; 955} 956 957CPWL_NoteItem* CPWL_NoteItem::CreateNoteItem() 958{ 959 if (m_pContents) 960 return m_pContents->CreateSubItem(); 961 962 return NULL; 963} 964 965IPWL_NoteItem* CPWL_NoteItem::CreateSubItem() 966{ 967 return CreateNoteItem(); 968} 969 970FX_INT32 CPWL_NoteItem::CountSubItems() const 971{ 972 if (m_pContents) 973 return m_pContents->CountSubItems(); 974 975 return 0; 976} 977 978IPWL_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 986void 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 999IPWL_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 1017IPWL_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 1039FX_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 1064FX_FLOAT CPWL_NoteItem::GetItemLeftMargin() 1065{ 1066 return POPUP_ITEM_SIDEMARGIN; 1067} 1068 1069FX_FLOAT CPWL_NoteItem::GetItemRightMargin() 1070{ 1071 return POPUP_ITEM_SIDEMARGIN; 1072} 1073 1074FX_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 1086FX_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 1099void 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 1135void 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 1147const 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 1162IPWL_NoteNotify* CPWL_NoteItem::GetNoteNotify() const 1163{ 1164 if (const CPWL_Note* pNote = GetNote()) 1165 return pNote->GetNoteNotify(); 1166 1167 return NULL; 1168} 1169 1170void CPWL_NoteItem::OnCreateNoteItem() 1171{ 1172 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) 1173 { 1174 pNotify->OnItemCreate(this); 1175 } 1176} 1177 1178void CPWL_NoteItem::OnContentsValidate() 1179{ 1180 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) 1181 { 1182 pNotify->OnSetContents(this); 1183 } 1184} 1185 1186void CPWL_NoteItem::SetNoteFocus(FX_BOOL bLast) 1187{ 1188 m_pContents->SetEditFocus(bLast); 1189} 1190 1191void CPWL_NoteItem::EnableModify(FX_BOOL bEnabled) 1192{ 1193 m_pContents->EnableModify(bEnabled); 1194 m_bAllowModify = bEnabled; 1195} 1196 1197void CPWL_NoteItem::EnableRead(FX_BOOL bEnabled) 1198{ 1199 m_pContents->EnableRead(bEnabled); 1200} 1201 1202/* ---------------------------------- CPWL_Note ---------------------------------- */ 1203 1204CPWL_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 1221CPWL_Note::~CPWL_Note() 1222{ 1223} 1224 1225IPWL_NoteItem* CPWL_Note::Reply() 1226{ 1227 return CreateNoteItem(); 1228} 1229 1230void CPWL_Note::EnableNotify(FX_BOOL bEnabled) 1231{ 1232 m_bEnalbleNotify = bEnabled; 1233} 1234 1235void 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 1255FX_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 1297FX_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 1305void CPWL_Note::SetOptionsText(const CFX_WideString& sText) 1306{ 1307 if (m_pOptions) 1308 m_pOptions->SetText(sText); 1309 1310 RePosNoteChildren(); 1311} 1312 1313void 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 1425FX_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 1457void 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 1522void CPWL_Note::SetSubjectName(const CFX_WideString& sName) 1523{ 1524 CPWL_NoteItem::SetSubjectName(sName); 1525 RePosChildWnd(); 1526} 1527 1528void 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 1542CFX_WideString CPWL_Note::GetAuthorName() const 1543{ 1544 if (m_pAuthor) 1545 return m_pAuthor->GetText(); 1546 1547 return L""; 1548} 1549 1550FX_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 1585void 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 1693void 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 1716FX_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 1736FX_BOOL CPWL_Note::OnRButtonUp(const CPDF_Point & point, FX_DWORD nFlag) 1737{ 1738 return CPWL_Wnd::OnRButtonUp(point,nFlag); 1739} 1740 1741const CPWL_Note* CPWL_Note::GetNote() const 1742{ 1743 return this; 1744} 1745 1746IPWL_NoteNotify* CPWL_Note::GetNoteNotify() const 1747{ 1748 if (m_bEnalbleNotify) 1749 return m_pNoteNotify; 1750 1751 return NULL; 1752} 1753 1754void CPWL_Note::SetIconType(FX_INT32 nType) 1755{ 1756 if (m_pIcon) 1757 m_pIcon->SetIconType(nType); 1758} 1759 1760void CPWL_Note::EnableModify(FX_BOOL bEnabled) 1761{ 1762 m_pContents->EnableModify(bEnabled); 1763} 1764 1765void CPWL_Note::EnableRead(FX_BOOL bEnabled) 1766{ 1767 m_pContents->EnableRead(bEnabled); 1768} 1769 1770CFX_WideString CPWL_Note::GetReplyString() const 1771{ 1772 return m_sReplyString; 1773} 1774 1775void CPWL_Note::SetReplyString(const CFX_WideString& string) 1776{ 1777 m_sReplyString = string; 1778} 1779 1780