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