LibreOffice Module sw (master)  1
PostItMgr.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <boost/property_tree/json_parser.hpp>
21 
22 #include <PostItMgr.hxx>
23 #include <postithelper.hxx>
24 
25 #include <AnnotationWin.hxx>
27 #include <accmap.hxx>
28 
29 #include <SidebarWindowsConsts.hxx>
30 #include "AnchorOverlayObject.hxx"
31 #include "ShadowOverlayObject.hxx"
32 
33 #include <vcl/svapp.hxx>
34 #include <vcl/scrbar.hxx>
35 #include <vcl/outdev.hxx>
36 #include <vcl/settings.hxx>
37 
38 #include <chrdlgmodes.hxx>
39 #include <viewopt.hxx>
40 #include <view.hxx>
41 #include <docsh.hxx>
42 #include <wrtsh.hxx>
43 #include <doc.hxx>
46 #include <fldbas.hxx>
47 #include <fmtfld.hxx>
48 #include <docufld.hxx>
49 #include <edtwin.hxx>
50 #include <txtfld.hxx>
51 #include <txtannotationfld.hxx>
52 #include <ndtxt.hxx>
53 #include <redline.hxx>
54 #include <docary.hxx>
55 #include <rootfrm.hxx>
56 #include <SwRewriter.hxx>
57 #include <tools/color.hxx>
58 #include <unotools/datetime.hxx>
59 
60 #include <swmodule.hxx>
61 #include <strings.hrc>
62 #include <cmdid.h>
63 
64 #include <sfx2/request.hxx>
65 #include <sfx2/event.hxx>
66 #include <svl/srchitem.hxx>
67 
68 #include <svl/languageoptions.hxx>
69 #include <svtools/langtab.hxx>
70 #include <svl/hint.hxx>
71 
72 #include <svx/svdview.hxx>
73 #include <svx/svxids.hrc>
74 #include <editeng/eeitem.hxx>
75 #include <editeng/langitem.hxx>
76 #include <editeng/kernitem.hxx>
77 #include <editeng/outliner.hxx>
78 #include <editeng/outlobj.hxx>
79 
80 #include <i18nlangtag/mslangid.hxx>
81 #include <i18nlangtag/lang.h>
82 #include <comphelper/lok.hxx>
83 #include <comphelper/string.hxx>
84 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
85 
86 #include <annotsh.hxx>
87 #include <swabstdlg.hxx>
88 #include <swevent.hxx>
89 #include <calbck.hxx>
90 #include <memory>
91 
92 // distance between Anchor Y and initial note position
93 #define POSTIT_INITIAL_ANCHOR_DISTANCE 20
94 //distance between two postits
95 #define POSTIT_SPACE_BETWEEN 8
96 #define POSTIT_MINIMUMSIZE_WITH_META 60
97 #define POSTIT_SCROLL_SIDEBAR_HEIGHT 20
98 
99 // if we layout more often we stop, this should never happen
100 #define MAX_LOOP_COUNT 50
101 
102 using namespace sw::sidebarwindows;
103 using namespace sw::annotation;
104 
105 namespace {
106 
108 
109  bool comp_pos(const std::unique_ptr<SwSidebarItem>& a, const std::unique_ptr<SwSidebarItem>& b)
110  {
111  // sort by anchor position
112  SwPosition aPosAnchorA = a->GetAnchorPosition();
113  SwPosition aPosAnchorB = b->GetAnchorPosition();
114 
115  bool aAnchorAInFooter = false;
116  bool aAnchorBInFooter = false;
117 
118  // is the anchor placed in Footnote or the Footer?
119  if( aPosAnchorA.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorA.nNode.GetNode().FindFooterStartNode() )
120  aAnchorAInFooter = true;
121  if( aPosAnchorB.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorB.nNode.GetNode().FindFooterStartNode() )
122  aAnchorBInFooter = true;
123 
124  // fdo#34800
125  // if AnchorA is in footnote, and AnchorB isn't
126  // we do not want to change over the position
127  if( aAnchorAInFooter && !aAnchorBInFooter )
128  return false;
129  // if aAnchorA is not placed in a footnote, and aAnchorB is
130  // force a change over
131  else if( !aAnchorAInFooter && aAnchorBInFooter )
132  return true;
133  // If neither or both are in the footer, compare the positions.
134  // Since footnotes are in Inserts section of nodes array and footers
135  // in Autotext section, all footnotes precede any footers so no need
136  // to check that.
137  else
138  return aPosAnchorA < aPosAnchorB;
139  }
140 
142  void lcl_CommentNotification(const SwView* pView, const CommentNotificationType nType, const SwSidebarItem* pItem, const sal_uInt32 nPostItId)
143  {
145  return;
146 
147  boost::property_tree::ptree aAnnotation;
148  aAnnotation.put("action", (nType == CommentNotificationType::Add ? "Add" :
149  (nType == CommentNotificationType::Remove ? "Remove" :
150  (nType == CommentNotificationType::Modify ? "Modify" : "???"))));
151  aAnnotation.put("id", nPostItId);
152  if (nType != CommentNotificationType::Remove && pItem != nullptr)
153  {
155 
156  const SwPostItField* pField = pWin->GetPostItField();
157  const SwRect& aRect = pWin->GetAnchorRect();
158  const tools::Rectangle aSVRect(aRect.Pos().getX(),
159  aRect.Pos().getY(),
160  aRect.Pos().getX() + aRect.SSize().Width(),
161  aRect.Pos().getY() + aRect.SSize().Height());
162  std::vector<OString> aRects;
163  for (const basegfx::B2DRange& aRange : pWin->GetAnnotationTextRanges())
164  {
165  const SwRect rect(aRange.getMinX(), aRange.getMinY(), aRange.getWidth(), aRange.getHeight());
166  aRects.push_back(rect.SVRect().toString());
167  }
168  const OString sRects = comphelper::string::join("; ", aRects);
169 
170  aAnnotation.put("id", pField->GetPostItId());
171  aAnnotation.put("parent", pWin->CalcParent());
172  aAnnotation.put("author", pField->GetPar1().toUtf8().getStr());
173  aAnnotation.put("text", pField->GetPar2().toUtf8().getStr());
174  aAnnotation.put("dateTime", utl::toISO8601(pField->GetDateTime().GetUNODateTime()));
175  aAnnotation.put("anchorPos", aSVRect.toString());
176  aAnnotation.put("textRange", sRects.getStr());
177  }
178 
179  boost::property_tree::ptree aTree;
180  aTree.add_child("comment", aAnnotation);
181  std::stringstream aStream;
182  boost::property_tree::write_json(aStream, aTree);
183  std::string aPayload = aStream.str();
184 
185  if (pView)
186  {
187  pView->libreOfficeKitViewCallback(LOK_CALLBACK_COMMENT, aPayload.c_str());
188  }
189  }
190 
191 } // anonymous namespace
192 
194  : mpView(pView)
195  , mpWrtShell(mpView->GetDocShell()->GetWrtShell())
196  , mpEditWin(&mpView->GetEditWin())
197  , mnEventId(nullptr)
198  , mbWaitingForCalcRects(false)
199  , mpActivePostIt(nullptr)
200  , mbLayout(false)
201  , mbLayoutHeight(0)
202  , mbLayouting(false)
203  , mbReadOnly(mpView->GetDocShell()->IsReadOnly())
204  , mbDeleteNote(true)
205  , mpAnswer(nullptr)
206  , mbIsShowAnchor( false )
207 {
208  if(!mpView->GetDrawView() )
210 
211  SwNoteProps aProps;
212  mbIsShowAnchor = aProps.IsShowAnchor();
213 
214  //make sure we get the colour yellow always, even if not the first one of comments or redlining
215  SW_MOD()->GetRedlineAuthor();
216 
217  // collect all PostIts and redline comments that exist after loading the document
218  // don't check for existence for any of them, don't focus them
219  AddPostIts(false,false);
220  /* this code can be used once we want redline comments in the Sidebar
221  AddRedlineComments(false,false);
222  */
223  // we want to receive stuff like SfxHintId::DocChanged
225  if (!mvPostItFields.empty())
226  {
227  mbWaitingForCalcRects = true;
229  }
230 }
231 
233 {
234  if ( mnEventId )
236  // forget about all our Sidebar windows
239 
240  mPages.clear();
241 }
242 
244 {
246  bool bRemoved = false;
247  auto it = mvPostItFields.begin();
248  while(it != mvPostItFields.end())
249  {
250  if (!(*it)->UseElement(*mpWrtShell->GetLayout(), rIDRA))
251  {
252  EndListening(const_cast<SfxBroadcaster&>(*(*it)->GetBroadcaster()));
253  std::unique_ptr<SwSidebarItem> p = std::move(*it);
254  it = mvPostItFields.erase(it);
255  if (GetActiveSidebarWin() == p->pPostIt)
256  SetActiveSidebarWin(nullptr);
257  p->pPostIt.disposeAndClear();
258  bRemoved = true;
259  }
260  else
261  ++it;
262  }
263 
264  if ( bRemoved )
265  {
266  // make sure that no deleted items remain in page lists
267  // todo: only remove deleted ones?!
268  if ( mvPostItFields.empty() )
269  {
271  PrepareView();
272  }
273  else
274  // if postits are their make sure that page lists are not empty
275  // otherwise sudden paints can cause pain (in BorderOverPageBorder)
276  CalcRects();
277  }
278 }
279 
280 SwSidebarItem* SwPostItMgr::InsertItem(SfxBroadcaster* pItem, bool bCheckExistence, bool bFocus)
281 {
282  if (bCheckExistence)
283  {
284  for (auto const& postItField : mvPostItFields)
285  {
286  if ( postItField->GetBroadcaster() == pItem )
287  return nullptr;
288  }
289  }
290  mbLayout = bFocus;
291 
292  SwSidebarItem* pAnnotationItem = nullptr;
293  if (dynamic_cast< const SwFormatField *>( pItem ) != nullptr)
294  {
295  mvPostItFields.push_back(std::make_unique<SwAnnotationItem>(static_cast<SwFormatField&>(*pItem), bFocus));
296  pAnnotationItem = mvPostItFields.back().get();
297  }
298  OSL_ENSURE(dynamic_cast< const SwFormatField *>( pItem ) != nullptr,"Mgr::InsertItem: seems like new stuff was added");
299  StartListening(*pItem);
300  return pAnnotationItem;
301 }
302 
304 {
305  EndListening(*pBroadcast);
306  auto i = std::find_if(mvPostItFields.begin(), mvPostItFields.end(),
307  [&pBroadcast](const std::unique_ptr<SwSidebarItem>& pField) { return pField->GetBroadcaster() == pBroadcast; });
308  if (i != mvPostItFields.end())
309  {
310  std::unique_ptr<SwSidebarItem> p = std::move(*i);
311  if (GetActiveSidebarWin() == p->pPostIt)
312  SetActiveSidebarWin(nullptr);
313  // tdf#120487 remove from list before dispose, so comment window
314  // won't be recreated due to the entry still in the list if focus
315  // transferring from the pPostIt triggers relayout of postits
316  mvPostItFields.erase(i);
317  p->pPostIt.disposeAndClear();
318  }
319  mbLayout = true;
320  PrepareView();
321 }
322 
323 void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
324 {
325  if ( const SfxEventHint* pSfxEventHint = dynamic_cast<const SfxEventHint*>(&rHint) )
326  {
327  if ( pSfxEventHint->GetEventId() == SfxEventHintId::SwEventLayoutFinished )
328  {
329  if ( !mbWaitingForCalcRects && !mvPostItFields.empty())
330  {
331  mbWaitingForCalcRects = true;
333  }
334  }
335  }
336  else if ( const SwFormatFieldHint * pFormatHint = dynamic_cast<const SwFormatFieldHint*>(&rHint) )
337  {
338  SwFormatField* pField = const_cast <SwFormatField*>( pFormatHint->GetField() );
339  switch ( pFormatHint->Which() )
340  {
342  {
343  if (!pField)
344  {
345  AddPostIts();
346  break;
347  }
348  // get field to be inserted from hint
349  if ( pField->IsFieldInDoc() )
350  {
351  bool bEmpty = !HasNotes();
352  SwSidebarItem* pItem = InsertItem( pField, true, false );
353 
354  if (bEmpty && !mvPostItFields.empty())
355  PrepareView(true);
356 
357  // True until the layout of this post it finishes
358  if (pItem)
359  pItem->bPendingLayout = true;
360  }
361  else
362  {
363  OSL_FAIL("Inserted field not in document!" );
364  }
365  break;
366  }
368  {
369  if (mbDeleteNote)
370  {
371  if (!pField)
372  {
374  break;
375  }
376  RemoveItem(pField);
377 
378  // If LOK has disabled tiled annotations, emit annotation callbacks
380  {
381  SwPostItField* pPostItField = static_cast<SwPostItField*>(pField->GetField());
382  lcl_CommentNotification(mpView, CommentNotificationType::Remove, nullptr, pPostItField->GetPostItId());
383  }
384  }
385  break;
386  }
388  {
389  if (pFormatHint->GetView()== mpView)
390  Focus(rBC);
391  break;
392  }
394  {
395  SwFormatField* pFormatField = dynamic_cast<SwFormatField*>(&rBC);
396  for (auto const& postItField : mvPostItFields)
397  {
398  if ( pFormatField == postItField->GetBroadcaster() )
399  {
400  if (postItField->pPostIt)
401  {
402  postItField->pPostIt->SetPostItText();
403  mbLayout = true;
404  }
405 
406  // If LOK has disabled tiled annotations, emit annotation callbacks
408  {
409  lcl_CommentNotification(mpView, CommentNotificationType::Modify, postItField.get(), 0);
410  }
411  break;
412  }
413  }
414  break;
415  }
416 
418  {
419  SwFormatField* pFormatField = dynamic_cast<SwFormatField*>(&rBC);
420  for (auto const& postItField : mvPostItFields)
421  {
422  if ( pFormatField == postItField->GetBroadcaster() )
423  {
424  if (postItField->pPostIt)
425  {
426  const SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( postItField->GetFormatField().GetField()->GetLanguage() );
427  sal_uInt16 nLangWhichId = 0;
428  switch (nScriptType)
429  {
430  case SvtScriptType::LATIN : nLangWhichId = EE_CHAR_LANGUAGE ; break;
431  case SvtScriptType::ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
432  case SvtScriptType::COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
433  default: break;
434  }
435  postItField->pPostIt->SetLanguage(
437  postItField->GetFormatField().GetField()->GetLanguage(),
438  nLangWhichId) );
439  }
440  break;
441  }
442  }
443  break;
444  }
445  }
446  }
447  else
448  {
449  SfxHintId nId = rHint.GetId();
450  switch ( nId )
451  {
452  case SfxHintId::ModeChanged:
453  {
454  if ( mbReadOnly != mpView->GetDocShell()->IsReadOnly() )
455  {
458  mbLayout = true;
459  }
460  break;
461  }
462  case SfxHintId::DocChanged:
463  {
464  if ( mpView->GetDocShell() == &rBC )
465  {
466  if ( !mbWaitingForCalcRects && !mvPostItFields.empty())
467  {
468  mbWaitingForCalcRects = true;
470  }
471  }
472  break;
473  }
474  case SfxHintId::SwSplitNodeOperation:
475  {
476  // if we are in a SplitNode/Cut operation, do not delete note and then add again, as this will flicker
478  break;
479  }
480  case SfxHintId::Dying:
481  {
482  if ( mpView->GetDocShell() != &rBC )
483  {
484  // field to be removed is the broadcaster
485  OSL_FAIL("Notification for removed SwFormatField was not sent!");
486  RemoveItem(&rBC);
487  }
488  break;
489  }
490  default: break;
491  }
492  }
493 }
494 
496 {
498  {
499  SfxRequest aRequest(mpView->GetViewFrame(), SID_TOGGLE_NOTES);
500  mpView->ExecViewOptions(aRequest);
501  }
502 
503  for (auto const& postItField : mvPostItFields)
504  {
505  // field to get the focus is the broadcaster
506  if ( &rBC == postItField->GetBroadcaster() )
507  {
508  if (postItField->pPostIt)
509  {
510  postItField->pPostIt->GrabFocus();
511  MakeVisible(postItField->pPostIt);
512  }
513  else
514  {
515  // when the layout algorithm starts, this postit is created and receives focus
516  postItField->bFocus = true;
517  }
518  }
519  }
520 }
521 
523 {
524  if ( mnEventId )
525  {
526  // if CalcRects() was forced and an event is still pending: remove it
527  // it is superfluous and also may cause reentrance problems if triggered while layouting
529  mnEventId = nullptr;
530  }
531 
532  bool bChange = false;
533  bool bRepair = false;
535  if ( !mvPostItFields.empty() )
536  {
538  for (auto const& pItem : mvPostItFields)
539  {
540  if (!pItem->UseElement(*mpWrtShell->GetLayout(), rIDRA))
541  {
542  OSL_FAIL("PostIt is not in doc or other wrong use");
543  bRepair = true;
544  continue;
545  }
546  const SwRect aOldAnchorRect( pItem->maLayoutInfo.mPosition );
547  const SwPostItHelper::SwLayoutStatus eOldLayoutStatus = pItem->mLayoutStatus;
548  const sal_uLong nOldStartNodeIdx( pItem->maLayoutInfo.mnStartNodeIdx );
549  const sal_Int32 nOldStartContent( pItem->maLayoutInfo.mnStartContent );
550  {
551  // update layout information
552  const SwTextAnnotationField* pTextAnnotationField =
553  dynamic_cast< const SwTextAnnotationField* >( pItem->GetFormatField().GetTextField() );
554  const ::sw::mark::IMark* pAnnotationMark =
555  pTextAnnotationField != nullptr ? pTextAnnotationField->GetAnnotationMark() : nullptr;
556  if ( pAnnotationMark != nullptr )
557  {
558  pItem->mLayoutStatus =
560  pItem->maLayoutInfo,
561  pItem->GetAnchorPosition(),
562  pAnnotationMark );
563  }
564  else
565  {
566  pItem->mLayoutStatus =
568  }
569  }
570  bChange = bChange
571  || pItem->maLayoutInfo.mPosition != aOldAnchorRect
572  || pItem->mLayoutStatus != eOldLayoutStatus
573  || pItem->maLayoutInfo.mnStartNodeIdx != nOldStartNodeIdx
574  || pItem->maLayoutInfo.mnStartContent != nOldStartContent;
575  }
576 
577  // show notes in right order in navigator
578  //prevent Anchors during layout to overlap, e.g. when moving a frame
579  if (mvPostItFields.size()>1 )
580  std::stable_sort(mvPostItFields.begin(), mvPostItFields.end(), comp_pos);
581 
582  // sort the items into the right page vector, so layout can be done by page
583  for (auto const& pItem : mvPostItFields)
584  {
586  {
587  if (pItem->pPostIt)
588  pItem->pPostIt->HideNote();
589  continue;
590  }
591 
592  if( SwPostItHelper::HIDDEN == pItem->mLayoutStatus )
593  {
595  {
596  if (pItem->pPostIt)
597  pItem->pPostIt->HideNote();
598  continue;
599  }
600  }
601 
602  const unsigned long aPageNum = pItem->maLayoutInfo.mnPageNumber;
603  if (aPageNum > mPages.size())
604  {
605  const unsigned long nNumberOfPages = mPages.size();
606  mPages.reserve(aPageNum);
607  for (unsigned long j=0; j<aPageNum - nNumberOfPages; ++j)
608  mPages.emplace_back( new SwPostItPageItem());
609  }
610  mPages[aPageNum-1]->mvSidebarItems.push_back(pItem.get());
611  mPages[aPageNum-1]->mPageRect = pItem->maLayoutInfo.mPageFrame;
612  mPages[aPageNum-1]->eSidebarPosition = pItem->maLayoutInfo.meSidebarPosition;
613  }
614 
616  {
617  long nLayoutHeight = SwPostItHelper::getLayoutHeight( mpWrtShell->GetLayout() );
618  if( nLayoutHeight > mbLayoutHeight )
619  {
620  if (mPages[0]->bScrollbar || HasScrollbars())
621  bChange = true;
622  }
623  else if( nLayoutHeight < mbLayoutHeight )
624  {
625  if (mPages[0]->bScrollbar || !BorderOverPageBorder(1))
626  bChange = true;
627  }
628  }
629  }
630 
631  if ( bRepair )
633 
635  mbWaitingForCalcRects = false;
636  return bChange;
637 }
638 
640 {
641  for (auto const& postItField : mvPostItFields)
642  {
643  if (postItField->bShow && postItField->pPostIt && postItField->pPostIt->HasScrollbar())
644  return true;
645  }
646  return false;
647 }
648 
650 {
651  // we do not just delete the SwPostItPageItem, so offset/scrollbar is not lost
652  long lPageSize = mpWrtShell->GetNumPages();
653  long lContainerSize = mPages.size();
654 
655  if (lContainerSize < lPageSize)
656  {
657  mPages.reserve(lPageSize);
658  for (long i=0; i<lPageSize - lContainerSize;i++)
659  mPages.emplace_back( new SwPostItPageItem());
660  }
661  else if (lContainerSize > lPageSize)
662  {
663  for (int i=mPages.size()-1; i >= lPageSize;--i)
664  {
665  mPages.pop_back();
666  }
667  }
668  // only clear the list, DO NOT delete the objects itself
669  for (auto const& page : mPages)
670  {
671  page->mvSidebarItems.clear();
672  if (mvPostItFields.empty())
673  page->bScrollbar = false;
674  }
675 }
676 
678 {
679  bool bEnableMapMode = comphelper::LibreOfficeKit::isActive() && !mpEditWin->IsMapModeEnabled();
680  if (bEnableMapMode)
682 
683  if ( !mvPostItFields.empty() && !mbWaitingForCalcRects )
684  {
685  mbLayouting = true;
686 
687  //loop over all pages and do the layout
688  // - create SwPostIt if necessary
689  // - place SwPostIts on their initial position
690  // - calculate necessary height for all PostIts together
691  bool bUpdate = false;
692  for (std::unique_ptr<SwPostItPageItem>& pPage : mPages)
693  {
694  // only layout if there are notes on this page
695  if (!pPage->mvSidebarItems.empty())
696  {
697  std::vector<SwAnnotationWin*> aVisiblePostItList;
698  unsigned long lNeededHeight = 0;
699  long mlPageBorder = 0;
700  long mlPageEnd = 0;
701 
702  for (auto const& pItem : pPage->mvSidebarItems)
703  {
704  VclPtr<SwAnnotationWin> pPostIt = pItem->pPostIt;
705 
706  if (pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT )
707  {
708  // x value for notes positioning
709  mlPageBorder = mpEditWin->LogicToPixel( Point( pPage->mPageRect.Left(), 0)).X() - GetSidebarWidth(true);// - GetSidebarBorderWidth(true);
710  //bending point
711  mlPageEnd =
713  ? pItem->maLayoutInfo.mPagePrtArea.Left()
714  : pPage->mPageRect.Left() + 350;
715  }
716  else if (pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::RIGHT )
717  {
718  // x value for notes positioning
719  mlPageBorder = mpEditWin->LogicToPixel( Point(pPage->mPageRect.Right(), 0)).X() + GetSidebarBorderWidth(true);
720  //bending point
721  mlPageEnd =
723  ? pItem->maLayoutInfo.mPagePrtArea.Right() :
724  pPage->mPageRect.Right() - 350;
725  }
726 
727  if (pItem->bShow)
728  {
729  long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y();
730  long aPostItHeight = 0;
731  if (!pPostIt)
732  {
733  pPostIt = pItem->GetSidebarWindow( mpView->GetEditWin(),
734  *this );
735  pPostIt->InitControls();
736  pPostIt->SetReadonly(mbReadOnly);
737  pItem->pPostIt = pPostIt;
738  if (mpAnswer)
739  {
740  if (static_cast<bool>(pPostIt->CalcParent())) //do we really have another note in front of this one
741  pPostIt.get()->InitAnswer(mpAnswer);
742  delete mpAnswer;
743  mpAnswer = nullptr;
744  }
745  }
746 
747  pPostIt->SetChangeTracking(
748  pItem->mLayoutStatus,
750  pPostIt->SetSidebarPosition(pPage->eSidebarPosition);
751  pPostIt->SetFollow(static_cast<bool>(pPostIt->CalcParent()));
752  aPostItHeight = ( pPostIt->GetPostItTextHeight() < pPostIt->GetMinimumSizeWithoutMeta()
753  ? pPostIt->GetMinimumSizeWithoutMeta()
754  : pPostIt->GetPostItTextHeight() )
755  + pPostIt->GetMetaHeight();
756  pPostIt->SetPosSizePixelRect( mlPageBorder ,
758  GetSidebarWidth(true),
759  aPostItHeight,
760  pItem->maLayoutInfo.mPosition,
761  mlPageEnd );
762  pPostIt->ChangeSidebarItem( *pItem );
763 
764  if (pItem->bFocus)
765  {
766  mbLayout = true;
767  pPostIt->GrabFocus();
768  pItem->bFocus = false;
769  }
770  // only the visible postits are used for the final layout
771  aVisiblePostItList.push_back(pPostIt);
772  lNeededHeight += pPostIt->IsFollow() ? aPostItHeight : aPostItHeight+GetSpaceBetween();
773  }
774  else // we don't want to see it
775  {
776  if (pPostIt)
777  pPostIt->HideNote();
778  }
779  }
780 
781  if ((!aVisiblePostItList.empty()) && ShowNotes())
782  {
783  bool bOldScrollbar = pPage->bScrollbar;
784  if (ShowNotes())
785  pPage->bScrollbar = LayoutByPage(aVisiblePostItList, pPage->mPageRect.SVRect(), lNeededHeight);
786  else
787  pPage->bScrollbar = false;
788  if (!pPage->bScrollbar)
789  {
790  pPage->lOffset = 0;
791  }
792  else
793  {
794  //when we changed our zoom level, the offset value can be to big, so lets check for the largest possible zoom value
795  long aAvailableHeight = mpEditWin->LogicToPixel(Size(0,pPage->mPageRect.Height())).Height() - 2 * GetSidebarScrollerHeight();
796  long lOffset = -1 * GetScrollSize() * (aVisiblePostItList.size() - aAvailableHeight / GetScrollSize());
797  if (pPage->lOffset < lOffset)
798  pPage->lOffset = lOffset;
799  }
800  bUpdate = (bOldScrollbar != pPage->bScrollbar) || bUpdate;
801  const long aSidebarheight = pPage->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0;
802  /*
803  TODO
804  - enlarge all notes till GetNextBorder(), as we resized to average value before
805  */
806  //lets hide the ones which overlap the page
807  for (auto const& visiblePostIt : aVisiblePostItList)
808  {
809  if (pPage->lOffset != 0)
810  visiblePostIt->TranslateTopPosition(pPage->lOffset);
811 
812  bool bBottom = mpEditWin->PixelToLogic(Point(0,visiblePostIt->VirtualPos().Y()+visiblePostIt->VirtualSize().Height())).Y() <= (pPage->mPageRect.Bottom()-aSidebarheight);
813  bool bTop = mpEditWin->PixelToLogic(Point(0,visiblePostIt->VirtualPos().Y())).Y() >= (pPage->mPageRect.Top()+aSidebarheight);
814  if ( bBottom && bTop )
815  {
816  // When tiled rendering, make sure that only the
817  // view that has the comment focus emits callbacks,
818  // so the editing view jumps to the comment, but
819  // not the others.
820  bool bTiledPainting = comphelper::LibreOfficeKit::isTiledPainting();
821  if (!bTiledPainting)
822  // No focus -> disable callbacks.
823  comphelper::LibreOfficeKit::setTiledPainting(!visiblePostIt->HasChildPathFocus());
824  visiblePostIt->ShowNote();
825  if (!bTiledPainting)
826  {
828  visiblePostIt->InvalidateControl();
829  }
830  }
831  else
832  {
833  if (mpEditWin->PixelToLogic(Point(0,visiblePostIt->VirtualPos().Y())).Y() < (pPage->mPageRect.Top()+aSidebarheight))
834  {
835  if ( pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT )
836  visiblePostIt->ShowAnchorOnly(Point( pPage->mPageRect.Left(),
837  pPage->mPageRect.Top()));
838  else if ( pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::RIGHT )
839  visiblePostIt->ShowAnchorOnly(Point( pPage->mPageRect.Right(),
840  pPage->mPageRect.Top()));
841  }
842  else
843  {
844  if ( pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT )
845  visiblePostIt->ShowAnchorOnly(Point(pPage->mPageRect.Left(),
846  pPage->mPageRect.Bottom()));
847  else if ( pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::RIGHT )
848  visiblePostIt->ShowAnchorOnly(Point(pPage->mPageRect.Right(),
849  pPage->mPageRect.Bottom()));
850  }
851  OSL_ENSURE(pPage->bScrollbar,"SwPostItMgr::LayoutByPage(): note overlaps, but bScrollbar is not true");
852  }
853  }
854  }
855  else
856  {
857  for (auto const& visiblePostIt : aVisiblePostItList)
858  {
859  visiblePostIt->SetPosAndSize();
860  }
861 
862  bool bOldScrollbar = pPage->bScrollbar;
863  pPage->bScrollbar = false;
864  bUpdate = (bOldScrollbar != pPage->bScrollbar) || bUpdate;
865  }
866 
867  for (auto const& visiblePostIt : aVisiblePostItList)
868  {
870  {
871  if (visiblePostIt->GetSidebarItem().bPendingLayout)
872  lcl_CommentNotification(mpView, CommentNotificationType::Add, &visiblePostIt->GetSidebarItem(), 0);
873  else if (visiblePostIt->IsAnchorRectChanged())
874  {
875  lcl_CommentNotification(mpView, CommentNotificationType::Modify, &visiblePostIt->GetSidebarItem(), 0);
876  visiblePostIt->ResetAnchorRectChanged();
877  }
878  }
879 
880  // Layout for this post it finished now
881  visiblePostIt->GetSidebarItem().bPendingLayout = false;
882  }
883  }
884  else
885  {
886  if (pPage->bScrollbar)
887  bUpdate = true;
888  pPage->bScrollbar = false;
889  }
890  }
891 
892  if (!ShowNotes())
893  { // we do not want to see the notes anymore -> Options-Writer-View-Notes
895  bool bRepair = false;
896  for (auto const& postItField : mvPostItFields)
897  {
898  if (!postItField->UseElement(*mpWrtShell->GetLayout(), rIDRA))
899  {
900  OSL_FAIL("PostIt is not in doc!");
901  bRepair = true;
902  continue;
903  }
904 
905  if (postItField->pPostIt)
906  {
907  postItField->pPostIt->HideNote();
908  if (postItField->pPostIt->HasChildPathFocus())
909  {
910  SetActiveSidebarWin(nullptr);
911  postItField->pPostIt->GrabFocusToDocument();
912  }
913  }
914  }
915 
916  if ( bRepair )
918  }
919 
920  // notes scrollbar is otherwise not drawn correctly for some cases
921  // scrollbar area is enough
922  if (bUpdate)
923  mpEditWin->Invalidate(); /*This is a super expensive relayout and render of the entire page*/
924 
925  mbLayouting = false;
926  }
927 
928  if (bEnableMapMode)
929  mpEditWin->EnableMapMode(false);
930 }
931 
932 bool SwPostItMgr::BorderOverPageBorder(unsigned long aPage) const
933 {
934  if ( mPages[aPage-1]->mvSidebarItems.empty() )
935  {
936  OSL_FAIL("Notes SidePane painted but no rects and page lists calculated!");
937  return false;
938  }
939 
940  auto aItem = mPages[aPage-1]->mvSidebarItems.end();
941  --aItem;
942  OSL_ENSURE ((*aItem)->pPostIt,"BorderOverPageBorder: NULL postIt, should never happen");
943  if ((*aItem)->pPostIt)
944  {
945  const long aSidebarheight = mPages[aPage-1]->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0;
946  const long aEndValue = mpEditWin->PixelToLogic(Point(0,(*aItem)->pPostIt->GetPosPixel().Y()+(*aItem)->pPostIt->GetSizePixel().Height())).Y();
947  return aEndValue <= mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight;
948  }
949  else
950  return false;
951 }
952 
953 void SwPostItMgr::DrawNotesForPage(OutputDevice *pOutDev, sal_uInt32 nPage)
954 {
955  assert(nPage < mPages.size());
956  if (nPage >= mPages.size())
957  return;
958  for (auto const& pItem : mPages[nPage]->mvSidebarItems)
959  {
960  SwAnnotationWin* pPostIt = pItem->pPostIt;
961  if (!pPostIt)
962  continue;
963  Point aPoint(mpEditWin->PixelToLogic(pPostIt->GetPosPixel()));
964  Size aSize(pPostIt->PixelToLogic(pPostIt->GetSizePixel()));
965  pPostIt->Draw(pOutDev, aPoint, aSize, DrawFlags::NONE);
966  }
967 }
968 
970 {
971  for (std::unique_ptr<SwSidebarItem>& pItem : mvPostItFields)
972  {
973  SwAnnotationWin* pPostIt = pItem->pPostIt;
974  if (!pPostIt)
975  continue;
976 
977  bool bEnableMapMode = !mpEditWin->IsMapModeEnabled();
979  rRenderContext.Push(PushFlags::MAPMODE);
980  Point aOffset(mpEditWin->PixelToLogic(pPostIt->GetPosPixel()));
981  MapMode aMapMode(rRenderContext.GetMapMode());
982  aMapMode.SetOrigin(aMapMode.GetOrigin() + aOffset);
983  rRenderContext.SetMapMode(aMapMode);
984  Size aSize(rRenderContext.PixelToLogic(pPostIt->GetSizePixel()));
985  tools::Rectangle aRectangle(Point(0, 0), aSize);
986 
987  pPostIt->PaintTile(rRenderContext, aRectangle);
988 
989  rRenderContext.Pop();
990  if (bEnableMapMode)
991  mpEditWin->EnableMapMode(false);
992  }
993 }
994 
995 void SwPostItMgr::Scroll(const long lScroll,const unsigned long aPage)
996 {
997  OSL_ENSURE((lScroll % GetScrollSize() )==0,"SwPostItMgr::Scroll: scrolling by wrong value");
998  // do not scroll more than necessary up or down
999  if ( ((mPages[aPage-1]->lOffset == 0) && (lScroll>0)) || ( BorderOverPageBorder(aPage) && (lScroll<0)) )
1000  return;
1001 
1002  const bool bOldUp = ArrowEnabled(KEY_PAGEUP,aPage);
1003  const bool bOldDown = ArrowEnabled(KEY_PAGEDOWN,aPage);
1004  const long aSidebarheight = mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height();
1005  for (auto const& item : mPages[aPage-1]->mvSidebarItems)
1006  {
1007  SwAnnotationWin* pPostIt = item->pPostIt;
1008  // if this is an answer, we should take the normal position and not the real, slightly moved position
1009  pPostIt->SetVirtualPosSize(pPostIt->GetPosPixel(),pPostIt->GetSizePixel());
1010  pPostIt->TranslateTopPosition(lScroll);
1011 
1012  if (item->bShow)
1013  {
1014  bool bBottom = mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y()+pPostIt->VirtualSize().Height())).Y() <= (mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight);
1015  bool bTop = mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y())).Y() >= (mPages[aPage-1]->mPageRect.Top()+aSidebarheight);
1016  if ( bBottom && bTop)
1017  {
1018  pPostIt->ShowNote();
1019  }
1020  else
1021  {
1022  if ( mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y())).Y() < (mPages[aPage-1]->mPageRect.Top()+aSidebarheight))
1023  {
1024  if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT)
1025  pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Left(),mPages[aPage-1]->mPageRect.Top()));
1026  else if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SidebarPosition::RIGHT)
1027  pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Right(),mPages[aPage-1]->mPageRect.Top()));
1028  }
1029  else
1030  {
1031  if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT)
1032  pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Left(),mPages[aPage-1]->mPageRect.Bottom()));
1033  else if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SidebarPosition::RIGHT)
1034  pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Right(),mPages[aPage-1]->mPageRect.Bottom()));
1035  }
1036  }
1037  }
1038  }
1039  mPages[aPage-1]->lOffset += lScroll;
1040  if ( (bOldUp != ArrowEnabled(KEY_PAGEUP,aPage)) ||(bOldDown != ArrowEnabled(KEY_PAGEDOWN,aPage)) )
1041  {
1044  }
1045 }
1046 
1047 void SwPostItMgr::AutoScroll(const SwAnnotationWin* pPostIt,const unsigned long aPage )
1048 {
1049  // otherwise all notes are visible
1050  if (mPages[aPage-1]->bScrollbar)
1051  {
1052  const long aSidebarheight = mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height();
1053  const bool bBottom = mpEditWin->PixelToLogic(Point(0,pPostIt->GetPosPixel().Y()+pPostIt->GetSizePixel().Height())).Y() <= (mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight);
1054  const bool bTop = mpEditWin->PixelToLogic(Point(0,pPostIt->GetPosPixel().Y())).Y() >= (mPages[aPage-1]->mPageRect.Top()+aSidebarheight);
1055  if ( !(bBottom && bTop))
1056  {
1057  const long aDiff = bBottom ? mpEditWin->LogicToPixel(Point(0,mPages[aPage-1]->mPageRect.Top() + aSidebarheight)).Y() - pPostIt->GetPosPixel().Y() :
1058  mpEditWin->LogicToPixel(Point(0,mPages[aPage-1]->mPageRect.Bottom() - aSidebarheight)).Y() - (pPostIt->GetPosPixel().Y()+pPostIt->GetSizePixel().Height());
1059  // this just adds the missing value to get the next a* GetScrollSize() after aDiff
1060  // e.g aDiff= 61 POSTIT_SCROLL=50 --> lScroll = 100
1061  const auto nScrollSize = GetScrollSize();
1062  assert(nScrollSize);
1063  const long lScroll = bBottom ? (aDiff + ( nScrollSize - (aDiff % nScrollSize))) : (aDiff - (nScrollSize + (aDiff % nScrollSize)));
1064  Scroll(lScroll, aPage);
1065  }
1066  }
1067 }
1068 
1070 {
1071  long aPage = -1;
1072  // we don't know the page yet, lets find it ourselves
1073  std::vector<SwPostItPageItem*>::size_type n=0;
1074  for (auto const& page : mPages)
1075  {
1076  for (auto const& item : page->mvSidebarItems)
1077  {
1078  if (item->pPostIt==pPostIt)
1079  {
1080  aPage = n+1;
1081  break;
1082  }
1083  }
1084  ++n;
1085  }
1086  if (aPage!=-1)
1087  AutoScroll(pPostIt,aPage);
1088  tools::Rectangle aNoteRect (Point(pPostIt->GetPosPixel().X(),pPostIt->GetPosPixel().Y()-5),pPostIt->GetSizePixel());
1089  if (!aNoteRect.IsEmpty())
1091 }
1092 
1093 bool SwPostItMgr::ArrowEnabled(sal_uInt16 aDirection,unsigned long aPage) const
1094 {
1095  switch (aDirection)
1096  {
1097  case KEY_PAGEUP:
1098  {
1099  return (mPages[aPage-1]->lOffset != 0);
1100  }
1101  case KEY_PAGEDOWN:
1102  {
1103  return (!BorderOverPageBorder(aPage));
1104  }
1105  default: return false;
1106  }
1107 }
1108 
1109 Color SwPostItMgr::GetArrowColor(sal_uInt16 aDirection,unsigned long aPage) const
1110 {
1111  if (ArrowEnabled(aDirection,aPage))
1112  {
1113  if (Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1114  return COL_WHITE;
1115  else
1117  }
1118  else
1119  {
1121  }
1122 }
1123 
1124 bool SwPostItMgr::LayoutByPage(std::vector<SwAnnotationWin*> &aVisiblePostItList, const tools::Rectangle& rBorder, long lNeededHeight)
1125 {
1126  /*** General layout idea:***/
1127  // - if we have space left, we always move the current one up,
1128  // otherwise the next one down
1129  // - first all notes are resized
1130  // - then the real layout starts
1131 
1132  //rBorder is the page rect
1133  const tools::Rectangle aBorder = mpEditWin->LogicToPixel(rBorder);
1134  long lTopBorder = aBorder.Top() + 5;
1135  long lBottomBorder = aBorder.Bottom() - 5;
1136  const long lVisibleHeight = lBottomBorder - lTopBorder; //aBorder.GetHeight() ;
1137  const size_t nPostItListSize = aVisiblePostItList.size();
1138  long lTranslatePos = 0;
1139  bool bScrollbars = false;
1140 
1141  // do all necessary resizings
1142  if (nPostItListSize > 0 && lVisibleHeight < lNeededHeight)
1143  {
1144  // ok, now we have to really resize and adding scrollbars
1145  const long lAverageHeight = (lVisibleHeight - nPostItListSize*GetSpaceBetween()) / nPostItListSize;
1146  if (lAverageHeight<GetMinimumSizeWithMeta())
1147  {
1148  bScrollbars = true;
1149  lTopBorder += GetSidebarScrollerHeight() + 10;
1150  lBottomBorder -= (GetSidebarScrollerHeight() + 10);
1151  for (auto const& visiblePostIt : aVisiblePostItList)
1152  visiblePostIt->SetSize(Size(visiblePostIt->VirtualSize().getWidth(),visiblePostIt->GetMinimumSizeWithMeta()));
1153  }
1154  else
1155  {
1156  for (auto const& visiblePostIt : aVisiblePostItList)
1157  {
1158  if ( visiblePostIt->VirtualSize().getHeight() > lAverageHeight)
1159  visiblePostIt->SetSize(Size(visiblePostIt->VirtualSize().getWidth(),lAverageHeight));
1160  }
1161  }
1162  }
1163 
1164  //start the real layout so nothing overlaps anymore
1165  if (aVisiblePostItList.size()>1)
1166  {
1167  int loop = 0;
1168  bool bDone = false;
1169  // if no window is moved anymore we are finished
1170  while (!bDone)
1171  {
1172  loop++;
1173  bDone = true;
1174  long lSpaceUsed = lTopBorder + GetSpaceBetween();
1175  for(auto i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
1176  {
1177  auto aNextPostIt = i;
1178  ++aNextPostIt;
1179 
1180  if (aNextPostIt != aVisiblePostItList.end())
1181  {
1182  lTranslatePos = ( (*i)->VirtualPos().Y() + (*i)->VirtualSize().Height()) - (*aNextPostIt)->VirtualPos().Y();
1183  if (lTranslatePos > 0) // note windows overlaps the next one
1184  {
1185  // we are not done yet, loop at least once more
1186  bDone = false;
1187  // if there is space left, move the current note up
1188  // it could also happen that there is no space left for the first note due to a scrollbar
1189  // then we also jump into, so we move the current one up and the next one down
1190  if ( (lSpaceUsed <= (*i)->VirtualPos().Y()) || (i==aVisiblePostItList.begin()))
1191  {
1192  // we have space left, so let's move the current one up
1193  if ( ((*i)->VirtualPos().Y()- lTranslatePos - GetSpaceBetween()) > lTopBorder)
1194  {
1195  if ((*aNextPostIt)->IsFollow())
1196  (*i)->TranslateTopPosition(-1*(lTranslatePos+ANCHORLINE_WIDTH));
1197  else
1198  (*i)->TranslateTopPosition(-1*(lTranslatePos+GetSpaceBetween()));
1199  }
1200  else
1201  {
1202  long lMoveUp = (*i)->VirtualPos().Y() - lTopBorder;
1203  (*i)->TranslateTopPosition(-1* lMoveUp);
1204  if ((*aNextPostIt)->IsFollow())
1205  (*aNextPostIt)->TranslateTopPosition( (lTranslatePos+ANCHORLINE_WIDTH) - lMoveUp);
1206  else
1207  (*aNextPostIt)->TranslateTopPosition( (lTranslatePos+GetSpaceBetween()) - lMoveUp);
1208  }
1209  }
1210  else
1211  {
1212  // no space left, left move the next one down
1213  if ((*aNextPostIt)->IsFollow())
1214  (*aNextPostIt)->TranslateTopPosition(lTranslatePos+ANCHORLINE_WIDTH);
1215  else
1216  (*aNextPostIt)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
1217  }
1218  }
1219  else
1220  {
1221  // the first one could overlap the topborder instead of a second note
1222  if (i==aVisiblePostItList.begin())
1223  {
1224  long lMoveDown = lTopBorder - (*i)->VirtualPos().Y();
1225  if (lMoveDown>0)
1226  {
1227  bDone = false;
1228  (*i)->TranslateTopPosition( lMoveDown);
1229  }
1230  }
1231  }
1232  if ( (*aNextPostIt)->IsFollow() )
1233  lSpaceUsed += (*i)->VirtualSize().Height() + ANCHORLINE_WIDTH;
1234  else
1235  lSpaceUsed += (*i)->VirtualSize().Height() + GetSpaceBetween();
1236  }
1237  else
1238  {
1239  //(*i) is the last visible item
1240  auto aPrevPostIt = i;
1241  --aPrevPostIt;
1242  lTranslatePos = ( (*aPrevPostIt)->VirtualPos().Y() + (*aPrevPostIt)->VirtualSize().Height() ) - (*i)->VirtualPos().Y();
1243  if (lTranslatePos > 0)
1244  {
1245  bDone = false;
1246  if ( ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()+lTranslatePos) < lBottomBorder)
1247  {
1248  if ( (*i)->IsFollow() )
1249  (*i)->TranslateTopPosition(lTranslatePos+ANCHORLINE_WIDTH);
1250  else
1251  (*i)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
1252  }
1253  else
1254  {
1255  (*i)->TranslateTopPosition(lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()) );
1256  }
1257  }
1258  else
1259  {
1260  // note does not overlap, but we might be over the lower border
1261  // only do this if there are no scrollbars, otherwise notes are supposed to overlap the border
1262  if (!bScrollbars && ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height() > lBottomBorder) )
1263  {
1264  bDone = false;
1265  (*i)->TranslateTopPosition(lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()));
1266  }
1267  }
1268  }
1269  }
1270  // security check so we don't loop forever
1271  if (loop>MAX_LOOP_COUNT)
1272  {
1273  OSL_FAIL("PostItMgr::Layout(): We are looping forever");
1274  break;
1275  }
1276  }
1277  }
1278  else
1279  {
1280  // only one left, make sure it is not hidden at the top or bottom
1281  auto i = aVisiblePostItList.begin();
1282  lTranslatePos = lTopBorder - (*i)->VirtualPos().Y();
1283  if (lTranslatePos>0)
1284  {
1285  (*i)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
1286  }
1287  lTranslatePos = lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height());
1288  if (lTranslatePos<0)
1289  {
1290  (*i)->TranslateTopPosition(lTranslatePos);
1291  }
1292  }
1293  return bScrollbars;
1294  }
1295 
1296 void SwPostItMgr::AddPostIts(bool bCheckExistence, bool bFocus)
1297 {
1298  bool bEmpty = mvPostItFields.empty();
1300  SwIterator<SwFormatField,SwFieldType> aIter( *pType );
1301  SwFormatField* pSwFormatField = aIter.First();
1302  while(pSwFormatField)
1303  {
1304  if ( pSwFormatField->GetTextField())
1305  {
1307  if (pSwFormatField->IsFieldInDoc()
1309  || !sw::IsFieldDeletedInModel(rIDRA, *pSwFormatField->GetTextField())))
1310  {
1311  InsertItem(pSwFormatField,bCheckExistence,bFocus);
1312  }
1313  }
1314  pSwFormatField = aIter.Next();
1315  }
1316 
1317  // if we just added the first one we have to update the view for centering
1318  if (bEmpty && !mvPostItFields.empty())
1319  PrepareView(true);
1320 }
1321 
1323 {
1324  for (auto& postItField : mvPostItFields)
1325  {
1326  EndListening( *const_cast<SfxBroadcaster*>(postItField->GetBroadcaster()) );
1327  postItField->pPostIt.disposeAndClear();
1328  postItField.reset();
1329  }
1330  mvPostItFields.clear();
1331 
1332  // all postits removed, no items should be left in pages
1334 }
1335 
1337 {
1338 public:
1339  virtual bool operator()(const SwFormatField* pField) const = 0;
1340  virtual ~FilterFunctor() {}
1341 };
1342 
1344 {
1345 public:
1346  bool operator()(const SwFormatField* pField) const override
1347  {
1348  return pField->GetField()->GetTyp()->Which() == SwFieldIds::Postit;
1349  }
1350 };
1351 
1353 {
1354  OUString const m_sAuthor;
1355 public:
1356  explicit IsPostitFieldWithAuthorOf(const OUString &rAuthor)
1357  : m_sAuthor(rAuthor)
1358  {
1359  }
1360  bool operator()(const SwFormatField* pField) const override
1361  {
1362  if (pField->GetField()->GetTyp()->Which() != SwFieldIds::Postit)
1363  return false;
1364  return static_cast<const SwPostItField*>(pField->GetField())->GetPar1() == m_sAuthor;
1365  }
1366 };
1367 
1369 {
1370  sal_uInt32 const m_nPostItId;
1371 public:
1372  explicit IsPostitFieldWithPostitId(sal_uInt32 nPostItId)
1373  : m_nPostItId(nPostItId)
1374  {}
1375 
1376  bool operator()(const SwFormatField* pField) const override
1377  {
1378  if (pField->GetField()->GetTyp()->Which() != SwFieldIds::Postit)
1379  return false;
1380  return static_cast<const SwPostItField*>(pField->GetField())->GetPostItId() == m_nPostItId;
1381  }
1382 };
1383 
1385 {
1386 private:
1389 
1390 public:
1392  const FilterFunctor & rNext)
1393  : m_rIDRA(rIDRA)
1394  , m_rNext(rNext)
1395  {
1396  }
1397  bool operator()(const SwFormatField* pField) const override
1398  {
1399  if (!m_rNext(pField))
1400  return false;
1401  if (!pField->GetTextField())
1402  return false;
1403  return !sw::IsFieldDeletedInModel(m_rIDRA, *pField->GetTextField());
1404  }
1405 };
1406 
1407 //Manages the passed in vector by automatically removing entries if they are deleted
1408 //and automatically adding entries if they appear in the document and match the
1409 //functor.
1410 //
1411 //This will completely refill in the case of a "anonymous" NULL pField stating
1412 //rather unhelpfully that "something changed" so you may process the same
1413 //Fields more than once.
1415 {
1416  std::vector<std::unique_ptr<SwSidebarItem>>& sidebarItemVector;
1417  std::vector<const SwFormatField*> v;
1420 
1421  virtual void Notify(SfxBroadcaster&, const SfxHint& rHint) override
1422  {
1423  const SwFormatFieldHint* pHint = dynamic_cast<const SwFormatFieldHint*>(&rHint);
1424  if (pHint)
1425  {
1426  bool bAllInvalidated = false;
1427  if (pHint->Which() == SwFormatFieldHintWhich::REMOVED)
1428  {
1429  const SwFormatField* pField = pHint->GetField();
1430  bAllInvalidated = pField == nullptr;
1431  if (!bAllInvalidated && m_rFilter(pField))
1432  {
1433  EndListening(const_cast<SwFormatField&>(*pField));
1434  v.erase(std::remove(v.begin(), v.end(), pField), v.end());
1435  }
1436  }
1437  else if (pHint->Which() == SwFormatFieldHintWhich::INSERTED)
1438  {
1439  const SwFormatField* pField = pHint->GetField();
1440  bAllInvalidated = pField == nullptr;
1441  if (!bAllInvalidated && m_rFilter(pField))
1442  {
1443  StartListening(const_cast<SwFormatField&>(*pField));
1444  v.push_back(pField);
1445  }
1446  }
1447 
1448  if (bAllInvalidated)
1449  FillVector();
1450 
1451  return;
1452  }
1453  }
1454 
1455 public:
1456  FieldDocWatchingStack(std::vector<std::unique_ptr<SwSidebarItem>>& in, SwDocShell &rDocShell, FilterFunctor& rFilter)
1457  : sidebarItemVector(in)
1458  , m_rDocShell(rDocShell)
1459  , m_rFilter(rFilter)
1460  {
1461  FillVector();
1462  StartListening(m_rDocShell);
1463  }
1464  void FillVector()
1465  {
1467  v.clear();
1468  v.reserve(sidebarItemVector.size());
1469  for (auto const& p : sidebarItemVector)
1470  {
1471  const SwFormatField& rField = p->GetFormatField();
1472  if (!m_rFilter(&rField))
1473  continue;
1474  StartListening(const_cast<SwFormatField&>(rField));
1475  v.push_back(&rField);
1476  }
1477  }
1479  {
1480  for (auto const& pField : v)
1481  {
1482  EndListening(const_cast<SwFormatField&>(*pField));
1483  }
1484  }
1485  virtual ~FieldDocWatchingStack() override
1486  {
1488  EndListening(m_rDocShell);
1489  }
1491  {
1492  if (v.empty())
1493  return nullptr;
1494  const SwFormatField* p = v.back();
1495  EndListening(const_cast<SwFormatField&>(*p));
1496  v.pop_back();
1497  return p;
1498  }
1499 };
1500 
1501 // copy to new vector, otherwise RemoveItem would operate and delete stuff on mvPostItFields as well
1502 // RemoveItem will clean up the core field and visible postit if necessary
1503 // we cannot just delete everything as before, as postits could move into change tracking
1504 void SwPostItMgr::Delete(const OUString& rAuthor)
1505 {
1507  if (HasActiveSidebarWin() && (GetActiveSidebarWin()->GetAuthor() == rAuthor))
1508  {
1509  SetActiveSidebarWin(nullptr);
1510  }
1511  SwRewriter aRewriter;
1512  aRewriter.AddRule(UndoArg1, SwResId(STR_DELETE_AUTHOR_NOTES) + rAuthor);
1513  mpWrtShell->StartUndo( SwUndoId::DELETE, &aRewriter );
1514 
1515  IsPostitFieldWithAuthorOf aFilter(rAuthor);
1517  IsFieldNotDeleted aFilter2(rIDRA, aFilter);
1518  FieldDocWatchingStack aStack(mvPostItFields, *mpView->GetDocShell(), aFilter2);
1519  while (const SwFormatField* pField = aStack.pop())
1520  {
1521  if (mpWrtShell->GotoField(*pField))
1522  mpWrtShell->DelRight();
1523  }
1524  mpWrtShell->EndUndo();
1525  PrepareView();
1527  mbLayout = true;
1528  CalcRects();
1529  LayoutPostIts();
1530 }
1531 
1532 void SwPostItMgr::Delete(sal_uInt32 nPostItId)
1533 {
1535  if (HasActiveSidebarWin() &&
1536  mpActivePostIt.get()->GetPostItField()->GetPostItId() == nPostItId)
1537  {
1538  SetActiveSidebarWin(nullptr);
1539  }
1540  SwRewriter aRewriter;
1541  aRewriter.AddRule(UndoArg1, SwResId(STR_CONTENT_TYPE_SINGLE_POSTIT));
1542  mpWrtShell->StartUndo( SwUndoId::DELETE, &aRewriter );
1543 
1544  IsPostitFieldWithPostitId aFilter(nPostItId);
1546  IsFieldNotDeleted aFilter2(rIDRA, aFilter);
1547  FieldDocWatchingStack aStack(mvPostItFields, *mpView->GetDocShell(), aFilter2);
1548  const SwFormatField* pField = aStack.pop();
1549  if (pField && mpWrtShell->GotoField(*pField))
1550  mpWrtShell->DelRight();
1551  mpWrtShell->EndUndo();
1552  PrepareView();
1554  mbLayout = true;
1555  CalcRects();
1556  LayoutPostIts();
1557 }
1558 
1560 {
1562  SetActiveSidebarWin(nullptr);
1563  SwRewriter aRewriter;
1564  aRewriter.AddRule(UndoArg1, SwResId(STR_DELETE_ALL_NOTES) );
1565  mpWrtShell->StartUndo( SwUndoId::DELETE, &aRewriter );
1566 
1567  IsPostitField aFilter;
1569  IsFieldNotDeleted aFilter2(rIDRA, aFilter);
1571  aFilter2);
1572  while (const SwFormatField* pField = aStack.pop())
1573  {
1574  if (mpWrtShell->GotoField(*pField))
1575  mpWrtShell->DelRight();
1576  }
1577 
1578  mpWrtShell->EndUndo();
1579  PrepareView();
1581  mbLayout = true;
1582  CalcRects();
1583  LayoutPostIts();
1584 }
1585 
1587 {
1588  if (mvPostItFields.empty())
1589  return;
1591  sw::annotation::SwAnnotationWin *pWin = pOrigActiveWin;
1592  if (!pWin)
1593  {
1594  for (auto const& postItField : mvPostItFields)
1595  {
1596  pWin = postItField->pPostIt;
1597  if (pWin)
1598  break;
1599  }
1600  }
1601  if (!pWin)
1602  return;
1603  SetActiveSidebarWin(pWin);
1604  OutlinerView* pOLV = pWin->GetOutlinerView();
1605  SfxItemSet aEditAttr(pOLV->GetAttribs());
1608  aDlgAttr.Put(aEditAttr);
1611  sal_uInt16 nRet = pDlg->Execute();
1612  if (RET_OK == nRet)
1613  {
1614  aDlgAttr.Put(*pDlg->GetOutputItemSet());
1615  FormatAll(aDlgAttr);
1616  }
1617  pDlg.disposeAndClear();
1618  SetActiveSidebarWin(pOrigActiveWin);
1619 }
1620 
1621 void SwPostItMgr::FormatAll(const SfxItemSet &rNewAttr)
1622 {
1624  SwRewriter aRewriter;
1625  aRewriter.AddRule(UndoArg1, SwResId(STR_FORMAT_ALL_NOTES) );
1626  mpWrtShell->StartUndo( SwUndoId::INSATTR, &aRewriter );
1627 
1628  for (auto const& postItField : mvPostItFields)
1629  {
1630  if (!postItField->pPostIt)
1631  continue;
1632  OutlinerView* pOLV = postItField->pPostIt->GetOutlinerView();
1633  //save old selection
1634  ESelection aOrigSel(pOLV->GetSelection());
1635  //select all
1636  Outliner *pOutliner = pOLV->GetOutliner();
1637  if (pOutliner)
1638  {
1639  sal_Int32 nParaCount = pOutliner->GetParagraphCount();
1640  if (nParaCount > 0)
1641  pOLV->SelectRange(0, nParaCount);
1642  }
1643  //set new char properties
1644  pOLV->SetAttribs(rNewAttr);
1645  //restore old selection
1646  pOLV->SetSelection(aOrigSel);
1647  // tdf#91596 store updated formatting in SwField
1648  postItField->pPostIt->UpdateData();
1649  }
1650 
1651  mpWrtShell->EndUndo();
1652  PrepareView();
1654  mbLayout = true;
1655  CalcRects();
1656  LayoutPostIts();
1657 }
1658 
1659 void SwPostItMgr::Hide( const OUString& rAuthor )
1660 {
1661  for (auto const& postItField : mvPostItFields)
1662  {
1663  if ( postItField->pPostIt && (postItField->pPostIt->GetAuthor() == rAuthor) )
1664  {
1665  postItField->bShow = false;
1666  postItField->pPostIt->HideNote();
1667  }
1668  }
1669 
1670  LayoutPostIts();
1671 }
1672 
1674 {
1675  for (auto const& postItField : mvPostItFields)
1676  {
1677  postItField->bShow = false;
1678  postItField->pPostIt->HideNote();
1679  }
1680 }
1681 
1683 {
1684  for (auto const& postItField : mvPostItFields)
1685  {
1686  postItField->bShow = true;
1687  }
1688  LayoutPostIts();
1689 }
1690 
1692 {
1693  for (auto const& postItField : mvPostItFields)
1694  {
1695  if ( postItField->GetBroadcaster() == pBroadcaster)
1696  return postItField->pPostIt;
1697  }
1698  return nullptr;
1699 }
1700 
1702 {
1703  for (auto const& postItField : mvPostItFields)
1704  {
1705  if ( postItField->GetFormatField().GetField() == pField )
1706  return postItField->pPostIt.get();
1707  }
1708  return nullptr;
1709 }
1710 
1712 {
1713  for (auto const& postItField : mvPostItFields)
1714  {
1715  if ( static_cast<const SwPostItField*>(postItField->GetFormatField().GetField())->GetPostItId() == nPostItId )
1716  return postItField->pPostIt.get();
1717  }
1718  return nullptr;
1719 }
1720 
1722  SwAnnotationWin* aPostIt )
1723 {
1724  if (mvPostItFields.size()>1)
1725  {
1726  auto i = std::find_if(mvPostItFields.begin(), mvPostItFields.end(),
1727  [&aPostIt](const std::unique_ptr<SwSidebarItem>& pField) { return pField->pPostIt == aPostIt; });
1728  if (i == mvPostItFields.end())
1729  return nullptr;
1730 
1731  auto iNextPostIt = i;
1732  if (aDirection == KEY_PAGEUP)
1733  {
1734  if ( iNextPostIt == mvPostItFields.begin() )
1735  {
1736  return nullptr;
1737  }
1738  --iNextPostIt;
1739  }
1740  else
1741  {
1742  ++iNextPostIt;
1743  if ( iNextPostIt == mvPostItFields.end() )
1744  {
1745  return nullptr;
1746  }
1747  }
1748  // lets quit, we are back at the beginning
1749  if ( (*iNextPostIt)->pPostIt == aPostIt)
1750  return nullptr;
1751  return (*iNextPostIt)->pPostIt;
1752  }
1753  else
1754  return nullptr;
1755 }
1756 
1758 {
1759  for (auto const& pPage : mPages)
1760  {
1761  for(auto b = pPage->mvSidebarItems.begin(); b!= pPage->mvSidebarItems.end(); ++b)
1762  {
1763  if ((*b)->pPostIt == mpActivePostIt)
1764  {
1765  auto aNext = b;
1766  ++aNext;
1767  bool bFollow = (aNext != pPage->mvSidebarItems.end()) && (*aNext)->pPostIt->IsFollow();
1768  if ( pPage->bScrollbar || bFollow )
1769  {
1770  return -1;
1771  }
1772  else
1773  {
1774  //if this is the last item, return the bottom border otherwise the next item
1775  if (aNext == pPage->mvSidebarItems.end())
1776  return mpEditWin->LogicToPixel(Point(0,pPage->mPageRect.Bottom())).Y() - GetSpaceBetween();
1777  else
1778  return (*aNext)->pPostIt->GetPosPixel().Y() - GetSpaceBetween();
1779  }
1780  }
1781  }
1782  }
1783 
1784  OSL_FAIL("SwPostItMgr::GetNextBorder(): We have to find a next border here");
1785  return -1;
1786 }
1787 
1788 void SwPostItMgr::SetShadowState(const SwPostItField* pField,bool bCursor)
1789 {
1790  if (pField)
1791  {
1792  if (pField !=mShadowState.mpShadowField)
1793  {
1795  {
1796  // reset old one if still alive
1797  // TODO: does not work properly if mouse and cursor was set
1798  sw::annotation::SwAnnotationWin* pOldPostIt =
1800  if (pOldPostIt && pOldPostIt->Shadow() && (pOldPostIt->Shadow()->GetShadowState() != SS_EDIT))
1801  pOldPostIt->SetViewState(ViewState::NORMAL);
1802  }
1803  //set new one, if it is not currently edited
1804  sw::annotation::SwAnnotationWin* pNewPostIt = GetAnnotationWin(pField);
1805  if (pNewPostIt && pNewPostIt->Shadow() && (pNewPostIt->Shadow()->GetShadowState() != SS_EDIT))
1806  {
1807  pNewPostIt->SetViewState(ViewState::VIEW);
1808  //remember our new field
1809  mShadowState.mpShadowField = pField;
1810  mShadowState.bCursor = false;
1811  mShadowState.bMouse = false;
1812  }
1813  }
1814  if (bCursor)
1815  mShadowState.bCursor = true;
1816  else
1817  mShadowState.bMouse = true;
1818  }
1819  else
1820  {
1822  {
1823  if (bCursor)
1824  mShadowState.bCursor = false;
1825  else
1826  mShadowState.bMouse = false;
1828  {
1829  // reset old one if still alive
1831  if (pOldPostIt && pOldPostIt->Shadow() && (pOldPostIt->Shadow()->GetShadowState() != SS_EDIT))
1832  {
1833  pOldPostIt->SetViewState(ViewState::NORMAL);
1834  mShadowState.mpShadowField = nullptr;
1835  }
1836  }
1837  }
1838  }
1839 }
1840 
1841 void SwPostItMgr::PrepareView(bool bIgnoreCount)
1842 {
1843  if (!HasNotes() || bIgnoreCount)
1844  {
1846  SwRootFrame* pLayout = mpWrtShell->GetLayout();
1847  if ( pLayout )
1851  }
1852 }
1853 
1854 bool SwPostItMgr::ShowScrollbar(const unsigned long aPage) const
1855 {
1856  if (mPages.size() > aPage-1)
1857  return (mPages[aPage-1]->bScrollbar && !mbWaitingForCalcRects);
1858  else
1859  return false;
1860 }
1861 
1862 bool SwPostItMgr::IsHit(const Point &aPointPixel)
1863 {
1864  if (HasNotes() && ShowNotes())
1865  {
1866  const Point aPoint = mpEditWin->PixelToLogic(aPointPixel);
1867  const SwRootFrame* pLayout = mpWrtShell->GetLayout();
1868  SwRect aPageFrame;
1869  const unsigned long nPageNum = SwPostItHelper::getPageInfo( aPageFrame, pLayout, aPoint );
1870  if( nPageNum )
1871  {
1872  tools::Rectangle aRect;
1873  OSL_ENSURE(mPages.size()>nPageNum-1,"SwPostitMgr:: page container size wrong");
1874  aRect = mPages[nPageNum-1]->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT
1875  ? tools::Rectangle(Point(aPageFrame.Left()-GetSidebarWidth()-GetSidebarBorderWidth(),aPageFrame.Top()),Size(GetSidebarWidth(),aPageFrame.Height()))
1876  : tools::Rectangle( Point(aPageFrame.Right()+GetSidebarBorderWidth(),aPageFrame.Top()) , Size(GetSidebarWidth(),aPageFrame.Height()));
1877  if (aRect.IsInside(aPoint))
1878  {
1879  // we hit the note's sidebar
1880  // lets now test for the arrow area
1881  if (mPages[nPageNum-1]->bScrollbar)
1882  return ScrollbarHit(nPageNum,aPoint);
1883  else
1884  return false;
1885  }
1886  }
1887  }
1888  return false;
1889 }
1890 
1892 {
1893  vcl::Window* pRet = nullptr;
1894 
1895  if (HasNotes() && ShowNotes())
1896  {
1897  bool bEnableMapMode = !mpEditWin->IsMapModeEnabled();
1898  if (bEnableMapMode)
1900 
1901  for (std::unique_ptr<SwSidebarItem>& pItem : mvPostItFields)
1902  {
1903  SwAnnotationWin* pPostIt = pItem->pPostIt;
1904  if (!pPostIt)
1905  continue;
1906 
1907  if (pPostIt->IsHitWindow(rPointLogic))
1908  {
1909  pRet = pPostIt;
1910  break;
1911  }
1912  }
1913 
1914  if (bEnableMapMode)
1915  mpEditWin->EnableMapMode(false);
1916  }
1917 
1918  return pRet;
1919 }
1920 
1921 tools::Rectangle SwPostItMgr::GetBottomScrollRect(const unsigned long aPage) const
1922 {
1923  SwRect aPageRect = mPages[aPage-1]->mPageRect;
1924  Point aPointBottom = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT
1925  ? Point(aPageRect.Left() - GetSidebarWidth() - GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height())
1926  : Point(aPageRect.Right() + GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height());
1928  return tools::Rectangle(aPointBottom,aSize);
1929 }
1930 
1931 tools::Rectangle SwPostItMgr::GetTopScrollRect(const unsigned long aPage) const
1932 {
1933  SwRect aPageRect = mPages[aPage-1]->mPageRect;
1934  Point aPointTop = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT
1935  ? Point(aPageRect.Left() - GetSidebarWidth() -GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height())
1936  : Point(aPageRect.Right() + GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height());
1938  return tools::Rectangle(aPointTop,aSize);
1939 }
1940 
1941 //IMPORTANT: if you change the rects here, also change SwPageFrame::PaintNotesSidebar()
1942 bool SwPostItMgr::ScrollbarHit(const unsigned long aPage,const Point &aPoint)
1943 {
1944  SwRect aPageRect = mPages[aPage-1]->mPageRect;
1945  Point aPointBottom = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT
1946  ? Point(aPageRect.Left() - GetSidebarWidth()-GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height())
1947  : Point(aPageRect.Right() + GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height());
1948 
1949  Point aPointTop = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT
1950  ? Point(aPageRect.Left() - GetSidebarWidth()-GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height())
1951  : Point(aPageRect.Right()+GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height());
1952 
1953  tools::Rectangle aRectBottom(GetBottomScrollRect(aPage));
1954  tools::Rectangle aRectTop(GetTopScrollRect(aPage));
1955 
1956  if (aRectBottom.IsInside(aPoint))
1957  {
1958  if (aPoint.X() < long((aPointBottom.X() + GetSidebarWidth()/3)))
1959  Scroll( GetScrollSize(),aPage);
1960  else
1961  Scroll( -1*GetScrollSize(), aPage);
1962  return true;
1963  }
1964  else if (aRectTop.IsInside(aPoint))
1965  {
1966  if (aPoint.X() < long((aPointTop.X() + GetSidebarWidth()/3*2)))
1967  Scroll(GetScrollSize(), aPage);
1968  else
1969  Scroll(-1*GetScrollSize(), aPage);
1970  return true;
1971  }
1972  return false;
1973 }
1974 
1976 {
1977  if ( mbWaitingForCalcRects || mbLayouting || mvPostItFields.empty() )
1978  return;
1979 
1980  // find first valid note
1981  SwAnnotationWin *pFirstPostIt = nullptr;
1982  for (auto const& postItField : mvPostItFields)
1983  {
1984  pFirstPostIt = postItField->pPostIt;
1985  if (pFirstPostIt)
1986  break;
1987  }
1988 
1989  //if we have not found a valid note, forget about it and leave
1990  if (!pFirstPostIt)
1991  return;
1992 
1993  // 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
1994  // check, if anchor overlay object exists.
1995  const long aAnchorX = pFirstPostIt->Anchor()
1996  ? mpEditWin->LogicToPixel( Point(static_cast<long>(pFirstPostIt->Anchor()->GetSixthPosition().getX()),0)).X()
1997  : 0;
1998  const long aAnchorY = pFirstPostIt->Anchor()
1999  ? mpEditWin->LogicToPixel( Point(0,static_cast<long>(pFirstPostIt->Anchor()->GetSixthPosition().getY()))).Y() + 1
2000  : 0;
2001  if (Point(aAnchorX,aAnchorY) != pFirstPostIt->GetPosPixel())
2002  {
2003  long aAnchorPosX = 0;
2004  long aAnchorPosY = 0;
2005  for (std::unique_ptr<SwPostItPageItem>& pPage : mPages)
2006  {
2007  for (auto const& item : pPage->mvSidebarItems)
2008  {
2009  // check, if anchor overlay object exists.
2010  if ( item->bShow && item->pPostIt && item->pPostIt->Anchor() )
2011  {
2012  aAnchorPosX = pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT
2013  ? mpEditWin->LogicToPixel( Point(static_cast<long>(item->pPostIt->Anchor()->GetSeventhPosition().getX()),0)).X()
2014  : mpEditWin->LogicToPixel( Point(static_cast<long>(item->pPostIt->Anchor()->GetSixthPosition().getX()),0)).X();
2015  aAnchorPosY = mpEditWin->LogicToPixel( Point(0,static_cast<long>(item->pPostIt->Anchor()->GetSixthPosition().getY()))).Y() + 1;
2016  item->pPostIt->SetPosPixel(Point(aAnchorPosX,aAnchorPosY));
2017  }
2018  }
2019  }
2020  }
2021 }
2022 
2024 {
2025  // we only want to see notes if Options - Writer - View - Notes is ticked
2026  return mpWrtShell->GetViewOptions()->IsPostIts();
2027 }
2028 
2030 {
2031  return !mvPostItFields.empty();
2032 }
2033 
2034 unsigned long SwPostItMgr::GetSidebarWidth(bool bPx) const
2035 {
2036  bool bEnableMapMode = !mpWrtShell->GetOut()->IsMapModeEnabled();
2037  sal_uInt16 nZoom = mpWrtShell->GetViewOptions()->GetZoom();
2038  if (comphelper::LibreOfficeKit::isActive() && !bEnableMapMode)
2039  {
2040  // The output device is the tile and contains the real wanted scale factor.
2041  double fScaleX = double(mpWrtShell->GetOut()->GetMapMode().GetScaleX());
2042  nZoom = fScaleX * 100;
2043  }
2044  unsigned long aWidth = static_cast<unsigned long>(nZoom * 1.8);
2045 
2046  if (bPx)
2047  return aWidth;
2048  else
2049  {
2050  if (bEnableMapMode)
2051  // The output device is the window.
2053  long nRet = mpWrtShell->GetOut()->PixelToLogic(Size(aWidth, 0)).Width();
2054  if (bEnableMapMode)
2055  mpWrtShell->GetOut()->EnableMapMode(false);
2056  return nRet;
2057  }
2058 }
2059 
2060 unsigned long SwPostItMgr::GetSidebarBorderWidth(bool bPx) const
2061 {
2062  if (bPx)
2063  return 2;
2064  else
2065  return mpWrtShell->GetOut()->PixelToLogic(Size(2,0)).Width();
2066 }
2067 
2068 Color SwPostItMgr::GetColorDark(std::size_t aAuthorIndex)
2069 {
2070  if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
2071  {
2072  static const Color aArrayNormal[] = {
2076 
2077  return aArrayNormal[ aAuthorIndex % SAL_N_ELEMENTS( aArrayNormal )];
2078  }
2079  else
2080  return COL_WHITE;
2081 }
2082 
2083 Color SwPostItMgr::GetColorLight(std::size_t aAuthorIndex)
2084 {
2085  if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
2086  {
2087  static const Color aArrayLight[] = {
2091 
2092  return aArrayLight[ aAuthorIndex % SAL_N_ELEMENTS( aArrayLight )];
2093  }
2094  else
2095  return COL_WHITE;
2096 }
2097 
2098 Color SwPostItMgr::GetColorAnchor(std::size_t aAuthorIndex)
2099 {
2100  if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
2101  {
2102  static const Color aArrayAnchor[] = {
2106 
2107  return aArrayAnchor[ aAuthorIndex % SAL_N_ELEMENTS( aArrayAnchor )];
2108  }
2109  else
2110  return COL_WHITE;
2111 }
2112 
2114 {
2115  if ( p != mpActivePostIt )
2116  {
2117  // we need the temp variable so we can set mpActivePostIt before we call DeactivatePostIt
2118  // therefore we get a new layout in DOCCHANGED when switching from postit to document,
2119  // otherwise, GetActivePostIt() would still hold our old postit
2120  SwAnnotationWin* pActive = mpActivePostIt;
2121  mpActivePostIt = p;
2122  if (pActive)
2123  {
2124  pActive->DeactivatePostIt();
2125  mShadowState.mpShadowField = nullptr;
2126  }
2127  if (mpActivePostIt)
2128  {
2130  mpView->AttrChangedNotify(nullptr);
2132  }
2133  }
2134 }
2135 
2136 IMPL_LINK_NOARG( SwPostItMgr, CalcHdl, void*, void )
2137 {
2138  mnEventId = nullptr;
2139  if ( mbLayouting )
2140  {
2141  OSL_FAIL("Reentrance problem in Layout Manager!");
2142  mbWaitingForCalcRects = false;
2143  return;
2144  }
2145 
2146  // do not change order, even if it would seem so in the first place, we need the calcrects always
2147  if (CalcRects() || mbLayout)
2148  {
2149  mbLayout = false;
2150  LayoutPostIts();
2151  }
2152 }
2153 
2155 {
2156  for (auto const& postItField : mvPostItFields)
2157  if ( postItField->pPostIt )
2158  postItField->pPostIt->Rescale();
2159 }
2160 
2162 {
2163  const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
2164  return sal_Int32(POSTIT_INITIAL_ANCHOR_DISTANCE * f);
2165 }
2166 
2168 {
2169  const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
2170  return sal_Int32(POSTIT_SPACE_BETWEEN * f);
2171 }
2172 
2174 {
2175  const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
2176  return sal_Int32((POSTIT_SPACE_BETWEEN + POSTIT_MINIMUMSIZE_WITH_META) * f);
2177 }
2178 
2180 {
2181  const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
2182  return sal_Int32(POSTIT_MINIMUMSIZE_WITH_META * f);
2183 }
2184 
2186 {
2187  const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
2188  return sal_Int32(POSTIT_SCROLL_SIDEBAR_HEIGHT * f);
2189 }
2190 
2192 {
2193  for (auto const& postItField : mvPostItFields)
2194  if ( postItField->pPostIt )
2195  postItField->pPostIt->SetSpellChecking();
2196 }
2197 
2199 {
2200  for (auto const& postItField : mvPostItFields)
2201  if ( postItField->pPostIt )
2202  postItField->pPostIt->SetReadonly( mbReadOnly );
2203 }
2204 
2206 {
2207  for (auto const& postItField : mvPostItFields)
2208  if ( postItField->pPostIt )
2209  postItField->pPostIt->CheckMetaText();
2210 
2211 }
2212 
2213 sal_uInt16 SwPostItMgr::Replace(SvxSearchItem const * pItem)
2214 {
2216  sal_uInt16 aResult = pWin->GetOutlinerView()->StartSearchAndReplace( *pItem );
2217  if (!aResult)
2218  SetActiveSidebarWin(nullptr);
2219  return aResult;
2220 }
2221 
2222 sal_uInt16 SwPostItMgr::FinishSearchReplace(const i18nutil::SearchOptions2& rSearchOptions, bool bSrchForward)
2223 {
2225  SvxSearchItem aItem(SID_SEARCH_ITEM );
2226  aItem.SetSearchOptions(rSearchOptions);
2227  aItem.SetBackward(!bSrchForward);
2228  sal_uInt16 aResult = pWin->GetOutlinerView()->StartSearchAndReplace( aItem );
2229  if (!aResult)
2230  SetActiveSidebarWin(nullptr);
2231  return aResult;
2232 }
2233 
2234 sal_uInt16 SwPostItMgr::SearchReplace(const SwFormatField &pField, const i18nutil::SearchOptions2& rSearchOptions, bool bSrchForward)
2235 {
2236  sal_uInt16 aResult = 0;
2237  SwAnnotationWin* pWin = GetSidebarWin(&pField);
2238  if (pWin)
2239  {
2240  ESelection aOldSelection = pWin->GetOutlinerView()->GetSelection();
2241  if (bSrchForward)
2242  pWin->GetOutlinerView()->SetSelection(ESelection(0,0,0,0));
2243  else
2244  pWin->GetOutlinerView()->SetSelection(
2246  SvxSearchItem aItem(SID_SEARCH_ITEM );
2247  aItem.SetSearchOptions(rSearchOptions);
2248  aItem.SetBackward(!bSrchForward);
2249  aResult = pWin->GetOutlinerView()->StartSearchAndReplace( aItem );
2250  if (!aResult)
2251  pWin->GetOutlinerView()->SetSelection(aOldSelection);
2252  else
2253  {
2254  SetActiveSidebarWin(pWin);
2255  MakeVisible(pWin);
2256  }
2257  }
2258  return aResult;
2259 }
2260 
2262 {
2263  // deselect any drawing or frame and leave editing mode
2264  SdrView* pSdrView = mpWrtShell->GetDrawView();
2265  if ( pSdrView && pSdrView->IsTextEdit() )
2266  {
2267  bool bLockView = mpWrtShell->IsViewLocked();
2268  mpWrtShell->LockView( true );
2270  mpWrtShell->LockView( bLockView );
2271  }
2272 
2274  {
2279 
2282  }
2283 }
2284 
2286 {
2287  return mpActivePostIt != nullptr;
2288 }
2289 
2291 {
2292  return HasActiveSidebarWin() &&
2293  mpActivePostIt != nullptr;
2294 }
2295 
2297 {
2298  if ( HasActiveSidebarWin() )
2299  {
2301  }
2302 }
2303 
2305 {
2306  if ( HasActiveSidebarWin() )
2307  {
2309  }
2310 }
2311 
2313 {
2314  if ( HasActiveSidebarWin() )
2315  {
2317  }
2318 }
2319 
2321 {
2322  if ( HasActiveSidebarWin() )
2323  {
2324  mpActivePostIt->Hide();
2325  }
2326 }
2327 
2329 {
2330  if ( HasActiveSidebarWin() )
2331  {
2333  }
2334 }
2335 
2337  const SwFormatField& rFormatField,
2338  SwAnnotationWin& rSidebarWin )
2339 {
2340  if ( mpFrameSidebarWinContainer == nullptr )
2341  {
2343  }
2344 
2345  const bool bInserted = mpFrameSidebarWinContainer->insert( rFrame, rFormatField, rSidebarWin );
2346  if ( bInserted &&
2348  {
2349  mpWrtShell->GetAccessibleMap()->InvalidatePosOrSize( nullptr, nullptr, &rSidebarWin, SwRect() );
2350  }
2351 }
2352 
2354  SwAnnotationWin& rSidebarWin )
2355 {
2356  if ( mpFrameSidebarWinContainer != nullptr )
2357  {
2358  const bool bRemoved = mpFrameSidebarWinContainer->remove( rFrame, rSidebarWin );
2359  if ( bRemoved &&
2361  {
2362  mpWrtShell->GetAccessibleMap()->A11yDispose( nullptr, nullptr, &rSidebarWin );
2363  }
2364  }
2365 }
2366 
2368 {
2369  bool bRet( false );
2370 
2371  if ( mpFrameSidebarWinContainer != nullptr )
2372  {
2373  bRet = !mpFrameSidebarWinContainer->empty( rFrame );
2374  }
2375 
2376  return bRet;
2377 }
2378 
2380  const sal_Int32 nIndex )
2381 {
2382  vcl::Window* pSidebarWin( nullptr );
2383 
2384  if ( mpFrameSidebarWinContainer != nullptr )
2385  {
2386  pSidebarWin = mpFrameSidebarWinContainer->get( rFrame, nIndex );
2387  }
2388 
2389  return pSidebarWin;
2390 }
2391 
2393  std::vector< vcl::Window* >* pChildren )
2394 {
2395  if ( mpFrameSidebarWinContainer != nullptr )
2396  {
2397  mpFrameSidebarWinContainer->getAll( rFrame, pChildren );
2398  }
2399 }
2400 
2402 void SwNoteProps::Notify( const css::uno::Sequence< OUString >& ) {}
2403 
2404 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual Point GetPosPixel() const
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:341
SfxViewFrame * GetViewFrame() const
const Fraction & GetScaleX() const
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:233
void StopShellTimer()
Definition: view.cxx:1757
bool IsHit(const Point &aPointPixel)
Definition: PostItMgr.cxx:1862
Base class of the Writer layout elements.
Definition: frame.hxx:295
bool mbWaitingForCalcRects
Definition: PostItMgr.hxx:136
void CheckForRemovedPostIts()
Definition: PostItMgr.cxx:243
SfxHintId
Marks a position in the document model.
Definition: pam.hxx:35
vcl::Window * GetSidebarWinForFrameByIndex(const SwFrame &rFrame, const sal_Int32 nIndex)
Definition: PostItMgr.cxx:2379
void SetViewState(::sw::sidebarwindows::ViewState bViewState)
void HideActiveSidebarWin()
Definition: PostItMgr.cxx:2320
#define EE_CHAR_LANGUAGE_CJK
const SwField * GetField() const
Definition: fmtfld.hxx:71
virtual void DrawSelChanged() override
Definition: wrtsh3.cxx:109
void FormatAll(const SfxItemSet &rNewAttr)
Definition: PostItMgr.cxx:1621
SdrView * GetDrawView()
Definition: vnew.cxx:376
constexpr::Color COL_AUTHOR9_LIGHT(255, 231, 199)
bool ScrollbarHit(const unsigned long aPage, const Point &aPoint)
Definition: PostItMgr.cxx:1942
const SwStartNode * FindFooterStartNode() const
Definition: node.hxx:204
virtual ~SwPostItMgr() override
Definition: PostItMgr.cxx:232
OUString toISO8601(const css::util::DateTime &rDateTime)
#define KEY_PAGEDOWN
#define EE_CHAR_LANGUAGE
virtual void Notify(SfxBroadcaster &, const SfxHint &rHint) override
Definition: PostItMgr.cxx:1421
bool ArrowEnabled(sal_uInt16 aDirection, unsigned long aPage) const
Definition: PostItMgr.cxx:1093
constexpr::Color COL_AUTHOR6_LIGHT(230, 250, 250)
virtual const SfxItemSet * GetOutputItemSet() const =0
sal_Int32 GetInitialAnchorDistance() const
Definition: PostItMgr.cxx:2161
constexpr::Color COL_AUTHOR3_NORMAL(218, 248, 193)
long Height() const
#define KEY_PAGEUP
#define POSTIT_INITIAL_ANCHOR_DISTANCE
Definition: PostItMgr.cxx:93
virtual SwFieldType * GetFieldType(SwFieldIds nResId, const OUString &rName, bool bDbFieldMatching) const =0
SwNodeIndex nNode
Definition: pam.hxx:37
IMPL_LINK_NOARG(SwPostItMgr, CalcHdl, void *, void)
Definition: PostItMgr.cxx:2136
CommentNotificationType
bool IsReadOnly(const OUString &rURL, bool *pbExist)
bool HasScrollbars() const
Definition: PostItMgr.cxx:639
sal_Int32 StartSearchAndReplace(const SvxSearchItem &rSearchItem)
void SetSearchOptions(const i18nutil::SearchOptions2 &rOpt)
bool operator()(const SwFormatField *pField) const override
Definition: PostItMgr.cxx:1376
sal_uIntPtr sal_uLong
void disposeAndClear()
bool IsPostIts() const
Definition: viewopt.hxx:255
constexpr::Color COL_AUTHOR6_NORMAL(210, 246, 246)
virtual ~FieldDocWatchingStack() override
Definition: PostItMgr.cxx:1485
static const AllSettings & GetSettings()
std::size_t mRedlineAuthor
SwFormatFieldHintWhich Which() const
Definition: fmtfld.hxx:134
bool IsMapModeEnabled() const
double getX() const
virtual Size GetSizePixel() const
TElementType * Next()
Definition: calbck.hxx:376
constexpr::Color COL_AUTHOR2_LIGHT(233, 242, 255)
void Height(long nNew)
Definition: swrect.hxx:189
const std::vector< basegfx::B2DRange > & GetAnnotationTextRanges()
constexpr::Color COL_AUTHOR4_DARK(105, 43, 157)
#define POSTIT_MINIMUMSIZE_WITH_META
Definition: PostItMgr.cxx:96
sw::annotation::SwAnnotationWin * GetSidebarWin(const SfxBroadcaster *pBroadcaster) const
Definition: PostItMgr.cxx:1691
sal_Int16 nId
VclPtr< sw::annotation::SwAnnotationWin > mpActivePostIt
Definition: PostItMgr.hxx:137
constexpr::Color COL_AUTHOR8_NORMAL(211, 222, 232)
virtual OUString GetPar1() const override
Author.
Definition: docufld.cxx:1787
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:233
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
const MapMode & GetMapMode() const
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: viewsh.cxx:2588
double getY() const
SwNode & GetNode() const
Definition: ndindex.hxx:118
void SetActiveSidebarWin(sw::annotation::SwAnnotationWin *p)
Definition: PostItMgr.cxx:2113
vcl::Window * IsHitSidebarWindow(const Point &rPointLogic)
Get the matching window that is responsible for handling mouse events of rPointLogic, if any.
Definition: PostItMgr.cxx:1891
virtual ~FilterFunctor()
Definition: PostItMgr.cxx:1340
void EnterStdMode()
Definition: select.cxx:552
SwEditWin & GetEditWin()
Definition: view.hxx:403
sal_Int32 GetParagraphCount() const
void Pos(const Point &rNew)
Definition: swrect.hxx:167
static Color GetColorAnchor(std::size_t aAuthorIndex)
Definition: PostItMgr.cxx:2098
bool HasActiveAnnotationWin() const
Definition: PostItMgr.cxx:2290
OString join(const OString &rSeparator, const std::vector< OString > &rSequence)
SwSidebarItem * InsertItem(SfxBroadcaster *pItem, bool bCheckExistence, bool bFocus)
Definition: PostItMgr.cxx:280
void EnableMapMode(bool bEnable=true)
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
bool IsHitWindow(const Point &rPointLogic)
Is there a matching sub-widget inside this sidebar widget for rPointLogic?
FilterFunctor const & m_rNext
Definition: PostItMgr.cxx:1388
void setTiledPainting(bool bTiledPainting)
constexpr::Color COL_AUTHOR2_NORMAL(216, 232, 255)
unsigned long GetSidebarBorderWidth(bool bPx=false) const
Definition: PostItMgr.cxx:2060
void EndAllAction()
Definition: edws.cxx:96
The root element of a Writer document layout.
Definition: rootfrm.hxx:79
constexpr::Color COL_AUTHOR7_NORMAL(237, 252, 163)
void TranslateTopPosition(const long aAmount)
void SetMapMode()
SfxHintId GetId() const
SwDocShell & m_rDocShell
Definition: PostItMgr.cxx:1418
bool DelRight()
Definition: delete.cxx:282
SwWrtShell & GetWrtShell() const
Definition: view.hxx:400
IsPostitFieldWithPostitId(sal_uInt32 nPostItId)
Definition: PostItMgr.cxx:1372
const sal_Int8 ANCHORLINE_WIDTH
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:389
void PaintTile(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect)
void InvalidatePosOrSize(const SwFrame *pFrame, const SdrObject *pObj, vcl::Window *pWindow, const SwRect &rOldFrame)
Definition: accmap.cxx:2284
bool mbDeleteNote
Definition: PostItMgr.hxx:142
std::unique_ptr< sw::sidebarwindows::SwFrameSidebarWinContainer > mpFrameSidebarWinContainer
Definition: PostItMgr.hxx:149
VclPtr< sw::annotation::SwAnnotationWin > pPostIt
FilterFunctor & m_rFilter
Definition: PostItMgr.cxx:1419
#define COL_NOTES_SIDEPANE_ARROW_DISABLED
Definition: PostItMgr.hxx:64
void SetSidebarPosition(sw::sidebarwindows::SidebarPosition eSidebarPosition)
const SwView & GetView() const
Definition: wrtsh.hxx:426
void Top(const long nTop)
Definition: swrect.hxx:202
constexpr::Color COL_AUTHOR8_LIGHT(226, 234, 241)
#define MAX_LOOP_COUNT
Definition: PostItMgr.cxx:100
void DisconnectSidebarWinFromFrame(const SwFrame &rFrame, sw::annotation::SwAnnotationWin &rSidebarWin)
Definition: PostItMgr.cxx:2353
SwAccessibleMap * GetAccessibleMap()
Definition: viewsh.cxx:2458
constexpr::Color COL_AUTHOR4_NORMAL(228, 210, 245)
const Fraction & GetScaleY() const
const SwTextField * GetTextField() const
Definition: fmtfld.hxx:89
void DrawNotesForPage(OutputDevice *pOutDev, sal_uInt32 nPage)
Definition: PostItMgr.cxx:953
SW_DLLPUBLIC void UpdateDataOnActiveSidebarWin()
Definition: PostItMgr.cxx:2304
#define X
constexpr::Color COL_AUTHOR7_LIGHT(242, 254, 181)
void SelectRange(sal_Int32 nFirst, sal_Int32 nCount)
SwView * mpView
Definition: PostItMgr.hxx:130
static Color GetColorDark(std::size_t aAuthorIndex)
Definition: PostItMgr.cxx:2068
void libreOfficeKitViewCallback(int nType, const char *pPayload) const override
constexpr::Color COL_AUTHOR6_DARK(0, 128, 128)
void ExecViewOptions(SfxRequest &)
Definition: view0.cxx:344
constexpr::Color COL_AUTHOR8_DARK(53, 85, 107)
constexpr::Color COL_AUTHOR2_DARK(6, 70, 162)
long Top() const
static SvtScriptType GetScriptTypeOfLanguage(LanguageType nLang)
void Right(const long nRight)
Definition: swrect.hxx:198
const SwFormatField * pop()
Definition: PostItMgr.cxx:1490
const IDocumentRedlineAccess & getIDocumentRedlineAccess() const
Provides access to the document redline interface.
Definition: viewsh.cxx:2596
const SwPostItField * GetPostItField()
void AutoScroll(const sw::annotation::SwAnnotationWin *pPostIt, const unsigned long aPage)
Definition: PostItMgr.cxx:1047
constexpr::Color COL_AUTHOR1_LIGHT(255, 255, 195)
void PrepareView(bool bIgnoreCount=false)
Definition: PostItMgr.cxx:1841
OutlinerParaObject * mpAnswer
Definition: PostItMgr.hxx:144
#define POSTIT_SPACE_BETWEEN
Definition: PostItMgr.cxx:95
void MakeVisible(const SwRect &)
Definition: viewsh.cxx:577
void PaintTile(OutputDevice &rRenderContext)
Definition: PostItMgr.cxx:969
ImplSVEvent * mnEventId
Definition: PostItMgr.hxx:135
void SetBackward(bool bNewBackward)
void GetAllSidebarWinForFrame(const SwFrame &rFrame, std::vector< vcl::Window * > *pChildren)
Definition: PostItMgr.cxx:2392
#define SAL_N_ELEMENTS(arr)
sal_Int32 GetSpaceBetween() const
Definition: PostItMgr.cxx:2167
css::util::DateTime GetUNODateTime() const
long GetNextBorder()
Definition: PostItMgr.cxx:1757
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
bool CalcRects()
Definition: PostItMgr.cxx:522
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:203
void ConnectSidebarWinToFrame(const SwFrame &rFrame, const SwFormatField &rFormatField, sw::annotation::SwAnnotationWin &rSidebarWin)
Definition: PostItMgr.cxx:2336
sal_uInt32 const m_nPostItId
Definition: PostItMgr.cxx:1370
sal_uInt32 GetPostItId() const
Definition: docufld.hxx:474
#define POSTIT_SCROLL_SIDEBAR_HEIGHT
Definition: PostItMgr.cxx:97
IsFieldNotDeleted(IDocumentRedlineAccess const &rIDRA, const FilterFunctor &rNext)
Definition: PostItMgr.cxx:1391
const DateTime & GetDateTime() const
Definition: docufld.hxx:471
SvtScriptType
#define SW_MOD()
Definition: swmodule.hxx:255
constexpr::Color COL_AUTHOR1_NORMAL(255, 255, 158)
sal_uInt16 GetNumPages()
Definition: viewsh.cxx:632
void SetAttribs(const SfxItemSet &)
Color GetArrowColor(sal_uInt16 aDirection, unsigned long aPage) const
Definition: PostItMgr.cxx:1109
::sw::mark::IMark * GetAnnotationMark() const
Definition: atrfld.cxx:653
const SwFormatField * GetField() const
Definition: fmtfld.hxx:133
void InitAnswer(OutlinerParaObject const *pText)
SwRect mPageFrame
void DeleteActiveSidebarWin()
Definition: PostItMgr.cxx:2312
sal_uInt16 SearchReplace(const SwFormatField &pField, const i18nutil::SearchOptions2 &rSearchOptions, bool bSrchForward)
Definition: PostItMgr.cxx:2234
FieldShadowState mShadowState
Definition: PostItMgr.hxx:143
SwRect mPagePrtArea
void Focus(SfxBroadcaster &rBC)
Definition: PostItMgr.cxx:495
TElementType * First()
Definition: calbck.hxx:345
int i
bool ShowScrollbar(const unsigned long aPage) const
Definition: PostItMgr.cxx:1854
constexpr::Color COL_AUTHOR9_DARK(209, 118, 0)
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
void AddPostIts(bool bCheckExistence=true, bool bFocus=true)
Definition: PostItMgr.cxx:1296
void Scroll(const long lScroll, const unsigned long aPage)
Definition: PostItMgr.cxx:995
long getLayoutHeight(const SwRootFrame *pRoot)
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:222
void MakeVisible(const sw::annotation::SwAnnotationWin *pPostIt)
Definition: PostItMgr.cxx:1069
IDocumentRedlineAccess const & m_rIDRA
Definition: PostItMgr.cxx:1387
void AddRule(SwUndoArg eWhat, const OUString &rWith)
Definition: SwRewriter.cxx:29
long Bottom() const
void SetVirtualPosSize(const Point &aPoint, const Size &aSize)
bool IsInside(const Point &rPOINT) const
Outliner * GetOutliner() const
static SwAbstractDialogFactory * Create()
Definition: swabstdlg.cxx:36
sal_uLong mnStartNodeIdx
unsigned long mnPageNumber
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
OUString SwResId(const char *pId)
Definition: swmodule.cxx:191
constexpr::Color COL_AUTHOR4_LIGHT(239, 228, 248)
void SSize(const Size &rNew)
Definition: swrect.hxx:176
void LeaveDrawCreate()
Definition: view.hxx:525
VclPtr< SwEditWin > mpEditWin
Definition: PostItMgr.hxx:132
void GrabFocus()
constexpr::Color COL_AUTHOR3_LIGHT(226, 250, 207)
long X() const
#define Y
sal_uInt32 CalcParent()
Calculate parent postit id of current annotation window.
SwDocShell * GetDocShell()
Definition: view.cxx:1115
const SwPostItField * mpShadowField
Definition: PostItMgr.hxx:80
bool IsReadOnly() const
bool HasFrameConnectedSidebarWins(const SwFrame &rFrame)
Definition: PostItMgr.cxx:2367
SwLayoutInfo maLayoutInfo
SwFieldType * GetTyp() const
Definition: fldbas.hxx:382
void Delete()
Definition: PostItMgr.cxx:1559
::sw::sidebarwindows::AnchorOverlayObject * Anchor()
SW_DLLPUBLIC bool HasActiveSidebarWin() const
Definition: PostItMgr.cxx:2285
void RemoveSidebarWin()
Definition: PostItMgr.cxx:1322
void LayoutPostIts()
Definition: PostItMgr.cxx:677
Point PixelToLogic(const Point &rDevicePt) const
Point LogicToPixel(const Point &rLogicPt) const
void CheckMetaText()
Definition: PostItMgr.cxx:2205
void PreparePageContainer()
Definition: PostItMgr.cxx:649
void ExecuteFormatAllDialog(SwView &rView)
Definition: PostItMgr.cxx:1586
SwPostItHelper::SwLayoutStatus mLayoutStatus
constexpr::Color COL_AUTHOR1_DARK(198, 146, 0)
std::vector< std::unique_ptr< SwSidebarItem > > & sidebarItemVector
Definition: PostItMgr.cxx:1416
std::vector< const SwFormatField * > v
Definition: PostItMgr.cxx:1417
void A11yDispose(const SwFrame *pFrame, const SdrObject *pObj, vcl::Window *pWindow, bool bRecursive=false, bool bCanSkipInvisible=true)
Definition: accmap.cxx:2158
void SetFollow(bool bIsFollow)
void ChangeSidebarItem(SwSidebarItem const &rSidebarItem)
bool operator()(const SwFormatField *pField) const override
Definition: PostItMgr.cxx:1360
void Left(const long nLeft)
Definition: swrect.hxx:193
bool IsFieldInDoc() const
Definition: atrfld.cxx:329
void Bottom(const long nBottom)
Definition: swrect.hxx:207
void AssureStdModeAtShell()
Definition: PostItMgr.cxx:2261
void ShowAnchorOnly(const Point &aPoint)
void GrabFocusOnActiveSidebarWin()
Definition: PostItMgr.cxx:2296
void SetSelection(const ESelection &)
sal_uInt16 Replace(SvxSearchItem const *pItem)
Definition: PostItMgr.cxx:2213
IsPostitFieldWithAuthorOf(const OUString &rAuthor)
Definition: PostItMgr.cxx:1356
void ToggleInsModeOnActiveSidebarWin()
Definition: PostItMgr.cxx:2328
bool GotoField(const SwFormatField &rField)
Definition: wrtsh3.cxx:70
void MakeDrawView()
Definition: vnew.cxx:366
void SetReadOnlyState()
Definition: PostItMgr.cxx:2198
virtual bool IsTextEdit() const final override
const basegfx::B2DPoint & GetSixthPosition() const
weld::Window * GetFrameWeld() const
sal_Int32 GetSidebarScrollerHeight() const
Definition: PostItMgr.cxx:2185
static Color GetColorLight(std::size_t aAuthorIndex)
Definition: PostItMgr.cxx:2083
virtual VclPtr< sw::annotation::SwAnnotationWin > GetSidebarWindow(SwEditWin &rEditWin, SwPostItMgr &aMgr)=0
virtual void ImplCommit() override
Definition: PostItMgr.cxx:2401
bool IsFieldDeletedInModel(IDocumentRedlineAccess const &rIDRA, SwTextField const &rTextField)
void CorrectPositions()
Definition: PostItMgr.cxx:1975
sal_Int32 GetScrollSize() const
Definition: PostItMgr.cxx:2173
virtual SwPosition GetAnchorPosition() const =0
void SetPosSizePixelRect(long nX, long nY, long nWidth, long nHeight, const SwRect &aAnchorRect, const long PageBorder)
sw::sidebarwindows::SidebarPosition meSidebarPosition
void LockView(bool b)
Definition: viewsh.hxx:465
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:426
#define COL_NOTES_SIDEPANE_ARROW_ENABLED
Definition: PostItMgr.hxx:63
constexpr::Color COL_AUTHOR5_DARK(197, 0, 11)
bool mbLayouting
Definition: PostItMgr.hxx:140
bool IsShowAnchor()
Definition: PostItMgr.hxx:108
virtual bool UseElement(SwRootFrame const &, IDocumentRedlineAccess const &)=0
void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: PostItMgr.cxx:323
void SetChangeTracking(const SwPostItHelper::SwLayoutStatus aStatus, const Color &aColor)
RET_OK
bool mbIsShowAnchor
Definition: PostItMgr.hxx:146
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
sal_Int32 GetMinimumSizeWithMeta() const
Definition: PostItMgr.cxx:2179
constexpr::Color COL_AUTHOR9_NORMAL(255, 226, 185)
sal_uInt16 GetZoom() const
Definition: viewopt.hxx:459
void EndTextEdit()
Deletes object if required.
Definition: feshview.cxx:1235
size_t IsObjSelected() const
Definition: feshview.cxx:1167
constexpr::Color COL_AUTHOR7_DARK(140, 132, 0)
void UnSelectFrame()
Definition: select.cxx:327
#define EE_TEXTPOS_MAX_COUNT
void Rescale()
Definition: PostItMgr.cxx:2154
bool HasNotes() const
Definition: PostItMgr.cxx:2029
ESelection GetSelection()
constexpr::Color COL_WHITE(0xFF, 0xFF, 0xFF)
UnoViewSharedPtr mpView
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:416
void setSidebarChanged(SwRootFrame *pRoot, bool bBrowseMode)
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
sw::annotation::SwAnnotationWin * GetActiveSidebarWin()
Definition: PostItMgr.hxx:232
void LeaveSelFrameMode()
Definition: select.cxx:721
void SetSpellChecking()
Definition: PostItMgr.cxx:2191
std::vector< std::unique_ptr< SwPostItPageItem > > mPages
Definition: PostItMgr.hxx:134
long mbLayoutHeight
Definition: PostItMgr.hxx:139
sw::annotation::SwAnnotationWin * GetNextPostIt(sal_uInt16 aDirection, sw::annotation::SwAnnotationWin *aPostIt)
Definition: PostItMgr.cxx:1721
tools::Rectangle GetBottomScrollRect(const unsigned long aPage) const
Definition: PostItMgr.cxx:1921
unsigned long GetSidebarWidth(bool bPx=false) const
Definition: PostItMgr.cxx:2034
virtual void Draw(OutputDevice *pDev, const Point &, const Size &, DrawFlags) override
SwPostItMgr(SwView *aDoc)
Definition: PostItMgr.cxx:193
reference_type * get() const
virtual OUString GetPar2() const override
Text.
Definition: docufld.cxx:1799
bool LayoutByPage(std::vector< sw::annotation::SwAnnotationWin * > &aVisiblePostItList, const tools::Rectangle &rBorder, long lNeededHeight)
Definition: PostItMgr.cxx:1124
SfxItemSet GetAttribs()
void(* f)(TrueTypeTable *)
sal_Int32 mnStartContent
bool mbReadOnly
Definition: PostItMgr.hxx:141
constexpr::Color COL_AUTHOR5_LIGHT(255, 227, 229)
bool BorderOverPageBorder(unsigned long aPage) const
Definition: PostItMgr.cxx:932
bool IsShowHiddenChar(bool bHard=false) const
Definition: viewopt.hxx:275
::sw::sidebarwindows::ShadowOverlayObject * Shadow()
virtual SdrView * GetDrawView() const override
Definition: viewdraw.cxx:622
virtual VclPtr< SfxAbstractTabDialog > CreateSwCharDlg(weld::Window *pParent, SwView &pVw, const SfxItemSet &rCoreSet, SwCharDlgMode nDialogMode, const OUString *pFormatStr=nullptr)=0
virtual bool operator()(const SwFormatField *pField) const =0
bool ShowNotes() const
Definition: PostItMgr.cxx:2023
#define EE_PARA_MAX_COUNT
bool operator()(const SwFormatField *pField) const override
Definition: PostItMgr.cxx:1346
void SetShadowState(const SwPostItField *pField, bool bCursor=true)
Definition: PostItMgr.cxx:1788
void StartAllAction()
For all views of this document.
Definition: edws.cxx:85
constexpr::Color COL_AUTHOR3_DARK(87, 157, 28)
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2072
void Push(PushFlags nFlags=PushFlags::ALL)
static SfxItemPool * GetAnnotationPool(SwView const &rV)
Definition: annotsh.cxx:151
#define EE_CHAR_LANGUAGE_CTL
SwLayoutStatus getLayoutInfos(SwLayoutInfo &o_rInfo, const SwPosition &rAnchorPos, const sw::mark::IMark *pAnnotationMark=nullptr)
virtual const SwFormatField & GetFormatField() const =0
virtual void Notify(const css::uno::Sequence< OUString > &aPropertyNames) override
Definition: PostItMgr.cxx:2402
SwFieldIds Which() const
Definition: fldbas.hxx:265
constexpr::Color COL_AUTHOR5_NORMAL(254, 205, 208)
std::vector< std::unique_ptr< SwSidebarItem > > mvPostItFields
Definition: PostItMgr.hxx:133
sw::annotation::SwAnnotationWin * GetAnnotationWin(const SwPostItField *pField) const
Definition: PostItMgr.cxx:1701
tools::Rectangle GetTopScrollRect(const unsigned long aPage) const
Definition: PostItMgr.cxx:1931
unsigned long getPageInfo(SwRect &rPageFrame, const SwRootFrame *, const Point &)
const SwStartNode * FindFootnoteStartNode() const
Definition: node.hxx:200
bool IsViewLocked() const
Definition: viewsh.hxx:464
SwRect mPosition
void RemoveItem(SfxBroadcaster *pBroadcast)
Definition: PostItMgr.cxx:303
Definition: view.hxx:146
long Y() const
sal_uInt16 FinishSearchReplace(const i18nutil::SearchOptions2 &rSearchOptions, bool bSrchForward)
Definition: PostItMgr.cxx:2222
SwWrtShell * mpWrtShell
Definition: PostItMgr.hxx:131
bool IsSelFrameMode() const
Definition: wrtsh.hxx:168
FieldDocWatchingStack(std::vector< std::unique_ptr< SwSidebarItem >> &in, SwDocShell &rDocShell, FilterFunctor &rFilter)
Definition: PostItMgr.cxx:1456
OUString const m_sAuthor
Definition: PostItMgr.cxx:1354
bool operator()(const SwFormatField *pField) const override
Definition: PostItMgr.cxx:1397