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