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