1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_starmath.hxx"
26 #include <com/sun/star/accessibility/AccessibleRole.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
29 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
30 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
31 #include <com/sun/star/awt/FocusEvent.hpp>
32 #include <com/sun/star/awt/XFocusListener.hpp>
33 #include <unotools/accessiblerelationsethelper.hxx>
34 
35 
36 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
37 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
38 #include <com/sun/star/i18n/WordType.hpp>
39 #include <unotools/accessiblestatesethelper.hxx>
40 #include <comphelper/accessibleeventnotifier.hxx>
41 #include <tools/debug.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/window.hxx>
44 #include <vcl/unohelp2.hxx>
45 #include <tools/gen.hxx>
46 #include <vos/mutex.hxx>
47 #include <svl/itemset.hxx>
48 
49 #include <editeng/editobj.hxx>
50 #include <editeng/editdata.hxx>
51 #include <editeng/editview.hxx>
52 #include <editeng/eeitem.hxx>
53 #include <editeng/outliner.hxx>
54 #include <editeng/unoedhlp.hxx>
55 
56 
57 #include "accessibility.hxx"
58 #include <applicat.hxx>
59 #include <document.hxx>
60 #include <view.hxx>
61 
62 using namespace rtl;
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;
67 
68 #define A2OU(cChar)  rtl::OUString::createFromAscii(cChar)
69 
70 //////////////////////////////////////////////////////////////////////
71 
72 static awt::Rectangle lcl_GetBounds( Window *pWin )
73 {
74     // !! see VCLXAccessibleComponent::implGetBounds()
75 
76     //! the coordinates returned are relativ to the parent window !
77     //! Thus the top-left point may be different from (0, 0) !
78 
79     awt::Rectangle aBounds;
80     if (pWin)
81     {
82         Rectangle aRect = pWin->GetWindowExtentsRelative( NULL );
83         aBounds.X       = aRect.Left();
84         aBounds.Y       = aRect.Top();
85         aBounds.Width   = aRect.GetWidth();
86         aBounds.Height  = aRect.GetHeight();
87         Window* pParent = pWin->GetAccessibleParentWindow();
88         if (pParent)
89         {
90             Rectangle aParentRect = pParent->GetWindowExtentsRelative( NULL );
91             awt::Point aParentScreenLoc( aParentRect.Left(), aParentRect.Top() );
92             aBounds.X -= aParentScreenLoc.X;
93             aBounds.Y -= aParentScreenLoc.Y;
94         }
95     }
96     return aBounds;
97 }
98 
99 static awt::Point lcl_GetLocationOnScreen( Window *pWin )
100 {
101     // !! see VCLXAccessibleComponent::getLocationOnScreen()
102 
103     awt::Point aPos;
104     if (pWin)
105     {
106         Rectangle aRect = pWin->GetWindowExtentsRelative( NULL );
107         aPos.X = aRect.Left();
108         aPos.Y = aRect.Top();
109     }
110     return aPos;
111 }
112 
113 //////////////////////////////////////////////////////////////////////
114 
115 SmGraphicAccessible::SmGraphicAccessible( SmGraphicWindow *pGraphicWin ) :
116     aAccName            ( String(SmResId(RID_DOCUMENTSTR)) ),
117     nClientId           (0),
118     pWin                (pGraphicWin)
119 {
120     DBG_ASSERT( pWin, "SmGraphicAccessible: window missing" );
121     //++aRefCount;
122 }
123 
124 
125 SmGraphicAccessible::SmGraphicAccessible( const SmGraphicAccessible &rSmAcc ) :
126     SmGraphicAccessibleBaseClass(),
127     aAccName            ( String(SmResId(RID_DOCUMENTSTR)) ),
128     nClientId           (0)
129 {
130     //vos::OGuard aGuard(Application::GetSolarMutex());
131     pWin = rSmAcc.pWin;
132     DBG_ASSERT( pWin, "SmGraphicAccessible: window missing" );
133     //++aRefCount;
134 }
135 
136 
137 SmGraphicAccessible::~SmGraphicAccessible()
138 {
139 /*
140 	vos::OGuard aGuard(Application::GetSolarMutex());
141     if (--aRefCount == 0)
142     {
143     }
144 */
145 }
146 
147 
148 SmDocShell * SmGraphicAccessible::GetDoc_Impl()
149 {
150     SmViewShell *pView = pWin ? pWin->GetView() : 0;
151     return pView ? pView->GetDoc() : 0;
152 }
153 
154 String SmGraphicAccessible::GetAccessibleText_Impl()
155 {
156     String aTxt;
157     SmDocShell *pDoc = GetDoc_Impl();
158     if (pDoc)
159         aTxt = pDoc->GetAccessibleText();
160     return aTxt;
161 }
162 
163 void SmGraphicAccessible::ClearWin()
164 {
165     pWin = 0;   // implicitly results in AccessibleStateType::DEFUNC set
166 
167 	if ( nClientId )
168 	{
169         comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
170 		nClientId =  0;
171 	}
172 }
173 
174 void SmGraphicAccessible::LaunchEvent(
175         const sal_Int16 nAccesibleEventId,
176         const uno::Any &rOldVal,
177         const uno::Any &rNewVal)
178 {
179     AccessibleEventObject aEvt;
180     aEvt.Source     = (XAccessible *) this;
181     aEvt.EventId    = nAccesibleEventId;
182     aEvt.OldValue   = rOldVal;
183     aEvt.NewValue   = rNewVal ;
184 
185     // pass event on to event-listener's
186 	if (nClientId)
187 		comphelper::AccessibleEventNotifier::addEvent( nClientId, aEvt );
188 }
189 
190 uno::Reference< XAccessibleContext > SAL_CALL SmGraphicAccessible::getAccessibleContext()
191     throw (RuntimeException)
192 {
193 	vos::OGuard aGuard(Application::GetSolarMutex());
194     return this;
195 }
196 
197 sal_Bool SAL_CALL SmGraphicAccessible::containsPoint( const awt::Point& aPoint )
198     throw (RuntimeException)
199 {
200     //! the arguments coordinates are relativ to the current window !
201     //! Thus the top-left point is (0, 0)
202 
203 	vos::OGuard aGuard(Application::GetSolarMutex());
204     if (!pWin)
205         throw RuntimeException();
206 
207     Size aSz( pWin->GetSizePixel() );
208     return  aPoint.X >= 0  &&  aPoint.Y >= 0  &&
209             aPoint.X < aSz.Width()  &&  aPoint.Y < aSz.Height();
210 }
211 
212 uno::Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleAtPoint(
213         const awt::Point& aPoint )
214     throw (RuntimeException)
215 {
216 	vos::OGuard aGuard(Application::GetSolarMutex());
217     XAccessible *pRes = 0;
218     if (containsPoint( aPoint ))
219         pRes = this;
220     return pRes;
221 }
222 
223 awt::Rectangle SAL_CALL SmGraphicAccessible::getBounds()
224     throw (RuntimeException)
225 {
226 	vos::OGuard aGuard(Application::GetSolarMutex());
227     if (!pWin)
228         throw RuntimeException();
229     DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
230             "mismatch of window parent and accessible parent" );
231     return lcl_GetBounds( pWin );
232 }
233 
234 awt::Point SAL_CALL SmGraphicAccessible::getLocation()
235     throw (RuntimeException)
236 {
237 	vos::OGuard aGuard(Application::GetSolarMutex());
238     if (!pWin)
239         throw RuntimeException();
240     DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
241             "mismatch of window parent and accessible parent" );
242     awt::Rectangle aRect( lcl_GetBounds( pWin ) );
243     return awt::Point( aRect.X, aRect.Y );
244 }
245 
246 awt::Point SAL_CALL SmGraphicAccessible::getLocationOnScreen()
247     throw (RuntimeException)
248 {
249 	vos::OGuard aGuard(Application::GetSolarMutex());
250     if (!pWin)
251         throw RuntimeException();
252     DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
253             "mismatch of window parent and accessible parent" );
254     return lcl_GetLocationOnScreen( pWin );
255 }
256 
257 awt::Size SAL_CALL SmGraphicAccessible::getSize()
258     throw (RuntimeException)
259 {
260 	vos::OGuard aGuard(Application::GetSolarMutex());
261     if (!pWin)
262         throw RuntimeException();
263     DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
264             "mismatch of window parent and accessible parent" );
265 
266     Size aSz( pWin->GetSizePixel() );
267 #if OSL_DEBUG_LEVEL > 1
268     awt::Rectangle aRect( lcl_GetBounds( pWin ) );
269     Size aSz2( aRect.Width, aRect.Height );
270     DBG_ASSERT( aSz == aSz2, "mismatch in width" );
271 #endif
272     return awt::Size( aSz.Width(), aSz.Height() );
273 }
274 
275 void SAL_CALL SmGraphicAccessible::grabFocus()
276     throw (RuntimeException)
277 {
278 	vos::OGuard aGuard(Application::GetSolarMutex());
279     if (!pWin)
280         throw RuntimeException();
281 
282     pWin->GrabFocus();
283 }
284 
285 sal_Int32 SAL_CALL SmGraphicAccessible::getForeground()
286     throw (RuntimeException)
287 {
288     vos::OGuard aGuard(Application::GetSolarMutex());
289 
290     if (!pWin)
291         throw RuntimeException();
292     return (sal_Int32) pWin->GetTextColor().GetColor();
293 }
294 
295 sal_Int32 SAL_CALL SmGraphicAccessible::getBackground()
296     throw (RuntimeException)
297 {
298     vos::OGuard aGuard(Application::GetSolarMutex());
299 
300     if (!pWin)
301         throw RuntimeException();
302     Wallpaper aWall( pWin->GetDisplayBackground() );
303     ColorData nCol;
304     if (aWall.IsBitmap() || aWall.IsGradient())
305         nCol = pWin->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
306     else
307         nCol = aWall.GetColor().GetColor();
308     return (sal_Int32) nCol;
309 }
310 
311 sal_Int32 SAL_CALL SmGraphicAccessible::getAccessibleChildCount()
312     throw (RuntimeException)
313 {
314 	vos::OGuard aGuard(Application::GetSolarMutex());
315     return 0;
316 }
317 
318 Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleChild(
319         sal_Int32 /*i*/ )
320     throw (IndexOutOfBoundsException, RuntimeException)
321 {
322 	vos::OGuard aGuard(Application::GetSolarMutex());
323     throw IndexOutOfBoundsException();  // there is no child...
324     /*return 0;*/
325 }
326 
327 Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleParent()
328     throw (RuntimeException)
329 {
330 	vos::OGuard aGuard(Application::GetSolarMutex());
331     if (!pWin)
332         throw RuntimeException();
333 
334     Window *pAccParent = pWin->GetAccessibleParentWindow();
335     DBG_ASSERT( pAccParent, "accessible parent missing" );
336     return pAccParent ? pAccParent->GetAccessible() : Reference< XAccessible >();
337 }
338 
339 sal_Int32 SAL_CALL SmGraphicAccessible::getAccessibleIndexInParent()
340     throw (RuntimeException)
341 {
342 	vos::OGuard aGuard(Application::GetSolarMutex());
343     sal_Int32 nIdx = -1;
344     Window *pAccParent = pWin ? pWin->GetAccessibleParentWindow() : 0;
345     if (pAccParent)
346     {
347         sal_uInt16 nCnt = pAccParent->GetAccessibleChildWindowCount();
348         for (sal_uInt16 i = 0;  i < nCnt  &&  nIdx == -1;  ++i)
349             if (pAccParent->GetAccessibleChildWindow( i ) == pWin)
350                 nIdx = i;
351     }
352     return nIdx;
353 }
354 
355 sal_Int16 SAL_CALL SmGraphicAccessible::getAccessibleRole()
356     throw (RuntimeException)
357 {
358 	vos::OGuard aGuard(Application::GetSolarMutex());
359     return AccessibleRole::DOCUMENT;
360 }
361 
362 OUString SAL_CALL SmGraphicAccessible::getAccessibleDescription()
363     throw (RuntimeException)
364 {
365 	vos::OGuard aGuard(Application::GetSolarMutex());
366     SmDocShell *pDoc = GetDoc_Impl();
367     return pDoc ? OUString(pDoc->GetText()) : OUString();
368 }
369 
370 OUString SAL_CALL SmGraphicAccessible::getAccessibleName()
371     throw (RuntimeException)
372 {
373 	vos::OGuard aGuard(Application::GetSolarMutex());
374     return aAccName;
375 }
376 
377 Reference< XAccessibleRelationSet > SAL_CALL SmGraphicAccessible::getAccessibleRelationSet()
378     throw (RuntimeException)
379 {
380 	vos::OGuard aGuard(Application::GetSolarMutex());
381     Reference< XAccessibleRelationSet > xRelSet = new utl::AccessibleRelationSetHelper();
382     return xRelSet;   // empty relation set
383 }
384 
385 Reference< XAccessibleStateSet > SAL_CALL SmGraphicAccessible::getAccessibleStateSet()
386     throw (RuntimeException)
387 {
388 	vos::OGuard aGuard(Application::GetSolarMutex());
389 	::utl::AccessibleStateSetHelper *pStateSet =
390             new ::utl::AccessibleStateSetHelper;
391 
392 	Reference<XAccessibleStateSet> xStateSet( pStateSet );
393 
394     if (!pWin)
395         pStateSet->AddState( AccessibleStateType::DEFUNC );
396     else
397     {
398         //pStateSet->AddState( AccessibleStateType::EDITABLE );
399         //pStateSet->AddState( AccessibleStateType::HORIZONTAL );
400         //pStateSet->AddState( AccessibleStateType::TRANSIENT );
401         pStateSet->AddState( AccessibleStateType::ENABLED );
402         pStateSet->AddState( AccessibleStateType::FOCUSABLE );
403         if (pWin->HasFocus())
404             pStateSet->AddState( AccessibleStateType::FOCUSED );
405         if (pWin->IsActive())
406             pStateSet->AddState( AccessibleStateType::ACTIVE );
407         if (pWin->IsVisible())
408             pStateSet->AddState( AccessibleStateType::SHOWING );
409         if (pWin->IsReallyVisible())
410             pStateSet->AddState( AccessibleStateType::VISIBLE );
411         if (COL_TRANSPARENT != pWin->GetBackground().GetColor().GetColor())
412             pStateSet->AddState( AccessibleStateType::OPAQUE );
413     }
414 
415 	return xStateSet;
416 }
417 
418 Locale SAL_CALL SmGraphicAccessible::getLocale()
419     throw (IllegalAccessibleComponentStateException, RuntimeException)
420 {
421 	vos::OGuard aGuard(Application::GetSolarMutex());
422     // should be the document language...
423     // We use the language of the localized symbol names here.
424     return Application::GetSettings().GetUILocale();
425 }
426 
427 
428 void SAL_CALL SmGraphicAccessible::addEventListener(
429         const Reference< XAccessibleEventListener >& xListener )
430     throw (RuntimeException)
431 {
432 	if (xListener.is())
433     {
434 		vos::OGuard aGuard(Application::GetSolarMutex());
435 		if (pWin)
436 		{
437 			if (!nClientId)
438                 nClientId = comphelper::AccessibleEventNotifier::registerClient( );
439 			comphelper::AccessibleEventNotifier::addEventListener( nClientId, xListener );
440 		}
441     }
442 }
443 
444 void SAL_CALL SmGraphicAccessible::removeEventListener(
445         const Reference< XAccessibleEventListener >& xListener )
446     throw (RuntimeException)
447 {
448 	if (xListener.is())
449 	{
450 		vos::OGuard aGuard(Application::GetSolarMutex());
451 		sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( nClientId, xListener );
452 		if ( !nListenerCount )
453 		{
454 			// no listeners anymore
455 			// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
456 			// and at least to us not firing any events anymore, in case somebody calls
457 			// NotifyAccessibleEvent, again
458 			comphelper::AccessibleEventNotifier::revokeClient( nClientId );
459 			nClientId = 0;
460 		}
461 	}
462 }
463 
464 sal_Int32 SAL_CALL SmGraphicAccessible::getCaretPosition()
465     throw (RuntimeException)
466 {
467 	vos::OGuard aGuard(Application::GetSolarMutex());
468     return 0;
469 }
470 
471 sal_Bool SAL_CALL SmGraphicAccessible::setCaretPosition( sal_Int32 nIndex )
472     throw (IndexOutOfBoundsException, RuntimeException)
473 {
474     xub_StrLen nIdx = (xub_StrLen) nIndex;
475     String aTxt( GetAccessibleText_Impl() );
476     if (!(/*0 <= nIdx  &&*/  nIdx < aTxt.Len()))
477         throw IndexOutOfBoundsException();
478 	return sal_False;
479 }
480 
481 sal_Unicode SAL_CALL SmGraphicAccessible::getCharacter( sal_Int32 nIndex )
482     throw (IndexOutOfBoundsException, RuntimeException)
483 {
484 	vos::OGuard aGuard(Application::GetSolarMutex());
485 
486     xub_StrLen nIdx = (xub_StrLen) nIndex;
487     String aTxt( GetAccessibleText_Impl() );
488     if (!(/*0 <= nIdx  &&*/  nIdx < aTxt.Len()))
489         throw IndexOutOfBoundsException();
490     return aTxt.GetChar( nIdx );
491 }
492 
493 Sequence< beans::PropertyValue > SAL_CALL SmGraphicAccessible::getCharacterAttributes(
494         sal_Int32 nIndex,
495         const uno::Sequence< ::rtl::OUString > & /*rRequestedAttributes*/ )
496     throw (IndexOutOfBoundsException, RuntimeException)
497 {
498 	vos::OGuard aGuard(Application::GetSolarMutex());
499     sal_Int32 nLen = GetAccessibleText_Impl().Len();
500     if (!(0 <= nIndex  &&  nIndex < nLen))
501         throw IndexOutOfBoundsException();
502     return Sequence< beans::PropertyValue >();
503 }
504 
505 awt::Rectangle SAL_CALL SmGraphicAccessible::getCharacterBounds( sal_Int32 nIndex )
506     throw (IndexOutOfBoundsException, RuntimeException)
507 {
508 	vos::OGuard aGuard(Application::GetSolarMutex());
509 
510     awt::Rectangle aRes;
511 
512     if (!pWin)
513         throw RuntimeException();
514     else
515     {
516         // get accessible text
517         SmViewShell *pView = pWin->GetView();
518         SmDocShell  *pDoc  = pView ? pView->GetDoc() : 0;
519         if (!pDoc)
520             throw RuntimeException();
521         String aTxt( GetAccessibleText_Impl() );
522         if (!(0 <= nIndex  &&  nIndex <= aTxt.Len()))   // #108812# aTxt.Len() is valid
523             throw IndexOutOfBoundsException();
524 
525         // #108812# find a reasonable rectangle for position aTxt.Len().
526         bool bWasBehindText = (nIndex == aTxt.Len());
527         if (bWasBehindText && nIndex)
528             --nIndex;
529 
530         const SmNode *pTree = pDoc->GetFormulaTree();
531         const SmNode *pNode = pTree->FindNodeWithAccessibleIndex( (xub_StrLen) nIndex );
532         //! pNode may be 0 if the index belongs to a char that was inserted
533         //! only for the accessible text!
534         if (pNode)
535         {
536             sal_Int32 nAccIndex = pNode->GetAccessibleIndex();
537             DBG_ASSERT( nAccIndex >= 0, "invalid accessible index" );
538             DBG_ASSERT( nIndex >= nAccIndex, "index out of range" );
539 
540             String    aNodeText;
541             pNode->GetAccessibleText( aNodeText );
542             sal_Int32 nNodeIndex = nIndex - nAccIndex;
543             if (0 <= nNodeIndex  &&  nNodeIndex < aNodeText.Len())
544             {
545                 // get appropriate rectangle
546                 Point aOffset(pNode->GetTopLeft() - pTree->GetTopLeft());
547                 Point aTLPos (pWin->GetFormulaDrawPos() + aOffset);
548 //                aTLPos.X() -= pNode->GetItalicLeftSpace();
549 //                Size  aSize (pNode->GetItalicSize());
550                 aTLPos.X() -= 0;
551                 Size  aSize (pNode->GetSize());
552 
553                 sal_Int32 *pXAry = new sal_Int32[ aNodeText.Len() ];
554                 pWin->SetFont( pNode->GetFont() );
555                 pWin->GetTextArray( aNodeText, pXAry, 0, aNodeText.Len() );
556                 aTLPos.X()    += nNodeIndex > 0 ? pXAry[nNodeIndex - 1] : 0;
557                 aSize.Width()  = nNodeIndex > 0 ? pXAry[nNodeIndex] - pXAry[nNodeIndex - 1] : pXAry[nNodeIndex];
558                 delete[] pXAry;
559 
560 #if OSL_DEBUG_LEVEL > 1
561     Point aLP00( pWin->LogicToPixel( Point(0,0)) );
562     Point aPL00( pWin->PixelToLogic( Point(0,0)) );
563 #endif
564                 aTLPos = pWin->LogicToPixel( aTLPos );
565                 aSize  = pWin->LogicToPixel( aSize );
566                 aRes.X = aTLPos.X();
567                 aRes.Y = aTLPos.Y();
568                 aRes.Width  = aSize.Width();
569                 aRes.Height = aSize.Height();
570             }
571         }
572 
573         // #108812# take rectangle from last character and move it to the right
574         if (bWasBehindText)
575             aRes.X += aRes.Width;
576     }
577 
578     return aRes;
579 }
580 
581 sal_Int32 SAL_CALL SmGraphicAccessible::getCharacterCount()
582     throw (RuntimeException)
583 {
584 	vos::OGuard aGuard(Application::GetSolarMutex());
585     return GetAccessibleText_Impl().Len();
586 }
587 
588 sal_Int32 SAL_CALL SmGraphicAccessible::getIndexAtPoint( const awt::Point& aPoint )
589     throw (RuntimeException)
590 {
591 	vos::OGuard aGuard(Application::GetSolarMutex());
592 
593     sal_Int32 nRes = -1;
594     if (pWin)
595     {
596         const SmNode *pTree = pWin->GetView()->GetDoc()->GetFormulaTree();
597 		//! kann NULL sein! ZB wenn bereits beim laden des Dokuments (bevor der
598 		//! Parser angeworfen wurde) ins Fenster geklickt wird.
599 		if (!pTree)
600             return nRes;
601 
602         // get position relativ to formula draw position
603         Point  aPos( aPoint.X, aPoint.Y );
604         aPos = pWin->PixelToLogic( aPos );
605         aPos -= pWin->GetFormulaDrawPos();
606 
607         // if it was inside the formula then get the appropriate node
608 		const SmNode *pNode = 0;
609 		if (pTree->OrientedDist(aPos) <= 0)
610 			pNode = pTree->FindRectClosestTo(aPos);
611 
612         if (pNode)
613         {
614             // get appropriate rectangle
615             Point   aOffset( pNode->GetTopLeft() - pTree->GetTopLeft() );
616             Point   aTLPos ( /*pWin->GetFormulaDrawPos() +*/ aOffset );
617 //            aTLPos.X() -= pNode->GetItalicLeftSpace();
618 //            Size  aSize( pNode->GetItalicSize() );
619             aTLPos.X() -= 0;
620             Size  aSize( pNode->GetSize() );
621 #if OSL_DEBUG_LEVEL > 1
622     Point aLP00( pWin->LogicToPixel( Point(0,0)) );
623     Point aPL00( pWin->PixelToLogic( Point(0,0)) );
624 #endif
625 
626             Rectangle aRect( aTLPos, aSize );
627             if (aRect.IsInside( aPos ))
628             {
629                 DBG_ASSERT( pNode->IsVisible(), "node is not a leaf" );
630                 String aTxt;
631                 pNode->GetAccessibleText( aTxt );
632                 DBG_ASSERT( aTxt.Len(), "no accessible text available" );
633 
634                 long nNodeX = pNode->GetLeft();
635 
636                 sal_Int32 *pXAry = new sal_Int32[ aTxt.Len() ];
637                 pWin->SetFont( pNode->GetFont() );
638                 pWin->GetTextArray( aTxt, pXAry, 0, aTxt.Len() );
639                 for (sal_Int32 i = 0;  i < aTxt.Len()  &&  nRes == -1;  ++i)
640                 {
641                     if (pXAry[i] + nNodeX > aPos.X())
642                         nRes = i;
643                 }
644                 delete[] pXAry;
645                 DBG_ASSERT( nRes >= 0  &&  nRes < aTxt.Len(), "index out of range" );
646                 DBG_ASSERT( pNode->GetAccessibleIndex() >= 0,
647                         "invalid accessible index" );
648 
649                 nRes = pNode->GetAccessibleIndex() + nRes;
650             }
651 		}
652     }
653     return nRes;
654 }
655 
656 OUString SAL_CALL SmGraphicAccessible::getSelectedText()
657     throw (RuntimeException)
658 {
659 	vos::OGuard aGuard(Application::GetSolarMutex());
660     return OUString();
661 }
662 
663 sal_Int32 SAL_CALL SmGraphicAccessible::getSelectionStart()
664     throw (RuntimeException)
665 {
666 	vos::OGuard aGuard(Application::GetSolarMutex());
667     return -1;
668 }
669 
670 sal_Int32 SAL_CALL SmGraphicAccessible::getSelectionEnd()
671     throw (RuntimeException)
672 {
673 	vos::OGuard aGuard(Application::GetSolarMutex());
674     return -1;
675 }
676 
677 sal_Bool SAL_CALL SmGraphicAccessible::setSelection(
678         sal_Int32 nStartIndex,
679         sal_Int32 nEndIndex )
680     throw (IndexOutOfBoundsException, RuntimeException)
681 {
682 	vos::OGuard aGuard(Application::GetSolarMutex());
683     sal_Int32 nLen = GetAccessibleText_Impl().Len();
684     if (!(0 <= nStartIndex  &&  nStartIndex < nLen) ||
685         !(0 <= nEndIndex    &&  nEndIndex   < nLen))
686         throw IndexOutOfBoundsException();
687     return sal_False;
688 }
689 
690 OUString SAL_CALL SmGraphicAccessible::getText()
691     throw (RuntimeException)
692 {
693 	vos::OGuard aGuard(Application::GetSolarMutex());
694     return GetAccessibleText_Impl();
695 }
696 
697 OUString SAL_CALL SmGraphicAccessible::getTextRange(
698         sal_Int32 nStartIndex,
699         sal_Int32 nEndIndex )
700     throw (IndexOutOfBoundsException, RuntimeException)
701 {
702     //!! nEndIndex may be the string length per definition of the interface !!
703     //!! text should be copied exclusive that end index though. And arguments
704     //!! may be switched.
705 
706     vos::OGuard aGuard(Application::GetSolarMutex());
707     String aTxt( GetAccessibleText_Impl() );
708     xub_StrLen nStart = (xub_StrLen) Min(nStartIndex, nEndIndex);
709     xub_StrLen nEnd   = (xub_StrLen) Max(nStartIndex, nEndIndex);
710     if (!(/*0 <= nStart  &&*/  nStart <= aTxt.Len()) ||
711         !(/*0 <= nEnd    &&*/  nEnd   <= aTxt.Len()))
712         throw IndexOutOfBoundsException();
713     return aTxt.Copy( nStart, nEnd - nStart );
714 }
715 
716 ::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)
717 {
718 	vos::OGuard aGuard(Application::GetSolarMutex());
719     String aTxt( GetAccessibleText_Impl() );
720     xub_StrLen nIdx = (xub_StrLen) nIndex;
721     //!! nIndex is allowed to be the string length
722     if (!(/*0 <= nIdx  &&*/  nIdx <= aTxt.Len()))
723         throw IndexOutOfBoundsException();
724 
725     ::com::sun::star::accessibility::TextSegment aResult;
726     aResult.SegmentStart = -1;
727     aResult.SegmentEnd = -1;
728     if ( (AccessibleTextType::CHARACTER == aTextType)  &&  (nIdx < aTxt.Len()) )
729     {
730         aResult.SegmentText = aTxt.Copy(nIdx, 1);
731         aResult.SegmentStart = nIdx;
732         aResult.SegmentEnd = nIdx+1;
733     }
734     return aResult;
735 }
736 
737 ::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)
738 {
739 	vos::OGuard aGuard(Application::GetSolarMutex());
740     String aTxt( GetAccessibleText_Impl() );
741     xub_StrLen nIdx = (xub_StrLen) nIndex;
742     //!! nIndex is allowed to be the string length
743     if (!(/*0 <= nIdx  &&*/  nIdx <= aTxt.Len()))
744         throw IndexOutOfBoundsException();
745 
746     ::com::sun::star::accessibility::TextSegment aResult;
747     aResult.SegmentStart = -1;
748     aResult.SegmentEnd = -1;
749 
750     if ( (AccessibleTextType::CHARACTER == aTextType)  && nIdx )
751     {
752         aResult.SegmentText = aTxt.Copy(nIdx-1, 1);
753         aResult.SegmentStart = nIdx-1;
754         aResult.SegmentEnd = nIdx;
755     }
756     return aResult;
757 }
758 
759 ::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)
760 {
761 	vos::OGuard aGuard(Application::GetSolarMutex());
762     String aTxt( GetAccessibleText_Impl() );
763     xub_StrLen nIdx = (xub_StrLen) nIndex;
764     //!! nIndex is allowed to be the string length
765     if (!(/*0 <= nIdx  &&*/  nIdx <= aTxt.Len()))
766         throw IndexOutOfBoundsException();
767 
768     ::com::sun::star::accessibility::TextSegment aResult;
769     aResult.SegmentStart = -1;
770     aResult.SegmentEnd = -1;
771 
772     nIdx++; // text *behind*
773     if ( (AccessibleTextType::CHARACTER == aTextType)  &&  (nIdx < aTxt.Len()) )
774     {
775         aResult.SegmentText = aTxt.Copy(nIdx, 1);
776         aResult.SegmentStart = nIdx;
777         aResult.SegmentEnd = nIdx+1;
778     }
779     return aResult;
780 }
781 
782 sal_Bool SAL_CALL SmGraphicAccessible::copyText(
783         sal_Int32 nStartIndex,
784         sal_Int32 nEndIndex )
785     throw (IndexOutOfBoundsException, RuntimeException)
786 {
787 	vos::OGuard aGuard(Application::GetSolarMutex());
788 	sal_Bool bReturn = sal_False;
789 
790     if (!pWin)
791         throw RuntimeException();
792     else
793 	{
794         Reference< datatransfer::clipboard::XClipboard > xClipboard = pWin->GetClipboard();
795 		if ( xClipboard.is() )
796 		{
797             ::rtl::OUString sText( getTextRange(nStartIndex, nEndIndex) );
798 
799 			::vcl::unohelper::TextDataObject* pDataObj = new ::vcl::unohelper::TextDataObject( sText );
800 			const sal_uInt32 nRef = Application::ReleaseSolarMutex();
801 			xClipboard->setContents( pDataObj, NULL );
802 
803 			Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY );
804 			if( xFlushableClipboard.is() )
805 				xFlushableClipboard->flushClipboard();
806 
807 			Application::AcquireSolarMutex( nRef );
808 
809 			bReturn = sal_True;
810 		}
811 	}
812 
813     return bReturn;
814 }
815 
816 OUString SAL_CALL SmGraphicAccessible::getImplementationName()
817     throw (RuntimeException)
818 {
819     //vos::OGuard aGuard(Application::GetSolarMutex());
820     return A2OU("SmGraphicAccessible");
821 }
822 
823 sal_Bool SAL_CALL SmGraphicAccessible::supportsService(
824         const OUString& rServiceName )
825     throw (RuntimeException)
826 {
827     //vos::OGuard aGuard(Application::GetSolarMutex());
828     return  rServiceName == A2OU( "com::sun::star::accessibility::Accessible" ) ||
829             rServiceName == A2OU( "com::sun::star::accessibility::AccessibleComponent" ) ||
830             rServiceName == A2OU( "com::sun::star::accessibility::AccessibleContext" ) ||
831             rServiceName == A2OU( "com::sun::star::accessibility::AccessibleText" );
832 }
833 
834 Sequence< OUString > SAL_CALL SmGraphicAccessible::getSupportedServiceNames()
835     throw (RuntimeException)
836 {
837     //vos::OGuard aGuard(Application::GetSolarMutex());
838     Sequence< OUString > aNames(4);
839     OUString *pNames = aNames.getArray();
840     pNames[0] = A2OU( "com::sun::star::accessibility::Accessible" );
841     pNames[1] = A2OU( "com::sun::star::accessibility::AccessibleComponent" );
842     pNames[2] = A2OU( "com::sun::star::accessibility::AccessibleContext" );
843     pNames[3] = A2OU( "com::sun::star::accessibility::AccessibleText" );
844     return aNames;
845 }
846 
847 //////////////////////////////////////////////////////////////////////
848 
849 //------------------------------------------------------------------------
850 
851 SmEditSource::SmEditSource( SmEditWindow * /*pWin*/, SmEditAccessible &rAcc ) :
852     aViewFwd    (rAcc),
853     aTextFwd    (rAcc, *this),
854     aEditViewFwd(rAcc),
855     rEditAcc (rAcc)
856 {
857 }
858 
859 SmEditSource::SmEditSource( const SmEditSource &rSrc ) :
860     SvxEditSource(),
861     aViewFwd    (rSrc.rEditAcc),
862     aTextFwd    (rSrc.rEditAcc, *this),
863     aEditViewFwd(rSrc.rEditAcc),
864     rEditAcc	(rSrc.rEditAcc)
865 {
866     //aBroadCaster;     can be completely new
867 }
868 
869 SmEditSource::~SmEditSource()
870 {
871 }
872 
873 SvxEditSource* SmEditSource::Clone() const
874 {
875     return new SmEditSource( *this );
876 }
877 
878 SvxTextForwarder* SmEditSource::GetTextForwarder()
879 {
880     return &aTextFwd;
881 }
882 
883 SvxViewForwarder* SmEditSource::GetViewForwarder()
884 {
885     return &aViewFwd;
886 }
887 
888 SvxEditViewForwarder* SmEditSource::GetEditViewForwarder( sal_Bool /*bCreate*/ )
889 {
890     return &aEditViewFwd;
891 }
892 
893 void SmEditSource::UpdateData()
894 {
895     // would possibly only by needed if the XText inteface is implemented
896     // and its text needs to be updated.
897 }
898 
899 SfxBroadcaster & SmEditSource::GetBroadcaster() const
900 {
901     return ((SmEditSource *) this)->aBroadCaster;
902 }
903 
904 //------------------------------------------------------------------------
905 
906 SmViewForwarder::SmViewForwarder( SmEditAccessible &rAcc ) :
907     rEditAcc(rAcc)
908 {
909 }
910 
911 SmViewForwarder::~SmViewForwarder()
912 {
913 }
914 
915 sal_Bool SmViewForwarder::IsValid() const
916 {
917     return rEditAcc.GetEditView() != 0;
918 }
919 
920 Rectangle SmViewForwarder::GetVisArea() const
921 {
922 	EditView *pEditView = rEditAcc.GetEditView();
923 	OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
924 
925     if( pOutDev && pEditView)
926     {
927         Rectangle aVisArea = pEditView->GetVisArea();
928 
929         // figure out map mode from edit engine
930         EditEngine* pEditEngine = pEditView->GetEditEngine();
931 
932         if( pEditEngine )
933         {
934             MapMode aMapMode(pOutDev->GetMapMode());
935             aVisArea = OutputDevice::LogicToLogic( aVisArea,
936                                                    pEditEngine->GetRefMapMode(),
937                                                    aMapMode.GetMapUnit() );
938             aMapMode.SetOrigin(Point());
939             return pOutDev->LogicToPixel( aVisArea, aMapMode );
940         }
941     }
942 
943     return Rectangle();
944 }
945 
946 Point SmViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
947 {
948 	EditView *pEditView = rEditAcc.GetEditView();
949 	OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
950 
951     if( pOutDev )
952     {
953         MapMode aMapMode(pOutDev->GetMapMode());
954         Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
955                                                   aMapMode.GetMapUnit() ) );
956         aMapMode.SetOrigin(Point());
957         return pOutDev->LogicToPixel( aPoint, aMapMode );
958     }
959 
960     return Point();
961 }
962 
963 Point SmViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
964 {
965 	EditView *pEditView = rEditAcc.GetEditView();
966 	OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
967 
968     if( pOutDev )
969     {
970         MapMode aMapMode(pOutDev->GetMapMode());
971         aMapMode.SetOrigin(Point());
972         Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
973         return OutputDevice::LogicToLogic( aPoint,
974                                            aMapMode.GetMapUnit(),
975                                            rMapMode );
976     }
977 
978     return Point();
979 }
980 
981 
982 //------------------------------------------------------------------------
983 
984 SmTextForwarder::SmTextForwarder( SmEditAccessible& rAcc, SmEditSource & rSource) :
985     rEditAcc ( rAcc ),
986     rEditSource (rSource)
987 {
988 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
989 	if (pEditEngine)
990 		pEditEngine->SetNotifyHdl( LINK(this, SmTextForwarder, NotifyHdl) );
991 }
992 
993 SmTextForwarder::~SmTextForwarder()
994 {
995     EditEngine *pEditEngine = rEditAcc.GetEditEngine();
996     if (pEditEngine)
997         pEditEngine->SetNotifyHdl( Link() );
998 }
999 
1000 IMPL_LINK(SmTextForwarder, NotifyHdl, EENotify*, aNotify)
1001 {
1002     if (aNotify)
1003     {
1004         ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify );
1005         if (aHint.get())
1006             rEditSource.GetBroadcaster().Broadcast( *aHint.get() );
1007     }
1008 
1009     return 0;
1010 }
1011 
1012 sal_uInt32 SmTextForwarder::GetParagraphCount() const
1013 {
1014 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1015 	return pEditEngine ? pEditEngine->GetParagraphCount() : 0;
1016 }
1017 
1018 sal_uInt16 SmTextForwarder::GetTextLen( sal_uInt32 nParagraph ) const
1019 {
1020 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1021 	return pEditEngine ? pEditEngine->GetTextLen( nParagraph ) : 0;
1022 }
1023 
1024 String SmTextForwarder::GetText( const ESelection& rSel ) const
1025 {
1026 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1027 	String aRet;
1028 	if (pEditEngine)
1029 		aRet = pEditEngine->GetText( rSel, LINEEND_LF );
1030 	aRet.ConvertLineEnd();
1031 	return aRet;
1032 }
1033 
1034 SfxItemSet SmTextForwarder::GetAttribs( const ESelection& rSel, sal_Bool bOnlyHardAttrib ) const
1035 {
1036 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1037 	DBG_ASSERT( pEditEngine, "EditEngine missing" );
1038 	if( rSel.nStartPara == rSel.nEndPara )
1039 	{
1040 		sal_uInt8 nFlags = 0;
1041 		switch( bOnlyHardAttrib )
1042 		{
1043 		case EditEngineAttribs_All:
1044 			nFlags = GETATTRIBS_ALL;
1045 			break;
1046 		case EditEngineAttribs_HardAndPara:
1047 			nFlags = GETATTRIBS_PARAATTRIBS|GETATTRIBS_CHARATTRIBS;
1048 			break;
1049 		case EditEngineAttribs_OnlyHard:
1050 			nFlags = GETATTRIBS_CHARATTRIBS;
1051 			break;
1052 		default:
1053             DBG_ERROR("unknown flags for SmTextForwarder::GetAttribs");
1054 		}
1055 
1056 		return pEditEngine->GetAttribs( rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags );
1057 	}
1058 	else
1059 	{
1060 		return pEditEngine->GetAttribs( rSel, bOnlyHardAttrib );
1061 	}
1062 }
1063 
1064 SfxItemSet SmTextForwarder::GetParaAttribs( sal_uInt32 nPara ) const
1065 {
1066 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1067 	DBG_ASSERT( pEditEngine, "EditEngine missing" );
1068 
1069 	SfxItemSet aSet( pEditEngine->GetParaAttribs( nPara ) );
1070 
1071 	sal_uInt16 nWhich = EE_PARA_START;
1072 	while( nWhich <= EE_PARA_END )
1073 	{
1074 		if( aSet.GetItemState( nWhich, sal_True ) != SFX_ITEM_ON )
1075 		{
1076 			if( pEditEngine->HasParaAttrib( nPara, nWhich ) )
1077 				aSet.Put( pEditEngine->GetParaAttrib( nPara, nWhich ) );
1078 		}
1079 		nWhich++;
1080 	}
1081 
1082 	return aSet;
1083 }
1084 
1085 void SmTextForwarder::SetParaAttribs( sal_uInt32 nPara, const SfxItemSet& rSet )
1086 {
1087 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1088 	if (pEditEngine)
1089 		pEditEngine->SetParaAttribs( nPara, rSet );
1090 }
1091 
1092 SfxItemPool* SmTextForwarder::GetPool() const
1093 {
1094 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1095 	return pEditEngine ? pEditEngine->GetEmptyItemSet().GetPool() : 0;
1096 }
1097 
1098 void SmTextForwarder::RemoveAttribs( const ESelection& rSelection, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich )
1099 {
1100     EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1101     if (pEditEngine)
1102         pEditEngine->RemoveAttribs( rSelection, bRemoveParaAttribs, nWhich );
1103 }
1104 
1105 void SmTextForwarder::GetPortions( sal_uInt32 nPara, SvUShorts& rList ) const
1106 {
1107 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1108 	if (pEditEngine)
1109 		pEditEngine->GetPortions( nPara, rList );
1110 }
1111 
1112 void SmTextForwarder::QuickInsertText( const String& rText, const ESelection& rSel )
1113 {
1114 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1115 	if (pEditEngine)
1116 		pEditEngine->QuickInsertText( rText, rSel );
1117 }
1118 
1119 void SmTextForwarder::QuickInsertLineBreak( const ESelection& rSel )
1120 {
1121 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1122 	if (pEditEngine)
1123 		pEditEngine->QuickInsertLineBreak( rSel );
1124 }
1125 
1126 void SmTextForwarder::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
1127 {
1128 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1129 	if (pEditEngine)
1130 		pEditEngine->QuickInsertField( rFld, rSel );
1131 }
1132 
1133 void SmTextForwarder::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
1134 {
1135 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1136 	if (pEditEngine)
1137 		pEditEngine->QuickSetAttribs( rSet, rSel );
1138 }
1139 
1140 sal_Bool SmTextForwarder::IsValid() const
1141 {
1142 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1143     // cannot reliably query EditEngine state
1144     // while in the middle of an update
1145 	return pEditEngine ? pEditEngine->GetUpdateMode() : sal_False;
1146 }
1147 
1148 XubString SmTextForwarder::CalcFieldValue( const SvxFieldItem& rField, sal_uInt32 nPara, sal_uInt16 nPos, Color*& rpTxtColor, Color*& rpFldColor )
1149 {
1150 	XubString aTxt;
1151 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1152 	if (pEditEngine)
1153 		aTxt = pEditEngine->CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
1154 	return aTxt;
1155 }
1156 
1157 void SmTextForwarder::FieldClicked(const SvxFieldItem&, sal_uInt32, sal_uInt16)
1158 {
1159 }
1160 
1161 sal_uInt16 GetSvxEditEngineItemState( EditEngine& rEditEngine, const ESelection& rSel, sal_uInt16 nWhich )
1162 {
1163 	EECharAttribArray aAttribs;
1164 
1165 	const SfxPoolItem*	pLastItem = NULL;
1166 
1167 	SfxItemState eState = SFX_ITEM_DEFAULT;
1168 
1169 	// check all paragraphs inside the selection
1170 	for( sal_uInt32 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++ )
1171 	{
1172 		SfxItemState eParaState = SFX_ITEM_DEFAULT;
1173 
1174 		// calculate start and endpos for this paragraph
1175 		sal_uInt16 nPos = 0;
1176 		if( rSel.nStartPara == nPara )
1177 			nPos = rSel.nStartPos;
1178 
1179 		sal_uInt16 nEndPos = rSel.nEndPos;
1180 		if( rSel.nEndPara != nPara )
1181 			nEndPos = rEditEngine.GetTextLen( nPara );
1182 
1183 
1184 		// get list of char attribs
1185 		rEditEngine.GetCharAttribs( nPara, aAttribs );
1186 
1187 		sal_Bool bEmpty = sal_True;		// we found no item inside the selektion of this paragraph
1188 		sal_Bool bGaps  = sal_False;	// we found items but theire gaps between them
1189 		sal_uInt16 nLastEnd = nPos;
1190 
1191 		const SfxPoolItem* pParaItem = NULL;
1192 
1193 		for( sal_uInt16 nAttrib = 0; nAttrib < aAttribs.Count(); nAttrib++ )
1194 		{
1195 			struct EECharAttrib aAttrib = aAttribs.GetObject( nAttrib );
1196 			DBG_ASSERT( aAttrib.pAttr, "GetCharAttribs gives corrupt data" );
1197 
1198 			const sal_Bool bEmptyPortion = aAttrib.nStart == aAttrib.nEnd;
1199 			if( (!bEmptyPortion && (aAttrib.nStart >= nEndPos)) || (bEmptyPortion && (aAttrib.nStart > nEndPos)) )
1200 				break;	// break if we are already behind our selektion
1201 
1202 			if( (!bEmptyPortion && (aAttrib.nEnd <= nPos)) || (bEmptyPortion && (aAttrib.nEnd < nPos)) )
1203 				continue;	// or if the attribute ends before our selektion
1204 
1205 			if( aAttrib.pAttr->Which() != nWhich )
1206 				continue; // skip if is not the searched item
1207 
1208 			// if we already found an item
1209 			if( pParaItem )
1210 			{
1211 				// ... and its different to this one than the state is dont care
1212 				if( *pParaItem != *aAttrib.pAttr )
1213 					return SFX_ITEM_DONTCARE;
1214 			}
1215 			else
1216 			{
1217 				pParaItem = aAttrib.pAttr;
1218 			}
1219 
1220 			if( bEmpty )
1221 				bEmpty = sal_False;
1222 
1223 			if( !bGaps && aAttrib.nStart > nLastEnd )
1224 				bGaps = sal_True;
1225 
1226 			nLastEnd = aAttrib.nEnd;
1227 		}
1228 
1229 		if( !bEmpty && !bGaps && nLastEnd < ( nEndPos - 1 ) )
1230 			bGaps = sal_True;
1231 /*
1232 		// since we have no portion with our item or if there were gaps
1233 		if( bEmpty || bGaps )
1234 		{
1235 			// we need to check the paragraph item
1236 			const SfxItemSet& rParaSet = rEditEngine.GetParaAttribs( nPara );
1237 			if( rParaSet.GetItemState( nWhich ) == SFX_ITEM_SET )
1238 			{
1239 				eState = SFX_ITEM_SET;
1240 				// get item from the paragraph
1241 				const SfxPoolItem* pTempItem = rParaSet.GetItem( nWhich );
1242 				if( pParaItem )
1243 				{
1244 					if( *pParaItem != *pTempItem )
1245 						return SFX_ITEM_DONTCARE;
1246 				}
1247 				else
1248 				{
1249 					pParaItem = pTempItem;
1250 				}
1251 
1252 				// set if theres no last item or if its the same
1253 				eParaState = SFX_ITEM_SET;
1254 			}
1255 			else if( bEmpty )
1256 			{
1257 				eParaState = SFX_ITEM_DEFAULT;
1258 			}
1259 			else if( bGaps )
1260 			{
1261 				// gaps and item not set in paragraph, that's a dont care
1262 				return SFX_ITEM_DONTCARE;
1263 			}
1264 		}
1265 		else
1266 		{
1267 			eParaState = SFX_ITEM_SET;
1268 		}
1269 */
1270 		if( bEmpty )
1271 			eParaState = SFX_ITEM_DEFAULT;
1272 		else if( bGaps )
1273 			eParaState = SFX_ITEM_DONTCARE;
1274 		else
1275 			eParaState = SFX_ITEM_SET;
1276 
1277 		// if we already found an item check if we found the same
1278 		if( pLastItem )
1279 		{
1280 			if( (pParaItem == NULL) || (*pLastItem != *pParaItem) )
1281 				return SFX_ITEM_DONTCARE;
1282 		}
1283 		else
1284 		{
1285 			pLastItem = pParaItem;
1286 			eState = eParaState;
1287 		}
1288 	}
1289 
1290 	return eState;
1291 }
1292 
1293 sal_uInt16 SmTextForwarder::GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const
1294 {
1295 	sal_uInt16 nState = SFX_ITEM_DISABLED;
1296 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1297 	if (pEditEngine)
1298 		nState = GetSvxEditEngineItemState( *pEditEngine, rSel, nWhich );
1299 	return nState;
1300 }
1301 
1302 sal_uInt16 SmTextForwarder::GetItemState( sal_uInt16 nPara, sal_uInt16 nWhich ) const
1303 {
1304 	sal_uInt16 nState = SFX_ITEM_DISABLED;
1305 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1306 	if (pEditEngine)
1307 	{
1308 		const SfxItemSet& rSet = pEditEngine->GetParaAttribs( nPara );
1309 		nState = rSet.GetItemState( nWhich );
1310 	}
1311 	return nState;
1312 }
1313 
1314 LanguageType SmTextForwarder::GetLanguage( sal_uInt16 nPara, sal_uInt16 nIndex ) const
1315 {
1316 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1317 	return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex) : LANGUAGE_NONE;
1318 }
1319 
1320 sal_uInt16 SmTextForwarder::GetFieldCount( sal_uInt32 nPara ) const
1321 {
1322 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1323 	return pEditEngine ? pEditEngine->GetFieldCount(nPara) : 0;
1324 }
1325 
1326 EFieldInfo SmTextForwarder::GetFieldInfo( sal_uInt32 nPara, sal_uInt16 nField ) const
1327 {
1328 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1329 	return pEditEngine ? pEditEngine->GetFieldInfo( nPara, nField ) : EFieldInfo();
1330 }
1331 
1332 EBulletInfo SmTextForwarder::GetBulletInfo( sal_uInt16 /*nPara*/ ) const
1333 {
1334     return EBulletInfo();
1335 }
1336 
1337 Rectangle SmTextForwarder::GetCharBounds( sal_uInt16 nPara, sal_uInt16 nIndex ) const
1338 {
1339 	Rectangle aRect(0,0,0,0);
1340 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1341 
1342 	if (pEditEngine)
1343 	{
1344 		// #108900# Handle virtual position one-past-the end of the string
1345 		if( nIndex >= pEditEngine->GetTextLen(nPara) )
1346 		{
1347 			if( nIndex )
1348 				aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex-1) );
1349 
1350 			aRect.Move( aRect.Right() - aRect.Left(), 0 );
1351 			aRect.SetSize( Size(1, pEditEngine->GetTextHeight()) );
1352 		}
1353 		else
1354 		{
1355 			aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex) );
1356 	    }
1357 	}
1358 	return aRect;
1359 }
1360 
1361 Rectangle SmTextForwarder::GetParaBounds( sal_uInt16 nPara ) const
1362 {
1363 	Rectangle aRect(0,0,0,0);
1364 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1365 
1366 	if (pEditEngine)
1367 	{
1368 		const Point aPnt = pEditEngine->GetDocPosTopLeft( nPara );
1369 		const sal_uLong nWidth = pEditEngine->CalcTextWidth();
1370 		const sal_uLong nHeight = pEditEngine->GetTextHeight( nPara );
1371 		aRect = Rectangle( aPnt.X(), aPnt.Y(), aPnt.X() + nWidth, aPnt.Y() + nHeight );
1372 	}
1373 
1374     return aRect;
1375 }
1376 
1377 MapMode SmTextForwarder::GetMapMode() const
1378 {
1379 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1380 	return pEditEngine ? pEditEngine->GetRefMapMode() : MapMode( MAP_100TH_MM );
1381 }
1382 
1383 OutputDevice* SmTextForwarder::GetRefDevice() const
1384 {
1385 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1386 	return pEditEngine ? pEditEngine->GetRefDevice() : 0;
1387 }
1388 
1389 sal_Bool SmTextForwarder::GetIndexAtPoint( const Point& rPos, sal_uInt16& nPara, sal_uInt16& nIndex ) const
1390 {
1391 	sal_Bool bRes = sal_False;
1392 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1393 	if (pEditEngine)
1394 	{
1395 		EPosition aDocPos = pEditEngine->FindDocPosition( rPos );
1396 		nPara	= aDocPos.nPara;
1397 		nIndex	= aDocPos.nIndex;
1398 		bRes = sal_True;
1399 	}
1400 	return bRes;
1401 }
1402 
1403 sal_Bool SmTextForwarder::GetWordIndices( sal_uInt16 nPara, sal_uInt16 nIndex, sal_uInt16& nStart, sal_uInt16& nEnd ) const
1404 {
1405 	sal_Bool bRes = sal_False;
1406 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1407 	if (pEditEngine)
1408 	{
1409 		ESelection aRes = pEditEngine->GetWord( ESelection(nPara, nIndex, nPara, nIndex), com::sun::star::i18n::WordType::DICTIONARY_WORD );
1410 
1411 		if( aRes.nStartPara == nPara &&
1412 			aRes.nStartPara == aRes.nEndPara )
1413 		{
1414 			nStart = aRes.nStartPos;
1415 			nEnd = aRes.nEndPos;
1416 
1417 			bRes = sal_True;
1418 	    }
1419 	}
1420 
1421     return bRes;
1422 }
1423 
1424 sal_Bool SmTextForwarder::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_uInt32 nPara, sal_uInt16 nIndex, sal_Bool bInCell ) const
1425 {
1426 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1427     return pEditEngine ?
1428 		SvxEditSourceHelper::GetAttributeRun( nStartIndex, nEndIndex, *pEditEngine, nPara, nIndex, bInCell )
1429 		: sal_False;
1430 }
1431 
1432 sal_uInt16 SmTextForwarder::GetLineCount( sal_uInt16 nPara ) const
1433 {
1434 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1435 	return pEditEngine ? pEditEngine->GetLineCount(nPara) : 0;
1436 }
1437 
1438 sal_uInt16 SmTextForwarder::GetLineLen( sal_uInt16 nPara, sal_uInt16 nLine ) const
1439 {
1440 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1441 	return pEditEngine ? pEditEngine->GetLineLen(nPara, nLine) : 0;
1442 }
1443 
1444 void SmTextForwarder::GetLineBoundaries( /*out*/sal_uInt16 &rStart, /*out*/sal_uInt16 &rEnd, sal_uInt16 nPara, sal_uInt16 nLine ) const
1445 {
1446     EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1447     pEditEngine->GetLineBoundaries(rStart, rEnd, nPara, nLine);
1448 }
1449 
1450 sal_uInt16 SmTextForwarder::GetLineNumberAtIndex( sal_uInt16 nPara, sal_uInt16 nIndex ) const
1451 {
1452     EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1453     return pEditEngine ? pEditEngine->GetLineNumberAtIndex(nPara, nIndex) : 0;
1454 }
1455 
1456 sal_Bool SmTextForwarder::QuickFormatDoc( sal_Bool /*bFull*/ )
1457 {
1458 	sal_Bool bRes = sal_False;
1459 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1460 	if (pEditEngine)
1461 	{
1462 		pEditEngine->QuickFormatDoc();
1463 		bRes = sal_True;
1464 	}
1465     return bRes;
1466 }
1467 
1468 sal_Int16 SmTextForwarder::GetDepth( sal_uInt16 /*nPara*/ ) const
1469 {
1470     // math has no outliner...
1471     return -1;
1472 }
1473 
1474 sal_Bool SmTextForwarder::SetDepth( sal_uInt16 /*nPara*/, sal_Int16 nNewDepth )
1475 {
1476     // math has no outliner...
1477     return -1 == nNewDepth;  // is it the value from 'GetDepth' ?
1478 }
1479 
1480 sal_Bool SmTextForwarder::Delete( const ESelection& rSelection )
1481 {
1482 	sal_Bool bRes = sal_False;
1483 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1484 	if (pEditEngine)
1485 	{
1486 		pEditEngine->QuickDelete( rSelection );
1487 		pEditEngine->QuickFormatDoc();
1488 		bRes = sal_True;
1489 	}
1490 	return bRes;
1491 }
1492 
1493 sal_Bool SmTextForwarder::InsertText( const String& rStr, const ESelection& rSelection )
1494 {
1495 	sal_Bool bRes = sal_False;
1496 	EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1497 	if (pEditEngine)
1498 	{
1499 		pEditEngine->QuickInsertText( rStr, rSelection );
1500 		pEditEngine->QuickFormatDoc();
1501 		bRes = sal_True;
1502 	}
1503 	return bRes;
1504 }
1505 
1506 const SfxItemSet*   SmTextForwarder::GetEmptyItemSetPtr()
1507 {
1508     const SfxItemSet *pItemSet = 0;
1509     EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1510     if (pEditEngine)
1511     {
1512         pItemSet = &pEditEngine->GetEmptyItemSet();
1513     }
1514     return pItemSet;
1515 }
1516 
1517 void SmTextForwarder::AppendParagraph()
1518 {
1519     // append an empty paragraph
1520     EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1521     if (pEditEngine)
1522     {
1523         sal_uInt32 nParaCount = pEditEngine->GetParagraphCount();
1524         pEditEngine->InsertParagraph( nParaCount, String() );
1525     }
1526 }
1527 
1528 xub_StrLen SmTextForwarder::AppendTextPortion( sal_uInt16 nPara, const String &rText, const SfxItemSet &rSet )
1529 {
1530     xub_StrLen nRes = 0;
1531     EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1532     if (pEditEngine && nPara < pEditEngine->GetParagraphCount())
1533     {
1534         // append text
1535         ESelection aSel( nPara, pEditEngine->GetTextLen( nPara ) );
1536         pEditEngine->QuickInsertText( rText, aSel );
1537 
1538         // set attributes for new appended text
1539         nRes = aSel.nEndPos = pEditEngine->GetTextLen( nPara );
1540         pEditEngine->QuickSetAttribs( rSet, aSel );
1541     }
1542     return nRes;
1543 }
1544 
1545 void SmTextForwarder::CopyText(const SvxTextForwarder& rSource)
1546 {
1547 
1548     const SmTextForwarder* pSourceForwarder = dynamic_cast< const SmTextForwarder* >( &rSource );
1549     if( !pSourceForwarder )
1550         return;
1551     EditEngine* pSourceEditEngine = pSourceForwarder->rEditAcc.GetEditEngine();
1552     EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1553     if (pEditEngine && pSourceEditEngine )
1554     {
1555         EditTextObject* pNewTextObject = pSourceEditEngine->CreateTextObject();
1556         pEditEngine->SetText( *pNewTextObject );
1557         delete pNewTextObject;
1558     }
1559 }
1560 
1561 //------------------------------------------------------------------------
1562 
1563 SmEditViewForwarder::SmEditViewForwarder( SmEditAccessible& rAcc ) :
1564     rEditAcc( rAcc )
1565 {
1566 }
1567 
1568 SmEditViewForwarder::~SmEditViewForwarder()
1569 {
1570 }
1571 
1572 sal_Bool SmEditViewForwarder::IsValid() const
1573 {
1574     return rEditAcc.GetEditView() != 0;
1575 }
1576 
1577 Rectangle SmEditViewForwarder::GetVisArea() const
1578 {
1579 	Rectangle aRect(0,0,0,0);
1580 
1581 	EditView *pEditView = rEditAcc.GetEditView();
1582 	OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
1583 
1584     if( pOutDev && pEditView)
1585     {
1586         Rectangle aVisArea = pEditView->GetVisArea();
1587 
1588         // figure out map mode from edit engine
1589         EditEngine* pEditEngine = pEditView->GetEditEngine();
1590 
1591         if( pEditEngine )
1592         {
1593             MapMode aMapMode(pOutDev->GetMapMode());
1594             aVisArea = OutputDevice::LogicToLogic( aVisArea,
1595                                                    pEditEngine->GetRefMapMode(),
1596                                                    aMapMode.GetMapUnit() );
1597             aMapMode.SetOrigin(Point());
1598             aRect = pOutDev->LogicToPixel( aVisArea, aMapMode );
1599         }
1600     }
1601 
1602     return aRect;
1603 }
1604 
1605 Point SmEditViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
1606 {
1607 	EditView *pEditView = rEditAcc.GetEditView();
1608 	OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
1609 
1610     if( pOutDev )
1611     {
1612         MapMode aMapMode(pOutDev->GetMapMode());
1613         Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
1614                                                   aMapMode.GetMapUnit() ) );
1615         aMapMode.SetOrigin(Point());
1616         return pOutDev->LogicToPixel( aPoint, aMapMode );
1617     }
1618 
1619     return Point();
1620 }
1621 
1622 Point SmEditViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
1623 {
1624 	EditView *pEditView = rEditAcc.GetEditView();
1625 	OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
1626 
1627     if( pOutDev )
1628     {
1629         MapMode aMapMode(pOutDev->GetMapMode());
1630         aMapMode.SetOrigin(Point());
1631         Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
1632         return OutputDevice::LogicToLogic( aPoint,
1633                                            aMapMode.GetMapUnit(),
1634                                            rMapMode );
1635     }
1636 
1637     return Point();
1638 }
1639 
1640 sal_Bool SmEditViewForwarder::GetSelection( ESelection& rSelection ) const
1641 {
1642 	sal_Bool bRes = sal_False;
1643 	EditView *pEditView = rEditAcc.GetEditView();
1644 	if (pEditView)
1645 	{
1646 		rSelection = pEditView->GetSelection();
1647 		bRes = sal_True;
1648 	}
1649     return bRes;
1650 }
1651 
1652 sal_Bool SmEditViewForwarder::SetSelection( const ESelection& rSelection )
1653 {
1654 	sal_Bool bRes = sal_False;
1655 	EditView *pEditView = rEditAcc.GetEditView();
1656 	if (pEditView)
1657 	{
1658 		pEditView->SetSelection( rSelection );
1659 		bRes = sal_True;
1660 	}
1661 	return bRes;
1662 }
1663 
1664 sal_Bool SmEditViewForwarder::Copy()
1665 {
1666 	sal_Bool bRes = sal_False;
1667 	EditView *pEditView = rEditAcc.GetEditView();
1668 	if (pEditView)
1669 	{
1670 		pEditView->Copy();
1671 		bRes = sal_True;
1672 	}
1673 	return bRes;
1674 }
1675 
1676 sal_Bool SmEditViewForwarder::Cut()
1677 {
1678 	sal_Bool bRes = sal_False;
1679 	EditView *pEditView = rEditAcc.GetEditView();
1680 	if (pEditView)
1681 	{
1682 		pEditView->Cut();
1683 		bRes = sal_True;
1684 	}
1685 	return bRes;
1686 }
1687 
1688 sal_Bool SmEditViewForwarder::Paste()
1689 {
1690 	sal_Bool bRes = sal_False;
1691 	EditView *pEditView = rEditAcc.GetEditView();
1692 	if (pEditView)
1693 	{
1694 		pEditView->Paste();
1695 		bRes = sal_True;
1696 	}
1697 	return bRes;
1698 }
1699 
1700 //------------------------------------------------------------------------
1701 
1702 SmEditAccessible::SmEditAccessible( SmEditWindow *pEditWin ) :
1703     aAccName            ( String(SmResId(STR_CMDBOXWINDOW)) ),
1704     pTextHelper         (0),
1705     pWin                (pEditWin)
1706 {
1707     DBG_ASSERT( pWin, "SmEditAccessible: window missing" );
1708     //++aRefCount;
1709 }
1710 
1711 
1712 SmEditAccessible::SmEditAccessible( const SmEditAccessible &rSmAcc ) :
1713     SmEditAccessibleBaseClass(),
1714     aAccName            ( String(SmResId(STR_CMDBOXWINDOW)) )
1715 {
1716     //vos::OGuard aGuard(Application::GetSolarMutex());
1717     pWin = rSmAcc.pWin;
1718     DBG_ASSERT( pWin, "SmEditAccessible: window missing" );
1719     //++aRefCount;
1720 }
1721 
1722 SmEditAccessible::~SmEditAccessible()
1723 {
1724     delete pTextHelper;
1725 /*
1726 	vos::OGuard aGuard(Application::GetSolarMutex());
1727     if (--aRefCount == 0)
1728     {
1729     }
1730 */
1731 }
1732 
1733 void SmEditAccessible::Init()
1734 {
1735     DBG_ASSERT( pWin, "SmEditAccessible: window missing" );
1736     if (pWin)
1737     {
1738         EditEngine *pEditEngine = pWin->GetEditEngine();
1739         EditView   *pEditView   = pWin->GetEditView();
1740         if (pEditEngine && pEditView)
1741         {
1742             ::std::auto_ptr< SvxEditSource > pEditSource(
1743                     new SmEditSource( pWin, *this ) );
1744             pTextHelper = new ::accessibility::AccessibleTextHelper( pEditSource );
1745             pTextHelper->SetEventSource( this );
1746         }
1747     }
1748 }
1749 
1750 #ifdef TL_NOT_YET_USED
1751 SmDocShell * SmEditAccessible::GetDoc_Impl()
1752 {
1753     SmViewShell *pView = pWin ? pWin->GetView() : 0;
1754     return pView ? pView->GetDoc() : 0;
1755 }
1756 #endif // TL_NOT_YET_USED
1757 
1758 void SmEditAccessible::ClearWin()
1759 {
1760 	// #112565# remove handler before current object gets destroyed
1761 	// (avoid handler being called for already dead object)
1762 	EditEngine *pEditEngine = GetEditEngine();
1763 	if (pEditEngine)
1764 		pEditEngine->SetNotifyHdl( Link() );
1765 
1766 	pWin = 0;   // implicitly results in AccessibleStateType::DEFUNC set
1767 
1768     //! make TextHelper implicitly release C++ references to some core objects
1769     pTextHelper->SetEditSource( ::std::auto_ptr<SvxEditSource>(NULL) );
1770     //! make TextHelper release references
1771     //! (e.g. the one set by the 'SetEventSource' call)
1772     pTextHelper->Dispose();
1773     delete pTextHelper;     pTextHelper = 0;
1774 }
1775 
1776 // XAccessible
1777 uno::Reference< XAccessibleContext > SAL_CALL SmEditAccessible::getAccessibleContext(  )
1778     throw (RuntimeException)
1779 {
1780 	vos::OGuard aGuard(Application::GetSolarMutex());
1781     return this;
1782 }
1783 
1784 // XAccessibleComponent
1785 sal_Bool SAL_CALL SmEditAccessible::containsPoint( const awt::Point& aPoint )
1786     throw (RuntimeException)
1787 {
1788     //! the arguments coordinates are relativ to the current window !
1789     //! Thus the top left-point is (0, 0)
1790 
1791 	vos::OGuard aGuard(Application::GetSolarMutex());
1792     if (!pWin)
1793         throw RuntimeException();
1794 
1795     Size aSz( pWin->GetSizePixel() );
1796     return  aPoint.X >= 0  &&  aPoint.Y >= 0  &&
1797             aPoint.X < aSz.Width()  &&  aPoint.Y < aSz.Height();
1798 }
1799 
1800 uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleAtPoint( const awt::Point& aPoint )
1801     throw (RuntimeException)
1802 {
1803 	vos::OGuard aGuard(Application::GetSolarMutex());
1804     if (!pTextHelper)
1805         throw RuntimeException();
1806     return pTextHelper->GetAt( aPoint );
1807 }
1808 
1809 awt::Rectangle SAL_CALL SmEditAccessible::getBounds(  )
1810     throw (RuntimeException)
1811 {
1812 	vos::OGuard aGuard(Application::GetSolarMutex());
1813     if (!pWin)
1814         throw RuntimeException();
1815     DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
1816             "mismatch of window parent and accessible parent" );
1817     return lcl_GetBounds( pWin );
1818 }
1819 
1820 awt::Point SAL_CALL SmEditAccessible::getLocation(  )
1821     throw (RuntimeException)
1822 {
1823 	vos::OGuard aGuard(Application::GetSolarMutex());
1824     if (!pWin)
1825         throw RuntimeException();
1826     DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
1827             "mismatch of window parent and accessible parent" );
1828     awt::Rectangle aRect( lcl_GetBounds( pWin ) );
1829     return awt::Point( aRect.X, aRect.Y );
1830 }
1831 
1832 awt::Point SAL_CALL SmEditAccessible::getLocationOnScreen(  )
1833     throw (RuntimeException)
1834 {
1835     vos::OGuard aGuard(Application::GetSolarMutex());
1836     if (!pWin)
1837         throw RuntimeException();
1838     DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
1839             "mismatch of window parent and accessible parent" );
1840     return lcl_GetLocationOnScreen( pWin );
1841 }
1842 
1843 awt::Size SAL_CALL SmEditAccessible::getSize(  )
1844     throw (RuntimeException)
1845 {
1846 	vos::OGuard aGuard(Application::GetSolarMutex());
1847     if (!pWin)
1848         throw RuntimeException();
1849     DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
1850             "mismatch of window parent and accessible parent" );
1851 
1852     Size aSz( pWin->GetSizePixel() );
1853 #if OSL_DEBUG_LEVEL > 1
1854     awt::Rectangle aRect( lcl_GetBounds( pWin ) );
1855     Size aSz2( aRect.Width, aRect.Height );
1856     DBG_ASSERT( aSz == aSz2, "mismatch in width" );
1857 #endif
1858     return awt::Size( aSz.Width(), aSz.Height() );
1859 }
1860 
1861 void SAL_CALL SmEditAccessible::grabFocus(  )
1862     throw (RuntimeException)
1863 {
1864 	vos::OGuard aGuard(Application::GetSolarMutex());
1865     if (!pWin)
1866         throw RuntimeException();
1867 
1868     pWin->GrabFocus();
1869 }
1870 
1871 sal_Int32 SAL_CALL SmEditAccessible::getForeground()
1872     throw (RuntimeException)
1873 {
1874     vos::OGuard aGuard(Application::GetSolarMutex());
1875 
1876     if (!pWin)
1877         throw RuntimeException();
1878     return (sal_Int32) pWin->GetTextColor().GetColor();
1879 }
1880 
1881 sal_Int32 SAL_CALL SmEditAccessible::getBackground()
1882     throw (RuntimeException)
1883 {
1884     vos::OGuard aGuard(Application::GetSolarMutex());
1885 
1886     if (!pWin)
1887         throw RuntimeException();
1888     Wallpaper aWall( pWin->GetDisplayBackground() );
1889     ColorData nCol;
1890     if (aWall.IsBitmap() || aWall.IsGradient())
1891         nCol = pWin->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
1892     else
1893         nCol = aWall.GetColor().GetColor();
1894     return (sal_Int32) nCol;
1895 }
1896 
1897 // XAccessibleContext
1898 sal_Int32 SAL_CALL SmEditAccessible::getAccessibleChildCount(  )
1899     throw (RuntimeException)
1900 {
1901 	vos::OGuard aGuard(Application::GetSolarMutex());
1902     if (!pTextHelper)
1903         throw RuntimeException();
1904     return pTextHelper->GetChildCount();
1905 }
1906 
1907 uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleChild( sal_Int32 i )
1908     throw (IndexOutOfBoundsException, RuntimeException)
1909 {
1910     vos::OGuard aGuard(Application::GetSolarMutex());
1911     if (!pTextHelper)
1912         throw RuntimeException();
1913     return pTextHelper->GetChild( i );
1914 }
1915 
1916 uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleParent(  )
1917     throw (RuntimeException)
1918 {
1919 	vos::OGuard aGuard(Application::GetSolarMutex());
1920     if (!pWin)
1921         throw RuntimeException();
1922 
1923     Window *pAccParent = pWin->GetAccessibleParentWindow();
1924     DBG_ASSERT( pAccParent, "accessible parent missing" );
1925     return pAccParent ? pAccParent->GetAccessible() : Reference< XAccessible >();
1926 }
1927 
1928 sal_Int32 SAL_CALL SmEditAccessible::getAccessibleIndexInParent(  )
1929     throw (RuntimeException)
1930 {
1931 	vos::OGuard aGuard(Application::GetSolarMutex());
1932     sal_Int32 nIdx = -1;
1933     Window *pAccParent = pWin ? pWin->GetAccessibleParentWindow() : 0;
1934     if (pAccParent)
1935     {
1936         sal_uInt16 nCnt = pAccParent->GetAccessibleChildWindowCount();
1937         for (sal_uInt16 i = 0;  i < nCnt  &&  nIdx == -1;  ++i)
1938             if (pAccParent->GetAccessibleChildWindow( i ) == pWin)
1939                 nIdx = i;
1940     }
1941     return nIdx;
1942 }
1943 
1944 sal_Int16 SAL_CALL SmEditAccessible::getAccessibleRole(  )
1945     throw (RuntimeException)
1946 {
1947 	vos::OGuard aGuard(Application::GetSolarMutex());
1948     return AccessibleRole::PANEL /*TEXT ?*/;
1949 }
1950 
1951 rtl::OUString SAL_CALL SmEditAccessible::getAccessibleDescription(  )
1952     throw (RuntimeException)
1953 {
1954 	vos::OGuard aGuard(Application::GetSolarMutex());
1955     return OUString();  // empty as agreed with product-management
1956 }
1957 
1958 rtl::OUString SAL_CALL SmEditAccessible::getAccessibleName(  )
1959     throw (RuntimeException)
1960 {
1961 	vos::OGuard aGuard(Application::GetSolarMutex());
1962     // same name as displayed by the window when not docked
1963     return aAccName;
1964 }
1965 
1966 uno::Reference< XAccessibleRelationSet > SAL_CALL SmEditAccessible::getAccessibleRelationSet(  )
1967     throw (RuntimeException)
1968 {
1969 	vos::OGuard aGuard(Application::GetSolarMutex());
1970     Reference< XAccessibleRelationSet > xRelSet = new utl::AccessibleRelationSetHelper();
1971     return xRelSet;   // empty relation set
1972 }
1973 
1974 uno::Reference< XAccessibleStateSet > SAL_CALL SmEditAccessible::getAccessibleStateSet(  )
1975     throw (RuntimeException)
1976 {
1977 	vos::OGuard aGuard(Application::GetSolarMutex());
1978 	::utl::AccessibleStateSetHelper *pStateSet =
1979             new ::utl::AccessibleStateSetHelper;
1980 
1981 	Reference<XAccessibleStateSet> xStateSet( pStateSet );
1982 
1983     if (!pWin || !pTextHelper)
1984         pStateSet->AddState( AccessibleStateType::DEFUNC );
1985     else
1986     {
1987         //pStateSet->AddState( AccessibleStateType::EDITABLE );
1988         pStateSet->AddState( AccessibleStateType::MULTI_LINE );
1989         //pStateSet->AddState( AccessibleStateType::HORIZONTAL );
1990         //pStateSet->AddState( AccessibleStateType::TRANSIENT );
1991         pStateSet->AddState( AccessibleStateType::ENABLED );
1992         pStateSet->AddState( AccessibleStateType::FOCUSABLE );
1993         if (pWin->HasFocus())
1994             pStateSet->AddState( AccessibleStateType::FOCUSED );
1995         if (pWin->IsActive())
1996             pStateSet->AddState( AccessibleStateType::ACTIVE );
1997         if (pWin->IsVisible())
1998             pStateSet->AddState( AccessibleStateType::SHOWING );
1999         if (pWin->IsReallyVisible())
2000             pStateSet->AddState( AccessibleStateType::VISIBLE );
2001         if (COL_TRANSPARENT != pWin->GetBackground().GetColor().GetColor())
2002             pStateSet->AddState( AccessibleStateType::OPAQUE );
2003     }
2004 
2005 	return xStateSet;
2006 }
2007 
2008 Locale SAL_CALL SmEditAccessible::getLocale(  )
2009     throw (IllegalAccessibleComponentStateException, RuntimeException)
2010 {
2011 	vos::OGuard aGuard(Application::GetSolarMutex());
2012     // should be the document language...
2013     // We use the language of the localized symbol names here.
2014     return Application::GetSettings().GetUILocale();
2015 }
2016 
2017 
2018 // XAccessibleEventBroadcaster
2019 void SAL_CALL SmEditAccessible::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
2020     throw (RuntimeException)
2021 {
2022     //vos::OGuard aGuard(Application::GetSolarMutex());   if (pTextHelper)   // not disposing (about to destroy view shell)
2023         pTextHelper->AddEventListener( xListener );
2024 }
2025 
2026 void SAL_CALL SmEditAccessible::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
2027     throw (RuntimeException)
2028 {
2029     //vos::OGuard aGuard(Application::GetSolarMutex());
2030    if (pTextHelper)   // not disposing (about to destroy view shell)
2031         pTextHelper->RemoveEventListener( xListener );
2032 }
2033 
2034 OUString SAL_CALL SmEditAccessible::getImplementationName()
2035     throw (RuntimeException)
2036 {
2037     //vos::OGuard aGuard(Application::GetSolarMutex());
2038     return A2OU("SmEditAccessible");
2039 }
2040 
2041 sal_Bool SAL_CALL SmEditAccessible::supportsService(
2042         const OUString& rServiceName )
2043     throw (RuntimeException)
2044 {
2045     //vos::OGuard aGuard(Application::GetSolarMutex());
2046     return  rServiceName == A2OU( "com::sun::star::accessibility::Accessible" ) ||
2047             rServiceName == A2OU( "com::sun::star::accessibility::AccessibleComponent" ) ||
2048             rServiceName == A2OU( "com::sun::star::accessibility::AccessibleContext" );
2049 }
2050 
2051 Sequence< OUString > SAL_CALL SmEditAccessible::getSupportedServiceNames()
2052     throw (RuntimeException)
2053 {
2054     //vos::OGuard aGuard(Application::GetSolarMutex());
2055     Sequence< OUString > aNames(3);
2056     OUString *pNames = aNames.getArray();
2057     pNames[0] = A2OU( "com::sun::star::accessibility::Accessible" );
2058     pNames[1] = A2OU( "com::sun::star::accessibility::AccessibleComponent" );
2059     pNames[2] = A2OU( "com::sun::star::accessibility::AccessibleContext" );
2060     return aNames;
2061 }
2062 
2063 //////////////////////////////////////////////////////////////////////
2064 
2065