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>
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
;
70 static awt::Rectangle
lcl_GetBounds( vcl::Window
*pWin
)
72 // !! see VCLXAccessibleComponent::implGetBounds()
74 //! the coordinates returned are relativ to the parent window !
75 //! Thus the top-left point may be different from (0, 0) !
77 awt::Rectangle aBounds
;
80 Rectangle aRect
= pWin
->GetWindowExtentsRelative( NULL
);
81 aBounds
.X
= aRect
.Left();
82 aBounds
.Y
= aRect
.Top();
83 aBounds
.Width
= aRect
.GetWidth();
84 aBounds
.Height
= aRect
.GetHeight();
85 vcl::Window
* pParent
= pWin
->GetAccessibleParentWindow();
88 Rectangle aParentRect
= pParent
->GetWindowExtentsRelative( NULL
);
89 awt::Point
aParentScreenLoc( aParentRect
.Left(), aParentRect
.Top() );
90 aBounds
.X
-= aParentScreenLoc
.X
;
91 aBounds
.Y
-= aParentScreenLoc
.Y
;
97 static awt::Point
lcl_GetLocationOnScreen( vcl::Window
*pWin
)
99 // !! see VCLXAccessibleComponent::getLocationOnScreen()
104 Rectangle aRect
= pWin
->GetWindowExtentsRelative( NULL
);
105 aPos
.X
= aRect
.Left();
106 aPos
.Y
= aRect
.Top();
113 SmGraphicAccessible::SmGraphicAccessible( SmGraphicWindow
*pGraphicWin
) :
114 aAccName (SM_RESSTR(RID_DOCUMENTSTR
)),
118 OSL_ENSURE( pWin
, "SmGraphicAccessible: window missing" );
121 SmGraphicAccessible::~SmGraphicAccessible()
126 SmDocShell
* SmGraphicAccessible::GetDoc_Impl()
128 SmViewShell
*pView
= pWin
? pWin
->GetView() : 0;
129 return pView
? pView
->GetDoc() : 0;
132 OUString
SmGraphicAccessible::GetAccessibleText_Impl()
135 SmDocShell
*pDoc
= GetDoc_Impl();
137 aTxt
= pDoc
->GetAccessibleText();
141 void SmGraphicAccessible::ClearWin()
143 pWin
= 0; // implicitly results in AccessibleStateType::DEFUNC set
147 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId
, *this );
152 void SmGraphicAccessible::LaunchEvent(
153 const sal_Int16 nAccesibleEventId
,
154 const uno::Any
&rOldVal
,
155 const uno::Any
&rNewVal
)
157 AccessibleEventObject aEvt
;
158 aEvt
.Source
= (XAccessible
*) this;
159 aEvt
.EventId
= nAccesibleEventId
;
160 aEvt
.OldValue
= rOldVal
;
161 aEvt
.NewValue
= rNewVal
;
163 // pass event on to event-listener's
165 comphelper::AccessibleEventNotifier::addEvent( nClientId
, aEvt
);
168 uno::Reference
< XAccessibleContext
> SAL_CALL
SmGraphicAccessible::getAccessibleContext()
169 throw (RuntimeException
, std::exception
)
171 SolarMutexGuard aGuard
;
175 sal_Bool SAL_CALL
SmGraphicAccessible::containsPoint( const awt::Point
& aPoint
)
176 throw (RuntimeException
, std::exception
)
178 //! the arguments coordinates are relativ to the current window !
179 //! Thus the top-left point is (0, 0)
181 SolarMutexGuard aGuard
;
183 throw RuntimeException();
185 Size
aSz( pWin
->GetSizePixel() );
186 return aPoint
.X
>= 0 && aPoint
.Y
>= 0 &&
187 aPoint
.X
< aSz
.Width() && aPoint
.Y
< aSz
.Height();
190 uno::Reference
< XAccessible
> SAL_CALL
SmGraphicAccessible::getAccessibleAtPoint(
191 const awt::Point
& aPoint
)
192 throw (RuntimeException
, std::exception
)
194 SolarMutexGuard aGuard
;
195 XAccessible
*pRes
= 0;
196 if (containsPoint( aPoint
))
201 awt::Rectangle SAL_CALL
SmGraphicAccessible::getBounds()
202 throw (RuntimeException
, std::exception
)
204 SolarMutexGuard aGuard
;
206 throw RuntimeException();
207 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
208 "mismatch of window parent and accessible parent" );
209 return lcl_GetBounds( pWin
);
212 awt::Point SAL_CALL
SmGraphicAccessible::getLocation()
213 throw (RuntimeException
, std::exception
)
215 SolarMutexGuard aGuard
;
217 throw RuntimeException();
218 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
219 "mismatch of window parent and accessible parent" );
220 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
221 return awt::Point( aRect
.X
, aRect
.Y
);
224 awt::Point SAL_CALL
SmGraphicAccessible::getLocationOnScreen()
225 throw (RuntimeException
, std::exception
)
227 SolarMutexGuard aGuard
;
229 throw RuntimeException();
230 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
231 "mismatch of window parent and accessible parent" );
232 return lcl_GetLocationOnScreen( pWin
);
235 awt::Size SAL_CALL
SmGraphicAccessible::getSize()
236 throw (RuntimeException
, std::exception
)
238 SolarMutexGuard aGuard
;
240 throw RuntimeException();
241 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
242 "mismatch of window parent and accessible parent" );
244 Size
aSz( pWin
->GetSizePixel() );
245 #if OSL_DEBUG_LEVEL > 1
246 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
247 Size
aSz2( aRect
.Width
, aRect
.Height
);
248 OSL_ENSURE( aSz
== aSz2
, "mismatch in width" );
250 return awt::Size( aSz
.Width(), aSz
.Height() );
253 void SAL_CALL
SmGraphicAccessible::grabFocus()
254 throw (RuntimeException
, std::exception
)
256 SolarMutexGuard aGuard
;
258 throw RuntimeException();
263 sal_Int32 SAL_CALL
SmGraphicAccessible::getForeground()
264 throw (RuntimeException
, std::exception
)
266 SolarMutexGuard aGuard
;
269 throw RuntimeException();
270 return (sal_Int32
) pWin
->GetTextColor().GetColor();
273 sal_Int32 SAL_CALL
SmGraphicAccessible::getBackground()
274 throw (RuntimeException
, std::exception
)
276 SolarMutexGuard aGuard
;
279 throw RuntimeException();
280 Wallpaper
aWall( pWin
->GetDisplayBackground() );
282 if (aWall
.IsBitmap() || aWall
.IsGradient())
283 nCol
= pWin
->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
285 nCol
= aWall
.GetColor().GetColor();
286 return (sal_Int32
) nCol
;
289 sal_Int32 SAL_CALL
SmGraphicAccessible::getAccessibleChildCount()
290 throw (RuntimeException
, std::exception
)
292 SolarMutexGuard aGuard
;
296 Reference
< XAccessible
> SAL_CALL
SmGraphicAccessible::getAccessibleChild(
298 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
300 SolarMutexGuard aGuard
;
301 throw IndexOutOfBoundsException(); // there is no child...
304 Reference
< XAccessible
> SAL_CALL
SmGraphicAccessible::getAccessibleParent()
305 throw (RuntimeException
, std::exception
)
307 SolarMutexGuard aGuard
;
309 throw RuntimeException();
311 vcl::Window
*pAccParent
= pWin
->GetAccessibleParentWindow();
312 OSL_ENSURE( pAccParent
, "accessible parent missing" );
313 return pAccParent
? pAccParent
->GetAccessible() : Reference
< XAccessible
>();
316 sal_Int32 SAL_CALL
SmGraphicAccessible::getAccessibleIndexInParent()
317 throw (RuntimeException
, std::exception
)
319 SolarMutexGuard aGuard
;
321 vcl::Window
*pAccParent
= pWin
? pWin
->GetAccessibleParentWindow() : 0;
324 sal_uInt16 nCnt
= pAccParent
->GetAccessibleChildWindowCount();
325 for (sal_uInt16 i
= 0; i
< nCnt
&& nIdx
== -1; ++i
)
326 if (pAccParent
->GetAccessibleChildWindow( i
) == pWin
)
332 sal_Int16 SAL_CALL
SmGraphicAccessible::getAccessibleRole()
333 throw (RuntimeException
, std::exception
)
335 SolarMutexGuard aGuard
;
336 return AccessibleRole::DOCUMENT
;
339 OUString SAL_CALL
SmGraphicAccessible::getAccessibleDescription()
340 throw (RuntimeException
, std::exception
)
342 SolarMutexGuard aGuard
;
343 SmDocShell
*pDoc
= GetDoc_Impl();
344 return pDoc
? OUString(pDoc
->GetText()) : OUString();
347 OUString SAL_CALL
SmGraphicAccessible::getAccessibleName()
348 throw (RuntimeException
, std::exception
)
350 SolarMutexGuard aGuard
;
354 Reference
< XAccessibleRelationSet
> SAL_CALL
SmGraphicAccessible::getAccessibleRelationSet()
355 throw (RuntimeException
, std::exception
)
357 SolarMutexGuard aGuard
;
358 Reference
< XAccessibleRelationSet
> xRelSet
= new utl::AccessibleRelationSetHelper();
359 return xRelSet
; // empty relation set
362 Reference
< XAccessibleStateSet
> SAL_CALL
SmGraphicAccessible::getAccessibleStateSet()
363 throw (RuntimeException
, std::exception
)
365 SolarMutexGuard aGuard
;
366 ::utl::AccessibleStateSetHelper
*pStateSet
=
367 new ::utl::AccessibleStateSetHelper
;
369 Reference
<XAccessibleStateSet
> xStateSet( pStateSet
);
372 pStateSet
->AddState( AccessibleStateType::DEFUNC
);
375 pStateSet
->AddState( AccessibleStateType::ENABLED
);
376 pStateSet
->AddState( AccessibleStateType::FOCUSABLE
);
377 if (pWin
->HasFocus())
378 pStateSet
->AddState( AccessibleStateType::FOCUSED
);
379 if (pWin
->IsActive())
380 pStateSet
->AddState( AccessibleStateType::ACTIVE
);
381 if (pWin
->IsVisible())
382 pStateSet
->AddState( AccessibleStateType::SHOWING
);
383 if (pWin
->IsReallyVisible())
384 pStateSet
->AddState( AccessibleStateType::VISIBLE
);
385 if (COL_TRANSPARENT
!= pWin
->GetBackground().GetColor().GetColor())
386 pStateSet
->AddState( AccessibleStateType::OPAQUE
);
392 Locale SAL_CALL
SmGraphicAccessible::getLocale()
393 throw (IllegalAccessibleComponentStateException
, RuntimeException
, std::exception
)
395 SolarMutexGuard aGuard
;
396 // should be the document language...
397 // We use the language of the localized symbol names here.
398 return Application::GetSettings().GetUILanguageTag().getLocale();
402 void SAL_CALL
SmGraphicAccessible::addAccessibleEventListener(
403 const Reference
< XAccessibleEventListener
>& xListener
)
404 throw (RuntimeException
, std::exception
)
408 SolarMutexGuard aGuard
;
412 nClientId
= comphelper::AccessibleEventNotifier::registerClient( );
413 comphelper::AccessibleEventNotifier::addEventListener( nClientId
, xListener
);
418 void SAL_CALL
SmGraphicAccessible::removeAccessibleEventListener(
419 const Reference
< XAccessibleEventListener
>& xListener
)
420 throw (RuntimeException
, std::exception
)
424 SolarMutexGuard aGuard
;
425 sal_Int32 nListenerCount
= comphelper::AccessibleEventNotifier::removeEventListener( nClientId
, xListener
);
426 if ( !nListenerCount
)
428 // no listeners anymore
429 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
430 // and at least to us not firing any events anymore, in case somebody calls
431 // NotifyAccessibleEvent, again
432 comphelper::AccessibleEventNotifier::revokeClient( nClientId
);
438 sal_Int32 SAL_CALL
SmGraphicAccessible::getCaretPosition()
439 throw (RuntimeException
, std::exception
)
441 SolarMutexGuard aGuard
;
445 sal_Bool SAL_CALL
SmGraphicAccessible::setCaretPosition( sal_Int32 nIndex
)
446 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
448 SolarMutexGuard aGuard
;
449 OUString
aTxt( GetAccessibleText_Impl() );
450 if (!(nIndex
< aTxt
.getLength()))
451 throw IndexOutOfBoundsException();
455 sal_Unicode SAL_CALL
SmGraphicAccessible::getCharacter( sal_Int32 nIndex
)
456 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
458 SolarMutexGuard aGuard
;
459 OUString
aTxt( GetAccessibleText_Impl() );
460 if (!(nIndex
< aTxt
.getLength()))
461 throw IndexOutOfBoundsException();
465 Sequence
< beans::PropertyValue
> SAL_CALL
SmGraphicAccessible::getCharacterAttributes(
467 const uno::Sequence
< OUString
> & /*rRequestedAttributes*/ )
468 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
470 SolarMutexGuard aGuard
;
471 sal_Int32 nLen
= GetAccessibleText_Impl().getLength();
472 if (!(0 <= nIndex
&& nIndex
< nLen
))
473 throw IndexOutOfBoundsException();
474 return Sequence
< beans::PropertyValue
>();
477 awt::Rectangle SAL_CALL
SmGraphicAccessible::getCharacterBounds( sal_Int32 nIndex
)
478 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
480 SolarMutexGuard aGuard
;
485 throw RuntimeException();
488 // get accessible text
489 SmViewShell
*pView
= pWin
->GetView();
490 SmDocShell
*pDoc
= pView
? pView
->GetDoc() : 0;
492 throw RuntimeException();
493 OUString
aTxt( GetAccessibleText_Impl() );
494 if (!(0 <= nIndex
&& nIndex
<= aTxt
.getLength())) // aTxt.getLength() is valid
495 throw IndexOutOfBoundsException();
497 // find a reasonable rectangle for position aTxt.getLength().
498 bool bWasBehindText
= (nIndex
== aTxt
.getLength());
499 if (bWasBehindText
&& nIndex
)
502 const SmNode
*pTree
= pDoc
->GetFormulaTree();
503 const SmNode
*pNode
= pTree
->FindNodeWithAccessibleIndex( nIndex
);
504 //! pNode may be 0 if the index belongs to a char that was inserted
505 //! only for the accessible text!
508 sal_Int32 nAccIndex
= pNode
->GetAccessibleIndex();
509 OSL_ENSURE( nAccIndex
>= 0, "invalid accessible index" );
510 OSL_ENSURE( nIndex
>= nAccIndex
, "index out of range" );
513 pNode
->GetAccessibleText(aBuf
);
514 OUString aNodeText
= aBuf
.makeStringAndClear();
515 sal_Int32 nNodeIndex
= nIndex
- nAccIndex
;
516 if (0 <= nNodeIndex
&& nNodeIndex
< aNodeText
.getLength())
518 // get appropriate rectangle
519 Point
aOffset(pNode
->GetTopLeft() - pTree
->GetTopLeft());
520 Point
aTLPos (pWin
->GetFormulaDrawPos() + aOffset
);
522 Size
aSize (pNode
->GetSize());
524 long* pXAry
= new long[ aNodeText
.getLength() ];
525 pWin
->SetFont( pNode
->GetFont() );
526 pWin
->GetTextArray( aNodeText
, pXAry
, 0, aNodeText
.getLength() );
527 aTLPos
.X() += nNodeIndex
> 0 ? pXAry
[nNodeIndex
- 1] : 0;
528 aSize
.Width() = nNodeIndex
> 0 ? pXAry
[nNodeIndex
] - pXAry
[nNodeIndex
- 1] : pXAry
[nNodeIndex
];
531 aTLPos
= pWin
->LogicToPixel( aTLPos
);
532 aSize
= pWin
->LogicToPixel( aSize
);
535 aRes
.Width
= aSize
.Width();
536 aRes
.Height
= aSize
.Height();
540 // take rectangle from last character and move it to the right
542 aRes
.X
+= aRes
.Width
;
548 sal_Int32 SAL_CALL
SmGraphicAccessible::getCharacterCount()
549 throw (RuntimeException
, std::exception
)
551 SolarMutexGuard aGuard
;
552 return GetAccessibleText_Impl().getLength();
555 sal_Int32 SAL_CALL
SmGraphicAccessible::getIndexAtPoint( const awt::Point
& aPoint
)
556 throw (RuntimeException
, std::exception
)
558 SolarMutexGuard aGuard
;
563 const SmNode
*pTree
= pWin
->GetView()->GetDoc()->GetFormulaTree();
564 // can be NULL! e.g. if one clicks within the window already during loading of the
565 // document (before the parser even started)
569 // get position relative to formula draw position
570 Point
aPos( aPoint
.X
, aPoint
.Y
);
571 aPos
= pWin
->PixelToLogic( aPos
);
572 aPos
-= pWin
->GetFormulaDrawPos();
574 // if it was inside the formula then get the appropriate node
575 const SmNode
*pNode
= 0;
576 if (pTree
->OrientedDist(aPos
) <= 0)
577 pNode
= pTree
->FindRectClosestTo(aPos
);
581 // get appropriate rectangle
582 Point
aOffset( pNode
->GetTopLeft() - pTree
->GetTopLeft() );
583 Point
aTLPos ( aOffset
);
585 Size
aSize( pNode
->GetSize() );
587 Rectangle
aRect( aTLPos
, aSize
);
588 if (aRect
.IsInside( aPos
))
590 OSL_ENSURE( pNode
->IsVisible(), "node is not a leaf" );
592 pNode
->GetAccessibleText(aBuf
);
593 OUString aTxt
= aBuf
.makeStringAndClear();
594 OSL_ENSURE( !aTxt
.isEmpty(), "no accessible text available" );
596 long nNodeX
= pNode
->GetLeft();
598 long* pXAry
= new long[ aTxt
.getLength() ];
599 pWin
->SetFont( pNode
->GetFont() );
600 pWin
->GetTextArray( aTxt
, pXAry
, 0, aTxt
.getLength() );
601 for (sal_Int32 i
= 0; i
< aTxt
.getLength() && nRes
== -1; ++i
)
603 if (pXAry
[i
] + nNodeX
> aPos
.X())
607 OSL_ENSURE( nRes
>= 0 && nRes
< aTxt
.getLength(), "index out of range" );
608 OSL_ENSURE( pNode
->GetAccessibleIndex() >= 0,
609 "invalid accessible index" );
611 nRes
= pNode
->GetAccessibleIndex() + nRes
;
618 OUString SAL_CALL
SmGraphicAccessible::getSelectedText()
619 throw (RuntimeException
, std::exception
)
621 SolarMutexGuard aGuard
;
625 sal_Int32 SAL_CALL
SmGraphicAccessible::getSelectionStart()
626 throw (RuntimeException
, std::exception
)
628 SolarMutexGuard aGuard
;
632 sal_Int32 SAL_CALL
SmGraphicAccessible::getSelectionEnd()
633 throw (RuntimeException
, std::exception
)
635 SolarMutexGuard aGuard
;
639 sal_Bool SAL_CALL
SmGraphicAccessible::setSelection(
640 sal_Int32 nStartIndex
,
641 sal_Int32 nEndIndex
)
642 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
644 SolarMutexGuard aGuard
;
645 sal_Int32 nLen
= GetAccessibleText_Impl().getLength();
646 if (!(0 <= nStartIndex
&& nStartIndex
< nLen
) ||
647 !(0 <= nEndIndex
&& nEndIndex
< nLen
))
648 throw IndexOutOfBoundsException();
652 OUString SAL_CALL
SmGraphicAccessible::getText()
653 throw (RuntimeException
, std::exception
)
655 SolarMutexGuard aGuard
;
656 return GetAccessibleText_Impl();
659 OUString SAL_CALL
SmGraphicAccessible::getTextRange(
660 sal_Int32 nStartIndex
,
661 sal_Int32 nEndIndex
)
662 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
664 //!! nEndIndex may be the string length per definition of the interface !!
665 //!! text should be copied exclusive that end index though. And arguments
666 //!! may be switched.
668 SolarMutexGuard aGuard
;
669 OUString
aTxt( GetAccessibleText_Impl() );
670 sal_Int32 nStart
= std::min(nStartIndex
, nEndIndex
);
671 sal_Int32 nEnd
= std::max(nStartIndex
, nEndIndex
);
672 if (!(nStart
<= aTxt
.getLength()) ||
673 !(nEnd
<= aTxt
.getLength()))
674 throw IndexOutOfBoundsException();
675 return aTxt
.copy( nStart
, nEnd
- nStart
);
678 ::com::sun::star::accessibility::TextSegment SAL_CALL
SmGraphicAccessible::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (::com::sun::star::lang::IndexOutOfBoundsException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
, std::exception
)
680 SolarMutexGuard aGuard
;
681 OUString
aTxt( GetAccessibleText_Impl() );
682 //!! nIndex is allowed to be the string length
683 if (!(nIndex
<= aTxt
.getLength()))
684 throw IndexOutOfBoundsException();
686 ::com::sun::star::accessibility::TextSegment aResult
;
687 aResult
.SegmentStart
= -1;
688 aResult
.SegmentEnd
= -1;
689 if ( (AccessibleTextType::CHARACTER
== aTextType
) && (nIndex
< aTxt
.getLength()) )
691 aResult
.SegmentText
= aTxt
.copy(nIndex
, 1);
692 aResult
.SegmentStart
= nIndex
;
693 aResult
.SegmentEnd
= nIndex
+1;
698 ::com::sun::star::accessibility::TextSegment SAL_CALL
SmGraphicAccessible::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (::com::sun::star::lang::IndexOutOfBoundsException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
, std::exception
)
700 SolarMutexGuard aGuard
;
701 OUString
aTxt( GetAccessibleText_Impl() );
702 //!! nIndex is allowed to be the string length
703 if (!(nIndex
<= aTxt
.getLength()))
704 throw IndexOutOfBoundsException();
706 ::com::sun::star::accessibility::TextSegment aResult
;
707 aResult
.SegmentStart
= -1;
708 aResult
.SegmentEnd
= -1;
710 if ( (AccessibleTextType::CHARACTER
== aTextType
) && nIndex
)
712 aResult
.SegmentText
= aTxt
.copy(nIndex
-1, 1);
713 aResult
.SegmentStart
= nIndex
-1;
714 aResult
.SegmentEnd
= nIndex
;
719 ::com::sun::star::accessibility::TextSegment SAL_CALL
SmGraphicAccessible::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (::com::sun::star::lang::IndexOutOfBoundsException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
, std::exception
)
721 SolarMutexGuard aGuard
;
722 OUString
aTxt( GetAccessibleText_Impl() );
723 //!! nIndex is allowed to be the string length
724 if (!(nIndex
<= aTxt
.getLength()))
725 throw IndexOutOfBoundsException();
727 ::com::sun::star::accessibility::TextSegment aResult
;
728 aResult
.SegmentStart
= -1;
729 aResult
.SegmentEnd
= -1;
731 nIndex
++; // text *behind*
732 if ( (AccessibleTextType::CHARACTER
== aTextType
) && (nIndex
< aTxt
.getLength()) )
734 aResult
.SegmentText
= aTxt
.copy(nIndex
, 1);
735 aResult
.SegmentStart
= nIndex
;
736 aResult
.SegmentEnd
= nIndex
+1;
741 sal_Bool SAL_CALL
SmGraphicAccessible::copyText(
742 sal_Int32 nStartIndex
,
743 sal_Int32 nEndIndex
)
744 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
746 SolarMutexGuard aGuard
;
747 bool bReturn
= false;
750 throw RuntimeException();
753 Reference
< datatransfer::clipboard::XClipboard
> xClipboard
= pWin
->GetClipboard();
754 if ( xClipboard
.is() )
756 OUString
sText( getTextRange(nStartIndex
, nEndIndex
) );
758 vcl::unohelper::TextDataObject
* pDataObj
= new vcl::unohelper::TextDataObject( sText
);
759 SolarMutexReleaser aReleaser
;
760 xClipboard
->setContents( pDataObj
, NULL
);
762 Reference
< datatransfer::clipboard::XFlushableClipboard
> xFlushableClipboard( xClipboard
, uno::UNO_QUERY
);
763 if( xFlushableClipboard
.is() )
764 xFlushableClipboard
->flushClipboard();
773 OUString SAL_CALL
SmGraphicAccessible::getImplementationName()
774 throw (RuntimeException
, std::exception
)
776 return OUString("SmGraphicAccessible");
779 sal_Bool SAL_CALL
SmGraphicAccessible::supportsService(
780 const OUString
& rServiceName
)
781 throw (RuntimeException
, std::exception
)
783 return cppu::supportsService(this, rServiceName
);
786 Sequence
< OUString
> SAL_CALL
SmGraphicAccessible::getSupportedServiceNames()
787 throw (RuntimeException
, std::exception
)
789 return Sequence
< OUString
>{
790 "com::sun::star::accessibility::Accessible",
791 "com::sun::star::accessibility::AccessibleComponent",
792 "com::sun::star::accessibility::AccessibleContext",
793 "com::sun::star::accessibility::AccessibleText"
801 SmEditSource::SmEditSource( SmEditWindow
* /*pWin*/, SmEditAccessible
&rAcc
) :
803 aTextFwd (rAcc
, *this),
809 SmEditSource::SmEditSource( const SmEditSource
&rSrc
) :
811 aViewFwd (rSrc
.rEditAcc
),
812 aTextFwd (rSrc
.rEditAcc
, *this),
813 aEditViewFwd(rSrc
.rEditAcc
),
814 rEditAcc (rSrc
.rEditAcc
)
818 SmEditSource::~SmEditSource()
822 SvxEditSource
* SmEditSource::Clone() const
824 return new SmEditSource( *this );
827 SvxTextForwarder
* SmEditSource::GetTextForwarder()
832 SvxViewForwarder
* SmEditSource::GetViewForwarder()
837 SvxEditViewForwarder
* SmEditSource::GetEditViewForwarder( bool /*bCreate*/ )
839 return &aEditViewFwd
;
842 void SmEditSource::UpdateData()
844 // would possibly only by needed if the XText interface is implemented
845 // and its text needs to be updated.
848 SfxBroadcaster
& SmEditSource::GetBroadcaster() const
850 return const_cast<SmEditSource
*>(this)->aBroadCaster
;
853 SmViewForwarder::SmViewForwarder( SmEditAccessible
&rAcc
) :
858 SmViewForwarder::~SmViewForwarder()
862 bool SmViewForwarder::IsValid() const
864 return rEditAcc
.GetEditView() != 0;
867 Rectangle
SmViewForwarder::GetVisArea() const
869 EditView
*pEditView
= rEditAcc
.GetEditView();
870 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : 0;
872 if( pOutDev
&& pEditView
)
874 Rectangle aVisArea
= pEditView
->GetVisArea();
876 // figure out map mode from edit engine
877 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
881 MapMode
aMapMode(pOutDev
->GetMapMode());
882 aVisArea
= OutputDevice::LogicToLogic( aVisArea
,
883 pEditEngine
->GetRefMapMode(),
884 aMapMode
.GetMapUnit() );
885 aMapMode
.SetOrigin(Point());
886 return pOutDev
->LogicToPixel( aVisArea
, aMapMode
);
893 Point
SmViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
895 EditView
*pEditView
= rEditAcc
.GetEditView();
896 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : 0;
900 MapMode
aMapMode(pOutDev
->GetMapMode());
901 Point
aPoint( OutputDevice::LogicToLogic( rPoint
, rMapMode
,
902 aMapMode
.GetMapUnit() ) );
903 aMapMode
.SetOrigin(Point());
904 return pOutDev
->LogicToPixel( aPoint
, aMapMode
);
910 Point
SmViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
912 EditView
*pEditView
= rEditAcc
.GetEditView();
913 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : 0;
917 MapMode
aMapMode(pOutDev
->GetMapMode());
918 aMapMode
.SetOrigin(Point());
919 Point
aPoint( pOutDev
->PixelToLogic( rPoint
, aMapMode
) );
920 return OutputDevice::LogicToLogic( aPoint
,
921 aMapMode
.GetMapUnit(),
931 SmTextForwarder::SmTextForwarder( SmEditAccessible
& rAcc
, SmEditSource
& rSource
) :
933 rEditSource (rSource
)
935 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
937 pEditEngine
->SetNotifyHdl( LINK(this, SmTextForwarder
, NotifyHdl
) );
940 SmTextForwarder::~SmTextForwarder()
942 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
944 pEditEngine
->SetNotifyHdl( Link
<>() );
947 IMPL_LINK(SmTextForwarder
, NotifyHdl
, EENotify
*, aNotify
)
951 ::std::unique_ptr
< SfxHint
> aHint
= SvxEditSourceHelper::EENotification2Hint( aNotify
);
953 rEditSource
.GetBroadcaster().Broadcast( *aHint
.get() );
959 sal_Int32
SmTextForwarder::GetParagraphCount() const
961 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
962 return pEditEngine
? pEditEngine
->GetParagraphCount() : 0;
965 sal_Int32
SmTextForwarder::GetTextLen( sal_Int32 nParagraph
) const
967 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
968 return pEditEngine
? pEditEngine
->GetTextLen( nParagraph
) : 0;
971 OUString
SmTextForwarder::GetText( const ESelection
& rSel
) const
973 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
976 aRet
= pEditEngine
->GetText( rSel
, LINEEND_LF
);
977 return convertLineEnd(aRet
, GetSystemLineEnd());
980 SfxItemSet
SmTextForwarder::GetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
) const
982 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
983 OSL_ENSURE( pEditEngine
, "EditEngine missing" );
984 if( rSel
.nStartPara
== rSel
.nEndPara
)
986 GetAttribsFlags nFlags
= GetAttribsFlags::NONE
;
987 switch( nOnlyHardAttrib
)
989 case EditEngineAttribs_All
:
990 nFlags
= GetAttribsFlags::ALL
;
992 case EditEngineAttribs_HardAndPara
:
993 nFlags
= GetAttribsFlags::PARAATTRIBS
|GetAttribsFlags::CHARATTRIBS
;
995 case EditEngineAttribs_OnlyHard
:
996 nFlags
= GetAttribsFlags::CHARATTRIBS
;
999 SAL_WARN("starmath", "unknown flags for SmTextForwarder::GetAttribs");
1002 return pEditEngine
->GetAttribs( rSel
.nStartPara
, rSel
.nStartPos
, rSel
.nEndPos
, nFlags
);
1006 return pEditEngine
->GetAttribs( rSel
, nOnlyHardAttrib
);
1010 SfxItemSet
SmTextForwarder::GetParaAttribs( sal_Int32 nPara
) const
1012 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1013 OSL_ENSURE( pEditEngine
, "EditEngine missing" );
1015 SfxItemSet
aSet( pEditEngine
->GetParaAttribs( nPara
) );
1017 sal_uInt16 nWhich
= EE_PARA_START
;
1018 while( nWhich
<= EE_PARA_END
)
1020 if( aSet
.GetItemState( nWhich
, true ) != SfxItemState::SET
)
1022 if( pEditEngine
->HasParaAttrib( nPara
, nWhich
) )
1023 aSet
.Put( pEditEngine
->GetParaAttrib( nPara
, nWhich
) );
1031 void SmTextForwarder::SetParaAttribs( sal_Int32 nPara
, const SfxItemSet
& rSet
)
1033 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1035 pEditEngine
->SetParaAttribs( nPara
, rSet
);
1038 SfxItemPool
* SmTextForwarder::GetPool() const
1040 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1041 return pEditEngine
? pEditEngine
->GetEmptyItemSet().GetPool() : 0;
1044 void SmTextForwarder::RemoveAttribs( const ESelection
& rSelection
, bool bRemoveParaAttribs
, sal_uInt16 nWhich
)
1046 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1048 pEditEngine
->RemoveAttribs( rSelection
, bRemoveParaAttribs
, nWhich
);
1051 void SmTextForwarder::GetPortions( sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
1053 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1055 pEditEngine
->GetPortions( nPara
, rList
);
1058 void SmTextForwarder::QuickInsertText( const OUString
& rText
, const ESelection
& rSel
)
1060 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1062 pEditEngine
->QuickInsertText( rText
, rSel
);
1065 void SmTextForwarder::QuickInsertLineBreak( const ESelection
& rSel
)
1067 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1069 pEditEngine
->QuickInsertLineBreak( rSel
);
1072 void SmTextForwarder::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
1074 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1076 pEditEngine
->QuickInsertField( rFld
, rSel
);
1079 void SmTextForwarder::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
1081 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1083 pEditEngine
->QuickSetAttribs( rSet
, rSel
);
1086 bool SmTextForwarder::IsValid() const
1088 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1089 // cannot reliably query EditEngine state
1090 // while in the middle of an update
1091 return pEditEngine
&& pEditEngine
->GetUpdateMode();
1094 OUString
SmTextForwarder::CalcFieldValue( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
, Color
*& rpTxtColor
, Color
*& rpFldColor
)
1096 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1097 return pEditEngine
? pEditEngine
->CalcFieldValue(rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
) : OUString();
1100 void SmTextForwarder::FieldClicked(const SvxFieldItem
&, sal_Int32
, sal_Int32
)
1104 static SfxItemState
GetSvxEditEngineItemState( EditEngine
& rEditEngine
, const ESelection
& rSel
, sal_uInt16 nWhich
)
1106 std::vector
<EECharAttrib
> aAttribs
;
1108 const SfxPoolItem
* pLastItem
= NULL
;
1110 SfxItemState eState
= SfxItemState::DEFAULT
;
1112 // check all paragraphs inside the selection
1113 for( sal_Int32 nPara
= rSel
.nStartPara
; nPara
<= rSel
.nEndPara
; nPara
++ )
1115 SfxItemState eParaState
= SfxItemState::DEFAULT
;
1117 // calculate start and endpos for this paragraph
1119 if( rSel
.nStartPara
== nPara
)
1120 nPos
= rSel
.nStartPos
;
1122 sal_Int32 nEndPos
= rSel
.nEndPos
;
1123 if( rSel
.nEndPara
!= nPara
)
1124 nEndPos
= rEditEngine
.GetTextLen( nPara
);
1127 // get list of char attribs
1128 rEditEngine
.GetCharAttribs( nPara
, aAttribs
);
1130 bool bEmpty
= true; // we found no item inside the selection of this paragraph
1131 bool bGaps
= false; // we found items but theire gaps between them
1132 sal_Int32 nLastEnd
= nPos
;
1134 const SfxPoolItem
* pParaItem
= NULL
;
1136 for(std::vector
<EECharAttrib
>::const_iterator i
= aAttribs
.begin(); i
< aAttribs
.end(); ++i
)
1138 OSL_ENSURE( i
->pAttr
, "GetCharAttribs gives corrupt data" );
1140 const bool bEmptyPortion
= (i
->nStart
== i
->nEnd
);
1141 if( (!bEmptyPortion
&& (i
->nStart
>= nEndPos
)) || (bEmptyPortion
&& (i
->nStart
> nEndPos
)) )
1142 break; // break if we are already behind our selection
1144 if( (!bEmptyPortion
&& (i
->nEnd
<= nPos
)) || (bEmptyPortion
&& (i
->nEnd
< nPos
)) )
1145 continue; // or if the attribute ends before our selection
1147 if( i
->pAttr
->Which() != nWhich
)
1148 continue; // skip if is not the searched item
1150 // if we already found an item
1153 // ... and its different to this one than the state is dont care
1154 if( *pParaItem
!= *(i
->pAttr
) )
1155 return SfxItemState::DONTCARE
;
1159 pParaItem
= i
->pAttr
;
1165 if( !bGaps
&& i
->nStart
> nLastEnd
)
1171 if( !bEmpty
&& !bGaps
&& nLastEnd
< ( nEndPos
- 1 ) )
1174 eParaState
= SfxItemState::DEFAULT
;
1176 eParaState
= SfxItemState::DONTCARE
;
1178 eParaState
= SfxItemState::SET
;
1180 // if we already found an item check if we found the same
1183 if( (pParaItem
== NULL
) || (*pLastItem
!= *pParaItem
) )
1184 return SfxItemState::DONTCARE
;
1188 pLastItem
= pParaItem
;
1189 eState
= eParaState
;
1196 SfxItemState
SmTextForwarder::GetItemState( const ESelection
& rSel
, sal_uInt16 nWhich
) const
1198 SfxItemState nState
= SfxItemState::DISABLED
;
1199 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1201 nState
= GetSvxEditEngineItemState( *pEditEngine
, rSel
, nWhich
);
1205 SfxItemState
SmTextForwarder::GetItemState( sal_Int32 nPara
, sal_uInt16 nWhich
) const
1207 SfxItemState nState
= SfxItemState::DISABLED
;
1208 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1211 const SfxItemSet
& rSet
= pEditEngine
->GetParaAttribs( nPara
);
1212 nState
= rSet
.GetItemState( nWhich
);
1217 LanguageType
SmTextForwarder::GetLanguage( sal_Int32 nPara
, sal_Int32 nIndex
) const
1219 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1220 return pEditEngine
? pEditEngine
->GetLanguage(nPara
, nIndex
) : LANGUAGE_NONE
;
1223 sal_Int32
SmTextForwarder::GetFieldCount( sal_Int32 nPara
) const
1225 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1226 return pEditEngine
? pEditEngine
->GetFieldCount(nPara
) : 0;
1229 EFieldInfo
SmTextForwarder::GetFieldInfo( sal_Int32 nPara
, sal_uInt16 nField
) const
1231 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1232 return pEditEngine
? pEditEngine
->GetFieldInfo( nPara
, nField
) : EFieldInfo();
1235 EBulletInfo
SmTextForwarder::GetBulletInfo( sal_Int32
/*nPara*/ ) const
1237 return EBulletInfo();
1240 Rectangle
SmTextForwarder::GetCharBounds( sal_Int32 nPara
, sal_Int32 nIndex
) const
1242 Rectangle
aRect(0,0,0,0);
1243 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1247 // Handle virtual position one-past-the end of the string
1248 if( nIndex
>= pEditEngine
->GetTextLen(nPara
) )
1251 aRect
= pEditEngine
->GetCharacterBounds( EPosition(nPara
, nIndex
-1) );
1253 aRect
.Move( aRect
.Right() - aRect
.Left(), 0 );
1254 aRect
.SetSize( Size(1, pEditEngine
->GetTextHeight()) );
1258 aRect
= pEditEngine
->GetCharacterBounds( EPosition(nPara
, nIndex
) );
1264 Rectangle
SmTextForwarder::GetParaBounds( sal_Int32 nPara
) const
1266 Rectangle
aRect(0,0,0,0);
1267 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1271 const Point aPnt
= pEditEngine
->GetDocPosTopLeft( nPara
);
1272 const sal_uLong nWidth
= pEditEngine
->CalcTextWidth();
1273 const sal_uLong nHeight
= pEditEngine
->GetTextHeight( nPara
);
1274 aRect
= Rectangle( aPnt
.X(), aPnt
.Y(), aPnt
.X() + nWidth
, aPnt
.Y() + nHeight
);
1280 MapMode
SmTextForwarder::GetMapMode() const
1282 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1283 return pEditEngine
? pEditEngine
->GetRefMapMode() : MapMode( MAP_100TH_MM
);
1286 OutputDevice
* SmTextForwarder::GetRefDevice() const
1288 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1289 return pEditEngine
? pEditEngine
->GetRefDevice() : 0;
1292 bool SmTextForwarder::GetIndexAtPoint( const Point
& rPos
, sal_Int32
& nPara
, sal_Int32
& nIndex
) const
1295 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1298 EPosition aDocPos
= pEditEngine
->FindDocPosition( rPos
);
1299 nPara
= aDocPos
.nPara
;
1300 nIndex
= aDocPos
.nIndex
;
1306 bool SmTextForwarder::GetWordIndices( sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
, sal_Int32
& nEnd
) const
1309 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1312 ESelection aRes
= pEditEngine
->GetWord( ESelection(nPara
, nIndex
, nPara
, nIndex
), com::sun::star::i18n::WordType::DICTIONARY_WORD
);
1314 if( aRes
.nStartPara
== nPara
&&
1315 aRes
.nStartPara
== aRes
.nEndPara
)
1317 nStart
= aRes
.nStartPos
;
1318 nEnd
= aRes
.nEndPos
;
1327 bool SmTextForwarder::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
) const
1329 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1330 return pEditEngine
&&
1331 SvxEditSourceHelper::GetAttributeRun( nStartIndex
, nEndIndex
, *pEditEngine
, nPara
, nIndex
, bInCell
);
1334 sal_Int32
SmTextForwarder::GetLineCount( sal_Int32 nPara
) const
1336 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1337 return pEditEngine
? pEditEngine
->GetLineCount(nPara
) : 0;
1340 sal_Int32
SmTextForwarder::GetLineLen( sal_Int32 nPara
, sal_Int32 nLine
) const
1342 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1343 return pEditEngine
? pEditEngine
->GetLineLen(nPara
, nLine
) : 0;
1346 void SmTextForwarder::GetLineBoundaries( /*out*/sal_Int32
&rStart
, /*out*/sal_Int32
&rEnd
, sal_Int32 nPara
, sal_Int32 nLine
) const
1348 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1350 pEditEngine
->GetLineBoundaries(rStart
, rEnd
, nPara
, nLine
);
1355 sal_Int32
SmTextForwarder::GetLineNumberAtIndex( sal_Int32 nPara
, sal_Int32 nIndex
) const
1357 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1358 return pEditEngine
? pEditEngine
->GetLineNumberAtIndex(nPara
, nIndex
) : 0;
1361 bool SmTextForwarder::QuickFormatDoc( bool /*bFull*/ )
1364 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1367 pEditEngine
->QuickFormatDoc();
1373 sal_Int16
SmTextForwarder::GetDepth( sal_Int32
/*nPara*/ ) const
1375 // math has no outliner...
1379 bool SmTextForwarder::SetDepth( sal_Int32
/*nPara*/, sal_Int16 nNewDepth
)
1381 // math has no outliner...
1382 return -1 == nNewDepth
; // is it the value from 'GetDepth' ?
1385 bool SmTextForwarder::Delete( const ESelection
& rSelection
)
1388 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1391 pEditEngine
->QuickDelete( rSelection
);
1392 pEditEngine
->QuickFormatDoc();
1398 bool SmTextForwarder::InsertText( const OUString
& rStr
, const ESelection
& rSelection
)
1401 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1404 pEditEngine
->QuickInsertText( rStr
, rSelection
);
1405 pEditEngine
->QuickFormatDoc();
1411 const SfxItemSet
* SmTextForwarder::GetEmptyItemSetPtr()
1413 const SfxItemSet
*pItemSet
= 0;
1414 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1417 pItemSet
= &pEditEngine
->GetEmptyItemSet();
1422 void SmTextForwarder::AppendParagraph()
1424 // append an empty paragraph
1425 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1428 sal_Int32 nParaCount
= pEditEngine
->GetParagraphCount();
1429 pEditEngine
->InsertParagraph( nParaCount
, OUString() );
1433 sal_Int32
SmTextForwarder::AppendTextPortion( sal_Int32 nPara
, const OUString
&rText
, const SfxItemSet
&rSet
)
1435 sal_uInt16 nRes
= 0;
1436 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1437 if (pEditEngine
&& nPara
< pEditEngine
->GetParagraphCount())
1440 ESelection
aSel( nPara
, pEditEngine
->GetTextLen( nPara
) );
1441 pEditEngine
->QuickInsertText( rText
, aSel
);
1443 // set attributes for new appended text
1444 nRes
= aSel
.nEndPos
= pEditEngine
->GetTextLen( nPara
);
1445 pEditEngine
->QuickSetAttribs( rSet
, aSel
);
1450 void SmTextForwarder::CopyText(const SvxTextForwarder
& rSource
)
1453 const SmTextForwarder
* pSourceForwarder
= dynamic_cast< const SmTextForwarder
* >( &rSource
);
1454 if( !pSourceForwarder
)
1456 EditEngine
* pSourceEditEngine
= pSourceForwarder
->rEditAcc
.GetEditEngine();
1457 EditEngine
*pEditEngine
= rEditAcc
.GetEditEngine();
1458 if (pEditEngine
&& pSourceEditEngine
)
1460 EditTextObject
* pNewTextObject
= pSourceEditEngine
->CreateTextObject();
1461 pEditEngine
->SetText( *pNewTextObject
);
1462 delete pNewTextObject
;
1468 SmEditViewForwarder::SmEditViewForwarder( SmEditAccessible
& rAcc
) :
1473 SmEditViewForwarder::~SmEditViewForwarder()
1477 bool SmEditViewForwarder::IsValid() const
1479 return rEditAcc
.GetEditView() != 0;
1482 Rectangle
SmEditViewForwarder::GetVisArea() const
1484 Rectangle
aRect(0,0,0,0);
1486 EditView
*pEditView
= rEditAcc
.GetEditView();
1487 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : 0;
1489 if( pOutDev
&& pEditView
)
1491 Rectangle aVisArea
= pEditView
->GetVisArea();
1493 // figure out map mode from edit engine
1494 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
1498 MapMode
aMapMode(pOutDev
->GetMapMode());
1499 aVisArea
= OutputDevice::LogicToLogic( aVisArea
,
1500 pEditEngine
->GetRefMapMode(),
1501 aMapMode
.GetMapUnit() );
1502 aMapMode
.SetOrigin(Point());
1503 aRect
= pOutDev
->LogicToPixel( aVisArea
, aMapMode
);
1510 Point
SmEditViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
1512 EditView
*pEditView
= rEditAcc
.GetEditView();
1513 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : 0;
1517 MapMode
aMapMode(pOutDev
->GetMapMode());
1518 Point
aPoint( OutputDevice::LogicToLogic( rPoint
, rMapMode
,
1519 aMapMode
.GetMapUnit() ) );
1520 aMapMode
.SetOrigin(Point());
1521 return pOutDev
->LogicToPixel( aPoint
, aMapMode
);
1527 Point
SmEditViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
1529 EditView
*pEditView
= rEditAcc
.GetEditView();
1530 OutputDevice
* pOutDev
= pEditView
? pEditView
->GetWindow() : 0;
1534 MapMode
aMapMode(pOutDev
->GetMapMode());
1535 aMapMode
.SetOrigin(Point());
1536 Point
aPoint( pOutDev
->PixelToLogic( rPoint
, aMapMode
) );
1537 return OutputDevice::LogicToLogic( aPoint
,
1538 aMapMode
.GetMapUnit(),
1545 bool SmEditViewForwarder::GetSelection( ESelection
& rSelection
) const
1548 EditView
*pEditView
= rEditAcc
.GetEditView();
1551 rSelection
= pEditView
->GetSelection();
1557 bool SmEditViewForwarder::SetSelection( const ESelection
& rSelection
)
1560 EditView
*pEditView
= rEditAcc
.GetEditView();
1563 pEditView
->SetSelection( rSelection
);
1569 bool SmEditViewForwarder::Copy()
1572 EditView
*pEditView
= rEditAcc
.GetEditView();
1581 bool SmEditViewForwarder::Cut()
1584 EditView
*pEditView
= rEditAcc
.GetEditView();
1593 bool SmEditViewForwarder::Paste()
1596 EditView
*pEditView
= rEditAcc
.GetEditView();
1607 SmEditAccessible::SmEditAccessible( SmEditWindow
*pEditWin
) :
1608 aAccName (SM_RESSTR(STR_CMDBOXWINDOW
)),
1612 OSL_ENSURE( pWin
, "SmEditAccessible: window missing" );
1615 SmEditAccessible::~SmEditAccessible()
1620 void SmEditAccessible::Init()
1622 OSL_ENSURE( pWin
, "SmEditAccessible: window missing" );
1625 EditEngine
*pEditEngine
= pWin
->GetEditEngine();
1626 EditView
*pEditView
= pWin
->GetEditView();
1627 if (pEditEngine
&& pEditView
)
1629 ::std::unique_ptr
< SvxEditSource
> pEditSource(
1630 new SmEditSource( pWin
, *this ) );
1631 pTextHelper
= new ::accessibility::AccessibleTextHelper( std::move(pEditSource
) );
1632 pTextHelper
->SetEventSource( this );
1637 void SmEditAccessible::ClearWin()
1639 // remove handler before current object gets destroyed
1640 // (avoid handler being called for already dead object)
1641 EditEngine
*pEditEngine
= GetEditEngine();
1643 pEditEngine
->SetNotifyHdl( Link
<>() );
1645 pWin
= 0; // implicitly results in AccessibleStateType::DEFUNC set
1647 //! make TextHelper implicitly release C++ references to some core objects
1648 pTextHelper
->SetEditSource( ::std::unique_ptr
<SvxEditSource
>() );
1649 //! make TextHelper release references
1650 //! (e.g. the one set by the 'SetEventSource' call)
1651 pTextHelper
->Dispose();
1652 delete pTextHelper
; pTextHelper
= 0;
1656 uno::Reference
< XAccessibleContext
> SAL_CALL
SmEditAccessible::getAccessibleContext( )
1657 throw (RuntimeException
, std::exception
)
1659 SolarMutexGuard aGuard
;
1663 // XAccessibleComponent
1664 sal_Bool SAL_CALL
SmEditAccessible::containsPoint( const awt::Point
& aPoint
)
1665 throw (RuntimeException
, std::exception
)
1667 //! the arguments coordinates are relativ to the current window !
1668 //! Thus the top left-point is (0, 0)
1670 SolarMutexGuard aGuard
;
1672 throw RuntimeException();
1674 Size
aSz( pWin
->GetSizePixel() );
1675 return aPoint
.X
>= 0 && aPoint
.Y
>= 0 &&
1676 aPoint
.X
< aSz
.Width() && aPoint
.Y
< aSz
.Height();
1679 uno::Reference
< XAccessible
> SAL_CALL
SmEditAccessible::getAccessibleAtPoint( const awt::Point
& aPoint
)
1680 throw (RuntimeException
, std::exception
)
1682 SolarMutexGuard aGuard
;
1684 throw RuntimeException();
1685 return pTextHelper
->GetAt( aPoint
);
1688 awt::Rectangle SAL_CALL
SmEditAccessible::getBounds( )
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 return lcl_GetBounds( pWin
);
1699 awt::Point SAL_CALL
SmEditAccessible::getLocation( )
1700 throw (RuntimeException
, std::exception
)
1702 SolarMutexGuard aGuard
;
1704 throw RuntimeException();
1705 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
1706 "mismatch of window parent and accessible parent" );
1707 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
1708 return awt::Point( aRect
.X
, aRect
.Y
);
1711 awt::Point SAL_CALL
SmEditAccessible::getLocationOnScreen( )
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" );
1719 return lcl_GetLocationOnScreen( pWin
);
1722 awt::Size SAL_CALL
SmEditAccessible::getSize( )
1723 throw (RuntimeException
, std::exception
)
1725 SolarMutexGuard aGuard
;
1727 throw RuntimeException();
1728 OSL_ENSURE(pWin
->GetParent()->GetAccessible() == getAccessibleParent(),
1729 "mismatch of window parent and accessible parent" );
1731 Size
aSz( pWin
->GetSizePixel() );
1732 #if OSL_DEBUG_LEVEL > 1
1733 awt::Rectangle
aRect( lcl_GetBounds( pWin
) );
1734 Size
aSz2( aRect
.Width
, aRect
.Height
);
1735 OSL_ENSURE( aSz
== aSz2
, "mismatch in width" );
1737 return awt::Size( aSz
.Width(), aSz
.Height() );
1740 void SAL_CALL
SmEditAccessible::grabFocus( )
1741 throw (RuntimeException
, std::exception
)
1743 SolarMutexGuard aGuard
;
1745 throw RuntimeException();
1750 sal_Int32 SAL_CALL
SmEditAccessible::getForeground()
1751 throw (RuntimeException
, std::exception
)
1753 SolarMutexGuard aGuard
;
1756 throw RuntimeException();
1757 return (sal_Int32
) pWin
->GetTextColor().GetColor();
1760 sal_Int32 SAL_CALL
SmEditAccessible::getBackground()
1761 throw (RuntimeException
, std::exception
)
1763 SolarMutexGuard aGuard
;
1766 throw RuntimeException();
1767 Wallpaper
aWall( pWin
->GetDisplayBackground() );
1769 if (aWall
.IsBitmap() || aWall
.IsGradient())
1770 nCol
= pWin
->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
1772 nCol
= aWall
.GetColor().GetColor();
1773 return (sal_Int32
) nCol
;
1776 // XAccessibleContext
1777 sal_Int32 SAL_CALL
SmEditAccessible::getAccessibleChildCount( )
1778 throw (RuntimeException
, std::exception
)
1780 SolarMutexGuard aGuard
;
1782 throw RuntimeException();
1783 return pTextHelper
->GetChildCount();
1786 uno::Reference
< XAccessible
> SAL_CALL
SmEditAccessible::getAccessibleChild( sal_Int32 i
)
1787 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1789 SolarMutexGuard aGuard
;
1791 throw RuntimeException();
1792 return pTextHelper
->GetChild( i
);
1795 uno::Reference
< XAccessible
> SAL_CALL
SmEditAccessible::getAccessibleParent( )
1796 throw (RuntimeException
, std::exception
)
1798 SolarMutexGuard aGuard
;
1800 throw RuntimeException();
1802 vcl::Window
*pAccParent
= pWin
->GetAccessibleParentWindow();
1803 OSL_ENSURE( pAccParent
, "accessible parent missing" );
1804 return pAccParent
? pAccParent
->GetAccessible() : Reference
< XAccessible
>();
1807 sal_Int32 SAL_CALL
SmEditAccessible::getAccessibleIndexInParent( )
1808 throw (RuntimeException
, std::exception
)
1810 SolarMutexGuard aGuard
;
1811 sal_Int32 nIdx
= -1;
1812 vcl::Window
*pAccParent
= pWin
? pWin
->GetAccessibleParentWindow() : 0;
1815 sal_uInt16 nCnt
= pAccParent
->GetAccessibleChildWindowCount();
1816 for (sal_uInt16 i
= 0; i
< nCnt
&& nIdx
== -1; ++i
)
1817 if (pAccParent
->GetAccessibleChildWindow( i
) == pWin
)
1823 sal_Int16 SAL_CALL
SmEditAccessible::getAccessibleRole( )
1824 throw (RuntimeException
, std::exception
)
1826 SolarMutexGuard aGuard
;
1827 return AccessibleRole::PANEL
/*TEXT ?*/;
1830 OUString SAL_CALL
SmEditAccessible::getAccessibleDescription( )
1831 throw (RuntimeException
, std::exception
)
1833 SolarMutexGuard aGuard
;
1834 return OUString(); // empty as agreed with product-management
1837 OUString SAL_CALL
SmEditAccessible::getAccessibleName( )
1838 throw (RuntimeException
, std::exception
)
1840 SolarMutexGuard aGuard
;
1841 // same name as displayed by the window when not docked
1845 uno::Reference
< XAccessibleRelationSet
> SAL_CALL
SmEditAccessible::getAccessibleRelationSet( )
1846 throw (RuntimeException
, std::exception
)
1848 SolarMutexGuard aGuard
;
1849 Reference
< XAccessibleRelationSet
> xRelSet
= new utl::AccessibleRelationSetHelper();
1850 return xRelSet
; // empty relation set
1853 uno::Reference
< XAccessibleStateSet
> SAL_CALL
SmEditAccessible::getAccessibleStateSet( )
1854 throw (RuntimeException
, std::exception
)
1856 SolarMutexGuard aGuard
;
1857 ::utl::AccessibleStateSetHelper
*pStateSet
=
1858 new ::utl::AccessibleStateSetHelper
;
1860 Reference
<XAccessibleStateSet
> xStateSet( pStateSet
);
1862 if (!pWin
|| !pTextHelper
)
1863 pStateSet
->AddState( AccessibleStateType::DEFUNC
);
1866 pStateSet
->AddState( AccessibleStateType::MULTI_LINE
);
1867 pStateSet
->AddState( AccessibleStateType::ENABLED
);
1868 pStateSet
->AddState( AccessibleStateType::FOCUSABLE
);
1869 if (pWin
->HasFocus())
1870 pStateSet
->AddState( AccessibleStateType::FOCUSED
);
1871 if (pWin
->IsActive())
1872 pStateSet
->AddState( AccessibleStateType::ACTIVE
);
1873 if (pWin
->IsVisible())
1874 pStateSet
->AddState( AccessibleStateType::SHOWING
);
1875 if (pWin
->IsReallyVisible())
1876 pStateSet
->AddState( AccessibleStateType::VISIBLE
);
1877 if (COL_TRANSPARENT
!= pWin
->GetBackground().GetColor().GetColor())
1878 pStateSet
->AddState( AccessibleStateType::OPAQUE
);
1884 Locale SAL_CALL
SmEditAccessible::getLocale( )
1885 throw (IllegalAccessibleComponentStateException
, RuntimeException
, std::exception
)
1887 SolarMutexGuard aGuard
;
1888 // should be the document language...
1889 // We use the language of the localized symbol names here.
1890 return Application::GetSettings().GetUILanguageTag().getLocale();
1894 // XAccessibleEventBroadcaster
1895 void SAL_CALL
SmEditAccessible::addAccessibleEventListener( const uno::Reference
< XAccessibleEventListener
>& xListener
)
1896 throw (RuntimeException
, std::exception
)
1898 if (pTextHelper
) // not disposing (about to destroy view shell)
1899 pTextHelper
->AddEventListener( xListener
);
1902 void SAL_CALL
SmEditAccessible::removeAccessibleEventListener( const uno::Reference
< XAccessibleEventListener
>& xListener
)
1903 throw (RuntimeException
, std::exception
)
1905 if (pTextHelper
) // not disposing (about to destroy view shell)
1906 pTextHelper
->RemoveEventListener( xListener
);
1909 OUString SAL_CALL
SmEditAccessible::getImplementationName()
1910 throw (RuntimeException
, std::exception
)
1912 return OUString("SmEditAccessible");
1915 sal_Bool SAL_CALL
SmEditAccessible::supportsService(
1916 const OUString
& rServiceName
)
1917 throw (RuntimeException
, std::exception
)
1919 return cppu::supportsService(this, rServiceName
);
1922 Sequence
< OUString
> SAL_CALL
SmEditAccessible::getSupportedServiceNames()
1923 throw (RuntimeException
, std::exception
)
1925 return Sequence
< OUString
>{
1926 "com::sun::star::accessibility::Accessible",
1927 "com::sun::star::accessibility::AccessibleComponent",
1928 "com::sun::star::accessibility::AccessibleContext"
1934 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */