Version 7.1.7.1, tag libreoffice-7.1.7.1
[LibreOffice.git] / svx / source / dialog / weldeditview.cxx
bloba987ef2a4c33d79d5e3ba65797adc44351d95981
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <com/sun/star/accessibility/AccessibleRole.hpp>
21 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
22 #include <com/sun/star/accessibility/XAccessible.hpp>
23 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
24 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
25 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
26 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27 #include <editeng/eeitem.hxx>
28 #include <editeng/fhgtitem.hxx>
29 #include <editeng/fontitem.hxx>
30 #include <editeng/outliner.hxx>
31 #include <editeng/unoedhlp.hxx>
32 #include <editeng/unoedsrc.hxx>
33 #include <i18nlangtag/languagetag.hxx>
34 #include <osl/diagnose.h>
35 #include <svl/itemset.hxx>
36 #include <sal/log.hxx>
37 #include <svx/AccessibleTextHelper.hxx>
38 #include <svx/weldeditview.hxx>
39 #include <tools/diagnose_ex.h>
40 #include <unotools/accessiblestatesethelper.hxx>
41 #include <vcl/cursor.hxx>
42 #include <vcl/event.hxx>
43 #include <vcl/ptrstyle.hxx>
44 #include <vcl/settings.hxx>
45 #include <vcl/svapp.hxx>
46 #include <vcl/uitest/uiobject.hxx>
48 WeldEditView::WeldEditView() {}
50 // tdf#127033 want to use UI font so override makeEditEngine to enable that
51 void WeldEditView::makeEditEngine()
53 SfxItemPool* pItemPool = EditEngine::CreatePool();
55 vcl::Font aAppFont(Application::GetSettings().GetStyleSettings().GetAppFont());
57 pItemPool->SetPoolDefaultItem(SvxFontItem(aAppFont.GetFamilyType(), aAppFont.GetFamilyName(),
58 "", PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW,
59 EE_CHAR_FONTINFO));
60 pItemPool->SetPoolDefaultItem(SvxFontItem(aAppFont.GetFamilyType(), aAppFont.GetFamilyName(),
61 "", PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW,
62 EE_CHAR_FONTINFO_CJK));
63 pItemPool->SetPoolDefaultItem(SvxFontItem(aAppFont.GetFamilyType(), aAppFont.GetFamilyName(),
64 "", PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW,
65 EE_CHAR_FONTINFO_CTL));
67 pItemPool->SetPoolDefaultItem(
68 SvxFontHeightItem(aAppFont.GetFontHeight() * 20, 100, EE_CHAR_FONTHEIGHT));
69 pItemPool->SetPoolDefaultItem(
70 SvxFontHeightItem(aAppFont.GetFontHeight() * 20, 100, EE_CHAR_FONTHEIGHT_CJK));
71 pItemPool->SetPoolDefaultItem(
72 SvxFontHeightItem(aAppFont.GetFontHeight() * 20, 100, EE_CHAR_FONTHEIGHT_CTL));
74 m_xEditEngine.reset(new EditEngine(pItemPool));
77 void WeldEditView::Resize()
79 if (m_xEditView)
81 OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
82 Size aOutputSize(rDevice.PixelToLogic(GetOutputSizePixel()));
83 Size aSize(aOutputSize);
84 m_xEditEngine->SetPaperSize(aSize);
85 m_xEditView->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize));
87 weld::CustomWidgetController::Resize();
90 void WeldEditView::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
92 rRenderContext.Push(PushFlags::ALL);
93 rRenderContext.SetClipRegion();
95 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
96 Color aBgColor = rStyleSettings.GetWindowColor();
98 rRenderContext.SetBackground(aBgColor);
100 std::vector<tools::Rectangle> aLogicRects;
102 if (m_xEditView)
104 m_xEditView->SetBackgroundColor(aBgColor);
106 m_xEditView->Paint(rRect, &rRenderContext);
108 if (HasFocus())
110 m_xEditView->ShowCursor(false);
111 vcl::Cursor* pCursor = m_xEditView->GetCursor();
112 pCursor->DrawToDevice(rRenderContext);
115 // get logic selection
116 m_xEditView->GetSelectionRectangles(aLogicRects);
119 rRenderContext.SetLineColor();
120 rRenderContext.SetFillColor(COL_BLACK);
121 rRenderContext.SetRasterOp(RasterOp::Invert);
123 for (const auto& rSelectionRect : aLogicRects)
124 rRenderContext.DrawRect(rSelectionRect);
126 rRenderContext.Pop();
129 bool WeldEditView::MouseMove(const MouseEvent& rMEvt)
131 return m_xEditView && m_xEditView->MouseMove(rMEvt);
134 bool WeldEditView::MouseButtonDown(const MouseEvent& rMEvt)
136 if (!IsMouseCaptured())
137 CaptureMouse();
139 if (!HasFocus() && CanFocus())
141 GrabFocus();
142 GetFocus();
145 return m_xEditView && m_xEditView->MouseButtonDown(rMEvt);
148 bool WeldEditView::MouseButtonUp(const MouseEvent& rMEvt)
150 if (IsMouseCaptured())
151 ReleaseMouse();
152 return m_xEditView && m_xEditView->MouseButtonUp(rMEvt);
155 bool WeldEditView::KeyInput(const KeyEvent& rKEvt)
157 sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();
159 if (nKey == KEY_TAB)
161 return false;
163 else if (m_xEditView && !m_xEditView->PostKeyEvent(rKEvt))
165 if (rKEvt.GetKeyCode().IsMod1() && !rKEvt.GetKeyCode().IsMod2())
167 if (nKey == KEY_A)
169 sal_Int32 nPar = m_xEditEngine->GetParagraphCount();
170 if (nPar)
172 sal_Int32 nLen = m_xEditEngine->GetTextLen(nPar - 1);
173 m_xEditView->SetSelection(ESelection(0, 0, nPar - 1, nLen));
175 return true;
179 return false;
182 return true;
185 bool WeldEditView::Command(const CommandEvent& rCEvt)
187 if (!m_xEditView)
188 return false;
189 m_xEditView->Command(rCEvt);
190 return true;
193 class WeldEditAccessible;
195 namespace
197 class WeldViewForwarder : public SvxViewForwarder
199 WeldEditAccessible& m_rEditAcc;
201 WeldViewForwarder(const WeldViewForwarder&) = delete;
202 WeldViewForwarder& operator=(const WeldViewForwarder&) = delete;
204 public:
205 explicit WeldViewForwarder(WeldEditAccessible& rAcc)
206 : m_rEditAcc(rAcc)
210 virtual bool IsValid() const override;
211 virtual Point LogicToPixel(const Point& rPoint, const MapMode& rMapMode) const override;
212 virtual Point PixelToLogic(const Point& rPoint, const MapMode& rMapMode) const override;
216 class WeldEditAccessible;
218 namespace
220 class WeldEditSource;
222 /* analog to SvxEditEngineForwarder */
223 class WeldTextForwarder : public SvxTextForwarder
225 WeldEditAccessible& m_rEditAcc;
226 WeldEditSource& m_rEditSource;
228 DECL_LINK(NotifyHdl, EENotify&, void);
230 WeldTextForwarder(const WeldTextForwarder&) = delete;
231 WeldTextForwarder& operator=(const WeldTextForwarder&) = delete;
233 public:
234 WeldTextForwarder(WeldEditAccessible& rAcc, WeldEditSource& rSource);
235 virtual ~WeldTextForwarder() override;
237 virtual sal_Int32 GetParagraphCount() const override;
238 virtual sal_Int32 GetTextLen(sal_Int32 nParagraph) const override;
239 virtual OUString GetText(const ESelection& rSel) const override;
240 virtual SfxItemSet GetAttribs(const ESelection& rSel, EditEngineAttribs nOnlyHardAttrib
241 = EditEngineAttribs::All) const override;
242 virtual SfxItemSet GetParaAttribs(sal_Int32 nPara) const override;
243 virtual void SetParaAttribs(sal_Int32 nPara, const SfxItemSet& rSet) override;
244 virtual void RemoveAttribs(const ESelection& rSelection) override;
245 virtual void GetPortions(sal_Int32 nPara, std::vector<sal_Int32>& rList) const override;
247 virtual SfxItemState GetItemState(const ESelection& rSel, sal_uInt16 nWhich) const override;
248 virtual SfxItemState GetItemState(sal_Int32 nPara, sal_uInt16 nWhich) const override;
250 virtual void QuickInsertText(const OUString& rText, const ESelection& rSel) override;
251 virtual void QuickInsertField(const SvxFieldItem& rFld, const ESelection& rSel) override;
252 virtual void QuickSetAttribs(const SfxItemSet& rSet, const ESelection& rSel) override;
253 virtual void QuickInsertLineBreak(const ESelection& rSel) override;
255 virtual SfxItemPool* GetPool() const override;
257 virtual OUString CalcFieldValue(const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos,
258 std::optional<Color>& rpTxtColor,
259 std::optional<Color>& rpFldColor) override;
260 virtual void FieldClicked(const SvxFieldItem&) override;
261 virtual bool IsValid() const override;
263 virtual LanguageType GetLanguage(sal_Int32, sal_Int32) const override;
264 virtual sal_Int32 GetFieldCount(sal_Int32 nPara) const override;
265 virtual EFieldInfo GetFieldInfo(sal_Int32 nPara, sal_uInt16 nField) const override;
266 virtual EBulletInfo GetBulletInfo(sal_Int32 nPara) const override;
267 virtual tools::Rectangle GetCharBounds(sal_Int32 nPara, sal_Int32 nIndex) const override;
268 virtual tools::Rectangle GetParaBounds(sal_Int32 nPara) const override;
269 virtual MapMode GetMapMode() const override;
270 virtual OutputDevice* GetRefDevice() const override;
271 virtual bool GetIndexAtPoint(const Point&, sal_Int32& nPara, sal_Int32& nIndex) const override;
272 virtual bool GetWordIndices(sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart,
273 sal_Int32& nEnd) const override;
274 virtual bool GetAttributeRun(sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nPara,
275 sal_Int32 nIndex, bool bInCell = false) const override;
276 virtual sal_Int32 GetLineCount(sal_Int32 nPara) const override;
277 virtual sal_Int32 GetLineLen(sal_Int32 nPara, sal_Int32 nLine) const override;
278 virtual void GetLineBoundaries(/*out*/ sal_Int32& rStart, /*out*/ sal_Int32& rEnd,
279 sal_Int32 nParagraph, sal_Int32 nLine) const override;
280 virtual sal_Int32 GetLineNumberAtIndex(sal_Int32 nPara, sal_Int32 nLine) const override;
281 virtual bool Delete(const ESelection&) override;
282 virtual bool InsertText(const OUString&, const ESelection&) override;
283 virtual bool QuickFormatDoc(bool bFull = false) override;
285 virtual sal_Int16 GetDepth(sal_Int32 nPara) const override;
286 virtual bool SetDepth(sal_Int32 nPara, sal_Int16 nNewDepth) override;
288 virtual const SfxItemSet* GetEmptyItemSetPtr() override;
289 // implementation functions for XParagraphAppend and XTextPortionAppend
290 virtual void AppendParagraph() override;
291 virtual sal_Int32 AppendTextPortion(sal_Int32 nPara, const OUString& rText,
292 const SfxItemSet& rSet) override;
294 virtual void CopyText(const SvxTextForwarder& rSource) override;
297 /* analog to SvxEditEngineViewForwarder */
298 class WeldEditViewForwarder : public SvxEditViewForwarder
300 WeldEditAccessible& m_rEditAcc;
302 WeldEditViewForwarder(const WeldEditViewForwarder&) = delete;
303 WeldEditViewForwarder& operator=(const WeldEditViewForwarder&) = delete;
305 public:
306 explicit WeldEditViewForwarder(WeldEditAccessible& rAcc);
308 virtual bool IsValid() const override;
310 virtual Point LogicToPixel(const Point& rPoint, const MapMode& rMapMode) const override;
311 virtual Point PixelToLogic(const Point& rPoint, const MapMode& rMapMode) const override;
313 virtual bool GetSelection(ESelection& rSelection) const override;
314 virtual bool SetSelection(const ESelection& rSelection) override;
315 virtual bool Copy() override;
316 virtual bool Cut() override;
317 virtual bool Paste() override;
320 class WeldEditSource : public SvxEditSource
322 SfxBroadcaster m_aBroadCaster;
323 WeldViewForwarder m_aViewFwd;
324 WeldTextForwarder m_aTextFwd;
325 WeldEditViewForwarder m_aEditViewFwd;
326 WeldEditAccessible& m_rEditAcc;
328 WeldEditSource(const WeldEditSource& rSrc)
329 : SvxEditSource()
330 , m_aViewFwd(rSrc.m_rEditAcc)
331 , m_aTextFwd(rSrc.m_rEditAcc, *this)
332 , m_aEditViewFwd(rSrc.m_rEditAcc)
333 , m_rEditAcc(rSrc.m_rEditAcc)
337 WeldEditSource& operator=(const WeldEditSource&) = delete;
339 public:
340 WeldEditSource(WeldEditAccessible& rAcc)
341 : m_aViewFwd(rAcc)
342 , m_aTextFwd(rAcc, *this)
343 , m_aEditViewFwd(rAcc)
344 , m_rEditAcc(rAcc)
348 virtual std::unique_ptr<SvxEditSource> Clone() const override
350 return std::unique_ptr<SvxEditSource>(new WeldEditSource(*this));
353 virtual SvxTextForwarder* GetTextForwarder() override { return &m_aTextFwd; }
355 virtual SvxViewForwarder* GetViewForwarder() override { return &m_aViewFwd; }
357 virtual SvxEditViewForwarder* GetEditViewForwarder(bool /*bCreate*/) override
359 return &m_aEditViewFwd;
362 virtual void UpdateData() override
364 // would possibly only by needed if the XText interface is implemented
365 // and its text needs to be updated.
367 virtual SfxBroadcaster& GetBroadcaster() const override
369 return const_cast<WeldEditSource*>(this)->m_aBroadCaster;
374 typedef cppu::WeakImplHelper<
375 css::accessibility::XAccessible, css::accessibility::XAccessibleComponent,
376 css::accessibility::XAccessibleContext, css::accessibility::XAccessibleEventBroadcaster>
377 WeldEditAccessibleBaseClass;
379 class WeldEditAccessible : public WeldEditAccessibleBaseClass
381 weld::CustomWidgetController* m_pController;
382 EditEngine* m_pEditEngine;
383 EditView* m_pEditView;
384 std::unique_ptr<::accessibility::AccessibleTextHelper> m_xTextHelper;
386 public:
387 WeldEditAccessible(weld::CustomWidgetController* pController)
388 : m_pController(pController)
389 , m_pEditEngine(nullptr)
390 , m_pEditView(nullptr)
394 ::accessibility::AccessibleTextHelper* GetTextHelper() { return m_xTextHelper.get(); }
396 void Init(EditEngine* pEditEngine, EditView* pEditView)
398 m_pEditEngine = pEditEngine;
399 m_pEditView = pEditView;
400 m_xTextHelper.reset(
401 new ::accessibility::AccessibleTextHelper(std::make_unique<WeldEditSource>(*this)));
402 m_xTextHelper->SetEventSource(this);
405 EditEngine* GetEditEngine() { return m_pEditEngine; }
406 EditView* GetEditView() { return m_pEditView; }
408 void ClearWin()
410 // remove handler before current object gets destroyed
411 // (avoid handler being called for already dead object)
412 m_pEditEngine->SetNotifyHdl(Link<EENotify&, void>());
414 m_pEditEngine = nullptr;
415 m_pEditView = nullptr;
416 m_pController = nullptr; // implicitly results in AccessibleStateType::DEFUNC set
418 //! make TextHelper implicitly release C++ references to some core objects
419 m_xTextHelper->SetEditSource(::std::unique_ptr<SvxEditSource>());
421 //! make TextHelper release references
422 //! (e.g. the one set by the 'SetEventSource' call)
423 m_xTextHelper->Dispose();
424 m_xTextHelper.reset();
427 // XAccessible
428 virtual css::uno::Reference<css::accessibility::XAccessibleContext>
429 SAL_CALL getAccessibleContext() override
431 return this;
434 // XAccessibleComponent
435 virtual sal_Bool SAL_CALL containsPoint(const css::awt::Point& rPoint) override
437 //! the arguments coordinates are relative to the current window !
438 //! Thus the top left-point is (0, 0)
439 SolarMutexGuard aGuard;
440 if (!m_pController)
441 throw css::uno::RuntimeException();
443 Size aSz(m_pController->GetOutputSizePixel());
444 return rPoint.X >= 0 && rPoint.Y >= 0 && rPoint.X < aSz.Width() && rPoint.Y < aSz.Height();
447 virtual css::uno::Reference<css::accessibility::XAccessible>
448 SAL_CALL getAccessibleAtPoint(const css::awt::Point& rPoint) override
450 SolarMutexGuard aGuard;
451 if (!m_xTextHelper)
452 throw css::uno::RuntimeException();
454 return m_xTextHelper->GetAt(rPoint);
457 virtual css::awt::Rectangle SAL_CALL getBounds() override
459 SolarMutexGuard aGuard;
460 if (!m_pController)
461 throw css::uno::RuntimeException();
463 const Point aOutPos;
464 const Size aOutSize(m_pController->GetOutputSizePixel());
465 css::awt::Rectangle aRet;
467 aRet.X = aOutPos.X();
468 aRet.Y = aOutPos.Y();
469 aRet.Width = aOutSize.Width();
470 aRet.Height = aOutSize.Height();
472 return aRet;
475 virtual css::awt::Point SAL_CALL getLocation() override
477 SolarMutexGuard aGuard;
478 if (!m_pController)
479 throw css::uno::RuntimeException();
481 const css::awt::Rectangle aRect(getBounds());
482 css::awt::Point aRet;
484 aRet.X = aRect.X;
485 aRet.Y = aRect.Y;
487 return aRet;
490 virtual css::awt::Point SAL_CALL getLocationOnScreen() override
492 SolarMutexGuard aGuard;
493 if (!m_pController)
494 throw css::uno::RuntimeException();
496 css::awt::Point aScreenLoc(0, 0);
498 css::uno::Reference<css::accessibility::XAccessible> xParent(getAccessibleParent());
499 if (xParent)
501 css::uno::Reference<css::accessibility::XAccessibleContext> xParentContext(
502 xParent->getAccessibleContext());
503 css::uno::Reference<css::accessibility::XAccessibleComponent> xParentComponent(
504 xParentContext, css::uno::UNO_QUERY);
505 OSL_ENSURE(xParentComponent.is(),
506 "WeldEditAccessible::getLocationOnScreen: no parent component!");
507 if (xParentComponent.is())
509 css::awt::Point aParentScreenLoc(xParentComponent->getLocationOnScreen());
510 css::awt::Point aOwnRelativeLoc(getLocation());
511 aScreenLoc.X = aParentScreenLoc.X + aOwnRelativeLoc.X;
512 aScreenLoc.Y = aParentScreenLoc.Y + aOwnRelativeLoc.Y;
516 return aScreenLoc;
519 virtual css::awt::Size SAL_CALL getSize() override
521 SolarMutexGuard aGuard;
522 if (!m_pController)
523 throw css::uno::RuntimeException();
525 Size aSz(m_pController->GetOutputSizePixel());
526 return css::awt::Size(aSz.Width(), aSz.Height());
529 virtual void SAL_CALL grabFocus() override { m_pController->GrabFocus(); }
531 virtual sal_Int32 SAL_CALL getForeground() override
533 SolarMutexGuard aGuard;
534 if (!m_pController)
535 throw css::uno::RuntimeException();
537 Color nCol = m_pEditEngine->GetAutoColor();
538 return static_cast<sal_Int32>(nCol);
541 virtual sal_Int32 SAL_CALL getBackground() override
543 SolarMutexGuard aGuard;
544 if (!m_pController)
545 throw css::uno::RuntimeException();
547 Color nCol = m_pEditEngine->GetBackgroundColor();
548 return static_cast<sal_Int32>(nCol);
551 // XAccessibleContext
552 virtual sal_Int32 SAL_CALL getAccessibleChildCount() override
554 if (m_xTextHelper)
555 return m_xTextHelper->GetChildCount();
556 return 0;
559 virtual css::uno::Reference<css::accessibility::XAccessible>
560 SAL_CALL getAccessibleChild(sal_Int32 i) override
562 if (m_xTextHelper)
563 return m_xTextHelper->GetChild(i);
564 throw css::lang::IndexOutOfBoundsException(); // there is no child...
567 virtual css::uno::Reference<css::accessibility::XAccessible>
568 SAL_CALL getAccessibleParent() override
570 SolarMutexGuard aGuard;
571 if (!m_pController)
572 throw css::uno::RuntimeException();
574 return m_pController->GetDrawingArea()->get_accessible_parent();
577 virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() override
579 SolarMutexGuard aGuard;
580 if (!m_pController)
581 throw css::uno::RuntimeException();
583 // -1 for child not found/no parent (according to specification)
584 sal_Int32 nRet = -1;
586 css::uno::Reference<css::accessibility::XAccessible> xParent(getAccessibleParent());
587 if (!xParent)
588 return nRet;
592 css::uno::Reference<css::accessibility::XAccessibleContext> xParentContext(
593 xParent->getAccessibleContext());
595 // iterate over parent's children and search for this object
596 if (xParentContext.is())
598 sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
599 for (sal_Int32 nChild = 0; (nChild < nChildCount) && (-1 == nRet); ++nChild)
601 css::uno::Reference<css::accessibility::XAccessible> xChild(
602 xParentContext->getAccessibleChild(nChild));
603 if (xChild.get() == this)
604 nRet = nChild;
608 catch (const css::uno::Exception&)
610 TOOLS_WARN_EXCEPTION("svx", "WeldEditAccessible::getAccessibleIndexInParent");
613 return nRet;
616 virtual sal_Int16 SAL_CALL getAccessibleRole() override
618 return css::accessibility::AccessibleRole::TEXT_FRAME;
621 virtual OUString SAL_CALL getAccessibleDescription() override
623 SolarMutexGuard aGuard;
625 OUString aRet;
627 if (m_pController)
629 aRet = m_pController->GetAccessibleDescription();
632 return aRet;
635 virtual OUString SAL_CALL getAccessibleName() override
637 SolarMutexGuard aGuard;
639 OUString aRet;
641 if (m_pController)
643 aRet = m_pController->GetAccessibleName();
646 return aRet;
649 virtual css::uno::Reference<css::accessibility::XAccessibleRelationSet>
650 SAL_CALL getAccessibleRelationSet() override
652 SolarMutexGuard aGuard;
653 if (!m_pController)
654 throw css::uno::RuntimeException();
656 return m_pController->GetDrawingArea()->get_accessible_relation_set();
659 virtual css::uno::Reference<css::accessibility::XAccessibleStateSet>
660 SAL_CALL getAccessibleStateSet() override
662 SolarMutexGuard aGuard;
663 ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper;
665 css::uno::Reference<css::accessibility::XAccessibleStateSet> xStateSet(pStateSet);
667 if (!m_pController || !m_xTextHelper)
668 pStateSet->AddState(css::accessibility::AccessibleStateType::DEFUNC);
669 else
671 pStateSet->AddState(css::accessibility::AccessibleStateType::MULTI_LINE);
672 pStateSet->AddState(css::accessibility::AccessibleStateType::ENABLED);
673 pStateSet->AddState(css::accessibility::AccessibleStateType::EDITABLE);
674 pStateSet->AddState(css::accessibility::AccessibleStateType::FOCUSABLE);
675 pStateSet->AddState(css::accessibility::AccessibleStateType::SELECTABLE);
676 if (m_pController->HasFocus())
677 pStateSet->AddState(css::accessibility::AccessibleStateType::FOCUSED);
678 if (m_pController->IsActive())
679 pStateSet->AddState(css::accessibility::AccessibleStateType::ACTIVE);
680 if (m_pController->IsVisible())
681 pStateSet->AddState(css::accessibility::AccessibleStateType::SHOWING);
682 if (m_pController->IsReallyVisible())
683 pStateSet->AddState(css::accessibility::AccessibleStateType::VISIBLE);
684 if (COL_TRANSPARENT != m_pEditEngine->GetBackgroundColor())
685 pStateSet->AddState(css::accessibility::AccessibleStateType::OPAQUE);
688 return xStateSet;
691 virtual css::lang::Locale SAL_CALL getLocale() override
693 SolarMutexGuard aGuard;
694 return LanguageTag(m_pEditEngine->GetDefaultLanguage()).getLocale();
697 // XAccessibleEventBroadcaster
698 virtual void SAL_CALL addAccessibleEventListener(
699 const css::uno::Reference<css::accessibility::XAccessibleEventListener>& rListener) override
701 if (!m_xTextHelper) // not disposing (about to destroy view shell)
702 return;
703 m_xTextHelper->AddEventListener(rListener);
706 virtual void SAL_CALL removeAccessibleEventListener(
707 const css::uno::Reference<css::accessibility::XAccessibleEventListener>& rListener) override
709 if (!m_xTextHelper) // not disposing (about to destroy view shell)
710 return;
711 m_xTextHelper->RemoveEventListener(rListener);
715 css::uno::Reference<css::accessibility::XAccessible> WeldEditView::CreateAccessible()
717 if (!m_xAccessible.is())
718 m_xAccessible.set(new WeldEditAccessible(this));
719 return css::uno::Reference<css::accessibility::XAccessible>(m_xAccessible.get());
722 WeldEditView::~WeldEditView()
724 if (m_xAccessible.is())
726 m_xAccessible->ClearWin(); // make Accessible nonfunctional
727 m_xAccessible.clear();
731 bool WeldViewForwarder::IsValid() const { return m_rEditAcc.GetEditView() != nullptr; }
733 Point WeldViewForwarder::LogicToPixel(const Point& rPoint, const MapMode& rMapMode) const
735 EditView* pEditView = m_rEditAcc.GetEditView();
736 if (!pEditView)
737 return Point();
738 OutputDevice& rOutDev = pEditView->GetOutputDevice();
739 MapMode aMapMode(rOutDev.GetMapMode());
740 Point aPoint(OutputDevice::LogicToLogic(rPoint, rMapMode, MapMode(aMapMode.GetMapUnit())));
741 aMapMode.SetOrigin(Point());
742 return rOutDev.LogicToPixel(aPoint, aMapMode);
745 Point WeldViewForwarder::PixelToLogic(const Point& rPoint, const MapMode& rMapMode) const
747 EditView* pEditView = m_rEditAcc.GetEditView();
748 if (!pEditView)
749 return Point();
750 OutputDevice& rOutDev = pEditView->GetOutputDevice();
751 MapMode aMapMode(rOutDev.GetMapMode());
752 aMapMode.SetOrigin(Point());
753 Point aPoint(rOutDev.PixelToLogic(rPoint, aMapMode));
754 return OutputDevice::LogicToLogic(aPoint, MapMode(aMapMode.GetMapUnit()), rMapMode);
757 WeldTextForwarder::WeldTextForwarder(WeldEditAccessible& rAcc, WeldEditSource& rSource)
758 : m_rEditAcc(rAcc)
759 , m_rEditSource(rSource)
761 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
762 if (pEditEngine)
763 pEditEngine->SetNotifyHdl(LINK(this, WeldTextForwarder, NotifyHdl));
766 WeldTextForwarder::~WeldTextForwarder()
768 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
769 if (pEditEngine)
770 pEditEngine->SetNotifyHdl(Link<EENotify&, void>());
773 IMPL_LINK(WeldTextForwarder, NotifyHdl, EENotify&, rNotify, void)
775 if (EditEngine* pEditEngine = m_rEditAcc.GetEditEngine())
777 if (rNotify.eNotificationType == EE_NOTIFY_PROCESSNOTIFICATIONS
778 && !pEditEngine->GetUpdateMode())
780 // tdf#143088 an UpdateMode of false will just to on to cause
781 // AccessibleTextHelper_Impl::GetTextForwarder to throw an
782 // exception as a Frozen EditEngine is considered Invalid so return
783 // early instead
784 return;
788 ::std::unique_ptr<SfxHint> aHint = SvxEditSourceHelper::EENotification2Hint(&rNotify);
789 if (aHint)
790 m_rEditSource.GetBroadcaster().Broadcast(*aHint);
793 sal_Int32 WeldTextForwarder::GetParagraphCount() const
795 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
796 return pEditEngine ? pEditEngine->GetParagraphCount() : 0;
799 sal_Int32 WeldTextForwarder::GetTextLen(sal_Int32 nParagraph) const
801 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
802 return pEditEngine ? pEditEngine->GetTextLen(nParagraph) : 0;
805 OUString WeldTextForwarder::GetText(const ESelection& rSel) const
807 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
808 OUString aRet;
809 if (pEditEngine)
810 aRet = pEditEngine->GetText(rSel);
811 return convertLineEnd(aRet, GetSystemLineEnd());
814 SfxItemSet WeldTextForwarder::GetAttribs(const ESelection& rSel,
815 EditEngineAttribs nOnlyHardAttrib) const
817 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
818 assert(pEditEngine && "EditEngine missing");
819 if (rSel.nStartPara == rSel.nEndPara)
821 GetAttribsFlags nFlags = GetAttribsFlags::NONE;
822 switch (nOnlyHardAttrib)
824 case EditEngineAttribs::All:
825 nFlags = GetAttribsFlags::ALL;
826 break;
827 case EditEngineAttribs::OnlyHard:
828 nFlags = GetAttribsFlags::CHARATTRIBS;
829 break;
830 default:
831 SAL_WARN("svx", "unknown flags for WeldTextForwarder::GetAttribs");
834 return pEditEngine->GetAttribs(rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags);
836 else
838 return pEditEngine->GetAttribs(rSel, nOnlyHardAttrib);
842 SfxItemSet WeldTextForwarder::GetParaAttribs(sal_Int32 nPara) const
844 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
845 assert(pEditEngine && "EditEngine missing");
847 SfxItemSet aSet(pEditEngine->GetParaAttribs(nPara));
849 sal_uInt16 nWhich = EE_PARA_START;
850 while (nWhich <= EE_PARA_END)
852 if (aSet.GetItemState(nWhich) != SfxItemState::SET)
854 if (pEditEngine->HasParaAttrib(nPara, nWhich))
855 aSet.Put(pEditEngine->GetParaAttrib(nPara, nWhich));
857 nWhich++;
860 return aSet;
863 void WeldTextForwarder::SetParaAttribs(sal_Int32 nPara, const SfxItemSet& rSet)
865 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
866 if (pEditEngine)
867 pEditEngine->SetParaAttribs(nPara, rSet);
870 SfxItemPool* WeldTextForwarder::GetPool() const
872 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
873 return pEditEngine ? pEditEngine->GetEmptyItemSet().GetPool() : nullptr;
876 void WeldTextForwarder::RemoveAttribs(const ESelection& rSelection)
878 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
879 if (pEditEngine)
880 pEditEngine->RemoveAttribs(rSelection, false /*bRemoveParaAttribs*/, 0);
883 void WeldTextForwarder::GetPortions(sal_Int32 nPara, std::vector<sal_Int32>& rList) const
885 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
886 if (pEditEngine)
887 pEditEngine->GetPortions(nPara, rList);
890 void WeldTextForwarder::QuickInsertText(const OUString& rText, const ESelection& rSel)
892 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
893 if (pEditEngine)
894 pEditEngine->QuickInsertText(rText, rSel);
897 void WeldTextForwarder::QuickInsertLineBreak(const ESelection& rSel)
899 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
900 if (pEditEngine)
901 pEditEngine->QuickInsertLineBreak(rSel);
904 void WeldTextForwarder::QuickInsertField(const SvxFieldItem& rFld, const ESelection& rSel)
906 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
907 if (pEditEngine)
908 pEditEngine->QuickInsertField(rFld, rSel);
911 void WeldTextForwarder::QuickSetAttribs(const SfxItemSet& rSet, const ESelection& rSel)
913 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
914 if (pEditEngine)
915 pEditEngine->QuickSetAttribs(rSet, rSel);
918 bool WeldTextForwarder::IsValid() const
920 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
921 // cannot reliably query EditEngine state
922 // while in the middle of an update
923 return pEditEngine && pEditEngine->GetUpdateMode();
926 OUString WeldTextForwarder::CalcFieldValue(const SvxFieldItem& rField, sal_Int32 nPara,
927 sal_Int32 nPos, std::optional<Color>& rpTxtColor,
928 std::optional<Color>& rpFldColor)
930 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
931 return pEditEngine ? pEditEngine->CalcFieldValue(rField, nPara, nPos, rpTxtColor, rpFldColor)
932 : OUString();
935 void WeldTextForwarder::FieldClicked(const SvxFieldItem&) {}
937 static SfxItemState GetSvxEditEngineItemState(EditEngine const& rEditEngine, const ESelection& rSel,
938 sal_uInt16 nWhich)
940 std::vector<EECharAttrib> aAttribs;
942 const SfxPoolItem* pLastItem = nullptr;
944 SfxItemState eState = SfxItemState::DEFAULT;
946 // check all paragraphs inside the selection
947 for (sal_Int32 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++)
949 SfxItemState eParaState = SfxItemState::DEFAULT;
951 // calculate start and endpos for this paragraph
952 sal_Int32 nPos = 0;
953 if (rSel.nStartPara == nPara)
954 nPos = rSel.nStartPos;
956 sal_Int32 nEndPos = rSel.nEndPos;
957 if (rSel.nEndPara != nPara)
958 nEndPos = rEditEngine.GetTextLen(nPara);
960 // get list of char attribs
961 rEditEngine.GetCharAttribs(nPara, aAttribs);
963 bool bEmpty = true; // we found no item inside the selection of this paragraph
964 bool bGaps = false; // we found items but there are gaps between them
965 sal_Int32 nLastEnd = nPos;
967 const SfxPoolItem* pParaItem = nullptr;
969 for (const auto& rAttrib : aAttribs)
971 OSL_ENSURE(rAttrib.pAttr, "GetCharAttribs gives corrupt data");
973 const bool bEmptyPortion = (rAttrib.nStart == rAttrib.nEnd);
974 if ((!bEmptyPortion && (rAttrib.nStart >= nEndPos))
975 || (bEmptyPortion && (rAttrib.nStart > nEndPos)))
976 break; // break if we are already behind our selection
978 if ((!bEmptyPortion && (rAttrib.nEnd <= nPos))
979 || (bEmptyPortion && (rAttrib.nEnd < nPos)))
980 continue; // or if the attribute ends before our selection
982 if (rAttrib.pAttr->Which() != nWhich)
983 continue; // skip if is not the searched item
985 // if we already found an item
986 if (pParaItem)
988 // ... and its different to this one than the state is don't care
989 if (*pParaItem != *(rAttrib.pAttr))
990 return SfxItemState::DONTCARE;
992 else
994 pParaItem = rAttrib.pAttr;
997 if (bEmpty)
998 bEmpty = false;
1000 if (!bGaps && rAttrib.nStart > nLastEnd)
1001 bGaps = true;
1003 nLastEnd = rAttrib.nEnd;
1006 if (!bEmpty && !bGaps && nLastEnd < (nEndPos - 1))
1007 bGaps = true;
1008 if (bEmpty)
1009 eParaState = SfxItemState::DEFAULT;
1010 else if (bGaps)
1011 eParaState = SfxItemState::DONTCARE;
1012 else
1013 eParaState = SfxItemState::SET;
1015 // if we already found an item check if we found the same
1016 if (pLastItem)
1018 if ((pParaItem == nullptr) || (*pLastItem != *pParaItem))
1019 return SfxItemState::DONTCARE;
1021 else
1023 pLastItem = pParaItem;
1024 eState = eParaState;
1028 return eState;
1031 SfxItemState WeldTextForwarder::GetItemState(const ESelection& rSel, sal_uInt16 nWhich) const
1033 SfxItemState nState = SfxItemState::DISABLED;
1034 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1035 if (pEditEngine)
1036 nState = GetSvxEditEngineItemState(*pEditEngine, rSel, nWhich);
1037 return nState;
1040 SfxItemState WeldTextForwarder::GetItemState(sal_Int32 nPara, sal_uInt16 nWhich) const
1042 SfxItemState nState = SfxItemState::DISABLED;
1043 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1044 if (pEditEngine)
1046 const SfxItemSet& rSet = pEditEngine->GetParaAttribs(nPara);
1047 nState = rSet.GetItemState(nWhich);
1049 return nState;
1052 LanguageType WeldTextForwarder::GetLanguage(sal_Int32 nPara, sal_Int32 nIndex) const
1054 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1055 return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex) : LANGUAGE_NONE;
1058 sal_Int32 WeldTextForwarder::GetFieldCount(sal_Int32 nPara) const
1060 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1061 return pEditEngine ? pEditEngine->GetFieldCount(nPara) : 0;
1064 EFieldInfo WeldTextForwarder::GetFieldInfo(sal_Int32 nPara, sal_uInt16 nField) const
1066 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1067 return pEditEngine ? pEditEngine->GetFieldInfo(nPara, nField) : EFieldInfo();
1070 EBulletInfo WeldTextForwarder::GetBulletInfo(sal_Int32 /*nPara*/) const { return EBulletInfo(); }
1072 tools::Rectangle WeldTextForwarder::GetCharBounds(sal_Int32 nPara, sal_Int32 nIndex) const
1074 tools::Rectangle aRect(0, 0, 0, 0);
1075 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1077 if (pEditEngine)
1079 // Handle virtual position one-past-the end of the string
1080 if (nIndex >= pEditEngine->GetTextLen(nPara))
1082 if (nIndex)
1083 aRect = pEditEngine->GetCharacterBounds(EPosition(nPara, nIndex - 1));
1085 aRect.Move(aRect.Right() - aRect.Left(), 0);
1086 aRect.SetSize(Size(1, pEditEngine->GetTextHeight()));
1088 else
1090 aRect = pEditEngine->GetCharacterBounds(EPosition(nPara, nIndex));
1093 return aRect;
1096 tools::Rectangle WeldTextForwarder::GetParaBounds(sal_Int32 nPara) const
1098 tools::Rectangle aRect(0, 0, 0, 0);
1099 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1101 if (pEditEngine)
1103 const Point aPnt = pEditEngine->GetDocPosTopLeft(nPara);
1104 const sal_Int32 nWidth = pEditEngine->CalcTextWidth();
1105 const sal_Int32 nHeight = pEditEngine->GetTextHeight(nPara);
1106 aRect = tools::Rectangle(aPnt.X(), aPnt.Y(), aPnt.X() + nWidth, aPnt.Y() + nHeight);
1109 return aRect;
1112 MapMode WeldTextForwarder::GetMapMode() const
1114 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1115 return pEditEngine ? pEditEngine->GetRefMapMode() : MapMode(MapUnit::Map100thMM);
1118 OutputDevice* WeldTextForwarder::GetRefDevice() const
1120 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1121 return pEditEngine ? pEditEngine->GetRefDevice() : nullptr;
1124 bool WeldTextForwarder::GetIndexAtPoint(const Point& rPos, sal_Int32& nPara,
1125 sal_Int32& nIndex) const
1127 bool bRes = false;
1128 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1129 if (pEditEngine)
1131 EPosition aDocPos = pEditEngine->FindDocPosition(rPos);
1132 nPara = aDocPos.nPara;
1133 nIndex = aDocPos.nIndex;
1134 bRes = true;
1136 return bRes;
1139 bool WeldTextForwarder::GetWordIndices(sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart,
1140 sal_Int32& nEnd) const
1142 bool bRes = false;
1143 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1144 if (pEditEngine)
1146 ESelection aRes = pEditEngine->GetWord(ESelection(nPara, nIndex, nPara, nIndex),
1147 css::i18n::WordType::DICTIONARY_WORD);
1149 if (aRes.nStartPara == nPara && aRes.nStartPara == aRes.nEndPara)
1151 nStart = aRes.nStartPos;
1152 nEnd = aRes.nEndPos;
1154 bRes = true;
1158 return bRes;
1161 bool WeldTextForwarder::GetAttributeRun(sal_Int32& nStartIndex, sal_Int32& nEndIndex,
1162 sal_Int32 nPara, sal_Int32 nIndex, bool bInCell) const
1164 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1165 if (!pEditEngine)
1166 return false;
1167 SvxEditSourceHelper::GetAttributeRun(nStartIndex, nEndIndex, *pEditEngine, nPara, nIndex,
1168 bInCell);
1169 return true;
1172 sal_Int32 WeldTextForwarder::GetLineCount(sal_Int32 nPara) const
1174 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1175 return pEditEngine ? pEditEngine->GetLineCount(nPara) : 0;
1178 sal_Int32 WeldTextForwarder::GetLineLen(sal_Int32 nPara, sal_Int32 nLine) const
1180 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1181 return pEditEngine ? pEditEngine->GetLineLen(nPara, nLine) : 0;
1184 void WeldTextForwarder::GetLineBoundaries(/*out*/ sal_Int32& rStart, /*out*/ sal_Int32& rEnd,
1185 sal_Int32 nPara, sal_Int32 nLine) const
1187 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1188 if (pEditEngine)
1189 pEditEngine->GetLineBoundaries(rStart, rEnd, nPara, nLine);
1190 else
1191 rStart = rEnd = 0;
1194 sal_Int32 WeldTextForwarder::GetLineNumberAtIndex(sal_Int32 nPara, sal_Int32 nIndex) const
1196 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1197 return pEditEngine ? pEditEngine->GetLineNumberAtIndex(nPara, nIndex) : 0;
1200 bool WeldTextForwarder::QuickFormatDoc(bool /*bFull*/)
1202 bool bRes = false;
1203 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1204 if (pEditEngine)
1206 pEditEngine->QuickFormatDoc();
1207 bRes = true;
1209 return bRes;
1212 sal_Int16 WeldTextForwarder::GetDepth(sal_Int32 /*nPara*/) const
1214 // math has no outliner...
1215 return -1;
1218 bool WeldTextForwarder::SetDepth(sal_Int32 /*nPara*/, sal_Int16 nNewDepth)
1220 // math has no outliner...
1221 return -1 == nNewDepth; // is it the value from 'GetDepth' ?
1224 bool WeldTextForwarder::Delete(const ESelection& rSelection)
1226 bool bRes = false;
1227 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1228 if (pEditEngine)
1230 pEditEngine->QuickDelete(rSelection);
1231 pEditEngine->QuickFormatDoc();
1232 bRes = true;
1234 return bRes;
1237 bool WeldTextForwarder::InsertText(const OUString& rStr, const ESelection& rSelection)
1239 bool bRes = false;
1240 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1241 if (pEditEngine)
1243 pEditEngine->QuickInsertText(rStr, rSelection);
1244 pEditEngine->QuickFormatDoc();
1245 bRes = true;
1247 return bRes;
1250 const SfxItemSet* WeldTextForwarder::GetEmptyItemSetPtr()
1252 const SfxItemSet* pItemSet = nullptr;
1253 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1254 if (pEditEngine)
1256 pItemSet = &pEditEngine->GetEmptyItemSet();
1258 return pItemSet;
1261 void WeldTextForwarder::AppendParagraph()
1263 // append an empty paragraph
1264 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1265 if (pEditEngine)
1267 sal_Int32 nParaCount = pEditEngine->GetParagraphCount();
1268 pEditEngine->InsertParagraph(nParaCount, OUString());
1272 sal_Int32 WeldTextForwarder::AppendTextPortion(sal_Int32 nPara, const OUString& rText,
1273 const SfxItemSet& rSet)
1275 sal_uInt16 nRes = 0;
1276 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1277 if (pEditEngine && nPara < pEditEngine->GetParagraphCount())
1279 // append text
1280 ESelection aSel(nPara, pEditEngine->GetTextLen(nPara));
1281 pEditEngine->QuickInsertText(rText, aSel);
1283 // set attributes for new appended text
1284 nRes = aSel.nEndPos = pEditEngine->GetTextLen(nPara);
1285 pEditEngine->QuickSetAttribs(rSet, aSel);
1287 return nRes;
1290 void WeldTextForwarder::CopyText(const SvxTextForwarder& rSource)
1292 const WeldTextForwarder* pSourceForwarder = dynamic_cast<const WeldTextForwarder*>(&rSource);
1293 if (!pSourceForwarder)
1294 return;
1295 EditEngine* pSourceEditEngine = pSourceForwarder->m_rEditAcc.GetEditEngine();
1296 EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1297 if (pEditEngine && pSourceEditEngine)
1299 std::unique_ptr<EditTextObject> pNewTextObject = pSourceEditEngine->CreateTextObject();
1300 pEditEngine->SetText(*pNewTextObject);
1304 WeldEditViewForwarder::WeldEditViewForwarder(WeldEditAccessible& rAcc)
1305 : m_rEditAcc(rAcc)
1309 bool WeldEditViewForwarder::IsValid() const { return m_rEditAcc.GetEditView() != nullptr; }
1311 Point WeldEditViewForwarder::LogicToPixel(const Point& rPoint, const MapMode& rMapMode) const
1313 EditView* pEditView = m_rEditAcc.GetEditView();
1314 if (!pEditView)
1315 return Point();
1316 OutputDevice& rOutDev = pEditView->GetOutputDevice();
1317 MapMode aMapMode(rOutDev.GetMapMode());
1318 Point aPoint(OutputDevice::LogicToLogic(rPoint, rMapMode, MapMode(aMapMode.GetMapUnit())));
1319 aMapMode.SetOrigin(Point());
1320 return rOutDev.LogicToPixel(aPoint, aMapMode);
1323 Point WeldEditViewForwarder::PixelToLogic(const Point& rPoint, const MapMode& rMapMode) const
1325 EditView* pEditView = m_rEditAcc.GetEditView();
1326 if (!pEditView)
1327 return Point();
1328 OutputDevice& rOutDev = pEditView->GetOutputDevice();
1329 MapMode aMapMode(rOutDev.GetMapMode());
1330 aMapMode.SetOrigin(Point());
1331 Point aPoint(rOutDev.PixelToLogic(rPoint, aMapMode));
1332 return OutputDevice::LogicToLogic(aPoint, MapMode(aMapMode.GetMapUnit()), rMapMode);
1335 bool WeldEditViewForwarder::GetSelection(ESelection& rSelection) const
1337 bool bRes = false;
1338 EditView* pEditView = m_rEditAcc.GetEditView();
1339 if (pEditView)
1341 rSelection = pEditView->GetSelection();
1342 bRes = true;
1344 return bRes;
1347 bool WeldEditViewForwarder::SetSelection(const ESelection& rSelection)
1349 bool bRes = false;
1350 EditView* pEditView = m_rEditAcc.GetEditView();
1351 if (pEditView)
1353 pEditView->SetSelection(rSelection);
1354 bRes = true;
1356 return bRes;
1359 bool WeldEditViewForwarder::Copy()
1361 bool bRes = false;
1362 EditView* pEditView = m_rEditAcc.GetEditView();
1363 if (pEditView)
1365 pEditView->Copy();
1366 bRes = true;
1368 return bRes;
1371 bool WeldEditViewForwarder::Cut()
1373 bool bRes = false;
1374 EditView* pEditView = m_rEditAcc.GetEditView();
1375 if (pEditView)
1377 pEditView->Cut();
1378 bRes = true;
1380 return bRes;
1383 bool WeldEditViewForwarder::Paste()
1385 bool bRes = false;
1386 EditView* pEditView = m_rEditAcc.GetEditView();
1387 if (pEditView)
1389 pEditView->Paste();
1390 bRes = true;
1392 return bRes;
1395 void WeldEditView::SetDrawingArea(weld::DrawingArea* pDrawingArea)
1397 Size aSize(pDrawingArea->get_size_request());
1398 if (aSize.Width() == -1)
1399 aSize.setWidth(500);
1400 if (aSize.Height() == -1)
1401 aSize.setHeight(100);
1402 pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
1404 SetOutputSizePixel(aSize);
1406 weld::CustomWidgetController::SetDrawingArea(pDrawingArea);
1408 EnableRTL(false);
1410 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1411 Color aBgColor = rStyleSettings.GetWindowColor();
1413 OutputDevice& rDevice = pDrawingArea->get_ref_device();
1415 rDevice.SetMapMode(MapMode(MapUnit::MapTwip));
1416 rDevice.SetBackground(aBgColor);
1418 Size aOutputSize(rDevice.PixelToLogic(aSize));
1419 aSize = aOutputSize;
1420 aSize.setHeight(aSize.Height());
1422 makeEditEngine();
1423 m_xEditEngine->SetPaperSize(aSize);
1424 m_xEditEngine->SetRefDevice(&rDevice);
1426 m_xEditEngine->SetControlWord(m_xEditEngine->GetControlWord() | EEControlBits::MARKFIELDS);
1428 m_xEditView.reset(new EditView(m_xEditEngine.get(), nullptr));
1429 m_xEditView->setEditViewCallbacks(this);
1430 m_xEditView->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize));
1432 m_xEditView->SetBackgroundColor(aBgColor);
1433 m_xEditEngine->InsertView(m_xEditView.get());
1435 pDrawingArea->set_cursor(PointerStyle::Text);
1437 if (m_xAccessible.is())
1438 m_xAccessible->Init(m_xEditEngine.get(), m_xEditView.get());
1441 int WeldEditView::GetSurroundingText(OUString& rSurrounding)
1443 if (!m_xEditView)
1444 return -1;
1445 rSurrounding = m_xEditView->GetSurroundingText();
1446 return m_xEditView->GetSurroundingTextSelection().Min();
1449 bool WeldEditView::DeleteSurroundingText(const Selection& rRange)
1451 if (!m_xEditView)
1452 return false;
1453 return m_xEditView->DeleteSurroundingText(rRange);
1456 void WeldEditView::GetFocus()
1458 if (m_xEditView)
1459 m_xEditView->ShowCursor(false);
1461 weld::CustomWidgetController::GetFocus();
1463 if (m_xAccessible.is())
1465 // Note: will implicitly send the AccessibleStateType::FOCUSED event
1466 ::accessibility::AccessibleTextHelper* pHelper = m_xAccessible->GetTextHelper();
1467 if (pHelper)
1468 pHelper->SetFocus();
1472 void WeldEditView::LoseFocus()
1474 weld::CustomWidgetController::LoseFocus();
1475 Invalidate(); // redraw without cursor
1477 if (m_xAccessible.is())
1479 // Note: will implicitly send the AccessibleStateType::FOCUSED event
1480 ::accessibility::AccessibleTextHelper* pHelper = m_xAccessible->GetTextHelper();
1481 if (pHelper)
1482 pHelper->SetFocus(false);
1486 bool WeldEditView::CanFocus() const { return true; }
1488 namespace
1490 class WeldEditViewUIObject final : public DrawingAreaUIObject
1492 private:
1493 WeldEditView* mpEditView;
1495 public:
1496 WeldEditViewUIObject(const VclPtr<vcl::Window>& rDrawingArea)
1497 : DrawingAreaUIObject(rDrawingArea)
1498 , mpEditView(static_cast<WeldEditView*>(mpController))
1502 static std::unique_ptr<UIObject> create(vcl::Window* pWindow)
1504 return std::unique_ptr<UIObject>(new WeldEditViewUIObject(pWindow));
1507 virtual StringMap get_state() override
1509 StringMap aMap = WindowUIObject::get_state();
1510 aMap["Text"] = mpEditView->GetText();
1511 return aMap;
1514 private:
1515 virtual OUString get_name() const override { return "WeldEditViewUIObject"; }
1519 FactoryFunction WeldEditView::GetUITestFactory() const { return WeldEditViewUIObject::create; }
1521 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */