LibreOffice Module sw (master)  1
AnnotationWin2.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 <sal/config.h>
21 
22 #include <cstddef>
23 #include <cstdlib>
24 
25 #include "SidebarWinAcc.hxx"
26 #include <PostItMgr.hxx>
27 #include <AnnotationWin.hxx>
29 #include "SidebarTxtControl.hxx"
30 #include "SidebarScrollBar.hxx"
31 #include "AnchorOverlayObject.hxx"
32 #include "ShadowOverlayObject.hxx"
33 #include "OverlayRanges.hxx"
34 
35 #include <strings.hrc>
36 #include <app.hrc>
37 
38 #include <viewopt.hxx>
39 #include <cmdid.h>
40 
41 #include <editeng/editobj.hxx>
42 #include <editeng/fontitem.hxx>
43 #include <editeng/fhgtitem.hxx>
44 #include <editeng/langitem.hxx>
45 #include <editeng/editview.hxx>
46 #include <editeng/outliner.hxx>
47 #include <editeng/editeng.hxx>
48 #include <editeng/eeitem.hxx>
49 #include <editeng/outlobj.hxx>
50 
51 #include <svl/zforlist.hxx>
52 #include <svl/undo.hxx>
53 #include <svl/stritem.hxx>
54 
55 #include <svx/svxids.hrc>
56 
57 #include <sfx2/viewfrm.hxx>
58 #include <sfx2/bindings.hxx>
59 #include <sfx2/dispatch.hxx>
60 
61 #include <vcl/event.hxx>
62 #include <vcl/scrbar.hxx>
63 #include <vcl/svapp.hxx>
64 #include <vcl/menubtn.hxx>
65 #include <vcl/settings.hxx>
66 #include <vcl/ptrstyle.hxx>
67 
68 #include <edtwin.hxx>
69 #include <view.hxx>
70 #include <docsh.hxx>
71 #include <wrtsh.hxx>
72 #include <doc.hxx>
73 #include <swmodule.hxx>
74 #include <langhelper.hxx>
75 
76 #include <txtannotationfld.hxx>
77 #include <ndtxt.hxx>
78 
79 #include <sw_primitivetypes2d.hxx>
87 #include <memory>
88 #include <comphelper/lok.hxx>
90 #include <drawdoc.hxx>
91 
92 using namespace sw::sidebarwindows;
93 
94 namespace
95 {
96 
98 void lcl_translateTwips(vcl::Window const & rParent, vcl::Window& rChild, MouseEvent* pMouseEvent)
99 {
100  // Set map mode, so that callback payloads will contain absolute coordinates instead of relative ones.
101  Point aOffset(rChild.GetOutOffXPixel() - rParent.GetOutOffXPixel(), rChild.GetOutOffYPixel() - rParent.GetOutOffYPixel());
102  if (!rChild.IsMapModeEnabled())
103  {
104  MapMode aMapMode(rChild.GetMapMode());
105  aMapMode.SetMapUnit(MapUnit::MapTwip);
106  aMapMode.SetScaleX(rParent.GetMapMode().GetScaleX());
107  aMapMode.SetScaleY(rParent.GetMapMode().GetScaleY());
108  rChild.SetMapMode(aMapMode);
109  rChild.EnableMapMode();
110  }
111  aOffset = rChild.PixelToLogic(aOffset);
112  MapMode aMapMode(rChild.GetMapMode());
113  aMapMode.SetOrigin(aOffset);
114  aMapMode.SetMapUnit(rParent.GetMapMode().GetMapUnit());
115  rChild.SetMapMode(aMapMode);
116  rChild.EnableMapMode(false);
117 
118  if (pMouseEvent)
119  {
120  // Set event coordinates, so they contain relative coordinates instead of absolute ones.
121  Point aPos = pMouseEvent->GetPosPixel();
122  aPos.Move(-aOffset.getX(), -aOffset.getY());
123  MouseEvent aMouseEvent(aPos, pMouseEvent->GetClicks(), pMouseEvent->GetMode(), pMouseEvent->GetButtons(), pMouseEvent->GetModifier());
124  *pMouseEvent = aMouseEvent;
125  }
126 }
127 
129 vcl::Window* lcl_getHitWindow(sw::annotation::SwAnnotationWin& rParent, const MouseEvent& rMouseEvent)
130 {
131  vcl::Window* pRet = nullptr;
132 
133  rParent.EditWin().Push(PushFlags::MAPMODE);
134  rParent.EditWin().EnableMapMode();
135  for (sal_Int16 i = rParent.GetChildCount() - 1; i >= 0; --i)
136  {
137  vcl::Window* pChild = rParent.GetChild(i);
138 
139  Point aPosition(rParent.GetPosPixel());
140  aPosition.Move(pChild->GetPosPixel().getX(), pChild->GetPosPixel().getY());
141  Size aSize(rParent.GetSizePixel());
142  tools::Rectangle aRectangleLogic(rParent.EditWin().PixelToLogic(aPosition), rParent.EditWin().PixelToLogic(aSize));
143  if (aRectangleLogic.IsInside(rMouseEvent.GetPosPixel()))
144  {
145  pRet = pChild;
146  break;
147  }
148  }
149  rParent.EditWin().Pop();
150  return pRet;
151 }
152 
153 }
154 
155 namespace sw { namespace annotation {
156 
157 #define METABUTTON_WIDTH 16
158 #define METABUTTON_HEIGHT 18
159 #define METABUTTON_AREA_WIDTH 30
160 #define POSTIT_META_HEIGHT sal_Int32(30)
161 #define POSTIT_MINIMUMSIZE_WITHOUT_META 50
162 
163 
164 void SwAnnotationWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
165 {
166  Window::Paint(rRenderContext, rRect);
167 
168  if (mpMetadataAuthor->IsVisible())
169  {
170  //draw left over space
172  {
173  rRenderContext.SetFillColor(COL_BLACK);
174  }
175  else
176  {
177  rRenderContext.SetFillColor(mColorDark);
178  }
179 
180  rRenderContext.SetLineColor();
181  tools::Rectangle aRectangle(Point(mpMetadataAuthor->GetPosPixel().X() + mpMetadataAuthor->GetSizePixel().Width(),
182  mpMetadataAuthor->GetPosPixel().Y()),
183  Size(GetMetaButtonAreaWidth(),
184  mpMetadataAuthor->GetSizePixel().Height() + mpMetadataDate->GetSizePixel().Height()));
185 
187  aRectangle = rRect;
188  else
189  aRectangle = PixelToLogic(aRectangle);
190  rRenderContext.DrawRect(aRectangle);
191  }
192 }
193 
194 void SwAnnotationWin::PaintTile(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
195 {
196  Paint(rRenderContext, rRect);
197 
198  for (sal_uInt16 i = 0; i < GetChildCount(); ++i)
199  {
200  vcl::Window* pChild = GetChild(i);
201 
202  // No point in showing this button till click on it are not handled.
203  if (pChild == mpMenuButton.get())
204  continue;
205 
206  if (!pChild->IsVisible())
207  continue;
208 
209  rRenderContext.Push(PushFlags::MAPMODE);
210  Point aOffset(PixelToLogic(pChild->GetPosPixel()));
211  MapMode aMapMode(rRenderContext.GetMapMode());
212  aMapMode.SetOrigin(aMapMode.GetOrigin() + aOffset);
213  rRenderContext.SetMapMode(aMapMode);
214 
215  bool bPopChild = false;
216  if (pChild->GetMapMode().GetMapUnit() != rRenderContext.GetMapMode().GetMapUnit())
217  {
218  // This is needed for the scrollbar that has its map unit in pixels.
219  pChild->Push(PushFlags::MAPMODE);
220  bPopChild = true;
221  pChild->EnableMapMode();
222  aMapMode = pChild->GetMapMode();
223  aMapMode.SetMapUnit(rRenderContext.GetMapMode().GetMapUnit());
224  aMapMode.SetScaleX(rRenderContext.GetMapMode().GetScaleX());
225  aMapMode.SetScaleY(rRenderContext.GetMapMode().GetScaleY());
226  pChild->SetMapMode(aMapMode);
227  }
228 
229  pChild->Paint(rRenderContext, rRect);
230 
231  if (bPopChild)
232  pChild->Pop();
233  rRenderContext.Pop();
234  }
235 
236  const drawinglayer::geometry::ViewInformation2D aViewInformation;
237  std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(rRenderContext, aViewInformation));
238 
239  // drawinglayer sets the map mode to pixels, not needed here.
240  rRenderContext.Pop();
241  // Work in document-global twips.
242  rRenderContext.Pop();
243  if (mpAnchor)
244  pProcessor->process(mpAnchor->getOverlayObjectPrimitive2DSequence());
245  if (mpTextRangeOverlay)
246  pProcessor->process(mpTextRangeOverlay->getOverlayObjectPrimitive2DSequence());
247 
248  rRenderContext.Push(PushFlags::NONE);
249  pProcessor.reset();
250  rRenderContext.Push(PushFlags::NONE);
251 }
252 
253 bool SwAnnotationWin::IsHitWindow(const Point& rPointLogic)
254 {
255  tools::Rectangle aRectangleLogic(EditWin().PixelToLogic(GetPosPixel()), EditWin().PixelToLogic(GetSizePixel()));
256  return aRectangleLogic.IsInside(rPointLogic);
257 }
258 
259 void SwAnnotationWin::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark)
260 {
261  mpSidebarTextControl->Push(PushFlags::MAPMODE);
262  MouseEvent aMouseEvent(rPosition);
263  lcl_translateTwips(EditWin(), *mpSidebarTextControl, &aMouseEvent);
264  Point aPosition(aMouseEvent.GetPosPixel());
265 
266  EditView& rEditView = GetOutlinerView()->GetEditView();
267  rEditView.SetCursorLogicPosition(aPosition, bPoint, bClearMark);
268 
269  mpSidebarTextControl->Pop();
270 }
271 
272 void SwAnnotationWin::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, DrawFlags nInFlags)
273 {
274  if (mpMetadataAuthor->IsVisible() )
275  {
276  pDev->SetFillColor(mColorDark);
277  pDev->SetLineColor();
278  pDev->DrawRect( tools::Rectangle( rPt, rSz ) );
279  }
280 
281  if (mpMetadataAuthor->IsVisible())
282  {
283  vcl::Font aOrigFont(mpMetadataAuthor->GetControlFont());
284  Size aSize(PixelToLogic(mpMetadataAuthor->GetSizePixel()));
285  Point aPos(PixelToLogic(mpMetadataAuthor->GetPosPixel()));
286  aPos += rPt;
287  vcl::Font aFont( mpMetadataAuthor->GetSettings().GetStyleSettings().GetFieldFont() );
288  mpMetadataAuthor->SetControlFont( aFont );
289  mpMetadataAuthor->Draw(pDev, aPos, aSize, nInFlags);
290  mpMetadataAuthor->SetControlFont( aOrigFont );
291  }
292 
293  if (mpMetadataDate->IsVisible())
294  {
295  vcl::Font aOrigFont(mpMetadataDate->GetControlFont());
296  Size aSize(PixelToLogic(mpMetadataDate->GetSizePixel()));
297  Point aPos(PixelToLogic(mpMetadataDate->GetPosPixel()));
298  aPos += rPt;
299  vcl::Font aFont( mpMetadataDate->GetSettings().GetStyleSettings().GetFieldFont() );
300  mpMetadataDate->SetControlFont( aFont );
301  mpMetadataDate->Draw(pDev, aPos, aSize, nInFlags);
302  mpMetadataDate->SetControlFont( aOrigFont );
303  }
304 
305  mpSidebarTextControl->Draw(pDev, rPt, rSz, nInFlags);
306 
307  const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
308  std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(
310  *pDev, aNewViewInfos ));
311 
312  if (mpAnchor)
313  pProcessor->process(mpAnchor->getOverlayObjectPrimitive2DSequence());
314  if (mpTextRangeOverlay)
315  pProcessor->process(mpTextRangeOverlay->getOverlayObjectPrimitive2DSequence());
316  pProcessor.reset();
317 
318  if (!mpVScrollbar->IsVisible())
319  return;
320 
321  vcl::Font aOrigFont(mpMetadataDate->GetControlFont());
322  Color aOrigBg( mpMetadataDate->GetControlBackground() );
323  OUString sOrigText(mpMetadataDate->GetText());
324 
325  Size aSize(PixelToLogic(mpMenuButton->GetSizePixel()));
326  Point aPos(PixelToLogic(mpMenuButton->GetPosPixel()));
327  aPos += rPt;
328 
329  vcl::Font aFont( mpMetadataDate->GetSettings().GetStyleSettings().GetFieldFont() );
330  mpMetadataDate->SetControlFont( aFont );
331  mpMetadataDate->SetControlBackground( Color(0xFFFFFF) );
332  mpMetadataDate->SetText("...");
333  mpMetadataDate->Draw(pDev, aPos, aSize, nInFlags);
334 
335  mpMetadataDate->SetText(sOrigText);
336  mpMetadataDate->SetControlFont( aOrigFont );
337  mpMetadataDate->SetControlBackground( aOrigBg );
338 
339 }
340 
341 void SwAnnotationWin::KeyInput(const KeyEvent& rKeyEvent)
342 {
343  if (mpSidebarTextControl)
344  {
345  mpSidebarTextControl->Push(PushFlags::MAPMODE);
346  lcl_translateTwips(EditWin(), *mpSidebarTextControl, nullptr);
347 
348  mpSidebarTextControl->KeyInput(rKeyEvent);
349 
350  mpSidebarTextControl->Pop();
351  }
352 }
353 
354 void SwAnnotationWin::MouseMove(const MouseEvent& rMouseEvent)
355 {
356  if (vcl::Window* pHit = lcl_getHitWindow(*this, rMouseEvent))
357  {
358  pHit->Push(PushFlags::MAPMODE);
359  MouseEvent aMouseEvent(rMouseEvent);
360  lcl_translateTwips(EditWin(), *pHit, &aMouseEvent);
361 
362  pHit->MouseMove(aMouseEvent);
363 
364  pHit->Pop();
365  }
366 }
367 
368 void SwAnnotationWin::MouseButtonDown(const MouseEvent& rMouseEvent)
369 {
370  if (vcl::Window* pHit = lcl_getHitWindow(*this, rMouseEvent))
371  {
372  pHit->Push(PushFlags::MAPMODE);
373  MouseEvent aMouseEvent(rMouseEvent);
374  lcl_translateTwips(EditWin(), *pHit, &aMouseEvent);
375 
376  pHit->MouseButtonDown(aMouseEvent);
377 
378  pHit->Pop();
379  }
380 }
381 
382 void SwAnnotationWin::MouseButtonUp(const MouseEvent& rMouseEvent)
383 {
384  if (vcl::Window* pHit = lcl_getHitWindow(*this, rMouseEvent))
385  {
386  pHit->Push(PushFlags::MAPMODE);
387  MouseEvent aMouseEvent(rMouseEvent);
388  lcl_translateTwips(EditWin(), *pHit, &aMouseEvent);
389 
390  pHit->MouseButtonUp(aMouseEvent);
391 
392  pHit->Pop();
393  }
394 }
395 
396 void SwAnnotationWin::SetPosSizePixelRect(long nX, long nY, long nWidth, long nHeight,
397  const SwRect& aAnchorRect, const long aPageBorder)
398 {
399  mPosSize = tools::Rectangle(Point(nX,nY),Size(nWidth,nHeight));
400  if (!mAnchorRect.IsEmpty() && mAnchorRect != aAnchorRect)
401  mbAnchorRectChanged = true;
402  mAnchorRect = aAnchorRect;
403  mPageBorder = aPageBorder;
404 }
405 
406 void SwAnnotationWin::SetSize( const Size& rNewSize )
407 {
408  mPosSize.SetSize(rNewSize);
409 }
410 
411 void SwAnnotationWin::SetVirtualPosSize( const Point& aPoint, const Size& aSize)
412 {
413  mPosSize = tools::Rectangle(aPoint,aSize);
414 }
415 
416 void SwAnnotationWin::TranslateTopPosition(const long aAmount)
417 {
418  mPosSize.Move(0,aAmount);
419 }
420 
421 void SwAnnotationWin::ShowAnchorOnly(const Point &aPoint)
422 {
423  HideNote();
424  SetPosAndSize();
425  if (mpAnchor)
426  {
427  mpAnchor->SetSixthPosition(basegfx::B2DPoint(aPoint.X(),aPoint.Y()));
428  mpAnchor->SetSeventhPosition(basegfx::B2DPoint(aPoint.X(),aPoint.Y()));
429  mpAnchor->SetAnchorState(AnchorState::All);
430  mpAnchor->setVisible(true);
431  }
432  if (mpShadow)
433  mpShadow->setVisible(false);
434 }
435 
436 SfxItemSet SwAnnotationWin::DefaultItem()
437 {
438  SfxItemSet aItem( mrView.GetDocShell()->GetPool() );
439  aItem.Put(SvxFontHeightItem(200,100,EE_CHAR_FONTHEIGHT));
440  return aItem;
441 }
442 
443 void SwAnnotationWin::InitControls()
444 {
445  AddEventListener( LINK( this, SwAnnotationWin, WindowEventListener ) );
446 
447  // actual window which holds the user text
448  mpSidebarTextControl = VclPtr<SidebarTextControl>::Create( *this,
450  mrView, mrMgr );
451  mpSidebarTextControl->SetPointer(PointerStyle::Text);
452 
453  // window controls for author and date
454  mpMetadataAuthor = VclPtr<Edit>::Create( this, 0 );
455  mpMetadataAuthor->SetAccessibleName( SwResId( STR_ACCESS_ANNOTATION_AUTHOR_NAME ) );
456  mpMetadataAuthor->EnableRTL(AllSettings::GetLayoutRTL());
457  mpMetadataAuthor->SetReadOnly();
458  mpMetadataAuthor->AlwaysDisableInput(true);
459  mpMetadataAuthor->SetCallHandlersOnInputDisabled(true);
460  mpMetadataAuthor->AddEventListener( LINK( this, SwAnnotationWin, WindowEventListener ) );
461  // we should leave this setting alone, but for this we need a better layout algo
462  // with variable meta size height
463  {
464  AllSettings aSettings = mpMetadataAuthor->GetSettings();
465  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
466  vcl::Font aFont = aStyleSettings.GetFieldFont();
467  aFont.SetFontHeight(8);
468  aStyleSettings.SetFieldFont(aFont);
469  aSettings.SetStyleSettings(aStyleSettings);
470  mpMetadataAuthor->SetSettings(aSettings);
471  }
472 
473  mpMetadataDate = VclPtr<Edit>::Create( this, 0 );
474  mpMetadataDate->SetAccessibleName( SwResId( STR_ACCESS_ANNOTATION_DATE_NAME ) );
475  mpMetadataDate->EnableRTL(AllSettings::GetLayoutRTL());
476  mpMetadataDate->SetReadOnly();
477  mpMetadataDate->AlwaysDisableInput(true);
478  mpMetadataDate->SetCallHandlersOnInputDisabled(true);
479  mpMetadataDate->AddEventListener( LINK( this, SwAnnotationWin, WindowEventListener ) );
480  // we should leave this setting alone, but for this we need a better layout algo
481  // with variable meta size height
482  {
483  AllSettings aSettings = mpMetadataDate->GetSettings();
484  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
485  vcl::Font aFont = aStyleSettings.GetFieldFont();
486  aFont.SetFontHeight(8);
487  aStyleSettings.SetFieldFont(aFont);
488  aSettings.SetStyleSettings(aStyleSettings);
489  mpMetadataDate->SetSettings(aSettings);
490  }
491 
492  SwDocShell* aShell = mrView.GetDocShell();
493  mpOutliner.reset(new Outliner(&aShell->GetPool(),OutlinerMode::TextObject));
494  aShell->GetDoc()->SetCalcFieldValueHdl( mpOutliner.get() );
495  mpOutliner->SetUpdateMode( true );
496  Rescale();
497 
498  mpSidebarTextControl->EnableRTL( false );
499  mpOutlinerView.reset(new OutlinerView ( mpOutliner.get(), mpSidebarTextControl ));
500  mpOutlinerView->SetBackgroundColor(COL_TRANSPARENT);
501  mpOutliner->InsertView(mpOutlinerView.get() );
502  mpOutlinerView->SetOutputArea( PixelToLogic( tools::Rectangle(0,0,1,1) ) );
503 
504  mpOutlinerView->SetAttribs(DefaultItem());
505 
507  {
508  // If there is a callback already registered, inform the new outliner view about it.
509  mpOutlinerView->RegisterViewShell(&mrView);
510  }
511 
512  //create Scrollbars
514  mpVScrollbar->EnableNativeWidget(false);
515  mpVScrollbar->EnableRTL( false );
516  mpVScrollbar->SetScrollHdl(LINK(this, SwAnnotationWin, ScrollHdl));
517  mpVScrollbar->EnableDrag();
518  mpVScrollbar->AddEventListener( LINK( this, SwAnnotationWin, WindowEventListener ) );
519 
520  const SwViewOption* pVOpt = mrView.GetWrtShellPtr()->GetViewOptions();
521  EEControlBits nCntrl = mpOutliner->GetControlWord();
522  // TODO: crash when AUTOCOMPLETE enabled
523  nCntrl |= EEControlBits::MARKFIELDS | EEControlBits::PASTESPECIAL | EEControlBits::AUTOCORRECT | EEControlBits::USECHARATTRIBS; // | EEControlBits::AUTOCOMPLETE;
525  nCntrl |= EEControlBits::MARKFIELDS;
526  else
527  nCntrl &= ~EEControlBits::MARKFIELDS;
528  if (pVOpt->IsOnlineSpell())
529  nCntrl |= EEControlBits::ONLINESPELLING;
530  else
531  nCntrl &= ~EEControlBits::ONLINESPELLING;
532  mpOutliner->SetControlWord(nCntrl);
533 
534  std::size_t aIndex = SW_MOD()->InsertRedlineAuthor(GetAuthor());
535  SetColor( SwPostItMgr::GetColorDark(aIndex),
538 
539  CheckMetaText();
540 
541  mpMenuButton = CreateMenuButton();
542 
544  GetOutlinerView()->StartSpeller();
545  SetPostItText();
546  mpOutliner->CompleteOnlineSpelling();
547 
548  mpSidebarTextControl->Show();
549  mpMetadataAuthor->Show();
550  mpMetadataDate->Show();
551  mpVScrollbar->Show();
552 }
553 
554 void SwAnnotationWin::CheckMetaText()
555 {
556  const SvtSysLocale aSysLocale;
557  const LocaleDataWrapper& rLocalData = aSysLocale.GetLocaleData();
558  OUString sMeta = GetAuthor();
559  if (sMeta.isEmpty())
560  {
561  sMeta = SwResId(STR_NOAUTHOR);
562  }
563  else if (sMeta.getLength() > 23)
564  {
565  sMeta = sMeta.copy(0, 20) + "...";
566  }
567  if ( mpMetadataAuthor->GetText() != sMeta )
568  {
569  mpMetadataAuthor->SetText(sMeta);
570  }
571 
572  Date aDate = GetDate();
573  if (aDate.IsValidAndGregorian() )
574  {
575  sMeta = rLocalData.getDate(aDate);
576  }
577  else
578  {
579  sMeta = SwResId(STR_NODATE);
580  }
581  if (GetTime().GetTime()!=0)
582  {
583  sMeta += " " + rLocalData.getTime( GetTime(),false );
584  }
585  if ( mpMetadataDate->GetText() != sMeta )
586  {
587  mpMetadataDate->SetText(sMeta);
588  }
589 }
590 
591 void SwAnnotationWin::Rescale()
592 {
593  MapMode aMode = GetParent()->GetMapMode();
594  aMode.SetOrigin( Point() );
595  mpOutliner->SetRefMapMode( aMode );
596  SetMapMode( aMode );
597  mpSidebarTextControl->SetMapMode( aMode );
598  const Fraction& rFraction = mrView.GetWrtShellPtr()->GetOut()->GetMapMode().GetScaleY();
599  if ( mpMetadataAuthor )
600  {
601  vcl::Font aFont( mpMetadataAuthor->GetSettings().GetStyleSettings().GetFieldFont() );
602  sal_Int32 nHeight = long(aFont.GetFontHeight() * rFraction);
603  aFont.SetFontHeight( nHeight );
604  mpMetadataAuthor->SetControlFont( aFont );
605  }
606  if ( mpMetadataDate )
607  {
608  vcl::Font aFont( mpMetadataDate->GetSettings().GetStyleSettings().GetFieldFont() );
609  sal_Int32 nHeight = long(aFont.GetFontHeight() * rFraction);
610  aFont.SetFontHeight( nHeight );
611  mpMetadataDate->SetControlFont( aFont );
612  }
613 }
614 
615 void SwAnnotationWin::SetPosAndSize()
616 {
617  bool bChange = false;
618 
619  if (GetSizePixel() != mPosSize.GetSize())
620  {
621  bChange = true;
622  SetSizePixel(mPosSize.GetSize());
623 
625  {
626  // Position is not yet set at VCL level, but the map mode should
627  // contain the right origin to emit the correct cursor position.
628  mpSidebarTextControl->Push(PushFlags::MAPMODE);
629  Point aOffset(mPosSize.Left(), mPosSize.Top());
630  aOffset = PixelToLogic(aOffset);
631  MapMode aMapMode(mpSidebarTextControl->GetMapMode());
632  aMapMode.SetOrigin(aOffset);
633  mpSidebarTextControl->SetMapMode(aMapMode);
634  mpSidebarTextControl->EnableMapMode(false);
635  }
636 
637  DoResize();
638 
640  mpSidebarTextControl->Pop();
641  }
642 
643  if (GetPosPixel().X() != mPosSize.TopLeft().X() || (std::abs(GetPosPixel().Y() - mPosSize.TopLeft().Y()) > 5) )
644  {
645  bChange = true;
646  SetPosPixel(mPosSize.TopLeft());
647 
648  Point aLineStart;
649  Point aLineEnd ;
650  switch ( meSidebarPosition )
651  {
653  {
654  aLineStart = EditWin().PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-1) );
655  aLineEnd = EditWin().PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-1) );
656  }
657  break;
659  {
660  aLineStart = EditWin().PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-1) );
661  aLineEnd = EditWin().PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-1) );
662  }
663  break;
664  default:
665  OSL_FAIL( "<SwAnnotationWin::SetPosAndSize()> - unexpected position of sidebar" );
666  break;
667  }
668 
669  // LOK has map mode disabled, and we still want to perform pixel ->
670  // twips conversion for the size of the line above the note.
671  if (comphelper::LibreOfficeKit::isActive() && !EditWin().IsMapModeEnabled())
672  {
673  EditWin().EnableMapMode();
674  Size aSize(aLineEnd.getX() - aLineStart.getX(), aLineEnd.getY() - aLineStart.getY());
675  aSize = EditWin().PixelToLogic(aSize);
676  aLineEnd = aLineStart;
677  aLineEnd.Move(aSize.getWidth(), aSize.getHeight());
678  EditWin().EnableMapMode(false);
679  }
680 
681  if (mpAnchor)
682  {
683  mpAnchor->SetAllPosition( basegfx::B2DPoint( mAnchorRect.Left() , mAnchorRect.Bottom() - 5* 15),
684  basegfx::B2DPoint( mAnchorRect.Left()-5*15 , mAnchorRect.Bottom()+5*15),
685  basegfx::B2DPoint( mAnchorRect.Left()+5*15 , mAnchorRect.Bottom()+5*15),
686  basegfx::B2DPoint( mAnchorRect.Left(), mAnchorRect.Bottom()+2*15),
687  basegfx::B2DPoint( mPageBorder ,mAnchorRect.Bottom()+2*15),
688  basegfx::B2DPoint( aLineStart.X(),aLineStart.Y()),
689  basegfx::B2DPoint( aLineEnd.X(),aLineEnd.Y()));
690  }
691  else
692  {
694  mAnchorRect,
695  mPageBorder,
696  aLineStart,
697  aLineEnd,
698  mColorAnchor );
699  if ( mpAnchor )
700  {
701  mpAnchor->setVisible(true);
702  mpAnchor->SetAnchorState(AnchorState::Tri);
703  if (HasChildPathFocus())
704  {
705  mpAnchor->setLineSolid(true);
706  }
707  }
708  }
709  }
710  else
711  {
712  if ( mpAnchor &&
713  ( mpAnchor->getBasePosition() != basegfx::B2DPoint( mAnchorRect.Left() , mAnchorRect.Bottom()-5*15) ) )
714  {
715  mpAnchor->SetTriPosition( basegfx::B2DPoint( mAnchorRect.Left() , mAnchorRect.Bottom() - 5* 15),
716  basegfx::B2DPoint( mAnchorRect.Left()-5*15 , mAnchorRect.Bottom()+5*15),
717  basegfx::B2DPoint( mAnchorRect.Left()+5*15 , mAnchorRect.Bottom()+5*15),
718  basegfx::B2DPoint( mAnchorRect.Left(), mAnchorRect.Bottom()+2*15),
719  basegfx::B2DPoint( mPageBorder , mAnchorRect.Bottom()+2*15));
720  }
721  }
722 
723  if (bChange)
724  {
725  Point aStart = EditWin().PixelToLogic(GetPosPixel()+Point(0,GetSizePixel().Height()));
726  Point aEnd = EditWin().PixelToLogic(GetPosPixel()+Point(GetSizePixel().Width()-1,GetSizePixel().Height()));
727  mpShadow->SetPosition(basegfx::B2DPoint(aStart.X(),aStart.Y()), basegfx::B2DPoint(aEnd.X(),aEnd.Y()));
728  }
729 
730  if (mrMgr.ShowNotes())
731  {
732  if (IsFollow() && !HasChildPathFocus())
733  {
734  // #i111964#
735  if ( mpAnchor )
736  {
737  mpAnchor->SetAnchorState(AnchorState::End);
738  }
739  }
740  else
741  {
742  // #i111964#
743  if ( mpAnchor )
744  {
745  mpAnchor->SetAnchorState(AnchorState::All);
746  }
747  SwAnnotationWin* pWin = GetTopReplyNote();
748  // #i111964#
749  if ( pWin && pWin->Anchor() )
750  {
752  }
753  }
754  }
755 
756 
757  // text range overlay
758  maAnnotationTextRanges.clear();
759  if ( mrSidebarItem.maLayoutInfo.mnStartNodeIdx != 0
760  && mrSidebarItem.maLayoutInfo.mnStartContent != -1 )
761  {
762  const SwTextAnnotationField* pTextAnnotationField =
763  dynamic_cast< const SwTextAnnotationField* >( mrSidebarItem.GetFormatField().GetTextField() );
764  SwTextNode* pTextNode = pTextAnnotationField ? pTextAnnotationField->GetpTextNode() : nullptr;
765  SwContentNode* pContentNd = nullptr;
766  if (pTextNode)
767  {
768  SwNodes& rNds = pTextNode->GetDoc()->GetNodes();
769  pContentNd = rNds[mrSidebarItem.maLayoutInfo.mnStartNodeIdx]->GetContentNode();
770  }
771  if (pContentNd)
772  {
773  SwPosition aStartPos( *pContentNd, mrSidebarItem.maLayoutInfo.mnStartContent );
774  SwShellCursor* pTmpCursor = nullptr;
775  const bool bTableCursorNeeded = pTextNode->FindTableBoxStartNode() != pContentNd->FindTableBoxStartNode();
776  if ( bTableCursorNeeded )
777  {
778  SwShellTableCursor* pTableCursor = new SwShellTableCursor( mrView.GetWrtShell(), aStartPos );
779  pTableCursor->SetMark();
780  pTableCursor->GetMark()->nNode = *pTextNode;
781  pTableCursor->GetMark()->nContent.Assign( pTextNode, pTextAnnotationField->GetStart()+1 );
782  pTableCursor->NewTableSelection();
783  pTmpCursor = pTableCursor;
784  }
785  else
786  {
787  SwShellCursor* pCursor = new SwShellCursor( mrView.GetWrtShell(), aStartPos );
788  pCursor->SetMark();
789  pCursor->GetMark()->nNode = *pTextNode;
790  pCursor->GetMark()->nContent.Assign( pTextNode, pTextAnnotationField->GetStart()+1 );
791  pTmpCursor = pCursor;
792  }
793  std::unique_ptr<SwShellCursor> pTmpCursorForAnnotationTextRange( pTmpCursor );
794 
795  // For annotation text range rectangles to be calculated correctly,
796  // we need the map mode disabled
797  bool bDisableMapMode = comphelper::LibreOfficeKit::isActive() && EditWin().IsMapModeEnabled();
798  if (bDisableMapMode)
799  EditWin().EnableMapMode(false);
800 
801  pTmpCursorForAnnotationTextRange->FillRects();
802 
803  if (bDisableMapMode)
804  EditWin().EnableMapMode();
805 
806  SwRects* pRects(pTmpCursorForAnnotationTextRange.get());
807  for(SwRect & rNextRect : *pRects)
808  {
809  const tools::Rectangle aPntRect(rNextRect.SVRect());
810  maAnnotationTextRanges.emplace_back(
811  aPntRect.Left(), aPntRect.Top(),
812  aPntRect.Right() + 1, aPntRect.Bottom() + 1);
813  }
814  }
815  }
816 
817  if (mrMgr.ShowNotes() && !maAnnotationTextRanges.empty())
818  {
819  if ( mpTextRangeOverlay != nullptr )
820  {
821  mpTextRangeOverlay->setRanges( maAnnotationTextRanges );
822  if ( mpAnchor != nullptr && mpAnchor->getLineSolid() )
823  {
824  mpTextRangeOverlay->ShowSolidBorder();
825  }
826  else
827  {
828  mpTextRangeOverlay->HideSolidBorder();
829  }
830  }
831  else if (!IsFollow())
832  {
833  // This window is not a reply, then draw its range overlay.
834  mpTextRangeOverlay =
836  mrView,
837  mColorAnchor,
838  maAnnotationTextRanges,
839  mpAnchor && mpAnchor->getLineSolid() );
840  }
841  }
842  else
843  {
844  mpTextRangeOverlay.reset();
845  }
846 }
847 
848 void SwAnnotationWin::DoResize()
849 {
850  long aTextHeight = LogicToPixel( mpOutliner->CalcTextSize()).Height();
851  long aHeight = GetSizePixel().Height();
852  unsigned long aWidth = GetSizePixel().Width();
853 
854  aHeight -= GetMetaHeight();
855  mpMetadataAuthor->Show();
856  mpMetadataDate->Show();
857  mpSidebarTextControl->SetQuickHelpText(OUString());
858 
859  if (aTextHeight > aHeight)
860  { // we need vertical scrollbars and have to reduce the width
861  aWidth -= GetScrollbarWidth();
862  mpVScrollbar->Show();
863  }
864  else
865  {
866  mpVScrollbar->Hide();
867  }
868 
869  {
870  const Size aSizeOfMetadataControls( GetSizePixel().Width() - GetMetaButtonAreaWidth(),
871  GetMetaHeight()/2 );
872  mpMetadataAuthor->setPosSizePixel( 0,
873  aHeight,
874  aSizeOfMetadataControls.Width(),
875  aSizeOfMetadataControls.Height() );
876  mpMetadataDate->setPosSizePixel( 0,
877  aHeight + aSizeOfMetadataControls.Height(),
878  aSizeOfMetadataControls.Width(),
879  aSizeOfMetadataControls.Height() );
880  }
881 
882  mpOutliner->SetPaperSize( PixelToLogic( Size(aWidth,aHeight) ) ) ;
883  if (!mpVScrollbar->IsVisible())
884  { // if we do not have a scrollbar anymore, we want to see the complete text
885  mpOutlinerView->SetVisArea( PixelToLogic( tools::Rectangle(0,0,aWidth,aHeight) ) );
886  }
887  mpOutlinerView->SetOutputArea( PixelToLogic( tools::Rectangle(0,0,aWidth,aHeight) ) );
888 
890  {
891  mpSidebarTextControl->setPosSizePixel(0, 0, aWidth, aHeight);
892  mpVScrollbar->setPosSizePixel( aWidth, 0, GetScrollbarWidth(), aHeight);
893  }
894  else
895  {
896  mpSidebarTextControl->setPosSizePixel( ( aTextHeight > aHeight ? GetScrollbarWidth() : 0 ), 0,
897  aWidth, aHeight);
898  mpVScrollbar->setPosSizePixel( 0, 0, GetScrollbarWidth(), aHeight);
899  }
900 
901  mpVScrollbar->SetVisibleSize( PixelToLogic(Size(0,aHeight)).Height() );
902  mpVScrollbar->SetPageSize( PixelToLogic(Size(0,aHeight)).Height() * 8 / 10 );
903  mpVScrollbar->SetLineSize( mpOutliner->GetTextHeight() / 10 );
904  SetScrollbar();
905  mpVScrollbar->SetRange( Range(0, mpOutliner->GetTextHeight()));
906 
907  //calculate rects for meta- button
908  const Fraction& fx( GetMapMode().GetScaleX() );
909  const Fraction& fy( GetMapMode().GetScaleY() );
910 
911  const Point aPos( mpMetadataAuthor->GetPosPixel());
912  mpMenuButton->setPosSizePixel( long(aPos.X()+GetSizePixel().Width()-(METABUTTON_WIDTH+10)*fx),
913  long(aPos.Y()+5*fy),
914  long(METABUTTON_WIDTH*fx),
915  long(METABUTTON_HEIGHT*fy) );
916 }
917 
918 void SwAnnotationWin::SetSizePixel( const Size& rNewSize )
919 {
920  Window::SetSizePixel(rNewSize);
921 
922  if (mpShadow)
923  {
924  Point aStart = EditWin().PixelToLogic(GetPosPixel()+Point(0,GetSizePixel().Height()));
925  Point aEnd = EditWin().PixelToLogic(GetPosPixel()+Point(GetSizePixel().Width()-1,GetSizePixel().Height()));
926  mpShadow->SetPosition(basegfx::B2DPoint(aStart.X(),aStart.Y()), basegfx::B2DPoint(aEnd.X(),aEnd.Y()));
927  }
928 }
929 
930 void SwAnnotationWin::SetScrollbar()
931 {
932  mpVScrollbar->SetThumbPos(mpOutlinerView->GetVisArea().Top());
933 }
934 
935 void SwAnnotationWin::ResizeIfNecessary(long aOldHeight, long aNewHeight)
936 {
937  if (aOldHeight != aNewHeight)
938  {
939  //check for lower border or next note
940  long aBorder = mrMgr.GetNextBorder();
941  if (aBorder != -1)
942  {
943  if (aNewHeight > GetMinimumSizeWithoutMeta())
944  {
945  long aNewLowerValue = GetPosPixel().Y() + aNewHeight + GetMetaHeight();
946  if (aNewLowerValue < aBorder)
947  SetSizePixel(Size(GetSizePixel().Width(),aNewHeight+GetMetaHeight()));
948  else
949  SetSizePixel(Size(GetSizePixel().Width(),aBorder - GetPosPixel().Y()));
950  DoResize();
951  Invalidate();
952  }
953  else
954  {
955  if (GetSizePixel().Height() != GetMinimumSizeWithoutMeta() + GetMetaHeight())
956  SetSizePixel(Size(GetSizePixel().Width(),GetMinimumSizeWithoutMeta() + GetMetaHeight()));
957  DoResize();
958  Invalidate();
959  }
960  }
961  else
962  {
963  DoResize();
964  Invalidate();
965  }
966  }
967  else
968  {
969  SetScrollbar();
970  }
971 }
972 
973 void SwAnnotationWin::SetColor(Color aColorDark,Color aColorLight, Color aColorAnchor)
974 {
975  mColorDark = aColorDark;
976  mColorLight = aColorLight;
977  mColorAnchor = aColorAnchor;
978 
979  if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
980  {
981  {
982  mpMetadataAuthor->SetControlBackground(mColorDark);
983  AllSettings aSettings = mpMetadataAuthor->GetSettings();
984  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
985  aStyleSettings.SetFieldTextColor(aColorAnchor);
986  aSettings.SetStyleSettings(aStyleSettings);
987  mpMetadataAuthor->SetSettings(aSettings);
988  }
989 
990  {
991  mpMetadataDate->SetControlBackground(mColorDark);
992  AllSettings aSettings = mpMetadataDate->GetSettings();
993  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
994  aStyleSettings.SetFieldTextColor(aColorAnchor);
995  aSettings.SetStyleSettings(aStyleSettings);
996  mpMetadataDate->SetSettings(aSettings);
997  }
998 
999  AllSettings aSettings2 = mpVScrollbar->GetSettings();
1000  StyleSettings aStyleSettings2 = aSettings2.GetStyleSettings();
1001  aStyleSettings2.SetButtonTextColor(Color(0,0,0));
1002  aStyleSettings2.SetCheckedColor(mColorLight); // background
1003  aStyleSettings2.SetShadowColor(mColorAnchor);
1004  aStyleSettings2.SetFaceColor(mColorDark);
1005  aSettings2.SetStyleSettings(aStyleSettings2);
1006  mpVScrollbar->SetSettings(aSettings2);
1007  }
1008 }
1009 
1010 void SwAnnotationWin::SetSidebarPosition(sw::sidebarwindows::SidebarPosition eSidebarPosition)
1011 {
1012  meSidebarPosition = eSidebarPosition;
1013 }
1014 
1015 void SwAnnotationWin::SetReadonly(bool bSet)
1016 {
1017  mbReadonly = bSet;
1018  GetOutlinerView()->SetReadOnly(bSet);
1019 }
1020 
1022 {
1023  Link<LinkParamNone*,void> aLink = mpOutliner->GetModifyHdl();
1024  mpOutliner->SetModifyHdl( Link<LinkParamNone*,void>() );
1025  ESelection aOld = GetOutlinerView()->GetSelection();
1026 
1027  ESelection aNewSelection( 0, 0, mpOutliner->GetParagraphCount()-1, EE_TEXTPOS_ALL );
1028  GetOutlinerView()->SetSelection( aNewSelection );
1029  SfxItemSet aEditAttr(GetOutlinerView()->GetAttribs());
1030  aEditAttr.Put(rNewItem);
1031  GetOutlinerView()->SetAttribs( aEditAttr );
1032 
1033  GetOutlinerView()->SetSelection(aOld);
1034  mpOutliner->SetModifyHdl( aLink );
1035 
1036  const SwViewOption* pVOpt = mrView.GetWrtShellPtr()->GetViewOptions();
1037  EEControlBits nCntrl = mpOutliner->GetControlWord();
1038  // turn off
1039  nCntrl &= ~EEControlBits::ONLINESPELLING;
1040  mpOutliner->SetControlWord(nCntrl);
1041 
1042  //turn back on
1043  if (pVOpt->IsOnlineSpell())
1044  nCntrl |= EEControlBits::ONLINESPELLING;
1045  else
1046  nCntrl &= ~EEControlBits::ONLINESPELLING;
1047  mpOutliner->SetControlWord(nCntrl);
1048 
1049  mpOutliner->CompleteOnlineSpelling();
1050  Invalidate();
1051 }
1052 
1053 void SwAnnotationWin::GetFocus()
1054 {
1055  if (mpSidebarTextControl)
1056  mpSidebarTextControl->GrabFocus();
1057 }
1058 
1059 void SwAnnotationWin::LoseFocus()
1060 {
1061 }
1062 
1063 void SwAnnotationWin::ShowNote()
1064 {
1065  SetPosAndSize();
1066  if (!IsVisible())
1067  Window::Show();
1068  if (mpShadow && !mpShadow->isVisible())
1069  mpShadow->setVisible(true);
1070  if (mpAnchor && !mpAnchor->isVisible())
1071  mpAnchor->setVisible(true);
1072 
1073  // Invalidate.
1074  InvalidateControl();
1075 }
1076 
1077 void SwAnnotationWin::HideNote()
1078 {
1079  if (IsVisible())
1080  Window::Hide();
1081  if (mpAnchor)
1082  {
1083  if (mrMgr.IsShowAnchor())
1084  mpAnchor->SetAnchorState(AnchorState::Tri);
1085  else
1086  mpAnchor->setVisible(false);
1087  }
1088  if (mpShadow && mpShadow->isVisible())
1089  mpShadow->setVisible(false);
1090 }
1091 
1092 void SwAnnotationWin::InvalidateControl()
1093 {
1094  // Invalidate.
1095  mpSidebarTextControl->Push(PushFlags::MAPMODE);
1096  lcl_translateTwips(EditWin(), *mpSidebarTextControl, nullptr);
1097  mpSidebarTextControl->Invalidate();
1098  mpSidebarTextControl->Pop();
1099 }
1100 
1101 void SwAnnotationWin::ActivatePostIt()
1102 {
1103  mrMgr.AssureStdModeAtShell();
1104 
1105  mpOutliner->ClearModifyFlag();
1106  mpOutliner->GetUndoManager().Clear();
1107 
1108  CheckMetaText();
1109  SetViewState(ViewState::EDIT);
1110  GetOutlinerView()->ShowCursor();
1111 
1112  mpOutlinerView->GetEditView().SetInsertMode(mrView.GetWrtShellPtr()->IsInsMode());
1113 
1115  GetOutlinerView()->SetBackgroundColor(mColorDark);
1116 
1117  //tdf#119130 only have the active postit as a dialog control in which pressing
1118  //ctrl+tab cycles between text and button so we don't waste time searching
1119  //thousands of SwAnnotationWins
1120  SetStyle(GetStyle() | WB_DIALOGCONTROL);
1121 }
1122 
1123 void SwAnnotationWin::DeactivatePostIt()
1124 {
1125  //tdf#119130 only have the active postit as a dialog control in which pressing
1126  //ctrl+tab cycles between text and button so we don't waste time searching
1127  //thousands of SwAnnotationWins
1128  SetStyle(GetStyle() & ~WB_DIALOGCONTROL);
1129 
1130  // remove selection, #i87073#
1131  if (GetOutlinerView()->GetEditView().HasSelection())
1132  {
1133  ESelection aSelection = GetOutlinerView()->GetEditView().GetSelection();
1134  aSelection.nEndPara = aSelection.nStartPara;
1135  aSelection.nEndPos = aSelection.nStartPos;
1136  GetOutlinerView()->GetEditView().SetSelection(aSelection);
1137  }
1138 
1139  mpOutliner->CompleteOnlineSpelling();
1140 
1141  SetViewState(ViewState::NORMAL);
1142  // Make sure this view doesn't emit LOK callbacks during the update, as the
1143  // sidebar window's SidebarTextControl doesn't have a valid twip offset
1144  // (map mode origin) during that operation.
1145  bool bTiledPainting = comphelper::LibreOfficeKit::isTiledPainting();
1147  // write the visible text back into the SwField
1148  UpdateData();
1150 
1151  if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1152  GetOutlinerView()->SetBackgroundColor(COL_TRANSPARENT);
1153 
1154  if ( !IsProtected() && mpOutliner->GetEditEngine().GetText().isEmpty() )
1155  {
1156  mnEventId = Application::PostUserEvent( LINK( this, SwAnnotationWin, DeleteHdl), nullptr, true );
1157  }
1158 }
1159 
1160 void SwAnnotationWin::ToggleInsMode()
1161 {
1162  if (!mrView.GetWrtShell().IsRedlineOn())
1163  {
1164  //change outliner
1165  mpOutlinerView->GetEditView().SetInsertMode(!mpOutlinerView->GetEditView().IsInsertMode());
1166  //change document
1167  mrView.GetWrtShell().ToggleInsMode();
1168  //update statusbar
1169  SfxBindings &rBnd = mrView.GetViewFrame()->GetBindings();
1170  rBnd.Invalidate(SID_ATTR_INSERT);
1171  rBnd.Update(SID_ATTR_INSERT);
1172  }
1173 }
1174 
1175 void SwAnnotationWin::ExecuteCommand(sal_uInt16 nSlot)
1176 {
1177  mrMgr.AssureStdModeAtShell();
1178 
1179  switch (nSlot)
1180  {
1181  case FN_POSTIT:
1182  case FN_REPLY:
1183  {
1184  // if this note is empty, it will be deleted once losing the focus, so no reply, but only a new note
1185  // will be created
1186  if (!mpOutliner->GetEditEngine().GetText().isEmpty())
1187  {
1188  OutlinerParaObject* pPara = new OutlinerParaObject(*GetOutlinerView()->GetEditView().CreateTextObject());
1189  mrMgr.RegisterAnswer(pPara);
1190  }
1191  if (mrMgr.HasActiveSidebarWin())
1192  mrMgr.SetActiveSidebarWin(nullptr);
1193  SwitchToFieldPos();
1194  mrView.GetViewFrame()->GetDispatcher()->Execute(FN_POSTIT);
1195  break;
1196  }
1197  case FN_DELETE_COMMENT:
1198 
1199  //Delete(); // do not kill the parent of our open popup menu
1200  mnEventId = Application::PostUserEvent( LINK( this, SwAnnotationWin, DeleteHdl), nullptr, true );
1201  break;
1202  case FN_FORMAT_ALL_NOTES:
1203  case FN_DELETE_ALL_NOTES:
1204  case FN_HIDE_ALL_NOTES:
1205  // not possible as slot as this would require that "this" is the active postit
1206  mrView.GetViewFrame()->GetBindings().Execute( nSlot, nullptr, SfxCallMode::ASYNCHRON );
1207  break;
1208  case FN_DELETE_NOTE_AUTHOR:
1209  case FN_HIDE_NOTE_AUTHOR:
1210  {
1211  // not possible as slot as this would require that "this" is the active postit
1212  SfxStringItem aItem( nSlot, GetAuthor() );
1213  const SfxPoolItem* aItems[2];
1214  aItems[0] = &aItem;
1215  aItems[1] = nullptr;
1216  mrView.GetViewFrame()->GetBindings().Execute( nSlot, aItems, SfxCallMode::ASYNCHRON );
1217  }
1218  break;
1219  default:
1220  mrView.GetViewFrame()->GetBindings().Execute( nSlot );
1221  break;
1222  }
1223 }
1224 
1225 SwEditWin& SwAnnotationWin::EditWin()
1226 {
1227  return mrView.GetEditWin();
1228 }
1229 
1230 long SwAnnotationWin::GetPostItTextHeight()
1231 {
1232  return mpOutliner ? LogicToPixel(mpOutliner->CalcTextSize()).Height() : 0;
1233 }
1234 
1235 void SwAnnotationWin::SwitchToPostIt(sal_uInt16 aDirection)
1236 {
1237  SwAnnotationWin* pPostIt = mrMgr.GetNextPostIt(aDirection, this);
1238  if (pPostIt)
1239  pPostIt->GrabFocus();
1240 }
1241 
1242 IMPL_LINK( SwAnnotationWin, WindowEventListener, VclWindowEvent&, rEvent, void )
1243 {
1244  if ( rEvent.GetId() == VclEventId::WindowMouseMove )
1245  {
1246  MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rEvent.GetData());
1247  if ( pMouseEvt->IsEnterWindow() )
1248  {
1249  mbMouseOver = true;
1250  if ( !HasFocus() )
1251  {
1252  SetViewState(ViewState::VIEW);
1253  Invalidate();
1254  }
1255  }
1256  else if ( pMouseEvt->IsLeaveWindow())
1257  {
1258  mbMouseOver = false;
1259  if ( !HasFocus() )
1260  {
1261  SetViewState(ViewState::NORMAL);
1262  Invalidate();
1263  }
1264  }
1265  }
1266  else if ( rEvent.GetId() == VclEventId::WindowActivate &&
1267  rEvent.GetWindow() == mpSidebarTextControl )
1268  {
1269  const bool bLockView = mrView.GetWrtShell().IsViewLocked();
1270  mrView.GetWrtShell().LockView( true );
1271  mrMgr.SetActiveSidebarWin( this );
1272  mrView.GetWrtShell().LockView( bLockView );
1273  mrMgr.MakeVisible( this );
1274  }
1275 }
1276 
1277 IMPL_LINK(SwAnnotationWin, ScrollHdl, ScrollBar*, pScroll, void)
1278 {
1279  long nDiff = GetOutlinerView()->GetEditView().GetVisArea().Top() - pScroll->GetThumbPos();
1280  GetOutlinerView()->Scroll( 0, nDiff );
1281 }
1282 
1284 {
1285  mrView.GetDocShell()->SetModified();
1286 }
1287 
1288 IMPL_LINK_NOARG(SwAnnotationWin, DeleteHdl, void*, void)
1289 {
1290  mnEventId = nullptr;
1291  Delete();
1292 }
1293 
1294 void SwAnnotationWin::ResetAttributes()
1295 {
1296  mpOutlinerView->RemoveAttribsKeepLanguages(true);
1297  mpOutliner->RemoveFields();
1298  mpOutlinerView->SetAttribs(DefaultItem());
1299 }
1300 
1301 sal_Int32 SwAnnotationWin::GetScrollbarWidth()
1302 {
1303  return mrView.GetWrtShell().GetViewOptions()->GetZoom() / 10;
1304 }
1305 
1306 sal_Int32 SwAnnotationWin::GetMetaButtonAreaWidth()
1307 {
1308  const Fraction& f( GetMapMode().GetScaleX() );
1309  return long(METABUTTON_AREA_WIDTH * f);
1310 }
1311 
1312 sal_Int32 SwAnnotationWin::GetMetaHeight()
1313 {
1314  const Fraction& f(mrView.GetWrtShellPtr()->GetOut()->GetMapMode().GetScaleY());
1315  return long(POSTIT_META_HEIGHT * f);
1316 }
1317 
1318 sal_Int32 SwAnnotationWin::GetMinimumSizeWithMeta()
1319 {
1320  return mrMgr.GetMinimumSizeWithMeta();
1321 }
1322 
1323 sal_Int32 SwAnnotationWin::GetMinimumSizeWithoutMeta()
1324 {
1325  const Fraction& f(mrView.GetWrtShellPtr()->GetOut()->GetMapMode().GetScaleY());
1326  return long(POSTIT_MINIMUMSIZE_WITHOUT_META * f);
1327 }
1328 
1329 void SwAnnotationWin::SetSpellChecking()
1330 {
1331  const SwViewOption* pVOpt = mrView.GetWrtShellPtr()->GetViewOptions();
1332  EEControlBits nCntrl = mpOutliner->GetControlWord();
1333  if (pVOpt->IsOnlineSpell())
1334  nCntrl |= EEControlBits::ONLINESPELLING;
1335  else
1336  nCntrl &= ~EEControlBits::ONLINESPELLING;
1337  mpOutliner->SetControlWord(nCntrl);
1338 
1339  mpOutliner->CompleteOnlineSpelling();
1340  Invalidate();
1341 }
1342 
1343 void SwAnnotationWin::SetViewState(ViewState bViewState)
1344 {
1345  switch (bViewState)
1346  {
1347  case ViewState::EDIT:
1348  {
1349  if (mpAnchor)
1350  {
1351  mpAnchor->SetAnchorState(AnchorState::All);
1352  SwAnnotationWin* pWin = GetTopReplyNote();
1353  // #i111964#
1354  if ( pWin && pWin->Anchor() )
1355  {
1357  }
1358  mpAnchor->setLineSolid(true);
1359  if ( mpTextRangeOverlay != nullptr )
1360  {
1361  mpTextRangeOverlay->ShowSolidBorder();
1362  }
1363  }
1364  if (mpShadow)
1365  mpShadow->SetShadowState(SS_EDIT);
1366  break;
1367  }
1368  case ViewState::VIEW:
1369  {
1370  if (mpAnchor)
1371  {
1372  mpAnchor->setLineSolid(true);
1373  if ( mpTextRangeOverlay != nullptr )
1374  {
1375  mpTextRangeOverlay->ShowSolidBorder();
1376  }
1377  }
1378  if (mpShadow)
1379  mpShadow->SetShadowState(SS_VIEW);
1380  break;
1381  }
1382  case ViewState::NORMAL:
1383  {
1384  if (mpAnchor)
1385  {
1386  if (IsFollow())
1387  {
1388  // if there is no visible parent note, we want to see the complete anchor ??
1389  //if (IsAnyStackParentVisible())
1390  mpAnchor->SetAnchorState(AnchorState::End);
1391  SwAnnotationWin* pTopWinSelf = GetTopReplyNote();
1392  SwAnnotationWin* pTopWinActive = mrMgr.HasActiveSidebarWin()
1393  ? mrMgr.GetActiveSidebarWin()->GetTopReplyNote()
1394  : nullptr;
1395  // #i111964#
1396  if ( pTopWinSelf && ( pTopWinSelf != pTopWinActive ) &&
1397  pTopWinSelf->Anchor() )
1398  {
1399  if ( pTopWinSelf != mrMgr.GetActiveSidebarWin() )
1400  {
1401  pTopWinSelf->Anchor()->setLineSolid(false);
1402  if ( pTopWinSelf->TextRange() != nullptr )
1403  {
1404  pTopWinSelf->TextRange()->HideSolidBorder();
1405  }
1406  }
1407  pTopWinSelf->Anchor()->SetAnchorState(AnchorState::All);
1408  }
1409  }
1410  mpAnchor->setLineSolid(false);
1411  if ( mpTextRangeOverlay != nullptr )
1412  {
1413  mpTextRangeOverlay->HideSolidBorder();
1414  }
1415  }
1416  if ( mpShadow )
1417  {
1418  mpShadow->SetShadowState(SS_NORMAL);
1419  }
1420  break;
1421  }
1422  }
1423 }
1424 
1425 SwAnnotationWin* SwAnnotationWin::GetTopReplyNote()
1426 {
1427  SwAnnotationWin* pTopNote = nullptr;
1428  SwAnnotationWin* pSidebarWin = IsFollow() ? mrMgr.GetNextPostIt(KEY_PAGEUP, this) : nullptr;
1429  while (pSidebarWin)
1430  {
1431  pTopNote = pSidebarWin;
1432  pSidebarWin = pSidebarWin->IsFollow() ? mrMgr.GetNextPostIt(KEY_PAGEUP, pSidebarWin) : nullptr;
1433  }
1434  return pTopNote;
1435 }
1436 
1437 void SwAnnotationWin::SwitchToFieldPos()
1438 {
1439  if ( mrMgr.GetActiveSidebarWin() == this )
1440  mrMgr.SetActiveSidebarWin(nullptr);
1441  GotoPos();
1442  sal_uInt32 aCount = MoveCaret();
1443  if (aCount)
1444  mrView.GetDocShell()->GetWrtShell()->SwCursorShell::Right(aCount, 0);
1445  GrabFocusToDocument();
1446 }
1447 
1448 void SwAnnotationWin::SetChangeTracking( const SwPostItHelper::SwLayoutStatus aLayoutStatus,
1449  const Color& aChangeColor )
1450 {
1451  if ( (mLayoutStatus != aLayoutStatus) ||
1452  (mChangeColor != aChangeColor) )
1453  {
1454  mLayoutStatus = aLayoutStatus;
1455  mChangeColor = aChangeColor;
1456  Invalidate();
1457  }
1458 }
1459 
1460 bool SwAnnotationWin::HasScrollbar() const
1461 {
1462  return mpVScrollbar != nullptr;
1463 }
1464 
1465 bool SwAnnotationWin::IsScrollbarVisible() const
1466 {
1467  return HasScrollbar() && mpVScrollbar->IsVisible();
1468 }
1469 
1470 void SwAnnotationWin::ChangeSidebarItem( SwSidebarItem const & rSidebarItem )
1471 {
1472  const bool bAnchorChanged = mpAnchorFrame != rSidebarItem.maLayoutInfo.mpAnchorFrame;
1473  if ( bAnchorChanged )
1474  {
1475  mrMgr.DisconnectSidebarWinFromFrame( *mpAnchorFrame, *this );
1476  }
1477 
1478  mrSidebarItem = rSidebarItem;
1479  mpAnchorFrame = mrSidebarItem.maLayoutInfo.mpAnchorFrame;
1480 
1481  if ( GetWindowPeer() )
1482  {
1483  SidebarWinAccessible* pAcc =
1484  static_cast<SidebarWinAccessible*>( GetWindowPeer() );
1485  OSL_ENSURE( dynamic_cast<SidebarWinAccessible*>( GetWindowPeer() ),
1486  "<SwAnnotationWin::ChangeSidebarItem(..)> - unexpected type of window peer -> crash possible!" );
1487  pAcc->ChangeSidebarItem( mrSidebarItem );
1488  }
1489 
1490  if ( bAnchorChanged )
1491  {
1492  mrMgr.ConnectSidebarWinToFrame( *(mrSidebarItem.maLayoutInfo.mpAnchorFrame),
1493  mrSidebarItem.GetFormatField(),
1494  *this );
1495  }
1496 }
1497 
1498 css::uno::Reference< css::accessibility::XAccessible > SwAnnotationWin::CreateAccessible()
1499 {
1500  SidebarWinAccessible* pAcc( new SidebarWinAccessible( *this,
1501  mrView.GetWrtShell(),
1502  mrSidebarItem ) );
1503  css::uno::Reference< css::awt::XWindowPeer > xWinPeer( pAcc );
1504  SetWindowPeer( xWinPeer, pAcc );
1505 
1506  css::uno::Reference< css::accessibility::XAccessible > xAcc( xWinPeer, css::uno::UNO_QUERY );
1507  return xAcc;
1508 }
1509 
1510 } } // eof of namespace sw::sidebarwindows
1511 
1512 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define FN_HIDE_ALL_NOTES
Definition: cmdid.h:725
virtual Point GetPosPixel() const
void SetCheckedColor(const Color &rColor)
const Fraction & GetScaleX() const
long Width() const
sal_Int32 & GetStart()
start position
Definition: txatbase.hxx:77
sal_Int32 nStartPara
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
Marks a position in the document model.
Definition: pam.hxx:35
const SwFrame * mpAnchorFrame
void SetFieldFont(const vcl::Font &rFont)
#define METABUTTON_AREA_WIDTH
void SetStyleSettings(const StyleSettings &rSet)
long Height() const
#define KEY_PAGEUP
WinBits const WB_NODIALOGCONTROL
SwNodeIndex nNode
Definition: pam.hxx:37
::sw::overlay::OverlayRanges * TextRange()
long GetOutOffXPixel() const
MouseEventModifiers GetMode() const
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
const SwPosition * GetMark() const
Definition: pam.hxx:209
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:402
bool IsMapModeEnabled() const
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:573
Any GetTime(const OUString &val)
IMPL_LINK(SidebarTextControl, OnlineSpellCallback, SpellCallbackInfo &, rInfo, void)
virtual Size GetSizePixel() const
void SetCalcFieldValueHdl(Outliner *pOutliner)
In the Outliner, set a link to the method for field display in edit objects.
Definition: docdraw.cxx:491
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
const MapMode & GetMapMode() const
SwTextNode * GetpTextNode() const
Definition: txtfld.hxx:49
static Color GetColorAnchor(std::size_t aAuthorIndex)
Definition: PostItMgr.cxx:2098
WinBits const WB_VSCROLL
Dialog to specify the properties of drop-down form field.
Definition: accfrmobj.cxx:40
void EnableMapMode(bool bEnable=true)
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
void Invalidate(sal_uInt16 nId)
void setTiledPainting(bool bTiledPainting)
void SetButtonTextColor(const Color &rColor)
EEControlBits
void SetMapMode()
const vcl::Font & GetFieldFont() const
#define POSTIT_MINIMUMSIZE_WITHOUT_META
bool IsValidAndGregorian() const
sal_uInt16 GetClicks() const
void ChangeSidebarItem(const SwSidebarItem &rSidebarItem)
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
const LocaleDataWrapper & GetLocaleData() const
ESelection aNewSelection(GetSelection())
#define FN_FORMAT_ALL_NOTES
Definition: cmdid.h:729
sal_uInt16 GetButtons() const
SwIndex nContent
Definition: pam.hxx:38
const Fraction & GetScaleY() const
#define X
bool IsEnterWindow() const
static Color GetColorDark(std::size_t aAuthorIndex)
Definition: PostItMgr.cxx:2068
bool GetHighContrastMode() const
#define FN_DELETE_COMMENT
Definition: cmdid.h:727
sal_Int32 nEndPos
static std::unique_ptr< AnchorOverlayObject > CreateAnchorOverlayObject(SwView const &rDocView, const SwRect &aAnchorRect, long aPageBorder, const Point &aLineStart, const Point &aLineEnd, const Color &aColorAnchor)
void DrawRect(const tools::Rectangle &rRect)
SfxItemPool & GetPool() const
long getY() const
void SetMapUnit(MapUnit eUnit)
long getX() const
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:202
WinBits const WB_DIALOGCONTROL
#define FN_REPLY
Definition: cmdid.h:728
void SetLineColor()
sal_Int32 nEndPara
#define SW_MOD()
Definition: swmodule.hxx:255
bool IsLeaveWindow() const
DrawFlags
static std::unique_ptr< OverlayRanges > CreateOverlayRange(SwView const &rDocView, const Color &rColor, const std::vector< basegfx::B2DRange > &rRanges, const bool bShowSolidBorder)
#define METABUTTON_WIDTH
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:59
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
#define FN_DELETE_NOTE_AUTHOR
Definition: cmdid.h:721
#define METABUTTON_HEIGHT
int i
void SetOrigin(const Point &rOrigin)
#define FN_HIDE_NOTE_AUTHOR
Definition: cmdid.h:724
void SetCursorLogicPosition(const Point &rPosition, bool bPoint, bool bClearMark)
SwDoc * GetDoc()
Definition: node.hxx:702
IMPL_LINK_NOARG(DocumentTimerManager, DoIdleJobs, Timer *, void)
void SetFillColor()
static bool GetLayoutRTL()
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:740
#define EE_CHAR_FONTHEIGHT
bool IsInside(const Point &rPOINT) const
MapUnit GetMapUnit() const
OUString SwResId(const char *pId)
Definition: swmodule.cxx:191
bool IsOnlineSpell() const
Definition: viewopt.hxx:325
sal_uInt16 GetModifier() const
static bool IsFieldShadings()
Definition: viewopt.hxx:625
void GrabFocus()
long X() const
#define Y
SwLayoutInfo maLayoutInfo
::sw::sidebarwindows::AnchorOverlayObject * Anchor()
void SetAnchorState(const AnchorState aState)
Point PixelToLogic(const Point &rDevicePt) const
std::unique_ptr< drawinglayer::processor2d::BaseProcessor2D > createBaseProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
void Update(sal_uInt16 nId)
WinBits const WB_3DLOOK
OUString getDate(const Date &rDate) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
sal_uInt16 GetChildCount() const
std::vector< SwRect > SwRects
Definition: swregion.hxx:26
void SetFaceColor(const Color &rColor)
static Color GetColorLight(std::size_t aAuthorIndex)
Definition: PostItMgr.cxx:2083
SlideSorterView & mrView
bool IsVisible() const
SwNodes & GetNodes()
Definition: doc.hxx:403
static VclPtr< reference_type > Create(Arg &&...arg)
void SetFontHeight(long nHeight)
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect)
#define POSTIT_META_HEIGHT
long GetOutOffYPixel() const
const Point & GetPosPixel() const
void SetLanguage(SwWrtShell &rWrtSh, const OUString &rLangText, bool bIsForSelection, SfxItemSet &rCoreSet)
Definition: langhelper.cxx:223
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:196
void Move(long nHorzMove, long nVertMove)
void(* f)(TrueTypeTable *)
void SetFieldTextColor(const Color &rColor)
void SetShadowColor(const Color &rColor)
OUString getTime(const tools::Time &rTime, bool bSec=true, bool b100Sec=false) const
void Push(PushFlags nFlags=PushFlags::ALL)
bool NewTableSelection()
Definition: swcrsr.cxx:2428
#define EE_TEXTPOS_ALL
#define FN_POSTIT
Definition: cmdid.h:206
long Y() const
vcl::Window * GetChild(sal_uInt16 nChild) const
#define FN_DELETE_ALL_NOTES
Definition: cmdid.h:722
WinBits const WB_DRAG
sal_Int32 nStartPos