LibreOffice Module svx (master)  1
weldeditview.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
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/XAccessibleText.hpp>
26 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
27 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
28 #include <editeng/eeitem.hxx>
29 #include <editeng/fhgtitem.hxx>
30 #include <editeng/fontitem.hxx>
31 #include <editeng/outliner.hxx>
32 #include <editeng/unoedhlp.hxx>
33 #include <editeng/unoedsrc.hxx>
35 #include <osl/diagnose.h>
36 #include <svl/itemset.hxx>
37 #include <sal/log.hxx>
39 #include <svx/weldeditview.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 
48 
49 // tdf#127033 want to use UI font so override makeEditEngine to enable that
51 {
52  SfxItemPool* pItemPool = EditEngine::CreatePool();
53 
54  vcl::Font aAppFont(Application::GetSettings().GetStyleSettings().GetAppFont());
55 
56  pItemPool->SetPoolDefaultItem(SvxFontItem(aAppFont.GetFamilyType(), aAppFont.GetFamilyName(),
57  "", PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW,
59  pItemPool->SetPoolDefaultItem(SvxFontItem(aAppFont.GetFamilyType(), aAppFont.GetFamilyName(),
60  "", PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW,
62  pItemPool->SetPoolDefaultItem(SvxFontItem(aAppFont.GetFamilyType(), aAppFont.GetFamilyName(),
63  "", PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW,
65 
66  pItemPool->SetPoolDefaultItem(
67  SvxFontHeightItem(aAppFont.GetFontHeight() * 20, 100, EE_CHAR_FONTHEIGHT));
68  pItemPool->SetPoolDefaultItem(
70  pItemPool->SetPoolDefaultItem(
72 
73  m_xEditEngine.reset(new EditEngine(pItemPool));
74 }
75 
77 {
79  Size aOutputSize(rDevice.PixelToLogic(GetOutputSizePixel()));
80  Size aSize(aOutputSize);
81  m_xEditEngine->SetPaperSize(aSize);
82  m_xEditView->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize));
84 }
85 
86 void WeldEditView::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
87 {
88  //note: ScEditWindow::Paint is similar
89 
90  rRenderContext.Push(PushFlags::ALL);
91  rRenderContext.SetClipRegion();
92 
93  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
94  Color aBgColor = rStyleSettings.GetWindowColor();
95 
96  m_xEditView->SetBackgroundColor(aBgColor);
97 
98  rRenderContext.SetBackground(aBgColor);
99 
100  tools::Rectangle aLogicRect(rRenderContext.PixelToLogic(rRect));
101  m_xEditView->Paint(aLogicRect, &rRenderContext);
102 
103  if (HasFocus())
104  {
105  m_xEditView->ShowCursor();
106  vcl::Cursor* pCursor = m_xEditView->GetCursor();
107  pCursor->DrawToDevice(rRenderContext);
108  }
109 
110  std::vector<tools::Rectangle> aLogicRects;
111 
112  // get logic selection
113  m_xEditView->GetSelectionRectangles(aLogicRects);
114 
115  rRenderContext.SetLineColor();
116  rRenderContext.SetFillColor(COL_BLACK);
117  rRenderContext.SetRasterOp(RasterOp::Invert);
118 
119  for (const auto& rSelectionRect : aLogicRects)
120  rRenderContext.DrawRect(rSelectionRect);
121 
122  rRenderContext.Pop();
123 }
124 
125 bool WeldEditView::MouseMove(const MouseEvent& rMEvt) { return m_xEditView->MouseMove(rMEvt); }
126 
128 {
129  if (!HasFocus())
130  {
131  GrabFocus();
132  GetFocus();
133  }
134 
135  return m_xEditView->MouseButtonDown(rMEvt);
136 }
137 
139 {
140  return m_xEditView->MouseButtonUp(rMEvt);
141 }
142 
144 {
145  sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();
146 
147  if (nKey == KEY_TAB)
148  {
149  return false;
150  }
151  else if (!m_xEditView->PostKeyEvent(rKEvt))
152  {
153  if (rKEvt.GetKeyCode().IsMod1() && !rKEvt.GetKeyCode().IsMod2())
154  {
155  if (nKey == KEY_A)
156  {
157  sal_Int32 nPar = m_xEditEngine->GetParagraphCount();
158  if (nPar)
159  {
160  sal_Int32 nLen = m_xEditEngine->GetTextLen(nPar - 1);
161  m_xEditView->SetSelection(ESelection(0, 0, nPar - 1, nLen));
162  }
163  return true;
164  }
165  }
166 
167  return false;
168  }
169 
170  return true;
171 }
172 
174 {
175  m_xEditView->Command(rCEvt);
176  return true;
177 }
178 
179 class WeldEditAccessible;
180 
181 namespace
182 {
183 class WeldViewForwarder : public SvxViewForwarder
184 {
185  WeldEditAccessible& m_rEditAcc;
186 
187  WeldViewForwarder(const WeldViewForwarder&) = delete;
188  WeldViewForwarder& operator=(const WeldViewForwarder&) = delete;
189 
190 public:
191  explicit WeldViewForwarder(WeldEditAccessible& rAcc)
192  : m_rEditAcc(rAcc)
193  {
194  }
195 
196  virtual bool IsValid() const override;
197  virtual Point LogicToPixel(const Point& rPoint, const MapMode& rMapMode) const override;
198  virtual Point PixelToLogic(const Point& rPoint, const MapMode& rMapMode) const override;
199 };
200 }
201 
202 class WeldEditAccessible;
203 
204 namespace
205 {
206 class WeldEditSource;
207 
208 /* analog to SvxEditEngineForwarder */
209 class WeldTextForwarder : public SvxTextForwarder
210 {
211  WeldEditAccessible& m_rEditAcc;
212  WeldEditSource& m_rEditSource;
213 
214  DECL_LINK(NotifyHdl, EENotify&, void);
215 
216  WeldTextForwarder(const WeldTextForwarder&) = delete;
217  WeldTextForwarder& operator=(const WeldTextForwarder&) = delete;
218 
219 public:
220  WeldTextForwarder(WeldEditAccessible& rAcc, WeldEditSource& rSource);
221  virtual ~WeldTextForwarder() override;
222 
223  virtual sal_Int32 GetParagraphCount() const override;
224  virtual sal_Int32 GetTextLen(sal_Int32 nParagraph) const override;
225  virtual OUString GetText(const ESelection& rSel) const override;
226  virtual SfxItemSet GetAttribs(const ESelection& rSel, EditEngineAttribs nOnlyHardAttrib
227  = EditEngineAttribs::All) const override;
228  virtual SfxItemSet GetParaAttribs(sal_Int32 nPara) const override;
229  virtual void SetParaAttribs(sal_Int32 nPara, const SfxItemSet& rSet) override;
230  virtual void RemoveAttribs(const ESelection& rSelection) override;
231  virtual void GetPortions(sal_Int32 nPara, std::vector<sal_Int32>& rList) const override;
232 
233  virtual SfxItemState GetItemState(const ESelection& rSel, sal_uInt16 nWhich) const override;
234  virtual SfxItemState GetItemState(sal_Int32 nPara, sal_uInt16 nWhich) const override;
235 
236  virtual void QuickInsertText(const OUString& rText, const ESelection& rSel) override;
237  virtual void QuickInsertField(const SvxFieldItem& rFld, const ESelection& rSel) override;
238  virtual void QuickSetAttribs(const SfxItemSet& rSet, const ESelection& rSel) override;
239  virtual void QuickInsertLineBreak(const ESelection& rSel) override;
240 
241  virtual SfxItemPool* GetPool() const override;
242 
243  virtual OUString CalcFieldValue(const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos,
244  o3tl::optional<Color>& rpTxtColor,
245  o3tl::optional<Color>& rpFldColor) override;
246  virtual void FieldClicked(const SvxFieldItem&) override;
247  virtual bool IsValid() const override;
248 
249  virtual LanguageType GetLanguage(sal_Int32, sal_Int32) const override;
250  virtual sal_Int32 GetFieldCount(sal_Int32 nPara) const override;
251  virtual EFieldInfo GetFieldInfo(sal_Int32 nPara, sal_uInt16 nField) const override;
252  virtual EBulletInfo GetBulletInfo(sal_Int32 nPara) const override;
253  virtual tools::Rectangle GetCharBounds(sal_Int32 nPara, sal_Int32 nIndex) const override;
254  virtual tools::Rectangle GetParaBounds(sal_Int32 nPara) const override;
255  virtual MapMode GetMapMode() const override;
256  virtual OutputDevice* GetRefDevice() const override;
257  virtual bool GetIndexAtPoint(const Point&, sal_Int32& nPara, sal_Int32& nIndex) const override;
258  virtual bool GetWordIndices(sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart,
259  sal_Int32& nEnd) const override;
260  virtual bool GetAttributeRun(sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nPara,
261  sal_Int32 nIndex, bool bInCell = false) const override;
262  virtual sal_Int32 GetLineCount(sal_Int32 nPara) const override;
263  virtual sal_Int32 GetLineLen(sal_Int32 nPara, sal_Int32 nLine) const override;
264  virtual void GetLineBoundaries(/*out*/ sal_Int32& rStart, /*out*/ sal_Int32& rEnd,
265  sal_Int32 nParagraph, sal_Int32 nLine) const override;
266  virtual sal_Int32 GetLineNumberAtIndex(sal_Int32 nPara, sal_Int32 nLine) const override;
267  virtual bool Delete(const ESelection&) override;
268  virtual bool InsertText(const OUString&, const ESelection&) override;
269  virtual bool QuickFormatDoc(bool bFull = false) override;
270 
271  virtual sal_Int16 GetDepth(sal_Int32 nPara) const override;
272  virtual bool SetDepth(sal_Int32 nPara, sal_Int16 nNewDepth) override;
273 
274  virtual const SfxItemSet* GetEmptyItemSetPtr() override;
275  // implementation functions for XParagraphAppend and XTextPortionAppend
276  virtual void AppendParagraph() override;
277  virtual sal_Int32 AppendTextPortion(sal_Int32 nPara, const OUString& rText,
278  const SfxItemSet& rSet) override;
279 
280  virtual void CopyText(const SvxTextForwarder& rSource) override;
281 };
282 
283 /* analog to SvxEditEngineViewForwarder */
284 class WeldEditViewForwarder : public SvxEditViewForwarder
285 {
286  WeldEditAccessible& m_rEditAcc;
287 
288  WeldEditViewForwarder(const WeldEditViewForwarder&) = delete;
289  WeldEditViewForwarder& operator=(const WeldEditViewForwarder&) = delete;
290 
291 public:
292  explicit WeldEditViewForwarder(WeldEditAccessible& rAcc);
293 
294  virtual bool IsValid() const override;
295 
296  virtual Point LogicToPixel(const Point& rPoint, const MapMode& rMapMode) const override;
297  virtual Point PixelToLogic(const Point& rPoint, const MapMode& rMapMode) const override;
298 
299  virtual bool GetSelection(ESelection& rSelection) const override;
300  virtual bool SetSelection(const ESelection& rSelection) override;
301  virtual bool Copy() override;
302  virtual bool Cut() override;
303  virtual bool Paste() override;
304 };
305 
306 class WeldEditSource : public SvxEditSource
307 {
308  SfxBroadcaster m_aBroadCaster;
309  WeldViewForwarder m_aViewFwd;
310  WeldTextForwarder m_aTextFwd;
311  WeldEditViewForwarder m_aEditViewFwd;
312  WeldEditAccessible& m_rEditAcc;
313 
314  WeldEditSource(const WeldEditSource& rSrc)
315  : SvxEditSource()
316  , m_aViewFwd(rSrc.m_rEditAcc)
317  , m_aTextFwd(rSrc.m_rEditAcc, *this)
318  , m_aEditViewFwd(rSrc.m_rEditAcc)
319  , m_rEditAcc(rSrc.m_rEditAcc)
320  {
321  }
322 
323  WeldEditSource& operator=(const WeldEditSource&) = delete;
324 
325 public:
326  WeldEditSource(WeldEditAccessible& rAcc)
327  : m_aViewFwd(rAcc)
328  , m_aTextFwd(rAcc, *this)
329  , m_aEditViewFwd(rAcc)
330  , m_rEditAcc(rAcc)
331  {
332  }
333 
334  virtual std::unique_ptr<SvxEditSource> Clone() const override
335  {
336  return std::unique_ptr<SvxEditSource>(new WeldEditSource(*this));
337  }
338 
339  virtual SvxTextForwarder* GetTextForwarder() override { return &m_aTextFwd; }
340 
341  virtual SvxViewForwarder* GetViewForwarder() override { return &m_aViewFwd; }
342 
343  virtual SvxEditViewForwarder* GetEditViewForwarder(bool /*bCreate*/) override
344  {
345  return &m_aEditViewFwd;
346  }
347 
348  virtual void UpdateData() override
349  {
350  // would possibly only by needed if the XText interface is implemented
351  // and its text needs to be updated.
352  }
353  virtual SfxBroadcaster& GetBroadcaster() const override
354  {
355  return const_cast<WeldEditSource*>(this)->m_aBroadCaster;
356  }
357 };
358 }
359 
360 typedef cppu::WeakImplHelper<
361  css::accessibility::XAccessible, css::accessibility::XAccessibleComponent,
362  css::accessibility::XAccessibleContext, css::accessibility::XAccessibleEventBroadcaster>
364 
366 {
370  std::unique_ptr<::accessibility::AccessibleTextHelper> m_xTextHelper;
371 
372 public:
374  : m_pController(pController)
375  , m_pEditEngine(nullptr)
376  , m_pEditView(nullptr)
377  {
378  }
379 
380  ::accessibility::AccessibleTextHelper* GetTextHelper() { return m_xTextHelper.get(); }
381 
382  void Init(EditEngine* pEditEngine, EditView* pEditView)
383  {
384  m_pEditEngine = pEditEngine;
385  m_pEditView = pEditView;
386  m_xTextHelper.reset(
387  new ::accessibility::AccessibleTextHelper(std::make_unique<WeldEditSource>(*this)));
388  m_xTextHelper->SetEventSource(this);
389  }
390 
393 
394  void ClearWin()
395  {
396  // remove handler before current object gets destroyed
397  // (avoid handler being called for already dead object)
398  m_pEditEngine->SetNotifyHdl(Link<EENotify&, void>());
399 
400  m_pEditEngine = nullptr;
401  m_pEditView = nullptr;
402  m_pController = nullptr; // implicitly results in AccessibleStateType::DEFUNC set
403 
405  m_xTextHelper->SetEditSource(::std::unique_ptr<SvxEditSource>());
406 
409  m_xTextHelper->Dispose();
410  m_xTextHelper.reset();
411  }
412 
413  // XAccessible
414  virtual css::uno::Reference<css::accessibility::XAccessibleContext>
415  SAL_CALL getAccessibleContext() override
416  {
417  return this;
418  }
419 
420  // XAccessibleComponent
421  virtual sal_Bool SAL_CALL containsPoint(const css::awt::Point& rPoint) override
422  {
425  SolarMutexGuard aGuard;
426  if (!m_pController)
427  throw css::uno::RuntimeException();
428 
429  Size aSz(m_pController->GetOutputSizePixel());
430  return rPoint.X >= 0 && rPoint.Y >= 0 && rPoint.X < aSz.Width() && rPoint.Y < aSz.Height();
431  }
432 
433  virtual css::uno::Reference<css::accessibility::XAccessible>
434  SAL_CALL getAccessibleAtPoint(const css::awt::Point& rPoint) override
435  {
436  SolarMutexGuard aGuard;
437  if (!m_xTextHelper)
438  throw css::uno::RuntimeException();
439 
440  return m_xTextHelper->GetAt(rPoint);
441  }
442 
443  virtual css::awt::Rectangle SAL_CALL getBounds() override
444  {
445  SolarMutexGuard aGuard;
446  if (!m_pController)
447  throw css::uno::RuntimeException();
448 
449  const Point aOutPos;
450  const Size aOutSize(m_pController->GetOutputSizePixel());
451  css::awt::Rectangle aRet;
452 
453  aRet.X = aOutPos.X();
454  aRet.Y = aOutPos.Y();
455  aRet.Width = aOutSize.Width();
456  aRet.Height = aOutSize.Height();
457 
458  return aRet;
459  }
460 
461  virtual css::awt::Point SAL_CALL getLocation() override
462  {
463  SolarMutexGuard aGuard;
464  if (!m_pController)
465  throw css::uno::RuntimeException();
466 
467  const css::awt::Rectangle aRect(getBounds());
468  css::awt::Point aRet;
469 
470  aRet.X = aRect.X;
471  aRet.Y = aRect.Y;
472 
473  return aRet;
474  }
475 
476  virtual css::awt::Point SAL_CALL getLocationOnScreen() override
477  {
478  SolarMutexGuard aGuard;
479  if (!m_pController)
480  throw css::uno::RuntimeException();
481 
482  css::awt::Point aScreenLoc(0, 0);
483 
484  css::uno::Reference<css::accessibility::XAccessible> xParent(getAccessibleParent());
485  if (xParent)
486  {
487  css::uno::Reference<css::accessibility::XAccessibleContext> xParentContext(
488  xParent->getAccessibleContext());
489  css::uno::Reference<css::accessibility::XAccessibleComponent> xParentComponent(
490  xParentContext, css::uno::UNO_QUERY);
491  OSL_ENSURE(xParentComponent.is(),
492  "WeldEditAccessible::getLocationOnScreen: no parent component!");
493  if (xParentComponent.is())
494  {
495  css::awt::Point aParentScreenLoc(xParentComponent->getLocationOnScreen());
496  css::awt::Point aOwnRelativeLoc(getLocation());
497  aScreenLoc.X = aParentScreenLoc.X + aOwnRelativeLoc.X;
498  aScreenLoc.Y = aParentScreenLoc.Y + aOwnRelativeLoc.Y;
499  }
500  }
501 
502  return aScreenLoc;
503  }
504 
505  virtual css::awt::Size SAL_CALL getSize() override
506  {
507  SolarMutexGuard aGuard;
508  if (!m_pController)
509  throw css::uno::RuntimeException();
510 
511  Size aSz(m_pController->GetOutputSizePixel());
512  return css::awt::Size(aSz.Width(), aSz.Height());
513  }
514 
515  virtual void SAL_CALL grabFocus() override { m_pController->GrabFocus(); }
516 
517  virtual sal_Int32 SAL_CALL getForeground() override
518  {
519  SolarMutexGuard aGuard;
520  if (!m_pController)
521  throw css::uno::RuntimeException();
522 
523  Color nCol = m_pEditEngine->GetAutoColor();
524  return static_cast<sal_Int32>(nCol);
525  }
526 
527  virtual sal_Int32 SAL_CALL getBackground() override
528  {
529  SolarMutexGuard aGuard;
530  if (!m_pController)
531  throw css::uno::RuntimeException();
532 
533  Color nCol = m_pEditEngine->GetBackgroundColor();
534  return static_cast<sal_Int32>(nCol);
535  }
536 
537  // XAccessibleContext
538  virtual sal_Int32 SAL_CALL getAccessibleChildCount() override
539  {
540  if (m_xTextHelper)
541  return m_xTextHelper->GetChildCount();
542  return 0;
543  }
544 
545  virtual css::uno::Reference<css::accessibility::XAccessible>
546  SAL_CALL getAccessibleChild(sal_Int32 i) override
547  {
548  if (m_xTextHelper)
549  return m_xTextHelper->GetChild(i);
550  throw css::lang::IndexOutOfBoundsException(); // there is no child...
551  }
552 
553  virtual css::uno::Reference<css::accessibility::XAccessible>
554  SAL_CALL getAccessibleParent() override
555  {
556  SolarMutexGuard aGuard;
557  if (!m_pController)
558  throw css::uno::RuntimeException();
559 
560  return m_pController->GetDrawingArea()->get_accessible_parent();
561  }
562 
563  virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() override
564  {
565  SolarMutexGuard aGuard;
566  if (!m_pController)
567  throw css::uno::RuntimeException();
568 
569  // -1 for child not found/no parent (according to specification)
570  sal_Int32 nRet = -1;
571 
572  css::uno::Reference<css::accessibility::XAccessible> xParent(getAccessibleParent());
573  if (!xParent)
574  return nRet;
575 
576  try
577  {
578  css::uno::Reference<css::accessibility::XAccessibleContext> xParentContext(
579  xParent->getAccessibleContext());
580 
581  // iterate over parent's children and search for this object
582  if (xParentContext.is())
583  {
584  sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
585  for (sal_Int32 nChild = 0; (nChild < nChildCount) && (-1 == nRet); ++nChild)
586  {
587  css::uno::Reference<css::accessibility::XAccessible> xChild(
588  xParentContext->getAccessibleChild(nChild));
589  if (xChild.get() == this)
590  nRet = nChild;
591  }
592  }
593  }
594  catch (const css::uno::Exception&)
595  {
596  OSL_FAIL("WeldEditAccessible::getAccessibleIndexInParent: caught an exception!");
597  }
598 
599  return nRet;
600  }
601 
602  virtual sal_Int16 SAL_CALL getAccessibleRole() override
603  {
604  return css::accessibility::AccessibleRole::TEXT_FRAME;
605  }
606 
607  virtual OUString SAL_CALL getAccessibleDescription() override
608  {
609  SolarMutexGuard aGuard;
610 
611  OUString aRet;
612 
613  if (m_pController)
614  {
615  aRet = m_pController->GetAccessibleDescription();
616  }
617 
618  return aRet;
619  }
620 
621  virtual OUString SAL_CALL getAccessibleName() override
622  {
623  SolarMutexGuard aGuard;
624 
625  OUString aRet;
626 
627  if (m_pController)
628  {
629  aRet = m_pController->GetAccessibleName();
630  }
631 
632  return aRet;
633  }
634 
635  virtual css::uno::Reference<css::accessibility::XAccessibleRelationSet>
636  SAL_CALL getAccessibleRelationSet() override
637  {
638  SolarMutexGuard aGuard;
639  if (!m_pController)
640  throw css::uno::RuntimeException();
641 
642  return m_pController->GetDrawingArea()->get_accessible_relation_set();
643  }
644 
645  virtual css::uno::Reference<css::accessibility::XAccessibleStateSet>
646  SAL_CALL getAccessibleStateSet() override
647  {
648  SolarMutexGuard aGuard;
649  ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper;
650 
651  css::uno::Reference<css::accessibility::XAccessibleStateSet> xStateSet(pStateSet);
652 
653  if (!m_pController || !m_xTextHelper)
654  pStateSet->AddState(css::accessibility::AccessibleStateType::DEFUNC);
655  else
656  {
657  pStateSet->AddState(css::accessibility::AccessibleStateType::MULTI_LINE);
658  pStateSet->AddState(css::accessibility::AccessibleStateType::ENABLED);
659  pStateSet->AddState(css::accessibility::AccessibleStateType::EDITABLE);
660  pStateSet->AddState(css::accessibility::AccessibleStateType::FOCUSABLE);
661  pStateSet->AddState(css::accessibility::AccessibleStateType::SELECTABLE);
662  if (m_pController->HasFocus())
663  pStateSet->AddState(css::accessibility::AccessibleStateType::FOCUSED);
664  if (m_pController->IsActive())
665  pStateSet->AddState(css::accessibility::AccessibleStateType::ACTIVE);
666  if (m_pController->IsVisible())
667  pStateSet->AddState(css::accessibility::AccessibleStateType::SHOWING);
668  if (m_pController->IsReallyVisible())
669  pStateSet->AddState(css::accessibility::AccessibleStateType::VISIBLE);
670  if (COL_TRANSPARENT != m_pEditEngine->GetBackgroundColor())
671  pStateSet->AddState(css::accessibility::AccessibleStateType::OPAQUE);
672  }
673 
674  return xStateSet;
675  }
676 
677  virtual css::lang::Locale SAL_CALL getLocale() override
678  {
679  SolarMutexGuard aGuard;
680  return LanguageTag(m_pEditEngine->GetDefaultLanguage()).getLocale();
681  }
682 
683  // XAccessibleEventBroadcaster
684  virtual void SAL_CALL addAccessibleEventListener(
685  const css::uno::Reference<css::accessibility::XAccessibleEventListener>& rListener) override
686  {
687  if (!m_xTextHelper) // not disposing (about to destroy view shell)
688  return;
689  m_xTextHelper->AddEventListener(rListener);
690  }
691 
692  virtual void SAL_CALL removeAccessibleEventListener(
693  const css::uno::Reference<css::accessibility::XAccessibleEventListener>& rListener) override
694  {
695  if (!m_xTextHelper) // not disposing (about to destroy view shell)
696  return;
697  m_xTextHelper->RemoveEventListener(rListener);
698  }
699 };
700 
701 css::uno::Reference<css::accessibility::XAccessible> WeldEditView::CreateAccessible()
702 {
703  if (!m_xAccessible.is())
704  m_xAccessible.set(new WeldEditAccessible(this));
705  return css::uno::Reference<css::accessibility::XAccessible>(m_xAccessible.get());
706 }
707 
709 {
710  if (m_xAccessible.is())
711  {
712  m_xAccessible->ClearWin(); // make Accessible nonfunctional
713  m_xAccessible.clear();
714  }
715 }
716 
717 bool WeldViewForwarder::IsValid() const { return m_rEditAcc.GetEditView() != nullptr; }
718 
719 Point WeldViewForwarder::LogicToPixel(const Point& rPoint, const MapMode& rMapMode) const
720 {
721  EditView* pEditView = m_rEditAcc.GetEditView();
722  OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : nullptr;
723 
724  if (pOutDev)
725  {
726  MapMode aMapMode(pOutDev->GetMapMode());
727  Point aPoint(OutputDevice::LogicToLogic(rPoint, rMapMode, MapMode(aMapMode.GetMapUnit())));
728  aMapMode.SetOrigin(Point());
729  return pOutDev->LogicToPixel(aPoint, aMapMode);
730  }
731 
732  return Point();
733 }
734 
735 Point WeldViewForwarder::PixelToLogic(const Point& rPoint, const MapMode& rMapMode) const
736 {
737  EditView* pEditView = m_rEditAcc.GetEditView();
738  OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : nullptr;
739 
740  if (pOutDev)
741  {
742  MapMode aMapMode(pOutDev->GetMapMode());
743  aMapMode.SetOrigin(Point());
744  Point aPoint(pOutDev->PixelToLogic(rPoint, aMapMode));
745  return OutputDevice::LogicToLogic(aPoint, MapMode(aMapMode.GetMapUnit()), rMapMode);
746  }
747 
748  return Point();
749 }
750 
751 WeldTextForwarder::WeldTextForwarder(WeldEditAccessible& rAcc, WeldEditSource& rSource)
752  : m_rEditAcc(rAcc)
753  , m_rEditSource(rSource)
754 {
755  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
756  if (pEditEngine)
757  pEditEngine->SetNotifyHdl(LINK(this, WeldTextForwarder, NotifyHdl));
758 }
759 
760 WeldTextForwarder::~WeldTextForwarder()
761 {
762  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
763  if (pEditEngine)
764  pEditEngine->SetNotifyHdl(Link<EENotify&, void>());
765 }
766 
767 IMPL_LINK(WeldTextForwarder, NotifyHdl, EENotify&, rNotify, void)
768 {
769  ::std::unique_ptr<SfxHint> aHint = SvxEditSourceHelper::EENotification2Hint(&rNotify);
770  if (aHint)
771  m_rEditSource.GetBroadcaster().Broadcast(*aHint);
772 }
773 
774 sal_Int32 WeldTextForwarder::GetParagraphCount() const
775 {
776  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
777  return pEditEngine ? pEditEngine->GetParagraphCount() : 0;
778 }
779 
780 sal_Int32 WeldTextForwarder::GetTextLen(sal_Int32 nParagraph) const
781 {
782  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
783  return pEditEngine ? pEditEngine->GetTextLen(nParagraph) : 0;
784 }
785 
786 OUString WeldTextForwarder::GetText(const ESelection& rSel) const
787 {
788  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
789  OUString aRet;
790  if (pEditEngine)
791  aRet = pEditEngine->GetText(rSel);
792  return convertLineEnd(aRet, GetSystemLineEnd());
793 }
794 
795 SfxItemSet WeldTextForwarder::GetAttribs(const ESelection& rSel,
796  EditEngineAttribs nOnlyHardAttrib) const
797 {
798  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
799  assert(pEditEngine && "EditEngine missing");
800  if (rSel.nStartPara == rSel.nEndPara)
801  {
802  GetAttribsFlags nFlags = GetAttribsFlags::NONE;
803  switch (nOnlyHardAttrib)
804  {
805  case EditEngineAttribs::All:
806  nFlags = GetAttribsFlags::ALL;
807  break;
808  case EditEngineAttribs::OnlyHard:
809  nFlags = GetAttribsFlags::CHARATTRIBS;
810  break;
811  default:
812  SAL_WARN("svx", "unknown flags for WeldTextForwarder::GetAttribs");
813  }
814 
815  return pEditEngine->GetAttribs(rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags);
816  }
817  else
818  {
819  return pEditEngine->GetAttribs(rSel, nOnlyHardAttrib);
820  }
821 }
822 
823 SfxItemSet WeldTextForwarder::GetParaAttribs(sal_Int32 nPara) const
824 {
825  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
826  assert(pEditEngine && "EditEngine missing");
827 
828  SfxItemSet aSet(pEditEngine->GetParaAttribs(nPara));
829 
830  sal_uInt16 nWhich = EE_PARA_START;
831  while (nWhich <= EE_PARA_END)
832  {
833  if (aSet.GetItemState(nWhich) != SfxItemState::SET)
834  {
835  if (pEditEngine->HasParaAttrib(nPara, nWhich))
836  aSet.Put(pEditEngine->GetParaAttrib(nPara, nWhich));
837  }
838  nWhich++;
839  }
840 
841  return aSet;
842 }
843 
844 void WeldTextForwarder::SetParaAttribs(sal_Int32 nPara, const SfxItemSet& rSet)
845 {
846  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
847  if (pEditEngine)
848  pEditEngine->SetParaAttribs(nPara, rSet);
849 }
850 
851 SfxItemPool* WeldTextForwarder::GetPool() const
852 {
853  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
854  return pEditEngine ? pEditEngine->GetEmptyItemSet().GetPool() : nullptr;
855 }
856 
857 void WeldTextForwarder::RemoveAttribs(const ESelection& rSelection)
858 {
859  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
860  if (pEditEngine)
861  pEditEngine->RemoveAttribs(rSelection, false /*bRemoveParaAttribs*/, 0);
862 }
863 
864 void WeldTextForwarder::GetPortions(sal_Int32 nPara, std::vector<sal_Int32>& rList) const
865 {
866  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
867  if (pEditEngine)
868  pEditEngine->GetPortions(nPara, rList);
869 }
870 
871 void WeldTextForwarder::QuickInsertText(const OUString& rText, const ESelection& rSel)
872 {
873  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
874  if (pEditEngine)
875  pEditEngine->QuickInsertText(rText, rSel);
876 }
877 
878 void WeldTextForwarder::QuickInsertLineBreak(const ESelection& rSel)
879 {
880  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
881  if (pEditEngine)
882  pEditEngine->QuickInsertLineBreak(rSel);
883 }
884 
885 void WeldTextForwarder::QuickInsertField(const SvxFieldItem& rFld, const ESelection& rSel)
886 {
887  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
888  if (pEditEngine)
889  pEditEngine->QuickInsertField(rFld, rSel);
890 }
891 
892 void WeldTextForwarder::QuickSetAttribs(const SfxItemSet& rSet, const ESelection& rSel)
893 {
894  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
895  if (pEditEngine)
896  pEditEngine->QuickSetAttribs(rSet, rSel);
897 }
898 
899 bool WeldTextForwarder::IsValid() const
900 {
901  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
902  // cannot reliably query EditEngine state
903  // while in the middle of an update
904  return pEditEngine && pEditEngine->GetUpdateMode();
905 }
906 
907 OUString WeldTextForwarder::CalcFieldValue(const SvxFieldItem& rField, sal_Int32 nPara,
908  sal_Int32 nPos, o3tl::optional<Color>& rpTxtColor,
909  o3tl::optional<Color>& rpFldColor)
910 {
911  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
912  return pEditEngine ? pEditEngine->CalcFieldValue(rField, nPara, nPos, rpTxtColor, rpFldColor)
913  : OUString();
914 }
915 
916 void WeldTextForwarder::FieldClicked(const SvxFieldItem&) {}
917 
918 static SfxItemState GetSvxEditEngineItemState(EditEngine const& rEditEngine, const ESelection& rSel,
919  sal_uInt16 nWhich)
920 {
921  std::vector<EECharAttrib> aAttribs;
922 
923  const SfxPoolItem* pLastItem = nullptr;
924 
925  SfxItemState eState = SfxItemState::DEFAULT;
926 
927  // check all paragraphs inside the selection
928  for (sal_Int32 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++)
929  {
930  SfxItemState eParaState = SfxItemState::DEFAULT;
931 
932  // calculate start and endpos for this paragraph
933  sal_Int32 nPos = 0;
934  if (rSel.nStartPara == nPara)
935  nPos = rSel.nStartPos;
936 
937  sal_Int32 nEndPos = rSel.nEndPos;
938  if (rSel.nEndPara != nPara)
939  nEndPos = rEditEngine.GetTextLen(nPara);
940 
941  // get list of char attribs
942  rEditEngine.GetCharAttribs(nPara, aAttribs);
943 
944  bool bEmpty = true; // we found no item inside the selection of this paragraph
945  bool bGaps = false; // we found items but there are gaps between them
946  sal_Int32 nLastEnd = nPos;
947 
948  const SfxPoolItem* pParaItem = nullptr;
949 
950  for (const auto& rAttrib : aAttribs)
951  {
952  OSL_ENSURE(rAttrib.pAttr, "GetCharAttribs gives corrupt data");
953 
954  const bool bEmptyPortion = (rAttrib.nStart == rAttrib.nEnd);
955  if ((!bEmptyPortion && (rAttrib.nStart >= nEndPos))
956  || (bEmptyPortion && (rAttrib.nStart > nEndPos)))
957  break; // break if we are already behind our selection
958 
959  if ((!bEmptyPortion && (rAttrib.nEnd <= nPos))
960  || (bEmptyPortion && (rAttrib.nEnd < nPos)))
961  continue; // or if the attribute ends before our selection
962 
963  if (rAttrib.pAttr->Which() != nWhich)
964  continue; // skip if is not the searched item
965 
966  // if we already found an item
967  if (pParaItem)
968  {
969  // ... and its different to this one than the state is don't care
970  if (*pParaItem != *(rAttrib.pAttr))
971  return SfxItemState::DONTCARE;
972  }
973  else
974  {
975  pParaItem = rAttrib.pAttr;
976  }
977 
978  if (bEmpty)
979  bEmpty = false;
980 
981  if (!bGaps && rAttrib.nStart > nLastEnd)
982  bGaps = true;
983 
984  nLastEnd = rAttrib.nEnd;
985  }
986 
987  if (!bEmpty && !bGaps && nLastEnd < (nEndPos - 1))
988  bGaps = true;
989  if (bEmpty)
990  eParaState = SfxItemState::DEFAULT;
991  else if (bGaps)
992  eParaState = SfxItemState::DONTCARE;
993  else
994  eParaState = SfxItemState::SET;
995 
996  // if we already found an item check if we found the same
997  if (pLastItem)
998  {
999  if ((pParaItem == nullptr) || (*pLastItem != *pParaItem))
1000  return SfxItemState::DONTCARE;
1001  }
1002  else
1003  {
1004  pLastItem = pParaItem;
1005  eState = eParaState;
1006  }
1007  }
1008 
1009  return eState;
1010 }
1011 
1012 SfxItemState WeldTextForwarder::GetItemState(const ESelection& rSel, sal_uInt16 nWhich) const
1013 {
1014  SfxItemState nState = SfxItemState::DISABLED;
1015  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1016  if (pEditEngine)
1017  nState = GetSvxEditEngineItemState(*pEditEngine, rSel, nWhich);
1018  return nState;
1019 }
1020 
1021 SfxItemState WeldTextForwarder::GetItemState(sal_Int32 nPara, sal_uInt16 nWhich) const
1022 {
1023  SfxItemState nState = SfxItemState::DISABLED;
1024  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1025  if (pEditEngine)
1026  {
1027  const SfxItemSet& rSet = pEditEngine->GetParaAttribs(nPara);
1028  nState = rSet.GetItemState(nWhich);
1029  }
1030  return nState;
1031 }
1032 
1033 LanguageType WeldTextForwarder::GetLanguage(sal_Int32 nPara, sal_Int32 nIndex) const
1034 {
1035  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1036  return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex) : LANGUAGE_NONE;
1037 }
1038 
1039 sal_Int32 WeldTextForwarder::GetFieldCount(sal_Int32 nPara) const
1040 {
1041  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1042  return pEditEngine ? pEditEngine->GetFieldCount(nPara) : 0;
1043 }
1044 
1045 EFieldInfo WeldTextForwarder::GetFieldInfo(sal_Int32 nPara, sal_uInt16 nField) const
1046 {
1047  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1048  return pEditEngine ? pEditEngine->GetFieldInfo(nPara, nField) : EFieldInfo();
1049 }
1050 
1051 EBulletInfo WeldTextForwarder::GetBulletInfo(sal_Int32 /*nPara*/) const { return EBulletInfo(); }
1052 
1053 tools::Rectangle WeldTextForwarder::GetCharBounds(sal_Int32 nPara, sal_Int32 nIndex) const
1054 {
1055  tools::Rectangle aRect(0, 0, 0, 0);
1056  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1057 
1058  if (pEditEngine)
1059  {
1060  // Handle virtual position one-past-the end of the string
1061  if (nIndex >= pEditEngine->GetTextLen(nPara))
1062  {
1063  if (nIndex)
1064  aRect = pEditEngine->GetCharacterBounds(EPosition(nPara, nIndex - 1));
1065 
1066  aRect.Move(aRect.Right() - aRect.Left(), 0);
1067  aRect.SetSize(Size(1, pEditEngine->GetTextHeight()));
1068  }
1069  else
1070  {
1071  aRect = pEditEngine->GetCharacterBounds(EPosition(nPara, nIndex));
1072  }
1073  }
1074  return aRect;
1075 }
1076 
1077 tools::Rectangle WeldTextForwarder::GetParaBounds(sal_Int32 nPara) const
1078 {
1079  tools::Rectangle aRect(0, 0, 0, 0);
1080  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1081 
1082  if (pEditEngine)
1083  {
1084  const Point aPnt = pEditEngine->GetDocPosTopLeft(nPara);
1085  const sal_uLong nWidth = pEditEngine->CalcTextWidth();
1086  const sal_uLong nHeight = pEditEngine->GetTextHeight(nPara);
1087  aRect = tools::Rectangle(aPnt.X(), aPnt.Y(), aPnt.X() + nWidth, aPnt.Y() + nHeight);
1088  }
1089 
1090  return aRect;
1091 }
1092 
1093 MapMode WeldTextForwarder::GetMapMode() const
1094 {
1095  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1096  return pEditEngine ? pEditEngine->GetRefMapMode() : MapMode(MapUnit::Map100thMM);
1097 }
1098 
1099 OutputDevice* WeldTextForwarder::GetRefDevice() const
1100 {
1101  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1102  return pEditEngine ? pEditEngine->GetRefDevice() : nullptr;
1103 }
1104 
1105 bool WeldTextForwarder::GetIndexAtPoint(const Point& rPos, sal_Int32& nPara,
1106  sal_Int32& nIndex) const
1107 {
1108  bool bRes = false;
1109  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1110  if (pEditEngine)
1111  {
1112  EPosition aDocPos = pEditEngine->FindDocPosition(rPos);
1113  nPara = aDocPos.nPara;
1114  nIndex = aDocPos.nIndex;
1115  bRes = true;
1116  }
1117  return bRes;
1118 }
1119 
1120 bool WeldTextForwarder::GetWordIndices(sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart,
1121  sal_Int32& nEnd) const
1122 {
1123  bool bRes = false;
1124  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1125  if (pEditEngine)
1126  {
1127  ESelection aRes = pEditEngine->GetWord(ESelection(nPara, nIndex, nPara, nIndex),
1128  css::i18n::WordType::DICTIONARY_WORD);
1129 
1130  if (aRes.nStartPara == nPara && aRes.nStartPara == aRes.nEndPara)
1131  {
1132  nStart = aRes.nStartPos;
1133  nEnd = aRes.nEndPos;
1134 
1135  bRes = true;
1136  }
1137  }
1138 
1139  return bRes;
1140 }
1141 
1142 bool WeldTextForwarder::GetAttributeRun(sal_Int32& nStartIndex, sal_Int32& nEndIndex,
1143  sal_Int32 nPara, sal_Int32 nIndex, bool bInCell) const
1144 {
1145  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1146  if (!pEditEngine)
1147  return false;
1148  SvxEditSourceHelper::GetAttributeRun(nStartIndex, nEndIndex, *pEditEngine, nPara, nIndex,
1149  bInCell);
1150  return true;
1151 }
1152 
1153 sal_Int32 WeldTextForwarder::GetLineCount(sal_Int32 nPara) const
1154 {
1155  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1156  return pEditEngine ? pEditEngine->GetLineCount(nPara) : 0;
1157 }
1158 
1159 sal_Int32 WeldTextForwarder::GetLineLen(sal_Int32 nPara, sal_Int32 nLine) const
1160 {
1161  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1162  return pEditEngine ? pEditEngine->GetLineLen(nPara, nLine) : 0;
1163 }
1164 
1165 void WeldTextForwarder::GetLineBoundaries(/*out*/ sal_Int32& rStart, /*out*/ sal_Int32& rEnd,
1166  sal_Int32 nPara, sal_Int32 nLine) const
1167 {
1168  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1169  if (pEditEngine)
1170  pEditEngine->GetLineBoundaries(rStart, rEnd, nPara, nLine);
1171  else
1172  rStart = rEnd = 0;
1173 }
1174 
1175 sal_Int32 WeldTextForwarder::GetLineNumberAtIndex(sal_Int32 nPara, sal_Int32 nIndex) const
1176 {
1177  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1178  return pEditEngine ? pEditEngine->GetLineNumberAtIndex(nPara, nIndex) : 0;
1179 }
1180 
1181 bool WeldTextForwarder::QuickFormatDoc(bool /*bFull*/)
1182 {
1183  bool bRes = false;
1184  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1185  if (pEditEngine)
1186  {
1187  pEditEngine->QuickFormatDoc();
1188  bRes = true;
1189  }
1190  return bRes;
1191 }
1192 
1193 sal_Int16 WeldTextForwarder::GetDepth(sal_Int32 /*nPara*/) const
1194 {
1195  // math has no outliner...
1196  return -1;
1197 }
1198 
1199 bool WeldTextForwarder::SetDepth(sal_Int32 /*nPara*/, sal_Int16 nNewDepth)
1200 {
1201  // math has no outliner...
1202  return -1 == nNewDepth; // is it the value from 'GetDepth' ?
1203 }
1204 
1205 bool WeldTextForwarder::Delete(const ESelection& rSelection)
1206 {
1207  bool bRes = false;
1208  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1209  if (pEditEngine)
1210  {
1211  pEditEngine->QuickDelete(rSelection);
1212  pEditEngine->QuickFormatDoc();
1213  bRes = true;
1214  }
1215  return bRes;
1216 }
1217 
1218 bool WeldTextForwarder::InsertText(const OUString& rStr, const ESelection& rSelection)
1219 {
1220  bool bRes = false;
1221  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1222  if (pEditEngine)
1223  {
1224  pEditEngine->QuickInsertText(rStr, rSelection);
1225  pEditEngine->QuickFormatDoc();
1226  bRes = true;
1227  }
1228  return bRes;
1229 }
1230 
1231 const SfxItemSet* WeldTextForwarder::GetEmptyItemSetPtr()
1232 {
1233  const SfxItemSet* pItemSet = nullptr;
1234  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1235  if (pEditEngine)
1236  {
1237  pItemSet = &pEditEngine->GetEmptyItemSet();
1238  }
1239  return pItemSet;
1240 }
1241 
1242 void WeldTextForwarder::AppendParagraph()
1243 {
1244  // append an empty paragraph
1245  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1246  if (pEditEngine)
1247  {
1248  sal_Int32 nParaCount = pEditEngine->GetParagraphCount();
1249  pEditEngine->InsertParagraph(nParaCount, OUString());
1250  }
1251 }
1252 
1253 sal_Int32 WeldTextForwarder::AppendTextPortion(sal_Int32 nPara, const OUString& rText,
1254  const SfxItemSet& rSet)
1255 {
1256  sal_uInt16 nRes = 0;
1257  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1258  if (pEditEngine && nPara < pEditEngine->GetParagraphCount())
1259  {
1260  // append text
1261  ESelection aSel(nPara, pEditEngine->GetTextLen(nPara));
1262  pEditEngine->QuickInsertText(rText, aSel);
1263 
1264  // set attributes for new appended text
1265  nRes = aSel.nEndPos = pEditEngine->GetTextLen(nPara);
1266  pEditEngine->QuickSetAttribs(rSet, aSel);
1267  }
1268  return nRes;
1269 }
1270 
1271 void WeldTextForwarder::CopyText(const SvxTextForwarder& rSource)
1272 {
1273  const WeldTextForwarder* pSourceForwarder = dynamic_cast<const WeldTextForwarder*>(&rSource);
1274  if (!pSourceForwarder)
1275  return;
1276  EditEngine* pSourceEditEngine = pSourceForwarder->m_rEditAcc.GetEditEngine();
1277  EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
1278  if (pEditEngine && pSourceEditEngine)
1279  {
1280  std::unique_ptr<EditTextObject> pNewTextObject = pSourceEditEngine->CreateTextObject();
1281  pEditEngine->SetText(*pNewTextObject);
1282  }
1283 }
1284 
1285 WeldEditViewForwarder::WeldEditViewForwarder(WeldEditAccessible& rAcc)
1286  : m_rEditAcc(rAcc)
1287 {
1288 }
1289 
1290 bool WeldEditViewForwarder::IsValid() const { return m_rEditAcc.GetEditView() != nullptr; }
1291 
1292 Point WeldEditViewForwarder::LogicToPixel(const Point& rPoint, const MapMode& rMapMode) const
1293 {
1294  EditView* pEditView = m_rEditAcc.GetEditView();
1295  OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : nullptr;
1296 
1297  if (pOutDev)
1298  {
1299  MapMode aMapMode(pOutDev->GetMapMode());
1300  Point aPoint(OutputDevice::LogicToLogic(rPoint, rMapMode, MapMode(aMapMode.GetMapUnit())));
1301  aMapMode.SetOrigin(Point());
1302  return pOutDev->LogicToPixel(aPoint, aMapMode);
1303  }
1304 
1305  return Point();
1306 }
1307 
1308 Point WeldEditViewForwarder::PixelToLogic(const Point& rPoint, const MapMode& rMapMode) const
1309 {
1310  EditView* pEditView = m_rEditAcc.GetEditView();
1311  OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : nullptr;
1312 
1313  if (pOutDev)
1314  {
1315  MapMode aMapMode(pOutDev->GetMapMode());
1316  aMapMode.SetOrigin(Point());
1317  Point aPoint(pOutDev->PixelToLogic(rPoint, aMapMode));
1318  return OutputDevice::LogicToLogic(aPoint, MapMode(aMapMode.GetMapUnit()), rMapMode);
1319  }
1320 
1321  return Point();
1322 }
1323 
1324 bool WeldEditViewForwarder::GetSelection(ESelection& rSelection) const
1325 {
1326  bool bRes = false;
1327  EditView* pEditView = m_rEditAcc.GetEditView();
1328  if (pEditView)
1329  {
1330  rSelection = pEditView->GetSelection();
1331  bRes = true;
1332  }
1333  return bRes;
1334 }
1335 
1336 bool WeldEditViewForwarder::SetSelection(const ESelection& rSelection)
1337 {
1338  bool bRes = false;
1339  EditView* pEditView = m_rEditAcc.GetEditView();
1340  if (pEditView)
1341  {
1342  pEditView->SetSelection(rSelection);
1343  bRes = true;
1344  }
1345  return bRes;
1346 }
1347 
1348 bool WeldEditViewForwarder::Copy()
1349 {
1350  bool bRes = false;
1351  EditView* pEditView = m_rEditAcc.GetEditView();
1352  if (pEditView)
1353  {
1354  pEditView->Copy();
1355  bRes = true;
1356  }
1357  return bRes;
1358 }
1359 
1360 bool WeldEditViewForwarder::Cut()
1361 {
1362  bool bRes = false;
1363  EditView* pEditView = m_rEditAcc.GetEditView();
1364  if (pEditView)
1365  {
1366  pEditView->Cut();
1367  bRes = true;
1368  }
1369  return bRes;
1370 }
1371 
1372 bool WeldEditViewForwarder::Paste()
1373 {
1374  bool bRes = false;
1375  EditView* pEditView = m_rEditAcc.GetEditView();
1376  if (pEditView)
1377  {
1378  pEditView->Paste();
1379  bRes = true;
1380  }
1381  return bRes;
1382 }
1383 
1385 {
1386  Size aSize(pDrawingArea->get_size_request());
1387  if (aSize.Width() == -1)
1388  aSize.setWidth(500);
1389  if (aSize.Height() == -1)
1390  aSize.setHeight(100);
1391  pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
1392 
1393  SetOutputSizePixel(aSize);
1394 
1396 
1397  EnableRTL(false);
1398 
1399  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1400  Color aBgColor = rStyleSettings.GetWindowColor();
1401 
1402  OutputDevice& rDevice = pDrawingArea->get_ref_device();
1403 
1404  rDevice.SetMapMode(MapMode(MapUnit::MapTwip));
1405  rDevice.SetBackground(aBgColor);
1406 
1407  Size aOutputSize(rDevice.PixelToLogic(aSize));
1408  aSize = aOutputSize;
1409  aSize.setHeight(aSize.Height());
1410 
1411  makeEditEngine();
1412  m_xEditEngine->SetPaperSize(aSize);
1413  m_xEditEngine->SetRefDevice(&rDevice);
1414 
1415  m_xEditEngine->SetControlWord(m_xEditEngine->GetControlWord() | EEControlBits::MARKFIELDS);
1416 
1417  m_xEditView.reset(new EditView(m_xEditEngine.get(), nullptr));
1418  m_xEditView->setEditViewCallbacks(this);
1419  m_xEditView->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize));
1420 
1421  m_xEditView->SetBackgroundColor(aBgColor);
1422  m_xEditEngine->InsertView(m_xEditView.get());
1423 
1424  pDrawingArea->set_cursor(PointerStyle::Text);
1425 
1426  if (m_xAccessible.is())
1427  m_xAccessible->Init(m_xEditEngine.get(), m_xEditView.get());
1428 }
1429 
1431 {
1432  m_xEditView->ShowCursor();
1433 
1435 
1436  if (m_xAccessible.is())
1437  {
1438  // Note: will implicitly send the AccessibleStateType::FOCUSED event
1439  ::accessibility::AccessibleTextHelper* pHelper = m_xAccessible->GetTextHelper();
1440  if (pHelper)
1441  pHelper->SetFocus();
1442  }
1443 }
1444 
1446 {
1448  Invalidate(); // redraw without cursor
1449 
1450  if (m_xAccessible.is())
1451  {
1452  // Note: will implicitly send the AccessibleStateType::FOCUSED event
1453  ::accessibility::AccessibleTextHelper* pHelper = m_xAccessible->GetTextHelper();
1454  if (pHelper)
1455  pHelper->SetFocus(false);
1456  }
1457 }
1458 
1459 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetClipRegion()
long Width() const
void QuickInsertLineBreak(const ESelection &rSel)
#define LANGUAGE_NONE
OUString GetText(LineEnd eEnd=LINEEND_LF) const
#define EE_CHAR_FONTINFO
sal_Int32 nStartPara
virtual tools::Rectangle GetParaBounds(sal_Int32 nPara) const =0
virtual css::awt::Point SAL_CALL getLocation() override
Color GetAutoColor() const
virtual tools::Rectangle GetCharBounds(sal_Int32 nPara, sal_Int32 nIndex) const =0
virtual bool IsValid() const =0
TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
OUString GetWord(sal_Int32 nPara, sal_Int32 nIndex)
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
void DrawToDevice(OutputDevice &rRenderContext)
virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() override
virtual OUString SAL_CALL getAccessibleName() override
const OUString & GetFamilyName() const
virtual std::unique_ptr< SvxEditSource > Clone() const =0
virtual void FieldClicked(const SvxFieldItem &rField)=0
void Cut()
virtual void Resize() override
long GetFontHeight() const
virtual a11yref get_accessible_parent()=0
Helper class for objects containing EditEngine/Outliner text.
#define KEY_TAB
virtual void AppendParagraph()=0
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
MapMode const & GetRefMapMode() const
virtual SvxEditViewForwarder * GetEditViewForwarder(bool bCreate=false)
virtual void QuickInsertField(const SvxFieldItem &rFld, const ESelection &rSel)=0
virtual SfxItemState GetItemState(const ESelection &rSel, sal_uInt16 nWhich) const =0
void QuickInsertField(const SvxFieldItem &rFld, const ESelection &rSel)
sal_Int32 GetLineNumberAtIndex(sal_Int32 nPara, sal_Int32 nIndex) const
virtual sal_Int32 GetLineNumberAtIndex(sal_Int32 nPara, sal_Int32 nIndex) const =0
virtual bool GetSelection(ESelection &rSelection) const =0
static SfxItemState GetSvxEditEngineItemState(EditEngine const &rEditEngine, const ESelection &rSel, sal_uInt16 nWhich)
virtual bool Paste()=0
sal_uIntPtr sal_uLong
static::std::unique_ptr< SfxHint > EENotification2Hint(EENotify const *aNotify)
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
OUString GetAccessibleDescription() const
LanguageType GetDefaultLanguage() const
sal_Int32 GetLineCount(sal_Int32 nParagraph) const
virtual void QuickInsertLineBreak(const ESelection &rSel)=0
const MapMode & GetMapMode() const
sal_uInt16 GetCode() const
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild(sal_Int32 i) override
virtual bool Copy()=0
#define EE_CHAR_FONTHEIGHT_CJK
virtual sal_Int32 SAL_CALL getAccessibleChildCount() override
virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext() override
virtual css::uno::Reference< css::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet() override
IMPL_LINK(WeldTextForwarder, NotifyHdl, EENotify &, rNotify, void)
virtual a11yrelationset get_accessible_relation_set()=0
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
LanguageType GetLanguage(const EditPaM &rPaM) const
void SetMapMode()
EditEngineAttribs
std::unique_ptr<::accessibility::AccessibleTextHelper > m_xTextHelper
SfxItemSet GetAttribs(sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, GetAttribsFlags nFlags=GetAttribsFlags::ALL) const
Size const & GetOutputSizePixel() const
EditEngine * m_pEditEngine
FontFamily GetFamilyType()
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override
void Move(long nHorzMoveDelta, long nVertMoveDelta)
GetAttribsFlags
SvxEditSource & operator=(SvxEditSource const &)=default
bool HasParaAttrib(sal_Int32 nPara, sal_uInt16 nWhich) const
Color const & GetBackgroundColor() const
virtual sal_Int16 SAL_CALL getAccessibleRole() override
WeldEditAccessible(weld::CustomWidgetController *pController)
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint(const css::awt::Point &rPoint) override
virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
::accessibility::AccessibleTextHelper * GetTextHelper()
void SetBackground()
void Copy()
virtual sal_Int32 AppendTextPortion(sal_Int32 nPara, const OUString &rText, const SfxItemSet &rSet)=0
virtual bool InsertText(const OUString &rText, const ESelection &rSel)=0
void SetText(const OUString &rStr)
tools::Rectangle GetCharacterBounds(const EPosition &rPos) const
virtual bool SetDepth(sal_Int32 nPara, sal_Int16 nNewDepth)=0
virtual bool Cut()=0
virtual SfxItemSet GetParaAttribs(sal_Int32 nPara) const =0
LineEnd GetSystemLineEnd()
EPosition FindDocPosition(const Point &rDocPos) const
#define KEY_A
virtual bool QuickFormatDoc(bool bFull=false)=0
virtual void CopyText(const SvxTextForwarder &rSource)=0
virtual bool MouseButtonUp(const MouseEvent &rMEvt) override
weld::CustomWidgetController * m_pController
virtual OutputDevice & get_ref_device()=0
sal_Int32 nEndPos
virtual sal_Int32 SAL_CALL getForeground() override
void SetNotifyHdl(const Link< EENotify &, void > &rLink)
void DrawRect(const tools::Rectangle &rRect)
virtual EBulletInfo GetBulletInfo(sal_Int32 nPara) const =0
virtual OUString CalcFieldValue(const SvxFieldItem &rField, sal_Int32 nPara, sal_Int32 nPos, o3tl::optional< Color > &rpTxtColor, o3tl::optional< Color > &rpFldColor)=0
void QuickFormatDoc(bool bFull=false)
virtual LanguageType GetLanguage(sal_Int32 nPara, sal_Int32 nIndex) const =0
virtual void GetLineBoundaries(sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nParagraph, sal_Int32 nLine) const =0
virtual css::awt::Point SAL_CALL getLocationOnScreen() override
void SetLineColor()
virtual void set_cursor(PointerStyle ePointerStyle)=0
sal_Int32 nEndPara
virtual void SetParaAttribs(sal_Int32 nPara, const SfxItemSet &rSet)=0
virtual SfxBroadcaster & GetBroadcaster() const
virtual OutputDevice * GetRefDevice() const =0
void GetCharAttribs(sal_Int32 nPara, std::vector< EECharAttrib > &rLst) const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Point GetDocPosTopLeft(sal_Int32 nParagraph)
sal_Int32 nIndex
virtual Size get_size_request() const =0
sal_Int32 GetLineLen(sal_Int32 nParagraph, sal_Int32 nLine) const
sal_uInt32 GetTextLen() const
#define EE_PARA_START
OUString GetAccessibleName() const
sal_Int32 nPara
virtual MapMode GetMapMode() const =0
virtual SfxItemPool * GetPool() const =0
EditView * m_pEditView
virtual sal_Int16 GetDepth(sal_Int32 nPara) const =0
void SetFillColor()
std::unique_ptr< EditTextObject > CreateTextObject()
virtual css::lang::Locale SAL_CALL getLocale() override
unsigned char sal_Bool
virtual SvxTextForwarder * GetTextForwarder()=0
vcl::Window * GetWindow() const
virtual bool GetAttributeRun(sal_Int32 &nStartIndex, sal_Int32 &nEndIndex, sal_Int32 nPara, sal_Int32 nIndex, bool bInCell=false) const =0
virtual bool MouseMove(const MouseEvent &rMEvt) override
void GetLineBoundaries(sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nParagraph, sal_Int32 nLine) const
virtual SvxViewForwarder * GetViewForwarder()
PITCH_DONTKNOW
std::unique_ptr< EditView > m_xEditView
#define EE_CHAR_FONTHEIGHT
virtual sal_Int32 GetFieldCount(sal_Int32 nPara) const =0
virtual void GetFocus() override
virtual EFieldInfo GetFieldInfo(sal_Int32 nPara, sal_uInt16 nField) const =0
virtual void SAL_CALL addAccessibleEventListener(const css::uno::Reference< css::accessibility::XAccessibleEventListener > &rListener) override
SfxItemPool * GetPool() const
sal_uInt16 GetFieldCount(sal_Int32 nPara) const
void SetOutputSizePixel(const Size &rSize)
long X() const
virtual css::awt::Rectangle SAL_CALL getBounds() override
sal_Int32 GetParagraphCount() const
virtual Point LogicToPixel(const Point &rPoint, const MapMode &rMapMode) const =0
virtual sal_Int32 GetLineLen(sal_Int32 nPara, sal_Int32 nLine) const =0
virtual css::awt::Size SAL_CALL getSize() override
static SfxItemPool * CreatePool()
virtual Point PixelToLogic(const Point &rPoint, const MapMode &rMapMode) const =0
static void GetAttributeRun(sal_Int32 &nStartIndex, sal_Int32 &nEndIndex, const EditEngine &rEE, sal_Int32 nPara, sal_Int32 nIndex, bool bInCell=false)
Point PixelToLogic(const Point &rDevicePt) const
Point LogicToPixel(const Point &rLogicPt) const
virtual void SAL_CALL grabFocus() override
void Init(EditEngine *pEditEngine, EditView *pEditView)
virtual sal_Int32 GetLineCount(sal_Int32 nPara) const =0
virtual bool KeyInput(const KeyEvent &rKEvt) override
const vcl::KeyCode & GetKeyCode() const
virtual bool GetWordIndices(sal_Int32 nPara, sal_Int32 nIndex, sal_Int32 &rStart, sal_Int32 &rEnd) const =0
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
weld::DrawingArea * GetDrawingArea() const
SfxItemState
#define EE_CHAR_FONTINFO_CJK
cppu::WeakImplHelper< css::accessibility::XAccessible, css::accessibility::XAccessibleComponent, css::accessibility::XAccessibleContext, css::accessibility::XAccessibleEventBroadcaster > WeldEditAccessibleBaseClass
EditView * GetEditView()
virtual ~WeldEditView() override
bool GetUpdateMode() const
virtual void SAL_CALL removeAccessibleEventListener(const css::uno::Reference< css::accessibility::XAccessibleEventListener > &rListener) override
void InsertParagraph(sal_Int32 nPara, const EditTextObject &rTxtObj, const bool bAppend=false)
const SfxItemSet & GetEmptyItemSet()
#define EE_CHAR_FONTHEIGHT_CTL
void RemoveAttribs(const ESelection &rSelection, bool bRemoveParaAttribs, sal_uInt16 nWhich)
virtual bool Delete(const ESelection &rSelection)=0
void GetPortions(sal_Int32 nPara, std::vector< sal_Int32 > &rList)
void SetRasterOp(RasterOp eRasterOp)
sal_uInt32 GetTextHeight() const
virtual bool GetIndexAtPoint(const Point &rPoint, sal_Int32 &rPara, sal_Int32 &rIndex) const =0
bool IsMod1() const
virtual void makeEditEngine()
virtual SfxItemSet GetAttribs(const ESelection &rSel, EditEngineAttribs nOnlyHardAttrib=EditEngineAttribs::All) const =0
virtual sal_Int32 SAL_CALL getBackground() override
virtual bool IsValid() const =0
void QuickDelete(const ESelection &rSel)
void QuickSetAttribs(const SfxItemSet &rSet, const ESelection &rSel)
rtl::Reference< WeldEditAccessible > m_xAccessible
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea)
EFieldInfo GetFieldInfo(sal_Int32 nPara, sal_uInt16 nField) const
virtual void RemoveAttribs(const ESelection &rSelection)=0
const Color & GetWindowColor() const
virtual sal_Int32 GetTextLen(sal_Int32 nParagraph) const =0
virtual OUString CalcFieldValue(const SvxFieldItem &rField, sal_Int32 nPara, sal_Int32 nPos, o3tl::optional< Color > &rTxtColor, o3tl::optional< Color > &rFldColor)
OutputDevice * GetRefDevice() const
void SetSelection(const ESelection &rNewSel)
virtual void SetParaAttribs(sal_Int32 nPara, const SfxItemSet &rSet)
virtual void QuickInsertText(const OUString &rText, const ESelection &rSel)=0
std::unique_ptr< EditEngine > m_xEditEngine
virtual void GetPortions(sal_Int32 nPara, std::vector< sal_Int32 > &rList) const =0
virtual const SfxItemSet * GetEmptyItemSetPtr()=0
virtual void LoseFocus() override
#define SAL_WARN(area, stream)
ESelection GetSelection() const
void QuickInsertText(const OUString &rText, const ESelection &rSel)
sal_uInt32 CalcTextWidth()
#define EE_CHAR_FONTINFO_CTL
virtual bool Command(const CommandEvent &rCEvt) override
void SetFocus(bool bHaveFocus=true)
Set the focus state of the accessibility object.
virtual void set_size_request(int nWidth, int nHeight)=0
virtual OUString SAL_CALL getAccessibleDescription() override
virtual sal_Bool SAL_CALL containsPoint(const css::awt::Point &rPoint) override
void Push(PushFlags nFlags=PushFlags::ALL)
virtual sal_Int32 GetParagraphCount() const =0
void AddState(sal_Int16 aState)
void setWidth(long nWidth)
void Paste()
virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() override
sal_Int32 nState
EditEngine * GetEditEngine()
virtual void UpdateData()=0
const SfxPoolItem & GetParaAttrib(sal_Int32 nPara, sal_uInt16 nWhich)
const SfxItemSet & GetParaAttribs(sal_Int32 nPara) const
virtual bool SetSelection(const ESelection &rSelection)=0
long Y() const
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
void SetPoolDefaultItem(const SfxPoolItem &)
virtual void QuickSetAttribs(const SfxItemSet &rSet, const ESelection &rSel)=0
virtual OUString GetText(const ESelection &rSel) const =0
void EnableRTL(bool bEnable)
bool IsMod2() const
sal_Int32 nStartPos
void setHeight(long nHeight)