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