update dev300-m58
[ooovba.git] / sw / source / ui / docvw / PostItMgr.cxx
blob1e5eb8788b57b2d3a910076d4da011e8bf6934c3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PostItMgr.cxx,v $
11 * $Revision: 1.12.34.10 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_sw.hxx"
35 #include "PostItMgr.hxx"
36 #include <postithelper.hxx>
38 #include <vcl/svapp.hxx>
39 #include <vcl/scrbar.hxx>
40 #include <vcl/outdev.hxx>
42 #include <viewopt.hxx>
44 #include <view.hxx>
45 #include <docsh.hxx>
46 #include <wrtsh.hxx>
47 #include <doc.hxx>
48 #include <fldbas.hxx>
49 #include <fmtfld.hxx>
50 #include <docufld.hxx>
51 #include <edtwin.hxx>
52 #include <postit.hxx>
53 #include <txtfld.hxx>
54 #include <ndtxt.hxx>
55 #include <redline.hxx>
56 #include <docary.hxx>
57 #include <SwRewriter.hxx>
58 #include <undobj.hxx>
59 #include <tools/color.hxx>
61 #include <swmodule.hxx>
62 #include <docvw.hrc>
63 #include "cmdid.h"
65 #include <SwRewriter.hxx>
66 #include <undobj.hxx>
68 #include <sfx2/request.hxx>
69 #include <sfx2/event.hxx>
70 #include <sfx2/srchitem.hxx>
73 #include <svtools/languageoptions.hxx>
74 #include <svtools/langtab.hxx>
75 #include <svtools/smplhint.hxx>
77 #include <svx/eeitem.hxx>
78 #include <svx/langitem.hxx>
79 #include <svx/outliner.hxx>
81 #include <i18npool/mslangid.hxx>
82 #include <i18npool/lang.h>
84 #include "swevent.hxx"
86 // distance between ankor Y and initial note position
87 #define POSTIT_INITIAL_ANKOR_DISTANCE 20
88 //distance between two postits
89 #define POSTIT_SPACE_BETWEEN 8
90 #define POSTIT_MINIMUMSIZE_WITH_META 60
91 #define POSTIT_SCROLL_SIDEBAR_HEIGHT 20
93 // if we layout more often we stop, this should never happen
94 #define MAX_LOOP_COUNT 50
97 bool comp_author( const SwPostItItem* a, const SwPostItItem* b)
99 return a->pFmtFld->GetFld()->GetPar1() < b->pFmtFld->GetFld()->GetPar1();
102 bool comp_date( const SwPostItItem* a, const SwPostItItem* b)
104 return static_cast<SwPostItField*>(a->pFmtFld->GetFld())->GetDate() < static_cast<SwPostItField*>(b->pFmtFld->GetFld())->GetDate();
108 // if position is on the same line, sort by x (Left) position, otherwise by y(Bottom) position
109 // if two notes are at the same position, sort by logical node position
110 bool comp_pos(const SwMarginItem *a, const SwMarginItem *b)
112 return (a->mPos.Bottom() == b->mPos.Bottom()) ?
113 ( ((a->mPos.Left() == b->mPos.Left()) && (a->GetBroadCaster()->ISA(SwFmtFld) && b->GetBroadCaster()->ISA(SwFmtFld)) ) ?
114 *(static_cast<SwFmtFld*>(a->GetBroadCaster())->GetTxtFld()->GetStart()) <
115 *(static_cast<SwFmtFld*>(b->GetBroadCaster())->GetTxtFld()->GetStart())
116 : a->mPos.Left() < b->mPos.Left() )
117 : a->mPos.Bottom() < b->mPos.Bottom();
120 SwPostItMgr::SwPostItMgr(SwView* pView)
121 : mpView(pView)
122 , mpWrtShell(mpView->GetDocShell()->GetWrtShell())
123 , mpEditWin(&mpView->GetEditWin())
124 , mnEventId(0)
125 , mbWaitingForCalcRects(false)
126 , mpActivePostIt(0)
127 , mbLayout(false)
128 , mbLayoutHeight(0)
129 , mbLayouting(false)
130 , mbReadOnly(mpView->GetDocShell()->IsReadOnly())
131 , mbDeleteNote(true)
132 , mpAnswer(0)
134 if(!mpView->GetDrawView() )
135 mpView->GetWrtShell().MakeDrawView();
137 SwNoteProps aProps;
138 mpIsShowAnkor = aProps.IsShowAnkor();
140 //make sure we get the colour yellow always, even if not the first one of comments or redlining
141 SW_MOD()->GetRedlineAuthor();
143 // collect all PostIts and redline comments that exist after loading the document
144 // don't check for existance for any of them, don't focus them
145 AddPostIts(false,false);
146 /* this code can be used once we want redline comments in the margin
147 AddRedlineComments(false,false);
149 // we want to receive stuff like SFX_HINT_DOCCHANGED
150 StartListening(*mpView->GetDocShell());
151 if (!mvPostItFlds.empty())
153 mbWaitingForCalcRects = true;
154 mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 );
158 SwPostItMgr::~SwPostItMgr()
160 if ( mnEventId )
161 Application::RemoveUserEvent( mnEventId );
162 // forget about all our margin windows
163 RemoveMarginWin();
164 EndListening( *mpView->GetDocShell() );
166 for(std::vector<SwPostItPageItem*>::iterator i = mPages.begin(); i!= mPages.end() ; i++)
167 delete (*i);
168 mPages.clear();
171 void SwPostItMgr::CheckForRemovedPostIts()
173 bool bRemoved = false;
174 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end(); )
176 std::list<SwMarginItem*>::iterator it = i++;
177 if ( !(*it)->UseElement() )
179 SwMarginItem* p = (*it);
180 mvPostItFlds.remove(*it);
181 if (GetActivePostIt() == p->pPostIt)
182 SetActivePostIt(0);
183 if (p->pPostIt)
184 delete p->pPostIt;
185 delete p;
186 bRemoved = true;
190 if ( bRemoved )
192 // make sure that no deleted items remain in page lists
193 // todo: only remove deleted ones?!
194 if ( mvPostItFlds.empty() )
196 PreparePageContainer();
197 PrepareView();
199 else
200 // if postits are their make sure that page lists are not empty
201 // otherwise sudden paints can cause pain (in BorderOverPageBorder)
202 CalcRects();
206 void SwPostItMgr::InsertItem(SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus)
208 if (bCheckExistance)
210 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
212 if ( (*i)->GetBroadCaster() == pItem )
213 return;
216 mbLayout = bFocus;
217 if (pItem->ISA(SwFmtFld))
218 mvPostItFlds.push_back(new SwPostItItem(static_cast<SwFmtFld*>(pItem), true, bFocus) );
220 else
221 if (pItem->ISA(SwRedline))
222 mvPostItFlds.push_back(new SwRedCommentItem( static_cast<SwRedline*>(pItem), true, bFocus)) ;
224 DBG_ASSERT(pItem->ISA(SwFmtFld) /*|| pItem->ISA(SwRedline)*/,"Mgr::InsertItem: seems like new stuff was added");
225 StartListening(*pItem);
228 void SwPostItMgr::RemoveItem( SfxBroadcaster* pBroadcast )
230 EndListening(*pBroadcast);
231 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
233 if ( (*i)->GetBroadCaster() == pBroadcast )
235 SwMarginItem* p = (*i);
236 if (GetActivePostIt() == p->pPostIt)
237 SetActivePostIt(0);
238 mvPostItFlds.remove(*i);
239 delete p->pPostIt;
240 delete p;
241 break;
244 mbLayout = true;
245 PrepareView();
248 void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
250 if ( rHint.IsA(TYPE(SfxEventHint) ) )
252 sal_uInt32 nId = ((SfxEventHint&)rHint).GetEventId();
253 if ( nId == SW_EVENT_LAYOUT_FINISHED )
255 if ( !mbWaitingForCalcRects && !mvPostItFlds.empty())
257 mbWaitingForCalcRects = true;
258 mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 );
262 else if ( rHint.IsA(TYPE(SfxSimpleHint) ) )
264 sal_uInt32 nId = ((SfxSimpleHint&)rHint).GetId();
265 switch ( nId )
267 case SFX_HINT_MODECHANGED:
269 if ( mbReadOnly != !!(mpView->GetDocShell()->IsReadOnly()) )
271 mbReadOnly = !mbReadOnly;
272 SetReadOnlyState();
273 mbLayout = true;
275 break;
277 case SFX_HINT_DOCCHANGED:
279 if ( mpView->GetDocShell() == &rBC )
281 if ( !mbWaitingForCalcRects && !mvPostItFlds.empty())
283 mbWaitingForCalcRects = true;
284 mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 );
287 break;
289 case SFX_HINT_USER04:
291 // if we are in a SplitNode/Cut operation, do not delete note and then add again, as this will flicker
292 mbDeleteNote = !mbDeleteNote;
293 break;
295 case SFX_HINT_DYING:
297 if ( mpView->GetDocShell() != &rBC )
299 // field to be removed is the broadcaster
300 DBG_ERROR("Notification for removed SwFmtFld was not sent!");
301 RemoveItem(&rBC);
303 break;
308 else if ( rHint.IsA(TYPE(SwRedlineHint) ) )
310 SwRedline* pRedline = const_cast<SwRedline*>(((SwRedlineHint&)rHint).GetRedline());
311 switch ( ((SwRedlineHint&)rHint).Which() )
313 case SWREDLINE_INSERTED :
315 bool bEmpty = !HasNotes();
316 InsertItem( pRedline, true, false );
317 if (bEmpty && !mvPostItFlds.empty())
318 PrepareView(true);
319 break;
321 case SWREDLINE_REMOVED:
323 RemoveItem(pRedline);
324 break;
326 case SWREDLINE_FOCUS:
328 Focus(rBC);
329 break;
334 else if ( rHint.IsA(TYPE(SwFmtFldHint) ) )
336 SwFmtFld* pFld = const_cast <SwFmtFld*>( ((SwFmtFldHint&)rHint).GetField() );
337 switch ( ((SwFmtFldHint&)rHint).Which() )
339 case SWFMTFLD_INSERTED :
341 if (!pFld)
343 AddPostIts(true);
344 break;
346 // get field to be inserted from hint
347 if ( pFld->IsFldInDoc() )
349 bool bEmpty = !HasNotes();
350 InsertItem( pFld, true, false );
351 if (bEmpty && !mvPostItFlds.empty())
352 PrepareView(true);
354 else {
355 DBG_ERROR( "Inserted field not in document!" );
357 break;
359 case SWFMTFLD_REMOVED:
361 if (mbDeleteNote)
363 if (!pFld)
365 CheckForRemovedPostIts();
366 break;
368 RemoveItem(pFld);
370 break;
372 case SWFMTFLD_FOCUS:
374 Focus(rBC);
375 break;
377 case SWFMTFLD_CHANGED:
379 SwFmtFld* pFmtFld = dynamic_cast<SwFmtFld*>(&rBC);
380 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
382 if ( pFmtFld == (*i)->GetBroadCaster() )
384 if ((*i)->pPostIt)
385 (*i)->pPostIt->SetPostItText();
386 break;
389 break;
391 case SWFMTFLD_LANGUAGE:
393 SwFmtFld* pFmtFld = dynamic_cast<SwFmtFld*>(&rBC);
394 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
396 if ( pFmtFld == (*i)->GetBroadCaster() )
398 if ((*i)->pPostIt)
400 USHORT nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( (*i)->GetFmtFld()->GetFld()->GetLanguage() );
401 USHORT nLangWhichId = 0;
402 switch (nScriptType)
404 case SCRIPTTYPE_LATIN : nLangWhichId = EE_CHAR_LANGUAGE ; break;
405 case SCRIPTTYPE_ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
406 case SCRIPTTYPE_COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
408 (*i)->pPostIt->SetLanguage(SvxLanguageItem((*i)->GetFmtFld()->GetFld()->GetLanguage(),nLangWhichId));
410 break;
413 break;
419 void SwPostItMgr::Focus(SfxBroadcaster& rBC)
421 if (!mpWrtShell->GetViewOptions()->IsPostIts())
423 SfxRequest aRequest(mpView->GetViewFrame(),FN_VIEW_NOTES);
424 mpView->ExecViewOptions(aRequest);
427 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
429 // field to get the focus is the broadcaster
430 if ( &rBC == (*i)->GetBroadCaster() )
432 if ((*i)->pPostIt)
434 (*i)->pPostIt->GrabFocus();
435 MakeVisible((*i)->pPostIt);
437 else
439 // when the layout algorithm starts, this postit is created and receives focus
440 (*i)->bFocus = true;
446 bool SwPostItMgr::CalcRects()
448 if ( mnEventId )
450 // if CalcRects() was forced and an event is still pending: remove it
451 // it is superfluous and also may cause reentrance problems if triggered while layouting
452 Application::RemoveUserEvent( mnEventId );
453 mnEventId = 0;
456 bool bChange = false;
457 bool bRepair = false;
458 PreparePageContainer();
459 if ( !mvPostItFlds.empty() )
461 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
463 SwMarginItem* pItem = (*i);
464 if ( !pItem->UseElement() )
466 DBG_ERROR("PostIt is not in doc or other wrong use");
467 bRepair = true;
468 continue;
471 //save old rect and visible state
472 SwRect aOldRect(pItem->mPos);
473 SwPostItHelper::SwLayoutStatus eOldStatus = pItem->mLayoutStatus;
474 std::vector< SwLayoutInfo > aInfo;
475 SwPosition aPosition = pItem->GetPosition();
476 pItem->mLayoutStatus = SwPostItHelper::getLayoutInfos( aInfo, aPosition );
477 if( aInfo.size() )
479 SwLayoutInfo& rInfo = aInfo[0];
480 pItem->mPos = rInfo.mPosition;
481 pItem->mPagePos = rInfo.mPageFrame;
482 pItem->mFramePos = rInfo.mPagePrtArea;
483 pItem->bMarginSide = rInfo.mbMarginSide;
484 pItem->mnPageNumber = rInfo.mnPageNumber;
485 pItem->mRedlineAuthor = rInfo.mRedlineAuthor;
487 bChange = bChange || (pItem->mPos != aOldRect) || (eOldStatus != pItem->mLayoutStatus);
490 // show notes in right order in navigator
491 //prevent ankors during layout to overlap, e.g. when moving a frame
492 Sort(SORT_POS);
494 // sort the items into the right page vector, so layout can be done by page
495 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
497 SwMarginItem* pItem = (*i);
498 if( SwPostItHelper::INVISIBLE == pItem->mLayoutStatus )
500 if (pItem->pPostIt)
501 pItem->pPostIt->HideNote();
502 continue;
505 if( SwPostItHelper::HIDDEN == pItem->mLayoutStatus )
507 if (!mpWrtShell->GetViewOptions()->IsShowHiddenChar())
509 if (pItem->pPostIt)
510 pItem->pPostIt->HideNote();
511 continue;
515 const unsigned long aPageNum = pItem->mnPageNumber;
516 if (aPageNum > mPages.size())
518 const unsigned long nNumberOfPages = mPages.size();
519 for (unsigned int j=0; j<aPageNum - nNumberOfPages; ++j)
520 mPages.push_back( new SwPostItPageItem());
522 mPages[aPageNum-1]->mList->push_back(pItem);
523 mPages[aPageNum-1]->mPageRect = pItem->mPagePos;
524 mPages[aPageNum-1]->bMarginSide = pItem->bMarginSide;
527 if (!bChange && mpWrtShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE))
529 long nLayoutHeight = SwPostItHelper::getLayoutHeight( mpWrtShell->GetLayout() );
530 if( nLayoutHeight > mbLayoutHeight )
532 if (mPages[0]->bScrollbar || HasScrollbars())
533 bChange = true;
535 else if( nLayoutHeight < mbLayoutHeight )
537 if (mPages[0]->bScrollbar || !BorderOverPageBorder(1))
538 bChange = true;
543 if ( bRepair )
544 CheckForRemovedPostIts();
546 mbLayoutHeight = SwPostItHelper::getLayoutHeight( mpWrtShell->GetLayout() );
547 mbWaitingForCalcRects = false;
548 return bChange;
551 bool SwPostItMgr::HasScrollbars() const
553 for(std::list<SwMarginItem*>::const_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
555 if ((*i)->bShow && (*i)->pPostIt && (*i)->pPostIt->Scrollbar())
556 return true;
558 return false;
561 void SwPostItMgr::PreparePageContainer()
563 // we do not just delete the SwPostItPageItem, so offset/scrollbar is not lost
564 long lPageSize = mpWrtShell->GetNumPages();
565 long lContainerSize = mPages.size();
567 if (lContainerSize < lPageSize)
569 for (int i=0; i<lPageSize - lContainerSize;i++)
570 mPages.push_back( new SwPostItPageItem());
572 else
573 if (lContainerSize > lPageSize)
575 for (int i=mPages.size()-1; i >= lPageSize;--i)
577 delete mPages[i];
578 mPages.pop_back();
581 // only clear the list, DO NOT delete the objects itself
582 for(std::vector<SwPostItPageItem*>::iterator i = mPages.begin(); i!= mPages.end() ; i++)
584 (*i)->mList->clear();
585 if (mvPostItFlds.empty())
586 (*i)->bScrollbar = false;
591 void SwPostItMgr::LayoutPostIts()
593 if ( !mvPostItFlds.empty() && !mbWaitingForCalcRects )
595 mbLayouting = true;
597 //loop over all pages and do the layout
598 // - create SwPostIt if neccessary
599 // - place SwPostIts on their initial position
600 // - calculate neccessary height for all PostIts together
601 bool bUpdate = false;
602 for (unsigned long n=0;n<mPages.size();n++)
604 // only layout if there are notes on this page
605 if (mPages[n]->mList->size()>0)
607 std::list<SwMarginWin*> aVisiblePostItList;
608 unsigned long lNeededHeight = 0;
609 long mlPageBorder = 0;
610 long mlPageEnd = 0;
612 for(SwMarginItem_iterator i = mPages[n]->mList->begin(); i!= mPages[n]->mList->end(); i++)
614 SwMarginItem* pItem = (*i);
615 SwMarginWin* pPostIt = pItem->pPostIt;
617 if (mPages[n]->bMarginSide)
619 // x value for notes positioning
620 mlPageBorder = mpEditWin->LogicToPixel( Point( mPages[n]->mPageRect.Left(), 0)).X() - GetSidebarWidth(true);// - GetSidebarBorderWidth(true);
621 //bending point
622 mlPageEnd = mpWrtShell->getIDocumentSettingAccess()->get( IDocumentSettingAccess::BROWSE_MODE) ? pItem->mFramePos.Left() : mPages[n]->mPageRect.Left() + 350;
624 else
626 // x value for notes positioning
627 mlPageBorder = mpEditWin->LogicToPixel( Point(mPages[n]->mPageRect.Right(), 0)).X() + GetSidebarBorderWidth(true);
628 //bending point
629 mlPageEnd = mpWrtShell->getIDocumentSettingAccess()->get( IDocumentSettingAccess::BROWSE_MODE) ? pItem->mFramePos.Right() : mPages[n]->mPageRect.Right() - 350;
632 if (pItem->bShow)
634 long Y = mpEditWin->LogicToPixel( Point(0,pItem->mPos.Bottom())).Y();
635 long aPostItHeight = 0;
636 if (!pPostIt)
638 pPostIt = (*i)->GetMarginWindow(static_cast<Window*>(&mpView->GetEditWin()),WINDOW_CONTROL|WB_NODIALOGCONTROL,this,0);
639 pPostIt->InitControls();
640 pPostIt->SetReadonly(mbReadOnly);
641 pItem->pPostIt = pPostIt;
642 if (mpAnswer)
644 if (pPostIt->CalcFollow()) //do we really have another note in front of this one
645 static_cast<SwPostIt*>(pPostIt)->InitAnswer(mpAnswer);
646 delete mpAnswer;
647 mpAnswer = 0;
651 if (pItem->pPostIt->ISA(SwPostIt))
653 static_cast<SwPostIt*>(pPostIt)->SetChangeTracking(pItem->mLayoutStatus,GetColorAnkor(pItem->mRedlineAuthor));
655 pPostIt->SetMarginSide(mPages[n]->bMarginSide);
656 pPostIt->SetFollow(pPostIt->CalcFollow());
657 aPostItHeight = ( pPostIt->GetPostItTextHeight() < pPostIt->GetMinimumSizeWithoutMeta() ? pPostIt->GetMinimumSizeWithoutMeta() : pPostIt->GetPostItTextHeight() ) + pPostIt->GetMetaHeight();
658 pPostIt->SetPosSizePixelRect( mlPageBorder ,Y-GetInitialAnchorDistance(), GetNoteWidth() ,aPostItHeight,pItem->mPos, mlPageEnd);
660 if (pItem->bFocus)
662 mbLayout = true;
663 pPostIt->GrabFocus();
664 pItem->bFocus = false;
666 // only the visible postits are used for the final layout
667 aVisiblePostItList.push_back(pPostIt);
668 lNeededHeight += pPostIt->IsFollow() ? aPostItHeight : aPostItHeight+GetSpaceBetween();
670 else // we don't want to see it
672 if (pPostIt)
673 pPostIt->HideNote();
677 if ((aVisiblePostItList.size()>0) && ShowNotes())
679 bool bOldScrollbar = mPages[n]->bScrollbar;
680 if (ShowNotes())
681 mPages[n]->bScrollbar = LayoutByPage(aVisiblePostItList, mPages[n]->mPageRect.SVRect(), lNeededHeight);
682 else
683 mPages[n]->bScrollbar = false;
684 if (!mPages[n]->bScrollbar)
686 mPages[n]->lOffset = 0;
688 else
690 //when we changed our zoom level, the offset value can be to big, so lets check for the largest possible zoom value
691 long aAvailableHeight = mpEditWin->LogicToPixel(Size(0,mPages[n]->mPageRect.Height())).Height() - 2 * GetSidebarScrollerHeight();
692 long lOffset = -1 * GetScrollSize() * (aVisiblePostItList.size() - aAvailableHeight / GetScrollSize());
693 if (mPages[n]->lOffset < lOffset)
694 mPages[n]->lOffset = lOffset;
696 bUpdate = (bOldScrollbar != mPages[n]->bScrollbar) || bUpdate;
697 const long aSidebarheight = mPages[n]->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0;
699 TODO
700 - enlarge all notes till GetNextBorder(), as we resized to average value before
702 //lets hide the ones which overlap the page
703 for(SwMarginWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++)
705 if (mPages[n]->lOffset != 0)
706 (*i)->TranslateTopPosition(mPages[n]->lOffset);
708 bool bBottom = mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y()+(*i)->VirtualSize().Height())).Y() <= (mPages[n]->mPageRect.Bottom()-aSidebarheight);
709 bool bTop = mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y())).Y() >= (mPages[n]->mPageRect.Top()+aSidebarheight);
710 if ( bBottom && bTop )
712 (*i)->ShowNote();
714 else
716 if (mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y())).Y() < (mPages[n]->mPageRect.Top()+aSidebarheight))
718 if (mPages[n]->bMarginSide)
719 (*i)->ShowAnkorOnly(Point(mPages[n]->mPageRect.Left(),mPages[n]->mPageRect.Top()));
720 else
721 (*i)->ShowAnkorOnly(Point(mPages[n]->mPageRect.Right(),mPages[n]->mPageRect.Top()));
723 else
725 if (mPages[n]->bMarginSide)
726 (*i)->ShowAnkorOnly(Point(mPages[n]->mPageRect.Left(),mPages[n]->mPageRect.Bottom()));
727 else
728 (*i)->ShowAnkorOnly(Point(mPages[n]->mPageRect.Right(),mPages[n]->mPageRect.Bottom()));
730 DBG_ASSERT(mPages[n]->bScrollbar,"SwPostItMgr::LayoutByPage(): note overlaps, but bScrollbar is not true");
734 // do some magic so we really see the focused note
735 for(SwMarginWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++)
737 if ((*i)->HasChildPathFocus())
739 MakeVisible((*i),n+1);
740 break;
744 else
746 for(SwMarginWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++)
747 (*i)->SetPosAndSize();
749 bool bOldScrollbar = mPages[n]->bScrollbar;
750 mPages[n]->bScrollbar = false;
751 bUpdate = (bOldScrollbar != mPages[n]->bScrollbar) || bUpdate;
753 aVisiblePostItList.clear();
755 else
757 bUpdate = true;
758 mPages[n]->bScrollbar = false;
762 if (!ShowNotes())
763 { // we do not want to see the notes anymore -> Options-Writer-View-Notes
764 bool bRepair = false;
765 for(SwMarginItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
767 SwMarginItem* pItem = (*i);
768 if ( !pItem->UseElement() )
770 DBG_ERROR("PostIt is not in doc!");
771 bRepair = true;
772 continue;
775 if ((*i)->pPostIt)
777 (*i)->pPostIt->HideNote();
778 if ((*i)->pPostIt->HasChildPathFocus())
780 SetActivePostIt(0);
781 (*i)->pPostIt->GrabFocusToDocument();
786 if ( bRepair )
787 CheckForRemovedPostIts();
791 // notes scrollbar is otherwise not drawn correctly for some cases
792 // scrollbar area is enough
793 if (bUpdate)
794 mpEditWin->Invalidate();
795 mbLayouting = false;
799 bool SwPostItMgr::BorderOverPageBorder(unsigned long aPage) const
801 if ( mPages[aPage-1]->mList->empty() )
803 DBG_ERROR("Notes SidePane painted but no rects and page lists calculated!");
804 return false;
807 SwMarginItem_iterator aItem = mPages[aPage-1]->mList->end();
808 --aItem;
809 DBG_ASSERT ((*aItem)->pPostIt,"BorderOverPageBorder: NULL postIt, should never happen");
810 if ((*aItem)->pPostIt)
812 const long aSidebarheight = mPages[aPage-1]->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0;
813 const long aEndValue = mpEditWin->PixelToLogic(Point(0,(*aItem)->pPostIt->GetPosPixel().Y()+(*aItem)->pPostIt->GetSizePixel().Height())).Y();
814 return aEndValue <= mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight;
816 else
817 return false;
820 void SwPostItMgr::Scroll(const long lScroll,const unsigned long aPage)
822 DBG_ASSERT((lScroll % GetScrollSize() )==0,"SwPostItMgr::Scroll: scrolling by wrong value");
823 // do not scroll more than neccessary up or down
824 if ( ((mPages[aPage-1]->lOffset == 0) && (lScroll>0)) || ( BorderOverPageBorder(aPage) && (lScroll<0)) )
825 return;
827 const bool bOldUp = ArrowEnabled(KEY_PAGEUP,aPage);
828 const bool bOldDown = ArrowEnabled(KEY_PAGEDOWN,aPage);
829 const long aSidebarheight = mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height();
830 for(SwMarginItem_iterator i = mPages[aPage-1]->mList->begin(); i!= mPages[aPage-1]->mList->end(); i++)
832 SwMarginWin* pPostIt = (*i)->pPostIt;
833 // if this is an answer, we should take the normal position and not the real, slightly moved position
834 pPostIt->SetVirtualPosSize(pPostIt->GetPosPixel(),pPostIt->GetSizePixel());
835 pPostIt->TranslateTopPosition(lScroll);
837 if ((*i)->bShow)
839 bool bBottom = mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y()+pPostIt->VirtualSize().Height())).Y() <= (mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight);
840 bool bTop = mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y())).Y() >= (mPages[aPage-1]->mPageRect.Top()+aSidebarheight);
841 if ( bBottom && bTop)
843 pPostIt->ShowNote();
845 else
847 if ( mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y())).Y() < (mPages[aPage-1]->mPageRect.Top()+aSidebarheight))
849 if (mPages[aPage-1]->bMarginSide)
850 pPostIt->ShowAnkorOnly(Point(mPages[aPage-1]->mPageRect.Left(),mPages[aPage-1]->mPageRect.Top()));
851 else
852 pPostIt->ShowAnkorOnly(Point(mPages[aPage-1]->mPageRect.Right(),mPages[aPage-1]->mPageRect.Top()));
854 else
856 if (mPages[aPage-1]->bMarginSide)
857 pPostIt->ShowAnkorOnly(Point(mPages[aPage-1]->mPageRect.Left(),mPages[aPage-1]->mPageRect.Bottom()));
858 else
859 pPostIt->ShowAnkorOnly(Point(mPages[aPage-1]->mPageRect.Right(),mPages[aPage-1]->mPageRect.Bottom()));
864 mPages[aPage-1]->lOffset += lScroll;
865 if ( (bOldUp != ArrowEnabled(KEY_PAGEUP,aPage)) ||(bOldDown != ArrowEnabled(KEY_PAGEDOWN,aPage)) )
867 mpEditWin->Invalidate(GetBottomScrollRect(aPage));
868 mpEditWin->Invalidate(GetTopScrollRect(aPage));
872 void SwPostItMgr::AutoScroll(const SwMarginWin* pPostIt,const unsigned long aPage )
874 // otherwise all notes are visible
875 if (mPages[aPage-1]->bScrollbar)
877 const long aSidebarheight = mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height();
878 const bool bBottom = mpEditWin->PixelToLogic(Point(0,pPostIt->GetPosPixel().Y()+pPostIt->GetSizePixel().Height())).Y() <= (mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight);
879 const bool bTop = mpEditWin->PixelToLogic(Point(0,pPostIt->GetPosPixel().Y())).Y() >= (mPages[aPage-1]->mPageRect.Top()+aSidebarheight);
880 if ( !(bBottom && bTop))
882 const long aDiff = bBottom ? mpEditWin->LogicToPixel(Point(0,mPages[aPage-1]->mPageRect.Top() + aSidebarheight)).Y() - pPostIt->GetPosPixel().Y() :
883 mpEditWin->LogicToPixel(Point(0,mPages[aPage-1]->mPageRect.Bottom() - aSidebarheight)).Y() - (pPostIt->GetPosPixel().Y()+pPostIt->GetSizePixel().Height());
884 // this just adds the missing value to get the next a* GetScrollSize() after aDiff
885 // e.g aDiff= 61 POSTIT_SCOLL=50 --> lScroll = 100
886 const long lScroll = bBottom ? (aDiff + ( GetScrollSize() - (aDiff % GetScrollSize()))) : (aDiff - (GetScrollSize() + (aDiff % GetScrollSize())));
887 Scroll(lScroll, aPage);
892 void SwPostItMgr::MakeVisible(const SwMarginWin* pPostIt,long aPage )
894 if (aPage == -1)
896 // we dont know the page yet, lets find it ourselves
897 for (unsigned long n=0;n<mPages.size();n++)
899 if (mPages[n]->mList->size()>0)
901 for(SwMarginItem_iterator i = mPages[n]->mList->begin(); i!= mPages[n]->mList->end(); i++)
903 if ((*i)->pPostIt==pPostIt)
905 aPage = n+1;
906 break;
912 if (aPage!=-1)
913 AutoScroll(pPostIt,aPage);
914 Rectangle aNoteRect (Point(pPostIt->GetPosPixel().X(),pPostIt->GetPosPixel().Y()-5),pPostIt->GetSizePixel());
915 if (!aNoteRect.IsEmpty())
916 mpWrtShell->MakeVisible(SwRect(mpEditWin->PixelToLogic(aNoteRect)));
919 bool SwPostItMgr::ArrowEnabled(USHORT aDirection,unsigned long aPage) const
921 switch (aDirection)
923 case KEY_PAGEUP:
925 return (mPages[aPage-1]->lOffset != 0);
927 case KEY_PAGEDOWN:
929 return (!BorderOverPageBorder(aPage));
931 default: return false;
935 Color SwPostItMgr::GetArrowColor(USHORT aDirection,unsigned long aPage) const
937 if (ArrowEnabled(aDirection,aPage))
939 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode())
940 return Color(COL_WHITE);
941 else
942 return COL_NOTES_SIDEPANE_ARROW_ENABLED;
944 else
946 return COL_NOTES_SIDEPANE_ARROW_DISABLED;
950 bool SwPostItMgr::LayoutByPage(std::list<SwMarginWin*> &aVisiblePostItList,const Rectangle aBorder, long lNeededHeight)
952 /*** General layout idea:***/
953 // - if we have space left, we always move the current one up,
954 // otherwise the next one down
955 // - first all notes are resized
956 // - then the real layout starts
957 /*************************************************************/
959 //rBorder is the page rect
960 const Rectangle rBorder = mpEditWin->LogicToPixel( aBorder);
961 long lTopBorder = rBorder.Top() + 5;
962 long lBottomBorder = rBorder.Bottom() - 5;
963 const long lVisibleHeight = lBottomBorder - lTopBorder; //rBorder.GetHeight() ;
964 long lSpaceUsed = 0;
965 long lTranslatePos = 0;
966 int loop = 0;
967 bool bDone = false;
968 bool bScrollbars = false;
970 // do all neccessary resizings
971 if (lVisibleHeight < lNeededHeight)
973 // ok, now we have to really resize and adding scrollbars
974 const long lAverageHeight = (lVisibleHeight - aVisiblePostItList.size()*GetSpaceBetween()) / aVisiblePostItList.size();
975 if (lAverageHeight<GetMinimumSizeWithMeta())
977 bScrollbars = true;
978 lTopBorder += GetSidebarScrollerHeight() + 10;
979 lBottomBorder -= (GetSidebarScrollerHeight() + 10);
980 for(SwMarginWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++)
981 (*i)->SetSize(Size((*i)->VirtualSize().getWidth(),(*i)->GetMinimumSizeWithMeta()));
983 else
985 for(SwMarginWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++)
987 if ( (*i)->VirtualSize().getHeight() > lAverageHeight)
988 (*i)->SetSize(Size((*i)->VirtualSize().getWidth(),lAverageHeight));
993 //start the real layout so nothing overlaps anymore
994 if (aVisiblePostItList.size()>1)
996 // if no window is moved anymore we are finished
997 while (!bDone)
999 loop++;
1000 bDone = true;
1001 lSpaceUsed = lTopBorder + GetSpaceBetween();
1002 for(SwMarginWin_iterator i = aVisiblePostItList.begin(); i!= aVisiblePostItList.end() ; i++)
1004 SwMarginWin_iterator aNextPostIt = i;
1005 ++aNextPostIt;
1007 if (aNextPostIt !=aVisiblePostItList.end())
1009 lTranslatePos = ( (*i)->VirtualPos().Y() + (*i)->VirtualSize().Height()) - (*aNextPostIt)->VirtualPos().Y();
1010 if (lTranslatePos > 0) // note windows overlaps the next one
1012 // we are not done yet, loop at least once more
1013 bDone = false;
1014 // if there is space left, move the current note up
1015 // it could also happen that there is no space left for the first note due to a scrollbar
1016 // then we also jump into, so we move the current one up and the next one down
1017 if ( (lSpaceUsed <= (*i)->VirtualPos().Y()) || (i==aVisiblePostItList.begin()))
1019 // we have space left, so let's move the current one up
1020 if ( ((*i)->VirtualPos().Y()- lTranslatePos - GetSpaceBetween()) > lTopBorder)
1022 if ((*aNextPostIt)->IsFollow())
1023 (*i)->TranslateTopPosition(-1*(lTranslatePos+ANKORLINE_WIDTH));
1024 else
1025 (*i)->TranslateTopPosition(-1*(lTranslatePos+GetSpaceBetween()));
1027 else
1029 long lMoveUp = (*i)->VirtualPos().Y() - lTopBorder;
1030 (*i)->TranslateTopPosition(-1* lMoveUp);
1031 if ((*aNextPostIt)->IsFollow())
1032 (*aNextPostIt)->TranslateTopPosition( (lTranslatePos+ANKORLINE_WIDTH) - lMoveUp);
1033 else
1034 (*aNextPostIt)->TranslateTopPosition( (lTranslatePos+GetSpaceBetween()) - lMoveUp);
1037 else
1039 // no space left, left move the next one down
1040 if ((*aNextPostIt)->IsFollow())
1041 (*aNextPostIt)->TranslateTopPosition(lTranslatePos+ANKORLINE_WIDTH);
1042 else
1043 (*aNextPostIt)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
1046 else
1048 // the first one could overlap the topborder instead of a second note
1049 if (i==aVisiblePostItList.begin())
1051 long lMoveDown = lTopBorder - (*i)->VirtualPos().Y();
1052 if (lMoveDown>0)
1054 bDone = false;
1055 (*i)->TranslateTopPosition( lMoveDown);
1059 if (aNextPostIt !=aVisiblePostItList.end() && (*aNextPostIt)->IsFollow())
1060 lSpaceUsed += (*i)->VirtualSize().Height() + ANKORLINE_WIDTH;
1061 else
1062 lSpaceUsed += (*i)->VirtualSize().Height() + GetSpaceBetween();
1064 else
1066 //(*i) is the last visible item
1067 SwMarginWin_iterator aPrevPostIt = i;
1068 --aPrevPostIt;
1069 //lTranslatePos = ( (*aPrevPostIt)->VirtualPos().Y() + (*aPrevPostIt)->VirtualSize().Height() + GetSpaceBetween() ) - (*i)->VirtualPos().Y();
1070 lTranslatePos = ( (*aPrevPostIt)->VirtualPos().Y() + (*aPrevPostIt)->VirtualSize().Height() ) - (*i)->VirtualPos().Y();
1071 if (lTranslatePos > 0)
1073 bDone = false;
1074 if ( ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()+lTranslatePos) < lBottomBorder)
1076 if ( (*i)->IsFollow() )
1077 (*i)->TranslateTopPosition(lTranslatePos+ANKORLINE_WIDTH);
1078 else
1079 (*i)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
1081 else
1083 (*i)->TranslateTopPosition(lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()) );
1086 else
1088 // note does not overlap, but we might be over the lower border
1089 // only do this if there are no scrollbars, otherwise notes are supposed to overlap the border
1090 if (!bScrollbars && ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height() > lBottomBorder) )
1092 bDone = false;
1093 (*i)->TranslateTopPosition(lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()));
1098 // security check so we don't loop forever
1099 if (loop>MAX_LOOP_COUNT)
1101 DBG_ERROR("PostItMgr::Layout(): We are looping forever");
1102 break;
1106 else
1108 // only one left, make sure it is not hidden at the top or bottom
1109 SwMarginWin_iterator i = aVisiblePostItList.begin();
1110 lTranslatePos = lTopBorder - (*i)->VirtualPos().Y();
1111 if (lTranslatePos>0)
1113 (*i)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
1115 lTranslatePos = lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height());
1116 if (lTranslatePos<0)
1118 (*i)->TranslateTopPosition(lTranslatePos);
1121 return bScrollbars;
1125 void SwPostItMgr::AddRedlineComments(bool bCheckExistance, bool bFocus)
1127 bool bEmpty = mvPostItFlds.empty();
1128 const SwRedlineTbl& aTable = mpView->GetDocShell()->GetDoc()->GetRedlineTbl();
1129 for( USHORT i = 0; i < aTable.Count(); ++i )
1131 SwRedline* pRedline = const_cast<SwRedline*>((aTable)[i]);
1132 if ( pRedline->GetComment() != String(rtl::OUString::createFromAscii("")) )
1133 InsertItem(pRedline, bCheckExistance, bFocus);
1135 if (bEmpty && !mvPostItFlds.empty())
1136 PrepareView(true);
1140 void SwPostItMgr::AddPostIts(bool bCheckExistance, bool bFocus)
1142 bool bEmpty = mvPostItFlds.empty();
1143 SwFieldType* pType = mpView->GetDocShell()->GetDoc()->GetFldType(RES_POSTITFLD, aEmptyStr,false);
1144 SwClientIter aIter( *pType );
1145 SwClient * pFirst = aIter.GoStart();
1146 while(pFirst)
1148 SwFmtFld* pSwFmtFld = static_cast<SwFmtFld*>(pFirst);
1149 if ( pSwFmtFld->GetTxtFld())
1151 if ( pSwFmtFld->IsFldInDoc() )
1152 InsertItem(pSwFmtFld,bCheckExistance,bFocus);
1154 pFirst = aIter++;
1157 // if we just added the first one we have to update the view for centering
1158 if (bEmpty && !mvPostItFlds.empty())
1159 PrepareView(true);
1162 void SwPostItMgr::RemoveMarginWin()
1164 if (!mvPostItFlds.empty())
1166 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1168 EndListening( *((*i)->GetBroadCaster()) );
1169 if ((*i)->pPostIt)
1170 delete (*i)->pPostIt;
1171 delete (*i);
1173 mvPostItFlds.clear();
1176 // all postits removed, no items should be left in pages
1177 PreparePageContainer();
1180 // copy to new vector, otherwise RemoveItem would operate and delete stuff on mvPostItFlds as well
1181 // RemoveItem will clean up the core field and visible postit if neccessary
1182 // we cannot just delete everything as before, as postits could move into change tracking
1183 void SwPostItMgr::Delete(String aAuthor)
1185 mpWrtShell->StartAllAction();
1186 if ( GetActivePostIt() && (GetActivePostIt()->GetAuthor()==aAuthor) )
1187 SetActivePostIt(0);
1188 SwRewriter aRewriter;
1189 String aUndoString = SW_RES(STR_DELETE_AUTHOR_NOTES);
1190 aUndoString += aAuthor;
1191 aRewriter.AddRule(UNDO_ARG1, aUndoString);
1192 mpWrtShell->StartUndo( UNDO_DELETE, &aRewriter );
1194 std::vector<SwFmtFld*> aTmp;
1195 aTmp.reserve( mvPostItFlds.size() );
1196 for(std::list<SwMarginItem*>::iterator pPostIt = mvPostItFlds.begin(); pPostIt!= mvPostItFlds.end() ; pPostIt++)
1198 if ((*pPostIt)->GetFmtFld() && ((*pPostIt)->pPostIt->GetAuthor() == aAuthor) )
1199 aTmp.push_back( (*pPostIt)->GetFmtFld() );
1201 for(std::vector<SwFmtFld*>::iterator i = aTmp.begin(); i!= aTmp.end() ; i++)
1203 mpWrtShell->GotoField( *(*i) );
1204 mpWrtShell->DelRight();
1207 for(std::list<SwPostItItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end(); )
1209 SwPostItItem* pItem = (*i);
1210 SwPostItField* pPostItField = static_cast<SwPostItField*>(pItem->pFmtFld->GetFld());
1211 if (pPostItField->GetPar1() == aAuthor)
1213 // stop listening, we delete ourselves
1214 EndListening( *(pItem->pFmtFld) );
1216 // remove reference to yet-to-die postit
1217 if (pItem->pPostIt == GetActivePostIt())
1218 SetActivePostIt(0);
1220 // delete the actual SwPostItField
1221 mpWrtShell->GotoField(*pItem->pFmtFld);
1222 mpWrtShell->DelRight();
1223 i = mvPostItFlds.erase(i);
1225 // delete visual representation
1226 // lazy delete doesn't work because references to document (mpFmtFld, mpView etc. may be dead before deletion)
1227 delete pItem->pPostIt;
1229 // delete struct saving the pointers
1230 delete pItem;
1232 else
1233 ++i;
1236 mpWrtShell->EndUndo( UNDO_DELETE );
1237 PrepareView();
1238 mpWrtShell->EndAllAction();
1239 mbLayout = true;
1240 CalcRects();
1241 LayoutPostIts();
1244 void SwPostItMgr::Delete()
1246 mpWrtShell->StartAllAction();
1247 SetActivePostIt(0);
1248 SwRewriter aRewriter;
1249 aRewriter.AddRule(UNDO_ARG1, SW_RES(STR_DELETE_ALL_NOTES) );
1250 mpWrtShell->StartUndo( UNDO_DELETE, &aRewriter );
1252 std::vector<SwFmtFld*> aTmp;
1253 aTmp.reserve( mvPostItFlds.size() );
1254 for(std::list<SwMarginItem*>::iterator pPostIt = mvPostItFlds.begin(); pPostIt!= mvPostItFlds.end() ; pPostIt++)
1256 if ((*pPostIt)->GetFmtFld())
1257 aTmp.push_back( (*pPostIt)->GetFmtFld() );
1259 for(std::vector<SwFmtFld*>::iterator i = aTmp.begin(); i!= aTmp.end() ; i++)
1261 mpWrtShell->GotoField( *(*i) );
1262 mpWrtShell->DelRight();
1266 for(std::list<SwPostItItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1268 SwPostItItem* pItem = (*i);
1269 // stop listening, we delete ourselves
1270 EndListening( *(pItem->pFmtFld) );
1271 // delete the actual SwPostItField
1272 mpWrtShell->GotoField(*pItem->pFmtFld);
1273 mpWrtShell->DelRight();
1274 // delete visual representation
1275 delete pItem->pPostIt;
1276 // delete struct saving the pointers
1277 delete pItem;
1279 mvPostItFlds.clear();
1282 mpWrtShell->EndUndo( UNDO_DELETE );
1283 PrepareView();
1284 mpWrtShell->EndAllAction();
1285 mbLayout = true;
1286 CalcRects();
1287 LayoutPostIts();
1290 void SwPostItMgr::Hide(SwPostItField* pPostItField )
1292 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1294 if ((*i)->GetFmtFld())
1296 SwPostItField* pField = static_cast<SwPostItField*>((*i)->GetFmtFld()->GetFld());
1297 if (pPostItField==pField)
1299 (*i)->bShow = false;
1300 (*i)->pPostIt->HideNote();
1301 break;
1306 LayoutPostIts();
1309 void SwPostItMgr::Hide( const String& rAuthor )
1311 for(SwMarginItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1313 if ( (*i)->pPostIt && ((*i)->pPostIt->GetAuthor() == rAuthor) )
1315 (*i)->bShow = false;
1316 (*i)->pPostIt->HideNote();
1320 LayoutPostIts();
1323 void SwPostItMgr::Hide()
1325 for(SwMarginItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1327 (*i)->bShow = false;
1328 (*i)->pPostIt->HideNote();
1333 void SwPostItMgr::Show()
1335 for(SwMarginItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1337 (*i)->bShow = true;
1339 LayoutPostIts();
1342 void SwPostItMgr::Sort(const short aType)
1344 if (mvPostItFlds.size()>1 )
1346 switch (aType)
1348 case SORT_POS:
1349 mvPostItFlds.sort(comp_pos);
1350 break;
1352 case SORT_AUTHOR:
1353 mvPostItFlds.sort(comp_author);
1354 break;
1355 case SORT_DATE:
1356 mvPostItFlds.sort(comp_date);
1357 break;
1363 SwMarginWin* SwPostItMgr::GetPostIt(SfxBroadcaster* pBroadcaster) const
1365 for(const_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1367 if ( (*i)->GetBroadCaster() == pBroadcaster)
1368 return (*i)->pPostIt;
1370 return NULL;
1373 SwPostIt* SwPostItMgr::GetPostIt(SwPostItField* pFld) const
1375 for(const_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1377 if ( (*i)->GetFmtFld() && ((*i)->GetFmtFld()->GetFld() == pFld) )
1378 return static_cast<SwPostIt*>((*i)->pPostIt);
1380 return NULL;
1383 SwMarginWin* SwPostItMgr::GetPostIt( const SfxBroadcaster* pBroadcaster) const
1385 for(const_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1387 if ( (*i)->GetBroadCaster() == pBroadcaster)
1388 return (*i)->pPostIt;
1390 return NULL;
1393 SwPostIt* SwPostItMgr::GetPostIt(const SwPostItField* pFld) const
1395 for(const_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1397 if ( (*i)->GetFmtFld() && ((*i)->GetFmtFld()->GetFld() == pFld))
1398 return static_cast<SwPostIt*>((*i)->pPostIt);
1400 return NULL;
1403 bool SwPostItMgr::ShowPreview(const SwField* pFld, SwFmtFld*& pFmtFld) const
1405 for (unsigned long n=0;n<mPages.size();n++)
1407 if (mPages[n]->mList->size()>0)
1409 for(const_iterator i = mPages[n]->mList->begin(); i!= mPages[n]->mList->end(); i++)
1411 if ( (*i)->GetFmtFld() && ((*i)->GetFmtFld()->GetFld()==pFld) )
1413 pFmtFld = (*i)->GetFmtFld();
1414 const long aSidebarheight = mPages[n]->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0;
1415 bool bTopPage = mpEditWin->PixelToLogic(Point(0,(*i)->pPostIt->GetPosPixel().Y())).Y() >= (mPages[n]->mPageRect.Top()+aSidebarheight);
1416 bool bBottomPage = mpEditWin->PixelToLogic(Point(0,(*i)->pPostIt->GetPosPixel().Y()+(*i)->pPostIt->GetSizePixel().Height())).Y() <= (mPages[n]->mPageRect.Bottom()-aSidebarheight);
1417 const bool bTopVis = mpEditWin->PixelToLogic(Point(0,(*i)->pPostIt->GetPosPixel().Y())).Y() > mpView->GetVisArea().Top();
1418 const bool bBottomVis = mpEditWin->PixelToLogic(Point(0,(*i)->pPostIt->GetPosPixel().Y()/*+(*i)->pPostIt->GetSizePixel().Height()*/)).Y() <= mpView->GetVisArea().Bottom();
1419 return !(bBottomPage && bTopPage && bBottomVis && bTopVis);
1424 return false;
1427 SwMarginWin* SwPostItMgr::GetNextPostIt(USHORT aDirection, SwMarginWin* aPostIt)
1429 if (mvPostItFlds.size()>1)
1431 for(SwMarginItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1433 if ( (*i)->pPostIt ==aPostIt)
1435 SwMarginItem_iterator iNextPostIt = i;
1436 if (aDirection==KEY_PAGEUP)
1438 if ( iNextPostIt==mvPostItFlds.begin() )
1440 return NULL;
1442 --iNextPostIt;
1444 else
1446 iNextPostIt++;
1447 if ( iNextPostIt==mvPostItFlds.end() )
1449 return NULL;
1452 // lets quit, we are back at the beginng
1453 if ( (*iNextPostIt)->pPostIt==aPostIt)
1454 return NULL;
1455 return (*iNextPostIt)->pPostIt;
1458 return NULL;
1460 else
1461 return NULL;
1464 long SwPostItMgr::GetNextBorder()
1466 for (unsigned long n=0;n<mPages.size();n++)
1468 for(SwMarginItem_iterator b = mPages[n]->mList->begin(); b!= mPages[n]->mList->end(); b++)
1470 if ((*b)->pPostIt == mpActivePostIt)
1472 SwMarginItem_iterator aNext = b;
1473 aNext++;
1474 bool bFollow = (aNext == mPages[n]->mList->end()) ? false : (*aNext)->pPostIt->IsFollow();
1475 if ( mPages[n]->bScrollbar || bFollow )
1477 return -1;
1479 else
1481 //if this is the last item, return the bottom border otherwise the next item
1482 if (aNext == mPages[n]->mList->end())
1483 return mpEditWin->LogicToPixel(Point(0,mPages[n]->mPageRect.Bottom())).Y() - GetSpaceBetween();
1484 else
1485 return (*aNext)->pPostIt->GetPosPixel().Y() - GetSpaceBetween();
1491 DBG_ERROR("SwPostItMgr::GetNextBorder(): We have to find a next border here");
1492 return -1;
1495 void SwPostItMgr::SetShadowState(const SwPostItField* pFld,bool bCursor)
1497 if (pFld)
1499 if (pFld !=mShadowState.mpShadowFld)
1501 if (mShadowState.mpShadowFld)
1503 // reset old one if still alive
1504 // TODO: does not work properly if mouse and cursor was set
1505 SwPostIt* pOldPostIt = GetPostIt(mShadowState.mpShadowFld);
1506 if (pOldPostIt && pOldPostIt->Shadow() && (pOldPostIt->Shadow()->GetShadowState() != SS_EDIT))
1507 pOldPostIt->SetViewState(SS_NORMAL);
1509 //set new one, if it is not currently edited
1510 SwPostIt* pNewPostIt = GetPostIt(pFld);
1511 if (pNewPostIt && pNewPostIt->Shadow() && (pNewPostIt->Shadow()->GetShadowState() != SS_EDIT))
1513 pNewPostIt->SetViewState(SS_VIEW);
1514 //remember our new field
1515 mShadowState.mpShadowFld = pFld;
1516 mShadowState.bCursor = false;
1517 mShadowState.bMouse = false;
1520 if (bCursor)
1521 mShadowState.bCursor = true;
1522 else
1523 mShadowState.bMouse = true;
1525 else
1527 if (mShadowState.mpShadowFld)
1529 if (bCursor)
1530 mShadowState.bCursor = false;
1531 else
1532 mShadowState.bMouse = false;
1533 if (!mShadowState.bCursor && !mShadowState.bMouse)
1535 // reset old one if still alive
1536 SwPostIt* pOldPostIt = GetPostIt(mShadowState.mpShadowFld);
1537 if (pOldPostIt && pOldPostIt->Shadow() && (pOldPostIt->Shadow()->GetShadowState() != SS_EDIT))
1539 pOldPostIt->SetViewState(SS_NORMAL);
1540 mShadowState.mpShadowFld = 0;
1547 void SwPostItMgr::PrepareView(bool bIgnoreCount)
1549 if (!HasNotes() || bIgnoreCount)
1551 mpWrtShell->StartAllAction();
1552 //mpEditWin->Invalidate(); // really not needed anymore??
1553 SwRootFrm* pLayout = mpWrtShell->GetLayout();
1554 if ( pLayout )
1555 SwPostItHelper::setSidebarChanged( pLayout,
1556 mpWrtShell->getIDocumentSettingAccess()->get( IDocumentSettingAccess::BROWSE_MODE ) );
1557 mpWrtShell->EndAllAction();
1561 bool SwPostItMgr::ShowScrollbar(const unsigned long aPage) const
1563 if (mPages.size() > aPage-1)
1564 return (mPages[aPage-1]->bScrollbar && !mbWaitingForCalcRects);
1565 else
1566 return false;
1569 bool SwPostItMgr::IsHit(const Point &aPointPixel)
1571 if (HasNotes() && ShowNotes())
1573 const Point aPoint = mpEditWin->PixelToLogic(aPointPixel);
1574 const SwRootFrm* pLayout = mpWrtShell->GetLayout();
1575 SwRect aPageFrm;
1576 const unsigned long nPageNum = SwPostItHelper::getPageInfo( aPageFrm, pLayout, aPoint );
1577 if( nPageNum )
1579 Rectangle aRect;
1580 DBG_ASSERT(mPages.size()>nPageNum-1,"SwPostitMgr:: page container size wrong");
1581 aRect = mPages[nPageNum-1]->bMarginSide ? Rectangle(Point(aPageFrm.Left()-GetSidebarWidth()-GetSidebarBorderWidth(),aPageFrm.Top()),Size(GetSidebarWidth(),aPageFrm.Height())) :
1582 Rectangle( Point(aPageFrm.Right()+GetSidebarBorderWidth(),aPageFrm.Top()) , Size(GetSidebarWidth(),aPageFrm.Height()));
1583 if (aRect.IsInside(aPoint))
1585 // we hit the note's sidebar
1586 // lets now test for the arrow area
1587 if (mPages[nPageNum-1]->bScrollbar)
1588 return ScrollbarHit(nPageNum,aPoint);
1589 else
1590 return false;
1594 return false;
1596 Rectangle SwPostItMgr::GetBottomScrollRect(const unsigned long aPage) const
1598 SwRect aPageRect = mPages[aPage-1]->mPageRect;
1599 Point aPointBottom = mPages[aPage-1]->bMarginSide ? Point(aPageRect.Left() - GetSidebarWidth() - GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height()) :
1600 Point(aPageRect.Right() + GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height());
1601 Size aSize(GetSidebarWidth() - mpEditWin->PixelToLogic(Size(4,0)).Width(), mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height()) ;
1602 return Rectangle(aPointBottom,aSize);
1606 Rectangle SwPostItMgr::GetTopScrollRect(const unsigned long aPage) const
1608 SwRect aPageRect = mPages[aPage-1]->mPageRect;
1609 Point aPointTop = mPages[aPage-1]->bMarginSide ? Point(aPageRect.Left() - GetSidebarWidth() -GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height()) :
1610 Point(aPageRect.Right() + GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height());
1611 Size aSize(GetSidebarWidth() - mpEditWin->PixelToLogic(Size(4,0)).Width(), mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height()) ;
1612 return Rectangle(aPointTop,aSize);
1616 //IMPORTANT: if you change the rects here, also change SwPageFrm::PaintNotesSidebar()
1617 bool SwPostItMgr::ScrollbarHit(const unsigned long aPage,const Point &aPoint)
1619 SwRect aPageRect = mPages[aPage-1]->mPageRect;
1620 Point aPointBottom = mPages[aPage-1]->bMarginSide ? Point(aPageRect.Left() - GetSidebarWidth()-GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height()) :
1621 Point(aPageRect.Right() + GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height());
1623 Point aPointTop = mPages[aPage-1]->bMarginSide ? Point(aPageRect.Left() - GetSidebarWidth()-GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height()) :
1624 Point(aPageRect.Right()+GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height());
1626 Rectangle aRectBottom(GetBottomScrollRect(aPage));
1627 Rectangle aRectTop(GetTopScrollRect(aPage));
1629 if (aRectBottom.IsInside(aPoint))
1631 if (aPoint.X() < long((aPointBottom.X() + GetSidebarWidth()/3)))
1632 Scroll( GetScrollSize(),aPage);
1633 else
1634 Scroll( -1*GetScrollSize(), aPage);
1635 return true;
1637 else
1638 if (aRectTop.IsInside(aPoint))
1640 if (aPoint.X() < long((aPointTop.X() + GetSidebarWidth()/3*2)))
1641 Scroll(GetScrollSize(), aPage);
1642 else
1643 Scroll(-1*GetScrollSize(), aPage);
1644 return true;
1646 return false;
1649 void SwPostItMgr::CorrectPositions()
1651 if ( mbWaitingForCalcRects || mbLayouting || mvPostItFlds.empty() )
1652 return;
1654 // find first valid note
1655 SwMarginWin *pFirstPostIt = 0;
1656 for(SwMarginItem_iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1658 pFirstPostIt = (*i)->pPostIt;
1659 if (pFirstPostIt)
1660 break;
1663 //if we have not found a valid note, forget about it and leave
1664 if (!pFirstPostIt)
1665 return;
1667 // 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
1668 const long aAnkorX = mpEditWin->LogicToPixel( Point((long)(pFirstPostIt->Ankor()->GetSixthPosition().getX()),0)).X();
1669 const long aAnkorY = mpEditWin->LogicToPixel( Point(0,(long)(pFirstPostIt->Ankor()->GetSixthPosition().getY()))).Y() + 1;
1670 if (Point(aAnkorX,aAnkorY) != pFirstPostIt->GetPosPixel())
1672 long aAnkorPosX = 0;
1673 long aAnkorPosY = 0;
1674 for (unsigned long n=0;n<mPages.size();n++)
1676 for(SwMarginItem_iterator i = mPages[n]->mList->begin(); i!= mPages[n]->mList->end(); i++)
1678 if ((*i)->bShow && (*i)->pPostIt)
1680 aAnkorPosX = mPages[n]->bMarginSide ?
1681 mpEditWin->LogicToPixel( Point((long)((*i)->pPostIt->Ankor()->GetSeventhPosition().getX()),0)).X() :
1682 mpEditWin->LogicToPixel( Point((long)((*i)->pPostIt->Ankor()->GetSixthPosition().getX()),0)).X();
1683 aAnkorPosY = mpEditWin->LogicToPixel( Point(0,(long)((*i)->pPostIt->Ankor()->GetSixthPosition().getY()))).Y() + 1;
1684 (*i)->pPostIt->SetPosPixel(Point(aAnkorPosX,aAnkorPosY));
1692 bool SwPostItMgr::ShowNotes() const
1694 // we only want to see notes if Options - Writer - View - Notes is ticked
1695 return mpWrtShell->GetViewOptions()->IsPostIts();
1698 bool SwPostItMgr::HasNotes() const
1700 return !mvPostItFlds.empty();
1703 unsigned long SwPostItMgr::GetSidebarWidth(bool bPx) const
1705 unsigned long aWidth = (unsigned long)(mpWrtShell->GetViewOptions()->GetZoom() * 1.8);
1706 if (bPx)
1707 return aWidth;
1708 else
1709 return mpEditWin->PixelToLogic(Size( aWidth ,0)).Width();
1712 unsigned long SwPostItMgr::GetSidebarBorderWidth(bool bPx) const
1714 if (bPx)
1715 return 2;
1716 else
1717 return mpEditWin->PixelToLogic(Size(2,0)).Width();
1720 unsigned long SwPostItMgr::GetNoteWidth()
1722 return GetSidebarWidth(true);
1725 Color SwPostItMgr::GetColorDark(sal_uInt16 aAuthorIndex)
1727 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1729 static const Color aArrayNormal[] = {
1730 COL_AUTHOR1_NORMAL, COL_AUTHOR2_NORMAL, COL_AUTHOR3_NORMAL,
1731 COL_AUTHOR4_NORMAL, COL_AUTHOR5_NORMAL, COL_AUTHOR6_NORMAL,
1732 COL_AUTHOR7_NORMAL, COL_AUTHOR8_NORMAL, COL_AUTHOR9_NORMAL };
1734 return Color( aArrayNormal[ aAuthorIndex % (sizeof( aArrayNormal )/ sizeof( aArrayNormal[0] ))]);
1736 else
1737 return Color(COL_WHITE);
1740 Color SwPostItMgr::GetColorLight(sal_uInt16 aAuthorIndex)
1742 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1744 static const Color aArrayLight[] = {
1745 COL_AUTHOR1_LIGHT, COL_AUTHOR2_LIGHT, COL_AUTHOR3_LIGHT,
1746 COL_AUTHOR4_LIGHT, COL_AUTHOR5_LIGHT, COL_AUTHOR6_LIGHT,
1747 COL_AUTHOR7_LIGHT, COL_AUTHOR8_LIGHT, COL_AUTHOR9_LIGHT };
1749 return Color( aArrayLight[ aAuthorIndex % (sizeof( aArrayLight )/ sizeof( aArrayLight[0] ))]);
1751 else
1752 return Color(COL_WHITE);
1755 Color SwPostItMgr::GetColorAnkor(sal_uInt16 aAuthorIndex)
1757 if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1759 static const Color aArrayAnkor[] = {
1760 COL_AUTHOR1_DARK, COL_AUTHOR2_DARK, COL_AUTHOR3_DARK,
1761 COL_AUTHOR4_DARK, COL_AUTHOR5_DARK, COL_AUTHOR6_DARK,
1762 COL_AUTHOR7_DARK, COL_AUTHOR8_DARK, COL_AUTHOR9_DARK };
1764 return Color( aArrayAnkor[ aAuthorIndex % (sizeof( aArrayAnkor ) / sizeof( aArrayAnkor[0] ))]);
1766 else
1767 return Color(COL_WHITE);
1770 void SwPostItMgr::SetActivePostIt( SwMarginWin* p)
1772 if ( p != mpActivePostIt )
1774 // we need the temp variable so we can set mpActivePostIt before we call DeactivatePostIt
1775 // therefore we get a new layout in DOCCHANGED when switching from postit to document,
1776 // otherwise, GetActivePostIt() would still hold our old postit
1777 SwMarginWin* pActive = mpActivePostIt;
1778 mpActivePostIt = p;
1779 if (pActive)
1781 pActive->DeactivatePostIt();
1782 mShadowState.mpShadowFld = 0;
1784 if (mpActivePostIt)
1786 mpActivePostIt->GotoPos();
1787 mpView->AttrChangedNotify(0);
1788 mpActivePostIt->ActivatePostIt();
1793 IMPL_LINK( SwPostItMgr, CalcHdl, void*, /* pVoid*/ )
1795 mnEventId = 0;
1796 if ( mbLayouting )
1798 DBG_ERROR("Reentrance problem in Layout Manager!");
1799 mbWaitingForCalcRects = false;
1800 return 0;
1803 // do not change order, even if it would seem so in the first place, we need the calcrects always
1804 if (CalcRects() || mbLayout)
1806 mbLayout = false;
1807 LayoutPostIts();
1809 return 0;
1812 void SwPostItMgr::Rescale()
1814 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1815 if ( (*i)->pPostIt )
1816 (*i)->pPostIt->Rescale();
1819 sal_Int32 SwPostItMgr::GetInitialAnchorDistance() const
1821 const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
1822 return POSTIT_INITIAL_ANKOR_DISTANCE * f.GetNumerator() / f.GetDenominator();
1825 sal_Int32 SwPostItMgr::GetSpaceBetween() const
1827 const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
1828 return ( POSTIT_SPACE_BETWEEN ) * f.GetNumerator() / f.GetDenominator();
1831 sal_Int32 SwPostItMgr::GetScrollSize() const
1833 const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
1834 return ( POSTIT_SPACE_BETWEEN + POSTIT_MINIMUMSIZE_WITH_META ) * f.GetNumerator() / f.GetDenominator();
1837 sal_Int32 SwPostItMgr::GetMinimumSizeWithMeta() const
1839 const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
1840 return POSTIT_MINIMUMSIZE_WITH_META * f.GetNumerator() / f.GetDenominator();
1843 sal_Int32 SwPostItMgr::GetSidebarScrollerHeight() const
1845 const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
1846 return POSTIT_SCROLL_SIDEBAR_HEIGHT * f.GetNumerator() / f.GetDenominator();
1849 void SwPostItMgr::SetSpellChecking()
1851 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1852 if ( (*i)->pPostIt )
1853 (*i)->pPostIt->SetSpellChecking();
1856 void SwPostItMgr::SetReadOnlyState()
1858 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1859 if ( (*i)->pPostIt )
1860 (*i)->pPostIt->SetReadonly( mbReadOnly );
1863 void SwPostItMgr::CheckMetaText()
1865 for(std::list<SwMarginItem*>::iterator i = mvPostItFlds.begin(); i!= mvPostItFlds.end() ; i++)
1866 if ( (*i)->pPostIt )
1867 (*i)->pPostIt->CheckMetaText();
1871 sal_uInt16 SwPostItMgr::Replace(SvxSearchItem* pItem)
1873 SwMarginWin* pWin = GetActivePostIt();
1874 sal_uInt16 aResult = pWin->View()->StartSearchAndReplace( *pItem );
1875 if (!aResult)
1876 SetActivePostIt(0);
1877 return aResult;
1880 sal_uInt16 SwPostItMgr::FinishSearchReplace(const ::com::sun::star::util::SearchOptions& rSearchOptions, bool bSrchForward)
1882 SwMarginWin* pWin = GetActivePostIt();
1883 SvxSearchItem aItem(SID_SEARCH_ITEM );
1884 aItem.SetSearchOptions(rSearchOptions);
1885 aItem.SetBackward(!bSrchForward);
1886 sal_uInt16 aResult = pWin->View()->StartSearchAndReplace( aItem );
1887 if (!aResult)
1888 SetActivePostIt(0);
1889 return aResult;
1892 sal_uInt16 SwPostItMgr::SearchReplace(const SwFmtFld &pFld, const ::com::sun::star::util::SearchOptions& rSearchOptions, bool bSrchForward)
1894 sal_uInt16 aResult = 0;
1895 SwMarginWin* pWin = GetPostIt(&pFld);
1896 if (pWin)
1898 ESelection aOldSelection = pWin->View()->GetSelection();
1899 if (bSrchForward)
1900 pWin->View()->SetSelection(ESelection(0,0,0,0));
1901 else
1902 pWin->View()->SetSelection(ESelection(0xFFFF,0xFFFF,0xFFFF,0xFFFF));
1903 SvxSearchItem aItem(SID_SEARCH_ITEM );
1904 aItem.SetSearchOptions(rSearchOptions);
1905 aItem.SetBackward(!bSrchForward);
1906 aResult = pWin->View()->StartSearchAndReplace( aItem );
1907 if (!aResult)
1908 pWin->View()->SetSelection(aOldSelection);
1909 else
1911 SetActivePostIt(pWin);
1912 MakeVisible(pWin);
1915 return aResult;