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