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>
49 #include <svl/undo.hxx>
50 #include <svl/stritem.hxx>
52 #include <sfx2/viewfrm.hxx>
53 #include <sfx2/bindings.hxx>
54 #include <sfx2/dispatch.hxx>
56 #include <vcl/decoview.hxx>
57 #include <vcl/event.hxx>
58 #include <vcl/gradient.hxx>
59 #include <vcl/pdfextoutdevdata.hxx>
60 #include <vcl/svapp.hxx>
61 #include <vcl/settings.hxx>
62 #include <vcl/ptrstyle.hxx>
63 #include <vcl/uitest/logger.hxx>
64 #include <vcl/uitest/eventdescription.hxx>
71 #include <docufld.hxx>
72 #include <swmodule.hxx>
74 #include <SwRewriter.hxx>
75 #include <txtannotationfld.hxx>
78 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
79 #include <drawinglayer/processor2d/processor2dtools.hxx>
80 #include <osl/diagnose.h>
81 #include <unotools/localedatawrapper.hxx>
82 #include <unotools/syslocale.hxx>
84 #include <comphelper/lok.hxx>
86 using namespace sw::sidebarwindows
;
91 void collectUIInformation( const OUString
& aevent
, const OUString
& aID
)
93 EventDescription aDescription
;
94 aDescription
.aID
= aID
;
95 aDescription
.aParameters
= {{"" , ""}};
96 aDescription
.aAction
= aevent
;
97 aDescription
.aParent
= "MainWindow";
98 aDescription
.aKeyWord
= "SwEditWinUIObject";
99 UITestLogger::getInstance().logEvent(aDescription
);
104 namespace sw::annotation
{
106 #define METABUTTON_WIDTH 16
107 #define METABUTTON_HEIGHT 18
108 #define POSTIT_MINIMUMSIZE_WITHOUT_META 50
110 void SwAnnotationWin::PaintTile(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
112 bool bMenuButtonVisible
= mxMenuButton
->get_visible();
113 // No point in showing this button till click on it are not handled.
114 if (bMenuButtonVisible
)
115 mxMenuButton
->hide();
117 // draw left over space
118 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode())
119 rRenderContext
.SetFillColor(COL_BLACK
);
121 rRenderContext
.SetFillColor(mColorDark
);
122 rRenderContext
.SetLineColor();
123 rRenderContext
.DrawRect(rRect
);
125 m_xContainer
->draw(rRenderContext
, rRect
.TopLeft(), GetSizePixel());
127 const drawinglayer::geometry::ViewInformation2D aViewInformation
;
128 std::unique_ptr
<drawinglayer::processor2d::BaseProcessor2D
> pProcessor(drawinglayer::processor2d::createProcessor2DFromOutputDevice(rRenderContext
, aViewInformation
));
130 // drawinglayer sets the map mode to pixels, not needed here.
131 rRenderContext
.Pop();
132 // Work in document-global twips.
133 rRenderContext
.Pop();
135 pProcessor
->process(mpAnchor
->getOverlayObjectPrimitive2DSequence());
136 if (mpTextRangeOverlay
)
137 pProcessor
->process(mpTextRangeOverlay
->getOverlayObjectPrimitive2DSequence());
139 rRenderContext
.Push(vcl::PushFlags::NONE
);
141 rRenderContext
.Push(vcl::PushFlags::NONE
);
143 if (bMenuButtonVisible
)
144 mxMenuButton
->show();
147 bool SwAnnotationWin::IsHitWindow(const Point
& rPointLogic
)
149 tools::Rectangle
aRectangleLogic(EditWin().PixelToLogic(GetPosPixel()), EditWin().PixelToLogic(GetSizePixel()));
150 return aRectangleLogic
.Contains(rPointLogic
);
153 void SwAnnotationWin::SetCursorLogicPosition(const Point
& rPosition
, bool bPoint
, bool bClearMark
)
155 mxSidebarTextControl
->SetCursorLogicPosition(rPosition
, bPoint
, bClearMark
);
158 void SwAnnotationWin::DrawForPage(OutputDevice
* pDev
, const Point
& rPt
)
160 // tdf#143511 unclip SysObj so get_extents_relative_to of children
161 // of the SysObj can provide meaningful results
162 UnclipVisibleSysObj();
164 vcl::PDFExtOutDevData
*const pPDFExtOutDevData(
165 dynamic_cast<vcl::PDFExtOutDevData
*>(pDev
->GetExtOutDevData()));
166 if (pPDFExtOutDevData
&& pPDFExtOutDevData
->GetIsExportTaggedPDF())
168 pPDFExtOutDevData
->WrapBeginStructureElement(vcl::PDFWriter::NonStructElement
, OUString());
173 pDev
->SetFillColor(mColorDark
);
174 pDev
->SetLineColor();
176 pDev
->SetTextColor(mColorAnchor
);
177 vcl::Font aFont
= maLabelFont
;
178 aFont
.SetFontHeight(aFont
.GetFontHeight() * 20);
179 pDev
->SetFont(aFont
);
181 Size aSz
= PixelToLogic(GetSizePixel());
183 pDev
->DrawRect(tools::Rectangle(rPt
, aSz
));
185 if (mxMetadataAuthor
->get_visible())
187 int x
, y
, width
, height
;
188 mxMetadataAuthor
->get_extents_relative_to(*m_xContainer
, x
, y
, width
, height
);
189 Point
aPos(rPt
+ PixelToLogic(Point(x
, y
)));
190 Size
aSize(PixelToLogic(Size(width
, height
)));
192 pDev
->Push(vcl::PushFlags::CLIPREGION
);
193 pDev
->IntersectClipRegion(tools::Rectangle(aPos
, aSize
));
194 pDev
->DrawText(aPos
, mxMetadataAuthor
->get_label());
198 if (mxMetadataDate
->get_visible())
200 int x
, y
, width
, height
;
201 mxMetadataDate
->get_extents_relative_to(*m_xContainer
, x
, y
, width
, height
);
202 Point
aPos(rPt
+ PixelToLogic(Point(x
, y
)));
203 Size
aSize(PixelToLogic(Size(width
, height
)));
205 pDev
->Push(vcl::PushFlags::CLIPREGION
);
206 pDev
->IntersectClipRegion(tools::Rectangle(aPos
, aSize
));
207 pDev
->DrawText(aPos
, mxMetadataDate
->get_label());
211 if (mxMetadataResolved
->get_visible())
213 int x
, y
, width
, height
;
214 mxMetadataResolved
->get_extents_relative_to(*m_xContainer
, x
, y
, width
, height
);
215 Point
aPos(rPt
+ PixelToLogic(Point(x
, y
)));
216 Size
aSize(PixelToLogic(Size(width
, height
)));
218 pDev
->Push(vcl::PushFlags::CLIPREGION
);
219 pDev
->IntersectClipRegion(tools::Rectangle(aPos
, aSize
));
220 pDev
->DrawText(aPos
, mxMetadataResolved
->get_label());
224 mxSidebarTextControl
->DrawForPage(pDev
, rPt
);
226 const drawinglayer::geometry::ViewInformation2D aNewViewInfos
;
227 std::unique_ptr
<drawinglayer::processor2d::BaseProcessor2D
> pProcessor(
228 drawinglayer::processor2d::createProcessor2DFromOutputDevice(
229 *pDev
, aNewViewInfos
));
232 pProcessor
->process(mpAnchor
->getOverlayObjectPrimitive2DSequence());
233 if (mpTextRangeOverlay
)
234 pProcessor
->process(mpTextRangeOverlay
->getOverlayObjectPrimitive2DSequence());
237 if (mxVScrollbar
->get_vpolicy() != VclPolicyType::NEVER
)
239 // if there is a scrollbar shown, draw "..." to indicate the comment isn't
241 int x
, y
, width
, height
;
242 mxMenuButton
->get_extents_relative_to(*m_xContainer
, x
, y
, width
, height
);
243 Point
aPos(rPt
+ PixelToLogic(Point(x
, y
)));
244 pDev
->DrawText(aPos
, "...");
249 if (pPDFExtOutDevData
&& pPDFExtOutDevData
->GetIsExportTaggedPDF())
251 pPDFExtOutDevData
->EndStructureElement();
255 void SwAnnotationWin::SetPosSizePixelRect(tools::Long nX
, tools::Long nY
, tools::Long nWidth
, tools::Long nHeight
,
256 const SwRect
& aAnchorRect
, const tools::Long aPageBorder
)
258 mPosSize
= tools::Rectangle(Point(nX
,nY
),Size(nWidth
,nHeight
));
259 if (!mAnchorRect
.IsEmpty() && mAnchorRect
!= aAnchorRect
)
260 mbAnchorRectChanged
= true;
261 mAnchorRect
= aAnchorRect
;
262 mPageBorder
= aPageBorder
;
265 void SwAnnotationWin::SetSize( const Size
& rNewSize
)
267 mPosSize
.SetSize(rNewSize
);
270 void SwAnnotationWin::SetVirtualPosSize( const Point
& aPoint
, const Size
& aSize
)
272 mPosSize
= tools::Rectangle(aPoint
,aSize
);
275 void SwAnnotationWin::TranslateTopPosition(const tools::Long aAmount
)
277 mPosSize
.Move(0,aAmount
);
280 void SwAnnotationWin::ShowAnchorOnly(const Point
&aPoint
)
286 mpAnchor
->SetSixthPosition(basegfx::B2DPoint(aPoint
.X(),aPoint
.Y()));
287 mpAnchor
->SetSeventhPosition(basegfx::B2DPoint(aPoint
.X(),aPoint
.Y()));
288 mpAnchor
->SetAnchorState(AnchorState::All
);
289 mpAnchor
->setVisible(true);
292 mpShadow
->setVisible(false);
295 SfxItemSet
SwAnnotationWin::DefaultItem()
297 SfxItemSet
aItem( mrView
.GetDocShell()->GetPool() );
298 aItem
.Put(SvxFontHeightItem(200,100,EE_CHAR_FONTHEIGHT
));
302 void SwAnnotationWin::InitControls()
304 // window controls for author and date
305 mxMetadataAuthor
= m_xBuilder
->weld_label("author");
306 mxMetadataAuthor
->set_accessible_name( SwResId( STR_ACCESS_ANNOTATION_AUTHOR_NAME
) );
307 mxMetadataAuthor
->set_direction(AllSettings::GetLayoutRTL());
309 maLabelFont
= Application::GetSettings().GetStyleSettings().GetLabelFont();
310 maLabelFont
.SetFontHeight(8);
312 // we should leave this setting alone, but for this we need a better layout algo
313 // with variable meta size height
314 mxMetadataAuthor
->set_font(maLabelFont
);
316 mxMetadataDate
= m_xBuilder
->weld_label("date");
317 mxMetadataDate
->set_accessible_name( SwResId( STR_ACCESS_ANNOTATION_DATE_NAME
) );
318 mxMetadataDate
->set_direction(AllSettings::GetLayoutRTL());
319 mxMetadataDate
->connect_mouse_move(LINK(this, SwAnnotationWin
, MouseMoveHdl
));
321 // we should leave this setting alone, but for this we need a better layout algo
322 // with variable meta size height
323 mxMetadataDate
->set_font(maLabelFont
);
325 mxMetadataResolved
= m_xBuilder
->weld_label("resolved");
326 mxMetadataResolved
->set_accessible_name( SwResId( STR_ACCESS_ANNOTATION_RESOLVED_NAME
) );
327 mxMetadataResolved
->set_direction(AllSettings::GetLayoutRTL());
328 mxMetadataResolved
->connect_mouse_move(LINK(this, SwAnnotationWin
, MouseMoveHdl
));
330 // we should leave this setting alone, but for this we need a better layout algo
331 // with variable meta size height
332 mxMetadataResolved
->set_font(maLabelFont
);
333 mxMetadataResolved
->set_label(SwResId(STR_ACCESS_ANNOTATION_RESOLVED_NAME
));
335 SwDocShell
* aShell
= mrView
.GetDocShell();
336 mpOutliner
.reset(new Outliner(&aShell
->GetPool(),OutlinerMode::TextObject
));
337 aShell
->GetDoc()->SetCalcFieldValueHdl( mpOutliner
.get() );
338 mpOutliner
->SetUpdateLayout( true );
340 mpOutlinerView
.reset(new OutlinerView(mpOutliner
.get(), nullptr));
341 mpOutliner
->InsertView(mpOutlinerView
.get());
344 mxVScrollbar
= m_xBuilder
->weld_scrolled_window("scrolledwindow", true);
346 mxMenuButton
= m_xBuilder
->weld_menu_button("menubutton");
347 mxMenuButton
->set_size_request(METABUTTON_WIDTH
, METABUTTON_HEIGHT
);
349 // actual window which holds the user text
350 mxSidebarTextControl
.reset(new SidebarTextControl(*this, mrView
, mrMgr
));
351 mxSidebarTextControlWin
.reset(new weld::CustomWeld(*m_xBuilder
, "editview", *mxSidebarTextControl
));
352 mxSidebarTextControl
->SetPointer(PointerStyle::Text
);
356 mpOutlinerView
->SetBackgroundColor(COL_TRANSPARENT
);
357 mpOutlinerView
->SetOutputArea( PixelToLogic( tools::Rectangle(0,0,1,1) ) );
359 mpOutlinerView
->SetAttribs(DefaultItem());
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;
369 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
371 const SwViewOption
* pVOpt
= pWrtShell
->GetViewOptions();
372 if (pVOpt
->IsFieldShadings())
373 nCntrl
|= EEControlBits::MARKFIELDS
;
375 nCntrl
&= ~EEControlBits::MARKFIELDS
;
376 if (pVOpt
->IsOnlineSpell())
377 nCntrl
|= EEControlBits::ONLINESPELLING
;
379 nCntrl
&= ~EEControlBits::ONLINESPELLING
;
381 mpOutliner
->SetControlWord(nCntrl
);
383 std::size_t aIndex
= SW_MOD()->InsertRedlineAuthor(GetAuthor());
384 SetColor( SwPostItMgr::GetColorDark(aIndex
),
385 SwPostItMgr::GetColorLight(aIndex
),
386 SwPostItMgr::GetColorAnchor(aIndex
));
390 // expand %1 "Author"
391 OUString aText
= mxMenuButton
->get_item_label("deleteby");
392 SwRewriter aRewriter
;
393 aRewriter
.AddRule(UndoArg1
, GetAuthor());
394 aText
= aRewriter
.Apply(aText
);
395 mxMenuButton
->set_item_label("deleteby", aText
);
397 mxMenuButton
->set_accessible_name(SwResId(STR_ACCESS_ANNOTATION_BUTTON_NAME
));
398 mxMenuButton
->set_accessible_description(SwResId(STR_ACCESS_ANNOTATION_BUTTON_DESC
));
399 mxMenuButton
->set_tooltip_text(SwResId(STR_ACCESS_ANNOTATION_BUTTON_DESC
));
401 mxMenuButton
->connect_toggled(LINK(this, SwAnnotationWin
, ToggleHdl
));
402 mxMenuButton
->connect_selected(LINK(this, SwAnnotationWin
, SelectHdl
));
403 mxMenuButton
->connect_key_press(LINK(this, SwAnnotationWin
, KeyInputHdl
));
404 mxMenuButton
->connect_mouse_move(LINK(this, SwAnnotationWin
, MouseMoveHdl
));
406 SetLanguage(GetLanguage());
407 GetOutlinerView()->StartSpeller(mxSidebarTextControl
->GetDrawingArea());
409 mpOutliner
->CompleteOnlineSpelling();
411 mxSidebarTextControl
->Show();
412 mxMetadataAuthor
->show();
413 mxMetadataDate
->show();
414 mxMetadataResolved
->set_visible(IsResolved());
415 mxVScrollbar
->set_vpolicy(VclPolicyType::ALWAYS
);
418 void SwAnnotationWin::CheckMetaText()
420 const SvtSysLocale aSysLocale
;
421 const LocaleDataWrapper
& rLocalData
= aSysLocale
.GetLocaleData();
422 OUString sMeta
= GetAuthor();
425 sMeta
= SwResId(STR_NOAUTHOR
);
427 else if (sMeta
.getLength() > 23)
429 sMeta
= OUString::Concat(sMeta
.subView(0, 20)) + "...";
431 if ( mxMetadataAuthor
->get_label() != sMeta
)
433 mxMetadataAuthor
->set_label(sMeta
);
436 Date aDate
= GetDate();
437 if (aDate
.IsValidAndGregorian() )
439 sMeta
= rLocalData
.getDate(aDate
);
443 sMeta
= SwResId(STR_NODATE
);
445 if (GetTime().GetTime()!=0)
447 sMeta
+= " " + rLocalData
.getTime( GetTime(),false );
449 if ( mxMetadataDate
->get_label() != sMeta
)
451 mxMetadataDate
->set_label(sMeta
);
454 std::size_t aIndex
= SW_MOD()->InsertRedlineAuthor(GetAuthor());
455 SetColor( SwPostItMgr::GetColorDark(aIndex
),
456 SwPostItMgr::GetColorLight(aIndex
),
457 SwPostItMgr::GetColorAnchor(aIndex
));
460 static Color
ColorFromAlphaColor(const sal_uInt8 aTransparency
, const Color
& aFront
, const Color
& aBack
)
462 return Color(sal_uInt8(aFront
.GetRed() * aTransparency
/ 255.0 + aBack
.GetRed() * (1 - aTransparency
/ 255.0)),
463 sal_uInt8(aFront
.GetGreen() * aTransparency
/ 255.0 + aBack
.GetGreen() * (1 - aTransparency
/ 255.0)),
464 sal_uInt8(aFront
.GetBlue() * aTransparency
/ 255.0 + aBack
.GetBlue() * (1 - aTransparency
/ 255.0)));
467 void SwAnnotationWin::SetMenuButtonColors()
472 mxMenuButton
->set_background(mColorDark
);
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
,
486 ColorFromAlphaColor(15, mColorAnchor
, mColorDark
),
487 ColorFromAlphaColor(80, mColorAnchor
, mColorDark
));
488 xVirDev
->DrawGradient(aRect
, aGradient
);
490 //draw rect around button
491 xVirDev
->SetFillColor();
492 xVirDev
->SetLineColor(ColorFromAlphaColor(90, mColorAnchor
, 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 // 40% distance to the top button border
501 const tools::Long nBorderDistanceTop
= ((aSymbolRect
.GetHeight() * 400) + 500) / 1000;
502 aSymbolRect
.AdjustTop(nBorderDistanceTop
);
503 // 15% distance to the bottom button border
504 const tools::Long nBorderDistanceBottom
= ((aSymbolRect
.GetHeight() * 150) + 500) / 1000;
505 aSymbolRect
.AdjustBottom( -nBorderDistanceBottom
);
506 DecorationView
aDecoView(xVirDev
.get());
507 aDecoView
.DrawSymbol(aSymbolRect
, SymbolType::SPIN_DOWN
, GetTextColor(),
508 DrawSymbolFlags::NONE
);
509 mxMenuButton
->set_image(xVirDev
);
510 mxMenuButton
->set_size_request(aSize
.Width() + 4, aSize
.Height() + 4);
513 void SwAnnotationWin::Rescale()
515 // On Android, this method leads to invoke ImpEditEngine::UpdateViews
516 // which hides the text cursor. Moreover it causes sudden document scroll
517 // when modifying a commented text. Not clear the root cause,
518 // anyway skipping this method fixes the problem, and there should be
519 // no side effect, since the client has disabled annotations rendering.
520 if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations())
523 MapMode aMode
= GetParent()->GetMapMode();
524 aMode
.SetOrigin( Point() );
526 mxSidebarTextControl
->SetMapMode( aMode
);
528 SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr();
531 const Fraction
& rFraction
= pWrtShell
->GetOut()->GetMapMode().GetScaleY();
533 vcl::Font aFont
= maLabelFont
;
534 sal_Int32 nHeight
= tools::Long(aFont
.GetFontHeight() * rFraction
);
535 aFont
.SetFontHeight( nHeight
);
537 if (mxMetadataAuthor
)
538 mxMetadataAuthor
->set_font(aFont
);
540 mxMetadataDate
->set_font(aFont
);
541 if (mxMetadataResolved
)
542 mxMetadataResolved
->set_font(aFont
);
543 SetMenuButtonColors();
545 mxVScrollbar
->set_scroll_thickness(GetPrefScrollbarWidth());
548 void SwAnnotationWin::SetPosAndSize()
550 bool bChange
= false;
552 if (GetSizePixel() != mPosSize
.GetSize())
555 SetSizePixel(mPosSize
.GetSize());
560 if (GetPosPixel().X() != mPosSize
.Left() || (std::abs(GetPosPixel().Y() - mPosSize
.Top()) > 5) )
563 SetPosPixel(mPosSize
.TopLeft());
567 switch ( meSidebarPosition
)
569 case sw::sidebarwindows::SidebarPosition::LEFT
:
571 aLineStart
= EditWin().PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-1) );
572 aLineEnd
= EditWin().PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-1) );
575 case sw::sidebarwindows::SidebarPosition::RIGHT
:
577 aLineStart
= EditWin().PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-1) );
578 aLineEnd
= EditWin().PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-1) );
582 OSL_FAIL( "<SwAnnotationWin::SetPosAndSize()> - unexpected position of sidebar" );
586 // LOK has map mode disabled, and we still want to perform pixel ->
587 // twips conversion for the size of the line above the note.
588 if (comphelper::LibreOfficeKit::isActive() && !EditWin().IsMapModeEnabled())
590 EditWin().EnableMapMode();
591 Size
aSize(aLineEnd
.getX() - aLineStart
.getX(), aLineEnd
.getY() - aLineStart
.getY());
592 aSize
= EditWin().PixelToLogic(aSize
);
593 aLineEnd
= aLineStart
;
594 aLineEnd
.Move(aSize
.getWidth(), aSize
.getHeight());
595 EditWin().EnableMapMode(false);
600 mpAnchor
->SetAllPosition( basegfx::B2DPoint( mAnchorRect
.Left() , mAnchorRect
.Bottom() - 5* 15),
601 basegfx::B2DPoint( mAnchorRect
.Left()-5*15 , mAnchorRect
.Bottom()+5*15),
602 basegfx::B2DPoint( mAnchorRect
.Left()+5*15 , mAnchorRect
.Bottom()+5*15),
603 basegfx::B2DPoint( mAnchorRect
.Left(), mAnchorRect
.Bottom()+2*15),
604 basegfx::B2DPoint( mPageBorder
,mAnchorRect
.Bottom()+2*15),
605 basegfx::B2DPoint( aLineStart
.X(),aLineStart
.Y()),
606 basegfx::B2DPoint( aLineEnd
.X(),aLineEnd
.Y()));
610 mpAnchor
= AnchorOverlayObject::CreateAnchorOverlayObject( mrView
,
618 mpAnchor
->setVisible(true);
619 mpAnchor
->SetAnchorState(AnchorState::Tri
);
620 if (HasChildPathFocus())
622 mpAnchor
->setLineSolid(true);
630 ( mpAnchor
->getBasePosition() != basegfx::B2DPoint( mAnchorRect
.Left() , mAnchorRect
.Bottom()-5*15) ) )
632 mpAnchor
->SetTriPosition( basegfx::B2DPoint( mAnchorRect
.Left() , mAnchorRect
.Bottom() - 5* 15),
633 basegfx::B2DPoint( mAnchorRect
.Left()-5*15 , mAnchorRect
.Bottom()+5*15),
634 basegfx::B2DPoint( mAnchorRect
.Left()+5*15 , mAnchorRect
.Bottom()+5*15),
635 basegfx::B2DPoint( mAnchorRect
.Left(), mAnchorRect
.Bottom()+2*15),
636 basegfx::B2DPoint( mPageBorder
, mAnchorRect
.Bottom()+2*15));
640 if (mpShadow
&& bChange
)
642 Point aStart
= EditWin().PixelToLogic(GetPosPixel()+Point(0,GetSizePixel().Height()));
643 Point aEnd
= EditWin().PixelToLogic(GetPosPixel()+Point(GetSizePixel().Width()-1,GetSizePixel().Height()));
644 mpShadow
->SetPosition(basegfx::B2DPoint(aStart
.X(),aStart
.Y()), basegfx::B2DPoint(aEnd
.X(),aEnd
.Y()));
647 if (mrMgr
.ShowNotes())
649 if (IsFollow() && !HasChildPathFocus())
654 mpAnchor
->SetAnchorState(AnchorState::End
);
662 mpAnchor
->SetAnchorState(AnchorState::All
);
664 SwAnnotationWin
* pWin
= GetTopReplyNote();
666 if ( pWin
!= this && pWin
->Anchor() )
668 pWin
->Anchor()->SetAnchorState(AnchorState::End
);
674 // text range overlay
675 maAnnotationTextRanges
.clear();
676 if ( mrSidebarItem
.maLayoutInfo
.mnStartNodeIdx
!= SwNodeOffset(0)
677 && mrSidebarItem
.maLayoutInfo
.mnStartContent
!= -1 )
679 const SwTextAnnotationField
* pTextAnnotationField
=
680 dynamic_cast< const SwTextAnnotationField
* >( mrSidebarItem
.GetFormatField().GetTextField() );
681 SwTextNode
* pTextNode
= pTextAnnotationField
? pTextAnnotationField
->GetpTextNode() : nullptr;
682 SwContentNode
* pContentNd
= nullptr;
685 SwNodes
& rNds
= pTextNode
->GetDoc().GetNodes();
686 pContentNd
= rNds
[mrSidebarItem
.maLayoutInfo
.mnStartNodeIdx
]->GetContentNode();
690 SwPosition
aStartPos( *pContentNd
, mrSidebarItem
.maLayoutInfo
.mnStartContent
);
691 SwShellCursor
* pTmpCursor
= nullptr;
692 const bool bTableCursorNeeded
= pTextNode
->FindTableBoxStartNode() != pContentNd
->FindTableBoxStartNode();
693 if ( bTableCursorNeeded
)
695 SwShellTableCursor
* pTableCursor
= new SwShellTableCursor( mrView
.GetWrtShell(), aStartPos
);
696 pTableCursor
->SetMark();
697 pTableCursor
->GetMark()->Assign( *pTextNode
, pTextAnnotationField
->GetStart()+1 );
698 pTableCursor
->NewTableSelection();
699 pTmpCursor
= pTableCursor
;
703 SwShellCursor
* pCursor
= new SwShellCursor( mrView
.GetWrtShell(), aStartPos
);
705 pCursor
->GetMark()->Assign(*pTextNode
, pTextAnnotationField
->GetStart()+1 );
706 pTmpCursor
= pCursor
;
708 std::unique_ptr
<SwShellCursor
> pTmpCursorForAnnotationTextRange( pTmpCursor
);
710 // For annotation text range rectangles to be calculated correctly,
711 // we need the map mode disabled
712 bool bDisableMapMode
= comphelper::LibreOfficeKit::isActive() && EditWin().IsMapModeEnabled();
714 EditWin().EnableMapMode(false);
716 if (mrSidebarItem
.maLayoutInfo
.mPositionFromCommentAnchor
)
717 pTmpCursorForAnnotationTextRange
->FillRects();
720 EditWin().EnableMapMode();
722 SwRects
* pRects(pTmpCursorForAnnotationTextRange
.get());
723 for(const SwRect
& rNextRect
: *pRects
)
725 const tools::Rectangle
aPntRect(rNextRect
.SVRect());
726 maAnnotationTextRanges
.emplace_back(
727 aPntRect
.Left(), aPntRect
.Top(),
728 aPntRect
.Right() + 1, aPntRect
.Bottom() + 1);
733 if (mrMgr
.ShowNotes() && !maAnnotationTextRanges
.empty())
735 if ( mpTextRangeOverlay
!= nullptr )
737 mpTextRangeOverlay
->setRanges( std::vector(maAnnotationTextRanges
) );
738 if ( mpAnchor
!= nullptr && mpAnchor
->getLineSolid() )
740 mpTextRangeOverlay
->ShowSolidBorder();
744 mpTextRangeOverlay
->HideSolidBorder();
747 else if (!IsFollow())
749 // This window is not a reply, then draw its range overlay.
751 sw::overlay::OverlayRanges::CreateOverlayRange(
754 std::vector(maAnnotationTextRanges
),
755 mpAnchor
&& mpAnchor
->getLineSolid() );
760 mpTextRangeOverlay
.reset();
764 void SwAnnotationWin::DoResize()
766 tools::Long aHeight
= GetSizePixel().Height();
767 tools::ULong aWidth
= GetSizePixel().Width();
769 aHeight
-= GetMetaHeight();
771 mpOutliner
->SetPaperSize( PixelToLogic( Size(aWidth
, aHeight
) ) ) ;
772 tools::Long aTextHeight
= LogicToPixel( mpOutliner
->CalcTextSize()).Height();
774 mxMetadataAuthor
->show();
775 if(IsResolved()) { mxMetadataResolved
->show(); }
776 mxMetadataDate
->show();
778 if (aTextHeight
> aHeight
)
780 const int nThickness
= mxVScrollbar
->get_scroll_thickness();
783 // we need vertical scrollbars and have to reduce the width
784 aWidth
-= nThickness
;
785 mpOutliner
->SetPaperSize(PixelToLogic(Size(aWidth
, aHeight
)));
787 mxVScrollbar
->set_vpolicy(VclPolicyType::ALWAYS
);
791 mxVScrollbar
->set_vpolicy(VclPolicyType::NEVER
);
794 tools::Rectangle aOutputArea
= PixelToLogic(tools::Rectangle(0, 0, aWidth
, aHeight
));
795 if (mxVScrollbar
->get_vpolicy() == VclPolicyType::NEVER
)
797 // if we do not have a scrollbar anymore, we want to see the complete text
798 mpOutlinerView
->SetVisArea(aOutputArea
);
800 mpOutlinerView
->SetOutputArea(aOutputArea
);
801 mpOutlinerView
->ShowCursor(true, true);
803 // Don't leave an empty area at the bottom if we can move the text down.
804 tools::Long nMaxVisAreaTop
= mpOutliner
->GetTextHeight() - aOutputArea
.GetHeight();
805 if (mpOutlinerView
->GetVisArea().Top() > nMaxVisAreaTop
)
807 GetOutlinerView()->Scroll(0, mpOutlinerView
->GetVisArea().Top() - nMaxVisAreaTop
);
810 int nUpper
= mpOutliner
->GetTextHeight();
811 int nCurrentDocPos
= mpOutlinerView
->GetVisArea().Top();
812 int nStepIncrement
= mpOutliner
->GetTextHeight() / 10;
813 int nPageIncrement
= PixelToLogic(Size(0,aHeight
)).Height() * 8 / 10;
814 int nPageSize
= PixelToLogic(Size(0,aHeight
)).Height();
816 /* limit the page size to below nUpper because gtk's gtk_scrolled_window_start_deceleration has
819 lower = gtk_adjustment_get_lower
820 upper = gtk_adjustment_get_upper - gtk_adjustment_get_page_size
822 and requires that upper > lower or the deceleration animation never ends
824 nPageSize
= std::min(nPageSize
, nUpper
);
826 mxVScrollbar
->vadjustment_configure(nCurrentDocPos
, 0, nUpper
,
827 nStepIncrement
, nPageIncrement
, nPageSize
);
830 void SwAnnotationWin::SetSizePixel( const Size
& rNewSize
)
832 if (comphelper::LibreOfficeKit::isActive())
835 InterimItemWindow::SetSizePixel(rNewSize
);
839 Point aStart
= EditWin().PixelToLogic(GetPosPixel()+Point(0,GetSizePixel().Height()));
840 Point aEnd
= EditWin().PixelToLogic(GetPosPixel()+Point(GetSizePixel().Width()-1,GetSizePixel().Height()));
841 mpShadow
->SetPosition(basegfx::B2DPoint(aStart
.X(),aStart
.Y()), basegfx::B2DPoint(aEnd
.X(),aEnd
.Y()));
845 void SwAnnotationWin::SetScrollbar()
847 mxVScrollbar
->vadjustment_set_value(mpOutlinerView
->GetVisArea().Top());
850 void SwAnnotationWin::ResizeIfNecessary(tools::Long aOldHeight
, tools::Long aNewHeight
)
852 if (aOldHeight
!= aNewHeight
)
854 //check for lower border or next note
855 tools::Long aBorder
= mrMgr
.GetNextBorder();
858 if (aNewHeight
> GetMinimumSizeWithoutMeta())
860 tools::Long aNewLowerValue
= GetPosPixel().Y() + aNewHeight
+ GetMetaHeight();
861 if (aNewLowerValue
< aBorder
)
862 SetSizePixel(Size(GetSizePixel().Width(),aNewHeight
+GetMetaHeight()));
864 SetSizePixel(Size(GetSizePixel().Width(),aBorder
- GetPosPixel().Y()));
870 if (GetSizePixel().Height() != GetMinimumSizeWithoutMeta() + GetMetaHeight())
871 SetSizePixel(Size(GetSizePixel().Width(),GetMinimumSizeWithoutMeta() + GetMetaHeight()));
888 void SwAnnotationWin::SetColor(Color aColorDark
,Color aColorLight
, Color aColorAnchor
)
890 mColorDark
= aColorDark
;
891 mColorLight
= aColorLight
;
892 mColorAnchor
= aColorAnchor
;
894 if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
897 m_xContainer
->set_background(mColorDark
);
898 SetMenuButtonColors();
900 mxMetadataAuthor
->set_font_color(aColorAnchor
);
902 mxMetadataDate
->set_font_color(aColorAnchor
);
904 mxMetadataResolved
->set_font_color(aColorAnchor
);
906 mxVScrollbar
->customize_scrollbars(mColorLight
,
911 void SwAnnotationWin::SetSidebarPosition(sw::sidebarwindows::SidebarPosition eSidebarPosition
)
913 meSidebarPosition
= eSidebarPosition
;
916 void SwAnnotationWin::SetReadonly(bool bSet
)
919 GetOutlinerView()->SetReadOnly(bSet
);
922 void SwAnnotationWin::SetLanguage(const SvxLanguageItem
& rNewItem
)
924 IDocumentUndoRedo
& rUndoRedo(
925 mrView
.GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
926 const bool bDocUndoEnabled
= rUndoRedo
.DoesUndo();
927 const bool bOutlinerUndoEnabled
= mpOutliner
->IsUndoEnabled();
928 const bool bOutlinerModified
= mpOutliner
->IsModified();
929 const bool bDisableAndRestoreUndoMode
= !bDocUndoEnabled
&& bOutlinerUndoEnabled
;
931 if (bDisableAndRestoreUndoMode
)
933 // doc undo is disabled, but outliner was enabled, turn outliner undo off
934 // for the duration of this function
935 mpOutliner
->EnableUndo(false);
938 Link
<LinkParamNone
*,void> aLink
= mpOutliner
->GetModifyHdl();
939 mpOutliner
->SetModifyHdl( Link
<LinkParamNone
*,void>() );
940 ESelection aOld
= GetOutlinerView()->GetSelection();
942 ESelection
aNewSelection( 0, 0, mpOutliner
->GetParagraphCount()-1, EE_TEXTPOS_ALL
);
943 GetOutlinerView()->SetSelection( aNewSelection
);
944 SfxItemSet
aEditAttr(GetOutlinerView()->GetAttribs());
945 aEditAttr
.Put(rNewItem
);
946 GetOutlinerView()->SetAttribs( aEditAttr
);
948 if (!mpOutliner
->IsUndoEnabled() && !bOutlinerModified
)
950 // if undo was disabled (e.g. this is a redo action) and we were
951 // originally 'unmodified' keep it that way
952 mpOutliner
->ClearModifyFlag();
955 GetOutlinerView()->SetSelection(aOld
);
956 mpOutliner
->SetModifyHdl( aLink
);
958 EEControlBits nCntrl
= mpOutliner
->GetControlWord();
960 nCntrl
&= ~EEControlBits::ONLINESPELLING
;
961 mpOutliner
->SetControlWord(nCntrl
);
963 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
965 const SwViewOption
* pVOpt
= pWrtShell
->GetViewOptions();
967 if (pVOpt
->IsOnlineSpell())
968 nCntrl
|= EEControlBits::ONLINESPELLING
;
970 nCntrl
&= ~EEControlBits::ONLINESPELLING
;
972 mpOutliner
->SetControlWord(nCntrl
);
974 mpOutliner
->CompleteOnlineSpelling();
976 // restore original mode
977 if (bDisableAndRestoreUndoMode
)
978 mpOutliner
->EnableUndo(true);
983 void SwAnnotationWin::GetFocus()
985 if (mxSidebarTextControl
)
986 mxSidebarTextControl
->GrabFocus();
989 void SwAnnotationWin::LoseFocus()
993 void SwAnnotationWin::ShowNote()
998 if (mpShadow
&& !mpShadow
->isVisible())
999 mpShadow
->setVisible(true);
1000 if (mpAnchor
&& !mpAnchor
->isVisible())
1001 mpAnchor
->setVisible(true);
1002 if (mpTextRangeOverlay
&& !mpTextRangeOverlay
->isVisible())
1003 mpTextRangeOverlay
->setVisible(true);
1005 collectUIInformation("SHOW",get_id());
1008 void SwAnnotationWin::HideNote()
1014 if (mrMgr
.IsShowAnchor())
1015 mpAnchor
->SetAnchorState(AnchorState::Tri
);
1017 mpAnchor
->setVisible(false);
1019 if (mpShadow
&& mpShadow
->isVisible())
1020 mpShadow
->setVisible(false);
1021 if (mpTextRangeOverlay
&& mpTextRangeOverlay
->isVisible())
1022 mpTextRangeOverlay
->setVisible(false);
1023 collectUIInformation("HIDE",get_id());
1026 void SwAnnotationWin::ActivatePostIt()
1028 mrMgr
.AssureStdModeAtShell();
1030 mpOutliner
->ClearModifyFlag();
1031 mpOutliner
->GetUndoManager().Clear();
1034 SetViewState(ViewState::EDIT
);
1036 // prevent autoscroll to the old cursor location
1037 // when cursor out of visible area
1038 GetOutlinerView()->ShowCursor(false);
1040 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
1041 mpOutlinerView
->GetEditView().SetInsertMode(pWrtShell
->IsInsMode());
1043 if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1044 GetOutlinerView()->SetBackgroundColor(mColorDark
);
1046 //tdf#119130 only have the active postit as a dialog control in which pressing
1047 //ctrl+tab cycles between text and button so we don't waste time searching
1048 //thousands of SwAnnotationWins
1049 SetStyle(GetStyle() | WB_DIALOGCONTROL
);
1052 void SwAnnotationWin::DeactivatePostIt()
1054 //tdf#119130 only have the active postit as a dialog control in which pressing
1055 //ctrl+tab cycles between text and button so we don't waste time searching
1056 //thousands of SwAnnotationWins
1057 SetStyle(GetStyle() & ~WB_DIALOGCONTROL
);
1059 // remove selection, #i87073#
1060 if (GetOutlinerView()->GetEditView().HasSelection())
1062 ESelection aSelection
= GetOutlinerView()->GetEditView().GetSelection();
1063 aSelection
.nEndPara
= aSelection
.nStartPara
;
1064 aSelection
.nEndPos
= aSelection
.nStartPos
;
1065 GetOutlinerView()->GetEditView().SetSelection(aSelection
);
1068 mpOutliner
->CompleteOnlineSpelling();
1070 SetViewState(ViewState::NORMAL
);
1071 // Make sure this view doesn't emit LOK callbacks during the update, as the
1072 // sidebar window's SidebarTextControl doesn't have a valid twip offset
1073 // (map mode origin) during that operation.
1074 bool bTiledPainting
= comphelper::LibreOfficeKit::isTiledPainting();
1075 comphelper::LibreOfficeKit::setTiledPainting(true);
1076 // write the visible text back into the SwField
1078 comphelper::LibreOfficeKit::setTiledPainting(bTiledPainting
);
1080 if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1081 GetOutlinerView()->SetBackgroundColor(COL_TRANSPARENT
);
1083 if (!mnDeleteEventId
&& !IsReadOnlyOrProtected() && mpOutliner
->GetEditEngine().GetText().isEmpty())
1085 mnDeleteEventId
= Application::PostUserEvent( LINK( this, SwAnnotationWin
, DeleteHdl
), nullptr, true );
1089 void SwAnnotationWin::ToggleInsMode()
1091 if (!mrView
.GetWrtShell().IsRedlineOn())
1094 mpOutlinerView
->GetEditView().SetInsertMode(!mpOutlinerView
->GetEditView().IsInsertMode());
1096 mrView
.GetWrtShell().ToggleInsMode();
1098 SfxBindings
&rBnd
= mrView
.GetViewFrame().GetBindings();
1099 rBnd
.Invalidate(SID_ATTR_INSERT
);
1100 rBnd
.Update(SID_ATTR_INSERT
);
1104 void SwAnnotationWin::ExecuteCommand(sal_uInt16 nSlot
)
1106 mrMgr
.AssureStdModeAtShell();
1113 // if this note is empty, it will be deleted once losing the focus, so no reply, but only a new note
1115 if (!mpOutliner
->GetEditEngine().GetText().isEmpty())
1117 OutlinerParaObject
aPara(GetOutlinerView()->GetEditView().CreateTextObject());
1118 mrMgr
.RegisterAnswer(&aPara
);
1120 if (mrMgr
.HasActiveSidebarWin())
1121 mrMgr
.SetActiveSidebarWin(nullptr);
1123 mrView
.GetViewFrame().GetDispatcher()->Execute(FN_POSTIT
);
1125 if (nSlot
== FN_REPLY
)
1127 // Get newly created SwPostItField and set its paraIdParent
1128 auto pPostItField
= mrMgr
.GetLatestPostItField();
1129 pPostItField
->SetParentId(GetTopReplyNote()->GetParaId());
1133 case FN_DELETE_COMMENT
:
1134 //Delete(); // do not kill the parent of our open popup menu
1135 mnDeleteEventId
= Application::PostUserEvent( LINK( this, SwAnnotationWin
, DeleteHdl
), nullptr, true );
1137 case FN_DELETE_COMMENT_THREAD
:
1140 case FN_RESOLVE_NOTE
:
1144 mrMgr
.LayoutPostIts();
1146 case FN_RESOLVE_NOTE_THREAD
:
1147 GetTopReplyNote()->SetResolved(!IsThreadResolved());
1148 mrMgr
.UpdateResolvedStatus(GetTopReplyNote());
1151 mrMgr
.LayoutPostIts();
1153 case FN_FORMAT_ALL_NOTES
:
1154 case FN_DELETE_ALL_NOTES
:
1155 case FN_HIDE_ALL_NOTES
:
1156 // not possible as slot as this would require that "this" is the active postit
1157 mrView
.GetViewFrame().GetBindings().Execute( nSlot
, nullptr, SfxCallMode::ASYNCHRON
);
1159 case FN_DELETE_NOTE_AUTHOR
:
1160 case FN_HIDE_NOTE_AUTHOR
:
1162 // not possible as slot as this would require that "this" is the active postit
1163 SfxStringItem
aItem( nSlot
, GetAuthor() );
1164 const SfxPoolItem
* aItems
[2];
1166 aItems
[1] = nullptr;
1167 mrView
.GetViewFrame().GetBindings().Execute( nSlot
, aItems
, SfxCallMode::ASYNCHRON
);
1171 mrView
.GetViewFrame().GetBindings().Execute( nSlot
);
1176 SwEditWin
& SwAnnotationWin::EditWin()
1178 return mrView
.GetEditWin();
1181 tools::Long
SwAnnotationWin::GetPostItTextHeight()
1183 return mpOutliner
? LogicToPixel(mpOutliner
->CalcTextSize()).Height() : 0;
1186 void SwAnnotationWin::SwitchToPostIt(sal_uInt16 aDirection
)
1188 SwAnnotationWin
* pPostIt
= mrMgr
.GetNextPostIt(aDirection
, this);
1190 pPostIt
->GrabFocus();
1193 IMPL_LINK(SwAnnotationWin
, MouseMoveHdl
, const MouseEvent
&, rMEvt
, bool)
1195 if (rMEvt
.IsEnterWindow())
1200 SetViewState(ViewState::VIEW
);
1204 else if (rMEvt
.IsLeaveWindow())
1206 mbMouseOver
= false;
1209 SetViewState(ViewState::NORMAL
);
1216 bool SwAnnotationWin::SetActiveSidebarWin()
1218 if (mrMgr
.GetActiveSidebarWin() == this)
1220 mrView
.GetWrtShell().LockView( true );
1221 mrMgr
.SetActiveSidebarWin(this);
1222 mrView
.GetWrtShell().LockView( true );
1227 void SwAnnotationWin::UnsetActiveSidebarWin()
1229 if (mrMgr
.GetActiveSidebarWin() != this)
1231 mrView
.GetWrtShell().LockView( true );
1232 mrMgr
.SetActiveSidebarWin(nullptr);
1233 mrView
.GetWrtShell().LockView( false );
1236 void SwAnnotationWin::LockView(bool bLock
)
1238 mrView
.GetWrtShell().LockView( bLock
);
1241 IMPL_LINK(SwAnnotationWin
, ScrollHdl
, weld::ScrolledWindow
&, rScrolledWindow
, void)
1243 tools::Long nDiff
= GetOutlinerView()->GetEditView().GetVisArea().Top() - rScrolledWindow
.vadjustment_get_value();
1244 GetOutlinerView()->Scroll( 0, nDiff
);
1247 IMPL_LINK_NOARG(SwAnnotationWin
, ModifyHdl
, LinkParamNone
*, void)
1249 mrView
.GetDocShell()->SetModified();
1252 IMPL_LINK_NOARG(SwAnnotationWin
, DeleteHdl
, void*, void)
1254 mnDeleteEventId
= nullptr;
1258 void SwAnnotationWin::ResetAttributes()
1260 mpOutlinerView
->RemoveAttribsKeepLanguages(true);
1261 mpOutliner
->RemoveFields();
1262 mpOutlinerView
->SetAttribs(DefaultItem());
1265 int SwAnnotationWin::GetPrefScrollbarWidth() const
1267 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
1269 const Fraction
& f(pWrtShell
->GetOut()->GetMapMode().GetScaleY());
1270 return tools::Long(Application::GetSettings().GetStyleSettings().GetScrollBarSize() * f
);
1273 return tools::Long(Application::GetSettings().GetStyleSettings().GetScrollBarSize());
1276 sal_Int32
SwAnnotationWin::GetMetaHeight() const
1278 const int fields
= GetNumFields();
1280 sal_Int32 nRequiredHeight
= 0;
1281 weld::Label
* aLabels
[3] = { mxMetadataAuthor
.get(), mxMetadataDate
.get(), mxMetadataResolved
.get() };
1282 for (int i
= 0; i
< fields
; ++i
)
1283 nRequiredHeight
+= aLabels
[i
]->get_preferred_size().Height();
1285 return nRequiredHeight
;
1288 sal_Int32
SwAnnotationWin::GetNumFields() const
1290 return IsResolved() ? 3 : 2;
1293 sal_Int32
SwAnnotationWin::GetMinimumSizeWithMeta() const
1295 return mrMgr
.GetMinimumSizeWithMeta();
1298 sal_Int32
SwAnnotationWin::GetMinimumSizeWithoutMeta() const
1300 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
1302 const Fraction
& f(pWrtShell
->GetOut()->GetMapMode().GetScaleY());
1303 return tools::Long(POSTIT_MINIMUMSIZE_WITHOUT_META
* f
);
1306 return tools::Long(POSTIT_MINIMUMSIZE_WITHOUT_META
);
1309 void SwAnnotationWin::SetSpellChecking()
1311 if (SwWrtShell
* pWrtShell
= mrView
.GetWrtShellPtr())
1313 const SwViewOption
* pVOpt
= pWrtShell
->GetViewOptions();
1314 EEControlBits nCntrl
= mpOutliner
->GetControlWord();
1315 if (pVOpt
->IsOnlineSpell())
1316 nCntrl
|= EEControlBits::ONLINESPELLING
;
1318 nCntrl
&= ~EEControlBits::ONLINESPELLING
;
1319 mpOutliner
->SetControlWord(nCntrl
);
1321 mpOutliner
->CompleteOnlineSpelling();
1326 void SwAnnotationWin::SetViewState(ViewState bViewState
)
1330 case ViewState::EDIT
:
1334 mpAnchor
->SetAnchorState(AnchorState::All
);
1335 SwAnnotationWin
* pWin
= GetTopReplyNote();
1337 if ( pWin
!= this && pWin
->Anchor() )
1339 pWin
->Anchor()->SetAnchorState(AnchorState::End
);
1341 mpAnchor
->setLineSolid(true);
1342 if ( mpTextRangeOverlay
!= nullptr )
1344 mpTextRangeOverlay
->ShowSolidBorder();
1348 mpShadow
->SetShadowState(SS_EDIT
);
1351 case ViewState::VIEW
:
1355 mpAnchor
->setLineSolid(true);
1356 if ( mpTextRangeOverlay
!= nullptr )
1358 mpTextRangeOverlay
->ShowSolidBorder();
1362 mpShadow
->SetShadowState(SS_VIEW
);
1365 case ViewState::NORMAL
:
1371 // if there is no visible parent note, we want to see the complete anchor ??
1372 //if (IsAnyStackParentVisible())
1373 mpAnchor
->SetAnchorState(AnchorState::End
);
1374 SwAnnotationWin
* pTopWinSelf
= GetTopReplyNote();
1375 SwAnnotationWin
* pTopWinActive
= mrMgr
.HasActiveSidebarWin()
1376 ? mrMgr
.GetActiveSidebarWin()->GetTopReplyNote()
1379 if ( ( pTopWinSelf
!= this ) &&
1380 ( pTopWinSelf
!= pTopWinActive
) &&
1381 pTopWinSelf
->Anchor() )
1383 if ( pTopWinSelf
!= mrMgr
.GetActiveSidebarWin() )
1385 pTopWinSelf
->Anchor()->setLineSolid(false);
1386 if ( pTopWinSelf
->TextRange() != nullptr )
1388 pTopWinSelf
->TextRange()->HideSolidBorder();
1391 pTopWinSelf
->Anchor()->SetAnchorState(AnchorState::All
);
1394 mpAnchor
->setLineSolid(false);
1395 if ( mpTextRangeOverlay
!= nullptr )
1397 mpTextRangeOverlay
->HideSolidBorder();
1402 mpShadow
->SetShadowState(SS_NORMAL
);
1409 SwAnnotationWin
* SwAnnotationWin::GetTopReplyNote()
1411 SwAnnotationWin
* pTopNote
= this;
1412 SwAnnotationWin
* pSidebarWin
= IsFollow() ? mrMgr
.GetNextPostIt(KEY_PAGEUP
, this) : nullptr;
1415 pTopNote
= pSidebarWin
;
1416 pSidebarWin
= pSidebarWin
->IsFollow() ? mrMgr
.GetNextPostIt(KEY_PAGEUP
, pSidebarWin
) : nullptr;
1421 void SwAnnotationWin::SwitchToFieldPos()
1423 if ( mrMgr
.GetActiveSidebarWin() == this )
1424 mrMgr
.SetActiveSidebarWin(nullptr);
1426 sal_uInt32 aCount
= MoveCaret();
1428 mrView
.GetDocShell()->GetWrtShell()->SwCursorShell::Right(aCount
, SwCursorSkipMode::Chars
);
1429 GrabFocusToDocument();
1430 collectUIInformation("LEAVE",get_id());
1433 void SwAnnotationWin::SetChangeTracking( const SwPostItHelper::SwLayoutStatus aLayoutStatus
,
1434 const Color
& aChangeColor
)
1436 if ( (mLayoutStatus
!= aLayoutStatus
) ||
1437 (mChangeColor
!= aChangeColor
) )
1439 mLayoutStatus
= aLayoutStatus
;
1440 mChangeColor
= aChangeColor
;
1445 bool SwAnnotationWin::HasScrollbar() const
1447 return static_cast<bool>(mxVScrollbar
);
1450 bool SwAnnotationWin::IsScrollbarVisible() const
1452 return HasScrollbar() && mxVScrollbar
->get_vpolicy() == VclPolicyType::ALWAYS
;
1455 void SwAnnotationWin::ChangeSidebarItem( SwSidebarItem
const & rSidebarItem
)
1457 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1458 const bool bAnchorChanged
= mpAnchorFrame
!= rSidebarItem
.maLayoutInfo
.mpAnchorFrame
;
1459 if ( bAnchorChanged
)
1461 mrMgr
.DisconnectSidebarWinFromFrame( *mpAnchorFrame
, *this );
1465 mrSidebarItem
= rSidebarItem
;
1466 mpAnchorFrame
= mrSidebarItem
.maLayoutInfo
.mpAnchorFrame
;
1468 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1469 if (mxSidebarWinAccessible
)
1470 mxSidebarWinAccessible
->ChangeSidebarItem( mrSidebarItem
);
1472 if ( bAnchorChanged
)
1474 mrMgr
.ConnectSidebarWinToFrame( *(mrSidebarItem
.maLayoutInfo
.mpAnchorFrame
),
1475 mrSidebarItem
.GetFormatField(),
1481 css::uno::Reference
< css::accessibility::XAccessible
> SwAnnotationWin::CreateAccessible()
1483 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1484 // This is rather dodgy code. Normally in CreateAccessible, if we want a custom
1485 // object, we return a custom object, but we do no override the default toolkit
1487 if (!mxSidebarWinAccessible
)
1488 mxSidebarWinAccessible
= new SidebarWinAccessible( *this,
1489 mrView
.GetWrtShell(),
1492 return mxSidebarWinAccessible
;
1495 } // eof of namespace sw::sidebarwindows
1497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */