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 <vcl/window.hxx>
21 : #include <rootfrm.hxx>
22 :
23 : #include <com/sun/star/accessibility/AccessibleRole.hpp>
24 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
25 : #include <com/sun/star/beans/XPropertyChangeListener.hpp>
26 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
27 : #include <unotools/accessiblestatesethelper.hxx>
28 : #include <sfx2/viewsh.hxx>
29 : #include <osl/mutex.hxx>
30 : #include <vcl/svapp.hxx>
31 : #include <comphelper/servicehelper.hxx>
32 : #include <cppuhelper/supportsservice.hxx>
33 : #include <viewsh.hxx>
34 : #include <doc.hxx>
35 : #include <accmap.hxx>
36 : #include <accdoc.hxx>
37 : #include "access.hrc"
38 : #include <pagefrm.hxx>
39 :
40 : #include <editeng/brushitem.hxx>
41 : #include <swatrset.hxx>
42 : #include <frmatr.hxx>
43 : #include "unostyle.hxx"
44 : #include "docsh.hxx"
45 : #include <crsrsh.hxx>
46 : #include "fesh.hxx"
47 : #include <fmtclds.hxx>
48 : #include <flyfrm.hxx>
49 : #include <colfrm.hxx>
50 : #include <txtfrm.hxx>
51 : #include <sectfrm.hxx>
52 : #include <section.hxx>
53 : #include <svx/unoapi.hxx>
54 : #include <swmodule.hxx>
55 : #include <svtools/colorcfg.hxx>
56 :
57 : #include <fmtanchr.hxx>
58 : #include <viewimp.hxx>
59 : #include <dview.hxx>
60 : #include <dcontact.hxx>
61 : #include <svx/svdmark.hxx>
62 : const sal_Char sServiceName[] = "com.sun.star.text.AccessibleTextDocumentView";
63 : const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleDocumentView";
64 :
65 : using namespace ::com::sun::star;
66 : using namespace ::com::sun::star::accessibility;
67 :
68 : using lang::IndexOutOfBoundsException;
69 :
70 : // SwAccessibleDocumentBase: base class for SwAccessibleDocument and
71 : // SwAccessiblePreview
72 :
73 24 : SwAccessibleDocumentBase::SwAccessibleDocumentBase ( SwAccessibleMap *_pMap ) :
74 : SwAccessibleContext( _pMap, AccessibleRole::DOCUMENT_TEXT,
75 24 : _pMap->GetShell()->GetLayout() ),
76 : mxParent( _pMap->GetShell()->GetWin()->GetAccessibleParentWindow()->GetAccessible() ),
77 24 : mpChildWin( 0 )
78 : {
79 24 : }
80 :
81 24 : SwAccessibleDocumentBase::~SwAccessibleDocumentBase()
82 : {
83 24 : }
84 :
85 46 : void SwAccessibleDocumentBase::SetVisArea()
86 : {
87 46 : SolarMutexGuard aGuard;
88 :
89 46 : SwRect aOldVisArea( GetVisArea() );
90 46 : const SwRect& rNewVisArea = GetMap()->GetVisArea();
91 46 : if( aOldVisArea != rNewVisArea )
92 : {
93 46 : SwAccessibleFrame::SetVisArea( GetMap()->GetVisArea() );
94 : // #i58139# - showing state of document view needs also be updated.
95 : // Thus, call method <Scrolled(..)> instead of <ChildrenScrolled(..)>
96 : // ChildrenScrolled( GetFrm(), aOldVisArea );
97 46 : Scrolled( aOldVisArea );
98 46 : }
99 46 : }
100 :
101 0 : void SwAccessibleDocumentBase::AddChild( vcl::Window *pWin, bool bFireEvent )
102 : {
103 0 : SolarMutexGuard aGuard;
104 :
105 : OSL_ENSURE( !mpChildWin, "only one child window is supported" );
106 0 : if( !mpChildWin )
107 : {
108 0 : mpChildWin = pWin;
109 :
110 0 : if( bFireEvent )
111 : {
112 0 : AccessibleEventObject aEvent;
113 0 : aEvent.EventId = AccessibleEventId::CHILD;
114 0 : aEvent.NewValue <<= mpChildWin->GetAccessible();
115 0 : FireAccessibleEvent( aEvent );
116 : }
117 0 : }
118 0 : }
119 :
120 0 : void SwAccessibleDocumentBase::RemoveChild( vcl::Window *pWin )
121 : {
122 0 : SolarMutexGuard aGuard;
123 :
124 : OSL_ENSURE( !mpChildWin || pWin == mpChildWin, "invalid child window to remove" );
125 0 : if( mpChildWin && pWin == mpChildWin )
126 : {
127 0 : AccessibleEventObject aEvent;
128 0 : aEvent.EventId = AccessibleEventId::CHILD;
129 0 : aEvent.OldValue <<= mpChildWin->GetAccessible();
130 0 : FireAccessibleEvent( aEvent );
131 :
132 0 : mpChildWin = 0;
133 0 : }
134 0 : }
135 :
136 68 : sal_Int32 SAL_CALL SwAccessibleDocumentBase::getAccessibleChildCount( void )
137 : throw (uno::RuntimeException, std::exception)
138 : {
139 68 : SolarMutexGuard aGuard;
140 :
141 : // CHECK_FOR_DEFUNC is called by parent
142 :
143 68 : sal_Int32 nChildren = SwAccessibleContext::getAccessibleChildCount();
144 68 : if( !IsDisposing() && mpChildWin )
145 0 : nChildren++;
146 :
147 68 : return nChildren;
148 : }
149 :
150 : uno::Reference< XAccessible> SAL_CALL
151 40 : SwAccessibleDocumentBase::getAccessibleChild( sal_Int32 nIndex )
152 : throw (uno::RuntimeException,
153 : lang::IndexOutOfBoundsException, std::exception)
154 : {
155 40 : SolarMutexGuard aGuard;
156 :
157 40 : if( mpChildWin )
158 : {
159 0 : CHECK_FOR_DEFUNC( XAccessibleContext )
160 0 : if ( nIndex == GetChildCount( *(GetMap()) ) )
161 : {
162 0 : return mpChildWin->GetAccessible();
163 : }
164 : }
165 :
166 40 : return SwAccessibleContext::getAccessibleChild( nIndex );
167 : }
168 :
169 28 : uno::Reference< XAccessible> SAL_CALL SwAccessibleDocumentBase::getAccessibleParent (void)
170 : throw (uno::RuntimeException, std::exception)
171 : {
172 28 : return mxParent;
173 : }
174 :
175 0 : sal_Int32 SAL_CALL SwAccessibleDocumentBase::getAccessibleIndexInParent (void)
176 : throw (uno::RuntimeException, std::exception)
177 : {
178 0 : SolarMutexGuard aGuard;
179 :
180 0 : uno::Reference < XAccessibleContext > xAcc( mxParent->getAccessibleContext() );
181 0 : uno::Reference < XAccessible > xThis( this );
182 0 : sal_Int32 nCount = xAcc->getAccessibleChildCount();
183 :
184 0 : for( sal_Int32 i=0; i < nCount; i++ )
185 : {
186 : try
187 : {
188 0 : if( xAcc->getAccessibleChild( i ) == xThis )
189 0 : return i;
190 : }
191 0 : catch(const ::com::sun::star::lang::IndexOutOfBoundsException &)
192 : {
193 0 : return -1L;
194 : }
195 : }
196 0 : return -1L;
197 : }
198 :
199 28 : OUString SAL_CALL SwAccessibleDocumentBase::getAccessibleDescription (void)
200 : throw (uno::RuntimeException, std::exception)
201 : {
202 28 : return GetResource( STR_ACCESS_DOC_DESC );
203 : }
204 :
205 28 : OUString SAL_CALL SwAccessibleDocumentBase::getAccessibleName (void)
206 : throw (::com::sun::star::uno::RuntimeException, std::exception)
207 : {
208 28 : SolarMutexGuard g;
209 :
210 28 : OUString sAccName = GetResource( STR_ACCESS_DOC_WORDPROCESSING );
211 28 : SwDoc *pDoc = GetMap() ? GetShell()->GetDoc() : 0;
212 28 : if ( pDoc )
213 : {
214 28 : OUString sFileName = pDoc->getDocAccTitle();
215 28 : if ( sFileName.isEmpty() )
216 : {
217 28 : SwDocShell* pDocSh = pDoc->GetDocShell();
218 28 : if ( pDocSh )
219 : {
220 28 : sFileName = pDocSh->GetTitle( SFX_TITLE_APINAME );
221 : }
222 : }
223 56 : OUString sReadOnly;
224 28 : if(pDoc->getDocReadOnly())
225 : {
226 0 : sReadOnly = GetResource( STR_ACCESS_DOC_WORDPROCESSING_READONLY );
227 : }
228 :
229 28 : if ( !sFileName.isEmpty() )
230 : {
231 28 : sAccName = sFileName + sReadOnly + " - " + sAccName;
232 28 : }
233 : }
234 :
235 28 : return sAccName;
236 : }
237 :
238 0 : awt::Rectangle SAL_CALL SwAccessibleDocumentBase::getBounds()
239 : throw (uno::RuntimeException, std::exception)
240 : {
241 : try
242 : {
243 0 : SolarMutexGuard aGuard;
244 :
245 0 : vcl::Window *pWin = GetWindow();
246 :
247 0 : CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
248 :
249 0 : Rectangle aPixBounds( pWin->GetWindowExtentsRelative( pWin->GetAccessibleParentWindow() ) );
250 0 : awt::Rectangle aBox( aPixBounds.Left(), aPixBounds.Top(),
251 0 : aPixBounds.GetWidth(), aPixBounds.GetHeight() );
252 :
253 0 : return aBox;
254 : }
255 0 : catch(const ::com::sun::star::lang::IndexOutOfBoundsException &)
256 : {
257 0 : return awt::Rectangle();
258 : }
259 : }
260 :
261 0 : awt::Point SAL_CALL SwAccessibleDocumentBase::getLocation()
262 : throw (uno::RuntimeException, std::exception)
263 : {
264 0 : SolarMutexGuard aGuard;
265 :
266 0 : vcl::Window *pWin = GetWindow();
267 :
268 0 : CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
269 :
270 0 : Point aPixPos( pWin->GetWindowExtentsRelative( pWin->GetAccessibleParentWindow() ).TopLeft() );
271 0 : awt::Point aLoc( aPixPos.getX(), aPixPos.getY() );
272 :
273 0 : return aLoc;
274 : }
275 :
276 4 : ::com::sun::star::awt::Point SAL_CALL SwAccessibleDocumentBase::getLocationOnScreen()
277 : throw (uno::RuntimeException, std::exception)
278 : {
279 4 : SolarMutexGuard aGuard;
280 :
281 4 : vcl::Window *pWin = GetWindow();
282 :
283 4 : CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
284 :
285 4 : Point aPixPos( pWin->GetWindowExtentsRelative( 0 ).TopLeft() );
286 4 : awt::Point aLoc( aPixPos.getX(), aPixPos.getY() );
287 :
288 4 : return aLoc;
289 : }
290 :
291 0 : ::com::sun::star::awt::Size SAL_CALL SwAccessibleDocumentBase::getSize()
292 : throw (uno::RuntimeException, std::exception)
293 : {
294 0 : SolarMutexGuard aGuard;
295 :
296 0 : vcl::Window *pWin = GetWindow();
297 :
298 0 : CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
299 :
300 0 : Size aPixSize( pWin->GetWindowExtentsRelative( 0 ).GetSize() );
301 0 : awt::Size aSize( aPixSize.Width(), aPixSize.Height() );
302 :
303 0 : return aSize;
304 : }
305 :
306 0 : sal_Bool SAL_CALL SwAccessibleDocumentBase::containsPoint(
307 : const awt::Point& aPoint )
308 : throw (uno::RuntimeException, std::exception)
309 : {
310 0 : SolarMutexGuard aGuard;
311 :
312 0 : vcl::Window *pWin = GetWindow();
313 :
314 0 : CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
315 :
316 0 : Rectangle aPixBounds( pWin->GetWindowExtentsRelative( 0 ) );
317 0 : aPixBounds.Move(-aPixBounds.Left(), -aPixBounds.Top());
318 :
319 0 : Point aPixPoint( aPoint.X, aPoint.Y );
320 0 : return aPixBounds.IsInside( aPixPoint );
321 : }
322 :
323 0 : uno::Reference< XAccessible > SAL_CALL SwAccessibleDocumentBase::getAccessibleAtPoint(
324 : const awt::Point& aPoint )
325 : throw (uno::RuntimeException, std::exception)
326 : {
327 0 : SolarMutexGuard aGuard;
328 :
329 0 : if( mpChildWin )
330 : {
331 0 : CHECK_FOR_DEFUNC( XAccessibleComponent )
332 :
333 0 : vcl::Window *pWin = GetWindow();
334 0 : CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
335 :
336 0 : Point aPixPoint( aPoint.X, aPoint.Y ); // px rel to window
337 0 : if( mpChildWin->GetWindowExtentsRelative( pWin ).IsInside( aPixPoint ) )
338 0 : return mpChildWin->GetAccessible();
339 : }
340 :
341 0 : return SwAccessibleContext::getAccessibleAtPoint( aPoint );
342 : }
343 :
344 : // SwAccessibeDocument
345 :
346 24 : void SwAccessibleDocument::GetStates(
347 : ::utl::AccessibleStateSetHelper& rStateSet )
348 : {
349 24 : SwAccessibleContext::GetStates( rStateSet );
350 :
351 : // MULTISELECTABLE
352 24 : rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
353 24 : rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
354 24 : }
355 :
356 24 : SwAccessibleDocument::SwAccessibleDocument ( SwAccessibleMap* pInitMap ) :
357 : SwAccessibleDocumentBase( pInitMap ),
358 24 : maSelectionHelper( *this )
359 : {
360 24 : SetName( GetResource( STR_ACCESS_DOC_NAME ) );
361 24 : vcl::Window *pWin = pInitMap->GetShell()->GetWin();
362 24 : if( pWin )
363 : {
364 24 : pWin->AddChildEventListener( LINK( this, SwAccessibleDocument, WindowChildEventListener ));
365 24 : sal_uInt16 nCount = pWin->GetChildCount();
366 24 : for( sal_uInt16 i=0; i < nCount; i++ )
367 : {
368 0 : vcl::Window* pChildWin = pWin->GetChild( i );
369 0 : if( pChildWin &&
370 0 : AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
371 0 : AddChild( pChildWin, false );
372 : }
373 : }
374 24 : }
375 :
376 72 : SwAccessibleDocument::~SwAccessibleDocument()
377 : {
378 24 : vcl::Window *pWin = GetMap() ? GetMap()->GetShell()->GetWin() : 0;
379 24 : if( pWin )
380 0 : pWin->RemoveChildEventListener( LINK( this, SwAccessibleDocument, WindowChildEventListener ));
381 48 : }
382 :
383 24 : void SwAccessibleDocument::Dispose( bool bRecursive )
384 : {
385 : OSL_ENSURE( GetFrm() && GetMap(), "already disposed" );
386 :
387 24 : vcl::Window *pWin = GetMap() ? GetMap()->GetShell()->GetWin() : 0;
388 24 : if( pWin )
389 24 : pWin->RemoveChildEventListener( LINK( this, SwAccessibleDocument, WindowChildEventListener ));
390 24 : SwAccessibleContext::Dispose( bRecursive );
391 24 : }
392 :
393 148 : IMPL_LINK( SwAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent )
394 : {
395 : OSL_ENSURE( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
396 74 : if ( pEvent && pEvent->ISA( VclWindowEvent ) )
397 : {
398 74 : VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent );
399 : OSL_ENSURE( pVclEvent->GetWindow(), "Window???" );
400 74 : switch ( pVclEvent->GetId() )
401 : {
402 : case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children
403 : {
404 0 : vcl::Window* pChildWin = static_cast< vcl::Window* >( pVclEvent->GetData() );
405 0 : if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
406 : {
407 0 : AddChild( pChildWin );
408 : }
409 : }
410 0 : break;
411 : case VCLEVENT_WINDOW_HIDE: // send destroy on hide for direct accessible children
412 : {
413 24 : vcl::Window* pChildWin = static_cast< vcl::Window* >( pVclEvent->GetData() );
414 24 : if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
415 : {
416 0 : RemoveChild( pChildWin );
417 : }
418 : }
419 24 : break;
420 : case VCLEVENT_OBJECT_DYING: // send destroy on hide for direct accessible children
421 : {
422 0 : vcl::Window* pChildWin = pVclEvent->GetWindow();
423 0 : if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
424 : {
425 0 : RemoveChild( pChildWin );
426 : }
427 : }
428 0 : break;
429 : }
430 : }
431 74 : return 0;
432 : }
433 :
434 0 : OUString SAL_CALL SwAccessibleDocument::getImplementationName()
435 : throw( uno::RuntimeException, std::exception )
436 : {
437 0 : return OUString(sImplementationName);
438 : }
439 :
440 0 : sal_Bool SAL_CALL SwAccessibleDocument::supportsService(const OUString& sTestServiceName)
441 : throw (uno::RuntimeException, std::exception)
442 : {
443 0 : return cppu::supportsService(this, sTestServiceName);
444 : }
445 :
446 0 : uno::Sequence< OUString > SAL_CALL SwAccessibleDocument::getSupportedServiceNames()
447 : throw( uno::RuntimeException, std::exception )
448 : {
449 0 : uno::Sequence< OUString > aRet(2);
450 0 : OUString* pArray = aRet.getArray();
451 0 : pArray[0] = OUString( sServiceName );
452 0 : pArray[1] = OUString( sAccessibleServiceName );
453 0 : return aRet;
454 : }
455 :
456 : // XInterface
457 :
458 427 : uno::Any SwAccessibleDocument::queryInterface(
459 : const uno::Type& rType )
460 : throw ( uno::RuntimeException, std::exception )
461 : {
462 427 : uno::Any aRet;
463 427 : if ( rType == cppu::UnoType<XAccessibleSelection>::get() )
464 : {
465 0 : uno::Reference<XAccessibleSelection> aSelect = this;
466 0 : aRet <<= aSelect;
467 : }
468 : //Add XEventListener interface support.
469 427 : else if ( (rType == cppu::UnoType<com::sun::star::document::XEventListener>::get()) )
470 : {
471 0 : uno::Reference<com::sun::star::document::XEventListener> aSelect = this;
472 0 : aRet <<= aSelect;
473 : }
474 427 : else if ( rType == cppu::UnoType<XAccessibleExtendedAttributes>::get())
475 : {
476 0 : uno::Reference<XAccessibleExtendedAttributes> aAttribute = this;
477 0 : aRet <<= aAttribute;
478 : }
479 427 : else if(rType == cppu::UnoType<XAccessibleGetAccFlowTo>::get())
480 : {
481 0 : uno::Reference<XAccessibleGetAccFlowTo> AccFlowTo = this;
482 0 : aRet <<= AccFlowTo;
483 : }
484 : else
485 427 : aRet = SwAccessibleContext::queryInterface( rType );
486 427 : return aRet;
487 : }
488 :
489 : // XTypeProvider
490 0 : uno::Sequence< uno::Type > SAL_CALL SwAccessibleDocument::getTypes()
491 : throw(uno::RuntimeException, std::exception)
492 : {
493 0 : uno::Sequence< uno::Type > aTypes( SwAccessibleDocumentBase::getTypes() );
494 :
495 0 : sal_Int32 nIndex = aTypes.getLength();
496 : //Reset types memory alloc
497 : //aTypes.realloc( nIndex + 1 );
498 0 : aTypes.realloc( nIndex + 2 );
499 :
500 0 : uno::Type* pTypes = aTypes.getArray();
501 0 : pTypes[nIndex] = cppu::UnoType<XAccessibleSelection>::get();
502 : //Add XEventListener interface support.
503 0 : pTypes[nIndex + 1 ] = cppu::UnoType<com::sun::star::document::XEventListener>::get();
504 0 : return aTypes;
505 : }
506 :
507 0 : uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleDocument::getImplementationId()
508 : throw(uno::RuntimeException, std::exception)
509 : {
510 0 : return css::uno::Sequence<sal_Int8>();
511 : }
512 :
513 : // XAccessibleSelection
514 :
515 0 : void SwAccessibleDocument::selectAccessibleChild(
516 : sal_Int32 nChildIndex )
517 : throw ( lang::IndexOutOfBoundsException,
518 : uno::RuntimeException, std::exception )
519 : {
520 0 : maSelectionHelper.selectAccessibleChild(nChildIndex);
521 0 : }
522 :
523 0 : sal_Bool SwAccessibleDocument::isAccessibleChildSelected(
524 : sal_Int32 nChildIndex )
525 : throw ( lang::IndexOutOfBoundsException,
526 : uno::RuntimeException, std::exception )
527 : {
528 0 : return maSelectionHelper.isAccessibleChildSelected(nChildIndex);
529 : }
530 :
531 0 : void SwAccessibleDocument::clearAccessibleSelection( )
532 : throw ( uno::RuntimeException, std::exception )
533 : {
534 0 : maSelectionHelper.clearAccessibleSelection();
535 0 : }
536 :
537 0 : void SwAccessibleDocument::selectAllAccessibleChildren( )
538 : throw ( uno::RuntimeException, std::exception )
539 : {
540 0 : maSelectionHelper.selectAllAccessibleChildren();
541 0 : }
542 :
543 0 : sal_Int32 SwAccessibleDocument::getSelectedAccessibleChildCount( )
544 : throw ( uno::RuntimeException, std::exception )
545 : {
546 0 : return maSelectionHelper.getSelectedAccessibleChildCount();
547 : }
548 :
549 0 : uno::Reference<XAccessible> SwAccessibleDocument::getSelectedAccessibleChild(
550 : sal_Int32 nSelectedChildIndex )
551 : throw ( lang::IndexOutOfBoundsException,
552 : uno::RuntimeException, std::exception)
553 : {
554 0 : return maSelectionHelper.getSelectedAccessibleChild(nSelectedChildIndex);
555 : }
556 :
557 : // index has to be treated as global child index.
558 0 : void SwAccessibleDocument::deselectAccessibleChild(
559 : sal_Int32 nChildIndex )
560 : throw ( lang::IndexOutOfBoundsException,
561 : uno::RuntimeException, std::exception )
562 : {
563 0 : maSelectionHelper.deselectAccessibleChild( nChildIndex );
564 0 : }
565 :
566 : //Implement XEventListener interfaces
567 0 : void SAL_CALL SwAccessibleDocument::notifyEvent( const ::com::sun::star::document::EventObject& Event )
568 : throw (::com::sun::star::uno::RuntimeException, std::exception)
569 : {
570 0 : SolarMutexGuard g;
571 :
572 0 : if ( Event.EventName.equalsAscii( "FirstPageShows" ) )
573 : {
574 0 : FireStateChangedEvent( AccessibleStateType::FOCUSED,true );
575 : }
576 0 : else if ( Event.EventName.equalsAscii( "LoadFinished" ) )
577 : {
578 : // IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent
579 : // FireStateChangedEvent( AccessibleStateType::OFFSCREEN,sal_True );
580 : // MT: LoadFinished => Why not SHOWING == TRUE?
581 0 : FireStateChangedEvent( AccessibleStateType::SHOWING,false );
582 : }
583 0 : else if ( Event.EventName.equalsAscii( "FormatFinished" ) )
584 : {
585 0 : FireStateChangedEvent( AccessibleStateType::BUSY,false );
586 : // FireStateChangedEvent( AccessibleStateType::OFFSCREEN,sal_False );
587 0 : FireStateChangedEvent( AccessibleStateType::SHOWING,true );
588 : }
589 : else
590 : {
591 0 : isIfAsynLoad = false;
592 0 : }
593 0 : }
594 :
595 0 : void SAL_CALL SwAccessibleDocument::disposing( const ::com::sun::star::lang::EventObject& )
596 : throw (::com::sun::star::uno::RuntimeException, std::exception)
597 : {
598 0 : }
599 :
600 0 : uno::Any SAL_CALL SwAccessibleDocument::getExtendedAttributes()
601 : throw (::com::sun::star::lang::IndexOutOfBoundsException,
602 : ::com::sun::star::uno::RuntimeException,
603 : std::exception)
604 : {
605 0 : SolarMutexGuard g;
606 :
607 0 : uno::Any anyAtrribute;
608 0 : SwDoc *pDoc = GetMap() ? GetShell()->GetDoc() : 0;
609 :
610 0 : if (!pDoc)
611 0 : return anyAtrribute;
612 0 : SwCrsrShell* pCrsrShell = GetCrsrShell();
613 0 : if( !pCrsrShell )
614 0 : return anyAtrribute;
615 :
616 0 : SwFEShell* pFEShell = pCrsrShell->ISA( SwFEShell )
617 : ? static_cast<SwFEShell*>( pCrsrShell )
618 0 : : 0;
619 0 : OUString sAttrName;
620 0 : OUString sValue;
621 : sal_uInt16 nPage, nLogPage;
622 0 : OUString sDisplay;
623 :
624 0 : if( pFEShell )
625 : {
626 0 : pFEShell->GetPageNumber(-1,true,nPage,nLogPage,sDisplay);
627 0 : sAttrName = "page-name:";
628 :
629 0 : sValue = sAttrName + sDisplay ;
630 0 : sAttrName = ";page-number:";
631 0 : sValue += sAttrName;
632 0 : sValue += OUString::number( nPage ) ;
633 0 : sAttrName = ";total-pages:";
634 0 : sValue += sAttrName;
635 0 : sValue += OUString::number( pCrsrShell->GetPageCnt() ) ;
636 0 : sValue += ";";
637 :
638 0 : sAttrName = "line-number:";
639 :
640 0 : SwCntntFrm* pCurrFrm = pCrsrShell->GetCurrFrm();
641 0 : SwPageFrm* pCurrPage=((SwFrm*)pCurrFrm)->FindPageFrm();
642 0 : sal_uLong nLineNum = 0;
643 0 : SwTxtFrm* pTxtFrm = NULL;
644 0 : SwTxtFrm* pCurrTxtFrm = NULL;
645 0 : pTxtFrm = static_cast< SwTxtFrm* >(static_cast< SwPageFrm* > (pCurrPage)->ContainsCntnt());
646 0 : if (pCurrFrm->IsInFly())//such as, graphic,chart
647 : {
648 0 : SwFlyFrm *pFlyFrm = pCurrFrm->FindFlyFrm();
649 0 : const SwFmtAnchor& rAnchor = pFlyFrm->GetFmt()->GetAnchor();
650 0 : RndStdIds eAnchorId = rAnchor.GetAnchorId();
651 0 : if(eAnchorId == FLY_AS_CHAR)
652 : {
653 0 : const SwFrm *pSwFrm = pFlyFrm->GetAnchorFrm();
654 0 : if(pSwFrm->IsTxtFrm())
655 0 : pCurrTxtFrm = ((SwTxtFrm*)(pSwFrm));
656 : }
657 : }
658 : else
659 0 : pCurrTxtFrm = static_cast< SwTxtFrm* >(pCurrFrm);
660 : //check whether the text frame where the Graph/OLE/Frame anchored is in the Header/Footer
661 0 : SwFrm* pFrm = pCurrTxtFrm;
662 0 : while ( pFrm && !pFrm->IsHeaderFrm() && !pFrm->IsFooterFrm() )
663 0 : pFrm = pFrm->GetUpper();
664 0 : if ( pFrm )
665 0 : pCurrTxtFrm = NULL;
666 : //check shape
667 0 : if(pCrsrShell->Imp()->GetDrawView())
668 : {
669 0 : const SdrMarkList &rMrkList = pCrsrShell->Imp()->GetDrawView()->GetMarkedObjectList();
670 0 : for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
671 : {
672 0 : SdrObject *pObj = rMrkList.GetMark(i)->GetMarkedSdrObj();
673 0 : SwFrmFmt* pFmt = ((SwDrawContact*)pObj->GetUserCall())->GetFmt();
674 0 : const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
675 0 : if( FLY_AS_CHAR != rAnchor.GetAnchorId() )
676 0 : pCurrTxtFrm = NULL;
677 : }
678 : }
679 : //calculate line number
680 0 : if (pCurrTxtFrm && pTxtFrm)
681 : {
682 0 : if (!(pCurrTxtFrm->IsInTab() || pCurrTxtFrm->IsInFtn()))
683 : {
684 0 : while( pTxtFrm != pCurrTxtFrm )
685 : {
686 : //check header/footer
687 0 : pFrm = pTxtFrm;
688 0 : while ( pFrm && !pFrm->IsHeaderFrm() && !pFrm->IsFooterFrm() )
689 0 : pFrm = pFrm->GetUpper();
690 0 : if ( pFrm )
691 : {
692 0 : pTxtFrm = static_cast< SwTxtFrm*>(pTxtFrm->GetNextCntntFrm());
693 0 : continue;
694 : }
695 0 : if (!(pTxtFrm->IsInTab() || pTxtFrm->IsInFtn() || pTxtFrm->IsInFly()))
696 0 : nLineNum += pTxtFrm->GetThisLines();
697 0 : pTxtFrm = static_cast< SwTxtFrm* >(pTxtFrm ->GetNextCntntFrm());
698 : }
699 0 : SwPaM* pCaret = pCrsrShell->GetCrsr();
700 0 : if (!pCurrTxtFrm->IsEmpty() && pCaret)
701 : {
702 0 : sal_uInt16 nActPos = 0;
703 0 : if (pCurrTxtFrm->IsTxtFrm())
704 : {
705 0 : const SwPosition* pPoint = NULL;
706 0 : if(pCurrTxtFrm->IsInFly())
707 : {
708 0 : SwFlyFrm *pFlyFrm = pCurrTxtFrm->FindFlyFrm();
709 0 : const SwFmtAnchor& rAnchor = pFlyFrm->GetFmt()->GetAnchor();
710 0 : pPoint= rAnchor.GetCntntAnchor();
711 : }
712 : else
713 0 : pPoint = pCaret->GetPoint();
714 0 : nActPos = pPoint->nContent.GetIndex();
715 0 : nLineNum += pCurrTxtFrm->GetLineCount( nActPos );
716 : }
717 : else//graphic, form, shape, etc.
718 : {
719 0 : SwPosition* pPoint = pCaret->GetPoint();
720 0 : Point aPt = pCrsrShell->_GetCrsr()->GetPtPos();
721 0 : if( pCrsrShell->GetLayout()->GetCrsrOfst( pPoint, aPt/*,* &eTmpState*/ ) )
722 : {
723 0 : nActPos = pPoint->nContent.GetIndex();
724 0 : nLineNum += pCurrTxtFrm->GetLineCount( nActPos );
725 : }
726 : }
727 : }
728 : else
729 0 : ++nLineNum;
730 : }
731 : }
732 :
733 0 : sValue += sAttrName;
734 0 : sValue += OUString::number( nLineNum ) ;
735 :
736 0 : sValue += ";";
737 :
738 0 : SwFrm* pCurrCol=((SwFrm*)pCurrFrm)->FindColFrm();
739 :
740 0 : sAttrName = "column-number:";
741 0 : sValue += sAttrName;
742 :
743 0 : sal_uInt16 nCurrCol = 1;
744 0 : if(pCurrCol!=NULL)
745 : {
746 : //SwLayoutFrm* pParent = pCurrCol->GetUpper();
747 0 : SwFrm* pCurrPageCol=((SwFrm*)pCurrFrm)->FindColFrm();
748 0 : while(pCurrPageCol && pCurrPageCol->GetUpper() && pCurrPageCol->GetUpper()->IsPageFrm())
749 : {
750 0 : pCurrPageCol = pCurrPageCol->GetUpper();
751 : }
752 :
753 0 : SwLayoutFrm* pParent = (SwLayoutFrm*)(pCurrPageCol->GetUpper());
754 :
755 0 : if(pParent!=NULL)
756 : {
757 0 : SwFrm* pCol = pParent->Lower();
758 0 : while(pCol&&(pCol!=pCurrPageCol))
759 : {
760 0 : pCol = pCol->GetNext();
761 0 : nCurrCol +=1;
762 : }
763 : }
764 : }
765 0 : sValue += OUString::number( nCurrCol ) ;
766 0 : sValue += ";";
767 :
768 0 : sAttrName = "total-columns:";
769 :
770 0 : const SwFmtCol &rFmtCol=pCurrPage->GetAttrSet()->GetCol();
771 0 : sal_uInt16 nColCount=rFmtCol.GetNumCols();
772 0 : nColCount = nColCount>0?nColCount:1;
773 0 : sValue += sAttrName;
774 0 : sValue += OUString::number( nColCount ) ;
775 :
776 0 : sValue += ";";
777 :
778 0 : SwSectionFrm* pCurrSctFrm=((SwFrm*)pCurrFrm)->FindSctFrm();
779 0 : if(pCurrSctFrm!=NULL && pCurrSctFrm->GetSection()!=NULL )
780 : {
781 0 : sAttrName = "section-name:";
782 :
783 0 : sValue += sAttrName;
784 0 : OUString sectionName = pCurrSctFrm->GetSection()->GetSectionName();
785 :
786 0 : sectionName = sectionName.replaceFirst( "\\" , "\\\\" );
787 0 : sectionName = sectionName.replaceFirst( "=" , "\\=" );
788 0 : sectionName = sectionName.replaceFirst( ";" , "\\;" );
789 0 : sectionName = sectionName.replaceFirst( "," , "\\," );
790 0 : sectionName = sectionName.replaceFirst( ":" , "\\:" );
791 :
792 0 : sValue += sectionName;
793 :
794 0 : sValue += ";";
795 :
796 : //section-columns-number
797 0 : sAttrName = "section-columns-number:";
798 :
799 0 : nCurrCol = 1;
800 :
801 0 : if(pCurrCol!=NULL)
802 : {
803 0 : SwLayoutFrm* pParent = pCurrCol->GetUpper();
804 0 : if(pParent!=NULL)
805 : {
806 0 : SwFrm* pCol = pParent->Lower();
807 0 : while(pCol&&(pCol!=pCurrCol))
808 : {
809 0 : pCol = pCol->GetNext();
810 0 : nCurrCol +=1;
811 : }
812 : }
813 : }
814 0 : sValue += sAttrName;
815 0 : sValue += OUString::number( nCurrCol ) ;
816 0 : sValue += ";";
817 :
818 : //section-total-columns
819 0 : sAttrName = "section-total-columns:";
820 0 : const SwFmtCol &rFmtSctCol=pCurrSctFrm->GetAttrSet()->GetCol();
821 0 : sal_uInt16 nSctColCount=rFmtSctCol.GetNumCols();
822 0 : nSctColCount = nSctColCount>0?nSctColCount:1;
823 0 : sValue += sAttrName;
824 0 : sValue += OUString::number( nSctColCount ) ;
825 :
826 0 : sValue += ";";
827 : }
828 :
829 0 : anyAtrribute <<= sValue;
830 : }
831 0 : return anyAtrribute;
832 : }
833 :
834 2 : sal_Int32 SAL_CALL SwAccessibleDocument::getBackground()
835 : throw (::com::sun::star::uno::RuntimeException, std::exception)
836 : {
837 2 : SolarMutexGuard aGuard;
838 2 : return SW_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
839 : }
840 :
841 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
842 0 : SAL_CALL SwAccessibleDocument::getAccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType)
843 : throw (::com::sun::star::uno::RuntimeException,
844 : std::exception)
845 : {
846 0 : SolarMutexGuard g;
847 :
848 0 : const sal_Int32 FORSPELLCHECKFLOWTO = 1;
849 0 : const sal_Int32 FORFINDREPLACEFLOWTO = 2;
850 0 : SwAccessibleMap* pAccMap = GetMap();
851 0 : if ( !pAccMap )
852 : {
853 0 : return uno::Sequence< uno::Any >();
854 : }
855 :
856 0 : if ( nType == FORSPELLCHECKFLOWTO )
857 : {
858 0 : uno::Reference< ::com::sun::star::drawing::XShape > xShape;
859 0 : rAny >>= xShape;
860 0 : if( xShape.is() )
861 : {
862 0 : SdrObject* pObj = GetSdrObjectFromXShape(xShape);
863 0 : if( pObj )
864 : {
865 0 : uno::Reference<XAccessible> xAcc = pAccMap->GetContext(pObj, this, false);
866 0 : uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY );
867 0 : if ( xAccSelection.is() )
868 : {
869 : try
870 : {
871 0 : if ( xAccSelection->getSelectedAccessibleChildCount() )
872 : {
873 0 : uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 );
874 0 : if ( xSel.is() )
875 : {
876 0 : uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
877 0 : if ( xSelContext.is() )
878 : {
879 : //if in sw we find the selected paragraph here
880 0 : if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
881 : {
882 0 : uno::Sequence<uno::Any> aRet( 1 );
883 0 : aRet[0] = uno::makeAny( xSel );
884 0 : return aRet;
885 : }
886 0 : }
887 0 : }
888 : }
889 : }
890 0 : catch ( const com::sun::star::lang::IndexOutOfBoundsException& )
891 : {
892 0 : return uno::Sequence< uno::Any >();
893 : }
894 : //end of try...catch
895 0 : }
896 : }
897 : }
898 : else
899 : {
900 0 : uno::Reference< XAccessible > xAcc = pAccMap->GetCursorContext();
901 0 : SwAccessibleContext *pAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
902 0 : if ( pAccImpl && pAccImpl->getAccessibleRole() == AccessibleRole::PARAGRAPH )
903 : {
904 0 : uno::Sequence< uno::Any > aRet(1);
905 0 : aRet[0] = uno::makeAny( xAcc );
906 0 : return aRet;
907 0 : }
908 0 : }
909 : }
910 0 : else if ( nType == FORFINDREPLACEFLOWTO )
911 : {
912 0 : SwCrsrShell* pCrsrShell = GetCrsrShell();
913 0 : if ( pCrsrShell )
914 : {
915 0 : SwPaM *_pStartCrsr = pCrsrShell->GetCrsr(), *__pStartCrsr = _pStartCrsr;
916 0 : SwCntntNode* pPrevNode = NULL;
917 0 : std::vector<SwFrm*> vFrmList;
918 0 : do
919 : {
920 0 : if ( _pStartCrsr && _pStartCrsr->HasMark() )
921 : {
922 0 : SwCntntNode* pCntntNode = _pStartCrsr->GetCntntNode();
923 0 : if ( pCntntNode == pPrevNode )
924 : {
925 0 : continue;
926 : }
927 0 : SwFrm* pFrm = pCntntNode ? pCntntNode->getLayoutFrm( pCrsrShell->GetLayout() ) : NULL;
928 0 : if ( pFrm )
929 : {
930 0 : vFrmList.push_back( pFrm );
931 : }
932 :
933 0 : pPrevNode = pCntntNode;
934 : }
935 : }
936 :
937 0 : while( _pStartCrsr && ( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr) );
938 :
939 0 : if ( vFrmList.size() )
940 : {
941 0 : uno::Sequence< uno::Any > aRet(vFrmList.size());
942 0 : std::vector<SwFrm*>::iterator aIter = vFrmList.begin();
943 0 : for ( sal_Int32 nIndex = 0; aIter != vFrmList.end(); ++aIter, nIndex++ )
944 : {
945 0 : uno::Reference< XAccessible > xAcc = pAccMap->GetContext(*aIter, false);
946 0 : if ( xAcc.is() )
947 : {
948 0 : SwAccessibleContext *pAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
949 0 : if ( pAccImpl && pAccImpl->getAccessibleRole() == AccessibleRole::PARAGRAPH )
950 : {
951 0 : aRet[nIndex] = uno::makeAny( xAcc );
952 : }
953 : }
954 0 : }
955 :
956 0 : return aRet;
957 0 : }
958 : }
959 : }
960 :
961 0 : return uno::Sequence< uno::Any >();
962 270 : }
963 :
964 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|