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