1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_wasm_strip.h>
22 #include <sal/config.h>
26 #include "SidebarWinAcc.hxx"
27 #include <PostItMgr.hxx>
28 #include <AnnotationWin.hxx>
29 #include <IDocumentUndoRedo.hxx>
30 #include <basegfx/range/b2drange.hxx>
31 #include "SidebarTxtControl.hxx"
32 #include "AnchorOverlayObject.hxx"
33 #include "ShadowOverlayObject.hxx"
34 #include "OverlayRanges.hxx"
36 #include <strings.hrc>
38 #include <viewopt.hxx>
41 #include <editeng/fhgtitem.hxx>
42 #include <editeng/langitem.hxx>
43 #include <editeng/editview.hxx>
44 #include <editeng/outliner.hxx>
45 #include <editeng/editeng.hxx>
46 #include <editeng/eeitem.hxx>
47 #include <editeng/outlobj.hxx>
48 #include <editeng/editund2.hxx>
50 #include <svl/undo.hxx>
51 #include <svl/stritem.hxx>
53 #include <sfx2/viewfrm.hxx>
54 #include <sfx2/bindings.hxx>
55 #include <sfx2/dispatch.hxx>
57 #include <vcl/decoview.hxx>
58 #include <vcl/event.hxx>
59 #include <vcl/gradient.hxx>
60 #include <vcl/pdfextoutdevdata.hxx>
61 #include <vcl/svapp.hxx>
62 #include <vcl/settings.hxx>
63 #include <vcl/ptrstyle.hxx>
64 #include <vcl/uitest/logger.hxx>
65 #include <vcl/uitest/eventdescription.hxx>
72 #include <docstyle.hxx>
73 #include <docufld.hxx>
74 #include <swmodule.hxx>
76 #include <SwRewriter.hxx>
77 #include <txtannotationfld.hxx>
79 #include <svtools/colorcfg.hxx>
81 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
82 #include <drawinglayer/processor2d/processor2dtools.hxx>
83 #include <officecfg/Office/Writer.hxx>
84 #include <osl/diagnose.h>
85 #include <unotools/localedatawrapper.hxx>
86 #include <unotools/syslocale.hxx>
88 #include <comphelper/lok.hxx>
90 using namespace sw::sidebarwindows
;
95 void collectUIInformation( const OUString
& aevent
, const OUString
& aID
)
97 EventDescription aDescription
;
98 aDescription
.aID
= aID
;
99 aDescription
.aParameters
= {{"" , ""}};
100 aDescription
.aAction
= aevent
;
101 aDescription
.aParent
= "MainWindow";
102 aDescription
.aKeyWord
= "SwEditWinUIObject";
103 UITestLogger::getInstance().logEvent(aDescription
);
108 namespace sw::annotation
{
110 #define METABUTTON_WIDTH 16
111 #define METABUTTON_HEIGHT 18
112 #define POSTIT_MINIMUMSIZE_WITHOUT_META 50
114 void SwAnnotationWin::PaintTile(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
116 bool bMenuButtonVisible
= mxMenuButton
->get_visible();
117 // No point in showing this button till click on it are not handled.
118 if (bMenuButtonVisible
)
119 mxMenuButton
->hide();
121 // draw left over space
122 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode())
123 rRenderContext
.SetFillColor(COL_BLACK
);
125 rRenderContext
.SetFillColor(mColorDark
);
126 rRenderContext
.SetLineColor();
127 rRenderContext
.DrawRect(rRect
);
129 m_xContainer
->draw(rRenderContext
, rRect
.TopLeft(), GetSizePixel());
131 const drawinglayer::geometry::ViewInformation2D aViewInformation
;
132 std::unique_ptr
<drawinglayer::processor2d::BaseProcessor2D
> pProcessor(drawinglayer::processor2d::createProcessor2DFromOutputDevice(rRenderContext
, aViewInformation
));
134 // drawinglayer sets the map mode to pixels, not needed here.
135 rRenderContext
.Pop();
136 // Work in document-global twips.
137 rRenderContext
.Pop();
139 pProcessor
->process(mpAnchor
->getOverlayObjectPrimitive2DSequence());
140 if (mpTextRangeOverlay
)
141 pProcessor
->process(mpTextRangeOverlay
->getOverlayObjectPrimitive2DSequence());
143 rRenderContext
.Push(vcl::PushFlags::NONE
);
145 rRenderContext
.Push(vcl::PushFlags::NONE
);
147 if (bMenuButtonVisible
)
148 mxMenuButton
->show();
151 bool SwAnnotationWin::IsHitWindow(const Point
& rPointLogic
)
153 tools::Rectangle
aRectangleLogic(EditWin().PixelToLogic(tools::Rectangle(GetPosPixel(),GetSizePixel())));
154 return aRectangleLogic
.Contains(rPointLogic
);
157 void SwAnnotationWin::SetCursorLogicPosition(const Point
& rPosition
, bool bPoint
, bool bClearMark
)
159 mxSidebarTextControl
->SetCursorLogicPosition(rPosition
, bPoint
, bClearMark
);
162 void SwAnnotationWin::DrawForPage(OutputDevice
* pDev
, const Point
& rPt
)
164 // tdf#143511 unclip SysObj so get_extents_relative_to of children
165 // of the SysObj can provide meaningful results
166 UnclipVisibleSysObj();
168 vcl::PDFExtOutDevData
*const pPDFExtOutDevData(
169 dynamic_cast<vcl::PDFExtOutDevData
*>(pDev
->GetExtOutDevData()));
170 if (pPDFExtOutDevData
&& pPDFExtOutDevData
->GetIsExportTaggedPDF())
172 pPDFExtOutDevData
->WrapBeginStructureElement(vcl::pdf::StructElement::NonStructElement
, OUString());
177 pDev
->SetFillColor(mColorDark
);
178 pDev
->SetLineColor();
180 pDev
->SetTextColor(mColorDark
.IsDark() ? COL_WHITE
: COL_BLACK
);
181 vcl::Font aFont
= maLabelFont
;
182 aFont
.SetFontHeight(aFont
.GetFontHeight() * 20);
183 pDev
->SetFont(aFont
);
185 Size aSz
= PixelToLogic(GetSizePixel());
187 pDev
->DrawRect(tools::Rectangle(rPt
, aSz
));
189 if (mxMetadataAuthor
->get_visible())
191 int x
, y
, width
, height
;
192 mxMetadataAuthor
->get_extents_relative_to(*m_xContainer
, x
, y
, width
, height
);
193 Point
aPos(rPt
+ PixelToLogic(Point(x
, y
)));
194 Size
aSize(PixelToLogic(Size(width
, height
)));
196 pDev
->Push(vcl::PushFlags::CLIPREGION
);
197 pDev
->IntersectClipRegion(tools::Rectangle(aPos
, aSize
));
198 pDev
->DrawText(aPos
, mxMetadataAuthor
->get_label());
202 if (mxMetadataDate
->get_visible())
204 int x
, y
, width
, height
;
205 mxMetadataDate
->get_extents_relative_to(*m_xContainer
, x
, y
, width
, height
);
206 Point
aPos(rPt
+ PixelToLogic(Point(x
, y
)));
207 Size
aSize(PixelToLogic(Size(width
, height
)));
209 pDev
->Push(vcl::PushFlags::CLIPREGION
);
210 pDev
->IntersectClipRegion(tools::Rectangle(aPos
, aSize
));
211 pDev
->DrawText(aPos
, mxMetadataDate
->get_label());
215 if (mxMetadataResolved
->get_visible())
217 int x
, y
, width
, height
;
218 mxMetadataResolved
->get_extents_relative_to(*m_xContainer
, x
, y
, width
, height
);
219 Point
aPos(rPt
+ PixelToLogic(Point(x
, y
)));
220 Size
aSize(PixelToLogic(Size(width
, height
)));
222 pDev
->Push(vcl::PushFlags::CLIPREGION
);
223 pDev
->IntersectClipRegion(tools::Rectangle(aPos
, aSize
));
224 pDev
->DrawText(aPos
, mxMetadataResolved
->get_label());
228 mxSidebarTextControl
->DrawForPage(pDev
, rPt
);
230 const drawinglayer::geometry::ViewInformation2D aNewViewInfos
;
231 std::unique_ptr
<drawinglayer::processor2d::BaseProcessor2D
> pProcessor(
232 drawinglayer::processor2d::createProcessor2DFromOutputDevice(
233 *pDev
, aNewViewInfos
));
236 pProcessor
->process(mpAnchor
->getOverlayObjectPrimitive2DSequence());
237 if (mpTextRangeOverlay
)
238 pProcessor
->process(mpTextRangeOverlay
->getOverlayObjectPrimitive2DSequence());
241 if (mxVScrollbar
->get_vpolicy() != VclPolicyType::NEVER
)
243 // if there is a scrollbar shown, draw "..." to indicate the comment isn't
245 int x
, y
, width
, height
;
246 mxMenuButton
->get_extents_relative_to(*m_xContainer
, x
, y
, width
, height
);
247 Point
aPos(rPt
+ PixelToLogic(Point(x
, y
)));
248 pDev
->DrawText(aPos
, u
"..."_ustr
);
253 if (pPDFExtOutDevData
&& pPDFExtOutDevData
->GetIsExportTaggedPDF())
255 pPDFExtOutDevData
->EndStructureElement();
259 void SwAnnotationWin::SetPosSizePixelRect(tools::Long nX
, tools::Long nY
, tools::Long nWidth
, tools::Long nHeight
,
260 const tools::Long aPageBorder
)
262 mPosSize
= tools::Rectangle(Point(nX
,nY
),Size(nWidth
,nHeight
));
263 mPageBorder
= aPageBorder
;
266 void SwAnnotationWin::SetAnchorRect(const SwRect
& aAnchorRect
)
268 if (!mAnchorRect
.IsEmpty() && mAnchorRect
!= aAnchorRect
)
269 mbAnchorRectChanged
= true;
270 mAnchorRect
= aAnchorRect
;
273 void SwAnnotationWin::SetSize( const Size
& rNewSize
)
275 mPosSize
.SetSize(rNewSize
);
278 void SwAnnotationWin::SetVirtualPosSize( const Point
& aPoint
, const Size
& aSize
)
280 mPosSize
= tools::Rectangle(aPoint
,aSize
);
283 void SwAnnotationWin::TranslateTopPosition(const tools::Long aAmount
)
285 mPosSize
.Move(0,aAmount
);
288 void SwAnnotationWin::ShowAnchorOnly(const Point
&aPoint
)
294 mpAnchor
->SetSixthPosition(basegfx::B2DPoint(aPoint
.X(),aPoint
.Y()));
295 mpAnchor
->SetSeventhPosition(basegfx::B2DPoint(aPoint
.X(),aPoint
.Y()));
296 mpAnchor
->SetAnchorState(AnchorState::All
);
297 mpAnchor
->setVisible(true);
300 mpShadow
->setVisible(false);
303 void SwAnnotationWin::InitControls()
305 // window controls for author and date
306 mxMetadataAuthor
= m_xBuilder
->weld_label(u
"author"_ustr
);
307 mxMetadataAuthor
->set_accessible_name( SwResId( STR_ACCESS_ANNOTATION_AUTHOR_NAME
) );
308 mxMetadataAuthor
->set_direction(AllSettings::GetLayoutRTL());
310 maLabelFont
= Application::GetSettings().GetStyleSettings().GetLabelFont();
311 maLabelFont
.SetFontHeight(8);
313 // we should leave this setting alone, but for this we need a better layout algo
314 // with variable meta size height
315 mxMetadataAuthor
->set_font(maLabelFont
);
317 mxMetadataDate
= m_xBuilder
->weld_label(u
"date"_ustr
);
318 mxMetadataDate
->set_accessible_name( SwResId( STR_ACCESS_ANNOTATION_DATE_NAME
) );
319 mxMetadataDate
->set_direction(AllSettings::GetLayoutRTL());
320 mxMetadataDate
->connect_mouse_move(LINK(this, SwAnnotationWin
, MouseMoveHdl
));
322 // we should leave this setting alone, but for this we need a better layout algo
323 // with variable meta size height
324 mxMetadataDate
->set_font(maLabelFont
);
326 mxMetadataResolved
= m_xBuilder
->weld_label(u
"resolved"_ustr
);
327 mxMetadataResolved
->set_accessible_name( SwResId( STR_ACCESS_ANNOTATION_RESOLVED_NAME
) );
328 mxMetadataResolved
->set_direction(AllSettings::GetLayoutRTL());
329 mxMetadataResolved
->connect_mouse_move(LINK(this, SwAnnotationWin
, MouseMoveHdl
));
331 // we should leave this setting alone, but for this we need a better layout algo
332 // with variable meta size height
333 mxMetadataResolved
->set_font(maLabelFont
);
334 mxMetadataResolved
->set_label(SwResId(STR_ACCESS_ANNOTATION_RESOLVED_NAME
));
336 SwDocShell
* aShell
= mrView
.GetDocShell();
337 mpOutliner
.reset(new Outliner(&aShell
->GetPool(),OutlinerMode::TextObject
));
338 mpOutliner
->SetStyleSheetPool(static_cast<SwDocStyleSheetPool
*>(aShell
->GetStyleSheetPool())->GetEEStyleSheetPool());
339 aShell
->GetDoc()->SetCalcFieldValueHdl( mpOutliner
.get() );
340 mpOutliner
->SetUpdateLayout( true );
342 mpOutlinerView
.reset(new OutlinerView(mpOutliner
.get(), nullptr));
343 mpOutliner
->InsertView(mpOutlinerView
.get());
346 mxVScrollbar
= m_xBuilder
->weld_scrolled_window(u
"scrolledwindow"_ustr
, true);
348 mxMenuButton
= m_xBuilder
->weld_menu_button(u
"menubutton"_ustr
);
349 mxMenuButton
->set_size_request(METABUTTON_WIDTH
, METABUTTON_HEIGHT
);
351 // actual window which holds the user text
352 mxSidebarTextControl
.reset(new SidebarTextControl(*this, mrView
, mrMgr
));
353 mxSidebarTextControlWin
.reset(new weld::CustomWeld(*m_xBuilder
, u
"editview"_ustr
, *mxSidebarTextControl
));
354 mxSidebarTextControl
->SetPointer(PointerStyle::Text
);
358 mpOutlinerView
->SetBackgroundColor(COL_TRANSPARENT
);
359 mpOutlinerView
->SetOutputArea( PixelToLogic( tools::Rectangle(0,0,1,1) ) );
361 mxVScrollbar
->set_direction(false);
362 mxVScrollbar
->connect_vadjustment_changed(LINK(this, SwAnnotationWin
, ScrollHdl
));
363 mxVScrollbar
->connect_mouse_move(LINK(this, SwAnnotationWin
, MouseMoveHdl
));
365 EEControlBits nCntrl
= mpOutliner
->GetControlWord();
366 // TODO: crash when AUTOCOMPLETE enabled
367 nCntrl
|= EEControlBits::MARKFIELDS
| EEControlBits::PASTESPECIAL
| EEControlBits::AUTOCORRECT
| EEControlBits::USECHARATTRIBS
; // | EEControlBits::AUTOCOMPLETE;
368 // Our stylesheet pool follows closely the core paragraph styles.
369 // We don't want the rtf import (during paste) to mess with that.
370 nCntrl
&= ~EEControlBits::RTFSTYLESHEETS
;
372 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
374 const SwViewOption
* pVOpt
= pWrtShell
->GetViewOptions();
375 if (pVOpt
->IsFieldShadings())
376 nCntrl
|= EEControlBits::MARKFIELDS
;
378 nCntrl
&= ~EEControlBits::MARKFIELDS
;
379 if (pVOpt
->IsOnlineSpell())
380 nCntrl
|= EEControlBits::ONLINESPELLING
;
382 nCntrl
&= ~EEControlBits::ONLINESPELLING
;
384 mpOutliner
->SetControlWord(nCntrl
);
386 std::size_t aIndex
= SwModule::get()->InsertRedlineAuthor(GetAuthor());
387 SetColor( SwPostItMgr::GetColorDark(aIndex
),
388 SwPostItMgr::GetColorLight(aIndex
),
389 SwPostItMgr::GetColorAnchor(aIndex
));
393 // expand %1 "Author"
394 OUString aText
= mxMenuButton
->get_item_label(u
"deleteby"_ustr
);
395 SwRewriter aRewriter
;
396 aRewriter
.AddRule(UndoArg1
, GetAuthor());
397 aText
= aRewriter
.Apply(aText
);
398 mxMenuButton
->set_item_label(u
"deleteby"_ustr
, aText
);
400 mxMenuButton
->set_accessible_name(SwResId(STR_ACCESS_ANNOTATION_BUTTON_NAME
));
401 mxMenuButton
->set_accessible_description(SwResId(STR_ACCESS_ANNOTATION_BUTTON_DESC
));
402 mxMenuButton
->set_tooltip_text(SwResId(STR_ACCESS_ANNOTATION_BUTTON_DESC
));
404 mxMenuButton
->connect_toggled(LINK(this, SwAnnotationWin
, ToggleHdl
));
405 mxMenuButton
->connect_selected(LINK(this, SwAnnotationWin
, SelectHdl
));
406 mxMenuButton
->connect_key_press(LINK(this, SwAnnotationWin
, KeyInputHdl
));
407 mxMenuButton
->connect_mouse_move(LINK(this, SwAnnotationWin
, MouseMoveHdl
));
409 GetOutlinerView()->StartSpeller(mxSidebarTextControl
->GetDrawingArea());
411 mpOutliner
->CompleteOnlineSpelling();
413 mxSidebarTextControl
->Show();
414 mxMetadataAuthor
->show();
415 mxMetadataDate
->show();
416 mxMetadataResolved
->set_visible(IsResolved());
417 mxVScrollbar
->set_vpolicy(VclPolicyType::ALWAYS
);
420 void SwAnnotationWin::CheckMetaText()
422 const SvtSysLocale aSysLocale
;
423 const LocaleDataWrapper
& rLocalData
= aSysLocale
.GetLocaleData();
424 OUString sMeta
= GetAuthor();
427 sMeta
= SwResId(STR_NOAUTHOR
);
429 else if (sMeta
.getLength() > 23)
431 sMeta
= OUString::Concat(sMeta
.subView(0, 20)) + "...";
433 if ( mxMetadataAuthor
->get_label() != sMeta
)
435 mxMetadataAuthor
->set_label(sMeta
);
438 Date aDate
= GetDate();
439 if (aDate
.IsValidAndGregorian() )
441 sMeta
= rLocalData
.getDate(aDate
);
445 sMeta
= SwResId(STR_NODATE
);
447 if (GetTime().GetTime()!=0)
449 sMeta
+= " " + rLocalData
.getTime( GetTime(),false );
451 if ( mxMetadataDate
->get_label() != sMeta
)
453 mxMetadataDate
->set_label(sMeta
);
458 void SwAnnotationWin::UpdateColors()
460 std::size_t aIndex
= SwModule::get()->InsertRedlineAuthor(GetAuthor());
461 SetColor( SwPostItMgr::GetColorDark(aIndex
),
462 SwPostItMgr::GetColorLight(aIndex
),
463 SwPostItMgr::GetColorAnchor(aIndex
));
464 // draw comments either black or white depending on the document background
465 // TODO: make editeng depend on the actual note background
466 mpOutlinerView
->SetBackgroundColor(svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
);
469 void SwAnnotationWin::SetMenuButtonColors()
474 SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr();
477 const Fraction
& rFraction
= pWrtShell
->GetOut()->GetMapMode().GetScaleY();
479 ScopedVclPtrInstance
<VirtualDevice
> xVirDev
;
480 Size
aSize(tools::Long(METABUTTON_WIDTH
* rFraction
),
481 tools::Long(METABUTTON_HEIGHT
* rFraction
));
482 tools::Rectangle
aRect(Point(0, 0), aSize
);
483 xVirDev
->SetOutputSizePixel(aSize
);
485 Gradient
aGradient(css::awt::GradientStyle_LINEAR
,
488 xVirDev
->DrawGradient(aRect
, aGradient
);
490 //draw rect around button
491 xVirDev
->SetFillColor();
492 xVirDev
->SetLineColor(mColorDark
.IsDark() ? mColorLight
: mColorDark
);
493 xVirDev
->DrawRect(aRect
);
495 tools::Rectangle
aSymbolRect(aRect
);
496 // 25% distance to the left and right button border
497 const tools::Long nBorderDistanceLeftAndRight
= ((aSymbolRect
.GetWidth() * 250) + 500) / 1000;
498 aSymbolRect
.AdjustLeft(nBorderDistanceLeftAndRight
);
499 aSymbolRect
.AdjustRight( -nBorderDistanceLeftAndRight
);
500 // 30% distance to the top button border
501 const tools::Long nBorderDistanceTop
= ((aSymbolRect
.GetHeight() * 300) + 500) / 1000;
502 aSymbolRect
.AdjustTop(nBorderDistanceTop
);
503 // 25% distance to the bottom button border
504 const tools::Long nBorderDistanceBottom
= ((aSymbolRect
.GetHeight() * 250) + 500) / 1000;
505 aSymbolRect
.AdjustBottom( -nBorderDistanceBottom
);
507 DecorationView
aDecoView(xVirDev
.get());
508 aDecoView
.DrawSymbol(aSymbolRect
, SymbolType::SPIN_DOWN
, mColorDark
.IsDark() ? COL_WHITE
: COL_BLACK
,
509 DrawSymbolFlags::NONE
);
510 mxMenuButton
->set_image(xVirDev
);
511 mxMenuButton
->set_size_request(aSize
.Width() + 4, aSize
.Height() + 4);
514 void SwAnnotationWin::Rescale()
516 // On Android, this method leads to invoke ImpEditEngine::UpdateViews
517 // which hides the text cursor. Moreover it causes sudden document scroll
518 // when modifying a commented text. Not clear the root cause,
519 // anyway skipping this method fixes the problem, and there should be
520 // no side effect, since the client has disabled annotations rendering.
521 if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations())
524 MapMode aMode
= GetParent()->GetMapMode();
525 aMode
.SetOrigin( Point() );
527 mxSidebarTextControl
->SetMapMode( aMode
);
529 SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr();
532 const Fraction
& rFraction
= pWrtShell
->GetOut()->GetMapMode().GetScaleY();
534 vcl::Font aFont
= maLabelFont
;
535 sal_Int32 nHeight
= tools::Long(aFont
.GetFontHeight() * rFraction
);
536 aFont
.SetFontHeight( nHeight
);
538 if (mxMetadataAuthor
)
539 mxMetadataAuthor
->set_font(aFont
);
541 mxMetadataDate
->set_font(aFont
);
542 if (mxMetadataResolved
)
543 mxMetadataResolved
->set_font(aFont
);
544 SetMenuButtonColors();
546 mxVScrollbar
->set_scroll_thickness(GetPrefScrollbarWidth());
549 void SwAnnotationWin::SetPosAndSize()
551 const bool bShowNotes
= mrMgr
.ShowNotes();
554 bool bChange
= false;
556 if (GetSizePixel() != mPosSize
.GetSize())
559 SetSizePixel(mPosSize
.GetSize());
564 if (GetPosPixel().X() != mPosSize
.Left() || (std::abs(GetPosPixel().Y() - mPosSize
.Top()) > 5) )
567 SetPosPixel(mPosSize
.TopLeft());
574 switch ( meSidebarPosition
)
576 case sw::sidebarwindows::SidebarPosition::LEFT
:
578 aLineStart
= EditWin().PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-1) );
579 aLineEnd
= EditWin().PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-1) );
582 case sw::sidebarwindows::SidebarPosition::RIGHT
:
584 aLineStart
= EditWin().PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-1) );
585 aLineEnd
= EditWin().PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-1) );
589 OSL_FAIL( "<SwAnnotationWin::SetPosAndSize()> - unexpected position of sidebar" );
593 // LOK has map mode disabled, and we still want to perform pixel ->
594 // twips conversion for the size of the line above the note.
595 if (comphelper::LibreOfficeKit::isActive() && !EditWin().IsMapModeEnabled())
597 EditWin().EnableMapMode();
598 Size
aSize(aLineEnd
.getX() - aLineStart
.getX(), aLineEnd
.getY() - aLineStart
.getY());
599 aSize
= EditWin().PixelToLogic(aSize
);
600 aLineEnd
= aLineStart
;
601 aLineEnd
.Move(aSize
.getWidth(), aSize
.getHeight());
602 EditWin().EnableMapMode(false);
607 mpAnchor
->SetAllPosition( basegfx::B2DPoint( mAnchorRect
.Left() , mAnchorRect
.Bottom() - 5* 15),
608 basegfx::B2DPoint( mAnchorRect
.Left()-5*15 , mAnchorRect
.Bottom()+5*15),
609 basegfx::B2DPoint( mAnchorRect
.Left()+5*15 , mAnchorRect
.Bottom()+5*15),
610 basegfx::B2DPoint( mAnchorRect
.Left(), mAnchorRect
.Bottom()+2*15),
611 basegfx::B2DPoint( mPageBorder
,mAnchorRect
.Bottom()+2*15),
612 basegfx::B2DPoint( aLineStart
.X(),aLineStart
.Y()),
613 basegfx::B2DPoint( aLineEnd
.X(),aLineEnd
.Y()));
617 mpAnchor
= AnchorOverlayObject::CreateAnchorOverlayObject( mrView
,
625 mpAnchor
->setVisible(true);
626 mpAnchor
->SetAnchorState(AnchorState::Tri
);
627 if (HasChildPathFocus())
629 mpAnchor
->setLineSolid(true);
637 ( mpAnchor
->getBasePosition() != basegfx::B2DPoint( mAnchorRect
.Left() , mAnchorRect
.Bottom()-5*15) ) )
639 mpAnchor
->SetTriPosition( basegfx::B2DPoint( mAnchorRect
.Left() , mAnchorRect
.Bottom() - 5* 15),
640 basegfx::B2DPoint( mAnchorRect
.Left()-5*15 , mAnchorRect
.Bottom()+5*15),
641 basegfx::B2DPoint( mAnchorRect
.Left()+5*15 , mAnchorRect
.Bottom()+5*15),
642 basegfx::B2DPoint( mAnchorRect
.Left(), mAnchorRect
.Bottom()+2*15),
643 basegfx::B2DPoint( mPageBorder
, mAnchorRect
.Bottom()+2*15));
647 if (mpShadow
&& bChange
)
649 Point aStart
= EditWin().PixelToLogic(GetPosPixel()+Point(0,GetSizePixel().Height()));
650 Point aEnd
= EditWin().PixelToLogic(GetPosPixel()+Point(GetSizePixel().Width()-1,GetSizePixel().Height()));
651 mpShadow
->SetPosition(basegfx::B2DPoint(aStart
.X(),aStart
.Y()), basegfx::B2DPoint(aEnd
.X(),aEnd
.Y()));
654 if (IsFollow() && !HasChildPathFocus())
659 mpAnchor
->SetAnchorState(AnchorState::End
);
667 mpAnchor
->SetAnchorState(AnchorState::All
);
669 SwAnnotationWin
* pWin
= GetTopReplyNote();
671 if ( pWin
!= this && pWin
->Anchor() )
673 pWin
->Anchor()->SetAnchorState(AnchorState::End
);
678 // text range overlay
679 maAnnotationTextRanges
.clear();
680 if ( mpSidebarItem
->maLayoutInfo
.mnStartNodeIdx
!= SwNodeOffset(0)
681 && mpSidebarItem
->maLayoutInfo
.mnStartContent
!= -1 )
683 const SwTextAnnotationField
* pTextAnnotationField
=
684 dynamic_cast< const SwTextAnnotationField
* >( mpSidebarItem
->GetFormatField().GetTextField() );
685 SwTextNode
* pTextNode
= pTextAnnotationField
? pTextAnnotationField
->GetpTextNode() : nullptr;
686 SwContentNode
* pContentNd
= nullptr;
689 SwNodes
& rNds
= pTextNode
->GetDoc().GetNodes();
690 pContentNd
= rNds
[mpSidebarItem
->maLayoutInfo
.mnStartNodeIdx
]->GetContentNode();
694 SwPosition
aStartPos( *pContentNd
, mpSidebarItem
->maLayoutInfo
.mnStartContent
);
695 SwShellCursor
* pTmpCursor
= nullptr;
696 const bool bTableCursorNeeded
= pTextNode
->FindTableBoxStartNode() != pContentNd
->FindTableBoxStartNode();
697 if ( bTableCursorNeeded
)
699 SwShellTableCursor
* pTableCursor
= new SwShellTableCursor( mrView
.GetWrtShell(), aStartPos
);
700 pTableCursor
->SetMark();
701 pTableCursor
->GetMark()->Assign( *pTextNode
, pTextAnnotationField
->GetStart()+1 );
702 pTableCursor
->NewTableSelection();
703 pTmpCursor
= pTableCursor
;
707 SwShellCursor
* pCursor
= new SwShellCursor( mrView
.GetWrtShell(), aStartPos
);
709 pCursor
->GetMark()->Assign(*pTextNode
, pTextAnnotationField
->GetStart()+1 );
710 pTmpCursor
= pCursor
;
712 std::unique_ptr
<SwShellCursor
> pTmpCursorForAnnotationTextRange( pTmpCursor
);
714 // For annotation text range rectangles to be calculated correctly,
715 // we need the map mode disabled
716 bool bDisableMapMode
= comphelper::LibreOfficeKit::isActive() && EditWin().IsMapModeEnabled();
718 EditWin().EnableMapMode(false);
720 if (mpSidebarItem
->maLayoutInfo
.mPositionFromCommentAnchor
)
721 pTmpCursorForAnnotationTextRange
->FillRects();
724 EditWin().EnableMapMode();
726 SwRects
* pRects(pTmpCursorForAnnotationTextRange
.get());
727 for(const SwRect
& rNextRect
: *pRects
)
729 const tools::Rectangle
aPntRect(rNextRect
.SVRect());
730 maAnnotationTextRanges
.emplace_back(
731 aPntRect
.Left(), aPntRect
.Top(),
732 aPntRect
.Right() + 1, aPntRect
.Bottom() + 1);
737 if (bShowNotes
&& !maAnnotationTextRanges
.empty())
739 if ( mpTextRangeOverlay
!= nullptr )
741 mpTextRangeOverlay
->setRanges( std::vector(maAnnotationTextRanges
) );
742 if ( mpAnchor
!= nullptr && mpAnchor
->getLineSolid() )
744 mpTextRangeOverlay
->ShowSolidBorder();
748 mpTextRangeOverlay
->HideSolidBorder();
751 else if (!IsFollow())
753 // This window is not a reply, then draw its range overlay.
755 sw::overlay::OverlayRanges::CreateOverlayRange(
758 std::vector(maAnnotationTextRanges
),
759 mpAnchor
&& mpAnchor
->getLineSolid() );
764 mpTextRangeOverlay
.reset();
768 void SwAnnotationWin::DoResize()
770 tools::Long aHeight
= GetSizePixel().Height();
771 tools::ULong aWidth
= GetSizePixel().Width();
773 aHeight
-= GetMetaHeight();
775 mpOutliner
->SetPaperSize( PixelToLogic( Size(aWidth
, aHeight
) ) ) ;
776 tools::Long aTextHeight
= LogicToPixel( mpOutliner
->CalcTextSize()).Height();
778 mxMetadataAuthor
->show();
779 if(IsResolved()) { mxMetadataResolved
->show(); }
780 mxMetadataDate
->show();
782 if (aTextHeight
> aHeight
)
784 const int nThickness
= mxVScrollbar
->get_scroll_thickness();
787 // we need vertical scrollbars and have to reduce the width
788 aWidth
-= nThickness
;
789 mpOutliner
->SetPaperSize(PixelToLogic(Size(aWidth
, aHeight
)));
791 mxVScrollbar
->set_vpolicy(VclPolicyType::ALWAYS
);
795 mxVScrollbar
->set_vpolicy(VclPolicyType::NEVER
);
798 tools::Rectangle aOutputArea
= PixelToLogic(tools::Rectangle(0, 0, aWidth
, aHeight
));
799 if (mxVScrollbar
->get_vpolicy() == VclPolicyType::NEVER
)
801 // if we do not have a scrollbar anymore, we want to see the complete text
802 mpOutlinerView
->SetVisArea(aOutputArea
);
804 mpOutlinerView
->SetOutputArea(aOutputArea
);
805 mpOutlinerView
->ShowCursor(true, true);
807 // Don't leave an empty area at the bottom if we can move the text down.
808 tools::Long nMaxVisAreaTop
= mpOutliner
->GetTextHeight() - aOutputArea
.GetHeight();
809 if (mpOutlinerView
->GetVisArea().Top() > nMaxVisAreaTop
)
811 GetOutlinerView()->Scroll(0, mpOutlinerView
->GetVisArea().Top() - nMaxVisAreaTop
);
814 int nUpper
= mpOutliner
->GetTextHeight();
815 int nCurrentDocPos
= mpOutlinerView
->GetVisArea().Top();
816 int nStepIncrement
= mpOutliner
->GetTextHeight() / 10;
817 int nPageIncrement
= PixelToLogic(Size(0,aHeight
)).Height() * 8 / 10;
818 int nPageSize
= PixelToLogic(Size(0,aHeight
)).Height();
820 /* limit the page size to below nUpper because gtk's gtk_scrolled_window_start_deceleration has
823 lower = gtk_adjustment_get_lower
824 upper = gtk_adjustment_get_upper - gtk_adjustment_get_page_size
826 and requires that upper > lower or the deceleration animation never ends
828 nPageSize
= std::min(nPageSize
, nUpper
);
830 mxVScrollbar
->vadjustment_configure(nCurrentDocPos
, 0, nUpper
,
831 nStepIncrement
, nPageIncrement
, nPageSize
);
834 void SwAnnotationWin::SetSizePixel( const Size
& rNewSize
)
836 if (comphelper::LibreOfficeKit::isActive())
839 InterimItemWindow::SetSizePixel(rNewSize
);
843 Point aStart
= EditWin().PixelToLogic(GetPosPixel()+Point(0,GetSizePixel().Height()));
844 Point aEnd
= EditWin().PixelToLogic(GetPosPixel()+Point(GetSizePixel().Width()-1,GetSizePixel().Height()));
845 mpShadow
->SetPosition(basegfx::B2DPoint(aStart
.X(),aStart
.Y()), basegfx::B2DPoint(aEnd
.X(),aEnd
.Y()));
849 void SwAnnotationWin::SetScrollbar()
851 mxVScrollbar
->vadjustment_set_value(mpOutlinerView
->GetVisArea().Top());
854 void SwAnnotationWin::ResizeIfNecessary(tools::Long aOldHeight
, tools::Long aNewHeight
)
856 if (aOldHeight
!= aNewHeight
)
858 //check for lower border or next note
859 tools::Long aBorder
= mrMgr
.GetNextBorder();
862 if (aNewHeight
> GetMinimumSizeWithoutMeta())
864 tools::Long aNewLowerValue
= GetPosPixel().Y() + aNewHeight
+ GetMetaHeight();
865 if (aNewLowerValue
< aBorder
)
866 SetSizePixel(Size(GetSizePixel().Width(),aNewHeight
+GetMetaHeight()));
868 SetSizePixel(Size(GetSizePixel().Width(),aBorder
- GetPosPixel().Y()));
874 if (GetSizePixel().Height() != GetMinimumSizeWithoutMeta() + GetMetaHeight())
875 SetSizePixel(Size(GetSizePixel().Width(),GetMinimumSizeWithoutMeta() + GetMetaHeight()));
892 void SwAnnotationWin::SetColor(Color aColorDark
,Color aColorLight
, Color aColorAnchor
)
894 mColorDark
= aColorDark
;
895 mColorLight
= aColorLight
;
896 mColorAnchor
= aColorAnchor
;
898 if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
901 m_xContainer
->set_background(mColorDark
);
902 SetMenuButtonColors();
904 Color
aColor(mColorDark
.IsDark() ? COL_WHITE
: COL_BLACK
);
905 mxMetadataAuthor
->set_font_color(aColor
);
907 mxMetadataDate
->set_font_color(aColor
);
909 mxMetadataResolved
->set_font_color(aColor
);
911 mxVScrollbar
->customize_scrollbars(mColorLight
,
916 void SwAnnotationWin::SetSidebarPosition(sw::sidebarwindows::SidebarPosition eSidebarPosition
)
918 meSidebarPosition
= eSidebarPosition
;
921 void SwAnnotationWin::SetReadonly(bool bSet
)
924 GetOutlinerView()->SetReadOnly(bSet
);
927 void SwAnnotationWin::GetFocus()
929 if (mxSidebarTextControl
)
930 mxSidebarTextControl
->GrabFocus();
933 void SwAnnotationWin::LoseFocus()
937 void SwAnnotationWin::ShowNote()
942 if (mpShadow
&& !mpShadow
->isVisible())
943 mpShadow
->setVisible(true);
944 if (mpAnchor
&& !mpAnchor
->isVisible())
945 mpAnchor
->setVisible(true);
946 if (mpTextRangeOverlay
&& !mpTextRangeOverlay
->isVisible())
947 mpTextRangeOverlay
->setVisible(true);
949 collectUIInformation(u
"SHOW"_ustr
,get_id());
952 void SwAnnotationWin::HideNote()
958 if (officecfg::Office::Writer::Notes::ShowAnkor::get())
959 mpAnchor
->SetAnchorState(AnchorState::Tri
);
961 mpAnchor
->setVisible(false);
963 if (mpShadow
&& mpShadow
->isVisible())
964 mpShadow
->setVisible(false);
965 if (mpTextRangeOverlay
&& mpTextRangeOverlay
->isVisible())
966 mpTextRangeOverlay
->setVisible(false);
967 collectUIInformation(u
"HIDE"_ustr
,get_id());
970 void SwAnnotationWin::ActivatePostIt()
972 mrMgr
.AssureStdModeAtShell();
974 mpOutliner
->ClearModifyFlag();
975 mpOutliner
->GetUndoManager().Clear();
978 SetViewState(ViewState::EDIT
);
980 // prevent autoscroll to the old cursor location
981 // when cursor out of visible area
982 GetOutlinerView()->ShowCursor(false);
984 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
985 mpOutlinerView
->GetEditView().SetInsertMode(pWrtShell
->IsInsMode());
987 if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
988 GetOutlinerView()->SetBackgroundColor(mColorDark
);
990 //tdf#119130 only have the active postit as a dialog control in which pressing
991 //ctrl+tab cycles between text and button so we don't waste time searching
992 //thousands of SwAnnotationWins
993 SetStyle(GetStyle() | WB_DIALOGCONTROL
);
995 mrView
.GetDocShell()->Broadcast(SfxHint(SfxHintId::SwNavigatorUpdateTracking
));
998 void SwAnnotationWin::DeactivatePostIt()
1000 //tdf#119130 only have the active postit as a dialog control in which pressing
1001 //ctrl+tab cycles between text and button so we don't waste time searching
1002 //thousands of SwAnnotationWins
1003 SetStyle(GetStyle() & ~WB_DIALOGCONTROL
);
1005 // remove selection, #i87073#
1006 if (GetOutlinerView()->GetEditView().HasSelection())
1008 ESelection aSelection
= GetOutlinerView()->GetEditView().GetSelection();
1009 aSelection
.CollapseToStart();
1010 GetOutlinerView()->GetEditView().SetSelection(aSelection
);
1013 mpOutliner
->CompleteOnlineSpelling();
1015 SetViewState(ViewState::NORMAL
);
1016 // Make sure this view doesn't emit LOK callbacks during the update, as the
1017 // sidebar window's SidebarTextControl doesn't have a valid twip offset
1018 // (map mode origin) during that operation.
1019 bool bTiledPainting
= comphelper::LibreOfficeKit::isTiledPainting();
1020 comphelper::LibreOfficeKit::setTiledPainting(true);
1021 // write the visible text back into the SwField
1023 comphelper::LibreOfficeKit::setTiledPainting(bTiledPainting
);
1025 if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1026 GetOutlinerView()->SetBackgroundColor(COL_TRANSPARENT
);
1028 if (!mnDeleteEventId
&& !IsReadOnlyOrProtected() && !mpOutliner
->GetEditEngine().HasText())
1030 mnDeleteEventId
= Application::PostUserEvent( LINK( this, SwAnnotationWin
, DeleteHdl
), nullptr, true );
1034 void SwAnnotationWin::ToggleInsMode()
1036 if (!mrView
.GetWrtShell().IsRedlineOn())
1039 mpOutlinerView
->GetEditView().SetInsertMode(!mpOutlinerView
->GetEditView().IsInsertMode());
1041 mrView
.GetWrtShell().ToggleInsMode();
1043 SfxBindings
&rBnd
= mrView
.GetViewFrame().GetBindings();
1044 rBnd
.Invalidate(SID_ATTR_INSERT
);
1045 rBnd
.Update(SID_ATTR_INSERT
);
1049 void SwAnnotationWin::ExecuteCommand(sal_uInt16 nSlot
)
1051 mrMgr
.AssureStdModeAtShell();
1058 const bool bReply
= nSlot
== FN_REPLY
;
1059 // if this note is empty, it will be deleted once losing the focus, so no reply, but only a new note
1061 if (!mrMgr
.IsAnswer() && mpOutliner
->GetEditEngine().HasText())
1063 OutlinerParaObject
aPara(GetOutlinerView()->GetEditView().CreateTextObject());
1064 mrMgr
.RegisterAnswer(aPara
);
1066 if (mrMgr
.HasActiveSidebarWin())
1067 mrMgr
.SetActiveSidebarWin(nullptr);
1070 SwDocShell
* pShell
= mrView
.GetDocShell();
1072 pShell
->GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT
, nullptr);
1074 // synchronous dispatch
1075 mrView
.GetViewFrame().GetDispatcher()->Execute(FN_POSTIT
);
1079 // Get newly created SwPostItField and set its paraIdParent
1080 auto pPostItField
= mrMgr
.GetLatestPostItField();
1081 pPostItField
->SetParentId(GetParaId());
1082 pPostItField
->SetParentPostItId(GetPostItField()->GetPostItId());
1083 this->GeneratePostItName();
1084 pPostItField
->SetParentName(GetPostItField()->GetName());
1086 // In this case, force generating the associated window
1087 // synchronously so we can bundle its use of the registered
1088 // "Answer" into the same undo group that the synchronous
1089 // FN_POSTIT was put in
1090 mrMgr
.GetOrCreateAnnotationWindowForLatestPostItField();
1092 SwRewriter aRewriter
;
1093 aRewriter
.AddRule(UndoArg1
, pPostItField
->GetDescription());
1094 pShell
->GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT
, &aRewriter
);
1098 case FN_DELETE_COMMENT
:
1099 //Delete(); // do not kill the parent of our open popup menu
1100 mnDeleteEventId
= Application::PostUserEvent( LINK( this, SwAnnotationWin
, DeleteHdl
), nullptr, true );
1102 case FN_DELETE_COMMENT_THREAD
:
1105 case FN_RESOLVE_NOTE
:
1109 mrMgr
.LayoutPostIts();
1111 case FN_RESOLVE_NOTE_THREAD
:
1112 GetTopReplyNote()->SetResolved(!IsThreadResolved());
1113 mrMgr
.UpdateResolvedStatus(GetTopReplyNote());
1116 mrMgr
.LayoutPostIts();
1118 case FN_FORMAT_ALL_NOTES
:
1119 case FN_DELETE_ALL_NOTES
:
1120 case FN_HIDE_ALL_NOTES
:
1121 // not possible as slot as this would require that "this" is the active postit
1122 mrView
.GetViewFrame().GetBindings().Execute( nSlot
, nullptr, SfxCallMode::ASYNCHRON
);
1124 case FN_DELETE_NOTE_AUTHOR
:
1125 case FN_HIDE_NOTE_AUTHOR
:
1127 // not possible as slot as this would require that "this" is the active postit
1128 SfxStringItem
aItem( nSlot
, GetAuthor() );
1129 const SfxPoolItem
* aItems
[2];
1131 aItems
[1] = nullptr;
1132 mrView
.GetViewFrame().GetBindings().Execute( nSlot
, aItems
, SfxCallMode::ASYNCHRON
);
1135 case FN_PROMOTE_COMMENT
:
1139 mrMgr
.LayoutPostIts();
1142 mrView
.GetViewFrame().GetBindings().Execute( nSlot
);
1147 SwEditWin
& SwAnnotationWin::EditWin()
1149 return mrView
.GetEditWin();
1152 tools::Long
SwAnnotationWin::GetPostItTextHeight()
1154 return mpOutliner
? LogicToPixel(mpOutliner
->CalcTextSize()).Height() : 0;
1157 void SwAnnotationWin::SwitchToPostIt(sal_uInt16 aDirection
)
1159 SwAnnotationWin
* pPostIt
= mrMgr
.GetNextPostIt(aDirection
, this);
1161 pPostIt
->GrabFocus();
1164 IMPL_LINK(SwAnnotationWin
, MouseMoveHdl
, const MouseEvent
&, rMEvt
, bool)
1166 if (rMEvt
.IsEnterWindow())
1171 SetViewState(ViewState::VIEW
);
1175 else if (rMEvt
.IsLeaveWindow())
1177 mbMouseOver
= false;
1180 SetViewState(ViewState::NORMAL
);
1187 bool SwAnnotationWin::SetActiveSidebarWin()
1189 if (mrMgr
.GetActiveSidebarWin() == this)
1191 mrView
.GetWrtShell().LockView( true );
1192 mrMgr
.SetActiveSidebarWin(this);
1193 mrView
.GetWrtShell().LockView( true );
1198 void SwAnnotationWin::UnsetActiveSidebarWin()
1200 if (mrMgr
.GetActiveSidebarWin() != this)
1202 mrView
.GetWrtShell().LockView( true );
1203 mrMgr
.SetActiveSidebarWin(nullptr);
1204 mrView
.GetWrtShell().LockView( false );
1207 void SwAnnotationWin::LockView(bool bLock
)
1209 mrView
.GetWrtShell().LockView( bLock
);
1212 IMPL_LINK(SwAnnotationWin
, ScrollHdl
, weld::ScrolledWindow
&, rScrolledWindow
, void)
1214 tools::Long nDiff
= GetOutlinerView()->GetEditView().GetVisArea().Top() - rScrolledWindow
.vadjustment_get_value();
1215 GetOutlinerView()->Scroll( 0, nDiff
);
1218 IMPL_LINK_NOARG(SwAnnotationWin
, ModifyHdl
, LinkParamNone
*, void)
1220 mrView
.GetDocShell()->SetModified();
1223 IMPL_LINK_NOARG(SwAnnotationWin
, DeleteHdl
, void*, void)
1225 mnDeleteEventId
= nullptr;
1229 void SwAnnotationWin::ResetAttributes()
1231 mpOutlinerView
->RemoveAttribsKeepLanguages(true);
1232 mpOutliner
->RemoveFields();
1235 int SwAnnotationWin::GetPrefScrollbarWidth() const
1237 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
1239 const Fraction
& f(pWrtShell
->GetOut()->GetMapMode().GetScaleY());
1240 return tools::Long(Application::GetSettings().GetStyleSettings().GetScrollBarSize() * f
);
1243 return tools::Long(Application::GetSettings().GetStyleSettings().GetScrollBarSize());
1246 sal_Int32
SwAnnotationWin::GetMetaHeight() const
1248 const int fields
= GetNumFields();
1250 sal_Int32 nRequiredHeight
= 0;
1251 weld::Label
* aLabels
[3] = { mxMetadataAuthor
.get(), mxMetadataDate
.get(), mxMetadataResolved
.get() };
1252 for (int i
= 0; i
< fields
; ++i
)
1253 nRequiredHeight
+= aLabels
[i
]->get_preferred_size().Height();
1255 return nRequiredHeight
;
1258 sal_Int32
SwAnnotationWin::GetNumFields() const
1260 return IsResolved() ? 3 : 2;
1263 sal_Int32
SwAnnotationWin::GetMinimumSizeWithMeta() const
1265 return mrMgr
.GetMinimumSizeWithMeta();
1268 sal_Int32
SwAnnotationWin::GetMinimumSizeWithoutMeta() const
1270 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
1272 const Fraction
& f(pWrtShell
->GetOut()->GetMapMode().GetScaleY());
1273 return tools::Long(POSTIT_MINIMUMSIZE_WITHOUT_META
* f
);
1276 return tools::Long(POSTIT_MINIMUMSIZE_WITHOUT_META
);
1279 void SwAnnotationWin::SetSpellChecking()
1281 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
1283 const SwViewOption
* pVOpt
= pWrtShell
->GetViewOptions();
1284 EEControlBits nCntrl
= mpOutliner
->GetControlWord();
1285 mpOutliner
->SetControlWord(nCntrl
& ~EEControlBits::ONLINESPELLING
);
1286 if (pVOpt
->IsOnlineSpell())
1287 mpOutliner
->SetControlWord(nCntrl
| EEControlBits::ONLINESPELLING
);
1289 mpOutliner
->CompleteOnlineSpelling();
1294 void SwAnnotationWin::SetViewState(ViewState bViewState
)
1298 case ViewState::EDIT
:
1302 mpAnchor
->SetAnchorState(AnchorState::All
);
1303 SwAnnotationWin
* pWin
= GetTopReplyNote();
1305 if ( pWin
!= this && pWin
->Anchor() )
1307 pWin
->Anchor()->SetAnchorState(AnchorState::End
);
1309 mpAnchor
->setLineSolid(true);
1310 if ( mpTextRangeOverlay
!= nullptr )
1312 mpTextRangeOverlay
->ShowSolidBorder();
1316 mpShadow
->SetShadowState(SS_EDIT
);
1319 case ViewState::VIEW
:
1323 mpAnchor
->setLineSolid(true);
1324 if ( mpTextRangeOverlay
!= nullptr )
1326 mpTextRangeOverlay
->ShowSolidBorder();
1330 mpShadow
->SetShadowState(SS_VIEW
);
1333 case ViewState::NORMAL
:
1339 // if there is no visible parent note, we want to see the complete anchor ??
1340 //if (IsAnyStackParentVisible())
1341 mpAnchor
->SetAnchorState(AnchorState::End
);
1342 SwAnnotationWin
* pTopWinSelf
= GetTopReplyNote();
1343 SwAnnotationWin
* pTopWinActive
= mrMgr
.HasActiveSidebarWin()
1344 ? mrMgr
.GetActiveSidebarWin()->GetTopReplyNote()
1347 if ( ( pTopWinSelf
!= this ) &&
1348 ( pTopWinSelf
!= pTopWinActive
) &&
1349 pTopWinSelf
->Anchor() )
1351 if ( pTopWinSelf
!= mrMgr
.GetActiveSidebarWin() )
1353 pTopWinSelf
->Anchor()->setLineSolid(false);
1354 if ( pTopWinSelf
->TextRange() != nullptr )
1356 pTopWinSelf
->TextRange()->HideSolidBorder();
1359 pTopWinSelf
->Anchor()->SetAnchorState(AnchorState::All
);
1362 mpAnchor
->setLineSolid(false);
1363 if ( mpTextRangeOverlay
!= nullptr )
1365 mpTextRangeOverlay
->HideSolidBorder();
1370 mpShadow
->SetShadowState(SS_NORMAL
);
1377 SwAnnotationWin
* SwAnnotationWin::GetTopReplyNote()
1379 for (SwAnnotationWin
* pTopNote
= this;;)
1381 if (!pTopNote
->IsFollow())
1383 SwAnnotationWin
* pPrev
= mrMgr
.GetNextPostIt(KEY_PAGEUP
, pTopNote
);
1390 void SwAnnotationWin::SwitchToFieldPos()
1392 if ( mrMgr
.GetActiveSidebarWin() == this )
1393 mrMgr
.SetActiveSidebarWin(nullptr);
1395 sal_uInt32 aCount
= MoveCaret();
1397 mrView
.GetDocShell()->GetWrtShell()->SwCursorShell::Right(aCount
, SwCursorSkipMode::Chars
);
1398 GrabFocusToDocument();
1399 collectUIInformation(u
"LEAVE"_ustr
,get_id());
1402 void SwAnnotationWin::SetChangeTracking( const SwPostItHelper::SwLayoutStatus aLayoutStatus
,
1403 const Color
& aChangeColor
)
1405 if ( (mLayoutStatus
!= aLayoutStatus
) ||
1406 (mChangeColor
!= aChangeColor
) )
1408 mLayoutStatus
= aLayoutStatus
;
1409 mChangeColor
= aChangeColor
;
1414 bool SwAnnotationWin::HasScrollbar() const
1416 return static_cast<bool>(mxVScrollbar
);
1419 bool SwAnnotationWin::IsScrollbarVisible() const
1421 return HasScrollbar() && mxVScrollbar
->get_vpolicy() == VclPolicyType::ALWAYS
;
1424 void SwAnnotationWin::ChangeSidebarItem( SwAnnotationItem
& rSidebarItem
)
1426 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1427 const bool bAnchorChanged
= mpAnchorFrame
!= rSidebarItem
.maLayoutInfo
.mpAnchorFrame
;
1428 if (bAnchorChanged
&& mpAnchorFrame
)
1430 mrMgr
.DisconnectSidebarWinFromFrame( *mpAnchorFrame
, *this );
1434 mpSidebarItem
= &rSidebarItem
;
1435 mpAnchorFrame
= mpSidebarItem
->maLayoutInfo
.mpAnchorFrame
;
1436 assert(mpAnchorFrame
);
1438 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1439 if (mxSidebarWinAccessible
)
1440 mxSidebarWinAccessible
->ChangeSidebarItem( *mpSidebarItem
);
1442 if ( bAnchorChanged
)
1444 mrMgr
.ConnectSidebarWinToFrame( *(mpSidebarItem
->maLayoutInfo
.mpAnchorFrame
),
1445 mpSidebarItem
->GetFormatField(),
1451 css::uno::Reference
< css::accessibility::XAccessible
> SwAnnotationWin::CreateAccessible()
1453 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1454 if (!mxSidebarWinAccessible
)
1455 mxSidebarWinAccessible
= new SidebarWinAccessible( *this,
1456 mrView
.GetWrtShell(),
1459 return mxSidebarWinAccessible
;
1462 } // eof of namespace sw::sidebarwindows
1464 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */