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
lcl_GetBounds(Window * pWin)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
lcl_GetLocationOnScreen(Window * pWin)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
SmGraphicAccessible(SmGraphicWindow * pGraphicWin)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
SmGraphicAccessible(const SmGraphicAccessible & rSmAcc)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
~SmGraphicAccessible()137 SmGraphicAccessible::~SmGraphicAccessible()
138 {
139 /*
140 vos::OGuard aGuard(Application::GetSolarMutex());
141 if (--aRefCount == 0)
142 {
143 }
144 */
145 }
146
147
GetDoc_Impl()148 SmDocShell * SmGraphicAccessible::GetDoc_Impl()
149 {
150 SmViewShell *pView = pWin ? pWin->GetView() : 0;
151 return pView ? pView->GetDoc() : 0;
152 }
153
GetAccessibleText_Impl()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
ClearWin()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
LaunchEvent(const sal_Int16 nAccesibleEventId,const uno::Any & rOldVal,const uno::Any & rNewVal)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
getAccessibleContext()190 uno::Reference< XAccessibleContext > SAL_CALL SmGraphicAccessible::getAccessibleContext()
191 throw (RuntimeException)
192 {
193 vos::OGuard aGuard(Application::GetSolarMutex());
194 return this;
195 }
196
containsPoint(const awt::Point & aPoint)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
getAccessibleAtPoint(const awt::Point & aPoint)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
getBounds()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
getLocation()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
getLocationOnScreen()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
getSize()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
grabFocus()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
getForeground()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
getBackground()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
getAccessibleChildCount()311 sal_Int32 SAL_CALL SmGraphicAccessible::getAccessibleChildCount()
312 throw (RuntimeException)
313 {
314 vos::OGuard aGuard(Application::GetSolarMutex());
315 return 0;
316 }
317
getAccessibleChild(sal_Int32)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
getAccessibleParent()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
getAccessibleIndexInParent()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
getAccessibleRole()355 sal_Int16 SAL_CALL SmGraphicAccessible::getAccessibleRole()
356 throw (RuntimeException)
357 {
358 vos::OGuard aGuard(Application::GetSolarMutex());
359 return AccessibleRole::DOCUMENT;
360 }
361
getAccessibleDescription()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
getAccessibleName()370 OUString SAL_CALL SmGraphicAccessible::getAccessibleName()
371 throw (RuntimeException)
372 {
373 vos::OGuard aGuard(Application::GetSolarMutex());
374 return aAccName;
375 }
376
getAccessibleRelationSet()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
getAccessibleStateSet()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
getLocale()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
addEventListener(const Reference<XAccessibleEventListener> & xListener)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
removeEventListener(const Reference<XAccessibleEventListener> & xListener)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
getCaretPosition()464 sal_Int32 SAL_CALL SmGraphicAccessible::getCaretPosition()
465 throw (RuntimeException)
466 {
467 vos::OGuard aGuard(Application::GetSolarMutex());
468 return 0;
469 }
470
setCaretPosition(sal_Int32 nIndex)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
getCharacter(sal_Int32 nIndex)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
getCharacterAttributes(sal_Int32 nIndex,const uno::Sequence<::rtl::OUString> &)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
getCharacterBounds(sal_Int32 nIndex)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
getCharacterCount()581 sal_Int32 SAL_CALL SmGraphicAccessible::getCharacterCount()
582 throw (RuntimeException)
583 {
584 vos::OGuard aGuard(Application::GetSolarMutex());
585 return GetAccessibleText_Impl().Len();
586 }
587
getIndexAtPoint(const awt::Point & aPoint)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
getSelectedText()656 OUString SAL_CALL SmGraphicAccessible::getSelectedText()
657 throw (RuntimeException)
658 {
659 vos::OGuard aGuard(Application::GetSolarMutex());
660 return OUString();
661 }
662
getSelectionStart()663 sal_Int32 SAL_CALL SmGraphicAccessible::getSelectionStart()
664 throw (RuntimeException)
665 {
666 vos::OGuard aGuard(Application::GetSolarMutex());
667 return -1;
668 }
669
getSelectionEnd()670 sal_Int32 SAL_CALL SmGraphicAccessible::getSelectionEnd()
671 throw (RuntimeException)
672 {
673 vos::OGuard aGuard(Application::GetSolarMutex());
674 return -1;
675 }
676
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)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
getText()690 OUString SAL_CALL SmGraphicAccessible::getText()
691 throw (RuntimeException)
692 {
693 vos::OGuard aGuard(Application::GetSolarMutex());
694 return GetAccessibleText_Impl();
695 }
696
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)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
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)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
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)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
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)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
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)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
getImplementationName()816 OUString SAL_CALL SmGraphicAccessible::getImplementationName()
817 throw (RuntimeException)
818 {
819 //vos::OGuard aGuard(Application::GetSolarMutex());
820 return A2OU("SmGraphicAccessible");
821 }
822
supportsService(const OUString & rServiceName)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
getSupportedServiceNames()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
SmEditSource(SmEditWindow *,SmEditAccessible & rAcc)851 SmEditSource::SmEditSource( SmEditWindow * /*pWin*/, SmEditAccessible &rAcc ) :
852 aViewFwd (rAcc),
853 aTextFwd (rAcc, *this),
854 aEditViewFwd(rAcc),
855 rEditAcc (rAcc)
856 {
857 }
858
SmEditSource(const SmEditSource & rSrc)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
~SmEditSource()869 SmEditSource::~SmEditSource()
870 {
871 }
872
Clone() const873 SvxEditSource* SmEditSource::Clone() const
874 {
875 return new SmEditSource( *this );
876 }
877
GetTextForwarder()878 SvxTextForwarder* SmEditSource::GetTextForwarder()
879 {
880 return &aTextFwd;
881 }
882
GetViewForwarder()883 SvxViewForwarder* SmEditSource::GetViewForwarder()
884 {
885 return &aViewFwd;
886 }
887
GetEditViewForwarder(sal_Bool)888 SvxEditViewForwarder* SmEditSource::GetEditViewForwarder( sal_Bool /*bCreate*/ )
889 {
890 return &aEditViewFwd;
891 }
892
UpdateData()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
GetBroadcaster() const899 SfxBroadcaster & SmEditSource::GetBroadcaster() const
900 {
901 return ((SmEditSource *) this)->aBroadCaster;
902 }
903
904 //------------------------------------------------------------------------
905
SmViewForwarder(SmEditAccessible & rAcc)906 SmViewForwarder::SmViewForwarder( SmEditAccessible &rAcc ) :
907 rEditAcc(rAcc)
908 {
909 }
910
~SmViewForwarder()911 SmViewForwarder::~SmViewForwarder()
912 {
913 }
914
IsValid() const915 sal_Bool SmViewForwarder::IsValid() const
916 {
917 return rEditAcc.GetEditView() != 0;
918 }
919
GetVisArea() const920 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
LogicToPixel(const Point & rPoint,const MapMode & rMapMode) const946 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
PixelToLogic(const Point & rPoint,const MapMode & rMapMode) const963 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
SmTextForwarder(SmEditAccessible & rAcc,SmEditSource & rSource)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
~SmTextForwarder()993 SmTextForwarder::~SmTextForwarder()
994 {
995 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
996 if (pEditEngine)
997 pEditEngine->SetNotifyHdl( Link() );
998 }
999
IMPL_LINK(SmTextForwarder,NotifyHdl,EENotify *,aNotify)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
GetParagraphCount() const1012 sal_uInt32 SmTextForwarder::GetParagraphCount() const
1013 {
1014 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1015 return pEditEngine ? pEditEngine->GetParagraphCount() : 0;
1016 }
1017
GetTextLen(sal_uInt32 nParagraph) const1018 sal_uInt16 SmTextForwarder::GetTextLen( sal_uInt32 nParagraph ) const
1019 {
1020 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1021 return pEditEngine ? pEditEngine->GetTextLen( nParagraph ) : 0;
1022 }
1023
GetText(const ESelection & rSel) const1024 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
GetAttribs(const ESelection & rSel,sal_Bool bOnlyHardAttrib) const1034 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
GetParaAttribs(sal_uInt32 nPara) const1064 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
SetParaAttribs(sal_uInt32 nPara,const SfxItemSet & rSet)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
GetPool() const1092 SfxItemPool* SmTextForwarder::GetPool() const
1093 {
1094 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1095 return pEditEngine ? pEditEngine->GetEmptyItemSet().GetPool() : 0;
1096 }
1097
RemoveAttribs(const ESelection & rSelection,sal_Bool bRemoveParaAttribs,sal_uInt16 nWhich)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
GetPortions(sal_uInt32 nPara,SvUShorts & rList) const1105 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
QuickInsertText(const String & rText,const ESelection & rSel)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
QuickInsertLineBreak(const ESelection & rSel)1119 void SmTextForwarder::QuickInsertLineBreak( const ESelection& rSel )
1120 {
1121 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1122 if (pEditEngine)
1123 pEditEngine->QuickInsertLineBreak( rSel );
1124 }
1125
QuickInsertField(const SvxFieldItem & rFld,const ESelection & rSel)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
QuickSetAttribs(const SfxItemSet & rSet,const ESelection & rSel)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
IsValid() const1140 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
CalcFieldValue(const SvxFieldItem & rField,sal_uInt32 nPara,sal_uInt16 nPos,Color * & rpTxtColor,Color * & rpFldColor)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
FieldClicked(const SvxFieldItem &,sal_uInt32,sal_uInt16)1157 void SmTextForwarder::FieldClicked(const SvxFieldItem&, sal_uInt32, sal_uInt16)
1158 {
1159 }
1160
GetSvxEditEngineItemState(EditEngine & rEditEngine,const ESelection & rSel,sal_uInt16 nWhich)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
GetItemState(const ESelection & rSel,sal_uInt16 nWhich) const1293 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
GetItemState(sal_uInt32 nPara,sal_uInt16 nWhich) const1302 sal_uInt16 SmTextForwarder::GetItemState( sal_uInt32 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
GetLanguage(sal_uInt32 nPara,sal_uInt16 nIndex) const1314 LanguageType SmTextForwarder::GetLanguage( sal_uInt32 nPara, sal_uInt16 nIndex ) const
1315 {
1316 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1317 return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex) : LANGUAGE_NONE;
1318 }
1319
GetFieldCount(sal_uInt32 nPara) const1320 sal_uInt16 SmTextForwarder::GetFieldCount( sal_uInt32 nPara ) const
1321 {
1322 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1323 return pEditEngine ? pEditEngine->GetFieldCount(nPara) : 0;
1324 }
1325
GetFieldInfo(sal_uInt32 nPara,sal_uInt16 nField) const1326 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
GetBulletInfo(sal_uInt32) const1332 EBulletInfo SmTextForwarder::GetBulletInfo( sal_uInt32 /*nPara*/ ) const
1333 {
1334 return EBulletInfo();
1335 }
1336
GetCharBounds(sal_uInt32 nPara,sal_uInt16 nIndex) const1337 Rectangle SmTextForwarder::GetCharBounds( sal_uInt32 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
GetParaBounds(sal_uInt32 nPara) const1361 Rectangle SmTextForwarder::GetParaBounds( sal_uInt32 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
GetMapMode() const1377 MapMode SmTextForwarder::GetMapMode() const
1378 {
1379 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1380 return pEditEngine ? pEditEngine->GetRefMapMode() : MapMode( MAP_100TH_MM );
1381 }
1382
GetRefDevice() const1383 OutputDevice* SmTextForwarder::GetRefDevice() const
1384 {
1385 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1386 return pEditEngine ? pEditEngine->GetRefDevice() : 0;
1387 }
1388
GetIndexAtPoint(const Point & rPos,sal_uInt32 & nPara,sal_uInt16 & nIndex) const1389 sal_Bool SmTextForwarder::GetIndexAtPoint( const Point& rPos, sal_uInt32& 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
GetWordIndices(sal_uInt32 nPara,sal_uInt16 nIndex,sal_uInt16 & nStart,sal_uInt16 & nEnd) const1403 sal_Bool SmTextForwarder::GetWordIndices( sal_uInt32 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
GetAttributeRun(sal_uInt16 & nStartIndex,sal_uInt16 & nEndIndex,sal_uInt32 nPara,sal_uInt16 nIndex,sal_Bool bInCell) const1424 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
GetLineCount(sal_uInt32 nPara) const1432 sal_uInt16 SmTextForwarder::GetLineCount( sal_uInt32 nPara ) const
1433 {
1434 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1435 return pEditEngine ? pEditEngine->GetLineCount(nPara) : 0;
1436 }
1437
GetLineLen(sal_uInt32 nPara,sal_uInt16 nLine) const1438 sal_uInt16 SmTextForwarder::GetLineLen( sal_uInt32 nPara, sal_uInt16 nLine ) const
1439 {
1440 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1441 return pEditEngine ? pEditEngine->GetLineLen(nPara, nLine) : 0;
1442 }
1443
GetLineBoundaries(sal_uInt16 & rStart,sal_uInt16 & rEnd,sal_uInt32 nPara,sal_uInt16 nLine) const1444 void SmTextForwarder::GetLineBoundaries( /*out*/sal_uInt16 &rStart, /*out*/sal_uInt16 &rEnd, sal_uInt32 nPara, sal_uInt16 nLine ) const
1445 {
1446 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1447 pEditEngine->GetLineBoundaries(rStart, rEnd, nPara, nLine);
1448 }
1449
GetLineNumberAtIndex(sal_uInt32 nPara,sal_uInt16 nIndex) const1450 sal_uInt16 SmTextForwarder::GetLineNumberAtIndex( sal_uInt32 nPara, sal_uInt16 nIndex ) const
1451 {
1452 EditEngine *pEditEngine = rEditAcc.GetEditEngine();
1453 return pEditEngine ? pEditEngine->GetLineNumberAtIndex(nPara, nIndex) : 0;
1454 }
1455
QuickFormatDoc(sal_Bool)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
GetDepth(sal_uInt32) const1468 sal_Int16 SmTextForwarder::GetDepth( sal_uInt32 /*nPara*/ ) const
1469 {
1470 // math has no outliner...
1471 return -1;
1472 }
1473
SetDepth(sal_uInt32,sal_Int16 nNewDepth)1474 sal_Bool SmTextForwarder::SetDepth( sal_uInt32 /*nPara*/, sal_Int16 nNewDepth )
1475 {
1476 // math has no outliner...
1477 return -1 == nNewDepth; // is it the value from 'GetDepth' ?
1478 }
1479
Delete(const ESelection & rSelection)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
InsertText(const String & rStr,const ESelection & rSelection)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
GetEmptyItemSetPtr()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
AppendParagraph()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
AppendTextPortion(sal_uInt32 nPara,const String & rText,const SfxItemSet & rSet)1528 xub_StrLen SmTextForwarder::AppendTextPortion( sal_uInt32 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
CopyText(const SvxTextForwarder & rSource)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
SmEditViewForwarder(SmEditAccessible & rAcc)1563 SmEditViewForwarder::SmEditViewForwarder( SmEditAccessible& rAcc ) :
1564 rEditAcc( rAcc )
1565 {
1566 }
1567
~SmEditViewForwarder()1568 SmEditViewForwarder::~SmEditViewForwarder()
1569 {
1570 }
1571
IsValid() const1572 sal_Bool SmEditViewForwarder::IsValid() const
1573 {
1574 return rEditAcc.GetEditView() != 0;
1575 }
1576
GetVisArea() const1577 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
LogicToPixel(const Point & rPoint,const MapMode & rMapMode) const1605 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
PixelToLogic(const Point & rPoint,const MapMode & rMapMode) const1622 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
GetSelection(ESelection & rSelection) const1640 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
SetSelection(const ESelection & rSelection)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
Copy()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
Cut()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
Paste()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
SmEditAccessible(SmEditWindow * pEditWin)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
SmEditAccessible(const SmEditAccessible & rSmAcc)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
~SmEditAccessible()1722 SmEditAccessible::~SmEditAccessible()
1723 {
1724 delete pTextHelper;
1725 /*
1726 vos::OGuard aGuard(Application::GetSolarMutex());
1727 if (--aRefCount == 0)
1728 {
1729 }
1730 */
1731 }
1732
Init()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
GetDoc_Impl()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
ClearWin()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
getAccessibleContext()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
containsPoint(const awt::Point & aPoint)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
getAccessibleAtPoint(const awt::Point & aPoint)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
getBounds()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
getLocation()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
getLocationOnScreen()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
getSize()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
grabFocus()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
getForeground()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
getBackground()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
getAccessibleChildCount()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
getAccessibleChild(sal_Int32 i)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
getAccessibleParent()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
getAccessibleIndexInParent()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
getAccessibleRole()1944 sal_Int16 SAL_CALL SmEditAccessible::getAccessibleRole( )
1945 throw (RuntimeException)
1946 {
1947 vos::OGuard aGuard(Application::GetSolarMutex());
1948 return AccessibleRole::PANEL /*TEXT ?*/;
1949 }
1950
getAccessibleDescription()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
getAccessibleName()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
getAccessibleRelationSet()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
getAccessibleStateSet()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
getLocale()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
addEventListener(const uno::Reference<XAccessibleEventListener> & xListener)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
removeEventListener(const uno::Reference<XAccessibleEventListener> & xListener)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
getImplementationName()2034 OUString SAL_CALL SmEditAccessible::getImplementationName()
2035 throw (RuntimeException)
2036 {
2037 //vos::OGuard aGuard(Application::GetSolarMutex());
2038 return A2OU("SmEditAccessible");
2039 }
2040
supportsService(const OUString & rServiceName)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
getSupportedServiceNames()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