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 55 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 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 99 SwAccessibleNoTextFrame::~SwAccessibleNoTextFrame() 100 { 101 } 102 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 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# 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 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 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 ==================================================== 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 278 OUString SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageDescription() 279 throw ( uno::RuntimeException ) 280 { 281 return getAccessibleDescription(); 282 } 283 284 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageHeight( ) 285 throw ( uno::RuntimeException ) 286 { 287 return getSize().Height; 288 } 289 290 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageWidth( ) 291 throw ( uno::RuntimeException ) 292 { 293 return getSize().Width; 294 } 295 //===== XAccesibleText ================================================== 296 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 297 sal_Bool SAL_CALL SwAccessibleNoTextFrame::setCaretPosition( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;} 298 sal_Unicode SAL_CALL SwAccessibleNoTextFrame::getCharacter( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;} 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 } 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 } 308 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 309 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getIndexAtPoint( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException){return 0;} 310 ::rtl::OUString SAL_CALL SwAccessibleNoTextFrame::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();} 311 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 312 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 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;} 314 ::rtl::OUString SAL_CALL SwAccessibleNoTextFrame::getText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();} 315 ::rtl::OUString SAL_CALL SwAccessibleNoTextFrame::getTextRange( sal_Int32 , sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return OUString();} 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 } 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 } 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 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 // 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 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 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 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 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