1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 #include "PostItMgr.hxx" 32 #include <postithelper.hxx> 33 34 #include <SidebarWin.hxx> 35 #include <AnnotationWin.hxx> 36 #include <frmsidebarwincontainer.hxx> 37 #include <accmap.hxx> 38 39 #include <SidebarWindowsConsts.hxx> 40 #include <AnchorOverlayObject.hxx> 41 #include <ShadowOverlayObject.hxx> 42 43 #include <vcl/svapp.hxx> 44 #include <vcl/scrbar.hxx> 45 #include <vcl/outdev.hxx> 46 47 #include <viewopt.hxx> 48 49 #include <view.hxx> 50 #include <docsh.hxx> 51 #include <wrtsh.hxx> 52 #include <doc.hxx> 53 #include <fldbas.hxx> 54 #include <fmtfld.hxx> 55 #include <docufld.hxx> 56 #include <edtwin.hxx> 57 #include <txtfld.hxx> 58 #include <ndtxt.hxx> 59 #include <redline.hxx> 60 #include <docary.hxx> 61 #include <SwRewriter.hxx> 62 #include <tools/color.hxx> 63 64 #include <swmodule.hxx> 65 #include <annotation.hrc> 66 #include "cmdid.h" 67 68 #include <sfx2/request.hxx> 69 #include <sfx2/event.hxx> 70 #include <svl/srchitem.hxx> 71 72 73 #include <svl/languageoptions.hxx> 74 #include <svtools/langtab.hxx> 75 #include <svl/smplhint.hxx> 76 77 #include <svx/svdview.hxx> 78 #include <editeng/eeitem.hxx> 79 #include <editeng/langitem.hxx> 80 #include <editeng/outliner.hxx> 81 82 #include <i18npool/mslangid.hxx> 83 #include <i18npool/lang.h> 84 85 #include "swevent.hxx" 86 #include "switerator.hxx" 87 88 // distance between Anchor Y and initial note position 89 #define POSTIT_INITIAL_ANCHOR_DISTANCE 20 90 //distance between two postits 91 #define POSTIT_SPACE_BETWEEN 8 92 #define POSTIT_MINIMUMSIZE_WITH_META 60 93 #define POSTIT_SCROLL_SIDEBAR_HEIGHT 20 94 95 // if we layout more often we stop, this should never happen 96 #define MAX_LOOP_COUNT 50 97 98 using namespace sw::sidebarwindows; 99 100 /* 101 bool comp_author( const SwPostItItem* a, const SwPostItItem* b) 102 { 103 return a->pFmtFld->GetFld()->GetPar1() < b->pFmtFld->GetFld()->GetPar1(); 104 } 105 106 bool comp_date( const SwPostItItem* a, const SwPostItItem* b) 107 { 108 return static_cast<SwPostItField*>(a->pFmtFld->GetFld())->GetDate() < static_cast<SwPostItField*>(b->pFmtFld->GetFld())->GetDate(); 109 } 110 */ 111 112 // 113 bool comp_pos(const SwSidebarItem* a, const SwSidebarItem* b) 114 { 115 // --> OD 2010-01-19 #i88070# 116 // sort by anchor position 117 //// if position is on the same line, sort by x (Left) position, otherwise by y(Bottom) position 118 //// if two notes are at the same position, sort by logical node position 119 // return (a->maLayoutInfo.mPosition.Bottom() == b->maLayoutInfo.mPosition.Bottom()) 120 // ? ( ( (a->maLayoutInfo.mPosition.Left() == b->maLayoutInfo.mPosition.Left()) && 121 // (a->GetBroadCaster()->ISA(SwFmtFld) && b->GetBroadCaster()->ISA(SwFmtFld)) ) 122 // ? *(static_cast<SwFmtFld*>(a->GetBroadCaster())->GetTxtFld()->GetStart()) < 123 // *(static_cast<SwFmtFld*>(b->GetBroadCaster())->GetTxtFld()->GetStart()) 124 // : a->maLayoutInfo.mPosition.Left() < b->maLayoutInfo.mPosition.Left() ) 125 // : a->maLayoutInfo.mPosition.Bottom() < b->maLayoutInfo.mPosition.Bottom(); 126 return a->GetAnchorPosition() < b->GetAnchorPosition(); 127 // <-- 128 } 129 130 SwPostItMgr::SwPostItMgr(SwView* pView) 131 : mpView(pView) 132 , mpWrtShell(mpView->GetDocShell()->GetWrtShell()) 133 , mpEditWin(&mpView->GetEditWin()) 134 , mnEventId(0) 135 , mbWaitingForCalcRects(false) 136 , mpActivePostIt(0) 137 , mbLayout(false) 138 , mbLayoutHeight(0) 139 , mbLayouting(false) 140 , mbReadOnly(mpView->GetDocShell()->IsReadOnly()) 141 , mbDeleteNote(true) 142 , mpAnswer(0) 143 , mbIsShowAnchor( false ) 144 , mpFrmSidebarWinContainer( 0 ) 145 { 146 if(!mpView->GetDrawView() ) 147 mpView->GetWrtShell().MakeDrawView(); 148 149 SwNoteProps aProps; 150 mbIsShowAnchor = aProps.IsShowAnchor(); 151 152 //make sure we get the colour yellow always, even if not the first one of comments or redlining 153 SW_MOD()->GetRedlineAuthor(); 154 155 // collect all PostIts and redline comments that exist after loading the document 156 // don't check for existance for any of them, don't focus them 157 AddPostIts(false,false); 158 /* this code can be used once we want redline comments in the Sidebar 159 AddRedlineComments(false,false); 160 */ 161 // we want to receive stuff like SFX_HINT_DOCCHANGED 162 StartListening(*mpView->GetDocShell()); 163 if (!mvPostItFlds.empty()) 164 { 165 mbWaitingForCalcRects = true; 166 mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 ); 167 } 168 } 169 170 SwPostItMgr::~SwPostItMgr() 171 { 172 if ( mnEventId ) 173 Application::RemoveUserEvent( mnEventId ); 174 // forget about all our Sidebar windows 175 RemoveSidebarWin(); 176 EndListening( *mpView->GetDocShell() ); 177 178 for(std::vector<SwPostItPageItem*>::iterator i = mPages.begin(); i!= mPages.end() ; i++) 179 delete (*i); 180 mPages.clear(); 181 182 delete mpFrmSidebarWinContainer; 183 mpFrmSidebarWinContainer = 0; 184 } 185 186 void SwPostItMgr::CheckForRemovedPostIts() 187 { 188 bool bRemoved = false; 189 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end(); ) 190 { 191 std::list<SwSidebarItem*>::iterator it = i++; 192 if ( !(*it)->UseElement() ) 193 { 194 SwSidebarItem* p = (*it); 195 mvPostItFlds.remove(*it); 196 if (GetActiveSidebarWin() == p->pPostIt) 197 SetActiveSidebarWin(0); 198 if (p->pPostIt) 199 delete p->pPostIt; 200 delete p; 201 bRemoved = true; 202 } 203 } 204 205 if ( bRemoved ) 206 { 207 // make sure that no deleted items remain in page lists 208 // todo: only remove deleted ones?! 209 if ( mvPostItFlds.empty() ) 210 { 211 PreparePageContainer(); 212 PrepareView(); 213 } 214 else 215 // if postits are their make sure that page lists are not empty 216 // otherwise sudden paints can cause pain (in BorderOverPageBorder) 217 CalcRects(); 218 } 219 } 220 221 void SwPostItMgr::InsertItem(SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus) 222 { 223 if (bCheckExistance) 224 { 225 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 226 { 227 if ( (*i)->GetBroadCaster() == pItem ) 228 return; 229 } 230 } 231 mbLayout = bFocus; 232 if (pItem->ISA(SwFmtFld)) 233 mvPostItFlds.push_back(new SwAnnotationItem(static_cast<SwFmtFld*>(pItem), true, bFocus) ); 234 /* 235 else 236 if (pItem->ISA(SwRedline)) 237 mvPostItFlds.push_back(new SwRedCommentItem( static_cast<SwRedline*>(pItem), true, bFocus)) ; 238 */ 239 DBG_ASSERT(pItem->ISA(SwFmtFld) /*|| pItem->ISA(SwRedline)*/,"Mgr::InsertItem: seems like new stuff was added"); 240 StartListening(*pItem); 241 } 242 243 void SwPostItMgr::RemoveItem( SfxBroadcaster* pBroadcast ) 244 { 245 EndListening(*pBroadcast); 246 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 247 { 248 if ( (*i)->GetBroadCaster() == pBroadcast ) 249 { 250 SwSidebarItem* p = (*i); 251 if (GetActiveSidebarWin() == p->pPostIt) 252 SetActiveSidebarWin(0); 253 mvPostItFlds.remove(*i); 254 delete p->pPostIt; 255 delete p; 256 break; 257 } 258 } 259 mbLayout = true; 260 PrepareView(); 261 } 262 263 void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) 264 { 265 if ( rHint.IsA(TYPE(SfxEventHint) ) ) 266 { 267 sal_uInt32 nId = ((SfxEventHint&)rHint).GetEventId(); 268 if ( nId == SW_EVENT_LAYOUT_FINISHED ) 269 { 270 if ( !mbWaitingForCalcRects && !mvPostItFlds.empty()) 271 { 272 mbWaitingForCalcRects = true; 273 mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 ); 274 } 275 } 276 } 277 else if ( rHint.IsA(TYPE(SfxSimpleHint) ) ) 278 { 279 sal_uInt32 nId = ((SfxSimpleHint&)rHint).GetId(); 280 switch ( nId ) 281 { 282 case SFX_HINT_MODECHANGED: 283 { 284 if ( mbReadOnly != !!(mpView->GetDocShell()->IsReadOnly()) ) 285 { 286 mbReadOnly = !mbReadOnly; 287 SetReadOnlyState(); 288 mbLayout = true; 289 } 290 break; 291 } 292 case SFX_HINT_DOCCHANGED: 293 { 294 if ( mpView->GetDocShell() == &rBC ) 295 { 296 if ( !mbWaitingForCalcRects && !mvPostItFlds.empty()) 297 { 298 mbWaitingForCalcRects = true; 299 mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 ); 300 } 301 } 302 break; 303 } 304 case SFX_HINT_USER04: 305 { 306 // if we are in a SplitNode/Cut operation, do not delete note and then add again, as this will flicker 307 mbDeleteNote = !mbDeleteNote; 308 break; 309 } 310 case SFX_HINT_DYING: 311 { 312 if ( mpView->GetDocShell() != &rBC ) 313 { 314 // field to be removed is the broadcaster 315 DBG_ERROR("Notification for removed SwFmtFld was not sent!"); 316 RemoveItem(&rBC); 317 } 318 break; 319 } 320 } 321 } 322 /* 323 else if ( rHint.IsA(TYPE(SwRedlineHint) ) ) 324 { 325 const SwRedlineHint rRedlineHint = static_cast<const SwRedlineHint&>(rHint); 326 SwRedline* pRedline = const_cast<SwRedline*>(rRedlineHint.GetRedline()); 327 switch ( rRedlineHint.Which() ) 328 { 329 case SWREDLINE_INSERTED : 330 { 331 bool bEmpty = !HasNotes(); 332 InsertItem( pRedline, true, false ); 333 if (bEmpty && !mvPostItFlds.empty()) 334 PrepareView(true); 335 break; 336 } 337 case SWREDLINE_REMOVED: 338 { 339 RemoveItem(pRedline); 340 break; 341 } 342 case SWREDLINE_FOCUS: 343 { 344 if (rRedlineHint.GetView()== mpView) 345 Focus(rBC); 346 break; 347 } 348 } 349 } 350 */ 351 else if ( rHint.IsA(TYPE(SwFmtFldHint) ) ) 352 { 353 const SwFmtFldHint& rFmtHint = static_cast<const SwFmtFldHint&>(rHint); 354 SwFmtFld* pFld = const_cast <SwFmtFld*>( rFmtHint.GetField() ); 355 switch ( rFmtHint.Which() ) 356 { 357 case SWFMTFLD_INSERTED : 358 { 359 if (!pFld) 360 { 361 AddPostIts(true); 362 break; 363 } 364 // get field to be inserted from hint 365 if ( pFld->IsFldInDoc() ) 366 { 367 bool bEmpty = !HasNotes(); 368 InsertItem( pFld, true, false ); 369 if (bEmpty && !mvPostItFlds.empty()) 370 PrepareView(true); 371 } 372 else 373 { 374 DBG_ERROR( "Inserted field not in document!" ); 375 } 376 break; 377 } 378 case SWFMTFLD_REMOVED: 379 { 380 if (mbDeleteNote) 381 { 382 if (!pFld) 383 { 384 CheckForRemovedPostIts(); 385 break; 386 } 387 RemoveItem(pFld); 388 } 389 break; 390 } 391 case SWFMTFLD_FOCUS: 392 { 393 if (rFmtHint.GetView()== mpView) 394 Focus(rBC); 395 break; 396 } 397 case SWFMTFLD_CHANGED: 398 { 399 SwFmtFld* pFmtFld = dynamic_cast<SwFmtFld*>(&rBC); 400 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 401 { 402 if ( pFmtFld == (*i)->GetBroadCaster() ) 403 { 404 if ((*i)->pPostIt) 405 { 406 (*i)->pPostIt->SetPostItText(); 407 mbLayout = true; 408 } 409 break; 410 } 411 } 412 break; 413 } 414 case SWFMTFLD_LANGUAGE: 415 { 416 SwFmtFld* pFmtFld = dynamic_cast<SwFmtFld*>(&rBC); 417 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 418 { 419 if ( pFmtFld == (*i)->GetBroadCaster() ) 420 { 421 if ((*i)->pPostIt) 422 { 423 sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( (*i)->GetFmtFld()->GetFld()->GetLanguage() ); 424 sal_uInt16 nLangWhichId = 0; 425 switch (nScriptType) 426 { 427 case SCRIPTTYPE_LATIN : nLangWhichId = EE_CHAR_LANGUAGE ; break; 428 case SCRIPTTYPE_ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break; 429 case SCRIPTTYPE_COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break; 430 } 431 (*i)->pPostIt->SetLanguage( SvxLanguageItem((*i)->GetFmtFld()->GetFld()->GetLanguage(), 432 nLangWhichId) ); 433 } 434 break; 435 } 436 } 437 break; 438 } 439 } 440 } 441 } 442 443 void SwPostItMgr::Focus(SfxBroadcaster& rBC) 444 { 445 if (!mpWrtShell->GetViewOptions()->IsPostIts()) 446 { 447 SfxRequest aRequest(mpView->GetViewFrame(),FN_VIEW_NOTES); 448 mpView->ExecViewOptions(aRequest); 449 } 450 451 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 452 { 453 // field to get the focus is the broadcaster 454 if ( &rBC == (*i)->GetBroadCaster() ) 455 { 456 if ((*i)->pPostIt) 457 { 458 (*i)->pPostIt->GrabFocus(); 459 MakeVisible((*i)->pPostIt); 460 } 461 else 462 { 463 // when the layout algorithm starts, this postit is created and receives focus 464 (*i)->bFocus = true; 465 } 466 } 467 } 468 } 469 470 bool SwPostItMgr::CalcRects() 471 { 472 if ( mnEventId ) 473 { 474 // if CalcRects() was forced and an event is still pending: remove it 475 // it is superfluous and also may cause reentrance problems if triggered while layouting 476 Application::RemoveUserEvent( mnEventId ); 477 mnEventId = 0; 478 } 479 480 bool bChange = false; 481 bool bRepair = false; 482 PreparePageContainer(); 483 if ( !mvPostItFlds.empty() ) 484 { 485 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 486 { 487 SwSidebarItem* pItem = (*i); 488 if ( !pItem->UseElement() ) 489 { 490 DBG_ERROR("PostIt is not in doc or other wrong use"); 491 bRepair = true; 492 continue; 493 } 494 495 //save old rect and visible state 496 SwRect aOldRect(pItem->maLayoutInfo.mPosition); 497 SwPostItHelper::SwLayoutStatus eOldStatus = pItem->mLayoutStatus; 498 std::vector< SwLayoutInfo > aInfo; 499 { 500 SwPosition aPosition = pItem->GetAnchorPosition(); 501 pItem->mLayoutStatus = SwPostItHelper::getLayoutInfos( aInfo, aPosition ); 502 } 503 if( aInfo.size() ) 504 { 505 pItem->maLayoutInfo = aInfo[0]; 506 } 507 bChange = bChange || 508 ( pItem->maLayoutInfo.mPosition != aOldRect ) || 509 ( eOldStatus != pItem->mLayoutStatus ); 510 } 511 512 // show notes in right order in navigator 513 //prevent Anchors during layout to overlap, e.g. when moving a frame 514 Sort(SORT_POS); 515 516 // sort the items into the right page vector, so layout can be done by page 517 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 518 { 519 SwSidebarItem* pItem = (*i); 520 if( SwPostItHelper::INVISIBLE == pItem->mLayoutStatus ) 521 { 522 if (pItem->pPostIt) 523 pItem->pPostIt->HideNote(); 524 continue; 525 } 526 527 if( SwPostItHelper::HIDDEN == pItem->mLayoutStatus ) 528 { 529 if (!mpWrtShell->GetViewOptions()->IsShowHiddenChar()) 530 { 531 if (pItem->pPostIt) 532 pItem->pPostIt->HideNote(); 533 continue; 534 } 535 } 536 537 const unsigned long aPageNum = pItem->maLayoutInfo.mnPageNumber; 538 if (aPageNum > mPages.size()) 539 { 540 const unsigned long nNumberOfPages = mPages.size(); 541 for (unsigned int j=0; j<aPageNum - nNumberOfPages; ++j) 542 mPages.push_back( new SwPostItPageItem()); 543 } 544 mPages[aPageNum-1]->mList->push_back(pItem); 545 mPages[aPageNum-1]->mPageRect = pItem->maLayoutInfo.mPageFrame; 546 mPages[aPageNum-1]->eSidebarPosition = pItem->maLayoutInfo.meSidebarPosition; 547 } 548 549 if (!bChange && mpWrtShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE)) 550 { 551 long nLayoutHeight = SwPostItHelper::getLayoutHeight( mpWrtShell->GetLayout() ); 552 if( nLayoutHeight > mbLayoutHeight ) 553 { 554 if (mPages[0]->bScrollbar || HasScrollbars()) 555 bChange = true; 556 } 557 else if( nLayoutHeight < mbLayoutHeight ) 558 { 559 if (mPages[0]->bScrollbar || !BorderOverPageBorder(1)) 560 bChange = true; 561 } 562 } 563 } 564 565 if ( bRepair ) 566 CheckForRemovedPostIts(); 567 568 mbLayoutHeight = SwPostItHelper::getLayoutHeight( mpWrtShell->GetLayout() ); 569 mbWaitingForCalcRects = false; 570 return bChange; 571 } 572 573 bool SwPostItMgr::HasScrollbars() const 574 { 575 for(std::list<SwSidebarItem*>::const_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 576 { 577 if ((*i)->bShow && (*i)->pPostIt && (*i)->pPostIt->HasScrollbar()) 578 return true; 579 } 580 return false; 581 } 582 583 void SwPostItMgr::PreparePageContainer() 584 { 585 // we do not just delete the SwPostItPageItem, so offset/scrollbar is not lost 586 long lPageSize = mpWrtShell->GetNumPages(); 587 long lContainerSize = mPages.size(); 588 589 if (lContainerSize < lPageSize) 590 { 591 for (int i=0; i<lPageSize - lContainerSize;i++) 592 mPages.push_back( new SwPostItPageItem()); 593 } 594 else 595 if (lContainerSize > lPageSize) 596 { 597 for (int i=mPages.size()-1; i >= lPageSize;--i) 598 { 599 delete mPages[i]; 600 mPages.pop_back(); 601 } 602 } 603 // only clear the list, DO NOT delete the objects itself 604 for(std::vector<SwPostItPageItem*>::iterator i = mPages.begin(); i!= mPages.end() ; i++) 605 { 606 (*i)->mList->clear(); 607 if (mvPostItFlds.empty()) 608 (*i)->bScrollbar = false; 609 610 } 611 } 612 613 void SwPostItMgr::LayoutPostIts() 614 { 615 if ( !mvPostItFlds.empty() && !mbWaitingForCalcRects ) 616 { 617 mbLayouting = true; 618 619 //loop over all pages and do the layout 620 // - create SwPostIt if neccessary 621 // - place SwPostIts on their initial position 622 // - calculate neccessary height for all PostIts together 623 bool bUpdate = false; 624 for (unsigned long n=0;n<mPages.size();n++) 625 { 626 // only layout if there are notes on this page 627 if (mPages[n]->mList->size()>0) 628 { 629 std::list<SwSidebarWin*> aVisiblePostItList; 630 unsigned long lNeededHeight = 0; 631 long mlPageBorder = 0; 632 long mlPageEnd = 0; 633 634 for(SwSidebarItem_iterator i = mPages[n]->mList->begin(); i!= mPages[n]->mList->end(); i++) 635 { 636 SwSidebarItem* pItem = (*i); 637 SwSidebarWin* pPostIt = pItem->pPostIt; 638 639 if (mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT ) 640 { 641 // x value for notes positioning 642 mlPageBorder = mpEditWin->LogicToPixel( Point( mPages[n]->mPageRect.Left(), 0)).X() - GetSidebarWidth(true);// - GetSidebarBorderWidth(true); 643 //bending point 644 mlPageEnd = 645 mpWrtShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) 646 ? pItem->maLayoutInfo.mPagePrtArea.Left() 647 : mPages[n]->mPageRect.Left() + 350; 648 } 649 else if (mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT ) 650 { 651 // x value for notes positioning 652 mlPageBorder = mpEditWin->LogicToPixel( Point(mPages[n]->mPageRect.Right(), 0)).X() + GetSidebarBorderWidth(true); 653 //bending point 654 mlPageEnd = 655 mpWrtShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) 656 ? pItem->maLayoutInfo.mPagePrtArea.Right() : 657 mPages[n]->mPageRect.Right() - 350; 658 } 659 660 if (pItem->bShow) 661 { 662 long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y(); 663 long aPostItHeight = 0; 664 if (!pPostIt) 665 { 666 pPostIt = (*i)->GetSidebarWindow( mpView->GetEditWin(), 667 WB_DIALOGCONTROL, 668 *this, 669 0 ); 670 pPostIt->InitControls(); 671 pPostIt->SetReadonly(mbReadOnly); 672 pItem->pPostIt = pPostIt; 673 if (mpAnswer) 674 { 675 if (pPostIt->CalcFollow()) //do we really have another note in front of this one 676 static_cast<sw::annotation::SwAnnotationWin*>(pPostIt)->InitAnswer(mpAnswer); 677 delete mpAnswer; 678 mpAnswer = 0; 679 } 680 } 681 682 pPostIt->SetChangeTracking( 683 pItem->mLayoutStatus, 684 GetColorAnchor(pItem->maLayoutInfo.mRedlineAuthor)); 685 pPostIt->SetSidebarPosition(mPages[n]->eSidebarPosition); 686 pPostIt->SetFollow(pPostIt->CalcFollow()); 687 aPostItHeight = ( pPostIt->GetPostItTextHeight() < pPostIt->GetMinimumSizeWithoutMeta() 688 ? pPostIt->GetMinimumSizeWithoutMeta() 689 : pPostIt->GetPostItTextHeight() ) 690 + pPostIt->GetMetaHeight(); 691 pPostIt->SetPosSizePixelRect( mlPageBorder , 692 Y - GetInitialAnchorDistance(), 693 GetNoteWidth() , 694 aPostItHeight, 695 pItem->maLayoutInfo.mPosition, 696 mlPageEnd ); 697 pPostIt->ChangeSidebarItem( *pItem ); 698 699 if (pItem->bFocus) 700 { 701 mbLayout = true; 702 pPostIt->GrabFocus(); 703 pItem->bFocus = false; 704 } 705 // only the visible postits are used for the final layout 706 aVisiblePostItList.push_back(pPostIt); 707 lNeededHeight += pPostIt->IsFollow() ? aPostItHeight : aPostItHeight+GetSpaceBetween(); 708 } 709 else // we don't want to see it 710 { 711 if (pPostIt) 712 pPostIt->HideNote(); 713 } 714 } 715 716 if ((aVisiblePostItList.size()>0) && ShowNotes()) 717 { 718 bool bOldScrollbar = mPages[n]->bScrollbar; 719 if (ShowNotes()) 720 mPages[n]->bScrollbar = LayoutByPage(aVisiblePostItList, mPages[n]->mPageRect.SVRect(), lNeededHeight); 721 else 722 mPages[n]->bScrollbar = false; 723 if (!mPages[n]->bScrollbar) 724 { 725 mPages[n]->lOffset = 0; 726 } 727 else 728 { 729 //when we changed our zoom level, the offset value can be to big, so lets check for the largest possible zoom value 730 long aAvailableHeight = mpEditWin->LogicToPixel(Size(0,mPages[n]->mPageRect.Height())).Height() - 2 * GetSidebarScrollerHeight(); 731 long lOffset = -1 * GetScrollSize() * (aVisiblePostItList.size() - aAvailableHeight / GetScrollSize()); 732 if (mPages[n]->lOffset < lOffset) 733 mPages[n]->lOffset = lOffset; 734 } 735 bUpdate = (bOldScrollbar != mPages[n]->bScrollbar) || bUpdate; 736 const long aSidebarheight = mPages[n]->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0; 737 /* 738 TODO 739 - enlarge all notes till GetNextBorder(), as we resized to average value before 740 */ 741 //lets hide the ones which overlap the page 742 for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++) 743 { 744 if (mPages[n]->lOffset != 0) 745 (*i)->TranslateTopPosition(mPages[n]->lOffset); 746 747 bool bBottom = mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y()+(*i)->VirtualSize().Height())).Y() <= (mPages[n]->mPageRect.Bottom()-aSidebarheight); 748 bool bTop = mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y())).Y() >= (mPages[n]->mPageRect.Top()+aSidebarheight); 749 if ( bBottom && bTop ) 750 { 751 (*i)->ShowNote(); 752 } 753 else 754 { 755 if (mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y())).Y() < (mPages[n]->mPageRect.Top()+aSidebarheight)) 756 { 757 if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT ) 758 (*i)->ShowAnchorOnly(Point( mPages[n]->mPageRect.Left(), 759 mPages[n]->mPageRect.Top())); 760 else if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT ) 761 (*i)->ShowAnchorOnly(Point( mPages[n]->mPageRect.Right(), 762 mPages[n]->mPageRect.Top())); 763 } 764 else 765 { 766 if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT ) 767 (*i)->ShowAnchorOnly(Point(mPages[n]->mPageRect.Left(), 768 mPages[n]->mPageRect.Bottom())); 769 else if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT ) 770 (*i)->ShowAnchorOnly(Point(mPages[n]->mPageRect.Right(), 771 mPages[n]->mPageRect.Bottom())); 772 } 773 DBG_ASSERT(mPages[n]->bScrollbar,"SwPostItMgr::LayoutByPage(): note overlaps, but bScrollbar is not true"); 774 } 775 } 776 777 // do some magic so we really see the focused note 778 for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++) 779 { 780 if ((*i)->HasChildPathFocus()) 781 { 782 MakeVisible((*i),n+1); 783 break; 784 } 785 } 786 } 787 else 788 { 789 for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++) 790 (*i)->SetPosAndSize(); 791 792 bool bOldScrollbar = mPages[n]->bScrollbar; 793 mPages[n]->bScrollbar = false; 794 bUpdate = (bOldScrollbar != mPages[n]->bScrollbar) || bUpdate; 795 } 796 aVisiblePostItList.clear(); 797 } 798 else 799 { 800 bUpdate = true; 801 mPages[n]->bScrollbar = false; 802 } 803 } 804 805 if (!ShowNotes()) 806 { // we do not want to see the notes anymore -> Options-Writer-View-Notes 807 bool bRepair = false; 808 for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 809 { 810 SwSidebarItem* pItem = (*i); 811 if ( !pItem->UseElement() ) 812 { 813 DBG_ERROR("PostIt is not in doc!"); 814 bRepair = true; 815 continue; 816 } 817 818 if ((*i)->pPostIt) 819 { 820 (*i)->pPostIt->HideNote(); 821 if ((*i)->pPostIt->HasChildPathFocus()) 822 { 823 SetActiveSidebarWin(0); 824 (*i)->pPostIt->GrabFocusToDocument(); 825 } 826 } 827 } 828 829 if ( bRepair ) 830 CheckForRemovedPostIts(); 831 } 832 833 834 // notes scrollbar is otherwise not drawn correctly for some cases 835 // scrollbar area is enough 836 if (bUpdate) 837 mpEditWin->Invalidate(); 838 mbLayouting = false; 839 } 840 } 841 842 bool SwPostItMgr::BorderOverPageBorder(unsigned long aPage) const 843 { 844 if ( mPages[aPage-1]->mList->empty() ) 845 { 846 DBG_ERROR("Notes SidePane painted but no rects and page lists calculated!"); 847 return false; 848 } 849 850 SwSidebarItem_iterator aItem = mPages[aPage-1]->mList->end(); 851 --aItem; 852 DBG_ASSERT ((*aItem)->pPostIt,"BorderOverPageBorder: NULL postIt, should never happen"); 853 if ((*aItem)->pPostIt) 854 { 855 const long aSidebarheight = mPages[aPage-1]->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0; 856 const long aEndValue = mpEditWin->PixelToLogic(Point(0,(*aItem)->pPostIt->GetPosPixel().Y()+(*aItem)->pPostIt->GetSizePixel().Height())).Y(); 857 return aEndValue <= mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight; 858 } 859 else 860 return false; 861 } 862 863 void SwPostItMgr::Scroll(const long lScroll,const unsigned long aPage) 864 { 865 DBG_ASSERT((lScroll % GetScrollSize() )==0,"SwPostItMgr::Scroll: scrolling by wrong value"); 866 // do not scroll more than neccessary up or down 867 if ( ((mPages[aPage-1]->lOffset == 0) && (lScroll>0)) || ( BorderOverPageBorder(aPage) && (lScroll<0)) ) 868 return; 869 870 const bool bOldUp = ArrowEnabled(KEY_PAGEUP,aPage); 871 const bool bOldDown = ArrowEnabled(KEY_PAGEDOWN,aPage); 872 const long aSidebarheight = mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height(); 873 for(SwSidebarItem_iterator i = mPages[aPage-1]->mList->begin(); i!= mPages[aPage-1]->mList->end(); i++) 874 { 875 SwSidebarWin* pPostIt = (*i)->pPostIt; 876 // if this is an answer, we should take the normal position and not the real, slightly moved position 877 pPostIt->SetVirtualPosSize(pPostIt->GetPosPixel(),pPostIt->GetSizePixel()); 878 pPostIt->TranslateTopPosition(lScroll); 879 880 if ((*i)->bShow) 881 { 882 bool bBottom = mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y()+pPostIt->VirtualSize().Height())).Y() <= (mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight); 883 bool bTop = mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y())).Y() >= (mPages[aPage-1]->mPageRect.Top()+aSidebarheight); 884 if ( bBottom && bTop) 885 { 886 pPostIt->ShowNote(); 887 } 888 else 889 { 890 if ( mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y())).Y() < (mPages[aPage-1]->mPageRect.Top()+aSidebarheight)) 891 { 892 if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT) 893 pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Left(),mPages[aPage-1]->mPageRect.Top())); 894 else if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT) 895 pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Right(),mPages[aPage-1]->mPageRect.Top())); 896 } 897 else 898 { 899 if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT) 900 pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Left(),mPages[aPage-1]->mPageRect.Bottom())); 901 else if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT) 902 pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Right(),mPages[aPage-1]->mPageRect.Bottom())); 903 } 904 } 905 } 906 } 907 mPages[aPage-1]->lOffset += lScroll; 908 if ( (bOldUp != ArrowEnabled(KEY_PAGEUP,aPage)) ||(bOldDown != ArrowEnabled(KEY_PAGEDOWN,aPage)) ) 909 { 910 mpEditWin->Invalidate(GetBottomScrollRect(aPage)); 911 mpEditWin->Invalidate(GetTopScrollRect(aPage)); 912 } 913 } 914 915 void SwPostItMgr::AutoScroll(const SwSidebarWin* pPostIt,const unsigned long aPage ) 916 { 917 // otherwise all notes are visible 918 if (mPages[aPage-1]->bScrollbar) 919 { 920 const long aSidebarheight = mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height(); 921 const bool bBottom = mpEditWin->PixelToLogic(Point(0,pPostIt->GetPosPixel().Y()+pPostIt->GetSizePixel().Height())).Y() <= (mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight); 922 const bool bTop = mpEditWin->PixelToLogic(Point(0,pPostIt->GetPosPixel().Y())).Y() >= (mPages[aPage-1]->mPageRect.Top()+aSidebarheight); 923 if ( !(bBottom && bTop)) 924 { 925 const long aDiff = bBottom ? mpEditWin->LogicToPixel(Point(0,mPages[aPage-1]->mPageRect.Top() + aSidebarheight)).Y() - pPostIt->GetPosPixel().Y() : 926 mpEditWin->LogicToPixel(Point(0,mPages[aPage-1]->mPageRect.Bottom() - aSidebarheight)).Y() - (pPostIt->GetPosPixel().Y()+pPostIt->GetSizePixel().Height()); 927 // this just adds the missing value to get the next a* GetScrollSize() after aDiff 928 // e.g aDiff= 61 POSTIT_SCOLL=50 --> lScroll = 100 929 const long lScroll = bBottom ? (aDiff + ( GetScrollSize() - (aDiff % GetScrollSize()))) : (aDiff - (GetScrollSize() + (aDiff % GetScrollSize()))); 930 Scroll(lScroll, aPage); 931 } 932 } 933 } 934 935 void SwPostItMgr::MakeVisible(const SwSidebarWin* pPostIt,long aPage ) 936 { 937 if (aPage == -1) 938 { 939 // we dont know the page yet, lets find it ourselves 940 for (unsigned long n=0;n<mPages.size();n++) 941 { 942 if (mPages[n]->mList->size()>0) 943 { 944 for(SwSidebarItem_iterator i = mPages[n]->mList->begin(); i!= mPages[n]->mList->end(); i++) 945 { 946 if ((*i)->pPostIt==pPostIt) 947 { 948 aPage = n+1; 949 break; 950 } 951 } 952 } 953 } 954 } 955 if (aPage!=-1) 956 AutoScroll(pPostIt,aPage); 957 Rectangle aNoteRect (Point(pPostIt->GetPosPixel().X(),pPostIt->GetPosPixel().Y()-5),pPostIt->GetSizePixel()); 958 if (!aNoteRect.IsEmpty()) 959 mpWrtShell->MakeVisible(SwRect(mpEditWin->PixelToLogic(aNoteRect))); 960 } 961 962 bool SwPostItMgr::ArrowEnabled(sal_uInt16 aDirection,unsigned long aPage) const 963 { 964 switch (aDirection) 965 { 966 case KEY_PAGEUP: 967 { 968 return (mPages[aPage-1]->lOffset != 0); 969 } 970 case KEY_PAGEDOWN: 971 { 972 return (!BorderOverPageBorder(aPage)); 973 } 974 default: return false; 975 } 976 } 977 978 Color SwPostItMgr::GetArrowColor(sal_uInt16 aDirection,unsigned long aPage) const 979 { 980 if (ArrowEnabled(aDirection,aPage)) 981 { 982 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode()) 983 return Color(COL_WHITE); 984 else 985 return COL_NOTES_SIDEPANE_ARROW_ENABLED; 986 } 987 else 988 { 989 return COL_NOTES_SIDEPANE_ARROW_DISABLED; 990 } 991 } 992 993 bool SwPostItMgr::LayoutByPage(std::list<SwSidebarWin*> &aVisiblePostItList,const Rectangle aBorder, long lNeededHeight) 994 { 995 /*** General layout idea:***/ 996 // - if we have space left, we always move the current one up, 997 // otherwise the next one down 998 // - first all notes are resized 999 // - then the real layout starts 1000 /*************************************************************/ 1001 1002 //rBorder is the page rect 1003 const Rectangle rBorder = mpEditWin->LogicToPixel( aBorder); 1004 long lTopBorder = rBorder.Top() + 5; 1005 long lBottomBorder = rBorder.Bottom() - 5; 1006 const long lVisibleHeight = lBottomBorder - lTopBorder; //rBorder.GetHeight() ; 1007 long lSpaceUsed = 0; 1008 long lTranslatePos = 0; 1009 int loop = 0; 1010 bool bDone = false; 1011 bool bScrollbars = false; 1012 1013 // do all neccessary resizings 1014 if (lVisibleHeight < lNeededHeight) 1015 { 1016 // ok, now we have to really resize and adding scrollbars 1017 const long lAverageHeight = (lVisibleHeight - aVisiblePostItList.size()*GetSpaceBetween()) / aVisiblePostItList.size(); 1018 if (lAverageHeight<GetMinimumSizeWithMeta()) 1019 { 1020 bScrollbars = true; 1021 lTopBorder += GetSidebarScrollerHeight() + 10; 1022 lBottomBorder -= (GetSidebarScrollerHeight() + 10); 1023 for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++) 1024 (*i)->SetSize(Size((*i)->VirtualSize().getWidth(),(*i)->GetMinimumSizeWithMeta())); 1025 } 1026 else 1027 { 1028 for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++) 1029 { 1030 if ( (*i)->VirtualSize().getHeight() > lAverageHeight) 1031 (*i)->SetSize(Size((*i)->VirtualSize().getWidth(),lAverageHeight)); 1032 } 1033 } 1034 } 1035 1036 //start the real layout so nothing overlaps anymore 1037 if (aVisiblePostItList.size()>1) 1038 { 1039 // if no window is moved anymore we are finished 1040 while (!bDone) 1041 { 1042 loop++; 1043 bDone = true; 1044 lSpaceUsed = lTopBorder + GetSpaceBetween(); 1045 for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++) 1046 { 1047 SwSidebarWin_iterator aNextPostIt = i; 1048 ++aNextPostIt; 1049 1050 if (aNextPostIt !=aVisiblePostItList.end()) 1051 { 1052 lTranslatePos = ( (*i)->VirtualPos().Y() + (*i)->VirtualSize().Height()) - (*aNextPostIt)->VirtualPos().Y(); 1053 if (lTranslatePos > 0) // note windows overlaps the next one 1054 { 1055 // we are not done yet, loop at least once more 1056 bDone = false; 1057 // if there is space left, move the current note up 1058 // it could also happen that there is no space left for the first note due to a scrollbar 1059 // then we also jump into, so we move the current one up and the next one down 1060 if ( (lSpaceUsed <= (*i)->VirtualPos().Y()) || (i==aVisiblePostItList.begin())) 1061 { 1062 // we have space left, so let's move the current one up 1063 if ( ((*i)->VirtualPos().Y()- lTranslatePos - GetSpaceBetween()) > lTopBorder) 1064 { 1065 if ((*aNextPostIt)->IsFollow()) 1066 (*i)->TranslateTopPosition(-1*(lTranslatePos+ANCHORLINE_WIDTH)); 1067 else 1068 (*i)->TranslateTopPosition(-1*(lTranslatePos+GetSpaceBetween())); 1069 } 1070 else 1071 { 1072 long lMoveUp = (*i)->VirtualPos().Y() - lTopBorder; 1073 (*i)->TranslateTopPosition(-1* lMoveUp); 1074 if ((*aNextPostIt)->IsFollow()) 1075 (*aNextPostIt)->TranslateTopPosition( (lTranslatePos+ANCHORLINE_WIDTH) - lMoveUp); 1076 else 1077 (*aNextPostIt)->TranslateTopPosition( (lTranslatePos+GetSpaceBetween()) - lMoveUp); 1078 } 1079 } 1080 else 1081 { 1082 // no space left, left move the next one down 1083 if ((*aNextPostIt)->IsFollow()) 1084 (*aNextPostIt)->TranslateTopPosition(lTranslatePos+ANCHORLINE_WIDTH); 1085 else 1086 (*aNextPostIt)->TranslateTopPosition(lTranslatePos+GetSpaceBetween()); 1087 } 1088 } 1089 else 1090 { 1091 // the first one could overlap the topborder instead of a second note 1092 if (i==aVisiblePostItList.begin()) 1093 { 1094 long lMoveDown = lTopBorder - (*i)->VirtualPos().Y(); 1095 if (lMoveDown>0) 1096 { 1097 bDone = false; 1098 (*i)->TranslateTopPosition( lMoveDown); 1099 } 1100 } 1101 } 1102 if (aNextPostIt !=aVisiblePostItList.end() && (*aNextPostIt)->IsFollow()) 1103 lSpaceUsed += (*i)->VirtualSize().Height() + ANCHORLINE_WIDTH; 1104 else 1105 lSpaceUsed += (*i)->VirtualSize().Height() + GetSpaceBetween(); 1106 } 1107 else 1108 { 1109 //(*i) is the last visible item 1110 SwSidebarWin_iterator aPrevPostIt = i; 1111 --aPrevPostIt; 1112 //lTranslatePos = ( (*aPrevPostIt)->VirtualPos().Y() + (*aPrevPostIt)->VirtualSize().Height() + GetSpaceBetween() ) - (*i)->VirtualPos().Y(); 1113 lTranslatePos = ( (*aPrevPostIt)->VirtualPos().Y() + (*aPrevPostIt)->VirtualSize().Height() ) - (*i)->VirtualPos().Y(); 1114 if (lTranslatePos > 0) 1115 { 1116 bDone = false; 1117 if ( ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()+lTranslatePos) < lBottomBorder) 1118 { 1119 if ( (*i)->IsFollow() ) 1120 (*i)->TranslateTopPosition(lTranslatePos+ANCHORLINE_WIDTH); 1121 else 1122 (*i)->TranslateTopPosition(lTranslatePos+GetSpaceBetween()); 1123 } 1124 else 1125 { 1126 (*i)->TranslateTopPosition(lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()) ); 1127 } 1128 } 1129 else 1130 { 1131 // note does not overlap, but we might be over the lower border 1132 // only do this if there are no scrollbars, otherwise notes are supposed to overlap the border 1133 if (!bScrollbars && ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height() > lBottomBorder) ) 1134 { 1135 bDone = false; 1136 (*i)->TranslateTopPosition(lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height())); 1137 } 1138 } 1139 } 1140 } 1141 // security check so we don't loop forever 1142 if (loop>MAX_LOOP_COUNT) 1143 { 1144 DBG_ERROR("PostItMgr::Layout(): We are looping forever"); 1145 break; 1146 } 1147 } 1148 } 1149 else 1150 { 1151 // only one left, make sure it is not hidden at the top or bottom 1152 SwSidebarWin_iterator i = aVisiblePostItList.begin(); 1153 lTranslatePos = lTopBorder - (*i)->VirtualPos().Y(); 1154 if (lTranslatePos>0) 1155 { 1156 (*i)->TranslateTopPosition(lTranslatePos+GetSpaceBetween()); 1157 } 1158 lTranslatePos = lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()); 1159 if (lTranslatePos<0) 1160 { 1161 (*i)->TranslateTopPosition(lTranslatePos); 1162 } 1163 } 1164 return bScrollbars; 1165 } 1166 1167 /* 1168 void SwPostItMgr::AddRedlineComments(bool bCheckExistance, bool bFocus) 1169 { 1170 bool bEmpty = mvPostItFlds.empty(); 1171 const SwRedlineTbl& aTable = mpView->GetDocShell()->GetDoc()->GetRedlineTbl(); 1172 for( sal_uInt16 i = 0; i < aTable.Count(); ++i ) 1173 { 1174 SwRedline* pRedline = const_cast<SwRedline*>((aTable)[i]); 1175 if ( pRedline->GetComment() != String(rtl::OUString::createFromAscii("")) ) 1176 InsertItem(pRedline, bCheckExistance, bFocus); 1177 } 1178 if (bEmpty && !mvPostItFlds.empty()) 1179 PrepareView(true); 1180 } 1181 */ 1182 1183 void SwPostItMgr::AddPostIts(bool bCheckExistance, bool bFocus) 1184 { 1185 bool bEmpty = mvPostItFlds.empty(); 1186 SwFieldType* pType = mpView->GetDocShell()->GetDoc()->GetFldType(RES_POSTITFLD, aEmptyStr,false); 1187 SwIterator<SwFmtFld,SwFieldType> aIter( *pType ); 1188 SwFmtFld* pSwFmtFld = aIter.First(); 1189 while(pSwFmtFld) 1190 { 1191 if ( pSwFmtFld->GetTxtFld()) 1192 { 1193 if ( pSwFmtFld->IsFldInDoc() ) 1194 InsertItem(pSwFmtFld,bCheckExistance,bFocus); 1195 } 1196 pSwFmtFld = aIter.Next(); 1197 } 1198 1199 // if we just added the first one we have to update the view for centering 1200 if (bEmpty && !mvPostItFlds.empty()) 1201 PrepareView(true); 1202 } 1203 1204 void SwPostItMgr::RemoveSidebarWin() 1205 { 1206 if (!mvPostItFlds.empty()) 1207 { 1208 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1209 { 1210 EndListening( *((*i)->GetBroadCaster()) ); 1211 if ((*i)->pPostIt) 1212 delete (*i)->pPostIt; 1213 delete (*i); 1214 } 1215 mvPostItFlds.clear(); 1216 } 1217 1218 // all postits removed, no items should be left in pages 1219 PreparePageContainer(); 1220 } 1221 1222 // copy to new vector, otherwise RemoveItem would operate and delete stuff on mvPostItFlds as well 1223 // RemoveItem will clean up the core field and visible postit if neccessary 1224 // we cannot just delete everything as before, as postits could move into change tracking 1225 void SwPostItMgr::Delete(String aAuthor) 1226 { 1227 mpWrtShell->StartAllAction(); 1228 if ( HasActiveSidebarWin() && (GetActiveSidebarWin()->GetAuthor()==aAuthor) ) 1229 { 1230 SetActiveSidebarWin(0); 1231 } 1232 SwRewriter aRewriter; 1233 String aUndoString = SW_RES(STR_DELETE_AUTHOR_NOTES); 1234 aUndoString += aAuthor; 1235 aRewriter.AddRule(UNDO_ARG1, aUndoString); 1236 mpWrtShell->StartUndo( UNDO_DELETE, &aRewriter ); 1237 1238 std::vector<SwFmtFld*> aTmp; 1239 aTmp.reserve( mvPostItFlds.size() ); 1240 for(std::list<SwSidebarItem*>::iterator pPostIt = mvPostItFlds.begin(); pPostIt!= mvPostItFlds.end() ; pPostIt++) 1241 { 1242 if ((*pPostIt)->GetFmtFld() && ((*pPostIt)->pPostIt->GetAuthor() == aAuthor) ) 1243 aTmp.push_back( (*pPostIt)->GetFmtFld() ); 1244 } 1245 for(std::vector<SwFmtFld*>::iterator i = aTmp.begin(); i!= aTmp.end() ; i++) 1246 { 1247 mpWrtShell->GotoField( *(*i) ); 1248 mpWrtShell->DelRight(); 1249 } 1250 mpWrtShell->EndUndo(); 1251 PrepareView(); 1252 mpWrtShell->EndAllAction(); 1253 mbLayout = true; 1254 CalcRects(); 1255 LayoutPostIts(); 1256 } 1257 1258 void SwPostItMgr::Delete() 1259 { 1260 mpWrtShell->StartAllAction(); 1261 SetActiveSidebarWin(0); 1262 SwRewriter aRewriter; 1263 aRewriter.AddRule(UNDO_ARG1, SW_RES(STR_DELETE_ALL_NOTES) ); 1264 mpWrtShell->StartUndo( UNDO_DELETE, &aRewriter ); 1265 1266 std::vector<SwFmtFld*> aTmp; 1267 aTmp.reserve( mvPostItFlds.size() ); 1268 for(std::list<SwSidebarItem*>::iterator pPostIt = mvPostItFlds.begin(); pPostIt!= mvPostItFlds.end() ; pPostIt++) 1269 { 1270 if ((*pPostIt)->GetFmtFld()) 1271 aTmp.push_back( (*pPostIt)->GetFmtFld() ); 1272 } 1273 for(std::vector<SwFmtFld*>::iterator i = aTmp.begin(); i!= aTmp.end() ; i++) 1274 { 1275 mpWrtShell->GotoField( *(*i) ); 1276 mpWrtShell->DelRight(); 1277 } 1278 1279 /* 1280 for(std::list<SwPostItItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1281 { 1282 SwPostItItem* pItem = (*i); 1283 // stop listening, we delete ourselves 1284 EndListening( *(pItem->pFmtFld) ); 1285 // delete the actual SwPostItField 1286 mpWrtShell->GotoField(*pItem->pFmtFld); 1287 mpWrtShell->DelRight(); 1288 // delete visual representation 1289 delete pItem->pPostIt; 1290 // delete struct saving the pointers 1291 delete pItem; 1292 } 1293 mvPostItFlds.clear(); 1294 */ 1295 1296 mpWrtShell->EndUndo(); 1297 PrepareView(); 1298 mpWrtShell->EndAllAction(); 1299 mbLayout = true; 1300 CalcRects(); 1301 LayoutPostIts(); 1302 } 1303 #if 0 1304 void SwPostItMgr::Hide(SwPostItField* pPostItField ) 1305 { 1306 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1307 { 1308 if ((*i)->GetFmtFld()) 1309 { 1310 SwPostItField* pField = static_cast<SwPostItField*>((*i)->GetFmtFld()->GetFld()); 1311 if (pPostItField==pField) 1312 { 1313 (*i)->bShow = false; 1314 (*i)->pPostIt->HideNote(); 1315 break; 1316 } 1317 } 1318 } 1319 1320 LayoutPostIts(); 1321 } 1322 #endif 1323 void SwPostItMgr::Hide( const String& rAuthor ) 1324 { 1325 for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1326 { 1327 if ( (*i)->pPostIt && ((*i)->pPostIt->GetAuthor() == rAuthor) ) 1328 { 1329 (*i)->bShow = false; 1330 (*i)->pPostIt->HideNote(); 1331 } 1332 } 1333 1334 LayoutPostIts(); 1335 } 1336 1337 void SwPostItMgr::Hide() 1338 { 1339 for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1340 { 1341 (*i)->bShow = false; 1342 (*i)->pPostIt->HideNote(); 1343 } 1344 } 1345 1346 1347 void SwPostItMgr::Show() 1348 { 1349 for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1350 { 1351 (*i)->bShow = true; 1352 } 1353 LayoutPostIts(); 1354 } 1355 1356 void SwPostItMgr::Sort(const short aType) 1357 { 1358 if (mvPostItFlds.size()>1 ) 1359 { 1360 switch (aType) 1361 { 1362 case SORT_POS: 1363 mvPostItFlds.sort(comp_pos); 1364 break; 1365 /* 1366 case SORT_AUTHOR: 1367 mvPostItFlds.sort(comp_author); 1368 break; 1369 case SORT_DATE: 1370 mvPostItFlds.sort(comp_date); 1371 break; 1372 */ 1373 } 1374 } 1375 } 1376 1377 SwSidebarWin* SwPostItMgr::GetSidebarWin( const SfxBroadcaster* pBroadcaster) const 1378 { 1379 for(const_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1380 { 1381 if ( (*i)->GetBroadCaster() == pBroadcaster) 1382 return (*i)->pPostIt; 1383 } 1384 return NULL; 1385 } 1386 1387 sw::annotation::SwAnnotationWin* SwPostItMgr::GetAnnotationWin(const SwPostItField* pFld) const 1388 { 1389 for(const_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1390 { 1391 if ( (*i)->GetFmtFld() && ((*i)->GetFmtFld()->GetFld() == pFld)) 1392 return dynamic_cast<sw::annotation::SwAnnotationWin*>((*i)->pPostIt); 1393 } 1394 return NULL; 1395 } 1396 1397 SwSidebarWin* SwPostItMgr::GetNextPostIt( sal_uInt16 aDirection, 1398 SwSidebarWin* aPostIt ) 1399 { 1400 if (mvPostItFlds.size()>1) 1401 { 1402 for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1403 { 1404 if ( (*i)->pPostIt ==aPostIt) 1405 { 1406 SwSidebarItem_iterator iNextPostIt = i; 1407 if (aDirection==KEY_PAGEUP) 1408 { 1409 if ( iNextPostIt==mvPostItFlds.begin() ) 1410 { 1411 return NULL; 1412 } 1413 --iNextPostIt; 1414 } 1415 else 1416 { 1417 iNextPostIt++; 1418 if ( iNextPostIt==mvPostItFlds.end() ) 1419 { 1420 return NULL; 1421 } 1422 } 1423 // lets quit, we are back at the beginng 1424 if ( (*iNextPostIt)->pPostIt==aPostIt) 1425 return NULL; 1426 return (*iNextPostIt)->pPostIt; 1427 } 1428 } 1429 return NULL; 1430 } 1431 else 1432 return NULL; 1433 } 1434 1435 long SwPostItMgr::GetNextBorder() 1436 { 1437 for (unsigned long n=0;n<mPages.size();n++) 1438 { 1439 for(SwSidebarItem_iterator b = mPages[n]->mList->begin(); b!= mPages[n]->mList->end(); b++) 1440 { 1441 if ((*b)->pPostIt == mpActivePostIt) 1442 { 1443 SwSidebarItem_iterator aNext = b; 1444 aNext++; 1445 bool bFollow = (aNext == mPages[n]->mList->end()) ? false : (*aNext)->pPostIt->IsFollow(); 1446 if ( mPages[n]->bScrollbar || bFollow ) 1447 { 1448 return -1; 1449 } 1450 else 1451 { 1452 //if this is the last item, return the bottom border otherwise the next item 1453 if (aNext == mPages[n]->mList->end()) 1454 return mpEditWin->LogicToPixel(Point(0,mPages[n]->mPageRect.Bottom())).Y() - GetSpaceBetween(); 1455 else 1456 return (*aNext)->pPostIt->GetPosPixel().Y() - GetSpaceBetween(); 1457 } 1458 } 1459 } 1460 } 1461 1462 DBG_ERROR("SwPostItMgr::GetNextBorder(): We have to find a next border here"); 1463 return -1; 1464 } 1465 1466 void SwPostItMgr::SetShadowState(const SwPostItField* pFld,bool bCursor) 1467 { 1468 if (pFld) 1469 { 1470 if (pFld !=mShadowState.mpShadowFld) 1471 { 1472 if (mShadowState.mpShadowFld) 1473 { 1474 // reset old one if still alive 1475 // TODO: does not work properly if mouse and cursor was set 1476 sw::annotation::SwAnnotationWin* pOldPostIt = 1477 GetAnnotationWin(mShadowState.mpShadowFld); 1478 if (pOldPostIt && pOldPostIt->Shadow() && (pOldPostIt->Shadow()->GetShadowState() != SS_EDIT)) 1479 pOldPostIt->SetViewState(VS_NORMAL); 1480 } 1481 //set new one, if it is not currently edited 1482 sw::annotation::SwAnnotationWin* pNewPostIt = GetAnnotationWin(pFld); 1483 if (pNewPostIt && pNewPostIt->Shadow() && (pNewPostIt->Shadow()->GetShadowState() != SS_EDIT)) 1484 { 1485 pNewPostIt->SetViewState(VS_VIEW); 1486 //remember our new field 1487 mShadowState.mpShadowFld = pFld; 1488 mShadowState.bCursor = false; 1489 mShadowState.bMouse = false; 1490 } 1491 } 1492 if (bCursor) 1493 mShadowState.bCursor = true; 1494 else 1495 mShadowState.bMouse = true; 1496 } 1497 else 1498 { 1499 if (mShadowState.mpShadowFld) 1500 { 1501 if (bCursor) 1502 mShadowState.bCursor = false; 1503 else 1504 mShadowState.bMouse = false; 1505 if (!mShadowState.bCursor && !mShadowState.bMouse) 1506 { 1507 // reset old one if still alive 1508 sw::annotation::SwAnnotationWin* pOldPostIt = GetAnnotationWin(mShadowState.mpShadowFld); 1509 if (pOldPostIt && pOldPostIt->Shadow() && (pOldPostIt->Shadow()->GetShadowState() != SS_EDIT)) 1510 { 1511 pOldPostIt->SetViewState(VS_NORMAL); 1512 mShadowState.mpShadowFld = 0; 1513 } 1514 } 1515 } 1516 } 1517 } 1518 1519 void SwPostItMgr::PrepareView(bool bIgnoreCount) 1520 { 1521 if (!HasNotes() || bIgnoreCount) 1522 { 1523 mpWrtShell->StartAllAction(); 1524 //mpEditWin->Invalidate(); // really not needed anymore?? 1525 SwRootFrm* pLayout = mpWrtShell->GetLayout(); 1526 if ( pLayout ) 1527 SwPostItHelper::setSidebarChanged( pLayout, 1528 mpWrtShell->getIDocumentSettingAccess()->get( IDocumentSettingAccess::BROWSE_MODE ) ); 1529 mpWrtShell->EndAllAction(); 1530 } 1531 } 1532 1533 bool SwPostItMgr::ShowScrollbar(const unsigned long aPage) const 1534 { 1535 if (mPages.size() > aPage-1) 1536 return (mPages[aPage-1]->bScrollbar && !mbWaitingForCalcRects); 1537 else 1538 return false; 1539 } 1540 1541 bool SwPostItMgr::IsHit(const Point &aPointPixel) 1542 { 1543 if (HasNotes() && ShowNotes()) 1544 { 1545 const Point aPoint = mpEditWin->PixelToLogic(aPointPixel); 1546 const SwRootFrm* pLayout = mpWrtShell->GetLayout(); 1547 SwRect aPageFrm; 1548 const unsigned long nPageNum = SwPostItHelper::getPageInfo( aPageFrm, pLayout, aPoint ); 1549 if( nPageNum ) 1550 { 1551 Rectangle aRect; 1552 DBG_ASSERT(mPages.size()>nPageNum-1,"SwPostitMgr:: page container size wrong"); 1553 aRect = mPages[nPageNum-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT 1554 ? Rectangle(Point(aPageFrm.Left()-GetSidebarWidth()-GetSidebarBorderWidth(),aPageFrm.Top()),Size(GetSidebarWidth(),aPageFrm.Height())) 1555 : Rectangle( Point(aPageFrm.Right()+GetSidebarBorderWidth(),aPageFrm.Top()) , Size(GetSidebarWidth(),aPageFrm.Height())); 1556 if (aRect.IsInside(aPoint)) 1557 { 1558 // we hit the note's sidebar 1559 // lets now test for the arrow area 1560 if (mPages[nPageNum-1]->bScrollbar) 1561 return ScrollbarHit(nPageNum,aPoint); 1562 else 1563 return false; 1564 } 1565 } 1566 } 1567 return false; 1568 } 1569 Rectangle SwPostItMgr::GetBottomScrollRect(const unsigned long aPage) const 1570 { 1571 SwRect aPageRect = mPages[aPage-1]->mPageRect; 1572 Point aPointBottom = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT 1573 ? Point(aPageRect.Left() - GetSidebarWidth() - GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height()) 1574 : Point(aPageRect.Right() + GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height()); 1575 Size aSize(GetSidebarWidth() - mpEditWin->PixelToLogic(Size(4,0)).Width(), mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height()) ; 1576 return Rectangle(aPointBottom,aSize); 1577 1578 } 1579 1580 Rectangle SwPostItMgr::GetTopScrollRect(const unsigned long aPage) const 1581 { 1582 SwRect aPageRect = mPages[aPage-1]->mPageRect; 1583 Point aPointTop = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT 1584 ? Point(aPageRect.Left() - GetSidebarWidth() -GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height()) 1585 : Point(aPageRect.Right() + GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height()); 1586 Size aSize(GetSidebarWidth() - mpEditWin->PixelToLogic(Size(4,0)).Width(), mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height()) ; 1587 return Rectangle(aPointTop,aSize); 1588 } 1589 1590 1591 //IMPORTANT: if you change the rects here, also change SwPageFrm::PaintNotesSidebar() 1592 bool SwPostItMgr::ScrollbarHit(const unsigned long aPage,const Point &aPoint) 1593 { 1594 SwRect aPageRect = mPages[aPage-1]->mPageRect; 1595 Point aPointBottom = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT 1596 ? Point(aPageRect.Left() - GetSidebarWidth()-GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height()) 1597 : Point(aPageRect.Right() + GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height()); 1598 1599 Point aPointTop = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT 1600 ? Point(aPageRect.Left() - GetSidebarWidth()-GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height()) 1601 : Point(aPageRect.Right()+GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height()); 1602 1603 Rectangle aRectBottom(GetBottomScrollRect(aPage)); 1604 Rectangle aRectTop(GetTopScrollRect(aPage)); 1605 1606 if (aRectBottom.IsInside(aPoint)) 1607 { 1608 if (aPoint.X() < long((aPointBottom.X() + GetSidebarWidth()/3))) 1609 Scroll( GetScrollSize(),aPage); 1610 else 1611 Scroll( -1*GetScrollSize(), aPage); 1612 return true; 1613 } 1614 else 1615 if (aRectTop.IsInside(aPoint)) 1616 { 1617 if (aPoint.X() < long((aPointTop.X() + GetSidebarWidth()/3*2))) 1618 Scroll(GetScrollSize(), aPage); 1619 else 1620 Scroll(-1*GetScrollSize(), aPage); 1621 return true; 1622 } 1623 return false; 1624 } 1625 1626 void SwPostItMgr::CorrectPositions() 1627 { 1628 if ( mbWaitingForCalcRects || mbLayouting || mvPostItFlds.empty() ) 1629 return; 1630 1631 // find first valid note 1632 SwSidebarWin *pFirstPostIt = 0; 1633 for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1634 { 1635 pFirstPostIt = (*i)->pPostIt; 1636 if (pFirstPostIt) 1637 break; 1638 } 1639 1640 //if we have not found a valid note, forget about it and leave 1641 if (!pFirstPostIt) 1642 return; 1643 1644 // yeah, I know, if this is a left page it could be wrong, but finding the page and the note is probably not even faster than just doing it 1645 // --> OD 2010-06-03 #i111964# - check, if anchor overlay object exists. 1646 const long aAnchorX = pFirstPostIt->Anchor() 1647 ? mpEditWin->LogicToPixel( Point((long)(pFirstPostIt->Anchor()->GetSixthPosition().getX()),0)).X() 1648 : 0; 1649 const long aAnchorY = pFirstPostIt->Anchor() 1650 ? mpEditWin->LogicToPixel( Point(0,(long)(pFirstPostIt->Anchor()->GetSixthPosition().getY()))).Y() + 1 1651 : 0; 1652 // <-- 1653 if (Point(aAnchorX,aAnchorY) != pFirstPostIt->GetPosPixel()) 1654 { 1655 long aAnchorPosX = 0; 1656 long aAnchorPosY = 0; 1657 for (unsigned long n=0;n<mPages.size();n++) 1658 { 1659 for(SwSidebarItem_iterator i = mPages[n]->mList->begin(); i!= mPages[n]->mList->end(); i++) 1660 { 1661 // --> OD 2010-06-03 #i111964# - check, if anchor overlay object exists. 1662 if ( (*i)->bShow && (*i)->pPostIt && (*i)->pPostIt->Anchor() ) 1663 // <-- 1664 { 1665 aAnchorPosX = mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT 1666 ? mpEditWin->LogicToPixel( Point((long)((*i)->pPostIt->Anchor()->GetSeventhPosition().getX()),0)).X() 1667 : mpEditWin->LogicToPixel( Point((long)((*i)->pPostIt->Anchor()->GetSixthPosition().getX()),0)).X(); 1668 aAnchorPosY = mpEditWin->LogicToPixel( Point(0,(long)((*i)->pPostIt->Anchor()->GetSixthPosition().getY()))).Y() + 1; 1669 (*i)->pPostIt->SetPosPixel(Point(aAnchorPosX,aAnchorPosY)); 1670 } 1671 } 1672 } 1673 } 1674 } 1675 1676 1677 bool SwPostItMgr::ShowNotes() const 1678 { 1679 // we only want to see notes if Options - Writer - View - Notes is ticked 1680 return mpWrtShell->GetViewOptions()->IsPostIts(); 1681 } 1682 1683 bool SwPostItMgr::HasNotes() const 1684 { 1685 return !mvPostItFlds.empty(); 1686 } 1687 1688 unsigned long SwPostItMgr::GetSidebarWidth(bool bPx) const 1689 { 1690 unsigned long aWidth = (unsigned long)(mpWrtShell->GetViewOptions()->GetZoom() * 1.8); 1691 if (bPx) 1692 return aWidth; 1693 else 1694 return mpEditWin->PixelToLogic(Size( aWidth ,0)).Width(); 1695 } 1696 1697 unsigned long SwPostItMgr::GetSidebarBorderWidth(bool bPx) const 1698 { 1699 if (bPx) 1700 return 2; 1701 else 1702 return mpEditWin->PixelToLogic(Size(2,0)).Width(); 1703 } 1704 1705 unsigned long SwPostItMgr::GetNoteWidth() 1706 { 1707 return GetSidebarWidth(true); 1708 } 1709 1710 Color SwPostItMgr::GetColorDark(sal_uInt16 aAuthorIndex) 1711 { 1712 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode()) 1713 { 1714 static const Color aArrayNormal[] = { 1715 COL_AUTHOR1_NORMAL, COL_AUTHOR2_NORMAL, COL_AUTHOR3_NORMAL, 1716 COL_AUTHOR4_NORMAL, COL_AUTHOR5_NORMAL, COL_AUTHOR6_NORMAL, 1717 COL_AUTHOR7_NORMAL, COL_AUTHOR8_NORMAL, COL_AUTHOR9_NORMAL }; 1718 1719 return Color( aArrayNormal[ aAuthorIndex % (sizeof( aArrayNormal )/ sizeof( aArrayNormal[0] ))]); 1720 } 1721 else 1722 return Color(COL_WHITE); 1723 } 1724 1725 Color SwPostItMgr::GetColorLight(sal_uInt16 aAuthorIndex) 1726 { 1727 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode()) 1728 { 1729 static const Color aArrayLight[] = { 1730 COL_AUTHOR1_LIGHT, COL_AUTHOR2_LIGHT, COL_AUTHOR3_LIGHT, 1731 COL_AUTHOR4_LIGHT, COL_AUTHOR5_LIGHT, COL_AUTHOR6_LIGHT, 1732 COL_AUTHOR7_LIGHT, COL_AUTHOR8_LIGHT, COL_AUTHOR9_LIGHT }; 1733 1734 return Color( aArrayLight[ aAuthorIndex % (sizeof( aArrayLight )/ sizeof( aArrayLight[0] ))]); 1735 } 1736 else 1737 return Color(COL_WHITE); 1738 } 1739 1740 Color SwPostItMgr::GetColorAnchor(sal_uInt16 aAuthorIndex) 1741 { 1742 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode()) 1743 { 1744 static const Color aArrayAnchor[] = { 1745 COL_AUTHOR1_DARK, COL_AUTHOR2_DARK, COL_AUTHOR3_DARK, 1746 COL_AUTHOR4_DARK, COL_AUTHOR5_DARK, COL_AUTHOR6_DARK, 1747 COL_AUTHOR7_DARK, COL_AUTHOR8_DARK, COL_AUTHOR9_DARK }; 1748 1749 return Color( aArrayAnchor[ aAuthorIndex % (sizeof( aArrayAnchor ) / sizeof( aArrayAnchor[0] ))]); 1750 } 1751 else 1752 return Color(COL_WHITE); 1753 } 1754 1755 void SwPostItMgr::SetActiveSidebarWin( SwSidebarWin* p) 1756 { 1757 if ( p != mpActivePostIt ) 1758 { 1759 // we need the temp variable so we can set mpActivePostIt before we call DeactivatePostIt 1760 // therefore we get a new layout in DOCCHANGED when switching from postit to document, 1761 // otherwise, GetActivePostIt() would still hold our old postit 1762 SwSidebarWin* pActive = mpActivePostIt; 1763 mpActivePostIt = p; 1764 if (pActive) 1765 { 1766 pActive->DeactivatePostIt(); 1767 mShadowState.mpShadowFld = 0; 1768 } 1769 if (mpActivePostIt) 1770 { 1771 mpActivePostIt->GotoPos(); 1772 mpView->AttrChangedNotify(0); 1773 mpActivePostIt->ActivatePostIt(); 1774 } 1775 } 1776 } 1777 1778 IMPL_LINK( SwPostItMgr, CalcHdl, void*, /* pVoid*/ ) 1779 { 1780 mnEventId = 0; 1781 if ( mbLayouting ) 1782 { 1783 DBG_ERROR("Reentrance problem in Layout Manager!"); 1784 mbWaitingForCalcRects = false; 1785 return 0; 1786 } 1787 1788 // do not change order, even if it would seem so in the first place, we need the calcrects always 1789 if (CalcRects() || mbLayout) 1790 { 1791 mbLayout = false; 1792 LayoutPostIts(); 1793 } 1794 return 0; 1795 } 1796 1797 void SwPostItMgr::Rescale() 1798 { 1799 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1800 if ( (*i)->pPostIt ) 1801 (*i)->pPostIt->Rescale(); 1802 } 1803 1804 sal_Int32 SwPostItMgr::GetInitialAnchorDistance() const 1805 { 1806 const Fraction& f( mpEditWin->GetMapMode().GetScaleY() ); 1807 return POSTIT_INITIAL_ANCHOR_DISTANCE * f.GetNumerator() / f.GetDenominator(); 1808 } 1809 1810 sal_Int32 SwPostItMgr::GetSpaceBetween() const 1811 { 1812 const Fraction& f( mpEditWin->GetMapMode().GetScaleY() ); 1813 return ( POSTIT_SPACE_BETWEEN ) * f.GetNumerator() / f.GetDenominator(); 1814 } 1815 1816 sal_Int32 SwPostItMgr::GetScrollSize() const 1817 { 1818 const Fraction& f( mpEditWin->GetMapMode().GetScaleY() ); 1819 return ( POSTIT_SPACE_BETWEEN + POSTIT_MINIMUMSIZE_WITH_META ) * f.GetNumerator() / f.GetDenominator(); 1820 } 1821 1822 sal_Int32 SwPostItMgr::GetMinimumSizeWithMeta() const 1823 { 1824 const Fraction& f( mpEditWin->GetMapMode().GetScaleY() ); 1825 return POSTIT_MINIMUMSIZE_WITH_META * f.GetNumerator() / f.GetDenominator(); 1826 } 1827 1828 sal_Int32 SwPostItMgr::GetSidebarScrollerHeight() const 1829 { 1830 const Fraction& f( mpEditWin->GetMapMode().GetScaleY() ); 1831 return POSTIT_SCROLL_SIDEBAR_HEIGHT * f.GetNumerator() / f.GetDenominator(); 1832 } 1833 1834 void SwPostItMgr::SetSpellChecking() 1835 { 1836 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1837 if ( (*i)->pPostIt ) 1838 (*i)->pPostIt->SetSpellChecking(); 1839 } 1840 1841 void SwPostItMgr::SetReadOnlyState() 1842 { 1843 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1844 if ( (*i)->pPostIt ) 1845 (*i)->pPostIt->SetReadonly( mbReadOnly ); 1846 } 1847 1848 void SwPostItMgr::CheckMetaText() 1849 { 1850 for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++) 1851 if ( (*i)->pPostIt ) 1852 (*i)->pPostIt->CheckMetaText(); 1853 1854 } 1855 1856 sal_uInt16 SwPostItMgr::Replace(SvxSearchItem* pItem) 1857 { 1858 SwSidebarWin* pWin = GetActiveSidebarWin(); 1859 sal_uInt16 aResult = pWin->GetOutlinerView()->StartSearchAndReplace( *pItem ); 1860 if (!aResult) 1861 SetActiveSidebarWin(0); 1862 return aResult; 1863 } 1864 1865 sal_uInt16 SwPostItMgr::FinishSearchReplace(const ::com::sun::star::util::SearchOptions& rSearchOptions, bool bSrchForward) 1866 { 1867 SwSidebarWin* pWin = GetActiveSidebarWin(); 1868 SvxSearchItem aItem(SID_SEARCH_ITEM ); 1869 aItem.SetSearchOptions(rSearchOptions); 1870 aItem.SetBackward(!bSrchForward); 1871 sal_uInt16 aResult = pWin->GetOutlinerView()->StartSearchAndReplace( aItem ); 1872 if (!aResult) 1873 SetActiveSidebarWin(0); 1874 return aResult; 1875 } 1876 1877 sal_uInt16 SwPostItMgr::SearchReplace(const SwFmtFld &pFld, const ::com::sun::star::util::SearchOptions& rSearchOptions, bool bSrchForward) 1878 { 1879 sal_uInt16 aResult = 0; 1880 SwSidebarWin* pWin = GetSidebarWin(&pFld); 1881 if (pWin) 1882 { 1883 ESelection aOldSelection = pWin->GetOutlinerView()->GetSelection(); 1884 if (bSrchForward) 1885 pWin->GetOutlinerView()->SetSelection(ESelection(0,0,0,0)); 1886 else 1887 pWin->GetOutlinerView()->SetSelection(ESelection(0xFFFF,0xFFFF,0xFFFF,0xFFFF)); 1888 SvxSearchItem aItem(SID_SEARCH_ITEM ); 1889 aItem.SetSearchOptions(rSearchOptions); 1890 aItem.SetBackward(!bSrchForward); 1891 aResult = pWin->GetOutlinerView()->StartSearchAndReplace( aItem ); 1892 if (!aResult) 1893 pWin->GetOutlinerView()->SetSelection(aOldSelection); 1894 else 1895 { 1896 SetActiveSidebarWin(pWin); 1897 MakeVisible(pWin); 1898 } 1899 } 1900 return aResult; 1901 } 1902 1903 void SwPostItMgr::AssureStdModeAtShell() 1904 { 1905 //#i103373# #i103645# 1906 // deselect any drawing or frame and leave editing mode 1907 SdrView* pSdrView = mpWrtShell->GetDrawView(); 1908 if ( pSdrView && pSdrView->IsTextEdit() ) 1909 { 1910 sal_Bool bLockView = mpWrtShell->IsViewLocked(); 1911 mpWrtShell->LockView( sal_True ); 1912 mpWrtShell->EndTextEdit(); 1913 mpWrtShell->LockView( bLockView ); 1914 } 1915 1916 if( mpWrtShell->IsSelFrmMode() || mpWrtShell->IsObjSelected()) 1917 { 1918 mpWrtShell->UnSelectFrm(); 1919 mpWrtShell->LeaveSelFrmMode(); 1920 mpWrtShell->GetView().LeaveDrawCreate(); 1921 mpWrtShell->EnterStdMode(); 1922 1923 mpWrtShell->DrawSelChanged(); 1924 mpView->StopShellTimer(); 1925 } 1926 } 1927 1928 bool SwPostItMgr::HasActiveSidebarWin() const 1929 { 1930 return mpActivePostIt != 0; 1931 } 1932 1933 bool SwPostItMgr::HasActiveAnnotationWin() const 1934 { 1935 return HasActiveSidebarWin() && 1936 dynamic_cast<sw::annotation::SwAnnotationWin*>(mpActivePostIt) != 0; 1937 } 1938 1939 void SwPostItMgr::GrabFocusOnActiveSidebarWin() 1940 { 1941 if ( HasActiveSidebarWin() ) 1942 { 1943 mpActivePostIt->GrabFocus(); 1944 } 1945 } 1946 1947 void SwPostItMgr::UpdateDataOnActiveSidebarWin() 1948 { 1949 if ( HasActiveSidebarWin() ) 1950 { 1951 mpActivePostIt->UpdateData(); 1952 } 1953 } 1954 1955 void SwPostItMgr::DeleteActiveSidebarWin() 1956 { 1957 if ( HasActiveSidebarWin() ) 1958 { 1959 mpActivePostIt->Delete(); 1960 } 1961 } 1962 1963 void SwPostItMgr::HideActiveSidebarWin() 1964 { 1965 if ( HasActiveSidebarWin() ) 1966 { 1967 mpActivePostIt->Hide(); 1968 } 1969 } 1970 1971 void SwPostItMgr::ToggleInsModeOnActiveSidebarWin() 1972 { 1973 if ( HasActiveSidebarWin() ) 1974 { 1975 mpActivePostIt->ToggleInsMode(); 1976 } 1977 } 1978 1979 void SwPostItMgr::ConnectSidebarWinToFrm( const SwFrm& rFrm, 1980 const SwFmtFld& rFmtFld, 1981 SwSidebarWin& rSidebarWin ) 1982 { 1983 if ( mpFrmSidebarWinContainer == 0 ) 1984 { 1985 mpFrmSidebarWinContainer = new SwFrmSidebarWinContainer(); 1986 } 1987 1988 const bool bInserted = mpFrmSidebarWinContainer->insert( rFrm, rFmtFld, rSidebarWin ); 1989 if ( bInserted && 1990 mpWrtShell->GetAccessibleMap() ) 1991 { 1992 mpWrtShell->GetAccessibleMap()->InvalidatePosOrSize( 0, 0, &rSidebarWin, SwRect() ); 1993 } 1994 } 1995 1996 void SwPostItMgr::DisconnectSidebarWinFromFrm( const SwFrm& rFrm, 1997 SwSidebarWin& rSidebarWin ) 1998 { 1999 if ( mpFrmSidebarWinContainer != 0 ) 2000 { 2001 const bool bRemoved = mpFrmSidebarWinContainer->remove( rFrm, rSidebarWin ); 2002 if ( bRemoved && 2003 mpWrtShell->GetAccessibleMap() ) 2004 { 2005 mpWrtShell->GetAccessibleMap()->Dispose( 0, 0, &rSidebarWin ); 2006 } 2007 } 2008 } 2009 2010 bool SwPostItMgr::HasFrmConnectedSidebarWins( const SwFrm& rFrm ) 2011 { 2012 bool bRet( false ); 2013 2014 if ( mpFrmSidebarWinContainer != 0 ) 2015 { 2016 bRet = !mpFrmSidebarWinContainer->empty( rFrm ); 2017 } 2018 2019 return bRet; 2020 } 2021 2022 Window* SwPostItMgr::GetSidebarWinForFrmByIndex( const SwFrm& rFrm, 2023 const sal_Int32 nIndex ) 2024 { 2025 Window* pSidebarWin( 0 ); 2026 2027 if ( mpFrmSidebarWinContainer != 0 ) 2028 { 2029 pSidebarWin = mpFrmSidebarWinContainer->get( rFrm, nIndex ); 2030 } 2031 2032 return pSidebarWin; 2033 } 2034 2035 void SwPostItMgr::GetAllSidebarWinForFrm( const SwFrm& rFrm, 2036 std::vector< Window* >* pChildren ) 2037 { 2038 if ( mpFrmSidebarWinContainer != 0 ) 2039 { 2040 mpFrmSidebarWinContainer->getAll( rFrm, pChildren ); 2041 } 2042 } 2043 2044 void SwNoteProps::Commit() {} 2045 void SwNoteProps::Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& ) {} 2046