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>
21 #include <sal/log.hxx>
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/AccessibleEventObject.hpp>
29 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
30 #include <unotools/accessiblerelationsethelper.hxx>
32 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
33 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
34 #include <com/sun/star/i18n/WordType.hpp>
35 #include <unotools/accessiblestatesethelper.hxx>
36 #include <comphelper/accessibleeventnotifier.hxx>
37 #include <cppuhelper/supportsservice.hxx>
38 #include <osl/diagnose.h>
39 #include <svx/AccessibleTextHelper.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/window.hxx>
42 #include <vcl/unohelp2.hxx>
43 #include <vcl/settings.hxx>
45 #include <tools/gen.hxx>
46 #include <svl/itemset.hxx>
48 #include <editeng/editobj.hxx>
49 #include <editeng/editdata.hxx>
50 #include <editeng/editview.hxx>
51 #include <editeng/eeitem.hxx>
52 #include <editeng/outliner.hxx>
53 #include <editeng/unoedhlp.hxx>
56 #include "accessibility.hxx"
57 #include <document.hxx>
59 #include <strings.hrc>
62 using namespace com::sun::star
;
63 using namespace com::sun::star::lang
;
64 using namespace com::sun::star::uno
;
65 using namespace com::sun::star::accessibility
;
68 static awt::Rectangle
lcl_GetBounds( vcl::Window
const *pWin
)
70 // !! see VCLXAccessibleComponent::implGetBounds()
72 //! the coordinates returned are relative to the parent window !
73 //! Thus the top-left point may be different from (0, 0) !
75 awt::Rectangle aBounds
;
78 tools::Rectangle aRect
= pWin
->GetWindowExtentsRelative( nullptr );
79 aBounds
.X
= aRect
.Left();
80 aBounds
.Y
= aRect
.Top();
81 aBounds
.Width
= aRect
.GetWidth();
82 aBounds
.Height
= aRect
.GetHeight();
83 vcl::Window
* pParent
= pWin
->GetAccessibleParentWindow();
86 tools::Rectangle aParentRect
= pParent
->GetWindowExtentsRelative( nullptr );
87 awt::Point
aParentScreenLoc( aParentRect
.Left(), aParentRect
.Top() );
88 aBounds
.X
-= aParentScreenLoc
.X
;
89 aBounds
.Y
-= aParentScreenLoc
.Y
;
95 static awt::Point
lcl_GetLocationOnScreen( vcl::Window
const *pWin
)
97 // !! see VCLXAccessibleComponent::getLocationOnScreen()
102 tools::Rectangle aRect
= pWin
->GetWindowExtentsRelative( nullptr );
103 aPos
.X
= aRect
.Left();
104 aPos
.Y
= aRect
.Top();
110 SmGraphicAccessible::SmGraphicAccessible( SmGraphicWindow
*pGraphicWin
) :
111 aAccName (SmResId(RID_DOCUMENTSTR
)),
115 OSL_ENSURE( pWin
, "SmGraphicAccessible: window missing" );
118 SmGraphicAccessible::~SmGraphicAccessible()
123 SmDocShell
* SmGraphicAccessible::GetDoc_Impl()
125 SmViewShell
*pView
= pWin
? pWin
->GetView() : nullptr;
126 return pView
? pView
->GetDoc() : nullptr;
129 OUString
SmGraphicAccessible::GetAccessibleText_Impl()
132 SmDocShell
*pDoc
= GetDoc_Impl();
134 aTxt
= pDoc
->GetAccessibleText();
138 void SmGraphicAccessible::ClearWin()
140 pWin
= nullptr; // implicitly results in AccessibleStateType::DEFUNC set
144 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId
, *this );
149 void SmGraphicAccessible::LaunchEvent(
150 const sal_Int16 nAccessibleEventId
,
151 const uno::Any
&rOldVal
,
152 const uno::Any
&rNewVal
)
154 AccessibleEventObject aEvt
;
155 aEvt
.Source
= static_cast<XAccessible
*>(this);
156 aEvt
.EventId
= nAccessibleEventId
;
157 aEvt
.OldValue
= rOldVal
;
158 aEvt
.NewValue
= rNewVal
;
160 // pass event on to event-listener's
162 comphelper::AccessibleEventNotifier::addEvent( nClientId
, aEvt
);
165 uno::Reference
< XAccessibleContext
> SAL_CALL
SmGraphicAccessible::getAccessibleContext()
170 sal_Bool SAL_CALL
SmGraphicAccessible::containsPoint( const awt::Point
& aPoint
)
172 //! the arguments coordinates are relative to the current window !
173 //! Thus the top-left point is (0, 0)
175 SolarMutexGuard aGuard
;
177 throw RuntimeException();
179 Size
aSz( pWin
->GetSizePixel() );
180 return aPoint
.X
>= 0 && aPoint
.Y
>= 0 &&
181 aPoint
.X
< aSz
.Width() && aPoint
.Y
< aSz
.Height();
184 uno::Reference
< XAccessible
> SAL_CALL
SmGraphicAccessible::getAccessibleAtPoint(
185 const awt::Point
& aPoint
)
187 SolarMutexGuard aGuard
;
188 XAccessible
*pRes
= nullptr;
189 if (containsPoint( aPoint
))
194 awt::Rectangle SAL_CALL
SmGraphicAccessible::getBounds()
196 SolarMutexGuard aGuard
;
198 throw RuntimeException();
199 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
200 "mismatch of window parent and accessible parent" );
201 return lcl_GetBounds( pWin
);
204 awt::Point SAL_CALL
SmGraphicAccessible::getLocation()
206 SolarMutexGuard aGuard
;
208 throw RuntimeException();
209 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
210 "mismatch of window parent and accessible parent" );
211 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
212 return awt::Point( aRect
.X
, aRect
.Y
);
215 awt::Point SAL_CALL
SmGraphicAccessible::getLocationOnScreen()
217 SolarMutexGuard aGuard
;
219 throw RuntimeException();
220 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
221 "mismatch of window parent and accessible parent" );
222 return lcl_GetLocationOnScreen( pWin
);
225 awt::Size SAL_CALL
SmGraphicAccessible::getSize()
227 SolarMutexGuard aGuard
;
229 throw RuntimeException();
230 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
231 "mismatch of window parent and accessible parent" );
233 Size
aSz( pWin
->GetSizePixel() );
234 #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
235 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
236 Size
aSz2( aRect
.Width
, aRect
.Height
);
237 assert(aSz
== aSz2
&& "mismatch in width" );
239 return awt::Size( aSz
.Width(), aSz
.Height() );
242 void SAL_CALL
SmGraphicAccessible::grabFocus()
244 SolarMutexGuard aGuard
;
246 throw RuntimeException();
251 sal_Int32 SAL_CALL
SmGraphicAccessible::getForeground()
253 SolarMutexGuard aGuard
;
256 throw RuntimeException();
257 return static_cast<sal_Int32
>(pWin
->GetTextColor());
260 sal_Int32 SAL_CALL
SmGraphicAccessible::getBackground()
262 SolarMutexGuard aGuard
;
265 throw RuntimeException();
266 Wallpaper
aWall( pWin
->GetDisplayBackground() );
268 if (aWall
.IsBitmap() || aWall
.IsGradient())
269 nCol
= pWin
->GetSettings().GetStyleSettings().GetWindowColor();
271 nCol
= aWall
.GetColor();
272 return static_cast<sal_Int32
>(nCol
);
275 sal_Int32 SAL_CALL
SmGraphicAccessible::getAccessibleChildCount()
280 Reference
< XAccessible
> SAL_CALL
SmGraphicAccessible::getAccessibleChild(
283 throw IndexOutOfBoundsException(); // there is no child...
286 Reference
< XAccessible
> SAL_CALL
SmGraphicAccessible::getAccessibleParent()
288 SolarMutexGuard aGuard
;
290 throw RuntimeException();
292 vcl::Window
*pAccParent
= pWin
->GetAccessibleParentWindow();
293 OSL_ENSURE( pAccParent
, "accessible parent missing" );
294 return pAccParent
? pAccParent
->GetAccessible() : Reference
< XAccessible
>();
297 sal_Int32 SAL_CALL
SmGraphicAccessible::getAccessibleIndexInParent()
299 SolarMutexGuard aGuard
;
301 vcl::Window
*pAccParent
= pWin
? pWin
->GetAccessibleParentWindow() : nullptr;
304 sal_uInt16 nCnt
= pAccParent
->GetAccessibleChildWindowCount();
305 for (sal_uInt16 i
= 0; i
< nCnt
&& nIdx
== -1; ++i
)
306 if (pAccParent
->GetAccessibleChildWindow( i
) == pWin
)
312 sal_Int16 SAL_CALL
SmGraphicAccessible::getAccessibleRole()
314 return AccessibleRole::DOCUMENT
;
317 OUString SAL_CALL
SmGraphicAccessible::getAccessibleDescription()
319 SolarMutexGuard aGuard
;
320 SmDocShell
*pDoc
= GetDoc_Impl();
321 return pDoc
? pDoc
->GetText() : OUString();
324 OUString SAL_CALL
SmGraphicAccessible::getAccessibleName()
326 SolarMutexGuard aGuard
;
330 Reference
< XAccessibleRelationSet
> SAL_CALL
SmGraphicAccessible::getAccessibleRelationSet()
332 SolarMutexGuard aGuard
;
333 Reference
< XAccessibleRelationSet
> xRelSet
= new utl::AccessibleRelationSetHelper();
334 return xRelSet
; // empty relation set
337 Reference
< XAccessibleStateSet
> SAL_CALL
SmGraphicAccessible::getAccessibleStateSet()
339 SolarMutexGuard aGuard
;
340 ::utl::AccessibleStateSetHelper
*pStateSet
=
341 new ::utl::AccessibleStateSetHelper
;
343 Reference
<XAccessibleStateSet
> xStateSet( pStateSet
);
346 pStateSet
->AddState( AccessibleStateType::DEFUNC
);
349 pStateSet
->AddState( AccessibleStateType::ENABLED
);
350 pStateSet
->AddState( AccessibleStateType::FOCUSABLE
);
351 if (pWin
->HasFocus())
352 pStateSet
->AddState( AccessibleStateType::FOCUSED
);
353 if (pWin
->IsActive())
354 pStateSet
->AddState( AccessibleStateType::ACTIVE
);
355 if (pWin
->IsVisible())
356 pStateSet
->AddState( AccessibleStateType::SHOWING
);
357 if (pWin
->IsReallyVisible())
358 pStateSet
->AddState( AccessibleStateType::VISIBLE
);
359 if (COL_TRANSPARENT
!= pWin
->GetBackground().GetColor())
360 pStateSet
->AddState( AccessibleStateType::OPAQUE
);
366 Locale SAL_CALL
SmGraphicAccessible::getLocale()
368 SolarMutexGuard aGuard
;
369 // should be the document language...
370 // We use the language of the localized symbol names here.
371 return Application::GetSettings().GetUILanguageTag().getLocale();
375 void SAL_CALL
SmGraphicAccessible::addAccessibleEventListener(
376 const Reference
< XAccessibleEventListener
>& xListener
)
380 SolarMutexGuard aGuard
;
384 nClientId
= comphelper::AccessibleEventNotifier::registerClient( );
385 comphelper::AccessibleEventNotifier::addEventListener( nClientId
, xListener
);
390 void SAL_CALL
SmGraphicAccessible::removeAccessibleEventListener(
391 const Reference
< XAccessibleEventListener
>& xListener
)
393 if (!(xListener
.is() && nClientId
))
396 SolarMutexGuard aGuard
;
397 sal_Int32 nListenerCount
= comphelper::AccessibleEventNotifier::removeEventListener( nClientId
, xListener
);
398 if ( !nListenerCount
)
400 // no listeners anymore
401 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
402 // and at least to us not firing any events anymore, in case somebody calls
403 // NotifyAccessibleEvent, again
404 comphelper::AccessibleEventNotifier::revokeClient( nClientId
);
409 sal_Int32 SAL_CALL
SmGraphicAccessible::getCaretPosition()
414 sal_Bool SAL_CALL
SmGraphicAccessible::setCaretPosition( sal_Int32 nIndex
)
416 SolarMutexGuard aGuard
;
417 OUString
aTxt( GetAccessibleText_Impl() );
418 if (nIndex
>= aTxt
.getLength())
419 throw IndexOutOfBoundsException();
423 sal_Unicode SAL_CALL
SmGraphicAccessible::getCharacter( sal_Int32 nIndex
)
425 SolarMutexGuard aGuard
;
426 OUString
aTxt( GetAccessibleText_Impl() );
427 if (nIndex
>= aTxt
.getLength())
428 throw IndexOutOfBoundsException();
432 Sequence
< beans::PropertyValue
> SAL_CALL
SmGraphicAccessible::getCharacterAttributes(
434 const uno::Sequence
< OUString
> & /*rRequestedAttributes*/ )
436 SolarMutexGuard aGuard
;
437 sal_Int32 nLen
= GetAccessibleText_Impl().getLength();
438 if (0 > nIndex
|| nIndex
>= nLen
)
439 throw IndexOutOfBoundsException();
440 return Sequence
< beans::PropertyValue
>();
443 awt::Rectangle SAL_CALL
SmGraphicAccessible::getCharacterBounds( sal_Int32 nIndex
)
445 SolarMutexGuard aGuard
;
450 throw RuntimeException();
452 // get accessible text
453 SmViewShell
*pView
= pWin
->GetView();
454 SmDocShell
*pDoc
= pView
? pView
->GetDoc() : nullptr;
456 throw RuntimeException();
457 OUString
aTxt( GetAccessibleText_Impl() );
458 if (0 > nIndex
|| nIndex
> aTxt
.getLength()) // aTxt.getLength() is valid
459 throw IndexOutOfBoundsException();
461 // find a reasonable rectangle for position aTxt.getLength().
462 bool bWasBehindText
= (nIndex
== aTxt
.getLength());
463 if (bWasBehindText
&& nIndex
)
466 const SmNode
*pTree
= pDoc
->GetFormulaTree();
467 const SmNode
*pNode
= pTree
->FindNodeWithAccessibleIndex( nIndex
);
468 //! pNode may be 0 if the index belongs to a char that was inserted
469 //! only for the accessible text!
472 sal_Int32 nAccIndex
= pNode
->GetAccessibleIndex();
473 OSL_ENSURE( nAccIndex
>= 0, "invalid accessible index" );
474 OSL_ENSURE( nIndex
>= nAccIndex
, "index out of range" );
477 pNode
->GetAccessibleText(aBuf
);
478 OUString aNodeText
= aBuf
.makeStringAndClear();
479 sal_Int32 nNodeIndex
= nIndex
- nAccIndex
;
480 if (0 <= nNodeIndex
&& nNodeIndex
< aNodeText
.getLength())
482 // get appropriate rectangle
483 Point
aOffset(pNode
->GetTopLeft() - pTree
->GetTopLeft());
484 Point
aTLPos (pWin
->GetFormulaDrawPos() + aOffset
);
485 Size
aSize (pNode
->GetSize());
487 std::unique_ptr
<tools::Long
[]> pXAry(new tools::Long
[ aNodeText
.getLength() ]);
488 pWin
->SetFont( pNode
->GetFont() );
489 pWin
->GetTextArray( aNodeText
, pXAry
.get(), 0, aNodeText
.getLength() );
490 aTLPos
.AdjustX(nNodeIndex
> 0 ? pXAry
[nNodeIndex
- 1] : 0 );
491 aSize
.setWidth( nNodeIndex
> 0 ? pXAry
[nNodeIndex
] - pXAry
[nNodeIndex
- 1] : pXAry
[nNodeIndex
] );
494 aTLPos
= pWin
->LogicToPixel( aTLPos
);
495 aSize
= pWin
->LogicToPixel( aSize
);
498 aRes
.Width
= aSize
.Width();
499 aRes
.Height
= aSize
.Height();
503 // take rectangle from last character and move it to the right
505 aRes
.X
+= aRes
.Width
;
510 sal_Int32 SAL_CALL
SmGraphicAccessible::getCharacterCount()
512 SolarMutexGuard aGuard
;
513 return GetAccessibleText_Impl().getLength();
516 sal_Int32 SAL_CALL
SmGraphicAccessible::getIndexAtPoint( const awt::Point
& aPoint
)
518 SolarMutexGuard aGuard
;
523 const SmNode
*pTree
= pWin
->GetView()->GetDoc()->GetFormulaTree();
524 // can be NULL! e.g. if one clicks within the window already during loading of the
525 // document (before the parser even started)
529 // get position relative to formula draw position
530 Point
aPos( aPoint
.X
, aPoint
.Y
);
531 aPos
= pWin
->PixelToLogic( aPos
);
532 aPos
-= pWin
->GetFormulaDrawPos();
534 // if it was inside the formula then get the appropriate node
535 const SmNode
*pNode
= nullptr;
536 if (pTree
->OrientedDist(aPos
) <= 0)
537 pNode
= pTree
->FindRectClosestTo(aPos
);
541 // get appropriate rectangle
542 Point
aOffset( pNode
->GetTopLeft() - pTree
->GetTopLeft() );
543 Point
aTLPos ( aOffset
);
544 Size
aSize( pNode
->GetSize() );
546 tools::Rectangle
aRect( aTLPos
, aSize
);
547 if (aRect
.IsInside( aPos
))
549 OSL_ENSURE( pNode
->IsVisible(), "node is not a leaf" );
551 pNode
->GetAccessibleText(aBuf
);
552 OUString aTxt
= aBuf
.makeStringAndClear();
553 OSL_ENSURE( !aTxt
.isEmpty(), "no accessible text available" );
555 tools::Long nNodeX
= pNode
->GetLeft();
557 std::unique_ptr
<tools::Long
[]> pXAry(new tools::Long
[ aTxt
.getLength() ]);
558 pWin
->SetFont( pNode
->GetFont() );
559 pWin
->GetTextArray( aTxt
, pXAry
.get(), 0, aTxt
.getLength() );
560 for (sal_Int32 i
= 0; i
< aTxt
.getLength() && nRes
== -1; ++i
)
562 if (pXAry
[i
] + nNodeX
> aPos
.X())
566 OSL_ENSURE( nRes
>= 0 && nRes
< aTxt
.getLength(), "index out of range" );
567 OSL_ENSURE( pNode
->GetAccessibleIndex() >= 0,
568 "invalid accessible index" );
570 nRes
= pNode
->GetAccessibleIndex() + nRes
;
577 OUString SAL_CALL
SmGraphicAccessible::getSelectedText()
582 sal_Int32 SAL_CALL
SmGraphicAccessible::getSelectionStart()
587 sal_Int32 SAL_CALL
SmGraphicAccessible::getSelectionEnd()
592 sal_Bool SAL_CALL
SmGraphicAccessible::setSelection(
593 sal_Int32 nStartIndex
,
594 sal_Int32 nEndIndex
)
596 SolarMutexGuard aGuard
;
597 sal_Int32 nLen
= GetAccessibleText_Impl().getLength();
598 if (0 > nStartIndex
|| nStartIndex
>= nLen
||
599 0 > nEndIndex
|| nEndIndex
>= nLen
)
600 throw IndexOutOfBoundsException();
604 OUString SAL_CALL
SmGraphicAccessible::getText()
606 SolarMutexGuard aGuard
;
607 return GetAccessibleText_Impl();
610 OUString SAL_CALL
SmGraphicAccessible::getTextRange(
611 sal_Int32 nStartIndex
,
612 sal_Int32 nEndIndex
)
614 //!! nEndIndex may be the string length per definition of the interface !!
615 //!! text should be copied exclusive that end index though. And arguments
616 //!! may be switched.
618 SolarMutexGuard aGuard
;
619 OUString
aTxt( GetAccessibleText_Impl() );
620 sal_Int32 nStart
= std::min(nStartIndex
, nEndIndex
);
621 sal_Int32 nEnd
= std::max(nStartIndex
, nEndIndex
);
622 if ((nStart
> aTxt
.getLength()) ||
623 (nEnd
> aTxt
.getLength()))
624 throw IndexOutOfBoundsException();
625 return aTxt
.copy( nStart
, nEnd
- nStart
);
628 css::accessibility::TextSegment SAL_CALL
SmGraphicAccessible::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
)
630 SolarMutexGuard aGuard
;
631 OUString
aTxt( GetAccessibleText_Impl() );
632 //!! nIndex is allowed to be the string length
633 if (nIndex
> aTxt
.getLength())
634 throw IndexOutOfBoundsException();
636 css::accessibility::TextSegment aResult
;
637 aResult
.SegmentStart
= -1;
638 aResult
.SegmentEnd
= -1;
639 if ( (AccessibleTextType::CHARACTER
== aTextType
) && (nIndex
< aTxt
.getLength()) )
641 aResult
.SegmentText
= aTxt
.copy(nIndex
, 1);
642 aResult
.SegmentStart
= nIndex
;
643 aResult
.SegmentEnd
= nIndex
+1;
648 css::accessibility::TextSegment SAL_CALL
SmGraphicAccessible::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
)
650 SolarMutexGuard aGuard
;
651 OUString
aTxt( GetAccessibleText_Impl() );
652 //!! nIndex is allowed to be the string length
653 if (nIndex
> aTxt
.getLength())
654 throw IndexOutOfBoundsException();
656 css::accessibility::TextSegment aResult
;
657 aResult
.SegmentStart
= -1;
658 aResult
.SegmentEnd
= -1;
660 if ( (AccessibleTextType::CHARACTER
== aTextType
) && nIndex
)
662 aResult
.SegmentText
= aTxt
.copy(nIndex
-1, 1);
663 aResult
.SegmentStart
= nIndex
-1;
664 aResult
.SegmentEnd
= nIndex
;
669 css::accessibility::TextSegment SAL_CALL
SmGraphicAccessible::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
)
671 SolarMutexGuard aGuard
;
672 OUString
aTxt( GetAccessibleText_Impl() );
673 //!! nIndex is allowed to be the string length
674 if (nIndex
> aTxt
.getLength())
675 throw IndexOutOfBoundsException();
677 css::accessibility::TextSegment aResult
;
678 aResult
.SegmentStart
= -1;
679 aResult
.SegmentEnd
= -1;
681 nIndex
++; // text *behind*
682 if ( (AccessibleTextType::CHARACTER
== aTextType
) && (nIndex
< aTxt
.getLength()) )
684 aResult
.SegmentText
= aTxt
.copy(nIndex
, 1);
685 aResult
.SegmentStart
= nIndex
;
686 aResult
.SegmentEnd
= nIndex
+1;
691 sal_Bool SAL_CALL
SmGraphicAccessible::copyText(
692 sal_Int32 nStartIndex
,
693 sal_Int32 nEndIndex
)
695 SolarMutexGuard aGuard
;
696 bool bReturn
= false;
699 throw RuntimeException();
701 Reference
< datatransfer::clipboard::XClipboard
> xClipboard
= pWin
->GetClipboard();
702 if ( xClipboard
.is() )
704 OUString
sText( getTextRange(nStartIndex
, nEndIndex
) );
706 vcl::unohelper::TextDataObject
* pDataObj
= new vcl::unohelper::TextDataObject( sText
);
707 SolarMutexReleaser aReleaser
;
708 xClipboard
->setContents( pDataObj
, nullptr );
710 Reference
< datatransfer::clipboard::XFlushableClipboard
> xFlushableClipboard( xClipboard
, uno::UNO_QUERY
);
711 if( xFlushableClipboard
.is() )
712 xFlushableClipboard
->flushClipboard();
721 sal_Bool SAL_CALL
SmGraphicAccessible::scrollSubstringTo( sal_Int32
, sal_Int32
, AccessibleScrollType
)
726 OUString SAL_CALL
SmGraphicAccessible::getImplementationName()
728 return "SmGraphicAccessible";
731 sal_Bool SAL_CALL
SmGraphicAccessible::supportsService(
732 const OUString
& rServiceName
)
734 return cppu::supportsService(this, rServiceName
);
737 Sequence
< OUString
> SAL_CALL
SmGraphicAccessible::getSupportedServiceNames()
740 "css::accessibility::Accessible",
741 "css::accessibility::AccessibleComponent",
742 "css::accessibility::AccessibleContext",
743 "css::accessibility::AccessibleText"
748 SmEditSource::SmEditSource( SmEditAccessible
&rAcc
) :
750 aTextFwd (rAcc
, *this),
756 SmEditSource::SmEditSource( const SmEditSource
&rSrc
) :
758 aViewFwd (rSrc
.rEditAcc
),
759 aTextFwd (rSrc
.rEditAcc
, *this),
760 aEditViewFwd(rSrc
.rEditAcc
),
761 rEditAcc (rSrc
.rEditAcc
)
765 SmEditSource::~SmEditSource()
769 std::unique_ptr
<SvxEditSource
> SmEditSource::Clone() const
771 return std::unique_ptr
<SvxEditSource
>(new SmEditSource( *this ));
774 SvxTextForwarder
* SmEditSource::GetTextForwarder()
779 SvxViewForwarder
* SmEditSource::GetViewForwarder()
784 SvxEditViewForwarder
* SmEditSource::GetEditViewForwarder( bool /*bCreate*/ )
786 return &aEditViewFwd
;
789 void SmEditSource::UpdateData()
791 // would possibly only by needed if the XText interface is implemented
792 // and its text needs to be updated.
795 SfxBroadcaster
& SmEditSource::GetBroadcaster() const
797 return const_cast<SmEditSource
*>(this)->aBroadCaster
;
800 SmViewForwarder::SmViewForwarder( SmEditAccessible
&rAcc
) :
805 SmViewForwarder::~SmViewForwarder()
809 bool SmViewForwarder::IsValid() const
811 return rEditAcc
.GetEditView() != nullptr;
814 Point
SmViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
816 EditView
*pEditView
= rEditAcc
.GetEditView();
817 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : nullptr;
821 MapMode
aMapMode(pOutDev
->GetMapMode());
822 Point
aPoint( OutputDevice::LogicToLogic( rPoint
, rMapMode
,
823 MapMode(aMapMode
.GetMapUnit())) );
824 aMapMode
.SetOrigin(Point());
825 return pOutDev
->LogicToPixel( aPoint
, aMapMode
);
831 Point
SmViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
833 EditView
*pEditView
= rEditAcc
.GetEditView();
834 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : nullptr;
838 MapMode
aMapMode(pOutDev
->GetMapMode());
839 aMapMode
.SetOrigin(Point());
840 Point
aPoint( pOutDev
->PixelToLogic( rPoint
, aMapMode
) );
841 return OutputDevice::LogicToLogic( aPoint
,
842 MapMode(aMapMode
.GetMapUnit()),
850 SmTextForwarder::SmTextForwarder( SmEditAccessible
& rAcc
, SmEditSource
& rSource
) :
852 rEditSource (rSource
)
854 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
856 pEditEngine
->SetNotifyHdl( LINK(this, SmTextForwarder
, NotifyHdl
) );
859 SmTextForwarder::~SmTextForwarder()
861 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
863 pEditEngine
->SetNotifyHdl( Link
<EENotify
&,void>() );
866 IMPL_LINK(SmTextForwarder
, NotifyHdl
, EENotify
&, rNotify
, void)
868 ::std::unique_ptr
< SfxHint
> aHint
= SvxEditSourceHelper::EENotification2Hint( &rNotify
);
870 rEditSource
.GetBroadcaster().Broadcast(*aHint
);
873 sal_Int32
SmTextForwarder::GetParagraphCount() const
875 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
876 return pEditEngine
? pEditEngine
->GetParagraphCount() : 0;
879 sal_Int32
SmTextForwarder::GetTextLen( sal_Int32 nParagraph
) const
881 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
882 return pEditEngine
? pEditEngine
->GetTextLen( nParagraph
) : 0;
885 OUString
SmTextForwarder::GetText( const ESelection
& rSel
) const
887 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
890 aRet
= pEditEngine
->GetText( rSel
);
891 return convertLineEnd(aRet
, GetSystemLineEnd());
894 SfxItemSet
SmTextForwarder::GetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
) const
896 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
897 assert(pEditEngine
&& "EditEngine missing");
898 if( rSel
.nStartPara
== rSel
.nEndPara
)
900 GetAttribsFlags nFlags
= GetAttribsFlags::NONE
;
901 switch( nOnlyHardAttrib
)
903 case EditEngineAttribs::All
:
904 nFlags
= GetAttribsFlags::ALL
;
906 case EditEngineAttribs::OnlyHard
:
907 nFlags
= GetAttribsFlags::CHARATTRIBS
;
910 SAL_WARN("starmath", "unknown flags for SmTextForwarder::GetAttribs");
913 return pEditEngine
->GetAttribs( rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
917 return pEditEngine
->GetAttribs( rSel
, nOnlyHardAttrib
);
921 SfxItemSet
SmTextForwarder::GetParaAttribs( sal_Int32 nPara
) const
923 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
924 assert(pEditEngine
&& "EditEngine missing");
926 SfxItemSet
aSet( pEditEngine
->GetParaAttribs( nPara
) );
928 sal_uInt16 nWhich
= EE_PARA_START
;
929 while( nWhich
<= EE_PARA_END
)
931 if( aSet
.GetItemState( nWhich
) != SfxItemState::SET
)
933 if( pEditEngine
->HasParaAttrib( nPara
, nWhich
) )
934 aSet
.Put( pEditEngine
->GetParaAttrib( nPara
, nWhich
) );
942 void SmTextForwarder::SetParaAttribs( sal_Int32 nPara
, const SfxItemSet
& rSet
)
944 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
946 pEditEngine
->SetParaAttribs( nPara
, rSet
);
949 SfxItemPool
* SmTextForwarder::GetPool() const
951 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
952 return pEditEngine
? pEditEngine
->GetEmptyItemSet().GetPool() : nullptr;
955 void SmTextForwarder::RemoveAttribs( const ESelection
& rSelection
)
957 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
959 pEditEngine
->RemoveAttribs( rSelection
, false/*bRemoveParaAttribs*/, 0 );
962 void SmTextForwarder::GetPortions( sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
964 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
966 pEditEngine
->GetPortions( nPara
, rList
);
969 void SmTextForwarder::QuickInsertText( const OUString
& rText
, const ESelection
& rSel
)
971 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
973 pEditEngine
->QuickInsertText( rText
, rSel
);
976 void SmTextForwarder::QuickInsertLineBreak( const ESelection
& rSel
)
978 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
980 pEditEngine
->QuickInsertLineBreak( rSel
);
983 void SmTextForwarder::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
985 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
987 pEditEngine
->QuickInsertField( rFld
, rSel
);
990 void SmTextForwarder::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
992 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
994 pEditEngine
->QuickSetAttribs( rSet
, rSel
);
997 bool SmTextForwarder::IsValid() const
999 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1000 // cannot reliably query EditEngine state
1001 // while in the middle of an update
1002 return pEditEngine
&& pEditEngine
->GetUpdateMode();
1005 OUString
SmTextForwarder::CalcFieldValue( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
, std::optional
<Color
>& rpTxtColor
, std::optional
<Color
>& rpFldColor
)
1007 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1008 return pEditEngine
? pEditEngine
->CalcFieldValue(rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
) : OUString();
1011 void SmTextForwarder::FieldClicked(const SvxFieldItem
&)
1015 static SfxItemState
GetSvxEditEngineItemState( EditEngine
const & rEditEngine
, const ESelection
& rSel
, sal_uInt16 nWhich
)
1017 std::vector
<EECharAttrib
> aAttribs
;
1019 const SfxPoolItem
* pLastItem
= nullptr;
1021 SfxItemState eState
= SfxItemState::DEFAULT
;
1023 // check all paragraphs inside the selection
1024 for( sal_Int32 nPara
= rSel
.nStartPara
; nPara
<= rSel
.nEndPara
; nPara
++ )
1026 SfxItemState eParaState
= SfxItemState::DEFAULT
;
1028 // calculate start and endpos for this paragraph
1030 if( rSel
.nStartPara
== nPara
)
1031 nPos
= rSel
.nStartPos
;
1033 sal_Int32 nEndPos
= rSel
.nEndPos
;
1034 if( rSel
.nEndPara
!= nPara
)
1035 nEndPos
= rEditEngine
.GetTextLen( nPara
);
1038 // get list of char attribs
1039 rEditEngine
.GetCharAttribs( nPara
, aAttribs
);
1041 bool bEmpty
= true; // we found no item inside the selection of this paragraph
1042 bool bGaps
= false; // we found items but there are gaps between them
1043 sal_Int32 nLastEnd
= nPos
;
1045 const SfxPoolItem
* pParaItem
= nullptr;
1047 for(const auto& rAttrib
: aAttribs
)
1049 OSL_ENSURE( rAttrib
.pAttr
, "GetCharAttribs gives corrupt data" );
1051 const bool bEmptyPortion
= (rAttrib
.nStart
== rAttrib
.nEnd
);
1052 if( (!bEmptyPortion
&& (rAttrib
.nStart
>= nEndPos
)) || (bEmptyPortion
&& (rAttrib
.nStart
> nEndPos
)) )
1053 break; // break if we are already behind our selection
1055 if( (!bEmptyPortion
&& (rAttrib
.nEnd
<= nPos
)) || (bEmptyPortion
&& (rAttrib
.nEnd
< nPos
)) )
1056 continue; // or if the attribute ends before our selection
1058 if( rAttrib
.pAttr
->Which() != nWhich
)
1059 continue; // skip if is not the searched item
1061 // if we already found an item
1064 // ... and its different to this one than the state is don't care
1065 if( *pParaItem
!= *(rAttrib
.pAttr
) )
1066 return SfxItemState::DONTCARE
;
1070 pParaItem
= rAttrib
.pAttr
;
1076 if( !bGaps
&& rAttrib
.nStart
> nLastEnd
)
1079 nLastEnd
= rAttrib
.nEnd
;
1082 if( !bEmpty
&& !bGaps
&& nLastEnd
< ( nEndPos
- 1 ) )
1085 eParaState
= SfxItemState::DEFAULT
;
1087 eParaState
= SfxItemState::DONTCARE
;
1089 eParaState
= SfxItemState::SET
;
1091 // if we already found an item check if we found the same
1094 if( (pParaItem
== nullptr) || (*pLastItem
!= *pParaItem
) )
1095 return SfxItemState::DONTCARE
;
1099 pLastItem
= pParaItem
;
1100 eState
= eParaState
;
1107 SfxItemState
SmTextForwarder::GetItemState( const ESelection
& rSel
, sal_uInt16 nWhich
) const
1109 SfxItemState nState
= SfxItemState::DISABLED
;
1110 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1112 nState
= GetSvxEditEngineItemState( *pEditEngine
, rSel
, nWhich
);
1116 SfxItemState
SmTextForwarder::GetItemState( sal_Int32 nPara
, sal_uInt16 nWhich
) const
1118 SfxItemState nState
= SfxItemState::DISABLED
;
1119 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1122 const SfxItemSet
& rSet
= pEditEngine
->GetParaAttribs( nPara
);
1123 nState
= rSet
.GetItemState( nWhich
);
1128 LanguageType
SmTextForwarder::GetLanguage( sal_Int32 nPara
, sal_Int32 nIndex
) const
1130 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1131 return pEditEngine
? pEditEngine
->GetLanguage(nPara
, nIndex
) : LANGUAGE_NONE
;
1134 sal_Int32
SmTextForwarder::GetFieldCount( sal_Int32 nPara
) const
1136 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1137 return pEditEngine
? pEditEngine
->GetFieldCount(nPara
) : 0;
1140 EFieldInfo
SmTextForwarder::GetFieldInfo( sal_Int32 nPara
, sal_uInt16 nField
) const
1142 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1143 return pEditEngine
? pEditEngine
->GetFieldInfo( nPara
, nField
) : EFieldInfo();
1146 EBulletInfo
SmTextForwarder::GetBulletInfo( sal_Int32
/*nPara*/ ) const
1148 return EBulletInfo();
1151 tools::Rectangle
SmTextForwarder::GetCharBounds( sal_Int32 nPara
, sal_Int32 nIndex
) const
1153 tools::Rectangle
aRect(0,0,0,0);
1154 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1158 // Handle virtual position one-past-the end of the string
1159 if( nIndex
>= pEditEngine
->GetTextLen(nPara
) )
1162 aRect
= pEditEngine
->GetCharacterBounds( EPosition(nPara
, nIndex
-1) );
1164 aRect
.Move( aRect
.Right() - aRect
.Left(), 0 );
1165 aRect
.SetSize( Size(1, pEditEngine
->GetTextHeight()) );
1169 aRect
= pEditEngine
->GetCharacterBounds( EPosition(nPara
, nIndex
) );
1175 tools::Rectangle
SmTextForwarder::GetParaBounds( sal_Int32 nPara
) const
1177 tools::Rectangle
aRect(0,0,0,0);
1178 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1182 const Point aPnt
= pEditEngine
->GetDocPosTopLeft( nPara
);
1183 const sal_uLong nWidth
= pEditEngine
->CalcTextWidth();
1184 const sal_uLong nHeight
= pEditEngine
->GetTextHeight( nPara
);
1185 aRect
= tools::Rectangle( aPnt
.X(), aPnt
.Y(), aPnt
.X() + nWidth
, aPnt
.Y() + nHeight
);
1191 MapMode
SmTextForwarder::GetMapMode() const
1193 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1194 return pEditEngine
? pEditEngine
->GetRefMapMode() : MapMode( MapUnit::Map100thMM
);
1197 OutputDevice
* SmTextForwarder::GetRefDevice() const
1199 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1200 return pEditEngine
? pEditEngine
->GetRefDevice() : nullptr;
1203 bool SmTextForwarder::GetIndexAtPoint( const Point
& rPos
, sal_Int32
& nPara
, sal_Int32
& nIndex
) const
1206 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1209 EPosition aDocPos
= pEditEngine
->FindDocPosition( rPos
);
1210 nPara
= aDocPos
.nPara
;
1211 nIndex
= aDocPos
.nIndex
;
1217 bool SmTextForwarder::GetWordIndices( sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
, sal_Int32
& nEnd
) const
1220 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1223 ESelection aRes
= pEditEngine
->GetWord( ESelection(nPara
, nIndex
, nPara
, nIndex
), css::i18n::WordType::DICTIONARY_WORD
);
1225 if( aRes
.nStartPara
== nPara
&&
1226 aRes
.nStartPara
== aRes
.nEndPara
)
1228 nStart
= aRes
.nStartPos
;
1229 nEnd
= aRes
.nEndPos
;
1238 bool SmTextForwarder::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
) const
1240 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1243 SvxEditSourceHelper::GetAttributeRun( nStartIndex
, nEndIndex
, *pEditEngine
, nPara
, nIndex
, bInCell
);
1247 sal_Int32
SmTextForwarder::GetLineCount( sal_Int32 nPara
) const
1249 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1250 return pEditEngine
? pEditEngine
->GetLineCount(nPara
) : 0;
1253 sal_Int32
SmTextForwarder::GetLineLen( sal_Int32 nPara
, sal_Int32 nLine
) const
1255 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1256 return pEditEngine
? pEditEngine
->GetLineLen(nPara
, nLine
) : 0;
1259 void SmTextForwarder::GetLineBoundaries( /*out*/sal_Int32
&rStart
, /*out*/sal_Int32
&rEnd
, sal_Int32 nPara
, sal_Int32 nLine
) const
1261 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1263 pEditEngine
->GetLineBoundaries(rStart
, rEnd
, nPara
, nLine
);
1268 sal_Int32
SmTextForwarder::GetLineNumberAtIndex( sal_Int32 nPara
, sal_Int32 nIndex
) const
1270 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1271 return pEditEngine
? pEditEngine
->GetLineNumberAtIndex(nPara
, nIndex
) : 0;
1274 bool SmTextForwarder::QuickFormatDoc( bool /*bFull*/ )
1277 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1280 pEditEngine
->QuickFormatDoc();
1286 sal_Int16
SmTextForwarder::GetDepth( sal_Int32
/*nPara*/ ) const
1288 // math has no outliner...
1292 bool SmTextForwarder::SetDepth( sal_Int32
/*nPara*/, sal_Int16 nNewDepth
)
1294 // math has no outliner...
1295 return -1 == nNewDepth
; // is it the value from 'GetDepth' ?
1298 bool SmTextForwarder::Delete( const ESelection
& rSelection
)
1301 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1304 pEditEngine
->QuickDelete( rSelection
);
1305 pEditEngine
->QuickFormatDoc();
1311 bool SmTextForwarder::InsertText( const OUString
& rStr
, const ESelection
& rSelection
)
1314 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1317 pEditEngine
->QuickInsertText( rStr
, rSelection
);
1318 pEditEngine
->QuickFormatDoc();
1324 const SfxItemSet
* SmTextForwarder::GetEmptyItemSetPtr()
1326 const SfxItemSet
*pItemSet
= nullptr;
1327 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1330 pItemSet
= &pEditEngine
->GetEmptyItemSet();
1335 void SmTextForwarder::AppendParagraph()
1337 // append an empty paragraph
1338 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1341 sal_Int32 nParaCount
= pEditEngine
->GetParagraphCount();
1342 pEditEngine
->InsertParagraph( nParaCount
, OUString() );
1346 sal_Int32
SmTextForwarder::AppendTextPortion( sal_Int32 nPara
, const OUString
&rText
, const SfxItemSet
&rSet
)
1348 sal_uInt16 nRes
= 0;
1349 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1350 if (pEditEngine
&& nPara
< pEditEngine
->GetParagraphCount())
1353 ESelection
aSel( nPara
, pEditEngine
->GetTextLen( nPara
) );
1354 pEditEngine
->QuickInsertText( rText
, aSel
);
1356 // set attributes for new appended text
1357 nRes
= aSel
.nEndPos
= pEditEngine
->GetTextLen( nPara
);
1358 pEditEngine
->QuickSetAttribs( rSet
, aSel
);
1363 void SmTextForwarder::CopyText(const SvxTextForwarder
& rSource
)
1366 const SmTextForwarder
* pSourceForwarder
= dynamic_cast< const SmTextForwarder
* >( &rSource
);
1367 if( !pSourceForwarder
)
1369 EditEngine
* pSourceEditEngine
= pSourceForwarder
->rEditAcc
.GetEditEngine();
1370 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1371 if (pEditEngine
&& pSourceEditEngine
)
1373 std::unique_ptr
<EditTextObject
> pNewTextObject
= pSourceEditEngine
->CreateTextObject();
1374 pEditEngine
->SetText( *pNewTextObject
);
1379 SmEditViewForwarder::SmEditViewForwarder( SmEditAccessible
& rAcc
) :
1384 SmEditViewForwarder::~SmEditViewForwarder()
1388 bool SmEditViewForwarder::IsValid() const
1390 return rEditAcc
.GetEditView() != nullptr;
1394 Point
SmEditViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
1396 EditView
*pEditView
= rEditAcc
.GetEditView();
1397 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : nullptr;
1401 MapMode
aMapMode(pOutDev
->GetMapMode());
1402 Point
aPoint( OutputDevice::LogicToLogic( rPoint
, rMapMode
,
1403 MapMode(aMapMode
.GetMapUnit())));
1404 aMapMode
.SetOrigin(Point());
1405 return pOutDev
->LogicToPixel( aPoint
, aMapMode
);
1411 Point
SmEditViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
1413 EditView
*pEditView
= rEditAcc
.GetEditView();
1414 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : nullptr;
1418 MapMode
aMapMode(pOutDev
->GetMapMode());
1419 aMapMode
.SetOrigin(Point());
1420 Point
aPoint( pOutDev
->PixelToLogic( rPoint
, aMapMode
) );
1421 return OutputDevice::LogicToLogic( aPoint
,
1422 MapMode(aMapMode
.GetMapUnit()),
1429 bool SmEditViewForwarder::GetSelection( ESelection
& rSelection
) const
1432 EditView
*pEditView
= rEditAcc
.GetEditView();
1435 rSelection
= pEditView
->GetSelection();
1441 bool SmEditViewForwarder::SetSelection( const ESelection
& rSelection
)
1444 EditView
*pEditView
= rEditAcc
.GetEditView();
1447 pEditView
->SetSelection( rSelection
);
1453 bool SmEditViewForwarder::Copy()
1456 EditView
*pEditView
= rEditAcc
.GetEditView();
1465 bool SmEditViewForwarder::Cut()
1468 EditView
*pEditView
= rEditAcc
.GetEditView();
1477 bool SmEditViewForwarder::Paste()
1480 EditView
*pEditView
= rEditAcc
.GetEditView();
1490 SmEditAccessible::SmEditAccessible( SmEditWindow
*pEditWin
) :
1491 aAccName (SmResId(STR_CMDBOXWINDOW
)),
1495 OSL_ENSURE( pWin
, "SmEditAccessible: window missing" );
1498 SmEditAccessible::~SmEditAccessible()
1502 ::accessibility::AccessibleTextHelper
*SmEditAccessible::GetTextHelper()
1504 return pTextHelper
.get();
1507 void SmEditAccessible::Init()
1509 OSL_ENSURE( pWin
, "SmEditAccessible: window missing" );
1512 EditEngine
*pEditEngine
= pWin
->GetEditEngine();
1513 EditView
*pEditView
= pWin
->GetEditView();
1514 if (pEditEngine
&& pEditView
)
1516 assert(!pTextHelper
);
1517 pTextHelper
.reset(new ::accessibility::AccessibleTextHelper( std::make_unique
<SmEditSource
>( *this ) ));
1518 pTextHelper
->SetEventSource( this );
1523 void SmEditAccessible::ClearWin()
1525 // remove handler before current object gets destroyed
1526 // (avoid handler being called for already dead object)
1527 EditEngine
*pEditEngine
= GetEditEngine();
1529 pEditEngine
->SetNotifyHdl( Link
<EENotify
&,void>() );
1531 pWin
= nullptr; // implicitly results in AccessibleStateType::DEFUNC set
1533 //! make TextHelper implicitly release C++ references to some core objects
1534 pTextHelper
->SetEditSource( ::std::unique_ptr
<SvxEditSource
>() );
1535 //! make TextHelper release references
1536 //! (e.g. the one set by the 'SetEventSource' call)
1537 pTextHelper
->Dispose();
1538 pTextHelper
.reset();
1542 uno::Reference
< XAccessibleContext
> SAL_CALL
SmEditAccessible::getAccessibleContext( )
1547 // XAccessibleComponent
1548 sal_Bool SAL_CALL
SmEditAccessible::containsPoint( const awt::Point
& aPoint
)
1550 //! the arguments coordinates are relative to the current window !
1551 //! Thus the top left-point is (0, 0)
1553 SolarMutexGuard aGuard
;
1555 throw RuntimeException();
1557 Size
aSz( pWin
->GetSizePixel() );
1558 return aPoint
.X
>= 0 && aPoint
.Y
>= 0 &&
1559 aPoint
.X
< aSz
.Width() && aPoint
.Y
< aSz
.Height();
1562 uno::Reference
< XAccessible
> SAL_CALL
SmEditAccessible::getAccessibleAtPoint( const awt::Point
& aPoint
)
1564 SolarMutexGuard aGuard
;
1566 throw RuntimeException();
1567 return pTextHelper
->GetAt( aPoint
);
1570 awt::Rectangle SAL_CALL
SmEditAccessible::getBounds( )
1572 SolarMutexGuard aGuard
;
1574 throw RuntimeException();
1575 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
1576 "mismatch of window parent and accessible parent" );
1577 return lcl_GetBounds( pWin
);
1580 awt::Point SAL_CALL
SmEditAccessible::getLocation( )
1582 SolarMutexGuard aGuard
;
1584 throw RuntimeException();
1585 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
1586 "mismatch of window parent and accessible parent" );
1587 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
1588 return awt::Point( aRect
.X
, aRect
.Y
);
1591 awt::Point SAL_CALL
SmEditAccessible::getLocationOnScreen( )
1593 SolarMutexGuard aGuard
;
1595 throw RuntimeException();
1596 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
1597 "mismatch of window parent and accessible parent" );
1598 return lcl_GetLocationOnScreen( pWin
);
1601 awt::Size SAL_CALL
SmEditAccessible::getSize( )
1603 SolarMutexGuard aGuard
;
1605 throw RuntimeException();
1606 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
1607 "mismatch of window parent and accessible parent" );
1609 Size
aSz( pWin
->GetSizePixel() );
1610 #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
1611 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
1612 Size
aSz2( aRect
.Width
, aRect
.Height
);
1613 assert(aSz
== aSz2
&& "mismatch in width");
1615 return awt::Size( aSz
.Width(), aSz
.Height() );
1618 void SAL_CALL
SmEditAccessible::grabFocus( )
1620 SolarMutexGuard aGuard
;
1622 throw RuntimeException();
1627 sal_Int32 SAL_CALL
SmEditAccessible::getForeground()
1629 SolarMutexGuard aGuard
;
1632 throw RuntimeException();
1633 return static_cast<sal_Int32
>(pWin
->GetTextColor());
1636 sal_Int32 SAL_CALL
SmEditAccessible::getBackground()
1638 SolarMutexGuard aGuard
;
1641 throw RuntimeException();
1642 Wallpaper
aWall( pWin
->GetDisplayBackground() );
1644 if (aWall
.IsBitmap() || aWall
.IsGradient())
1645 nCol
= pWin
->GetSettings().GetStyleSettings().GetWindowColor();
1647 nCol
= aWall
.GetColor();
1648 return static_cast<sal_Int32
>(nCol
);
1651 // XAccessibleContext
1652 sal_Int32 SAL_CALL
SmEditAccessible::getAccessibleChildCount( )
1654 SolarMutexGuard aGuard
;
1657 return pTextHelper
->GetChildCount();
1660 uno::Reference
< XAccessible
> SAL_CALL
SmEditAccessible::getAccessibleChild( sal_Int32 i
)
1662 SolarMutexGuard aGuard
;
1664 throw RuntimeException();
1665 return pTextHelper
->GetChild( i
);
1668 uno::Reference
< XAccessible
> SAL_CALL
SmEditAccessible::getAccessibleParent( )
1670 SolarMutexGuard aGuard
;
1672 throw RuntimeException();
1674 vcl::Window
*pAccParent
= pWin
->GetAccessibleParentWindow();
1675 OSL_ENSURE( pAccParent
, "accessible parent missing" );
1676 return pAccParent
? pAccParent
->GetAccessible() : Reference
< XAccessible
>();
1679 sal_Int32 SAL_CALL
SmEditAccessible::getAccessibleIndexInParent( )
1681 SolarMutexGuard aGuard
;
1682 sal_Int32 nIdx
= -1;
1683 vcl::Window
*pAccParent
= pWin
? pWin
->GetAccessibleParentWindow() : nullptr;
1686 sal_uInt16 nCnt
= pAccParent
->GetAccessibleChildWindowCount();
1687 for (sal_uInt16 i
= 0; i
< nCnt
&& nIdx
== -1; ++i
)
1688 if (pAccParent
->GetAccessibleChildWindow( i
) == pWin
)
1694 sal_Int16 SAL_CALL
SmEditAccessible::getAccessibleRole( )
1696 return AccessibleRole::TEXT_FRAME
;
1699 OUString SAL_CALL
SmEditAccessible::getAccessibleDescription( )
1701 return OUString(); // empty as agreed with product-management
1704 OUString SAL_CALL
SmEditAccessible::getAccessibleName( )
1706 SolarMutexGuard aGuard
;
1707 // same name as displayed by the window when not docked
1711 uno::Reference
< XAccessibleRelationSet
> SAL_CALL
SmEditAccessible::getAccessibleRelationSet( )
1713 Reference
< XAccessibleRelationSet
> xRelSet
= new utl::AccessibleRelationSetHelper();
1714 return xRelSet
; // empty relation set
1717 uno::Reference
< XAccessibleStateSet
> SAL_CALL
SmEditAccessible::getAccessibleStateSet( )
1719 SolarMutexGuard aGuard
;
1720 ::utl::AccessibleStateSetHelper
*pStateSet
=
1721 new ::utl::AccessibleStateSetHelper
;
1723 Reference
<XAccessibleStateSet
> xStateSet( pStateSet
);
1725 if (!pWin
|| !pTextHelper
)
1726 pStateSet
->AddState( AccessibleStateType::DEFUNC
);
1729 pStateSet
->AddState( AccessibleStateType::MULTI_LINE
);
1730 pStateSet
->AddState( AccessibleStateType::ENABLED
);
1731 pStateSet
->AddState( AccessibleStateType::EDITABLE
);
1732 pStateSet
->AddState( AccessibleStateType::FOCUSABLE
);
1733 if (pWin
->HasFocus())
1734 pStateSet
->AddState( AccessibleStateType::FOCUSED
);
1735 if (pWin
->IsActive())
1736 pStateSet
->AddState( AccessibleStateType::ACTIVE
);
1737 if (pWin
->IsVisible())
1738 pStateSet
->AddState( AccessibleStateType::SHOWING
);
1739 if (pWin
->IsReallyVisible())
1740 pStateSet
->AddState( AccessibleStateType::VISIBLE
);
1741 if (COL_TRANSPARENT
!= pWin
->GetBackground().GetColor())
1742 pStateSet
->AddState( AccessibleStateType::OPAQUE
);
1748 Locale SAL_CALL
SmEditAccessible::getLocale( )
1750 SolarMutexGuard aGuard
;
1751 // should be the document language...
1752 // We use the language of the localized symbol names here.
1753 return Application::GetSettings().GetUILanguageTag().getLocale();
1757 // XAccessibleEventBroadcaster
1758 void SAL_CALL
SmEditAccessible::addAccessibleEventListener( const uno::Reference
< XAccessibleEventListener
>& xListener
)
1760 if (pTextHelper
) // not disposing (about to destroy view shell)
1761 pTextHelper
->AddEventListener( xListener
);
1764 void SAL_CALL
SmEditAccessible::removeAccessibleEventListener( const uno::Reference
< XAccessibleEventListener
>& xListener
)
1766 if (pTextHelper
) // not disposing (about to destroy view shell)
1767 pTextHelper
->RemoveEventListener( xListener
);
1770 OUString SAL_CALL
SmEditAccessible::getImplementationName()
1772 return "SmEditAccessible";
1775 sal_Bool SAL_CALL
SmEditAccessible::supportsService(
1776 const OUString
& rServiceName
)
1778 return cppu::supportsService(this, rServiceName
);
1781 Sequence
< OUString
> SAL_CALL
SmEditAccessible::getSupportedServiceNames()
1784 "css::accessibility::Accessible",
1785 "css::accessibility::AccessibleComponent",
1786 "css::accessibility::AccessibleContext"
1791 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */