1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26
27
28 #include <vos/mutex.hxx>
29 #include <vcl/svapp.hxx>
30 #include <com/sun/star/accessibility/AccessibleRole.hpp>
31 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
32 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
33 #include <unotools/accessiblestatesethelper.hxx>
34 #include <frmfmt.hxx>
35 #include <ndnotxt.hxx>
36 #include <flyfrm.hxx>
37 #include <cntfrm.hxx>
38 // --> OD 2009-07-14 #i73249#
39 #include <hints.hxx>
40 // <--
41 #include "accnotextframe.hxx"
42 #include <fmturl.hxx>
43 #include <accnotexthyperlink.hxx>
44 #include <svtools/imap.hxx>
45 #include <unotools/accessiblerelationsethelper.hxx>
46 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
47 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
48 #include <doc.hxx>
49
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::accessibility;
52 using ::rtl::OUString;
53 using utl::AccessibleRelationSetHelper;
54
GetNoTxtNode() const55 const SwNoTxtNode *SwAccessibleNoTextFrame::GetNoTxtNode() const
56 {
57 const SwNoTxtNode *pNd = 0;
58 const SwFlyFrm *pFlyFrm = static_cast< const SwFlyFrm *>( GetFrm() );
59 if( pFlyFrm->Lower() && pFlyFrm->Lower()->IsNoTxtFrm() )
60 {
61 const SwCntntFrm *pCntFrm =
62 static_cast<const SwCntntFrm *>( pFlyFrm->Lower() );
63 const SwCntntNode* pSwCntntNode = pCntFrm->GetNode();
64 if(pSwCntntNode != NULL)
65 {
66 pNd = pSwCntntNode->GetNoTxtNode();
67 }
68 }
69
70 return pNd;
71 }
72
SwAccessibleNoTextFrame(SwAccessibleMap * pInitMap,sal_Int16 nInitRole,const SwFlyFrm * pFlyFrm)73 SwAccessibleNoTextFrame::SwAccessibleNoTextFrame(
74 SwAccessibleMap* pInitMap,
75 sal_Int16 nInitRole,
76 const SwFlyFrm* pFlyFrm ) :
77 SwAccessibleFrameBase( pInitMap, nInitRole, pFlyFrm ),
78 aDepend( this, const_cast < SwNoTxtNode * >( GetNoTxtNode() ) ),
79 msTitle(),
80 msDesc()
81 {
82 const SwNoTxtNode* pNd = GetNoTxtNode();
83 // --> OD 2009-07-14 #i73249#
84 // consider new attributes Title and Description
85 if( pNd )
86 {
87 msTitle = pNd->GetTitle();
88
89 msDesc = pNd->GetDescription();
90 if ( msDesc.getLength() == 0 &&
91 msTitle != GetName() )
92 {
93 msDesc = msTitle;
94 }
95 }
96 // <--
97 }
98
~SwAccessibleNoTextFrame()99 SwAccessibleNoTextFrame::~SwAccessibleNoTextFrame()
100 {
101 }
102
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)103 void SwAccessibleNoTextFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
104 {
105 const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ;
106 // --> OD 2009-07-14 #i73249#
107 // suppress handling of RES_NAME_CHANGED in case that attribute Title is
108 // used as the accessible name.
109 if ( nWhich != RES_NAME_CHANGED ||
110 msTitle.getLength() == 0 )
111 {
112 SwAccessibleFrameBase::Modify( pOld, pNew );
113 }
114
115 const SwNoTxtNode *pNd = GetNoTxtNode();
116 ASSERT( pNd == aDepend.GetRegisteredIn(), "invalid frame" );
117 switch( nWhich )
118 {
119 // --> OD 2009-07-14 #i73249#
120 case RES_TITLE_CHANGED:
121 {
122 const String& sOldTitle(
123 dynamic_cast<const SwStringMsgPoolItem*>(pOld)->GetString() );
124 const String& sNewTitle(
125 dynamic_cast<const SwStringMsgPoolItem*>(pNew)->GetString() );
126 if ( sOldTitle == sNewTitle )
127 {
128 break;
129 }
130 msTitle = sNewTitle;
131 AccessibleEventObject aEvent;
132 aEvent.EventId = AccessibleEventId::NAME_CHANGED;
133 aEvent.OldValue <<= OUString( sOldTitle );
134 aEvent.NewValue <<= msTitle;
135 FireAccessibleEvent( aEvent );
136
137 if ( pNd->GetDescription().Len() != 0 )
138 {
139 break;
140 }
141 }
142 // intentional no break here
143 case RES_DESCRIPTION_CHANGED:
144 {
145 if ( pNd && GetFrm() )
146 {
147 const OUString sOldDesc( msDesc );
148
149 const String& rDesc = pNd->GetDescription();
150 msDesc = rDesc;
151 if ( msDesc.getLength() == 0 &&
152 msTitle != GetName() )
153 {
154 msDesc = msTitle;
155 }
156
157 if ( msDesc != sOldDesc )
158 {
159 AccessibleEventObject aEvent;
160 aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
161 aEvent.OldValue <<= sOldDesc;
162 aEvent.NewValue <<= msDesc;
163 FireAccessibleEvent( aEvent );
164 }
165 }
166 }
167 break;
168 // <--
169 /*
170 case RES_OBJECTDYING:
171 if( aDepend.GetRegisteredIn() ==
172 static_cast< SwModify *>( static_cast< SwPtrMsgPoolItem * >( pOld )->pObject ) )
173 const_cast < SwModify *>( aDepend.GetRegisteredIn()->Remove( aDepend );
174 break;
175
176 case RES_FMT_CHG:
177 if( static_cast< SwFmtChg * >(pNew)->pChangedFmt == GetRegisteredIn() &&
178 static_cast< SwFmtChg * >(pOld)->pChangedFmt->IsFmtInDTOR() )
179 GetRegisteredIn()->Remove( this );
180 break;
181 */
182 }
183 }
184
Dispose(sal_Bool bRecursive)185 void SwAccessibleNoTextFrame::Dispose( sal_Bool bRecursive )
186 {
187 vos::OGuard aGuard(Application::GetSolarMutex());
188
189 if( aDepend.GetRegisteredIn() )
190 const_cast < SwModify *>( aDepend.GetRegisteredIn() )->Remove( &aDepend );
191
192 SwAccessibleFrameBase::Dispose( bRecursive );
193 }
194
195 // --> OD 2009-07-14 #i73249#
getAccessibleName(void)196 OUString SAL_CALL SwAccessibleNoTextFrame::getAccessibleName (void)
197 throw (uno::RuntimeException)
198 {
199 vos::OGuard aGuard(Application::GetSolarMutex());
200
201 CHECK_FOR_DEFUNC( XAccessibleContext )
202
203 if ( msTitle.getLength() != 0 )
204 {
205 return msTitle;
206 }
207
208 return SwAccessibleFrameBase::getAccessibleName();
209 }
210 // <--
211
getAccessibleDescription(void)212 OUString SAL_CALL SwAccessibleNoTextFrame::getAccessibleDescription (void)
213 throw (uno::RuntimeException)
214 {
215 vos::OGuard aGuard(Application::GetSolarMutex());
216
217 CHECK_FOR_DEFUNC( XAccessibleContext )
218 // OUString longDesc;
219 // const SwFlyFrmFmt* pFlyFmt = GetShell()->GetDoc()->FindFlyByName( GetName(), 0);
220 // longDesc = OUString( pFlyFmt->GetLongDescription() );
221 // return longDesc; MT: Do not return longDesc, which still is empty - why was the line above commented out?
222
223 return msDesc;
224 }
225
226
227
228 //
229 // XInterface
230 //
231
queryInterface(const uno::Type & aType)232 uno::Any SAL_CALL SwAccessibleNoTextFrame::queryInterface( const uno::Type& aType )
233 throw (uno::RuntimeException)
234 {
235 if( aType ==
236 ::getCppuType( static_cast<uno::Reference<XAccessibleImage>*>( NULL ) ) )
237 {
238 uno::Reference<XAccessibleImage> xImage = this;
239 uno::Any aAny;
240 aAny <<= xImage;
241 return aAny;
242 }
243 else if ( aType == ::getCppuType((uno::Reference<XAccessibleHypertext> *)0) )
244 {
245 uno::Reference<XAccessibleHypertext> aAccHypertext = this;
246 uno::Any aAny;
247 aAny <<= aAccHypertext;
248 return aAny;
249 }
250 else
251 return SwAccessibleContext::queryInterface( aType );
252 }
253
254
255 //====== XTypeProvider ====================================================
getTypes()256 uno::Sequence< uno::Type > SAL_CALL SwAccessibleNoTextFrame::getTypes() throw(uno::RuntimeException)
257 {
258 uno::Sequence< uno::Type > aTypes( SwAccessibleFrameBase::getTypes() );
259
260 sal_Int32 nIndex = aTypes.getLength();
261 aTypes.realloc( nIndex + 1 );
262
263 uno::Type* pTypes = aTypes.getArray();
264 pTypes[nIndex] = ::getCppuType( static_cast< uno::Reference< XAccessibleImage > * >( 0 ) );
265
266 return aTypes;
267 }
268
269
270 //
271 // XAccessibleImage
272 //
273
274 // implementation of the XAccessibleImage methods is a no-brainer, as
275 // all releveant information is already accessible through other
276 // methods. So we just delegate to those.
277
getAccessibleImageDescription()278 OUString SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageDescription()
279 throw ( uno::RuntimeException )
280 {
281 return getAccessibleDescription();
282 }
283
getAccessibleImageHeight()284 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageHeight( )
285 throw ( uno::RuntimeException )
286 {
287 return getSize().Height;
288 }
289
getAccessibleImageWidth()290 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageWidth( )
291 throw ( uno::RuntimeException )
292 {
293 return getSize().Width;
294 }
295 //===== XAccesibleText ==================================================
getCaretPosition()296 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException){return 0;}
setCaretPosition(sal_Int32)297 sal_Bool SAL_CALL SwAccessibleNoTextFrame::setCaretPosition( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;}
getCharacter(sal_Int32)298 sal_Unicode SAL_CALL SwAccessibleNoTextFrame::getCharacter( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;}
getCharacterAttributes(sal_Int32,const::com::sun::star::uno::Sequence<::rtl::OUString> &)299 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL SwAccessibleNoTextFrame::getCharacterAttributes( sal_Int32 , const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
300 {
301 uno::Sequence<beans::PropertyValue> aValues(0);
302 return aValues;
303 }
getCharacterBounds(sal_Int32)304 ::com::sun::star::awt::Rectangle SAL_CALL SwAccessibleNoTextFrame::getCharacterBounds( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
305 {
306 return com::sun::star::awt::Rectangle(0, 0, 0, 0 );
307 }
getCharacterCount()308 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException){return 0;}
getIndexAtPoint(const::com::sun::star::awt::Point &)309 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getIndexAtPoint( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException){return 0;}
getSelectedText()310 ::rtl::OUString SAL_CALL SwAccessibleNoTextFrame::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();}
getSelectionStart()311 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException){return 0;}
getSelectionEnd()312 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException){return 0;}
setSelection(sal_Int32,sal_Int32)313 sal_Bool SAL_CALL SwAccessibleNoTextFrame::setSelection( sal_Int32 , sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;}
getText()314 ::rtl::OUString SAL_CALL SwAccessibleNoTextFrame::getText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();}
getTextRange(sal_Int32,sal_Int32)315 ::rtl::OUString SAL_CALL SwAccessibleNoTextFrame::getTextRange( sal_Int32 , sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return OUString();}
getTextAtIndex(sal_Int32,sal_Int16)316 ::com::sun::star::accessibility::TextSegment SAL_CALL SwAccessibleNoTextFrame::getTextAtIndex( sal_Int32 , sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
317 {
318 ::com::sun::star::accessibility::TextSegment aResult;
319 return aResult;
320 }
getTextBeforeIndex(sal_Int32,sal_Int16)321 ::com::sun::star::accessibility::TextSegment SAL_CALL SwAccessibleNoTextFrame::getTextBeforeIndex( sal_Int32, sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
322 {
323 ::com::sun::star::accessibility::TextSegment aResult;
324 return aResult;
325 }
getTextBehindIndex(sal_Int32,sal_Int16)326 ::com::sun::star::accessibility::TextSegment SAL_CALL SwAccessibleNoTextFrame::getTextBehindIndex( sal_Int32 , sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
327 {
328 ::com::sun::star::accessibility::TextSegment aResult;
329 return aResult;
330 }
331
copyText(sal_Int32,sal_Int32)332 sal_Bool SAL_CALL SwAccessibleNoTextFrame::copyText( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;}
333
334
335 //
336 // XAccessibleHyperText
337 //
getHyperLinkCount()338 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getHyperLinkCount()
339 throw (uno::RuntimeException)
340 {
341 vos::OGuard aGuard(Application::GetSolarMutex());
342
343 CHECK_FOR_DEFUNC( XAccessibleHypertext );
344
345 sal_Int32 nCount = 0;
346 SwFmtURL aURL( ((SwLayoutFrm*)GetFrm())->GetFmt()->GetURL() );
347
348 if(aURL.GetMap() || aURL.GetURL().Len())
349 nCount = 1;
350
351 return nCount;
352 }
353
354 uno::Reference< XAccessibleHyperlink > SAL_CALL
getHyperLink(sal_Int32 nLinkIndex)355 SwAccessibleNoTextFrame::getHyperLink( sal_Int32 nLinkIndex )
356 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
357 {
358 vos::OGuard aGuard(Application::GetSolarMutex());
359 CHECK_FOR_DEFUNC( XAccessibleHypertext );
360
361 uno::Reference< XAccessibleHyperlink > xRet;
362
363 SwFmtURL aURL( ((SwLayoutFrm*)GetFrm())->GetFmt()->GetURL() );
364
365 if( nLinkIndex > 0 )
366 throw lang::IndexOutOfBoundsException();
367
368 if( aURL.GetMap() || aURL.GetURL().Len() )
369 {
370 if ( !alink.is() )
371 {
372 alink = new SwAccessibleNoTextHyperlink( this, GetFrm() );
373 }
374
375 return alink;
376 }
377
378 return NULL;
379 }
380
getHyperLinkIndex(sal_Int32)381 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getHyperLinkIndex( sal_Int32 )
382 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
383 {
384 vos::OGuard aGuard(Application::GetSolarMutex());
385 CHECK_FOR_DEFUNC( XAccessibleHypertext );
386
387 sal_Int32 nRet = 0;
388
389 return nRet;
390 }
391
makeRelation(sal_Int16 nType,const SwFlyFrm * pFrm)392 AccessibleRelation SwAccessibleNoTextFrame::makeRelation( sal_Int16 nType, const SwFlyFrm* pFrm )
393 {
394 uno::Sequence<uno::Reference<XInterface> > aSequence(1);
395 aSequence[0] = GetMap()->GetContext( pFrm );
396 return AccessibleRelation( nType, aSequence );
397 }
398
399
getAccessibleRelationSet()400 uno::Reference<XAccessibleRelationSet> SAL_CALL SwAccessibleNoTextFrame::getAccessibleRelationSet( )
401 throw ( uno::RuntimeException )
402 {
403 vos::OGuard aGuard(Application::GetSolarMutex());
404 CHECK_FOR_DEFUNC( XAccessibleContext );
405
406 // get the caption frame, and insert label relations into helper
407
408 AccessibleRelationSetHelper* pHelper = new AccessibleRelationSetHelper();
409
410 SwFlyFrm* pFlyFrm = getFlyFrm();
411 DBG_ASSERT( pFlyFrm != NULL, "fly frame expected" );
412
413 SwFlyFrm* pCaptionFrm = NULL;
414 const SwFrmFmt* pFrm = pFlyFrm ->GetFmt()->GetCaptionFmt();
415 if (pFrm)
416 {
417 SwClientIter aIter (*(SwModify*)pFrm);
418 pCaptionFrm = (SwFlyFrm*)aIter.First( TYPE ( SwFlyFrm ));
419 }
420 if(pCaptionFrm!=NULL)
421 {
422 pHelper->AddRelation( makeRelation( AccessibleRelationType::DESCRIBED_BY, pCaptionFrm ) );
423 }
424
425 return pHelper;
426 }
427