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