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