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