fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / starmath / source / accessibility.cxx
blobd5dc93efc9d6ced0dade16a2c0d8ef9f263a060d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/accessibility/AccessibleRole.hpp>
21 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
22 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
23 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
24 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
25 #include <com/sun/star/awt/FocusEvent.hpp>
26 #include <com/sun/star/awt/XFocusListener.hpp>
27 #include <unotools/accessiblerelationsethelper.hxx>
30 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
31 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
32 #include <com/sun/star/i18n/WordType.hpp>
33 #include <unotools/accessiblestatesethelper.hxx>
34 #include <comphelper/accessibleeventnotifier.hxx>
35 #include <osl/diagnose.h>
36 #include <vcl/svapp.hxx>
37 #include <vcl/window.hxx>
38 #include <vcl/unohelp2.hxx>
39 #include <tools/gen.hxx>
40 #include <osl/mutex.hxx>
41 #include <svl/itemset.hxx>
43 #include <editeng/editobj.hxx>
44 #include <editeng/editdata.hxx>
45 #include <editeng/editview.hxx>
46 #include <editeng/eeitem.hxx>
47 #include <editeng/outliner.hxx>
48 #include <editeng/unoedhlp.hxx>
51 #include "accessibility.hxx"
52 #include <unomodel.hxx>
53 #include <document.hxx>
54 #include <view.hxx>
56 using namespace com::sun::star;
57 using namespace com::sun::star::lang;
58 using namespace com::sun::star::uno;
59 using namespace com::sun::star::accessibility;
61 //////////////////////////////////////////////////////////////////////
63 static awt::Rectangle lcl_GetBounds( Window *pWin )
65 // !! see VCLXAccessibleComponent::implGetBounds()
67 //! the coordinates returned are relativ to the parent window !
68 //! Thus the top-left point may be different from (0, 0) !
70 awt::Rectangle aBounds;
71 if (pWin)
73 Rectangle aRect = pWin->GetWindowExtentsRelative( NULL );
74 aBounds.X = aRect.Left();
75 aBounds.Y = aRect.Top();
76 aBounds.Width = aRect.GetWidth();
77 aBounds.Height = aRect.GetHeight();
78 Window* pParent = pWin->GetAccessibleParentWindow();
79 if (pParent)
81 Rectangle aParentRect = pParent->GetWindowExtentsRelative( NULL );
82 awt::Point aParentScreenLoc( aParentRect.Left(), aParentRect.Top() );
83 aBounds.X -= aParentScreenLoc.X;
84 aBounds.Y -= aParentScreenLoc.Y;
87 return aBounds;
90 static awt::Point lcl_GetLocationOnScreen( Window *pWin )
92 // !! see VCLXAccessibleComponent::getLocationOnScreen()
94 awt::Point aPos;
95 if (pWin)
97 Rectangle aRect = pWin->GetWindowExtentsRelative( NULL );
98 aPos.X = aRect.Left();
99 aPos.Y = aRect.Top();
101 return aPos;
104 //////////////////////////////////////////////////////////////////////
106 SmGraphicAccessible::SmGraphicAccessible( SmGraphicWindow *pGraphicWin ) :
107 aAccName (SM_RESSTR(RID_DOCUMENTSTR)),
108 nClientId (0),
109 pWin (pGraphicWin)
111 OSL_ENSURE( pWin, "SmGraphicAccessible: window missing" );
115 SmGraphicAccessible::SmGraphicAccessible( const SmGraphicAccessible &rSmAcc ) :
116 SmGraphicAccessibleBaseClass(),
117 aAccName (SM_RESSTR(RID_DOCUMENTSTR)),
118 nClientId (0)
120 pWin = rSmAcc.pWin;
121 OSL_ENSURE( pWin, "SmGraphicAccessible: window missing" );
125 SmGraphicAccessible::~SmGraphicAccessible()
130 SmDocShell * SmGraphicAccessible::GetDoc_Impl()
132 SmViewShell *pView = pWin ? pWin->GetView() : 0;
133 return pView ? pView->GetDoc() : 0;
136 OUString SmGraphicAccessible::GetAccessibleText_Impl()
138 OUString aTxt;
139 SmDocShell *pDoc = GetDoc_Impl();
140 if (pDoc)
141 aTxt = pDoc->GetAccessibleText();
142 return aTxt;
145 void SmGraphicAccessible::ClearWin()
147 pWin = 0; // implicitly results in AccessibleStateType::DEFUNC set
149 if ( nClientId )
151 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
152 nClientId = 0;
156 void SmGraphicAccessible::LaunchEvent(
157 const sal_Int16 nAccesibleEventId,
158 const uno::Any &rOldVal,
159 const uno::Any &rNewVal)
161 AccessibleEventObject aEvt;
162 aEvt.Source = (XAccessible *) this;
163 aEvt.EventId = nAccesibleEventId;
164 aEvt.OldValue = rOldVal;
165 aEvt.NewValue = rNewVal ;
167 // pass event on to event-listener's
168 if (nClientId)
169 comphelper::AccessibleEventNotifier::addEvent( nClientId, aEvt );
172 uno::Reference< XAccessibleContext > SAL_CALL SmGraphicAccessible::getAccessibleContext()
173 throw (RuntimeException)
175 SolarMutexGuard aGuard;
176 return this;
179 sal_Bool SAL_CALL SmGraphicAccessible::containsPoint( const awt::Point& aPoint )
180 throw (RuntimeException)
182 //! the arguments coordinates are relativ to the current window !
183 //! Thus the top-left point is (0, 0)
185 SolarMutexGuard aGuard;
186 if (!pWin)
187 throw RuntimeException();
189 Size aSz( pWin->GetSizePixel() );
190 return aPoint.X >= 0 && aPoint.Y >= 0 &&
191 aPoint.X < aSz.Width() && aPoint.Y < aSz.Height();
194 uno::Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleAtPoint(
195 const awt::Point& aPoint )
196 throw (RuntimeException)
198 SolarMutexGuard aGuard;
199 XAccessible *pRes = 0;
200 if (containsPoint( aPoint ))
201 pRes = this;
202 return pRes;
205 awt::Rectangle SAL_CALL SmGraphicAccessible::getBounds()
206 throw (RuntimeException)
208 SolarMutexGuard aGuard;
209 if (!pWin)
210 throw RuntimeException();
211 OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
212 "mismatch of window parent and accessible parent" );
213 return lcl_GetBounds( pWin );
216 awt::Point SAL_CALL SmGraphicAccessible::getLocation()
217 throw (RuntimeException)
219 SolarMutexGuard aGuard;
220 if (!pWin)
221 throw RuntimeException();
222 OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
223 "mismatch of window parent and accessible parent" );
224 awt::Rectangle aRect( lcl_GetBounds( pWin ) );
225 return awt::Point( aRect.X, aRect.Y );
228 awt::Point SAL_CALL SmGraphicAccessible::getLocationOnScreen()
229 throw (RuntimeException)
231 SolarMutexGuard aGuard;
232 if (!pWin)
233 throw RuntimeException();
234 OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
235 "mismatch of window parent and accessible parent" );
236 return lcl_GetLocationOnScreen( pWin );
239 awt::Size SAL_CALL SmGraphicAccessible::getSize()
240 throw (RuntimeException)
242 SolarMutexGuard aGuard;
243 if (!pWin)
244 throw RuntimeException();
245 OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
246 "mismatch of window parent and accessible parent" );
248 Size aSz( pWin->GetSizePixel() );
249 #if OSL_DEBUG_LEVEL > 1
250 awt::Rectangle aRect( lcl_GetBounds( pWin ) );
251 Size aSz2( aRect.Width, aRect.Height );
252 OSL_ENSURE( aSz == aSz2, "mismatch in width" );
253 #endif
254 return awt::Size( aSz.Width(), aSz.Height() );
257 void SAL_CALL SmGraphicAccessible::grabFocus()
258 throw (RuntimeException)
260 SolarMutexGuard aGuard;
261 if (!pWin)
262 throw RuntimeException();
264 pWin->GrabFocus();
267 sal_Int32 SAL_CALL SmGraphicAccessible::getForeground()
268 throw (RuntimeException)
270 SolarMutexGuard aGuard;
272 if (!pWin)
273 throw RuntimeException();
274 return (sal_Int32) pWin->GetTextColor().GetColor();
277 sal_Int32 SAL_CALL SmGraphicAccessible::getBackground()
278 throw (RuntimeException)
280 SolarMutexGuard aGuard;
282 if (!pWin)
283 throw RuntimeException();
284 Wallpaper aWall( pWin->GetDisplayBackground() );
285 ColorData nCol;
286 if (aWall.IsBitmap() || aWall.IsGradient())
287 nCol = pWin->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
288 else
289 nCol = aWall.GetColor().GetColor();
290 return (sal_Int32) nCol;
293 sal_Int32 SAL_CALL SmGraphicAccessible::getAccessibleChildCount()
294 throw (RuntimeException)
296 SolarMutexGuard aGuard;
297 return 0;
300 Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleChild(
301 sal_Int32 /*i*/ )
302 throw (IndexOutOfBoundsException, RuntimeException)
304 SolarMutexGuard aGuard;
305 throw IndexOutOfBoundsException(); // there is no child...
308 Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleParent()
309 throw (RuntimeException)
311 SolarMutexGuard aGuard;
312 if (!pWin)
313 throw RuntimeException();
315 Window *pAccParent = pWin->GetAccessibleParentWindow();
316 OSL_ENSURE( pAccParent, "accessible parent missing" );
317 return pAccParent ? pAccParent->GetAccessible() : Reference< XAccessible >();
320 sal_Int32 SAL_CALL SmGraphicAccessible::getAccessibleIndexInParent()
321 throw (RuntimeException)
323 SolarMutexGuard aGuard;
324 sal_Int32 nIdx = -1;
325 Window *pAccParent = pWin ? pWin->GetAccessibleParentWindow() : 0;
326 if (pAccParent)
328 sal_uInt16 nCnt = pAccParent->GetAccessibleChildWindowCount();
329 for (sal_uInt16 i = 0; i < nCnt && nIdx == -1; ++i)
330 if (pAccParent->GetAccessibleChildWindow( i ) == pWin)
331 nIdx = i;
333 return nIdx;
336 sal_Int16 SAL_CALL SmGraphicAccessible::getAccessibleRole()
337 throw (RuntimeException)
339 SolarMutexGuard aGuard;
340 return AccessibleRole::DOCUMENT;
343 OUString SAL_CALL SmGraphicAccessible::getAccessibleDescription()
344 throw (RuntimeException)
346 SolarMutexGuard aGuard;
347 SmDocShell *pDoc = GetDoc_Impl();
348 return pDoc ? OUString(pDoc->GetText()) : OUString();
351 OUString SAL_CALL SmGraphicAccessible::getAccessibleName()
352 throw (RuntimeException)
354 SolarMutexGuard aGuard;
355 return aAccName;
358 Reference< XAccessibleRelationSet > SAL_CALL SmGraphicAccessible::getAccessibleRelationSet()
359 throw (RuntimeException)
361 SolarMutexGuard aGuard;
362 Reference< XAccessibleRelationSet > xRelSet = new utl::AccessibleRelationSetHelper();
363 return xRelSet; // empty relation set
366 Reference< XAccessibleStateSet > SAL_CALL SmGraphicAccessible::getAccessibleStateSet()
367 throw (RuntimeException)
369 SolarMutexGuard aGuard;
370 ::utl::AccessibleStateSetHelper *pStateSet =
371 new ::utl::AccessibleStateSetHelper;
373 Reference<XAccessibleStateSet> xStateSet( pStateSet );
375 if (!pWin)
376 pStateSet->AddState( AccessibleStateType::DEFUNC );
377 else
379 pStateSet->AddState( AccessibleStateType::ENABLED );
380 pStateSet->AddState( AccessibleStateType::FOCUSABLE );
381 if (pWin->HasFocus())
382 pStateSet->AddState( AccessibleStateType::FOCUSED );
383 if (pWin->IsActive())
384 pStateSet->AddState( AccessibleStateType::ACTIVE );
385 if (pWin->IsVisible())
386 pStateSet->AddState( AccessibleStateType::SHOWING );
387 if (pWin->IsReallyVisible())
388 pStateSet->AddState( AccessibleStateType::VISIBLE );
389 if (COL_TRANSPARENT != pWin->GetBackground().GetColor().GetColor())
390 pStateSet->AddState( AccessibleStateType::OPAQUE );
393 return xStateSet;
396 Locale SAL_CALL SmGraphicAccessible::getLocale()
397 throw (IllegalAccessibleComponentStateException, RuntimeException)
399 SolarMutexGuard aGuard;
400 // should be the document language...
401 // We use the language of the localized symbol names here.
402 return Application::GetSettings().GetUILanguageTag().getLocale();
406 void SAL_CALL SmGraphicAccessible::addAccessibleEventListener(
407 const Reference< XAccessibleEventListener >& xListener )
408 throw (RuntimeException)
410 if (xListener.is())
412 SolarMutexGuard aGuard;
413 if (pWin)
415 if (!nClientId)
416 nClientId = comphelper::AccessibleEventNotifier::registerClient( );
417 comphelper::AccessibleEventNotifier::addEventListener( nClientId, xListener );
422 void SAL_CALL SmGraphicAccessible::removeAccessibleEventListener(
423 const Reference< XAccessibleEventListener >& xListener )
424 throw (RuntimeException)
426 if (xListener.is())
428 SolarMutexGuard aGuard;
429 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( nClientId, xListener );
430 if ( !nListenerCount )
432 // no listeners anymore
433 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
434 // and at least to us not firing any events anymore, in case somebody calls
435 // NotifyAccessibleEvent, again
436 comphelper::AccessibleEventNotifier::revokeClient( nClientId );
437 nClientId = 0;
442 sal_Int32 SAL_CALL SmGraphicAccessible::getCaretPosition()
443 throw (RuntimeException)
445 SolarMutexGuard aGuard;
446 return 0;
449 sal_Bool SAL_CALL SmGraphicAccessible::setCaretPosition( sal_Int32 nIndex )
450 throw (IndexOutOfBoundsException, RuntimeException)
452 SolarMutexGuard aGuard;
453 OUString aTxt( GetAccessibleText_Impl() );
454 if (!(nIndex < aTxt.getLength()))
455 throw IndexOutOfBoundsException();
456 return sal_False;
459 sal_Unicode SAL_CALL SmGraphicAccessible::getCharacter( sal_Int32 nIndex )
460 throw (IndexOutOfBoundsException, RuntimeException)
462 SolarMutexGuard aGuard;
463 OUString aTxt( GetAccessibleText_Impl() );
464 if (!(nIndex < aTxt.getLength()))
465 throw IndexOutOfBoundsException();
466 return aTxt[nIndex];
469 Sequence< beans::PropertyValue > SAL_CALL SmGraphicAccessible::getCharacterAttributes(
470 sal_Int32 nIndex,
471 const uno::Sequence< OUString > & /*rRequestedAttributes*/ )
472 throw (IndexOutOfBoundsException, RuntimeException)
474 SolarMutexGuard aGuard;
475 sal_Int32 nLen = GetAccessibleText_Impl().getLength();
476 if (!(0 <= nIndex && nIndex < nLen))
477 throw IndexOutOfBoundsException();
478 return Sequence< beans::PropertyValue >();
481 awt::Rectangle SAL_CALL SmGraphicAccessible::getCharacterBounds( sal_Int32 nIndex )
482 throw (IndexOutOfBoundsException, RuntimeException)
484 SolarMutexGuard aGuard;
486 awt::Rectangle aRes;
488 if (!pWin)
489 throw RuntimeException();
490 else
492 // get accessible text
493 SmViewShell *pView = pWin->GetView();
494 SmDocShell *pDoc = pView ? pView->GetDoc() : 0;
495 if (!pDoc)
496 throw RuntimeException();
497 OUString aTxt( GetAccessibleText_Impl() );
498 if (!(0 <= nIndex && nIndex <= aTxt.getLength())) // aTxt.getLength() is valid
499 throw IndexOutOfBoundsException();
501 // find a reasonable rectangle for position aTxt.getLength().
502 bool bWasBehindText = (nIndex == aTxt.getLength());
503 if (bWasBehindText && nIndex)
504 --nIndex;
506 const SmNode *pTree = pDoc->GetFormulaTree();
507 const SmNode *pNode = pTree->FindNodeWithAccessibleIndex( (xub_StrLen) nIndex );
508 //! pNode may be 0 if the index belongs to a char that was inserted
509 //! only for the accessible text!
510 if (pNode)
512 sal_Int32 nAccIndex = pNode->GetAccessibleIndex();
513 OSL_ENSURE( nAccIndex >= 0, "invalid accessible index" );
514 OSL_ENSURE( nIndex >= nAccIndex, "index out of range" );
516 OUStringBuffer aBuf;
517 pNode->GetAccessibleText(aBuf);
518 OUString aNodeText = aBuf.makeStringAndClear();
519 sal_Int32 nNodeIndex = nIndex - nAccIndex;
520 if (0 <= nNodeIndex && nNodeIndex < aNodeText.getLength())
522 // get appropriate rectangle
523 Point aOffset(pNode->GetTopLeft() - pTree->GetTopLeft());
524 Point aTLPos (pWin->GetFormulaDrawPos() + aOffset);
525 aTLPos.X() -= 0;
526 Size aSize (pNode->GetSize());
528 sal_Int32 *pXAry = new sal_Int32[ aNodeText.getLength() ];
529 pWin->SetFont( pNode->GetFont() );
530 pWin->GetTextArray( aNodeText, pXAry, 0, aNodeText.getLength() );
531 aTLPos.X() += nNodeIndex > 0 ? pXAry[nNodeIndex - 1] : 0;
532 aSize.Width() = nNodeIndex > 0 ? pXAry[nNodeIndex] - pXAry[nNodeIndex - 1] : pXAry[nNodeIndex];
533 delete[] pXAry;
535 #if OSL_DEBUG_LEVEL > 1
536 Point aLP00( pWin->LogicToPixel( Point(0,0)) );
537 Point aPL00( pWin->PixelToLogic( Point(0,0)) );
538 #endif
539 aTLPos = pWin->LogicToPixel( aTLPos );
540 aSize = pWin->LogicToPixel( aSize );
541 aRes.X = aTLPos.X();
542 aRes.Y = aTLPos.Y();
543 aRes.Width = aSize.Width();
544 aRes.Height = aSize.Height();
548 // take rectangle from last character and move it to the right
549 if (bWasBehindText)
550 aRes.X += aRes.Width;
553 return aRes;
556 sal_Int32 SAL_CALL SmGraphicAccessible::getCharacterCount()
557 throw (RuntimeException)
559 SolarMutexGuard aGuard;
560 return GetAccessibleText_Impl().getLength();
563 sal_Int32 SAL_CALL SmGraphicAccessible::getIndexAtPoint( const awt::Point& aPoint )
564 throw (RuntimeException)
566 SolarMutexGuard aGuard;
568 sal_Int32 nRes = -1;
569 if (pWin)
571 const SmNode *pTree = pWin->GetView()->GetDoc()->GetFormulaTree();
572 // can be NULL! e.g. if one clicks within the window already during loading of the
573 // document (before the parser even started)
574 if (!pTree)
575 return nRes;
577 // get position relative to formula draw position
578 Point aPos( aPoint.X, aPoint.Y );
579 aPos = pWin->PixelToLogic( aPos );
580 aPos -= pWin->GetFormulaDrawPos();
582 // if it was inside the formula then get the appropriate node
583 const SmNode *pNode = 0;
584 if (pTree->OrientedDist(aPos) <= 0)
585 pNode = pTree->FindRectClosestTo(aPos);
587 if (pNode)
589 // get appropriate rectangle
590 Point aOffset( pNode->GetTopLeft() - pTree->GetTopLeft() );
591 Point aTLPos ( aOffset );
592 aTLPos.X() -= 0;
593 Size aSize( pNode->GetSize() );
594 #if OSL_DEBUG_LEVEL > 1
595 Point aLP00( pWin->LogicToPixel( Point(0,0)) );
596 Point aPL00( pWin->PixelToLogic( Point(0,0)) );
597 #endif
599 Rectangle aRect( aTLPos, aSize );
600 if (aRect.IsInside( aPos ))
602 OSL_ENSURE( pNode->IsVisible(), "node is not a leaf" );
603 OUStringBuffer aBuf;
604 pNode->GetAccessibleText(aBuf);
605 OUString aTxt = aBuf.makeStringAndClear();
606 OSL_ENSURE( !aTxt.isEmpty(), "no accessible text available" );
608 long nNodeX = pNode->GetLeft();
610 sal_Int32 *pXAry = new sal_Int32[ aTxt.getLength() ];
611 pWin->SetFont( pNode->GetFont() );
612 pWin->GetTextArray( aTxt, pXAry, 0, aTxt.getLength() );
613 for (sal_Int32 i = 0; i < aTxt.getLength() && nRes == -1; ++i)
615 if (pXAry[i] + nNodeX > aPos.X())
616 nRes = i;
618 delete[] pXAry;
619 OSL_ENSURE( nRes >= 0 && nRes < aTxt.getLength(), "index out of range" );
620 OSL_ENSURE( pNode->GetAccessibleIndex() >= 0,
621 "invalid accessible index" );
623 nRes = pNode->GetAccessibleIndex() + nRes;
627 return nRes;
630 OUString SAL_CALL SmGraphicAccessible::getSelectedText()
631 throw (RuntimeException)
633 SolarMutexGuard aGuard;
634 return OUString();
637 sal_Int32 SAL_CALL SmGraphicAccessible::getSelectionStart()
638 throw (RuntimeException)
640 SolarMutexGuard aGuard;
641 return -1;
644 sal_Int32 SAL_CALL SmGraphicAccessible::getSelectionEnd()
645 throw (RuntimeException)
647 SolarMutexGuard aGuard;
648 return -1;
651 sal_Bool SAL_CALL SmGraphicAccessible::setSelection(
652 sal_Int32 nStartIndex,
653 sal_Int32 nEndIndex )
654 throw (IndexOutOfBoundsException, RuntimeException)
656 SolarMutexGuard aGuard;
657 sal_Int32 nLen = GetAccessibleText_Impl().getLength();
658 if (!(0 <= nStartIndex && nStartIndex < nLen) ||
659 !(0 <= nEndIndex && nEndIndex < nLen))
660 throw IndexOutOfBoundsException();
661 return sal_False;
664 OUString SAL_CALL SmGraphicAccessible::getText()
665 throw (RuntimeException)
667 SolarMutexGuard aGuard;
668 return GetAccessibleText_Impl();
671 OUString SAL_CALL SmGraphicAccessible::getTextRange(
672 sal_Int32 nStartIndex,
673 sal_Int32 nEndIndex )
674 throw (IndexOutOfBoundsException, RuntimeException)
676 //!! nEndIndex may be the string length per definition of the interface !!
677 //!! text should be copied exclusive that end index though. And arguments
678 //!! may be switched.
680 SolarMutexGuard aGuard;
681 OUString aTxt( GetAccessibleText_Impl() );
682 sal_Int32 nStart = std::min(nStartIndex, nEndIndex);
683 sal_Int32 nEnd = std::max(nStartIndex, nEndIndex);
684 if (!(nStart <= aTxt.getLength()) ||
685 !(nEnd <= aTxt.getLength()))
686 throw IndexOutOfBoundsException();
687 return aTxt.copy( nStart, nEnd - nStart );
690 ::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)
692 SolarMutexGuard aGuard;
693 OUString aTxt( GetAccessibleText_Impl() );
694 //!! nIndex is allowed to be the string length
695 if (!(nIndex <= aTxt.getLength()))
696 throw IndexOutOfBoundsException();
698 ::com::sun::star::accessibility::TextSegment aResult;
699 aResult.SegmentStart = -1;
700 aResult.SegmentEnd = -1;
701 if ( (AccessibleTextType::CHARACTER == aTextType) && (nIndex < aTxt.getLength()) )
703 aResult.SegmentText = aTxt.copy(nIndex, 1);
704 aResult.SegmentStart = nIndex;
705 aResult.SegmentEnd = nIndex+1;
707 return aResult;
710 ::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)
712 SolarMutexGuard aGuard;
713 OUString aTxt( GetAccessibleText_Impl() );
714 //!! nIndex is allowed to be the string length
715 if (!(nIndex <= aTxt.getLength()))
716 throw IndexOutOfBoundsException();
718 ::com::sun::star::accessibility::TextSegment aResult;
719 aResult.SegmentStart = -1;
720 aResult.SegmentEnd = -1;
722 if ( (AccessibleTextType::CHARACTER == aTextType) && nIndex )
724 aResult.SegmentText = aTxt.copy(nIndex-1, 1);
725 aResult.SegmentStart = nIndex-1;
726 aResult.SegmentEnd = nIndex;
728 return aResult;
731 ::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)
733 SolarMutexGuard aGuard;
734 OUString aTxt( GetAccessibleText_Impl() );
735 //!! nIndex is allowed to be the string length
736 if (!(nIndex <= aTxt.getLength()))
737 throw IndexOutOfBoundsException();
739 ::com::sun::star::accessibility::TextSegment aResult;
740 aResult.SegmentStart = -1;
741 aResult.SegmentEnd = -1;
743 nIndex++; // text *behind*
744 if ( (AccessibleTextType::CHARACTER == aTextType) && (nIndex < aTxt.getLength()) )
746 aResult.SegmentText = aTxt.copy(nIndex, 1);
747 aResult.SegmentStart = nIndex;
748 aResult.SegmentEnd = nIndex+1;
750 return aResult;
753 sal_Bool SAL_CALL SmGraphicAccessible::copyText(
754 sal_Int32 nStartIndex,
755 sal_Int32 nEndIndex )
756 throw (IndexOutOfBoundsException, RuntimeException)
758 SolarMutexGuard aGuard;
759 sal_Bool bReturn = sal_False;
761 if (!pWin)
762 throw RuntimeException();
763 else
765 Reference< datatransfer::clipboard::XClipboard > xClipboard = pWin->GetClipboard();
766 if ( xClipboard.is() )
768 OUString sText( getTextRange(nStartIndex, nEndIndex) );
770 ::vcl::unohelper::TextDataObject* pDataObj = new ::vcl::unohelper::TextDataObject( sText );
771 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
772 xClipboard->setContents( pDataObj, NULL );
774 Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY );
775 if( xFlushableClipboard.is() )
776 xFlushableClipboard->flushClipboard();
778 Application::AcquireSolarMutex( nRef );
780 bReturn = sal_True;
784 return bReturn;
787 OUString SAL_CALL SmGraphicAccessible::getImplementationName()
788 throw (RuntimeException)
790 return OUString("SmGraphicAccessible");
793 sal_Bool SAL_CALL SmGraphicAccessible::supportsService(
794 const OUString& rServiceName )
795 throw (RuntimeException)
797 return rServiceName == "com::sun::star::accessibility::Accessible" ||
798 rServiceName == "com::sun::star::accessibility::AccessibleComponent" ||
799 rServiceName == "com::sun::star::accessibility::AccessibleContext" ||
800 rServiceName == "com::sun::star::accessibility::AccessibleText";
803 Sequence< OUString > SAL_CALL SmGraphicAccessible::getSupportedServiceNames()
804 throw (RuntimeException)
806 Sequence< OUString > aNames(4);
807 OUString *pNames = aNames.getArray();
808 pNames[0] = "com::sun::star::accessibility::Accessible";
809 pNames[1] = "com::sun::star::accessibility::AccessibleComponent";
810 pNames[2] = "com::sun::star::accessibility::AccessibleContext";
811 pNames[3] = "com::sun::star::accessibility::AccessibleText";
812 return aNames;
815 //////////////////////////////////////////////////////////////////////
817 //------------------------------------------------------------------------
819 SmEditSource::SmEditSource( SmEditWindow * /*pWin*/, SmEditAccessible &rAcc ) :
820 aViewFwd (rAcc),
821 aTextFwd (rAcc, *this),
822 aEditViewFwd(rAcc),
823 rEditAcc (rAcc)
827 SmEditSource::SmEditSource( const SmEditSource &rSrc ) :
828 SvxEditSource(),
829 aViewFwd (rSrc.rEditAcc),
830 aTextFwd (rSrc.rEditAcc, *this),
831 aEditViewFwd(rSrc.rEditAcc),
832 rEditAcc (rSrc.rEditAcc)
836 SmEditSource::~SmEditSource()
840 SvxEditSource* SmEditSource::Clone() const
842 return new SmEditSource( *this );
845 SvxTextForwarder* SmEditSource::GetTextForwarder()
847 return &aTextFwd;
850 SvxViewForwarder* SmEditSource::GetViewForwarder()
852 return &aViewFwd;
855 SvxEditViewForwarder* SmEditSource::GetEditViewForwarder( sal_Bool /*bCreate*/ )
857 return &aEditViewFwd;
860 void SmEditSource::UpdateData()
862 // would possibly only by needed if the XText inteface is implemented
863 // and its text needs to be updated.
866 SfxBroadcaster & SmEditSource::GetBroadcaster() const
868 return ((SmEditSource *) this)->aBroadCaster;
871 //------------------------------------------------------------------------
873 SmViewForwarder::SmViewForwarder( SmEditAccessible &rAcc ) :
874 rEditAcc(rAcc)
878 SmViewForwarder::~SmViewForwarder()
882 sal_Bool SmViewForwarder::IsValid() const
884 return rEditAcc.GetEditView() != 0;
887 Rectangle SmViewForwarder::GetVisArea() const
889 EditView *pEditView = rEditAcc.GetEditView();
890 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
892 if( pOutDev && pEditView)
894 Rectangle aVisArea = pEditView->GetVisArea();
896 // figure out map mode from edit engine
897 EditEngine* pEditEngine = pEditView->GetEditEngine();
899 if( pEditEngine )
901 MapMode aMapMode(pOutDev->GetMapMode());
902 aVisArea = OutputDevice::LogicToLogic( aVisArea,
903 pEditEngine->GetRefMapMode(),
904 aMapMode.GetMapUnit() );
905 aMapMode.SetOrigin(Point());
906 return pOutDev->LogicToPixel( aVisArea, aMapMode );
910 return Rectangle();
913 Point SmViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
915 EditView *pEditView = rEditAcc.GetEditView();
916 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
918 if( pOutDev )
920 MapMode aMapMode(pOutDev->GetMapMode());
921 Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
922 aMapMode.GetMapUnit() ) );
923 aMapMode.SetOrigin(Point());
924 return pOutDev->LogicToPixel( aPoint, aMapMode );
927 return Point();
930 Point SmViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
932 EditView *pEditView = rEditAcc.GetEditView();
933 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
935 if( pOutDev )
937 MapMode aMapMode(pOutDev->GetMapMode());
938 aMapMode.SetOrigin(Point());
939 Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
940 return OutputDevice::LogicToLogic( aPoint,
941 aMapMode.GetMapUnit(),
942 rMapMode );
945 return Point();
949 //------------------------------------------------------------------------
951 SmTextForwarder::SmTextForwarder( SmEditAccessible& rAcc, SmEditSource & rSource) :
952 rEditAcc ( rAcc ),
953 rEditSource (rSource)
955 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
956 if (pEditEngine)
957 pEditEngine->SetNotifyHdl( LINK(this, SmTextForwarder, NotifyHdl) );
960 SmTextForwarder::~SmTextForwarder()
962 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
963 if (pEditEngine)
964 pEditEngine->SetNotifyHdl( Link() );
967 IMPL_LINK(SmTextForwarder, NotifyHdl, EENotify*, aNotify)
969 if (aNotify)
971 ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify );
972 if (aHint.get())
973 rEditSource.GetBroadcaster().Broadcast( *aHint.get() );
976 return 0;
979 sal_Int32 SmTextForwarder::GetParagraphCount() const
981 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
982 return pEditEngine ? pEditEngine->GetParagraphCount() : 0;
985 sal_uInt16 SmTextForwarder::GetTextLen( sal_Int32 nParagraph ) const
987 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
988 return pEditEngine ? pEditEngine->GetTextLen( nParagraph ) : 0;
991 String SmTextForwarder::GetText( const ESelection& rSel ) const
993 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
994 String aRet;
995 if (pEditEngine)
996 aRet = pEditEngine->GetText( rSel, LINEEND_LF );
997 return convertLineEnd(aRet, GetSystemLineEnd());
1000 SfxItemSet SmTextForwarder::GetAttribs( const ESelection& rSel, sal_Bool bOnlyHardAttrib ) const
1002 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1003 OSL_ENSURE( pEditEngine, "EditEngine missing" );
1004 if( rSel.nStartPara == rSel.nEndPara )
1006 sal_uInt8 nFlags = 0;
1007 switch( bOnlyHardAttrib )
1009 case EditEngineAttribs_All:
1010 nFlags = GETATTRIBS_ALL;
1011 break;
1012 case EditEngineAttribs_HardAndPara:
1013 nFlags = GETATTRIBS_PARAATTRIBS|GETATTRIBS_CHARATTRIBS;
1014 break;
1015 case EditEngineAttribs_OnlyHard:
1016 nFlags = GETATTRIBS_CHARATTRIBS;
1017 break;
1018 default:
1019 OSL_FAIL("unknown flags for SmTextForwarder::GetAttribs");
1022 return pEditEngine->GetAttribs( rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags );
1024 else
1026 return pEditEngine->GetAttribs( rSel, bOnlyHardAttrib );
1030 SfxItemSet SmTextForwarder::GetParaAttribs( sal_Int32 nPara ) const
1032 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1033 OSL_ENSURE( pEditEngine, "EditEngine missing" );
1035 SfxItemSet aSet( pEditEngine->GetParaAttribs( nPara ) );
1037 sal_uInt16 nWhich = EE_PARA_START;
1038 while( nWhich <= EE_PARA_END )
1040 if( aSet.GetItemState( nWhich, sal_True ) != SFX_ITEM_ON )
1042 if( pEditEngine->HasParaAttrib( nPara, nWhich ) )
1043 aSet.Put( pEditEngine->GetParaAttrib( nPara, nWhich ) );
1045 nWhich++;
1048 return aSet;
1051 void SmTextForwarder::SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet )
1053 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1054 if (pEditEngine)
1055 pEditEngine->SetParaAttribs( nPara, rSet );
1058 SfxItemPool* SmTextForwarder::GetPool() const
1060 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1061 return pEditEngine ? pEditEngine->GetEmptyItemSet().GetPool() : 0;
1064 void SmTextForwarder::RemoveAttribs( const ESelection& rSelection, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich )
1066 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1067 if (pEditEngine)
1068 pEditEngine->RemoveAttribs( rSelection, bRemoveParaAttribs, nWhich );
1071 void SmTextForwarder::GetPortions( sal_Int32 nPara, std::vector<sal_uInt16>& rList ) const
1073 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1074 if (pEditEngine)
1075 pEditEngine->GetPortions( nPara, rList );
1078 void SmTextForwarder::QuickInsertText( const String& rText, const ESelection& rSel )
1080 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1081 if (pEditEngine)
1082 pEditEngine->QuickInsertText( rText, rSel );
1085 void SmTextForwarder::QuickInsertLineBreak( const ESelection& rSel )
1087 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1088 if (pEditEngine)
1089 pEditEngine->QuickInsertLineBreak( rSel );
1092 void SmTextForwarder::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
1094 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1095 if (pEditEngine)
1096 pEditEngine->QuickInsertField( rFld, rSel );
1099 void SmTextForwarder::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
1101 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1102 if (pEditEngine)
1103 pEditEngine->QuickSetAttribs( rSet, rSel );
1106 sal_Bool SmTextForwarder::IsValid() const
1108 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1109 // cannot reliably query EditEngine state
1110 // while in the middle of an update
1111 return pEditEngine ? pEditEngine->GetUpdateMode() : sal_False;
1114 OUString SmTextForwarder::CalcFieldValue( const SvxFieldItem& rField, sal_Int32 nPara, sal_uInt16 nPos, Color*& rpTxtColor, Color*& rpFldColor )
1116 XubString aTxt;
1117 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1118 if (pEditEngine)
1119 aTxt = pEditEngine->CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
1120 return aTxt;
1123 void SmTextForwarder::FieldClicked(const SvxFieldItem&, sal_Int32, sal_uInt16)
1127 static sal_uInt16 GetSvxEditEngineItemState( EditEngine& rEditEngine, const ESelection& rSel, sal_uInt16 nWhich )
1129 std::vector<EECharAttrib> aAttribs;
1131 const SfxPoolItem* pLastItem = NULL;
1133 SfxItemState eState = SFX_ITEM_DEFAULT;
1135 // check all paragraphs inside the selection
1136 for( sal_Int32 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++ )
1138 SfxItemState eParaState = SFX_ITEM_DEFAULT;
1140 // calculate start and endpos for this paragraph
1141 sal_uInt16 nPos = 0;
1142 if( rSel.nStartPara == nPara )
1143 nPos = rSel.nStartPos;
1145 sal_uInt16 nEndPos = rSel.nEndPos;
1146 if( rSel.nEndPara != nPara )
1147 nEndPos = rEditEngine.GetTextLen( nPara );
1150 // get list of char attribs
1151 rEditEngine.GetCharAttribs( nPara, aAttribs );
1153 bool bEmpty = true; // we found no item inside the selektion of this paragraph
1154 bool bGaps = false; // we found items but theire gaps between them
1155 sal_uInt16 nLastEnd = nPos;
1157 const SfxPoolItem* pParaItem = NULL;
1159 for(std::vector<EECharAttrib>::const_iterator i = aAttribs.begin(); i < aAttribs.end(); ++i)
1161 OSL_ENSURE( i->pAttr, "GetCharAttribs gives corrupt data" );
1163 const sal_Bool bEmptyPortion = (i->nStart == i->nEnd);
1164 if( (!bEmptyPortion && (i->nStart >= nEndPos)) || (bEmptyPortion && (i->nStart > nEndPos)) )
1165 break; // break if we are already behind our selektion
1167 if( (!bEmptyPortion && (i->nEnd <= nPos)) || (bEmptyPortion && (i->nEnd < nPos)) )
1168 continue; // or if the attribute ends before our selektion
1170 if( i->pAttr->Which() != nWhich )
1171 continue; // skip if is not the searched item
1173 // if we already found an item
1174 if( pParaItem )
1176 // ... and its different to this one than the state is dont care
1177 if( *pParaItem != *(i->pAttr) )
1178 return SFX_ITEM_DONTCARE;
1180 else
1182 pParaItem = i->pAttr;
1185 if( bEmpty )
1186 bEmpty = false;
1188 if( !bGaps && i->nStart > nLastEnd )
1189 bGaps = true;
1191 nLastEnd = i->nEnd;
1194 if( !bEmpty && !bGaps && nLastEnd < ( nEndPos - 1 ) )
1195 bGaps = true;
1196 if( bEmpty )
1197 eParaState = SFX_ITEM_DEFAULT;
1198 else if( bGaps )
1199 eParaState = SFX_ITEM_DONTCARE;
1200 else
1201 eParaState = SFX_ITEM_SET;
1203 // if we already found an item check if we found the same
1204 if( pLastItem )
1206 if( (pParaItem == NULL) || (*pLastItem != *pParaItem) )
1207 return SFX_ITEM_DONTCARE;
1209 else
1211 pLastItem = pParaItem;
1212 eState = eParaState;
1216 return eState;
1219 sal_uInt16 SmTextForwarder::GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const
1221 sal_uInt16 nState = SFX_ITEM_DISABLED;
1222 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1223 if (pEditEngine)
1224 nState = GetSvxEditEngineItemState( *pEditEngine, rSel, nWhich );
1225 return nState;
1228 sal_uInt16 SmTextForwarder::GetItemState( sal_Int32 nPara, sal_uInt16 nWhich ) const
1230 sal_uInt16 nState = SFX_ITEM_DISABLED;
1231 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1232 if (pEditEngine)
1234 const SfxItemSet& rSet = pEditEngine->GetParaAttribs( nPara );
1235 nState = rSet.GetItemState( nWhich );
1237 return nState;
1240 LanguageType SmTextForwarder::GetLanguage( sal_Int32 nPara, sal_uInt16 nIndex ) const
1242 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1243 return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex) : LANGUAGE_NONE;
1246 sal_uInt16 SmTextForwarder::GetFieldCount( sal_Int32 nPara ) const
1248 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1249 return pEditEngine ? pEditEngine->GetFieldCount(nPara) : 0;
1252 EFieldInfo SmTextForwarder::GetFieldInfo( sal_Int32 nPara, sal_uInt16 nField ) const
1254 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1255 return pEditEngine ? pEditEngine->GetFieldInfo( nPara, nField ) : EFieldInfo();
1258 EBulletInfo SmTextForwarder::GetBulletInfo( sal_Int32 /*nPara*/ ) const
1260 return EBulletInfo();
1263 Rectangle SmTextForwarder::GetCharBounds( sal_Int32 nPara, sal_uInt16 nIndex ) const
1265 Rectangle aRect(0,0,0,0);
1266 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1268 if (pEditEngine)
1270 // Handle virtual position one-past-the end of the string
1271 if( nIndex >= pEditEngine->GetTextLen(nPara) )
1273 if( nIndex )
1274 aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex-1) );
1276 aRect.Move( aRect.Right() - aRect.Left(), 0 );
1277 aRect.SetSize( Size(1, pEditEngine->GetTextHeight()) );
1279 else
1281 aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex) );
1284 return aRect;
1287 Rectangle SmTextForwarder::GetParaBounds( sal_Int32 nPara ) const
1289 Rectangle aRect(0,0,0,0);
1290 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1292 if (pEditEngine)
1294 const Point aPnt = pEditEngine->GetDocPosTopLeft( nPara );
1295 const sal_uLong nWidth = pEditEngine->CalcTextWidth();
1296 const sal_uLong nHeight = pEditEngine->GetTextHeight( nPara );
1297 aRect = Rectangle( aPnt.X(), aPnt.Y(), aPnt.X() + nWidth, aPnt.Y() + nHeight );
1300 return aRect;
1303 MapMode SmTextForwarder::GetMapMode() const
1305 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1306 return pEditEngine ? pEditEngine->GetRefMapMode() : MapMode( MAP_100TH_MM );
1309 OutputDevice* SmTextForwarder::GetRefDevice() const
1311 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1312 return pEditEngine ? pEditEngine->GetRefDevice() : 0;
1315 sal_Bool SmTextForwarder::GetIndexAtPoint( const Point& rPos, sal_Int32& nPara, sal_uInt16& nIndex ) const
1317 sal_Bool bRes = sal_False;
1318 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1319 if (pEditEngine)
1321 EPosition aDocPos = pEditEngine->FindDocPosition( rPos );
1322 nPara = aDocPos.nPara;
1323 nIndex = aDocPos.nIndex;
1324 bRes = sal_True;
1326 return bRes;
1329 sal_Bool SmTextForwarder::GetWordIndices( sal_Int32 nPara, sal_uInt16 nIndex, sal_uInt16& nStart, sal_uInt16& nEnd ) const
1331 sal_Bool bRes = sal_False;
1332 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1333 if (pEditEngine)
1335 ESelection aRes = pEditEngine->GetWord( ESelection(nPara, nIndex, nPara, nIndex), com::sun::star::i18n::WordType::DICTIONARY_WORD );
1337 if( aRes.nStartPara == nPara &&
1338 aRes.nStartPara == aRes.nEndPara )
1340 nStart = aRes.nStartPos;
1341 nEnd = aRes.nEndPos;
1343 bRes = sal_True;
1347 return bRes;
1350 sal_Bool SmTextForwarder::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_Int32 nPara, sal_uInt16 nIndex ) const
1352 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1353 return pEditEngine ?
1354 SvxEditSourceHelper::GetAttributeRun( nStartIndex, nEndIndex, *pEditEngine, nPara, nIndex )
1355 : sal_False;
1358 sal_uInt16 SmTextForwarder::GetLineCount( sal_Int32 nPara ) const
1360 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1361 return pEditEngine ? pEditEngine->GetLineCount(nPara) : 0;
1364 sal_uInt16 SmTextForwarder::GetLineLen( sal_Int32 nPara, sal_uInt16 nLine ) const
1366 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1367 return pEditEngine ? pEditEngine->GetLineLen(nPara, nLine) : 0;
1370 void SmTextForwarder::GetLineBoundaries( /*out*/sal_uInt16 &rStart, /*out*/sal_uInt16 &rEnd, sal_Int32 nPara, sal_uInt16 nLine ) const
1372 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1373 pEditEngine->GetLineBoundaries(rStart, rEnd, nPara, nLine);
1376 sal_uInt16 SmTextForwarder::GetLineNumberAtIndex( sal_Int32 nPara, sal_uInt16 nIndex ) const
1378 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1379 return pEditEngine ? pEditEngine->GetLineNumberAtIndex(nPara, nIndex) : 0;
1382 sal_Bool SmTextForwarder::QuickFormatDoc( sal_Bool /*bFull*/ )
1384 sal_Bool bRes = sal_False;
1385 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1386 if (pEditEngine)
1388 pEditEngine->QuickFormatDoc();
1389 bRes = sal_True;
1391 return bRes;
1394 sal_Int16 SmTextForwarder::GetDepth( sal_Int32 /*nPara*/ ) const
1396 // math has no outliner...
1397 return -1;
1400 sal_Bool SmTextForwarder::SetDepth( sal_Int32 /*nPara*/, sal_Int16 nNewDepth )
1402 // math has no outliner...
1403 return -1 == nNewDepth; // is it the value from 'GetDepth' ?
1406 sal_Bool SmTextForwarder::Delete( const ESelection& rSelection )
1408 sal_Bool bRes = sal_False;
1409 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1410 if (pEditEngine)
1412 pEditEngine->QuickDelete( rSelection );
1413 pEditEngine->QuickFormatDoc();
1414 bRes = sal_True;
1416 return bRes;
1419 sal_Bool SmTextForwarder::InsertText( const String& rStr, const ESelection& rSelection )
1421 sal_Bool bRes = sal_False;
1422 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1423 if (pEditEngine)
1425 pEditEngine->QuickInsertText( rStr, rSelection );
1426 pEditEngine->QuickFormatDoc();
1427 bRes = sal_True;
1429 return bRes;
1432 const SfxItemSet* SmTextForwarder::GetEmptyItemSetPtr()
1434 const SfxItemSet *pItemSet = 0;
1435 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1436 if (pEditEngine)
1438 pItemSet = &pEditEngine->GetEmptyItemSet();
1440 return pItemSet;
1443 void SmTextForwarder::AppendParagraph()
1445 // append an empty paragraph
1446 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1447 if (pEditEngine)
1449 sal_Int32 nParaCount = pEditEngine->GetParagraphCount();
1450 pEditEngine->InsertParagraph( nParaCount, String() );
1454 xub_StrLen SmTextForwarder::AppendTextPortion( sal_Int32 nPara, const String &rText, const SfxItemSet &rSet )
1456 xub_StrLen nRes = 0;
1457 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1458 if (pEditEngine && nPara < pEditEngine->GetParagraphCount())
1460 // append text
1461 ESelection aSel( nPara, pEditEngine->GetTextLen( nPara ) );
1462 pEditEngine->QuickInsertText( rText, aSel );
1464 // set attributes for new appended text
1465 nRes = aSel.nEndPos = pEditEngine->GetTextLen( nPara );
1466 pEditEngine->QuickSetAttribs( rSet, aSel );
1468 return nRes;
1471 void SmTextForwarder::CopyText(const SvxTextForwarder& rSource)
1474 const SmTextForwarder* pSourceForwarder = dynamic_cast< const SmTextForwarder* >( &rSource );
1475 if( !pSourceForwarder )
1476 return;
1477 EditEngine* pSourceEditEngine = pSourceForwarder->rEditAcc.GetEditEngine();
1478 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1479 if (pEditEngine && pSourceEditEngine )
1481 EditTextObject* pNewTextObject = pSourceEditEngine->CreateTextObject();
1482 pEditEngine->SetText( *pNewTextObject );
1483 delete pNewTextObject;
1487 //------------------------------------------------------------------------
1489 SmEditViewForwarder::SmEditViewForwarder( SmEditAccessible& rAcc ) :
1490 rEditAcc( rAcc )
1494 SmEditViewForwarder::~SmEditViewForwarder()
1498 sal_Bool SmEditViewForwarder::IsValid() const
1500 return rEditAcc.GetEditView() != 0;
1503 Rectangle SmEditViewForwarder::GetVisArea() const
1505 Rectangle aRect(0,0,0,0);
1507 EditView *pEditView = rEditAcc.GetEditView();
1508 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
1510 if( pOutDev && pEditView)
1512 Rectangle aVisArea = pEditView->GetVisArea();
1514 // figure out map mode from edit engine
1515 EditEngine* pEditEngine = pEditView->GetEditEngine();
1517 if( pEditEngine )
1519 MapMode aMapMode(pOutDev->GetMapMode());
1520 aVisArea = OutputDevice::LogicToLogic( aVisArea,
1521 pEditEngine->GetRefMapMode(),
1522 aMapMode.GetMapUnit() );
1523 aMapMode.SetOrigin(Point());
1524 aRect = pOutDev->LogicToPixel( aVisArea, aMapMode );
1528 return aRect;
1531 Point SmEditViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
1533 EditView *pEditView = rEditAcc.GetEditView();
1534 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
1536 if( pOutDev )
1538 MapMode aMapMode(pOutDev->GetMapMode());
1539 Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
1540 aMapMode.GetMapUnit() ) );
1541 aMapMode.SetOrigin(Point());
1542 return pOutDev->LogicToPixel( aPoint, aMapMode );
1545 return Point();
1548 Point SmEditViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
1550 EditView *pEditView = rEditAcc.GetEditView();
1551 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
1553 if( pOutDev )
1555 MapMode aMapMode(pOutDev->GetMapMode());
1556 aMapMode.SetOrigin(Point());
1557 Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
1558 return OutputDevice::LogicToLogic( aPoint,
1559 aMapMode.GetMapUnit(),
1560 rMapMode );
1563 return Point();
1566 sal_Bool SmEditViewForwarder::GetSelection( ESelection& rSelection ) const
1568 sal_Bool bRes = sal_False;
1569 EditView *pEditView = rEditAcc.GetEditView();
1570 if (pEditView)
1572 rSelection = pEditView->GetSelection();
1573 bRes = sal_True;
1575 return bRes;
1578 sal_Bool SmEditViewForwarder::SetSelection( const ESelection& rSelection )
1580 sal_Bool bRes = sal_False;
1581 EditView *pEditView = rEditAcc.GetEditView();
1582 if (pEditView)
1584 pEditView->SetSelection( rSelection );
1585 bRes = sal_True;
1587 return bRes;
1590 sal_Bool SmEditViewForwarder::Copy()
1592 sal_Bool bRes = sal_False;
1593 EditView *pEditView = rEditAcc.GetEditView();
1594 if (pEditView)
1596 pEditView->Copy();
1597 bRes = sal_True;
1599 return bRes;
1602 sal_Bool SmEditViewForwarder::Cut()
1604 sal_Bool bRes = sal_False;
1605 EditView *pEditView = rEditAcc.GetEditView();
1606 if (pEditView)
1608 pEditView->Cut();
1609 bRes = sal_True;
1611 return bRes;
1614 sal_Bool SmEditViewForwarder::Paste()
1616 sal_Bool bRes = sal_False;
1617 EditView *pEditView = rEditAcc.GetEditView();
1618 if (pEditView)
1620 pEditView->Paste();
1621 bRes = sal_True;
1623 return bRes;
1626 //------------------------------------------------------------------------
1628 SmEditAccessible::SmEditAccessible( SmEditWindow *pEditWin ) :
1629 aAccName (SM_RESSTR(STR_CMDBOXWINDOW)),
1630 pTextHelper (0),
1631 pWin (pEditWin)
1633 OSL_ENSURE( pWin, "SmEditAccessible: window missing" );
1637 SmEditAccessible::SmEditAccessible( const SmEditAccessible &rSmAcc ) :
1638 SmEditAccessibleBaseClass(),
1639 aAccName (SM_RESSTR(STR_CMDBOXWINDOW))
1641 pWin = rSmAcc.pWin;
1642 OSL_ENSURE( pWin, "SmEditAccessible: window missing" );
1645 SmEditAccessible::~SmEditAccessible()
1647 delete pTextHelper;
1650 void SmEditAccessible::Init()
1652 OSL_ENSURE( pWin, "SmEditAccessible: window missing" );
1653 if (pWin)
1655 EditEngine *pEditEngine = pWin->GetEditEngine();
1656 EditView *pEditView = pWin->GetEditView();
1657 if (pEditEngine && pEditView)
1659 ::std::auto_ptr< SvxEditSource > pEditSource(
1660 new SmEditSource( pWin, *this ) );
1661 pTextHelper = new ::accessibility::AccessibleTextHelper( pEditSource );
1662 pTextHelper->SetEventSource( this );
1667 void SmEditAccessible::ClearWin()
1669 // remove handler before current object gets destroyed
1670 // (avoid handler being called for already dead object)
1671 EditEngine *pEditEngine = GetEditEngine();
1672 if (pEditEngine)
1673 pEditEngine->SetNotifyHdl( Link() );
1675 pWin = 0; // implicitly results in AccessibleStateType::DEFUNC set
1677 //! make TextHelper implicitly release C++ references to some core objects
1678 pTextHelper->SetEditSource( ::std::auto_ptr<SvxEditSource>(NULL) );
1679 //! make TextHelper release references
1680 //! (e.g. the one set by the 'SetEventSource' call)
1681 pTextHelper->Dispose();
1682 delete pTextHelper; pTextHelper = 0;
1685 // XAccessible
1686 uno::Reference< XAccessibleContext > SAL_CALL SmEditAccessible::getAccessibleContext( )
1687 throw (RuntimeException)
1689 SolarMutexGuard aGuard;
1690 return this;
1693 // XAccessibleComponent
1694 sal_Bool SAL_CALL SmEditAccessible::containsPoint( const awt::Point& aPoint )
1695 throw (RuntimeException)
1697 //! the arguments coordinates are relativ to the current window !
1698 //! Thus the top left-point is (0, 0)
1700 SolarMutexGuard aGuard;
1701 if (!pWin)
1702 throw RuntimeException();
1704 Size aSz( pWin->GetSizePixel() );
1705 return aPoint.X >= 0 && aPoint.Y >= 0 &&
1706 aPoint.X < aSz.Width() && aPoint.Y < aSz.Height();
1709 uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleAtPoint( const awt::Point& aPoint )
1710 throw (RuntimeException)
1712 SolarMutexGuard aGuard;
1713 if (!pTextHelper)
1714 throw RuntimeException();
1715 return pTextHelper->GetAt( aPoint );
1718 awt::Rectangle SAL_CALL SmEditAccessible::getBounds( )
1719 throw (RuntimeException)
1721 SolarMutexGuard aGuard;
1722 if (!pWin)
1723 throw RuntimeException();
1724 OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
1725 "mismatch of window parent and accessible parent" );
1726 return lcl_GetBounds( pWin );
1729 awt::Point SAL_CALL SmEditAccessible::getLocation( )
1730 throw (RuntimeException)
1732 SolarMutexGuard aGuard;
1733 if (!pWin)
1734 throw RuntimeException();
1735 OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
1736 "mismatch of window parent and accessible parent" );
1737 awt::Rectangle aRect( lcl_GetBounds( pWin ) );
1738 return awt::Point( aRect.X, aRect.Y );
1741 awt::Point SAL_CALL SmEditAccessible::getLocationOnScreen( )
1742 throw (RuntimeException)
1744 SolarMutexGuard aGuard;
1745 if (!pWin)
1746 throw RuntimeException();
1747 OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
1748 "mismatch of window parent and accessible parent" );
1749 return lcl_GetLocationOnScreen( pWin );
1752 awt::Size SAL_CALL SmEditAccessible::getSize( )
1753 throw (RuntimeException)
1755 SolarMutexGuard aGuard;
1756 if (!pWin)
1757 throw RuntimeException();
1758 OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
1759 "mismatch of window parent and accessible parent" );
1761 Size aSz( pWin->GetSizePixel() );
1762 #if OSL_DEBUG_LEVEL > 1
1763 awt::Rectangle aRect( lcl_GetBounds( pWin ) );
1764 Size aSz2( aRect.Width, aRect.Height );
1765 OSL_ENSURE( aSz == aSz2, "mismatch in width" );
1766 #endif
1767 return awt::Size( aSz.Width(), aSz.Height() );
1770 void SAL_CALL SmEditAccessible::grabFocus( )
1771 throw (RuntimeException)
1773 SolarMutexGuard aGuard;
1774 if (!pWin)
1775 throw RuntimeException();
1777 pWin->GrabFocus();
1780 sal_Int32 SAL_CALL SmEditAccessible::getForeground()
1781 throw (RuntimeException)
1783 SolarMutexGuard aGuard;
1785 if (!pWin)
1786 throw RuntimeException();
1787 return (sal_Int32) pWin->GetTextColor().GetColor();
1790 sal_Int32 SAL_CALL SmEditAccessible::getBackground()
1791 throw (RuntimeException)
1793 SolarMutexGuard aGuard;
1795 if (!pWin)
1796 throw RuntimeException();
1797 Wallpaper aWall( pWin->GetDisplayBackground() );
1798 ColorData nCol;
1799 if (aWall.IsBitmap() || aWall.IsGradient())
1800 nCol = pWin->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
1801 else
1802 nCol = aWall.GetColor().GetColor();
1803 return (sal_Int32) nCol;
1806 // XAccessibleContext
1807 sal_Int32 SAL_CALL SmEditAccessible::getAccessibleChildCount( )
1808 throw (RuntimeException)
1810 SolarMutexGuard aGuard;
1811 if (!pTextHelper)
1812 throw RuntimeException();
1813 return pTextHelper->GetChildCount();
1816 uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleChild( sal_Int32 i )
1817 throw (IndexOutOfBoundsException, RuntimeException)
1819 SolarMutexGuard aGuard;
1820 if (!pTextHelper)
1821 throw RuntimeException();
1822 return pTextHelper->GetChild( i );
1825 uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleParent( )
1826 throw (RuntimeException)
1828 SolarMutexGuard aGuard;
1829 if (!pWin)
1830 throw RuntimeException();
1832 Window *pAccParent = pWin->GetAccessibleParentWindow();
1833 OSL_ENSURE( pAccParent, "accessible parent missing" );
1834 return pAccParent ? pAccParent->GetAccessible() : Reference< XAccessible >();
1837 sal_Int32 SAL_CALL SmEditAccessible::getAccessibleIndexInParent( )
1838 throw (RuntimeException)
1840 SolarMutexGuard aGuard;
1841 sal_Int32 nIdx = -1;
1842 Window *pAccParent = pWin ? pWin->GetAccessibleParentWindow() : 0;
1843 if (pAccParent)
1845 sal_uInt16 nCnt = pAccParent->GetAccessibleChildWindowCount();
1846 for (sal_uInt16 i = 0; i < nCnt && nIdx == -1; ++i)
1847 if (pAccParent->GetAccessibleChildWindow( i ) == pWin)
1848 nIdx = i;
1850 return nIdx;
1853 sal_Int16 SAL_CALL SmEditAccessible::getAccessibleRole( )
1854 throw (RuntimeException)
1856 SolarMutexGuard aGuard;
1857 return AccessibleRole::PANEL /*TEXT ?*/;
1860 OUString SAL_CALL SmEditAccessible::getAccessibleDescription( )
1861 throw (RuntimeException)
1863 SolarMutexGuard aGuard;
1864 return OUString(); // empty as agreed with product-management
1867 OUString SAL_CALL SmEditAccessible::getAccessibleName( )
1868 throw (RuntimeException)
1870 SolarMutexGuard aGuard;
1871 // same name as displayed by the window when not docked
1872 return aAccName;
1875 uno::Reference< XAccessibleRelationSet > SAL_CALL SmEditAccessible::getAccessibleRelationSet( )
1876 throw (RuntimeException)
1878 SolarMutexGuard aGuard;
1879 Reference< XAccessibleRelationSet > xRelSet = new utl::AccessibleRelationSetHelper();
1880 return xRelSet; // empty relation set
1883 uno::Reference< XAccessibleStateSet > SAL_CALL SmEditAccessible::getAccessibleStateSet( )
1884 throw (RuntimeException)
1886 SolarMutexGuard aGuard;
1887 ::utl::AccessibleStateSetHelper *pStateSet =
1888 new ::utl::AccessibleStateSetHelper;
1890 Reference<XAccessibleStateSet> xStateSet( pStateSet );
1892 if (!pWin || !pTextHelper)
1893 pStateSet->AddState( AccessibleStateType::DEFUNC );
1894 else
1896 pStateSet->AddState( AccessibleStateType::MULTI_LINE );
1897 pStateSet->AddState( AccessibleStateType::ENABLED );
1898 pStateSet->AddState( AccessibleStateType::FOCUSABLE );
1899 if (pWin->HasFocus())
1900 pStateSet->AddState( AccessibleStateType::FOCUSED );
1901 if (pWin->IsActive())
1902 pStateSet->AddState( AccessibleStateType::ACTIVE );
1903 if (pWin->IsVisible())
1904 pStateSet->AddState( AccessibleStateType::SHOWING );
1905 if (pWin->IsReallyVisible())
1906 pStateSet->AddState( AccessibleStateType::VISIBLE );
1907 if (COL_TRANSPARENT != pWin->GetBackground().GetColor().GetColor())
1908 pStateSet->AddState( AccessibleStateType::OPAQUE );
1911 return xStateSet;
1914 Locale SAL_CALL SmEditAccessible::getLocale( )
1915 throw (IllegalAccessibleComponentStateException, RuntimeException)
1917 SolarMutexGuard aGuard;
1918 // should be the document language...
1919 // We use the language of the localized symbol names here.
1920 return Application::GetSettings().GetUILanguageTag().getLocale();
1924 // XAccessibleEventBroadcaster
1925 void SAL_CALL SmEditAccessible::addAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
1926 throw (RuntimeException)
1928 if (pTextHelper) // not disposing (about to destroy view shell)
1929 pTextHelper->AddEventListener( xListener );
1932 void SAL_CALL SmEditAccessible::removeAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
1933 throw (RuntimeException)
1935 if (pTextHelper) // not disposing (about to destroy view shell)
1936 pTextHelper->RemoveEventListener( xListener );
1939 OUString SAL_CALL SmEditAccessible::getImplementationName()
1940 throw (RuntimeException)
1942 return OUString("SmEditAccessible");
1945 sal_Bool SAL_CALL SmEditAccessible::supportsService(
1946 const OUString& rServiceName )
1947 throw (RuntimeException)
1949 return rServiceName == "com::sun::star::accessibility::Accessible" ||
1950 rServiceName == "com::sun::star::accessibility::AccessibleComponent" ||
1951 rServiceName == "com::sun::star::accessibility::AccessibleContext";
1954 Sequence< OUString > SAL_CALL SmEditAccessible::getSupportedServiceNames()
1955 throw (RuntimeException)
1957 Sequence< OUString > aNames(3);
1958 OUString *pNames = aNames.getArray();
1959 pNames[0] = "com::sun::star::accessibility::Accessible";
1960 pNames[1] = "com::sun::star::accessibility::AccessibleComponent";
1961 pNames[2] = "com::sun::star::accessibility::AccessibleContext";
1962 return aNames;
1965 //////////////////////////////////////////////////////////////////////
1967 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */