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