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