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