1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
25 #include <com/sun/star/accessibility/AccessibleRole.hpp>
26 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
27 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
28 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
29 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
30 #include <com/sun/star/awt/FocusEvent.hpp>
31 #include <com/sun/star/awt/XFocusListener.hpp>
32 #include <unotools/accessiblerelationsethelper.hxx>
34 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
35 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
36 #include <com/sun/star/i18n/WordType.hpp>
37 #include <unotools/accessiblestatesethelper.hxx>
38 #include <comphelper/accessibleeventnotifier.hxx>
39 #include <cppuhelper/supportsservice.hxx>
40 #include <osl/diagnose.h>
41 #include <vcl/svapp.hxx>
42 #include <vcl/window.hxx>
43 #include <vcl/unohelp2.hxx>
44 #include <vcl/settings.hxx>
46 #include <tools/gen.hxx>
47 #include <osl/mutex.hxx>
48 #include <svl/itemset.hxx>
50 #include <editeng/editobj.hxx>
51 #include <editeng/editdata.hxx>
52 #include <editeng/editview.hxx>
53 #include <editeng/eeitem.hxx>
54 #include <editeng/outliner.hxx>
55 #include <editeng/unoedhlp.hxx>
58 #include "accessibility.hxx"
59 #include <unomodel.hxx>
60 #include <document.hxx>
62 #include <o3tl/make_unique.hxx>
63 using namespace com::sun::star
;
64 using namespace com::sun::star::lang
;
65 using namespace com::sun::star::uno
;
66 using namespace com::sun::star::accessibility
;
69 static awt::Rectangle
lcl_GetBounds( vcl::Window
*pWin
)
71 // !! see VCLXAccessibleComponent::implGetBounds()
73 //! the coordinates returned are relativ to the parent window !
74 //! Thus the top-left point may be different from (0, 0) !
76 awt::Rectangle aBounds
;
79 Rectangle aRect
= pWin
->GetWindowExtentsRelative( nullptr );
80 aBounds
.X
= aRect
.Left();
81 aBounds
.Y
= aRect
.Top();
82 aBounds
.Width
= aRect
.GetWidth();
83 aBounds
.Height
= aRect
.GetHeight();
84 vcl::Window
* pParent
= pWin
->GetAccessibleParentWindow();
87 Rectangle aParentRect
= pParent
->GetWindowExtentsRelative( nullptr );
88 awt::Point
aParentScreenLoc( aParentRect
.Left(), aParentRect
.Top() );
89 aBounds
.X
-= aParentScreenLoc
.X
;
90 aBounds
.Y
-= aParentScreenLoc
.Y
;
96 static awt::Point
lcl_GetLocationOnScreen( vcl::Window
*pWin
)
98 // !! see VCLXAccessibleComponent::getLocationOnScreen()
103 Rectangle aRect
= pWin
->GetWindowExtentsRelative( nullptr );
104 aPos
.X
= aRect
.Left();
105 aPos
.Y
= aRect
.Top();
111 SmGraphicAccessible::SmGraphicAccessible( SmGraphicWindow
*pGraphicWin
) :
112 aAccName (SM_RESSTR(RID_DOCUMENTSTR
)),
116 OSL_ENSURE( pWin
, "SmGraphicAccessible: window missing" );
119 SmGraphicAccessible::~SmGraphicAccessible()
124 SmDocShell
* SmGraphicAccessible::GetDoc_Impl()
126 SmViewShell
*pView
= pWin
? pWin
->GetView() : nullptr;
127 return pView
? pView
->GetDoc() : nullptr;
130 OUString
SmGraphicAccessible::GetAccessibleText_Impl()
133 SmDocShell
*pDoc
= GetDoc_Impl();
135 aTxt
= pDoc
->GetAccessibleText();
139 void SmGraphicAccessible::ClearWin()
141 pWin
= nullptr; // implicitly results in AccessibleStateType::DEFUNC set
145 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId
, *this );
150 void SmGraphicAccessible::LaunchEvent(
151 const sal_Int16 nAccesibleEventId
,
152 const uno::Any
&rOldVal
,
153 const uno::Any
&rNewVal
)
155 AccessibleEventObject aEvt
;
156 aEvt
.Source
= static_cast<XAccessible
*>(this);
157 aEvt
.EventId
= nAccesibleEventId
;
158 aEvt
.OldValue
= rOldVal
;
159 aEvt
.NewValue
= rNewVal
;
161 // pass event on to event-listener's
163 comphelper::AccessibleEventNotifier::addEvent( nClientId
, aEvt
);
166 uno::Reference
< XAccessibleContext
> SAL_CALL
SmGraphicAccessible::getAccessibleContext()
167 throw (RuntimeException
, std::exception
)
169 SolarMutexGuard aGuard
;
173 sal_Bool SAL_CALL
SmGraphicAccessible::containsPoint( const awt::Point
& aPoint
)
174 throw (RuntimeException
, std::exception
)
176 //! the arguments coordinates are relativ to the current window !
177 //! Thus the top-left point is (0, 0)
179 SolarMutexGuard aGuard
;
181 throw RuntimeException();
183 Size
aSz( pWin
->GetSizePixel() );
184 return aPoint
.X
>= 0 && aPoint
.Y
>= 0 &&
185 aPoint
.X
< aSz
.Width() && aPoint
.Y
< aSz
.Height();
188 uno::Reference
< XAccessible
> SAL_CALL
SmGraphicAccessible::getAccessibleAtPoint(
189 const awt::Point
& aPoint
)
190 throw (RuntimeException
, std::exception
)
192 SolarMutexGuard aGuard
;
193 XAccessible
*pRes
= nullptr;
194 if (containsPoint( aPoint
))
199 awt::Rectangle SAL_CALL
SmGraphicAccessible::getBounds()
200 throw (RuntimeException
, std::exception
)
202 SolarMutexGuard aGuard
;
204 throw RuntimeException();
205 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
206 "mismatch of window parent and accessible parent" );
207 return lcl_GetBounds( pWin
);
210 awt::Point SAL_CALL
SmGraphicAccessible::getLocation()
211 throw (RuntimeException
, std::exception
)
213 SolarMutexGuard aGuard
;
215 throw RuntimeException();
216 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
217 "mismatch of window parent and accessible parent" );
218 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
219 return awt::Point( aRect
.X
, aRect
.Y
);
222 awt::Point SAL_CALL
SmGraphicAccessible::getLocationOnScreen()
223 throw (RuntimeException
, std::exception
)
225 SolarMutexGuard aGuard
;
227 throw RuntimeException();
228 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
229 "mismatch of window parent and accessible parent" );
230 return lcl_GetLocationOnScreen( pWin
);
233 awt::Size SAL_CALL
SmGraphicAccessible::getSize()
234 throw (RuntimeException
, std::exception
)
236 SolarMutexGuard aGuard
;
238 throw RuntimeException();
239 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
240 "mismatch of window parent and accessible parent" );
242 Size
aSz( pWin
->GetSizePixel() );
243 #if OSL_DEBUG_LEVEL > 0
244 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
245 Size
aSz2( aRect
.Width
, aRect
.Height
);
246 assert(aSz
== aSz2
&& "mismatch in width" );
248 return awt::Size( aSz
.Width(), aSz
.Height() );
251 void SAL_CALL
SmGraphicAccessible::grabFocus()
252 throw (RuntimeException
, std::exception
)
254 SolarMutexGuard aGuard
;
256 throw RuntimeException();
261 sal_Int32 SAL_CALL
SmGraphicAccessible::getForeground()
262 throw (RuntimeException
, std::exception
)
264 SolarMutexGuard aGuard
;
267 throw RuntimeException();
268 return static_cast<sal_Int32
>(pWin
->GetTextColor().GetColor());
271 sal_Int32 SAL_CALL
SmGraphicAccessible::getBackground()
272 throw (RuntimeException
, std::exception
)
274 SolarMutexGuard aGuard
;
277 throw RuntimeException();
278 Wallpaper
aWall( pWin
->GetDisplayBackground() );
280 if (aWall
.IsBitmap() || aWall
.IsGradient())
281 nCol
= pWin
->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
283 nCol
= aWall
.GetColor().GetColor();
284 return static_cast<sal_Int32
>(nCol
);
287 sal_Int32 SAL_CALL
SmGraphicAccessible::getAccessibleChildCount()
288 throw (RuntimeException
, std::exception
)
290 SolarMutexGuard aGuard
;
294 Reference
< XAccessible
> SAL_CALL
SmGraphicAccessible::getAccessibleChild(
296 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
298 SolarMutexGuard aGuard
;
299 throw IndexOutOfBoundsException(); // there is no child...
302 Reference
< XAccessible
> SAL_CALL
SmGraphicAccessible::getAccessibleParent()
303 throw (RuntimeException
, std::exception
)
305 SolarMutexGuard aGuard
;
307 throw RuntimeException();
309 vcl::Window
*pAccParent
= pWin
->GetAccessibleParentWindow();
310 OSL_ENSURE( pAccParent
, "accessible parent missing" );
311 return pAccParent
? pAccParent
->GetAccessible() : Reference
< XAccessible
>();
314 sal_Int32 SAL_CALL
SmGraphicAccessible::getAccessibleIndexInParent()
315 throw (RuntimeException
, std::exception
)
317 SolarMutexGuard aGuard
;
319 vcl::Window
*pAccParent
= pWin
? pWin
->GetAccessibleParentWindow() : nullptr;
322 sal_uInt16 nCnt
= pAccParent
->GetAccessibleChildWindowCount();
323 for (sal_uInt16 i
= 0; i
< nCnt
&& nIdx
== -1; ++i
)
324 if (pAccParent
->GetAccessibleChildWindow( i
) == pWin
)
330 sal_Int16 SAL_CALL
SmGraphicAccessible::getAccessibleRole()
331 throw (RuntimeException
, std::exception
)
333 SolarMutexGuard aGuard
;
334 return AccessibleRole::DOCUMENT
;
337 OUString SAL_CALL
SmGraphicAccessible::getAccessibleDescription()
338 throw (RuntimeException
, std::exception
)
340 SolarMutexGuard aGuard
;
341 SmDocShell
*pDoc
= GetDoc_Impl();
342 return pDoc
? OUString(pDoc
->GetText()) : OUString();
345 OUString SAL_CALL
SmGraphicAccessible::getAccessibleName()
346 throw (RuntimeException
, std::exception
)
348 SolarMutexGuard aGuard
;
352 Reference
< XAccessibleRelationSet
> SAL_CALL
SmGraphicAccessible::getAccessibleRelationSet()
353 throw (RuntimeException
, std::exception
)
355 SolarMutexGuard aGuard
;
356 Reference
< XAccessibleRelationSet
> xRelSet
= new utl::AccessibleRelationSetHelper();
357 return xRelSet
; // empty relation set
360 Reference
< XAccessibleStateSet
> SAL_CALL
SmGraphicAccessible::getAccessibleStateSet()
361 throw (RuntimeException
, std::exception
)
363 SolarMutexGuard aGuard
;
364 ::utl::AccessibleStateSetHelper
*pStateSet
=
365 new ::utl::AccessibleStateSetHelper
;
367 Reference
<XAccessibleStateSet
> xStateSet( pStateSet
);
370 pStateSet
->AddState( AccessibleStateType::DEFUNC
);
373 pStateSet
->AddState( AccessibleStateType::ENABLED
);
374 pStateSet
->AddState( AccessibleStateType::FOCUSABLE
);
375 if (pWin
->HasFocus())
376 pStateSet
->AddState( AccessibleStateType::FOCUSED
);
377 if (pWin
->IsActive())
378 pStateSet
->AddState( AccessibleStateType::ACTIVE
);
379 if (pWin
->IsVisible())
380 pStateSet
->AddState( AccessibleStateType::SHOWING
);
381 if (pWin
->IsReallyVisible())
382 pStateSet
->AddState( AccessibleStateType::VISIBLE
);
383 if (COL_TRANSPARENT
!= pWin
->GetBackground().GetColor().GetColor())
384 pStateSet
->AddState( AccessibleStateType::OPAQUE
);
390 Locale SAL_CALL
SmGraphicAccessible::getLocale()
391 throw (IllegalAccessibleComponentStateException
, RuntimeException
, std::exception
)
393 SolarMutexGuard aGuard
;
394 // should be the document language...
395 // We use the language of the localized symbol names here.
396 return Application::GetSettings().GetUILanguageTag().getLocale();
400 void SAL_CALL
SmGraphicAccessible::addAccessibleEventListener(
401 const Reference
< XAccessibleEventListener
>& xListener
)
402 throw (RuntimeException
, std::exception
)
406 SolarMutexGuard aGuard
;
410 nClientId
= comphelper::AccessibleEventNotifier::registerClient( );
411 comphelper::AccessibleEventNotifier::addEventListener( nClientId
, xListener
);
416 void SAL_CALL
SmGraphicAccessible::removeAccessibleEventListener(
417 const Reference
< XAccessibleEventListener
>& xListener
)
418 throw (RuntimeException
, std::exception
)
420 if (xListener
.is() && nClientId
)
422 SolarMutexGuard aGuard
;
423 sal_Int32 nListenerCount
= comphelper::AccessibleEventNotifier::removeEventListener( nClientId
, xListener
);
424 if ( !nListenerCount
)
426 // no listeners anymore
427 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
428 // and at least to us not firing any events anymore, in case somebody calls
429 // NotifyAccessibleEvent, again
430 comphelper::AccessibleEventNotifier::revokeClient( nClientId
);
436 sal_Int32 SAL_CALL
SmGraphicAccessible::getCaretPosition()
437 throw (RuntimeException
, std::exception
)
439 SolarMutexGuard aGuard
;
443 sal_Bool SAL_CALL
SmGraphicAccessible::setCaretPosition( sal_Int32 nIndex
)
444 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
446 SolarMutexGuard aGuard
;
447 OUString
aTxt( GetAccessibleText_Impl() );
448 if (!(nIndex
< aTxt
.getLength()))
449 throw IndexOutOfBoundsException();
453 sal_Unicode SAL_CALL
SmGraphicAccessible::getCharacter( sal_Int32 nIndex
)
454 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
456 SolarMutexGuard aGuard
;
457 OUString
aTxt( GetAccessibleText_Impl() );
458 if (!(nIndex
< aTxt
.getLength()))
459 throw IndexOutOfBoundsException();
463 Sequence
< beans::PropertyValue
> SAL_CALL
SmGraphicAccessible::getCharacterAttributes(
465 const uno::Sequence
< OUString
> & /*rRequestedAttributes*/ )
466 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
468 SolarMutexGuard aGuard
;
469 sal_Int32 nLen
= GetAccessibleText_Impl().getLength();
470 if (!(0 <= nIndex
&& nIndex
< nLen
))
471 throw IndexOutOfBoundsException();
472 return Sequence
< beans::PropertyValue
>();
475 awt::Rectangle SAL_CALL
SmGraphicAccessible::getCharacterBounds( sal_Int32 nIndex
)
476 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
478 SolarMutexGuard aGuard
;
483 throw RuntimeException();
486 // get accessible text
487 SmViewShell
*pView
= pWin
->GetView();
488 SmDocShell
*pDoc
= pView
? pView
->GetDoc() : nullptr;
490 throw RuntimeException();
491 OUString
aTxt( GetAccessibleText_Impl() );
492 if (!(0 <= nIndex
&& nIndex
<= aTxt
.getLength())) // aTxt.getLength() is valid
493 throw IndexOutOfBoundsException();
495 // find a reasonable rectangle for position aTxt.getLength().
496 bool bWasBehindText
= (nIndex
== aTxt
.getLength());
497 if (bWasBehindText
&& nIndex
)
500 const SmNode
*pTree
= pDoc
->GetFormulaTree();
501 const SmNode
*pNode
= pTree
->FindNodeWithAccessibleIndex( nIndex
);
502 //! pNode may be 0 if the index belongs to a char that was inserted
503 //! only for the accessible text!
506 sal_Int32 nAccIndex
= pNode
->GetAccessibleIndex();
507 OSL_ENSURE( nAccIndex
>= 0, "invalid accessible index" );
508 OSL_ENSURE( nIndex
>= nAccIndex
, "index out of range" );
511 pNode
->GetAccessibleText(aBuf
);
512 OUString aNodeText
= aBuf
.makeStringAndClear();
513 sal_Int32 nNodeIndex
= nIndex
- nAccIndex
;
514 if (0 <= nNodeIndex
&& nNodeIndex
< aNodeText
.getLength())
516 // get appropriate rectangle
517 Point
aOffset(pNode
->GetTopLeft() - pTree
->GetTopLeft());
518 Point
aTLPos (pWin
->GetFormulaDrawPos() + aOffset
);
520 Size
aSize (pNode
->GetSize());
522 long* pXAry
= new long[ aNodeText
.getLength() ];
523 pWin
->SetFont( pNode
->GetFont() );
524 pWin
->GetTextArray( aNodeText
, pXAry
, 0, aNodeText
.getLength() );
525 aTLPos
.X() += nNodeIndex
> 0 ? pXAry
[nNodeIndex
- 1] : 0;
526 aSize
.Width() = nNodeIndex
> 0 ? pXAry
[nNodeIndex
] - pXAry
[nNodeIndex
- 1] : pXAry
[nNodeIndex
];
529 aTLPos
= pWin
->LogicToPixel( aTLPos
);
530 aSize
= pWin
->LogicToPixel( aSize
);
533 aRes
.Width
= aSize
.Width();
534 aRes
.Height
= aSize
.Height();
538 // take rectangle from last character and move it to the right
540 aRes
.X
+= aRes
.Width
;
546 sal_Int32 SAL_CALL
SmGraphicAccessible::getCharacterCount()
547 throw (RuntimeException
, std::exception
)
549 SolarMutexGuard aGuard
;
550 return GetAccessibleText_Impl().getLength();
553 sal_Int32 SAL_CALL
SmGraphicAccessible::getIndexAtPoint( const awt::Point
& aPoint
)
554 throw (RuntimeException
, std::exception
)
556 SolarMutexGuard aGuard
;
561 const SmNode
*pTree
= pWin
->GetView()->GetDoc()->GetFormulaTree();
562 // can be NULL! e.g. if one clicks within the window already during loading of the
563 // document (before the parser even started)
567 // get position relative to formula draw position
568 Point
aPos( aPoint
.X
, aPoint
.Y
);
569 aPos
= pWin
->PixelToLogic( aPos
);
570 aPos
-= pWin
->GetFormulaDrawPos();
572 // if it was inside the formula then get the appropriate node
573 const SmNode
*pNode
= nullptr;
574 if (pTree
->OrientedDist(aPos
) <= 0)
575 pNode
= pTree
->FindRectClosestTo(aPos
);
579 // get appropriate rectangle
580 Point
aOffset( pNode
->GetTopLeft() - pTree
->GetTopLeft() );
581 Point
aTLPos ( aOffset
);
583 Size
aSize( pNode
->GetSize() );
585 Rectangle
aRect( aTLPos
, aSize
);
586 if (aRect
.IsInside( aPos
))
588 OSL_ENSURE( pNode
->IsVisible(), "node is not a leaf" );
590 pNode
->GetAccessibleText(aBuf
);
591 OUString aTxt
= aBuf
.makeStringAndClear();
592 OSL_ENSURE( !aTxt
.isEmpty(), "no accessible text available" );
594 long nNodeX
= pNode
->GetLeft();
596 long* pXAry
= new long[ aTxt
.getLength() ];
597 pWin
->SetFont( pNode
->GetFont() );
598 pWin
->GetTextArray( aTxt
, pXAry
, 0, aTxt
.getLength() );
599 for (sal_Int32 i
= 0; i
< aTxt
.getLength() && nRes
== -1; ++i
)
601 if (pXAry
[i
] + nNodeX
> aPos
.X())
605 OSL_ENSURE( nRes
>= 0 && nRes
< aTxt
.getLength(), "index out of range" );
606 OSL_ENSURE( pNode
->GetAccessibleIndex() >= 0,
607 "invalid accessible index" );
609 nRes
= pNode
->GetAccessibleIndex() + nRes
;
616 OUString SAL_CALL
SmGraphicAccessible::getSelectedText()
617 throw (RuntimeException
, std::exception
)
619 SolarMutexGuard aGuard
;
623 sal_Int32 SAL_CALL
SmGraphicAccessible::getSelectionStart()
624 throw (RuntimeException
, std::exception
)
626 SolarMutexGuard aGuard
;
630 sal_Int32 SAL_CALL
SmGraphicAccessible::getSelectionEnd()
631 throw (RuntimeException
, std::exception
)
633 SolarMutexGuard aGuard
;
637 sal_Bool SAL_CALL
SmGraphicAccessible::setSelection(
638 sal_Int32 nStartIndex
,
639 sal_Int32 nEndIndex
)
640 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
642 SolarMutexGuard aGuard
;
643 sal_Int32 nLen
= GetAccessibleText_Impl().getLength();
644 if (!(0 <= nStartIndex
&& nStartIndex
< nLen
) ||
645 !(0 <= nEndIndex
&& nEndIndex
< nLen
))
646 throw IndexOutOfBoundsException();
650 OUString SAL_CALL
SmGraphicAccessible::getText()
651 throw (RuntimeException
, std::exception
)
653 SolarMutexGuard aGuard
;
654 return GetAccessibleText_Impl();
657 OUString SAL_CALL
SmGraphicAccessible::getTextRange(
658 sal_Int32 nStartIndex
,
659 sal_Int32 nEndIndex
)
660 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
662 //!! nEndIndex may be the string length per definition of the interface !!
663 //!! text should be copied exclusive that end index though. And arguments
664 //!! may be switched.
666 SolarMutexGuard aGuard
;
667 OUString
aTxt( GetAccessibleText_Impl() );
668 sal_Int32 nStart
= std::min(nStartIndex
, nEndIndex
);
669 sal_Int32 nEnd
= std::max(nStartIndex
, nEndIndex
);
670 if (!(nStart
<= aTxt
.getLength()) ||
671 !(nEnd
<= aTxt
.getLength()))
672 throw IndexOutOfBoundsException();
673 return aTxt
.copy( nStart
, nEnd
- nStart
);
676 css::accessibility::TextSegment SAL_CALL
SmGraphicAccessible::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (css::lang::IndexOutOfBoundsException
, css::lang::IllegalArgumentException
, css::uno::RuntimeException
, std::exception
)
678 SolarMutexGuard aGuard
;
679 OUString
aTxt( GetAccessibleText_Impl() );
680 //!! nIndex is allowed to be the string length
681 if (!(nIndex
<= aTxt
.getLength()))
682 throw IndexOutOfBoundsException();
684 css::accessibility::TextSegment aResult
;
685 aResult
.SegmentStart
= -1;
686 aResult
.SegmentEnd
= -1;
687 if ( (AccessibleTextType::CHARACTER
== aTextType
) && (nIndex
< aTxt
.getLength()) )
689 aResult
.SegmentText
= aTxt
.copy(nIndex
, 1);
690 aResult
.SegmentStart
= nIndex
;
691 aResult
.SegmentEnd
= nIndex
+1;
696 css::accessibility::TextSegment SAL_CALL
SmGraphicAccessible::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (css::lang::IndexOutOfBoundsException
, css::lang::IllegalArgumentException
, css::uno::RuntimeException
, std::exception
)
698 SolarMutexGuard aGuard
;
699 OUString
aTxt( GetAccessibleText_Impl() );
700 //!! nIndex is allowed to be the string length
701 if (!(nIndex
<= aTxt
.getLength()))
702 throw IndexOutOfBoundsException();
704 css::accessibility::TextSegment aResult
;
705 aResult
.SegmentStart
= -1;
706 aResult
.SegmentEnd
= -1;
708 if ( (AccessibleTextType::CHARACTER
== aTextType
) && nIndex
)
710 aResult
.SegmentText
= aTxt
.copy(nIndex
-1, 1);
711 aResult
.SegmentStart
= nIndex
-1;
712 aResult
.SegmentEnd
= nIndex
;
717 css::accessibility::TextSegment SAL_CALL
SmGraphicAccessible::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (css::lang::IndexOutOfBoundsException
, css::lang::IllegalArgumentException
, css::uno::RuntimeException
, std::exception
)
719 SolarMutexGuard aGuard
;
720 OUString
aTxt( GetAccessibleText_Impl() );
721 //!! nIndex is allowed to be the string length
722 if (!(nIndex
<= aTxt
.getLength()))
723 throw IndexOutOfBoundsException();
725 css::accessibility::TextSegment aResult
;
726 aResult
.SegmentStart
= -1;
727 aResult
.SegmentEnd
= -1;
729 nIndex
++; // text *behind*
730 if ( (AccessibleTextType::CHARACTER
== aTextType
) && (nIndex
< aTxt
.getLength()) )
732 aResult
.SegmentText
= aTxt
.copy(nIndex
, 1);
733 aResult
.SegmentStart
= nIndex
;
734 aResult
.SegmentEnd
= nIndex
+1;
739 sal_Bool SAL_CALL
SmGraphicAccessible::copyText(
740 sal_Int32 nStartIndex
,
741 sal_Int32 nEndIndex
)
742 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
744 SolarMutexGuard aGuard
;
745 bool bReturn
= false;
748 throw RuntimeException();
751 Reference
< datatransfer::clipboard::XClipboard
> xClipboard
= pWin
->GetClipboard();
752 if ( xClipboard
.is() )
754 OUString
sText( getTextRange(nStartIndex
, nEndIndex
) );
756 vcl::unohelper::TextDataObject
* pDataObj
= new vcl::unohelper::TextDataObject( sText
);
757 SolarMutexReleaser aReleaser
;
758 xClipboard
->setContents( pDataObj
, nullptr );
760 Reference
< datatransfer::clipboard::XFlushableClipboard
> xFlushableClipboard( xClipboard
, uno::UNO_QUERY
);
761 if( xFlushableClipboard
.is() )
762 xFlushableClipboard
->flushClipboard();
771 OUString SAL_CALL
SmGraphicAccessible::getImplementationName()
772 throw (RuntimeException
, std::exception
)
774 return OUString("SmGraphicAccessible");
777 sal_Bool SAL_CALL
SmGraphicAccessible::supportsService(
778 const OUString
& rServiceName
)
779 throw (RuntimeException
, std::exception
)
781 return cppu::supportsService(this, rServiceName
);
784 Sequence
< OUString
> SAL_CALL
SmGraphicAccessible::getSupportedServiceNames()
785 throw (RuntimeException
, std::exception
)
787 return Sequence
< OUString
>{
788 "css::accessibility::Accessible",
789 "css::accessibility::AccessibleComponent",
790 "css::accessibility::AccessibleContext",
791 "css::accessibility::AccessibleText"
796 SmEditSource::SmEditSource( SmEditWindow
* /*pWin*/, SmEditAccessible
&rAcc
) :
798 aTextFwd (rAcc
, *this),
804 SmEditSource::SmEditSource( const SmEditSource
&rSrc
) :
806 aViewFwd (rSrc
.rEditAcc
),
807 aTextFwd (rSrc
.rEditAcc
, *this),
808 aEditViewFwd(rSrc
.rEditAcc
),
809 rEditAcc (rSrc
.rEditAcc
)
813 SmEditSource::~SmEditSource()
817 SvxEditSource
* SmEditSource::Clone() const
819 return new SmEditSource( *this );
822 SvxTextForwarder
* SmEditSource::GetTextForwarder()
827 SvxViewForwarder
* SmEditSource::GetViewForwarder()
832 SvxEditViewForwarder
* SmEditSource::GetEditViewForwarder( bool /*bCreate*/ )
834 return &aEditViewFwd
;
837 void SmEditSource::UpdateData()
839 // would possibly only by needed if the XText interface is implemented
840 // and its text needs to be updated.
843 SfxBroadcaster
& SmEditSource::GetBroadcaster() const
845 return const_cast<SmEditSource
*>(this)->aBroadCaster
;
848 SmViewForwarder::SmViewForwarder( SmEditAccessible
&rAcc
) :
853 SmViewForwarder::~SmViewForwarder()
857 bool SmViewForwarder::IsValid() const
859 return rEditAcc
.GetEditView() != nullptr;
862 Rectangle
SmViewForwarder::GetVisArea() const
864 EditView
*pEditView
= rEditAcc
.GetEditView();
865 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : nullptr;
867 if( pOutDev
&& pEditView
)
869 Rectangle aVisArea
= pEditView
->GetVisArea();
871 // figure out map mode from edit engine
872 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
876 MapMode
aMapMode(pOutDev
->GetMapMode());
877 aVisArea
= OutputDevice::LogicToLogic( aVisArea
,
878 pEditEngine
->GetRefMapMode(),
879 aMapMode
.GetMapUnit() );
880 aMapMode
.SetOrigin(Point());
881 return pOutDev
->LogicToPixel( aVisArea
, aMapMode
);
888 Point
SmViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
890 EditView
*pEditView
= rEditAcc
.GetEditView();
891 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : nullptr;
895 MapMode
aMapMode(pOutDev
->GetMapMode());
896 Point
aPoint( OutputDevice::LogicToLogic( rPoint
, rMapMode
,
897 aMapMode
.GetMapUnit() ) );
898 aMapMode
.SetOrigin(Point());
899 return pOutDev
->LogicToPixel( aPoint
, aMapMode
);
905 Point
SmViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
907 EditView
*pEditView
= rEditAcc
.GetEditView();
908 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : nullptr;
912 MapMode
aMapMode(pOutDev
->GetMapMode());
913 aMapMode
.SetOrigin(Point());
914 Point
aPoint( pOutDev
->PixelToLogic( rPoint
, aMapMode
) );
915 return OutputDevice::LogicToLogic( aPoint
,
916 aMapMode
.GetMapUnit(),
924 SmTextForwarder::SmTextForwarder( SmEditAccessible
& rAcc
, SmEditSource
& rSource
) :
926 rEditSource (rSource
)
928 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
930 pEditEngine
->SetNotifyHdl( LINK(this, SmTextForwarder
, NotifyHdl
) );
933 SmTextForwarder::~SmTextForwarder()
935 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
937 pEditEngine
->SetNotifyHdl( Link
<EENotify
&,void>() );
940 IMPL_LINK(SmTextForwarder
, NotifyHdl
, EENotify
&, rNotify
, void)
942 ::std::unique_ptr
< SfxHint
> aHint
= SvxEditSourceHelper::EENotification2Hint( &rNotify
);
944 rEditSource
.GetBroadcaster().Broadcast( *aHint
.get() );
947 sal_Int32
SmTextForwarder::GetParagraphCount() const
949 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
950 return pEditEngine
? pEditEngine
->GetParagraphCount() : 0;
953 sal_Int32
SmTextForwarder::GetTextLen( sal_Int32 nParagraph
) const
955 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
956 return pEditEngine
? pEditEngine
->GetTextLen( nParagraph
) : 0;
959 OUString
SmTextForwarder::GetText( const ESelection
& rSel
) const
961 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
964 aRet
= pEditEngine
->GetText( rSel
);
965 return convertLineEnd(aRet
, GetSystemLineEnd());
968 SfxItemSet
SmTextForwarder::GetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
) const
970 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
971 assert(pEditEngine
&& "EditEngine missing");
972 if( rSel
.nStartPara
== rSel
.nEndPara
)
974 GetAttribsFlags nFlags
= GetAttribsFlags::NONE
;
975 switch( nOnlyHardAttrib
)
977 case EditEngineAttribs_All
:
978 nFlags
= GetAttribsFlags::ALL
;
980 case EditEngineAttribs_HardAndPara
:
981 nFlags
= GetAttribsFlags::PARAATTRIBS
|GetAttribsFlags::CHARATTRIBS
;
983 case EditEngineAttribs_OnlyHard
:
984 nFlags
= GetAttribsFlags::CHARATTRIBS
;
987 SAL_WARN("starmath", "unknown flags for SmTextForwarder::GetAttribs");
990 return pEditEngine
->GetAttribs( rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
994 return pEditEngine
->GetAttribs( rSel
, nOnlyHardAttrib
);
998 SfxItemSet
SmTextForwarder::GetParaAttribs( sal_Int32 nPara
) const
1000 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1001 assert(pEditEngine
&& "EditEngine missing");
1003 SfxItemSet
aSet( pEditEngine
->GetParaAttribs( nPara
) );
1005 sal_uInt16 nWhich
= EE_PARA_START
;
1006 while( nWhich
<= EE_PARA_END
)
1008 if( aSet
.GetItemState( nWhich
) != SfxItemState::SET
)
1010 if( pEditEngine
->HasParaAttrib( nPara
, nWhich
) )
1011 aSet
.Put( pEditEngine
->GetParaAttrib( nPara
, nWhich
) );
1019 void SmTextForwarder::SetParaAttribs( sal_Int32 nPara
, const SfxItemSet
& rSet
)
1021 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1023 pEditEngine
->SetParaAttribs( nPara
, rSet
);
1026 SfxItemPool
* SmTextForwarder::GetPool() const
1028 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1029 return pEditEngine
? pEditEngine
->GetEmptyItemSet().GetPool() : nullptr;
1032 void SmTextForwarder::RemoveAttribs( const ESelection
& rSelection
)
1034 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1036 pEditEngine
->RemoveAttribs( rSelection
, false/*bRemoveParaAttribs*/, 0 );
1039 void SmTextForwarder::GetPortions( sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
1041 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1043 pEditEngine
->GetPortions( nPara
, rList
);
1046 void SmTextForwarder::QuickInsertText( const OUString
& rText
, const ESelection
& rSel
)
1048 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1050 pEditEngine
->QuickInsertText( rText
, rSel
);
1053 void SmTextForwarder::QuickInsertLineBreak( const ESelection
& rSel
)
1055 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1057 pEditEngine
->QuickInsertLineBreak( rSel
);
1060 void SmTextForwarder::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
1062 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1064 pEditEngine
->QuickInsertField( rFld
, rSel
);
1067 void SmTextForwarder::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
1069 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1071 pEditEngine
->QuickSetAttribs( rSet
, rSel
);
1074 bool SmTextForwarder::IsValid() const
1076 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1077 // cannot reliably query EditEngine state
1078 // while in the middle of an update
1079 return pEditEngine
&& pEditEngine
->GetUpdateMode();
1082 OUString
SmTextForwarder::CalcFieldValue( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
, Color
*& rpTxtColor
, Color
*& rpFldColor
)
1084 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1085 return pEditEngine
? pEditEngine
->CalcFieldValue(rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
) : OUString();
1088 void SmTextForwarder::FieldClicked(const SvxFieldItem
&, sal_Int32
, sal_Int32
)
1092 static SfxItemState
GetSvxEditEngineItemState( EditEngine
& rEditEngine
, const ESelection
& rSel
, sal_uInt16 nWhich
)
1094 std::vector
<EECharAttrib
> aAttribs
;
1096 const SfxPoolItem
* pLastItem
= nullptr;
1098 SfxItemState eState
= SfxItemState::DEFAULT
;
1100 // check all paragraphs inside the selection
1101 for( sal_Int32 nPara
= rSel
.nStartPara
; nPara
<= rSel
.nEndPara
; nPara
++ )
1103 SfxItemState eParaState
= SfxItemState::DEFAULT
;
1105 // calculate start and endpos for this paragraph
1107 if( rSel
.nStartPara
== nPara
)
1108 nPos
= rSel
.nStartPos
;
1110 sal_Int32 nEndPos
= rSel
.nEndPos
;
1111 if( rSel
.nEndPara
!= nPara
)
1112 nEndPos
= rEditEngine
.GetTextLen( nPara
);
1115 // get list of char attribs
1116 rEditEngine
.GetCharAttribs( nPara
, aAttribs
);
1118 bool bEmpty
= true; // we found no item inside the selection of this paragraph
1119 bool bGaps
= false; // we found items but theire gaps between them
1120 sal_Int32 nLastEnd
= nPos
;
1122 const SfxPoolItem
* pParaItem
= nullptr;
1124 for(std::vector
<EECharAttrib
>::const_iterator i
= aAttribs
.begin(); i
< aAttribs
.end(); ++i
)
1126 OSL_ENSURE( i
->pAttr
, "GetCharAttribs gives corrupt data" );
1128 const bool bEmptyPortion
= (i
->nStart
== i
->nEnd
);
1129 if( (!bEmptyPortion
&& (i
->nStart
>= nEndPos
)) || (bEmptyPortion
&& (i
->nStart
> nEndPos
)) )
1130 break; // break if we are already behind our selection
1132 if( (!bEmptyPortion
&& (i
->nEnd
<= nPos
)) || (bEmptyPortion
&& (i
->nEnd
< nPos
)) )
1133 continue; // or if the attribute ends before our selection
1135 if( i
->pAttr
->Which() != nWhich
)
1136 continue; // skip if is not the searched item
1138 // if we already found an item
1141 // ... and its different to this one than the state is don't care
1142 if( *pParaItem
!= *(i
->pAttr
) )
1143 return SfxItemState::DONTCARE
;
1147 pParaItem
= i
->pAttr
;
1153 if( !bGaps
&& i
->nStart
> nLastEnd
)
1159 if( !bEmpty
&& !bGaps
&& nLastEnd
< ( nEndPos
- 1 ) )
1162 eParaState
= SfxItemState::DEFAULT
;
1164 eParaState
= SfxItemState::DONTCARE
;
1166 eParaState
= SfxItemState::SET
;
1168 // if we already found an item check if we found the same
1171 if( (pParaItem
== nullptr) || (*pLastItem
!= *pParaItem
) )
1172 return SfxItemState::DONTCARE
;
1176 pLastItem
= pParaItem
;
1177 eState
= eParaState
;
1184 SfxItemState
SmTextForwarder::GetItemState( const ESelection
& rSel
, sal_uInt16 nWhich
) const
1186 SfxItemState nState
= SfxItemState::DISABLED
;
1187 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1189 nState
= GetSvxEditEngineItemState( *pEditEngine
, rSel
, nWhich
);
1193 SfxItemState
SmTextForwarder::GetItemState( sal_Int32 nPara
, sal_uInt16 nWhich
) const
1195 SfxItemState nState
= SfxItemState::DISABLED
;
1196 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1199 const SfxItemSet
& rSet
= pEditEngine
->GetParaAttribs( nPara
);
1200 nState
= rSet
.GetItemState( nWhich
);
1205 LanguageType
SmTextForwarder::GetLanguage( sal_Int32 nPara
, sal_Int32 nIndex
) const
1207 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1208 return pEditEngine
? pEditEngine
->GetLanguage(nPara
, nIndex
) : LANGUAGE_NONE
;
1211 sal_Int32
SmTextForwarder::GetFieldCount( sal_Int32 nPara
) const
1213 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1214 return pEditEngine
? pEditEngine
->GetFieldCount(nPara
) : 0;
1217 EFieldInfo
SmTextForwarder::GetFieldInfo( sal_Int32 nPara
, sal_uInt16 nField
) const
1219 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1220 return pEditEngine
? pEditEngine
->GetFieldInfo( nPara
, nField
) : EFieldInfo();
1223 EBulletInfo
SmTextForwarder::GetBulletInfo( sal_Int32
/*nPara*/ ) const
1225 return EBulletInfo();
1228 Rectangle
SmTextForwarder::GetCharBounds( sal_Int32 nPara
, sal_Int32 nIndex
) const
1230 Rectangle
aRect(0,0,0,0);
1231 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1235 // Handle virtual position one-past-the end of the string
1236 if( nIndex
>= pEditEngine
->GetTextLen(nPara
) )
1239 aRect
= pEditEngine
->GetCharacterBounds( EPosition(nPara
, nIndex
-1) );
1241 aRect
.Move( aRect
.Right() - aRect
.Left(), 0 );
1242 aRect
.SetSize( Size(1, pEditEngine
->GetTextHeight()) );
1246 aRect
= pEditEngine
->GetCharacterBounds( EPosition(nPara
, nIndex
) );
1252 Rectangle
SmTextForwarder::GetParaBounds( sal_Int32 nPara
) const
1254 Rectangle
aRect(0,0,0,0);
1255 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1259 const Point aPnt
= pEditEngine
->GetDocPosTopLeft( nPara
);
1260 const sal_uLong nWidth
= pEditEngine
->CalcTextWidth();
1261 const sal_uLong nHeight
= pEditEngine
->GetTextHeight( nPara
);
1262 aRect
= Rectangle( aPnt
.X(), aPnt
.Y(), aPnt
.X() + nWidth
, aPnt
.Y() + nHeight
);
1268 MapMode
SmTextForwarder::GetMapMode() const
1270 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1271 return pEditEngine
? pEditEngine
->GetRefMapMode() : MapMode( MapUnit::Map100thMM
);
1274 OutputDevice
* SmTextForwarder::GetRefDevice() const
1276 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1277 return pEditEngine
? pEditEngine
->GetRefDevice() : nullptr;
1280 bool SmTextForwarder::GetIndexAtPoint( const Point
& rPos
, sal_Int32
& nPara
, sal_Int32
& nIndex
) const
1283 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1286 EPosition aDocPos
= pEditEngine
->FindDocPosition( rPos
);
1287 nPara
= aDocPos
.nPara
;
1288 nIndex
= aDocPos
.nIndex
;
1294 bool SmTextForwarder::GetWordIndices( sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
, sal_Int32
& nEnd
) const
1297 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1300 ESelection aRes
= pEditEngine
->GetWord( ESelection(nPara
, nIndex
, nPara
, nIndex
), css::i18n::WordType::DICTIONARY_WORD
);
1302 if( aRes
.nStartPara
== nPara
&&
1303 aRes
.nStartPara
== aRes
.nEndPara
)
1305 nStart
= aRes
.nStartPos
;
1306 nEnd
= aRes
.nEndPos
;
1315 bool SmTextForwarder::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
) const
1317 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1318 return pEditEngine
&&
1319 SvxEditSourceHelper::GetAttributeRun( nStartIndex
, nEndIndex
, *pEditEngine
, nPara
, nIndex
, bInCell
);
1322 sal_Int32
SmTextForwarder::GetLineCount( sal_Int32 nPara
) const
1324 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1325 return pEditEngine
? pEditEngine
->GetLineCount(nPara
) : 0;
1328 sal_Int32
SmTextForwarder::GetLineLen( sal_Int32 nPara
, sal_Int32 nLine
) const
1330 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1331 return pEditEngine
? pEditEngine
->GetLineLen(nPara
, nLine
) : 0;
1334 void SmTextForwarder::GetLineBoundaries( /*out*/sal_Int32
&rStart
, /*out*/sal_Int32
&rEnd
, sal_Int32 nPara
, sal_Int32 nLine
) const
1336 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1338 pEditEngine
->GetLineBoundaries(rStart
, rEnd
, nPara
, nLine
);
1343 sal_Int32
SmTextForwarder::GetLineNumberAtIndex( sal_Int32 nPara
, sal_Int32 nIndex
) const
1345 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1346 return pEditEngine
? pEditEngine
->GetLineNumberAtIndex(nPara
, nIndex
) : 0;
1349 bool SmTextForwarder::QuickFormatDoc( bool /*bFull*/ )
1352 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1355 pEditEngine
->QuickFormatDoc();
1361 sal_Int16
SmTextForwarder::GetDepth( sal_Int32
/*nPara*/ ) const
1363 // math has no outliner...
1367 bool SmTextForwarder::SetDepth( sal_Int32
/*nPara*/, sal_Int16 nNewDepth
)
1369 // math has no outliner...
1370 return -1 == nNewDepth
; // is it the value from 'GetDepth' ?
1373 bool SmTextForwarder::Delete( const ESelection
& rSelection
)
1376 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1379 pEditEngine
->QuickDelete( rSelection
);
1380 pEditEngine
->QuickFormatDoc();
1386 bool SmTextForwarder::InsertText( const OUString
& rStr
, const ESelection
& rSelection
)
1389 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1392 pEditEngine
->QuickInsertText( rStr
, rSelection
);
1393 pEditEngine
->QuickFormatDoc();
1399 const SfxItemSet
* SmTextForwarder::GetEmptyItemSetPtr()
1401 const SfxItemSet
*pItemSet
= nullptr;
1402 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1405 pItemSet
= &pEditEngine
->GetEmptyItemSet();
1410 void SmTextForwarder::AppendParagraph()
1412 // append an empty paragraph
1413 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1416 sal_Int32 nParaCount
= pEditEngine
->GetParagraphCount();
1417 pEditEngine
->InsertParagraph( nParaCount
, OUString() );
1421 sal_Int32
SmTextForwarder::AppendTextPortion( sal_Int32 nPara
, const OUString
&rText
, const SfxItemSet
&rSet
)
1423 sal_uInt16 nRes
= 0;
1424 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1425 if (pEditEngine
&& nPara
< pEditEngine
->GetParagraphCount())
1428 ESelection
aSel( nPara
, pEditEngine
->GetTextLen( nPara
) );
1429 pEditEngine
->QuickInsertText( rText
, aSel
);
1431 // set attributes for new appended text
1432 nRes
= aSel
.nEndPos
= pEditEngine
->GetTextLen( nPara
);
1433 pEditEngine
->QuickSetAttribs( rSet
, aSel
);
1438 void SmTextForwarder::CopyText(const SvxTextForwarder
& rSource
)
1441 const SmTextForwarder
* pSourceForwarder
= dynamic_cast< const SmTextForwarder
* >( &rSource
);
1442 if( !pSourceForwarder
)
1444 EditEngine
* pSourceEditEngine
= pSourceForwarder
->rEditAcc
.GetEditEngine();
1445 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1446 if (pEditEngine
&& pSourceEditEngine
)
1448 EditTextObject
* pNewTextObject
= pSourceEditEngine
->CreateTextObject();
1449 pEditEngine
->SetText( *pNewTextObject
);
1450 delete pNewTextObject
;
1455 SmEditViewForwarder::SmEditViewForwarder( SmEditAccessible
& rAcc
) :
1460 SmEditViewForwarder::~SmEditViewForwarder()
1464 bool SmEditViewForwarder::IsValid() const
1466 return rEditAcc
.GetEditView() != nullptr;
1469 Rectangle
SmEditViewForwarder::GetVisArea() const
1471 Rectangle
aRect(0,0,0,0);
1473 EditView
*pEditView
= rEditAcc
.GetEditView();
1474 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : nullptr;
1476 if( pOutDev
&& pEditView
)
1478 Rectangle aVisArea
= pEditView
->GetVisArea();
1480 // figure out map mode from edit engine
1481 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
1485 MapMode
aMapMode(pOutDev
->GetMapMode());
1486 aVisArea
= OutputDevice::LogicToLogic( aVisArea
,
1487 pEditEngine
->GetRefMapMode(),
1488 aMapMode
.GetMapUnit() );
1489 aMapMode
.SetOrigin(Point());
1490 aRect
= pOutDev
->LogicToPixel( aVisArea
, aMapMode
);
1497 Point
SmEditViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
1499 EditView
*pEditView
= rEditAcc
.GetEditView();
1500 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : nullptr;
1504 MapMode
aMapMode(pOutDev
->GetMapMode());
1505 Point
aPoint( OutputDevice::LogicToLogic( rPoint
, rMapMode
,
1506 aMapMode
.GetMapUnit() ) );
1507 aMapMode
.SetOrigin(Point());
1508 return pOutDev
->LogicToPixel( aPoint
, aMapMode
);
1514 Point
SmEditViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
1516 EditView
*pEditView
= rEditAcc
.GetEditView();
1517 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : nullptr;
1521 MapMode
aMapMode(pOutDev
->GetMapMode());
1522 aMapMode
.SetOrigin(Point());
1523 Point
aPoint( pOutDev
->PixelToLogic( rPoint
, aMapMode
) );
1524 return OutputDevice::LogicToLogic( aPoint
,
1525 aMapMode
.GetMapUnit(),
1532 bool SmEditViewForwarder::GetSelection( ESelection
& rSelection
) const
1535 EditView
*pEditView
= rEditAcc
.GetEditView();
1538 rSelection
= pEditView
->GetSelection();
1544 bool SmEditViewForwarder::SetSelection( const ESelection
& rSelection
)
1547 EditView
*pEditView
= rEditAcc
.GetEditView();
1550 pEditView
->SetSelection( rSelection
);
1556 bool SmEditViewForwarder::Copy()
1559 EditView
*pEditView
= rEditAcc
.GetEditView();
1568 bool SmEditViewForwarder::Cut()
1571 EditView
*pEditView
= rEditAcc
.GetEditView();
1580 bool SmEditViewForwarder::Paste()
1583 EditView
*pEditView
= rEditAcc
.GetEditView();
1593 SmEditAccessible::SmEditAccessible( SmEditWindow
*pEditWin
) :
1594 aAccName (SM_RESSTR(STR_CMDBOXWINDOW
)),
1598 OSL_ENSURE( pWin
, "SmEditAccessible: window missing" );
1601 SmEditAccessible::~SmEditAccessible()
1605 ::accessibility::AccessibleTextHelper
*SmEditAccessible::GetTextHelper()
1607 return pTextHelper
.get();
1610 void SmEditAccessible::Init()
1612 OSL_ENSURE( pWin
, "SmEditAccessible: window missing" );
1615 EditEngine
*pEditEngine
= pWin
->GetEditEngine();
1616 EditView
*pEditView
= pWin
->GetEditView();
1617 if (pEditEngine
&& pEditView
)
1619 assert(!pTextHelper
);
1620 pTextHelper
.reset(new ::accessibility::AccessibleTextHelper( o3tl::make_unique
<SmEditSource
>( pWin
, *this ) ));
1621 pTextHelper
->SetEventSource( this );
1626 void SmEditAccessible::ClearWin()
1628 // remove handler before current object gets destroyed
1629 // (avoid handler being called for already dead object)
1630 EditEngine
*pEditEngine
= GetEditEngine();
1632 pEditEngine
->SetNotifyHdl( Link
<EENotify
&,void>() );
1634 pWin
= nullptr; // implicitly results in AccessibleStateType::DEFUNC set
1636 //! make TextHelper implicitly release C++ references to some core objects
1637 pTextHelper
->SetEditSource( ::std::unique_ptr
<SvxEditSource
>() );
1638 //! make TextHelper release references
1639 //! (e.g. the one set by the 'SetEventSource' call)
1640 pTextHelper
->Dispose();
1641 pTextHelper
.reset();
1645 uno::Reference
< XAccessibleContext
> SAL_CALL
SmEditAccessible::getAccessibleContext( )
1646 throw (RuntimeException
, std::exception
)
1648 SolarMutexGuard aGuard
;
1652 // XAccessibleComponent
1653 sal_Bool SAL_CALL
SmEditAccessible::containsPoint( const awt::Point
& aPoint
)
1654 throw (RuntimeException
, std::exception
)
1656 //! the arguments coordinates are relativ to the current window !
1657 //! Thus the top left-point is (0, 0)
1659 SolarMutexGuard aGuard
;
1661 throw RuntimeException();
1663 Size
aSz( pWin
->GetSizePixel() );
1664 return aPoint
.X
>= 0 && aPoint
.Y
>= 0 &&
1665 aPoint
.X
< aSz
.Width() && aPoint
.Y
< aSz
.Height();
1668 uno::Reference
< XAccessible
> SAL_CALL
SmEditAccessible::getAccessibleAtPoint( const awt::Point
& aPoint
)
1669 throw (RuntimeException
, std::exception
)
1671 SolarMutexGuard aGuard
;
1673 throw RuntimeException();
1674 return pTextHelper
->GetAt( aPoint
);
1677 awt::Rectangle SAL_CALL
SmEditAccessible::getBounds( )
1678 throw (RuntimeException
, std::exception
)
1680 SolarMutexGuard aGuard
;
1682 throw RuntimeException();
1683 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
1684 "mismatch of window parent and accessible parent" );
1685 return lcl_GetBounds( pWin
);
1688 awt::Point SAL_CALL
SmEditAccessible::getLocation( )
1689 throw (RuntimeException
, std::exception
)
1691 SolarMutexGuard aGuard
;
1693 throw RuntimeException();
1694 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
1695 "mismatch of window parent and accessible parent" );
1696 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
1697 return awt::Point( aRect
.X
, aRect
.Y
);
1700 awt::Point SAL_CALL
SmEditAccessible::getLocationOnScreen( )
1701 throw (RuntimeException
, std::exception
)
1703 SolarMutexGuard aGuard
;
1705 throw RuntimeException();
1706 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
1707 "mismatch of window parent and accessible parent" );
1708 return lcl_GetLocationOnScreen( pWin
);
1711 awt::Size SAL_CALL
SmEditAccessible::getSize( )
1712 throw (RuntimeException
, std::exception
)
1714 SolarMutexGuard aGuard
;
1716 throw RuntimeException();
1717 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
1718 "mismatch of window parent and accessible parent" );
1720 Size
aSz( pWin
->GetSizePixel() );
1721 #if OSL_DEBUG_LEVEL > 0
1722 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
1723 Size
aSz2( aRect
.Width
, aRect
.Height
);
1724 assert(aSz
== aSz2
&& "mismatch in width");
1726 return awt::Size( aSz
.Width(), aSz
.Height() );
1729 void SAL_CALL
SmEditAccessible::grabFocus( )
1730 throw (RuntimeException
, std::exception
)
1732 SolarMutexGuard aGuard
;
1734 throw RuntimeException();
1739 sal_Int32 SAL_CALL
SmEditAccessible::getForeground()
1740 throw (RuntimeException
, std::exception
)
1742 SolarMutexGuard aGuard
;
1745 throw RuntimeException();
1746 return static_cast<sal_Int32
>(pWin
->GetTextColor().GetColor());
1749 sal_Int32 SAL_CALL
SmEditAccessible::getBackground()
1750 throw (RuntimeException
, std::exception
)
1752 SolarMutexGuard aGuard
;
1755 throw RuntimeException();
1756 Wallpaper
aWall( pWin
->GetDisplayBackground() );
1758 if (aWall
.IsBitmap() || aWall
.IsGradient())
1759 nCol
= pWin
->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
1761 nCol
= aWall
.GetColor().GetColor();
1762 return static_cast<sal_Int32
>(nCol
);
1765 // XAccessibleContext
1766 sal_Int32 SAL_CALL
SmEditAccessible::getAccessibleChildCount( )
1767 throw (RuntimeException
, std::exception
)
1769 SolarMutexGuard aGuard
;
1771 throw RuntimeException();
1772 return pTextHelper
->GetChildCount();
1775 uno::Reference
< XAccessible
> SAL_CALL
SmEditAccessible::getAccessibleChild( sal_Int32 i
)
1776 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1778 SolarMutexGuard aGuard
;
1780 throw RuntimeException();
1781 return pTextHelper
->GetChild( i
);
1784 uno::Reference
< XAccessible
> SAL_CALL
SmEditAccessible::getAccessibleParent( )
1785 throw (RuntimeException
, std::exception
)
1787 SolarMutexGuard aGuard
;
1789 throw RuntimeException();
1791 vcl::Window
*pAccParent
= pWin
->GetAccessibleParentWindow();
1792 OSL_ENSURE( pAccParent
, "accessible parent missing" );
1793 return pAccParent
? pAccParent
->GetAccessible() : Reference
< XAccessible
>();
1796 sal_Int32 SAL_CALL
SmEditAccessible::getAccessibleIndexInParent( )
1797 throw (RuntimeException
, std::exception
)
1799 SolarMutexGuard aGuard
;
1800 sal_Int32 nIdx
= -1;
1801 vcl::Window
*pAccParent
= pWin
? pWin
->GetAccessibleParentWindow() : nullptr;
1804 sal_uInt16 nCnt
= pAccParent
->GetAccessibleChildWindowCount();
1805 for (sal_uInt16 i
= 0; i
< nCnt
&& nIdx
== -1; ++i
)
1806 if (pAccParent
->GetAccessibleChildWindow( i
) == pWin
)
1812 sal_Int16 SAL_CALL
SmEditAccessible::getAccessibleRole( )
1813 throw (RuntimeException
, std::exception
)
1815 SolarMutexGuard aGuard
;
1816 return AccessibleRole::PANEL
/*TEXT ?*/;
1819 OUString SAL_CALL
SmEditAccessible::getAccessibleDescription( )
1820 throw (RuntimeException
, std::exception
)
1822 SolarMutexGuard aGuard
;
1823 return OUString(); // empty as agreed with product-management
1826 OUString SAL_CALL
SmEditAccessible::getAccessibleName( )
1827 throw (RuntimeException
, std::exception
)
1829 SolarMutexGuard aGuard
;
1830 // same name as displayed by the window when not docked
1834 uno::Reference
< XAccessibleRelationSet
> SAL_CALL
SmEditAccessible::getAccessibleRelationSet( )
1835 throw (RuntimeException
, std::exception
)
1837 SolarMutexGuard aGuard
;
1838 Reference
< XAccessibleRelationSet
> xRelSet
= new utl::AccessibleRelationSetHelper();
1839 return xRelSet
; // empty relation set
1842 uno::Reference
< XAccessibleStateSet
> SAL_CALL
SmEditAccessible::getAccessibleStateSet( )
1843 throw (RuntimeException
, std::exception
)
1845 SolarMutexGuard aGuard
;
1846 ::utl::AccessibleStateSetHelper
*pStateSet
=
1847 new ::utl::AccessibleStateSetHelper
;
1849 Reference
<XAccessibleStateSet
> xStateSet( pStateSet
);
1851 if (!pWin
|| !pTextHelper
)
1852 pStateSet
->AddState( AccessibleStateType::DEFUNC
);
1855 pStateSet
->AddState( AccessibleStateType::MULTI_LINE
);
1856 pStateSet
->AddState( AccessibleStateType::ENABLED
);
1857 pStateSet
->AddState( AccessibleStateType::FOCUSABLE
);
1858 if (pWin
->HasFocus())
1859 pStateSet
->AddState( AccessibleStateType::FOCUSED
);
1860 if (pWin
->IsActive())
1861 pStateSet
->AddState( AccessibleStateType::ACTIVE
);
1862 if (pWin
->IsVisible())
1863 pStateSet
->AddState( AccessibleStateType::SHOWING
);
1864 if (pWin
->IsReallyVisible())
1865 pStateSet
->AddState( AccessibleStateType::VISIBLE
);
1866 if (COL_TRANSPARENT
!= pWin
->GetBackground().GetColor().GetColor())
1867 pStateSet
->AddState( AccessibleStateType::OPAQUE
);
1873 Locale SAL_CALL
SmEditAccessible::getLocale( )
1874 throw (IllegalAccessibleComponentStateException
, RuntimeException
, std::exception
)
1876 SolarMutexGuard aGuard
;
1877 // should be the document language...
1878 // We use the language of the localized symbol names here.
1879 return Application::GetSettings().GetUILanguageTag().getLocale();
1883 // XAccessibleEventBroadcaster
1884 void SAL_CALL
SmEditAccessible::addAccessibleEventListener( const uno::Reference
< XAccessibleEventListener
>& xListener
)
1885 throw (RuntimeException
, std::exception
)
1887 if (pTextHelper
) // not disposing (about to destroy view shell)
1888 pTextHelper
->AddEventListener( xListener
);
1891 void SAL_CALL
SmEditAccessible::removeAccessibleEventListener( const uno::Reference
< XAccessibleEventListener
>& xListener
)
1892 throw (RuntimeException
, std::exception
)
1894 if (pTextHelper
) // not disposing (about to destroy view shell)
1895 pTextHelper
->RemoveEventListener( xListener
);
1898 OUString SAL_CALL
SmEditAccessible::getImplementationName()
1899 throw (RuntimeException
, std::exception
)
1901 return OUString("SmEditAccessible");
1904 sal_Bool SAL_CALL
SmEditAccessible::supportsService(
1905 const OUString
& rServiceName
)
1906 throw (RuntimeException
, std::exception
)
1908 return cppu::supportsService(this, rServiceName
);
1911 Sequence
< OUString
> SAL_CALL
SmEditAccessible::getSupportedServiceNames()
1912 throw (RuntimeException
, std::exception
)
1914 return Sequence
< OUString
>{
1915 "css::accessibility::Accessible",
1916 "css::accessibility::AccessibleComponent",
1917 "css::accessibility::AccessibleContext"
1922 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */