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 <basegfx/matrix/b2dhommatrix.hxx>
23 #include <com/sun/star/accessibility/AccessibleRole.hpp>
24 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
25 #include <com/sun/star/accessibility/XAccessible.hpp>
26 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
27 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
28 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
29 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
30 #include <com/sun/star/lang/XServiceInfo.hpp>
31 #include <cppuhelper/supportsservice.hxx>
32 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
33 #include <drawinglayer/processor2d/processor2dtools.hxx>
34 #include <comphelper/lok.hxx>
35 #include <editeng/eeitem.hxx>
36 #include <editeng/fhgtitem.hxx>
37 #include <editeng/fontitem.hxx>
38 #include <editeng/outliner.hxx>
39 #include <editeng/unoedhlp.hxx>
40 #include <editeng/unoedsrc.hxx>
41 #include <i18nlangtag/languagetag.hxx>
42 #include <osl/diagnose.h>
43 #include <svl/itempool.hxx>
44 #include <svl/itemset.hxx>
45 #include <sal/log.hxx>
46 #include <svx/sdr/overlay/overlayselection.hxx>
47 #include <svtools/optionsdrawinglayer.hxx>
48 #include <svx/AccessibleTextHelper.hxx>
49 #include <svx/weldeditview.hxx>
50 #include <comphelper/diagnose_ex.hxx>
51 #include <vcl/canvastools.hxx>
52 #include <vcl/cursor.hxx>
53 #include <vcl/event.hxx>
54 #include <vcl/ptrstyle.hxx>
55 #include <vcl/settings.hxx>
56 #include <vcl/svapp.hxx>
57 #include <vcl/window.hxx>
58 #include <vcl/uitest/uiobject.hxx>
60 void WeldEditView::SetText(const OUString
& rStr
) { GetEditEngine()->SetText(rStr
); }
62 OUString
WeldEditView::GetText() const { return GetEditEngine()->GetText(); }
64 void WeldEditView::SetModifyHdl(const Link
<LinkParamNone
*, void>& rLink
)
66 GetEditEngine()->SetModifyHdl(rLink
);
69 EditView
* WeldEditView::GetEditView() const { return m_xEditView
.get(); }
71 EditEngine
* WeldEditView::GetEditEngine() const { return m_xEditEngine
.get(); }
73 bool WeldEditView::HasSelection() const
75 EditView
* pEditView
= GetEditView();
76 return pEditView
&& pEditView
->HasSelection();
79 void WeldEditView::Delete()
81 if (EditView
* pEditView
= GetEditView())
82 pEditView
->DeleteSelected();
85 void WeldEditView::Cut()
87 if (EditView
* pEditView
= GetEditView())
91 void WeldEditView::Copy()
93 if (EditView
* pEditView
= GetEditView())
97 void WeldEditView::Paste()
99 if (EditView
* pEditView
= GetEditView())
103 WeldEditView::WeldEditView()
104 : m_bAcceptsTab(false)
108 // tdf#127033 want to use UI font so override makeEditEngine to enable that
109 void WeldEditView::makeEditEngine()
111 rtl::Reference
<SfxItemPool
> pItemPool
= EditEngine::CreatePool();
113 vcl::Font
aAppFont(Application::GetSettings().GetStyleSettings().GetAppFont());
115 pItemPool
->SetPoolDefaultItem(SvxFontItem(aAppFont
.GetFamilyType(), aAppFont
.GetFamilyName(),
116 "", PITCH_DONTKNOW
, RTL_TEXTENCODING_DONTKNOW
,
118 pItemPool
->SetPoolDefaultItem(SvxFontItem(aAppFont
.GetFamilyType(), aAppFont
.GetFamilyName(),
119 "", PITCH_DONTKNOW
, RTL_TEXTENCODING_DONTKNOW
,
120 EE_CHAR_FONTINFO_CJK
));
121 pItemPool
->SetPoolDefaultItem(SvxFontItem(aAppFont
.GetFamilyType(), aAppFont
.GetFamilyName(),
122 "", PITCH_DONTKNOW
, RTL_TEXTENCODING_DONTKNOW
,
123 EE_CHAR_FONTINFO_CTL
));
125 pItemPool
->SetPoolDefaultItem(
126 SvxFontHeightItem(aAppFont
.GetFontHeight() * 20, 100, EE_CHAR_FONTHEIGHT
));
127 pItemPool
->SetPoolDefaultItem(
128 SvxFontHeightItem(aAppFont
.GetFontHeight() * 20, 100, EE_CHAR_FONTHEIGHT_CJK
));
129 pItemPool
->SetPoolDefaultItem(
130 SvxFontHeightItem(aAppFont
.GetFontHeight() * 20, 100, EE_CHAR_FONTHEIGHT_CTL
));
132 m_xEditEngine
.reset(new EditEngine(pItemPool
.get()));
135 void WeldEditView::Resize()
137 if (EditView
* pEditView
= GetEditView())
139 OutputDevice
& rDevice
= GetDrawingArea()->get_ref_device();
140 Size
aOutputSize(rDevice
.PixelToLogic(GetOutputSizePixel()));
141 // Resizes the edit engine to adjust to the size of the output area
142 pEditView
->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize
));
143 GetEditEngine()->SetPaperSize(aOutputSize
);
144 pEditView
->ShowCursor();
146 const tools::Long nMaxVisAreaStart
147 = pEditView
->GetEditEngine()->GetTextHeight() - aOutputSize
.Height();
148 tools::Rectangle
aVisArea(pEditView
->GetVisArea());
149 if (aVisArea
.Top() > nMaxVisAreaStart
)
151 aVisArea
.SetTop(std::max
<tools::Long
>(nMaxVisAreaStart
, 0));
152 aVisArea
.SetSize(aOutputSize
);
153 pEditView
->SetVisArea(aVisArea
);
154 pEditView
->ShowCursor();
157 EditViewScrollStateChange();
159 weld::CustomWidgetController::Resize();
162 void WeldEditView::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
164 DoPaint(rRenderContext
, rRect
);
167 void WeldEditView::DoPaint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
169 rRenderContext
.Push(vcl::PushFlags::ALL
);
170 rRenderContext
.SetClipRegion();
172 std::vector
<tools::Rectangle
> aLogicRects
;
174 if (EditView
* pEditView
= GetEditView())
176 pEditView
->Paint(comphelper::LibreOfficeKit::isActive() ? rRenderContext
.PixelToLogic(rRect
)
182 pEditView
->ShowCursor(false);
183 vcl::Cursor
* pCursor
= pEditView
->GetCursor();
184 pCursor
->DrawToDevice(rRenderContext
);
187 // get logic selection
188 pEditView
->GetSelectionRectangles(aLogicRects
);
191 if (!aLogicRects
.empty())
193 std::vector
<basegfx::B2DRange
> aLogicRanges
;
194 aLogicRanges
.reserve(aLogicRects
.size());
196 tools::Long
nMinX(LONG_MAX
), nMaxX(0), nMinY(LONG_MAX
), nMaxY(0);
197 for (const auto& aRect
: aLogicRects
)
199 nMinX
= std::min(nMinX
, aRect
.Left());
200 nMinY
= std::min(nMinY
, aRect
.Top());
201 nMaxX
= std::max(nMaxX
, aRect
.Right());
202 nMaxY
= std::max(nMaxY
, aRect
.Bottom());
205 const Size
aLogicPixel(rRenderContext
.PixelToLogic(Size(1, 1)));
206 for (const auto& aRect
: aLogicRects
)
208 // Extend each range by one pixel so multiple lines touch each
209 // other if adjacent, so the whole set is drawn with a single
210 // border around the lot. But keep the selection within the
211 // original max extents.
212 auto nTop
= aRect
.Top();
214 nTop
-= aLogicPixel
.Height();
215 auto nBottom
= aRect
.Bottom();
217 nBottom
+= aLogicPixel
.Height();
218 auto nLeft
= aRect
.Left();
220 nLeft
-= aLogicPixel
.Width();
221 auto nRight
= aRect
.Right();
223 nRight
+= aLogicPixel
.Width();
225 aLogicRanges
.emplace_back(nLeft
, nTop
, nRight
, nBottom
);
228 // get the system's highlight color
229 const Color
aHighlight(SvtOptionsDrawinglayer::getHilightColor());
231 sdr::overlay::OverlaySelection
aCursorOverlay(sdr::overlay::OverlayType::Transparent
,
232 aHighlight
, std::move(aLogicRanges
), true);
234 drawinglayer::geometry::ViewInformation2D aViewInformation2D
;
235 aViewInformation2D
.setViewTransformation(rRenderContext
.GetViewTransformation());
236 aViewInformation2D
.setViewport(vcl::unotools::b2DRectangleFromRectangle(rRect
));
238 std::unique_ptr
<drawinglayer::processor2d::BaseProcessor2D
> xProcessor(
239 drawinglayer::processor2d::createProcessor2DFromOutputDevice(rRenderContext
,
240 aViewInformation2D
));
242 xProcessor
->process(aCursorOverlay
.getOverlayObjectPrimitive2DSequence());
245 rRenderContext
.Pop();
248 bool WeldEditView::MouseMove(const MouseEvent
& rMEvt
)
250 EditView
* pEditView
= GetEditView();
251 return pEditView
&& pEditView
->MouseMove(rMEvt
);
254 bool WeldEditView::MouseButtonDown(const MouseEvent
& rMEvt
)
256 if (!IsMouseCaptured())
259 if (!HasFocus() && CanFocus())
262 EditView
* pEditView
= GetEditView();
263 return pEditView
&& pEditView
->MouseButtonDown(rMEvt
);
266 bool WeldEditView::MouseButtonUp(const MouseEvent
& rMEvt
)
268 if (IsMouseCaptured())
270 EditView
* pEditView
= GetEditView();
271 return pEditView
&& pEditView
->MouseButtonUp(rMEvt
);
274 bool WeldEditView::KeyInput(const KeyEvent
& rKEvt
)
276 EditView
* pEditView
= GetEditView();
278 sal_uInt16 nKey
= rKEvt
.GetKeyCode().GetCode();
280 if (nKey
== KEY_TAB
&& !GetAcceptsTab())
284 else if (pEditView
&& !pEditView
->PostKeyEvent(rKEvt
))
286 if (rKEvt
.GetKeyCode().IsMod1() && !rKEvt
.GetKeyCode().IsMod2())
290 EditEngine
* pEditEngine
= GetEditEngine();
291 sal_Int32 nPar
= pEditEngine
->GetParagraphCount();
294 sal_Int32 nLen
= pEditEngine
->GetTextLen(nPar
- 1);
295 pEditView
->SetSelection(ESelection(0, 0, nPar
- 1, nLen
));
307 bool WeldEditView::Command(const CommandEvent
& rCEvt
)
309 EditView
* pEditView
= GetEditView();
312 return pEditView
->Command(rCEvt
);
315 Point
WeldEditView::EditViewPointerPosPixel() const
317 return GetDrawingArea()->get_pointer_position();
320 class WeldEditAccessible
;
324 class WeldViewForwarder
: public SvxViewForwarder
326 WeldEditAccessible
& m_rEditAcc
;
328 WeldViewForwarder(const WeldViewForwarder
&) = delete;
329 WeldViewForwarder
& operator=(const WeldViewForwarder
&) = delete;
332 explicit WeldViewForwarder(WeldEditAccessible
& rAcc
)
337 virtual bool IsValid() const override
;
338 virtual Point
LogicToPixel(const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
339 virtual Point
PixelToLogic(const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
343 class WeldEditAccessible
;
347 class WeldEditSource
;
349 /* analog to SvxEditEngineForwarder */
350 class WeldTextForwarder
: public SvxTextForwarder
352 WeldEditAccessible
& m_rEditAcc
;
353 WeldEditSource
& m_rEditSource
;
355 DECL_LINK(NotifyHdl
, EENotify
&, void);
357 WeldTextForwarder(const WeldTextForwarder
&) = delete;
358 WeldTextForwarder
& operator=(const WeldTextForwarder
&) = delete;
361 WeldTextForwarder(WeldEditAccessible
& rAcc
, WeldEditSource
& rSource
);
362 virtual ~WeldTextForwarder() override
;
364 virtual sal_Int32
GetParagraphCount() const override
;
365 virtual sal_Int32
GetTextLen(sal_Int32 nParagraph
) const override
;
366 virtual OUString
GetText(const ESelection
& rSel
) const override
;
367 virtual SfxItemSet
GetAttribs(const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
368 = EditEngineAttribs::All
) const override
;
369 virtual SfxItemSet
GetParaAttribs(sal_Int32 nPara
) const override
;
370 virtual void SetParaAttribs(sal_Int32 nPara
, const SfxItemSet
& rSet
) override
;
371 virtual void RemoveAttribs(const ESelection
& rSelection
) override
;
372 virtual void GetPortions(sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const override
;
374 virtual SfxItemState
GetItemState(const ESelection
& rSel
, sal_uInt16 nWhich
) const override
;
375 virtual SfxItemState
GetItemState(sal_Int32 nPara
, sal_uInt16 nWhich
) const override
;
377 virtual void QuickInsertText(const OUString
& rText
, const ESelection
& rSel
) override
;
378 virtual void QuickInsertField(const SvxFieldItem
& rFld
, const ESelection
& rSel
) override
;
379 virtual void QuickSetAttribs(const SfxItemSet
& rSet
, const ESelection
& rSel
) override
;
380 virtual void QuickInsertLineBreak(const ESelection
& rSel
) override
;
382 virtual SfxItemPool
* GetPool() const override
;
384 virtual OUString
CalcFieldValue(const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
,
385 std::optional
<Color
>& rpTxtColor
,
386 std::optional
<Color
>& rpFldColor
,
387 std::optional
<FontLineStyle
>& rpFldLineStyle
) override
;
388 virtual void FieldClicked(const SvxFieldItem
&) override
;
389 virtual bool IsValid() const override
;
391 virtual LanguageType
GetLanguage(sal_Int32
, sal_Int32
) const override
;
392 virtual sal_Int32
GetFieldCount(sal_Int32 nPara
) const override
;
393 virtual EFieldInfo
GetFieldInfo(sal_Int32 nPara
, sal_uInt16 nField
) const override
;
394 virtual EBulletInfo
GetBulletInfo(sal_Int32 nPara
) const override
;
395 virtual tools::Rectangle
GetCharBounds(sal_Int32 nPara
, sal_Int32 nIndex
) const override
;
396 virtual tools::Rectangle
GetParaBounds(sal_Int32 nPara
) const override
;
397 virtual MapMode
GetMapMode() const override
;
398 virtual OutputDevice
* GetRefDevice() const override
;
399 virtual bool GetIndexAtPoint(const Point
&, sal_Int32
& nPara
, sal_Int32
& nIndex
) const override
;
400 virtual bool GetWordIndices(sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
,
401 sal_Int32
& nEnd
) const override
;
402 virtual bool GetAttributeRun(sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
,
403 sal_Int32 nIndex
, bool bInCell
= false) const override
;
404 virtual sal_Int32
GetLineCount(sal_Int32 nPara
) const override
;
405 virtual sal_Int32
GetLineLen(sal_Int32 nPara
, sal_Int32 nLine
) const override
;
406 virtual void GetLineBoundaries(/*out*/ sal_Int32
& rStart
, /*out*/ sal_Int32
& rEnd
,
407 sal_Int32 nParagraph
, sal_Int32 nLine
) const override
;
408 virtual sal_Int32
GetLineNumberAtIndex(sal_Int32 nPara
, sal_Int32 nLine
) const override
;
409 virtual bool Delete(const ESelection
&) override
;
410 virtual bool InsertText(const OUString
&, const ESelection
&) override
;
411 virtual bool QuickFormatDoc(bool bFull
= false) override
;
413 virtual sal_Int16
GetDepth(sal_Int32 nPara
) const override
;
414 virtual bool SetDepth(sal_Int32 nPara
, sal_Int16 nNewDepth
) override
;
416 virtual const SfxItemSet
* GetEmptyItemSetPtr() override
;
417 // implementation functions for XParagraphAppend and XTextPortionAppend
418 virtual void AppendParagraph() override
;
419 virtual sal_Int32
AppendTextPortion(sal_Int32 nPara
, const OUString
& rText
,
420 const SfxItemSet
& rSet
) override
;
422 virtual void CopyText(const SvxTextForwarder
& rSource
) override
;
425 /* analog to SvxEditEngineViewForwarder */
426 class WeldEditViewForwarder
: public SvxEditViewForwarder
428 WeldEditAccessible
& m_rEditAcc
;
430 WeldEditViewForwarder(const WeldEditViewForwarder
&) = delete;
431 WeldEditViewForwarder
& operator=(const WeldEditViewForwarder
&) = delete;
434 explicit WeldEditViewForwarder(WeldEditAccessible
& rAcc
);
436 virtual bool IsValid() const override
;
438 virtual Point
LogicToPixel(const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
439 virtual Point
PixelToLogic(const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
441 virtual bool GetSelection(ESelection
& rSelection
) const override
;
442 virtual bool SetSelection(const ESelection
& rSelection
) override
;
443 virtual bool Copy() override
;
444 virtual bool Cut() override
;
445 virtual bool Paste() override
;
448 class WeldEditSource
: public SvxEditSource
450 SfxBroadcaster m_aBroadCaster
;
451 WeldViewForwarder m_aViewFwd
;
452 WeldTextForwarder m_aTextFwd
;
453 WeldEditViewForwarder m_aEditViewFwd
;
454 WeldEditAccessible
& m_rEditAcc
;
456 WeldEditSource(const WeldEditSource
& rSrc
)
458 , m_aViewFwd(rSrc
.m_rEditAcc
)
459 , m_aTextFwd(rSrc
.m_rEditAcc
, *this)
460 , m_aEditViewFwd(rSrc
.m_rEditAcc
)
461 , m_rEditAcc(rSrc
.m_rEditAcc
)
465 WeldEditSource
& operator=(const WeldEditSource
&) = delete;
468 WeldEditSource(WeldEditAccessible
& rAcc
)
470 , m_aTextFwd(rAcc
, *this)
471 , m_aEditViewFwd(rAcc
)
476 virtual std::unique_ptr
<SvxEditSource
> Clone() const override
478 return std::unique_ptr
<SvxEditSource
>(new WeldEditSource(*this));
481 virtual SvxTextForwarder
* GetTextForwarder() override
{ return &m_aTextFwd
; }
483 virtual SvxViewForwarder
* GetViewForwarder() override
{ return &m_aViewFwd
; }
485 virtual SvxEditViewForwarder
* GetEditViewForwarder(bool /*bCreate*/) override
487 return &m_aEditViewFwd
;
490 virtual void UpdateData() override
492 // would possibly only by needed if the XText interface is implemented
493 // and its text needs to be updated.
495 virtual SfxBroadcaster
& GetBroadcaster() const override
497 return const_cast<WeldEditSource
*>(this)->m_aBroadCaster
;
502 typedef cppu::WeakImplHelper
<css::lang::XServiceInfo
, css::accessibility::XAccessible
,
503 css::accessibility::XAccessibleComponent
,
504 css::accessibility::XAccessibleContext
,
505 css::accessibility::XAccessibleEventBroadcaster
>
506 WeldEditAccessibleBaseClass
;
508 class WeldEditAccessible
: public WeldEditAccessibleBaseClass
510 weld::CustomWidgetController
* m_pController
;
511 EditEngine
* m_pEditEngine
;
512 EditView
* m_pEditView
;
513 std::unique_ptr
<::accessibility::AccessibleTextHelper
> m_xTextHelper
;
516 WeldEditAccessible(weld::CustomWidgetController
* pController
)
517 : m_pController(pController
)
518 , m_pEditEngine(nullptr)
519 , m_pEditView(nullptr)
523 ::accessibility::AccessibleTextHelper
* GetTextHelper() { return m_xTextHelper
.get(); }
525 void Init(EditEngine
* pEditEngine
, EditView
* pEditView
)
527 m_pEditEngine
= pEditEngine
;
528 m_pEditView
= pEditView
;
530 new ::accessibility::AccessibleTextHelper(std::make_unique
<WeldEditSource
>(*this)));
531 m_xTextHelper
->SetEventSource(this);
534 EditEngine
* GetEditEngine() { return m_pEditEngine
; }
535 EditView
* GetEditView() { return m_pEditView
; }
539 // remove handler before current object gets destroyed
540 // (avoid handler being called for already dead object)
541 m_pEditEngine
->SetNotifyHdl(Link
<EENotify
&, void>());
543 m_pEditEngine
= nullptr;
544 m_pEditView
= nullptr;
545 m_pController
= nullptr; // implicitly results in AccessibleStateType::DEFUNC set
547 //! make TextHelper implicitly release C++ references to some core objects
548 m_xTextHelper
->SetEditSource(::std::unique_ptr
<SvxEditSource
>());
550 //! make TextHelper release references
551 //! (e.g. the one set by the 'SetEventSource' call)
552 m_xTextHelper
->Dispose();
553 m_xTextHelper
.reset();
557 virtual css::uno::Reference
<css::accessibility::XAccessibleContext
>
558 SAL_CALL
getAccessibleContext() override
563 // XAccessibleComponent
564 virtual sal_Bool SAL_CALL
containsPoint(const css::awt::Point
& rPoint
) override
566 //! the arguments coordinates are relative to the current window !
567 //! Thus the top left-point is (0, 0)
568 SolarMutexGuard aGuard
;
570 throw css::uno::RuntimeException();
572 Size
aSz(m_pController
->GetOutputSizePixel());
573 return rPoint
.X
>= 0 && rPoint
.Y
>= 0 && rPoint
.X
< aSz
.Width() && rPoint
.Y
< aSz
.Height();
576 virtual css::uno::Reference
<css::accessibility::XAccessible
>
577 SAL_CALL
getAccessibleAtPoint(const css::awt::Point
& rPoint
) override
579 SolarMutexGuard aGuard
;
581 throw css::uno::RuntimeException();
583 return m_xTextHelper
->GetAt(rPoint
);
586 virtual css::awt::Rectangle SAL_CALL
getBounds() override
588 SolarMutexGuard aGuard
;
590 throw css::uno::RuntimeException();
593 const Size
aOutSize(m_pController
->GetOutputSizePixel());
594 css::awt::Rectangle aRet
;
596 aRet
.X
= aOutPos
.X();
597 aRet
.Y
= aOutPos
.Y();
598 aRet
.Width
= aOutSize
.Width();
599 aRet
.Height
= aOutSize
.Height();
604 virtual css::awt::Point SAL_CALL
getLocation() override
606 SolarMutexGuard aGuard
;
608 throw css::uno::RuntimeException();
610 const css::awt::Rectangle
aRect(getBounds());
611 css::awt::Point aRet
;
619 virtual css::awt::Point SAL_CALL
getLocationOnScreen() override
621 SolarMutexGuard aGuard
;
623 throw css::uno::RuntimeException();
625 css::awt::Point
aScreenLoc(0, 0);
627 if (weld::DrawingArea
* pDrawingArea
= m_pController
->GetDrawingArea())
629 Point aPos
= pDrawingArea
->get_accessible_location_on_screen();
630 aScreenLoc
.X
= aPos
.X();
631 aScreenLoc
.Y
= aPos
.Y();
637 virtual css::awt::Size SAL_CALL
getSize() override
639 SolarMutexGuard aGuard
;
641 throw css::uno::RuntimeException();
643 Size
aSz(m_pController
->GetOutputSizePixel());
644 return css::awt::Size(aSz
.Width(), aSz
.Height());
647 virtual void SAL_CALL
grabFocus() override
{ m_pController
->GrabFocus(); }
649 virtual sal_Int32 SAL_CALL
getForeground() override
651 SolarMutexGuard aGuard
;
653 throw css::uno::RuntimeException();
655 Color nCol
= m_pEditEngine
->GetAutoColor();
656 return static_cast<sal_Int32
>(nCol
);
659 virtual sal_Int32 SAL_CALL
getBackground() override
661 SolarMutexGuard aGuard
;
663 throw css::uno::RuntimeException();
665 Color nCol
= m_pEditEngine
->GetBackgroundColor();
666 return static_cast<sal_Int32
>(nCol
);
669 // XAccessibleContext
670 virtual sal_Int64 SAL_CALL
getAccessibleChildCount() override
673 return m_xTextHelper
->GetChildCount();
677 virtual css::uno::Reference
<css::accessibility::XAccessible
>
678 SAL_CALL
getAccessibleChild(sal_Int64 i
) override
681 return m_xTextHelper
->GetChild(i
);
682 throw css::lang::IndexOutOfBoundsException(); // there is no child...
685 virtual css::uno::Reference
<css::accessibility::XAccessible
>
686 SAL_CALL
getAccessibleParent() override
688 SolarMutexGuard aGuard
;
690 throw css::uno::RuntimeException();
692 return m_pController
->GetDrawingArea()->get_accessible_parent();
695 virtual sal_Int64 SAL_CALL
getAccessibleIndexInParent() override
697 SolarMutexGuard aGuard
;
699 throw css::uno::RuntimeException();
701 // -1 for child not found/no parent (according to specification)
704 css::uno::Reference
<css::accessibility::XAccessible
> xParent(getAccessibleParent());
710 css::uno::Reference
<css::accessibility::XAccessibleContext
> xParentContext(
711 xParent
->getAccessibleContext());
713 // iterate over parent's children and search for this object
714 if (xParentContext
.is())
716 sal_Int64 nChildCount
= xParentContext
->getAccessibleChildCount();
717 for (sal_Int64 nChild
= 0; (nChild
< nChildCount
) && (-1 == nRet
); ++nChild
)
719 css::uno::Reference
<css::accessibility::XAccessible
> xChild(
720 xParentContext
->getAccessibleChild(nChild
));
721 if (xChild
.get() == this)
726 catch (const css::uno::Exception
&)
728 TOOLS_WARN_EXCEPTION("svx", "WeldEditAccessible::getAccessibleIndexInParent");
734 virtual sal_Int16 SAL_CALL
getAccessibleRole() override
736 return css::accessibility::AccessibleRole::TEXT_FRAME
;
739 virtual OUString SAL_CALL
getAccessibleDescription() override
741 SolarMutexGuard aGuard
;
747 aRet
= m_pController
->GetAccessibleDescription();
753 virtual OUString SAL_CALL
getAccessibleName() override
755 SolarMutexGuard aGuard
;
761 aRet
= m_pController
->GetAccessibleName();
767 virtual css::uno::Reference
<css::accessibility::XAccessibleRelationSet
>
768 SAL_CALL
getAccessibleRelationSet() override
770 SolarMutexGuard aGuard
;
772 throw css::uno::RuntimeException();
774 return m_pController
->GetDrawingArea()->get_accessible_relation_set();
777 virtual sal_Int64 SAL_CALL
getAccessibleStateSet() override
779 SolarMutexGuard aGuard
;
780 sal_Int64 nStateSet
= 0;
782 if (!m_pController
|| !m_xTextHelper
)
783 nStateSet
|= css::accessibility::AccessibleStateType::DEFUNC
;
786 nStateSet
|= css::accessibility::AccessibleStateType::MULTI_LINE
;
787 nStateSet
|= css::accessibility::AccessibleStateType::ENABLED
;
788 nStateSet
|= css::accessibility::AccessibleStateType::EDITABLE
;
789 nStateSet
|= css::accessibility::AccessibleStateType::FOCUSABLE
;
790 nStateSet
|= css::accessibility::AccessibleStateType::SELECTABLE
;
791 if (m_pController
->HasFocus())
792 nStateSet
|= css::accessibility::AccessibleStateType::FOCUSED
;
793 if (m_pController
->IsActive())
794 nStateSet
|= css::accessibility::AccessibleStateType::ACTIVE
;
795 if (m_pController
->IsVisible())
796 nStateSet
|= css::accessibility::AccessibleStateType::SHOWING
;
797 if (m_pController
->IsReallyVisible())
798 nStateSet
|= css::accessibility::AccessibleStateType::VISIBLE
;
799 if (COL_TRANSPARENT
!= m_pEditEngine
->GetBackgroundColor())
800 nStateSet
|= css::accessibility::AccessibleStateType::OPAQUE
;
806 virtual css::lang::Locale SAL_CALL
getLocale() override
808 SolarMutexGuard aGuard
;
809 return LanguageTag(m_pEditEngine
->GetDefaultLanguage()).getLocale();
812 // XAccessibleEventBroadcaster
813 virtual void SAL_CALL
addAccessibleEventListener(
814 const css::uno::Reference
<css::accessibility::XAccessibleEventListener
>& rListener
) override
816 if (!m_xTextHelper
) // not disposing (about to destroy view shell)
818 m_xTextHelper
->AddEventListener(rListener
);
821 virtual void SAL_CALL
removeAccessibleEventListener(
822 const css::uno::Reference
<css::accessibility::XAccessibleEventListener
>& rListener
) override
824 if (!m_xTextHelper
) // not disposing (about to destroy view shell)
826 m_xTextHelper
->RemoveEventListener(rListener
);
829 virtual OUString SAL_CALL
getImplementationName() override
{ return "WeldEditAccessible"; }
831 virtual sal_Bool SAL_CALL
supportsService(const OUString
& rServiceName
) override
833 return cppu::supportsService(this, rServiceName
);
836 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
838 return { "css::accessibility::Accessible", "css::accessibility::AccessibleComponent",
839 "css::accessibility::AccessibleContext" };
843 css::uno::Reference
<css::accessibility::XAccessible
> WeldEditView::CreateAccessible()
845 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
846 if (!m_xAccessible
.is())
847 m_xAccessible
.set(new WeldEditAccessible(this));
849 return m_xAccessible
;
852 WeldEditView::~WeldEditView()
854 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
855 if (m_xAccessible
.is())
857 m_xAccessible
->ClearWin(); // make Accessible nonfunctional
858 m_xAccessible
.clear();
863 bool WeldViewForwarder::IsValid() const { return m_rEditAcc
.GetEditView() != nullptr; }
865 Point
WeldViewForwarder::LogicToPixel(const Point
& rPoint
, const MapMode
& rMapMode
) const
867 EditView
* pEditView
= m_rEditAcc
.GetEditView();
870 OutputDevice
& rOutDev
= pEditView
->GetOutputDevice();
871 MapMode
aMapMode(rOutDev
.GetMapMode());
872 Point
aPoint(OutputDevice::LogicToLogic(rPoint
, rMapMode
, MapMode(aMapMode
.GetMapUnit())));
873 aMapMode
.SetOrigin(Point());
874 return rOutDev
.LogicToPixel(aPoint
, aMapMode
);
877 Point
WeldViewForwarder::PixelToLogic(const Point
& rPoint
, const MapMode
& rMapMode
) const
879 EditView
* pEditView
= m_rEditAcc
.GetEditView();
882 OutputDevice
& rOutDev
= pEditView
->GetOutputDevice();
883 MapMode
aMapMode(rOutDev
.GetMapMode());
884 aMapMode
.SetOrigin(Point());
885 Point
aPoint(rOutDev
.PixelToLogic(rPoint
, aMapMode
));
886 return OutputDevice::LogicToLogic(aPoint
, MapMode(aMapMode
.GetMapUnit()), rMapMode
);
889 WeldTextForwarder::WeldTextForwarder(WeldEditAccessible
& rAcc
, WeldEditSource
& rSource
)
891 , m_rEditSource(rSource
)
893 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
895 pEditEngine
->SetNotifyHdl(LINK(this, WeldTextForwarder
, NotifyHdl
));
898 WeldTextForwarder::~WeldTextForwarder()
900 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
902 pEditEngine
->SetNotifyHdl(Link
<EENotify
&, void>());
905 IMPL_LINK(WeldTextForwarder
, NotifyHdl
, EENotify
&, rNotify
, void)
907 if (EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine())
909 if (rNotify
.eNotificationType
== EE_NOTIFY_PROCESSNOTIFICATIONS
910 && !pEditEngine
->IsUpdateLayout())
912 // tdf#143088 an UpdateMode of false will just to on to cause
913 // AccessibleTextHelper_Impl::GetTextForwarder to throw an
914 // exception as a Frozen EditEngine is considered Invalid so return
920 ::std::unique_ptr
<SfxHint
> aHint
= SvxEditSourceHelper::EENotification2Hint(&rNotify
);
922 m_rEditSource
.GetBroadcaster().Broadcast(*aHint
);
925 sal_Int32
WeldTextForwarder::GetParagraphCount() const
927 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
928 return pEditEngine
? pEditEngine
->GetParagraphCount() : 0;
931 sal_Int32
WeldTextForwarder::GetTextLen(sal_Int32 nParagraph
) const
933 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
934 return pEditEngine
? pEditEngine
->GetTextLen(nParagraph
) : 0;
937 OUString
WeldTextForwarder::GetText(const ESelection
& rSel
) const
939 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
942 aRet
= pEditEngine
->GetText(rSel
);
943 return convertLineEnd(aRet
, GetSystemLineEnd());
946 SfxItemSet
WeldTextForwarder::GetAttribs(const ESelection
& rSel
,
947 EditEngineAttribs nOnlyHardAttrib
) const
949 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
950 assert(pEditEngine
&& "EditEngine missing");
951 if (rSel
.nStartPara
== rSel
.nEndPara
)
953 GetAttribsFlags nFlags
= GetAttribsFlags::NONE
;
954 switch (nOnlyHardAttrib
)
956 case EditEngineAttribs::All
:
957 nFlags
= GetAttribsFlags::ALL
;
959 case EditEngineAttribs::OnlyHard
:
960 nFlags
= GetAttribsFlags::CHARATTRIBS
;
963 SAL_WARN("svx", "unknown flags for WeldTextForwarder::GetAttribs");
966 return pEditEngine
->GetAttribs(rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
970 return pEditEngine
->GetAttribs(rSel
, nOnlyHardAttrib
);
974 SfxItemSet
WeldTextForwarder::GetParaAttribs(sal_Int32 nPara
) const
976 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
977 assert(pEditEngine
&& "EditEngine missing");
979 SfxItemSet
aSet(pEditEngine
->GetParaAttribs(nPara
));
981 sal_uInt16 nWhich
= EE_PARA_START
;
982 while (nWhich
<= EE_PARA_END
)
984 if (aSet
.GetItemState(nWhich
) != SfxItemState::SET
)
986 if (pEditEngine
->HasParaAttrib(nPara
, nWhich
))
987 aSet
.Put(pEditEngine
->GetParaAttrib(nPara
, nWhich
));
995 void WeldTextForwarder::SetParaAttribs(sal_Int32 nPara
, const SfxItemSet
& rSet
)
997 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
999 pEditEngine
->SetParaAttribs(nPara
, rSet
);
1002 SfxItemPool
* WeldTextForwarder::GetPool() const
1004 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1005 return pEditEngine
? pEditEngine
->GetEmptyItemSet().GetPool() : nullptr;
1008 void WeldTextForwarder::RemoveAttribs(const ESelection
& rSelection
)
1010 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1012 pEditEngine
->RemoveAttribs(rSelection
, false /*bRemoveParaAttribs*/, 0);
1015 void WeldTextForwarder::GetPortions(sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
1017 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1019 pEditEngine
->GetPortions(nPara
, rList
);
1022 void WeldTextForwarder::QuickInsertText(const OUString
& rText
, const ESelection
& rSel
)
1024 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1026 pEditEngine
->QuickInsertText(rText
, rSel
);
1029 void WeldTextForwarder::QuickInsertLineBreak(const ESelection
& rSel
)
1031 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1033 pEditEngine
->QuickInsertLineBreak(rSel
);
1036 void WeldTextForwarder::QuickInsertField(const SvxFieldItem
& rFld
, const ESelection
& rSel
)
1038 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1040 pEditEngine
->QuickInsertField(rFld
, rSel
);
1043 void WeldTextForwarder::QuickSetAttribs(const SfxItemSet
& rSet
, const ESelection
& rSel
)
1045 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1047 pEditEngine
->QuickSetAttribs(rSet
, rSel
);
1050 bool WeldTextForwarder::IsValid() const
1052 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1053 // cannot reliably query EditEngine state
1054 // while in the middle of an update
1055 return pEditEngine
&& pEditEngine
->IsUpdateLayout();
1058 OUString
WeldTextForwarder::CalcFieldValue(const SvxFieldItem
& rField
, sal_Int32 nPara
,
1059 sal_Int32 nPos
, std::optional
<Color
>& rpTxtColor
,
1060 std::optional
<Color
>& rpFldColor
,
1061 std::optional
<FontLineStyle
>& rpFldLineStyle
)
1063 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1064 return pEditEngine
? pEditEngine
->CalcFieldValue(rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
,
1069 void WeldTextForwarder::FieldClicked(const SvxFieldItem
&) {}
1071 static SfxItemState
GetSvxEditEngineItemState(EditEngine
const& rEditEngine
, const ESelection
& rSel
,
1074 std::vector
<EECharAttrib
> aAttribs
;
1076 const SfxPoolItem
* pLastItem
= nullptr;
1078 SfxItemState eState
= SfxItemState::DEFAULT
;
1080 // check all paragraphs inside the selection
1081 for (sal_Int32 nPara
= rSel
.nStartPara
; nPara
<= rSel
.nEndPara
; nPara
++)
1083 SfxItemState eParaState
= SfxItemState::DEFAULT
;
1085 // calculate start and endpos for this paragraph
1087 if (rSel
.nStartPara
== nPara
)
1088 nPos
= rSel
.nStartPos
;
1090 sal_Int32 nEndPos
= rSel
.nEndPos
;
1091 if (rSel
.nEndPara
!= nPara
)
1092 nEndPos
= rEditEngine
.GetTextLen(nPara
);
1094 // get list of char attribs
1095 rEditEngine
.GetCharAttribs(nPara
, aAttribs
);
1097 bool bEmpty
= true; // we found no item inside the selection of this paragraph
1098 bool bGaps
= false; // we found items but there are gaps between them
1099 sal_Int32 nLastEnd
= nPos
;
1101 const SfxPoolItem
* pParaItem
= nullptr;
1103 for (const auto& rAttrib
: aAttribs
)
1105 OSL_ENSURE(rAttrib
.pAttr
, "GetCharAttribs gives corrupt data");
1107 const bool bEmptyPortion
= (rAttrib
.nStart
== rAttrib
.nEnd
);
1108 if ((!bEmptyPortion
&& (rAttrib
.nStart
>= nEndPos
))
1109 || (bEmptyPortion
&& (rAttrib
.nStart
> nEndPos
)))
1110 break; // break if we are already behind our selection
1112 if ((!bEmptyPortion
&& (rAttrib
.nEnd
<= nPos
))
1113 || (bEmptyPortion
&& (rAttrib
.nEnd
< nPos
)))
1114 continue; // or if the attribute ends before our selection
1116 if (rAttrib
.pAttr
->Which() != nWhich
)
1117 continue; // skip if is not the searched item
1119 // if we already found an item
1122 // ... and its different to this one than the state is don't care
1123 if (*pParaItem
!= *(rAttrib
.pAttr
))
1124 return SfxItemState::DONTCARE
;
1128 pParaItem
= rAttrib
.pAttr
;
1134 if (!bGaps
&& rAttrib
.nStart
> nLastEnd
)
1137 nLastEnd
= rAttrib
.nEnd
;
1140 if (!bEmpty
&& !bGaps
&& nLastEnd
< (nEndPos
- 1))
1143 eParaState
= SfxItemState::DEFAULT
;
1145 eParaState
= SfxItemState::DONTCARE
;
1147 eParaState
= SfxItemState::SET
;
1149 // if we already found an item check if we found the same
1152 if ((pParaItem
== nullptr) || (*pLastItem
!= *pParaItem
))
1153 return SfxItemState::DONTCARE
;
1157 pLastItem
= pParaItem
;
1158 eState
= eParaState
;
1165 SfxItemState
WeldTextForwarder::GetItemState(const ESelection
& rSel
, sal_uInt16 nWhich
) const
1167 SfxItemState nState
= SfxItemState::DISABLED
;
1168 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1170 nState
= GetSvxEditEngineItemState(*pEditEngine
, rSel
, nWhich
);
1174 SfxItemState
WeldTextForwarder::GetItemState(sal_Int32 nPara
, sal_uInt16 nWhich
) const
1176 SfxItemState nState
= SfxItemState::DISABLED
;
1177 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1180 const SfxItemSet
& rSet
= pEditEngine
->GetParaAttribs(nPara
);
1181 nState
= rSet
.GetItemState(nWhich
);
1186 LanguageType
WeldTextForwarder::GetLanguage(sal_Int32 nPara
, sal_Int32 nIndex
) const
1188 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1189 return pEditEngine
? pEditEngine
->GetLanguage(nPara
, nIndex
).nLang
: LANGUAGE_NONE
;
1192 sal_Int32
WeldTextForwarder::GetFieldCount(sal_Int32 nPara
) const
1194 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1195 return pEditEngine
? pEditEngine
->GetFieldCount(nPara
) : 0;
1198 EFieldInfo
WeldTextForwarder::GetFieldInfo(sal_Int32 nPara
, sal_uInt16 nField
) const
1200 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1201 return pEditEngine
? pEditEngine
->GetFieldInfo(nPara
, nField
) : EFieldInfo();
1204 EBulletInfo
WeldTextForwarder::GetBulletInfo(sal_Int32
/*nPara*/) const { return EBulletInfo(); }
1206 tools::Rectangle
WeldTextForwarder::GetCharBounds(sal_Int32 nPara
, sal_Int32 nIndex
) const
1208 tools::Rectangle
aRect(0, 0, 0, 0);
1209 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1213 // Handle virtual position one-past-the end of the string
1214 if (nIndex
>= pEditEngine
->GetTextLen(nPara
))
1217 aRect
= pEditEngine
->GetCharacterBounds(EPosition(nPara
, nIndex
- 1));
1219 aRect
.Move(aRect
.Right() - aRect
.Left(), 0);
1220 aRect
.SetSize(Size(1, pEditEngine
->GetTextHeight()));
1224 aRect
= pEditEngine
->GetCharacterBounds(EPosition(nPara
, nIndex
));
1230 tools::Rectangle
WeldTextForwarder::GetParaBounds(sal_Int32 nPara
) const
1232 tools::Rectangle
aRect(0, 0, 0, 0);
1233 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1237 const Point aPnt
= pEditEngine
->GetDocPosTopLeft(nPara
);
1238 const sal_Int32 nWidth
= pEditEngine
->CalcTextWidth();
1239 const sal_Int32 nHeight
= pEditEngine
->GetTextHeight(nPara
);
1240 aRect
= tools::Rectangle(aPnt
.X(), aPnt
.Y(), aPnt
.X() + nWidth
, aPnt
.Y() + nHeight
);
1246 MapMode
WeldTextForwarder::GetMapMode() const
1248 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1249 return pEditEngine
? pEditEngine
->GetRefMapMode() : MapMode(MapUnit::Map100thMM
);
1252 OutputDevice
* WeldTextForwarder::GetRefDevice() const
1254 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1255 return pEditEngine
? pEditEngine
->GetRefDevice() : nullptr;
1258 bool WeldTextForwarder::GetIndexAtPoint(const Point
& rPos
, sal_Int32
& nPara
,
1259 sal_Int32
& nIndex
) const
1262 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1265 EPosition aDocPos
= pEditEngine
->FindDocPosition(rPos
);
1266 nPara
= aDocPos
.nPara
;
1267 nIndex
= aDocPos
.nIndex
;
1273 bool WeldTextForwarder::GetWordIndices(sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
,
1274 sal_Int32
& nEnd
) const
1277 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1280 ESelection aRes
= pEditEngine
->GetWord(ESelection(nPara
, nIndex
, nPara
, nIndex
),
1281 css::i18n::WordType::DICTIONARY_WORD
);
1283 if (aRes
.nStartPara
== nPara
&& aRes
.nStartPara
== aRes
.nEndPara
)
1285 nStart
= aRes
.nStartPos
;
1286 nEnd
= aRes
.nEndPos
;
1295 bool WeldTextForwarder::GetAttributeRun(sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
,
1296 sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
) const
1298 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1301 SvxEditSourceHelper::GetAttributeRun(nStartIndex
, nEndIndex
, *pEditEngine
, nPara
, nIndex
,
1306 sal_Int32
WeldTextForwarder::GetLineCount(sal_Int32 nPara
) const
1308 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1309 return pEditEngine
? pEditEngine
->GetLineCount(nPara
) : 0;
1312 sal_Int32
WeldTextForwarder::GetLineLen(sal_Int32 nPara
, sal_Int32 nLine
) const
1314 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1315 return pEditEngine
? pEditEngine
->GetLineLen(nPara
, nLine
) : 0;
1318 void WeldTextForwarder::GetLineBoundaries(/*out*/ sal_Int32
& rStart
, /*out*/ sal_Int32
& rEnd
,
1319 sal_Int32 nPara
, sal_Int32 nLine
) const
1321 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1323 pEditEngine
->GetLineBoundaries(rStart
, rEnd
, nPara
, nLine
);
1328 sal_Int32
WeldTextForwarder::GetLineNumberAtIndex(sal_Int32 nPara
, sal_Int32 nIndex
) const
1330 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1331 return pEditEngine
? pEditEngine
->GetLineNumberAtIndex(nPara
, nIndex
) : 0;
1334 bool WeldTextForwarder::QuickFormatDoc(bool /*bFull*/)
1337 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1340 pEditEngine
->QuickFormatDoc();
1346 sal_Int16
WeldTextForwarder::GetDepth(sal_Int32
/*nPara*/) const
1348 // math has no outliner...
1352 bool WeldTextForwarder::SetDepth(sal_Int32
/*nPara*/, sal_Int16 nNewDepth
)
1354 // math has no outliner...
1355 return -1 == nNewDepth
; // is it the value from 'GetDepth' ?
1358 bool WeldTextForwarder::Delete(const ESelection
& rSelection
)
1361 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1364 pEditEngine
->QuickDelete(rSelection
);
1365 pEditEngine
->QuickFormatDoc();
1371 bool WeldTextForwarder::InsertText(const OUString
& rStr
, const ESelection
& rSelection
)
1374 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1377 pEditEngine
->QuickInsertText(rStr
, rSelection
);
1378 pEditEngine
->QuickFormatDoc();
1384 const SfxItemSet
* WeldTextForwarder::GetEmptyItemSetPtr()
1386 const SfxItemSet
* pItemSet
= nullptr;
1387 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1390 pItemSet
= &pEditEngine
->GetEmptyItemSet();
1395 void WeldTextForwarder::AppendParagraph()
1397 // append an empty paragraph
1398 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1401 sal_Int32 nParaCount
= pEditEngine
->GetParagraphCount();
1402 pEditEngine
->InsertParagraph(nParaCount
, OUString());
1406 sal_Int32
WeldTextForwarder::AppendTextPortion(sal_Int32 nPara
, const OUString
& rText
,
1407 const SfxItemSet
& rSet
)
1409 sal_uInt16 nRes
= 0;
1410 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1411 if (pEditEngine
&& nPara
< pEditEngine
->GetParagraphCount())
1414 ESelection
aSel(nPara
, pEditEngine
->GetTextLen(nPara
));
1415 pEditEngine
->QuickInsertText(rText
, aSel
);
1417 // set attributes for new appended text
1418 nRes
= aSel
.nEndPos
= pEditEngine
->GetTextLen(nPara
);
1419 pEditEngine
->QuickSetAttribs(rSet
, aSel
);
1424 void WeldTextForwarder::CopyText(const SvxTextForwarder
& rSource
)
1426 const WeldTextForwarder
* pSourceForwarder
= dynamic_cast<const WeldTextForwarder
*>(&rSource
);
1427 if (!pSourceForwarder
)
1429 EditEngine
* pSourceEditEngine
= pSourceForwarder
->m_rEditAcc
.GetEditEngine();
1430 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1431 if (pEditEngine
&& pSourceEditEngine
)
1433 std::unique_ptr
<EditTextObject
> pNewTextObject
= pSourceEditEngine
->CreateTextObject();
1434 pEditEngine
->SetText(*pNewTextObject
);
1438 WeldEditViewForwarder::WeldEditViewForwarder(WeldEditAccessible
& rAcc
)
1443 bool WeldEditViewForwarder::IsValid() const { return m_rEditAcc
.GetEditView() != nullptr; }
1445 Point
WeldEditViewForwarder::LogicToPixel(const Point
& rPoint
, const MapMode
& rMapMode
) const
1447 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1450 OutputDevice
& rOutDev
= pEditView
->GetOutputDevice();
1451 MapMode
aMapMode(rOutDev
.GetMapMode());
1452 Point
aPoint(OutputDevice::LogicToLogic(rPoint
, rMapMode
, MapMode(aMapMode
.GetMapUnit())));
1453 aMapMode
.SetOrigin(Point());
1454 return rOutDev
.LogicToPixel(aPoint
, aMapMode
);
1457 Point
WeldEditViewForwarder::PixelToLogic(const Point
& rPoint
, const MapMode
& rMapMode
) const
1459 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1462 OutputDevice
& rOutDev
= pEditView
->GetOutputDevice();
1463 MapMode
aMapMode(rOutDev
.GetMapMode());
1464 aMapMode
.SetOrigin(Point());
1465 Point
aPoint(rOutDev
.PixelToLogic(rPoint
, aMapMode
));
1466 return OutputDevice::LogicToLogic(aPoint
, MapMode(aMapMode
.GetMapUnit()), rMapMode
);
1469 bool WeldEditViewForwarder::GetSelection(ESelection
& rSelection
) const
1472 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1475 rSelection
= pEditView
->GetSelection();
1481 bool WeldEditViewForwarder::SetSelection(const ESelection
& rSelection
)
1484 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1487 pEditView
->SetSelection(rSelection
);
1493 bool WeldEditViewForwarder::Copy()
1496 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1505 bool WeldEditViewForwarder::Cut()
1508 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1517 bool WeldEditViewForwarder::Paste()
1520 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1529 void WeldEditView::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
1531 Size
aSize(pDrawingArea
->get_size_request());
1532 if (aSize
.Width() == -1)
1533 aSize
.setWidth(500);
1534 if (aSize
.Height() == -1)
1535 aSize
.setHeight(100);
1536 pDrawingArea
->set_size_request(aSize
.Width(), aSize
.Height());
1538 SetOutputSizePixel(aSize
);
1540 weld::CustomWidgetController::SetDrawingArea(pDrawingArea
);
1544 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1545 Color aBgColor
= rStyleSettings
.GetWindowColor();
1547 OutputDevice
& rDevice
= pDrawingArea
->get_ref_device();
1549 rDevice
.SetMapMode(MapMode(MapUnit::MapTwip
));
1550 rDevice
.SetBackground(aBgColor
);
1552 Size
aOutputSize(rDevice
.PixelToLogic(aSize
));
1555 m_xEditEngine
->SetPaperSize(aOutputSize
);
1556 m_xEditEngine
->SetRefDevice(&rDevice
);
1558 m_xEditEngine
->SetControlWord(m_xEditEngine
->GetControlWord() | EEControlBits::MARKFIELDS
);
1560 m_xEditView
.reset(new EditView(m_xEditEngine
.get(), nullptr));
1561 m_xEditView
->setEditViewCallbacks(this);
1562 m_xEditView
->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize
));
1564 m_xEditView
->SetBackgroundColor(aBgColor
);
1565 m_xEditEngine
->SetBackgroundColor(aBgColor
);
1566 m_xEditEngine
->InsertView(m_xEditView
.get());
1568 pDrawingArea
->set_cursor(PointerStyle::Text
);
1570 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1575 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1576 void WeldEditView::InitAccessible()
1578 if (m_xAccessible
.is())
1579 m_xAccessible
->Init(GetEditEngine(), GetEditView());
1583 int WeldEditView::GetSurroundingText(OUString
& rSurrounding
)
1585 EditView
* pEditView
= GetEditView();
1588 rSurrounding
= pEditView
->GetSurroundingText();
1589 return pEditView
->GetSurroundingTextSelection().Min();
1592 bool WeldEditView::DeleteSurroundingText(const Selection
& rRange
)
1594 EditView
* pEditView
= GetEditView();
1597 return pEditView
->DeleteSurroundingText(rRange
);
1600 void WeldEditView::GetFocus()
1602 EditView
* pEditView
= GetEditView();
1605 pEditView
->ShowCursor(false);
1606 Invalidate(); // redraw with cursor
1609 weld::CustomWidgetController::GetFocus();
1611 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1612 if (m_xAccessible
.is())
1614 // Note: will implicitly send the AccessibleStateType::FOCUSED event
1615 ::accessibility::AccessibleTextHelper
* pHelper
= m_xAccessible
->GetTextHelper();
1617 pHelper
->SetFocus();
1622 void WeldEditView::LoseFocus()
1624 weld::CustomWidgetController::LoseFocus();
1625 Invalidate(); // redraw without cursor
1627 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1628 if (m_xAccessible
.is())
1630 // Note: will implicitly send the AccessibleStateType::FOCUSED event
1631 ::accessibility::AccessibleTextHelper
* pHelper
= m_xAccessible
->GetTextHelper();
1633 pHelper
->SetFocus(false);
1638 bool WeldEditView::CanFocus() const { return true; }
1640 css::uno::Reference
<css::datatransfer::dnd::XDropTarget
> WeldEditView::GetDropTarget()
1643 m_xDropTarget
= weld::CustomWidgetController::GetDropTarget();
1644 return m_xDropTarget
;
1647 css::uno::Reference
<css::datatransfer::clipboard::XClipboard
> WeldEditView::GetClipboard() const
1649 return weld::CustomWidgetController::GetClipboard();
1654 class WeldEditViewUIObject final
: public DrawingAreaUIObject
1657 WeldEditView
* mpEditView
;
1660 WeldEditViewUIObject(const VclPtr
<vcl::Window
>& rDrawingArea
)
1661 : DrawingAreaUIObject(rDrawingArea
)
1662 , mpEditView(static_cast<WeldEditView
*>(mpController
))
1666 static std::unique_ptr
<UIObject
> create(vcl::Window
* pWindow
)
1668 return std::unique_ptr
<UIObject
>(new WeldEditViewUIObject(pWindow
));
1671 virtual StringMap
get_state() override
1673 StringMap aMap
= WindowUIObject::get_state();
1674 aMap
["Text"] = mpEditView
->GetText();
1679 virtual OUString
get_name() const override
{ return "WeldEditViewUIObject"; }
1683 FactoryFunction
WeldEditView::GetUITestFactory() const { return WeldEditViewUIObject::create
; }
1685 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */