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/XAccessibleContext2.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
->SetUserDefaultItem(SvxFontItem(aAppFont
.GetFamilyType(), aAppFont
.GetFamilyName(),
116 u
""_ustr
, PITCH_DONTKNOW
, RTL_TEXTENCODING_DONTKNOW
,
118 pItemPool
->SetUserDefaultItem(SvxFontItem(aAppFont
.GetFamilyType(), aAppFont
.GetFamilyName(),
119 u
""_ustr
, PITCH_DONTKNOW
, RTL_TEXTENCODING_DONTKNOW
,
120 EE_CHAR_FONTINFO_CJK
));
121 pItemPool
->SetUserDefaultItem(SvxFontItem(aAppFont
.GetFamilyType(), aAppFont
.GetFamilyName(),
122 u
""_ustr
, PITCH_DONTKNOW
, RTL_TEXTENCODING_DONTKNOW
,
123 EE_CHAR_FONTINFO_CTL
));
125 pItemPool
->SetUserDefaultItem(
126 SvxFontHeightItem(aAppFont
.GetFontHeight() * 20, 100, EE_CHAR_FONTHEIGHT
));
127 pItemPool
->SetUserDefaultItem(
128 SvxFontHeightItem(aAppFont
.GetFontHeight() * 20, 100, EE_CHAR_FONTHEIGHT_CJK
));
129 pItemPool
->SetUserDefaultItem(
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 if (GetEditEngine()->GetParagraphCount())
292 pEditView
->SetSelection(ESelection::All());
304 bool WeldEditView::Command(const CommandEvent
& rCEvt
)
306 EditView
* pEditView
= GetEditView();
309 return pEditView
->Command(rCEvt
);
312 Point
WeldEditView::EditViewPointerPosPixel() const
314 return GetDrawingArea()->get_pointer_position();
317 class WeldEditAccessible
;
321 class WeldViewForwarder
: public SvxViewForwarder
323 WeldEditAccessible
& m_rEditAcc
;
325 WeldViewForwarder(const WeldViewForwarder
&) = delete;
326 WeldViewForwarder
& operator=(const WeldViewForwarder
&) = delete;
329 explicit WeldViewForwarder(WeldEditAccessible
& rAcc
)
334 virtual bool IsValid() const override
;
335 virtual Point
LogicToPixel(const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
336 virtual Point
PixelToLogic(const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
340 class WeldEditAccessible
;
344 class WeldEditSource
;
346 /* analog to SvxEditEngineForwarder */
347 class WeldTextForwarder
: public SvxTextForwarder
349 WeldEditAccessible
& m_rEditAcc
;
350 WeldEditSource
& m_rEditSource
;
352 DECL_LINK(NotifyHdl
, EENotify
&, void);
354 WeldTextForwarder(const WeldTextForwarder
&) = delete;
355 WeldTextForwarder
& operator=(const WeldTextForwarder
&) = delete;
358 WeldTextForwarder(WeldEditAccessible
& rAcc
, WeldEditSource
& rSource
);
359 virtual ~WeldTextForwarder() override
;
361 virtual sal_Int32
GetParagraphCount() const override
;
362 virtual sal_Int32
GetTextLen(sal_Int32 nParagraph
) const override
;
363 virtual OUString
GetText(const ESelection
& rSel
) const override
;
364 virtual SfxItemSet
GetAttribs(const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
365 = EditEngineAttribs::All
) const override
;
366 virtual SfxItemSet
GetParaAttribs(sal_Int32 nPara
) const override
;
367 virtual void SetParaAttribs(sal_Int32 nPara
, const SfxItemSet
& rSet
) override
;
368 virtual void RemoveAttribs(const ESelection
& rSelection
) override
;
369 virtual void GetPortions(sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const override
;
371 virtual OUString
GetStyleSheet(sal_Int32 nPara
) const override
;
372 virtual void SetStyleSheet(sal_Int32 nPara
, const OUString
& rStyleName
) 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 std::vector
<EFieldInfo
> GetFieldInfo(sal_Int32 nPara
) const override
;
393 virtual EBulletInfo
GetBulletInfo(sal_Int32 nPara
) const override
;
394 virtual tools::Rectangle
GetCharBounds(sal_Int32 nPara
, sal_Int32 nIndex
) const override
;
395 virtual tools::Rectangle
GetParaBounds(sal_Int32 nPara
) const override
;
396 virtual MapMode
GetMapMode() const override
;
397 virtual OutputDevice
* GetRefDevice() const override
;
398 virtual bool GetIndexAtPoint(const Point
&, sal_Int32
& nPara
, sal_Int32
& nIndex
) const override
;
399 virtual bool GetWordIndices(sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
,
400 sal_Int32
& nEnd
) const override
;
401 virtual bool GetAttributeRun(sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
,
402 sal_Int32 nIndex
, bool bInCell
= false) const override
;
403 virtual sal_Int32
GetLineCount(sal_Int32 nPara
) const override
;
404 virtual sal_Int32
GetLineLen(sal_Int32 nPara
, sal_Int32 nLine
) const override
;
405 virtual void GetLineBoundaries(/*out*/ sal_Int32
& rStart
, /*out*/ sal_Int32
& rEnd
,
406 sal_Int32 nParagraph
, sal_Int32 nLine
) const override
;
407 virtual sal_Int32
GetLineNumberAtIndex(sal_Int32 nPara
, sal_Int32 nLine
) const override
;
408 virtual bool Delete(const ESelection
&) override
;
409 virtual bool InsertText(const OUString
&, const ESelection
&) override
;
410 virtual bool QuickFormatDoc(bool bFull
= false) override
;
412 virtual bool SupportsOutlineDepth() const override
{ return false; };
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::XAccessibleContext2
,
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 AbsoluteScreenPixelPoint 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
getAccessibleId() override
755 SolarMutexGuard aGuard
;
758 return m_pController
->GetAccessibleId();
763 virtual OUString SAL_CALL
getAccessibleName() override
765 SolarMutexGuard aGuard
;
771 aRet
= m_pController
->GetAccessibleName();
777 virtual css::uno::Reference
<css::accessibility::XAccessibleRelationSet
>
778 SAL_CALL
getAccessibleRelationSet() override
780 SolarMutexGuard aGuard
;
782 throw css::uno::RuntimeException();
784 return m_pController
->GetDrawingArea()->get_accessible_relation_set();
787 virtual sal_Int64 SAL_CALL
getAccessibleStateSet() override
789 SolarMutexGuard aGuard
;
790 sal_Int64 nStateSet
= 0;
792 if (!m_pController
|| !m_xTextHelper
)
793 nStateSet
|= css::accessibility::AccessibleStateType::DEFUNC
;
796 nStateSet
|= css::accessibility::AccessibleStateType::MULTI_LINE
;
797 nStateSet
|= css::accessibility::AccessibleStateType::ENABLED
;
798 nStateSet
|= css::accessibility::AccessibleStateType::EDITABLE
;
799 nStateSet
|= css::accessibility::AccessibleStateType::FOCUSABLE
;
800 nStateSet
|= css::accessibility::AccessibleStateType::SELECTABLE
;
801 if (m_pController
->HasFocus())
802 nStateSet
|= css::accessibility::AccessibleStateType::FOCUSED
;
803 if (m_pController
->IsActive())
804 nStateSet
|= css::accessibility::AccessibleStateType::ACTIVE
;
805 if (m_pController
->IsVisible())
806 nStateSet
|= css::accessibility::AccessibleStateType::SHOWING
;
807 if (m_pController
->IsReallyVisible())
808 nStateSet
|= css::accessibility::AccessibleStateType::VISIBLE
;
809 if (COL_TRANSPARENT
!= m_pEditEngine
->GetBackgroundColor())
810 nStateSet
|= css::accessibility::AccessibleStateType::OPAQUE
;
816 virtual css::lang::Locale SAL_CALL
getLocale() override
818 SolarMutexGuard aGuard
;
819 return LanguageTag(m_pEditEngine
->GetDefaultLanguage()).getLocale();
822 // XAccessibleEventBroadcaster
823 virtual void SAL_CALL
addAccessibleEventListener(
824 const css::uno::Reference
<css::accessibility::XAccessibleEventListener
>& rListener
) override
826 if (!m_xTextHelper
) // not disposing (about to destroy view shell)
828 m_xTextHelper
->AddEventListener(rListener
);
831 virtual void SAL_CALL
removeAccessibleEventListener(
832 const css::uno::Reference
<css::accessibility::XAccessibleEventListener
>& rListener
) override
834 if (!m_xTextHelper
) // not disposing (about to destroy view shell)
836 m_xTextHelper
->RemoveEventListener(rListener
);
839 virtual OUString SAL_CALL
getImplementationName() override
841 return u
"WeldEditAccessible"_ustr
;
844 virtual sal_Bool SAL_CALL
supportsService(const OUString
& rServiceName
) override
846 return cppu::supportsService(this, rServiceName
);
849 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
851 return { u
"css::accessibility::Accessible"_ustr
,
852 u
"css::accessibility::AccessibleComponent"_ustr
,
853 u
"css::accessibility::AccessibleContext"_ustr
};
857 css::uno::Reference
<css::accessibility::XAccessible
> WeldEditView::CreateAccessible()
859 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
860 if (!m_xAccessible
.is())
861 m_xAccessible
.set(new WeldEditAccessible(this));
863 return m_xAccessible
;
866 WeldEditView::~WeldEditView()
868 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
869 if (m_xAccessible
.is())
871 m_xAccessible
->ClearWin(); // make Accessible nonfunctional
872 m_xAccessible
.clear();
877 bool WeldViewForwarder::IsValid() const { return m_rEditAcc
.GetEditView() != nullptr; }
879 Point
WeldViewForwarder::LogicToPixel(const Point
& rPoint
, const MapMode
& rMapMode
) const
881 EditView
* pEditView
= m_rEditAcc
.GetEditView();
884 OutputDevice
& rOutDev
= pEditView
->GetOutputDevice();
885 MapMode
aMapMode(rOutDev
.GetMapMode());
886 Point
aPoint(OutputDevice::LogicToLogic(rPoint
, rMapMode
, MapMode(aMapMode
.GetMapUnit())));
887 aMapMode
.SetOrigin(Point());
888 return rOutDev
.LogicToPixel(aPoint
, aMapMode
);
891 Point
WeldViewForwarder::PixelToLogic(const Point
& rPoint
, const MapMode
& rMapMode
) const
893 EditView
* pEditView
= m_rEditAcc
.GetEditView();
896 OutputDevice
& rOutDev
= pEditView
->GetOutputDevice();
897 MapMode
aMapMode(rOutDev
.GetMapMode());
898 aMapMode
.SetOrigin(Point());
899 Point
aPoint(rOutDev
.PixelToLogic(rPoint
, aMapMode
));
900 return OutputDevice::LogicToLogic(aPoint
, MapMode(aMapMode
.GetMapUnit()), rMapMode
);
903 WeldTextForwarder::WeldTextForwarder(WeldEditAccessible
& rAcc
, WeldEditSource
& rSource
)
905 , m_rEditSource(rSource
)
907 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
909 pEditEngine
->SetNotifyHdl(LINK(this, WeldTextForwarder
, NotifyHdl
));
912 WeldTextForwarder::~WeldTextForwarder()
914 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
916 pEditEngine
->SetNotifyHdl(Link
<EENotify
&, void>());
919 IMPL_LINK(WeldTextForwarder
, NotifyHdl
, EENotify
&, rNotify
, void)
921 if (EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine())
923 if (rNotify
.eNotificationType
== EE_NOTIFY_PROCESSNOTIFICATIONS
924 && !pEditEngine
->IsUpdateLayout())
926 // tdf#143088 an UpdateMode of false will just to on to cause
927 // AccessibleTextHelper_Impl::GetTextForwarder to throw an
928 // exception as a Frozen EditEngine is considered Invalid so return
934 ::std::unique_ptr
<SfxHint
> aHint
= SvxEditSourceHelper::EENotification2Hint(&rNotify
);
936 m_rEditSource
.GetBroadcaster().Broadcast(*aHint
);
939 sal_Int32
WeldTextForwarder::GetParagraphCount() const
941 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
942 return pEditEngine
? pEditEngine
->GetParagraphCount() : 0;
945 sal_Int32
WeldTextForwarder::GetTextLen(sal_Int32 nParagraph
) const
947 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
948 return pEditEngine
? pEditEngine
->GetTextLen(nParagraph
) : 0;
951 OUString
WeldTextForwarder::GetText(const ESelection
& rSel
) const
953 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
956 aRet
= pEditEngine
->GetText(rSel
);
957 return convertLineEnd(aRet
, GetSystemLineEnd());
960 SfxItemSet
WeldTextForwarder::GetAttribs(const ESelection
& rSel
,
961 EditEngineAttribs nOnlyHardAttrib
) const
963 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
964 assert(pEditEngine
&& "EditEngine missing");
965 if (rSel
.start
.nPara
== rSel
.end
.nPara
)
967 GetAttribsFlags nFlags
= GetAttribsFlags::NONE
;
968 switch (nOnlyHardAttrib
)
970 case EditEngineAttribs::All
:
971 nFlags
= GetAttribsFlags::ALL
;
973 case EditEngineAttribs::OnlyHard
:
974 nFlags
= GetAttribsFlags::CHARATTRIBS
;
977 SAL_WARN("svx", "unknown flags for WeldTextForwarder::GetAttribs");
980 return pEditEngine
->GetAttribs(rSel
.start
.nPara
, rSel
.start
.nIndex
, rSel
.end
.nIndex
,
985 return pEditEngine
->GetAttribs(rSel
, nOnlyHardAttrib
);
989 SfxItemSet
WeldTextForwarder::GetParaAttribs(sal_Int32 nPara
) const
991 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
992 assert(pEditEngine
&& "EditEngine missing");
994 SfxItemSet
aSet(pEditEngine
->GetParaAttribs(nPara
));
996 sal_uInt16 nWhich
= EE_PARA_START
;
997 while (nWhich
<= EE_PARA_END
)
999 if (aSet
.GetItemState(nWhich
) != SfxItemState::SET
)
1001 if (pEditEngine
->HasParaAttrib(nPara
, nWhich
))
1002 aSet
.Put(pEditEngine
->GetParaAttrib(nPara
, nWhich
));
1010 void WeldTextForwarder::SetParaAttribs(sal_Int32 nPara
, const SfxItemSet
& rSet
)
1012 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1014 pEditEngine
->SetParaAttribs(nPara
, rSet
);
1017 SfxItemPool
* WeldTextForwarder::GetPool() const
1019 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1020 return pEditEngine
? pEditEngine
->GetEmptyItemSet().GetPool() : nullptr;
1023 void WeldTextForwarder::RemoveAttribs(const ESelection
& rSelection
)
1025 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1027 pEditEngine
->RemoveAttribs(rSelection
, false /*bRemoveParaAttribs*/, 0);
1030 void WeldTextForwarder::GetPortions(sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
1032 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1034 pEditEngine
->GetPortions(nPara
, rList
);
1037 OUString
WeldTextForwarder::GetStyleSheet(sal_Int32 nPara
) const
1039 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1040 if (auto pStyle
= pEditEngine
? pEditEngine
->GetStyleSheet(nPara
) : nullptr)
1041 return pStyle
->GetName();
1045 void WeldTextForwarder::SetStyleSheet(sal_Int32 nPara
, const OUString
& rStyleName
)
1047 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1048 auto pStyleSheetPool
= pEditEngine
? pEditEngine
->GetStyleSheetPool() : nullptr;
1050 = pStyleSheetPool
? pStyleSheetPool
->Find(rStyleName
, SfxStyleFamily::Para
) : nullptr)
1051 pEditEngine
->SetStyleSheet(nPara
, static_cast<SfxStyleSheet
*>(pStyle
));
1054 void WeldTextForwarder::QuickInsertText(const OUString
& rText
, const ESelection
& rSel
)
1056 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1058 pEditEngine
->QuickInsertText(rText
, rSel
);
1061 void WeldTextForwarder::QuickInsertLineBreak(const ESelection
& rSel
)
1063 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1065 pEditEngine
->QuickInsertLineBreak(rSel
);
1068 void WeldTextForwarder::QuickInsertField(const SvxFieldItem
& rFld
, const ESelection
& rSel
)
1070 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1072 pEditEngine
->QuickInsertField(rFld
, rSel
);
1075 void WeldTextForwarder::QuickSetAttribs(const SfxItemSet
& rSet
, const ESelection
& rSel
)
1077 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1079 pEditEngine
->QuickSetAttribs(rSet
, rSel
);
1082 bool WeldTextForwarder::IsValid() const
1084 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1085 // cannot reliably query EditEngine state
1086 // while in the middle of an update
1087 return pEditEngine
&& pEditEngine
->IsUpdateLayout();
1090 OUString
WeldTextForwarder::CalcFieldValue(const SvxFieldItem
& rField
, sal_Int32 nPara
,
1091 sal_Int32 nPos
, std::optional
<Color
>& rpTxtColor
,
1092 std::optional
<Color
>& rpFldColor
,
1093 std::optional
<FontLineStyle
>& rpFldLineStyle
)
1095 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1096 return pEditEngine
? pEditEngine
->CalcFieldValue(rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
,
1101 void WeldTextForwarder::FieldClicked(const SvxFieldItem
&) {}
1103 static SfxItemState
GetSvxEditEngineItemState(EditEngine
const& rEditEngine
, const ESelection
& rSel
,
1106 std::vector
<EECharAttrib
> aAttribs
;
1108 const SfxPoolItem
* pLastItem
= nullptr;
1110 SfxItemState eState
= SfxItemState::DEFAULT
;
1112 // check all paragraphs inside the selection
1113 for (sal_Int32 nPara
= rSel
.start
.nPara
; nPara
<= rSel
.end
.nPara
; nPara
++)
1115 SfxItemState eParaState
= SfxItemState::DEFAULT
;
1117 // calculate start and endpos for this paragraph
1119 if (rSel
.start
.nPara
== nPara
)
1120 nPos
= rSel
.start
.nIndex
;
1122 sal_Int32 nEndPos
= rSel
.end
.nIndex
;
1123 if (rSel
.end
.nPara
!= nPara
)
1124 nEndPos
= rEditEngine
.GetTextLen(nPara
);
1126 // get list of char attribs
1127 rEditEngine
.GetCharAttribs(nPara
, aAttribs
);
1129 bool bEmpty
= true; // we found no item inside the selection of this paragraph
1130 bool bGaps
= false; // we found items but there are gaps between them
1131 sal_Int32 nLastEnd
= nPos
;
1133 const SfxPoolItem
* pParaItem
= nullptr;
1135 for (const auto& rAttrib
: aAttribs
)
1137 assert(rAttrib
.pAttr
&& "GetCharAttribs gives corrupt data");
1139 const bool bEmptyPortion
= (rAttrib
.nStart
== rAttrib
.nEnd
);
1140 if ((!bEmptyPortion
&& (rAttrib
.nStart
>= nEndPos
))
1141 || (bEmptyPortion
&& (rAttrib
.nStart
> nEndPos
)))
1142 break; // break if we are already behind our selection
1144 if ((!bEmptyPortion
&& (rAttrib
.nEnd
<= nPos
))
1145 || (bEmptyPortion
&& (rAttrib
.nEnd
< nPos
)))
1146 continue; // or if the attribute ends before our selection
1148 if (rAttrib
.pAttr
->Which() != nWhich
)
1149 continue; // skip if is not the searched item
1151 // if we already found an item
1154 // ... and its different to this one than the state is don't care
1155 if (*pParaItem
!= *(rAttrib
.pAttr
))
1156 return SfxItemState::INVALID
;
1160 pParaItem
= rAttrib
.pAttr
;
1166 if (!bGaps
&& rAttrib
.nStart
> nLastEnd
)
1169 nLastEnd
= rAttrib
.nEnd
;
1172 if (!bEmpty
&& !bGaps
&& nLastEnd
< (nEndPos
- 1))
1175 eParaState
= SfxItemState::DEFAULT
;
1177 eParaState
= SfxItemState::INVALID
;
1179 eParaState
= SfxItemState::SET
;
1181 // if we already found an item check if we found the same
1184 if ((pParaItem
== nullptr) || (*pLastItem
!= *pParaItem
))
1185 return SfxItemState::INVALID
;
1189 pLastItem
= pParaItem
;
1190 eState
= eParaState
;
1197 SfxItemState
WeldTextForwarder::GetItemState(const ESelection
& rSel
, sal_uInt16 nWhich
) const
1199 SfxItemState nState
= SfxItemState::DISABLED
;
1200 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1202 nState
= GetSvxEditEngineItemState(*pEditEngine
, rSel
, nWhich
);
1206 SfxItemState
WeldTextForwarder::GetItemState(sal_Int32 nPara
, sal_uInt16 nWhich
) const
1208 SfxItemState nState
= SfxItemState::DISABLED
;
1209 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1212 const SfxItemSet
& rSet
= pEditEngine
->GetParaAttribs(nPara
);
1213 nState
= rSet
.GetItemState(nWhich
);
1218 LanguageType
WeldTextForwarder::GetLanguage(sal_Int32 nPara
, sal_Int32 nIndex
) const
1220 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1221 return pEditEngine
? pEditEngine
->GetLanguage(nPara
, nIndex
).nLang
: LANGUAGE_NONE
;
1224 std::vector
<EFieldInfo
> WeldTextForwarder::GetFieldInfo(sal_Int32 nPara
) const
1226 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1229 return pEditEngine
->GetFieldInfo(nPara
);
1232 EBulletInfo
WeldTextForwarder::GetBulletInfo(sal_Int32
/*nPara*/) const { return EBulletInfo(); }
1234 tools::Rectangle
WeldTextForwarder::GetCharBounds(sal_Int32 nPara
, sal_Int32 nIndex
) const
1236 tools::Rectangle
aRect(0, 0, 0, 0);
1237 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1241 // Handle virtual position one-past-the end of the string
1242 if (nIndex
>= pEditEngine
->GetTextLen(nPara
))
1245 aRect
= pEditEngine
->GetCharacterBounds(EPaM(nPara
, nIndex
- 1));
1247 aRect
.Move(aRect
.Right() - aRect
.Left(), 0);
1248 aRect
.SetSize(Size(1, pEditEngine
->GetTextHeight()));
1252 aRect
= pEditEngine
->GetCharacterBounds(EPaM(nPara
, nIndex
));
1258 tools::Rectangle
WeldTextForwarder::GetParaBounds(sal_Int32 nPara
) const
1260 tools::Rectangle
aRect(0, 0, 0, 0);
1261 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1265 const Point aPnt
= pEditEngine
->GetDocPosTopLeft(nPara
);
1266 const sal_Int32 nWidth
= pEditEngine
->CalcTextWidth();
1267 const sal_Int32 nHeight
= pEditEngine
->GetTextHeight(nPara
);
1268 aRect
= tools::Rectangle(aPnt
.X(), aPnt
.Y(), aPnt
.X() + nWidth
, aPnt
.Y() + nHeight
);
1274 MapMode
WeldTextForwarder::GetMapMode() const
1276 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1277 return pEditEngine
? pEditEngine
->GetRefMapMode() : MapMode(MapUnit::Map100thMM
);
1280 OutputDevice
* WeldTextForwarder::GetRefDevice() const
1282 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1283 return pEditEngine
? pEditEngine
->GetRefDevice() : nullptr;
1286 bool WeldTextForwarder::GetIndexAtPoint(const Point
& rPos
, sal_Int32
& nPara
,
1287 sal_Int32
& nIndex
) const
1290 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1293 EPaM aDocPos
= pEditEngine
->FindDocPosition(rPos
);
1294 nPara
= aDocPos
.nPara
;
1295 nIndex
= aDocPos
.nIndex
;
1301 bool WeldTextForwarder::GetWordIndices(sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
,
1302 sal_Int32
& nEnd
) const
1305 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1309 = pEditEngine
->GetWord(ESelection(nPara
, nIndex
), css::i18n::WordType::DICTIONARY_WORD
);
1311 if (aRes
.start
.nPara
== nPara
&& aRes
.start
.nPara
== aRes
.end
.nPara
)
1313 nStart
= aRes
.start
.nIndex
;
1314 nEnd
= aRes
.end
.nIndex
;
1323 bool WeldTextForwarder::GetAttributeRun(sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
,
1324 sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
) const
1326 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1329 SvxEditSourceHelper::GetAttributeRun(nStartIndex
, nEndIndex
, *pEditEngine
, nPara
, nIndex
,
1334 sal_Int32
WeldTextForwarder::GetLineCount(sal_Int32 nPara
) const
1336 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1337 return pEditEngine
? pEditEngine
->GetLineCount(nPara
) : 0;
1340 sal_Int32
WeldTextForwarder::GetLineLen(sal_Int32 nPara
, sal_Int32 nLine
) const
1342 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1343 return pEditEngine
? pEditEngine
->GetLineLen(nPara
, nLine
) : 0;
1346 void WeldTextForwarder::GetLineBoundaries(/*out*/ sal_Int32
& rStart
, /*out*/ sal_Int32
& rEnd
,
1347 sal_Int32 nPara
, sal_Int32 nLine
) const
1349 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1351 pEditEngine
->GetLineBoundaries(rStart
, rEnd
, nPara
, nLine
);
1356 sal_Int32
WeldTextForwarder::GetLineNumberAtIndex(sal_Int32 nPara
, sal_Int32 nIndex
) const
1358 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1359 return pEditEngine
? pEditEngine
->GetLineNumberAtIndex(nPara
, nIndex
) : 0;
1362 bool WeldTextForwarder::QuickFormatDoc(bool /*bFull*/)
1365 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1368 pEditEngine
->QuickFormatDoc();
1374 sal_Int16
WeldTextForwarder::GetDepth(sal_Int32
/*nPara*/) const
1376 // math has no outliner...
1380 bool WeldTextForwarder::SetDepth(sal_Int32
/*nPara*/, sal_Int16 nNewDepth
)
1382 // math has no outliner...
1383 return -1 == nNewDepth
; // is it the value from 'GetDepth' ?
1386 bool WeldTextForwarder::Delete(const ESelection
& rSelection
)
1389 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1392 pEditEngine
->QuickDelete(rSelection
);
1393 pEditEngine
->QuickFormatDoc();
1399 bool WeldTextForwarder::InsertText(const OUString
& rStr
, const ESelection
& rSelection
)
1402 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1405 pEditEngine
->QuickInsertText(rStr
, rSelection
);
1406 pEditEngine
->QuickFormatDoc();
1412 const SfxItemSet
* WeldTextForwarder::GetEmptyItemSetPtr()
1414 const SfxItemSet
* pItemSet
= nullptr;
1415 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1418 pItemSet
= &pEditEngine
->GetEmptyItemSet();
1423 void WeldTextForwarder::AppendParagraph()
1425 // append an empty paragraph
1426 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1429 sal_Int32 nParaCount
= pEditEngine
->GetParagraphCount();
1430 pEditEngine
->InsertParagraph(nParaCount
, OUString());
1434 sal_Int32
WeldTextForwarder::AppendTextPortion(sal_Int32 nPara
, const OUString
& rText
,
1435 const SfxItemSet
& rSet
)
1437 sal_uInt16 nRes
= 0;
1438 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1439 if (pEditEngine
&& nPara
< pEditEngine
->GetParagraphCount())
1442 ESelection
aSel(nPara
, pEditEngine
->GetTextLen(nPara
));
1443 pEditEngine
->QuickInsertText(rText
, aSel
);
1445 // set attributes for new appended text
1446 nRes
= aSel
.end
.nIndex
= pEditEngine
->GetTextLen(nPara
);
1447 pEditEngine
->QuickSetAttribs(rSet
, aSel
);
1452 void WeldTextForwarder::CopyText(const SvxTextForwarder
& rSource
)
1454 const WeldTextForwarder
* pSourceForwarder
= dynamic_cast<const WeldTextForwarder
*>(&rSource
);
1455 if (!pSourceForwarder
)
1457 EditEngine
* pSourceEditEngine
= pSourceForwarder
->m_rEditAcc
.GetEditEngine();
1458 EditEngine
* pEditEngine
= m_rEditAcc
.GetEditEngine();
1459 if (pEditEngine
&& pSourceEditEngine
)
1461 std::unique_ptr
<EditTextObject
> pNewTextObject
= pSourceEditEngine
->CreateTextObject();
1462 pEditEngine
->SetText(*pNewTextObject
);
1466 WeldEditViewForwarder::WeldEditViewForwarder(WeldEditAccessible
& rAcc
)
1471 bool WeldEditViewForwarder::IsValid() const { return m_rEditAcc
.GetEditView() != nullptr; }
1473 Point
WeldEditViewForwarder::LogicToPixel(const Point
& rPoint
, const MapMode
& rMapMode
) const
1475 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1478 OutputDevice
& rOutDev
= pEditView
->GetOutputDevice();
1479 MapMode
aMapMode(rOutDev
.GetMapMode());
1480 Point
aPoint(OutputDevice::LogicToLogic(rPoint
, rMapMode
, MapMode(aMapMode
.GetMapUnit())));
1481 aMapMode
.SetOrigin(Point());
1482 return rOutDev
.LogicToPixel(aPoint
, aMapMode
);
1485 Point
WeldEditViewForwarder::PixelToLogic(const Point
& rPoint
, const MapMode
& rMapMode
) const
1487 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1490 OutputDevice
& rOutDev
= pEditView
->GetOutputDevice();
1491 MapMode
aMapMode(rOutDev
.GetMapMode());
1492 aMapMode
.SetOrigin(Point());
1493 Point
aPoint(rOutDev
.PixelToLogic(rPoint
, aMapMode
));
1494 return OutputDevice::LogicToLogic(aPoint
, MapMode(aMapMode
.GetMapUnit()), rMapMode
);
1497 bool WeldEditViewForwarder::GetSelection(ESelection
& rSelection
) const
1500 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1503 rSelection
= pEditView
->GetSelection();
1509 bool WeldEditViewForwarder::SetSelection(const ESelection
& rSelection
)
1512 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1515 pEditView
->SetSelection(rSelection
);
1521 bool WeldEditViewForwarder::Copy()
1524 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1533 bool WeldEditViewForwarder::Cut()
1536 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1545 bool WeldEditViewForwarder::Paste()
1548 EditView
* pEditView
= m_rEditAcc
.GetEditView();
1557 void WeldEditView::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
1559 Size
aSize(pDrawingArea
->get_size_request());
1560 if (aSize
.Width() == -1)
1561 aSize
.setWidth(500);
1562 if (aSize
.Height() == -1)
1563 aSize
.setHeight(100);
1564 pDrawingArea
->set_size_request(aSize
.Width(), aSize
.Height());
1566 SetOutputSizePixel(aSize
);
1568 weld::CustomWidgetController::SetDrawingArea(pDrawingArea
);
1572 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1573 Color aBgColor
= rStyleSettings
.GetFieldColor();
1575 OutputDevice
& rDevice
= pDrawingArea
->get_ref_device();
1577 rDevice
.SetMapMode(MapMode(MapUnit::MapTwip
));
1578 rDevice
.SetBackground(aBgColor
);
1580 Size
aOutputSize(rDevice
.PixelToLogic(aSize
));
1583 m_xEditEngine
->SetPaperSize(aOutputSize
);
1584 m_xEditEngine
->SetRefDevice(&rDevice
);
1586 m_xEditEngine
->SetControlWord(m_xEditEngine
->GetControlWord() | EEControlBits::MARKFIELDS
);
1588 m_xEditView
.reset(new EditView(m_xEditEngine
.get(), nullptr));
1589 m_xEditView
->setEditViewCallbacks(this);
1590 m_xEditView
->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize
));
1592 m_xEditView
->SetBackgroundColor(aBgColor
);
1593 m_xEditEngine
->SetBackgroundColor(aBgColor
);
1594 m_xEditEngine
->InsertView(m_xEditView
.get());
1596 pDrawingArea
->set_cursor(PointerStyle::Text
);
1598 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1603 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1604 void WeldEditView::InitAccessible()
1606 if (m_xAccessible
.is())
1607 m_xAccessible
->Init(GetEditEngine(), GetEditView());
1611 int WeldEditView::GetSurroundingText(OUString
& rSurrounding
)
1613 EditView
* pEditView
= GetEditView();
1616 rSurrounding
= pEditView
->GetSurroundingText();
1617 return pEditView
->GetSurroundingTextSelection().Min();
1620 bool WeldEditView::DeleteSurroundingText(const Selection
& rRange
)
1622 EditView
* pEditView
= GetEditView();
1625 return pEditView
->DeleteSurroundingText(rRange
);
1628 void WeldEditView::GetFocus()
1630 EditView
* pEditView
= GetEditView();
1633 pEditView
->ShowCursor(false);
1634 Invalidate(); // redraw with cursor
1637 weld::CustomWidgetController::GetFocus();
1639 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1640 if (m_xAccessible
.is())
1642 // Note: will implicitly send the AccessibleStateType::FOCUSED event
1643 ::accessibility::AccessibleTextHelper
* pHelper
= m_xAccessible
->GetTextHelper();
1645 pHelper
->SetFocus();
1650 void WeldEditView::LoseFocus()
1652 weld::CustomWidgetController::LoseFocus();
1653 Invalidate(); // redraw without cursor
1655 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1656 if (m_xAccessible
.is())
1658 // Note: will implicitly send the AccessibleStateType::FOCUSED event
1659 ::accessibility::AccessibleTextHelper
* pHelper
= m_xAccessible
->GetTextHelper();
1661 pHelper
->SetFocus(false);
1666 bool WeldEditView::CanFocus() const { return true; }
1668 css::uno::Reference
<css::datatransfer::dnd::XDropTarget
> WeldEditView::GetDropTarget()
1671 m_xDropTarget
= weld::CustomWidgetController::GetDropTarget();
1672 return m_xDropTarget
;
1675 css::uno::Reference
<css::datatransfer::clipboard::XClipboard
> WeldEditView::GetClipboard() const
1677 return weld::CustomWidgetController::GetClipboard();
1680 void WeldEditView::EditViewSelectionChange()
1684 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1685 if (m_xAccessible
.is())
1687 ::accessibility::AccessibleTextHelper
* pHelper
= m_xAccessible
->GetTextHelper();
1689 pHelper
->UpdateSelection();
1696 class WeldEditViewUIObject final
: public DrawingAreaUIObject
1699 WeldEditView
* mpEditView
;
1702 WeldEditViewUIObject(const VclPtr
<vcl::Window
>& rDrawingArea
)
1703 : DrawingAreaUIObject(rDrawingArea
)
1704 , mpEditView(static_cast<WeldEditView
*>(mpController
))
1708 static std::unique_ptr
<UIObject
> create(vcl::Window
* pWindow
)
1710 return std::unique_ptr
<UIObject
>(new WeldEditViewUIObject(pWindow
));
1713 virtual StringMap
get_state() override
1715 StringMap aMap
= WindowUIObject::get_state();
1716 aMap
[u
"Text"_ustr
] = mpEditView
->GetText();
1721 virtual OUString
get_name() const override
{ return u
"WeldEditViewUIObject"_ustr
; }
1725 FactoryFunction
WeldEditView::GetUITestFactory() const { return WeldEditViewUIObject::create
; }
1727 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */