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