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_editeng.hxx" 26 27 #include <com/sun/star/uno/Any.hxx> 28 #include <com/sun/star/uno/Reference.hxx> 29 #include <comphelper/accessiblekeybindinghelper.hxx> 30 31 #include "AccessibleHyperlink.hxx" 32 #include "editeng/unoedprx.hxx" 33 #include <editeng/flditem.hxx> 34 #include <vcl/keycodes.hxx> 35 36 using namespace ::com::sun::star; 37 38 39 //------------------------------------------------------------------------ 40 // 41 // AccessibleHyperlink implementation 42 // 43 //------------------------------------------------------------------------ 44 45 namespace accessibility 46 { 47 48 AccessibleHyperlink::AccessibleHyperlink( SvxAccessibleTextAdapter& r, SvxFieldItem* p, sal_uInt16 nP, sal_uInt16 nR, sal_Int32 nStt, sal_Int32 nEnd, const ::rtl::OUString& rD ) 49 : rTA( r ) 50 { 51 pFld = p; 52 nPara = nP; 53 nRealIdx = nR; 54 nStartIdx = nStt; 55 nEndIdx = nEnd; 56 aDescription = rD; 57 } 58 59 AccessibleHyperlink::~AccessibleHyperlink() 60 { 61 delete pFld; 62 } 63 64 // XAccessibleAction 65 sal_Int32 SAL_CALL AccessibleHyperlink::getAccessibleActionCount() throw (uno::RuntimeException) 66 { 67 return isValid() ? 1 : 0; 68 } 69 70 sal_Bool SAL_CALL AccessibleHyperlink::doAccessibleAction( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 71 { 72 sal_Bool bRet = sal_False; 73 if ( isValid() && ( nIndex == 0 ) ) 74 { 75 rTA.FieldClicked( *pFld, nPara, nRealIdx ); 76 bRet = sal_True; 77 } 78 return bRet; 79 } 80 81 ::rtl::OUString SAL_CALL AccessibleHyperlink::getAccessibleActionDescription( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 82 { 83 ::rtl::OUString aDesc; 84 85 if ( isValid() && ( nIndex == 0 ) ) 86 aDesc = aDescription; 87 88 return aDesc; 89 } 90 91 uno::Reference< ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL AccessibleHyperlink::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 92 { 93 uno::Reference< ::com::sun::star::accessibility::XAccessibleKeyBinding > xKeyBinding; 94 95 if( isValid() && ( nIndex == 0 ) ) 96 { 97 ::comphelper::OAccessibleKeyBindingHelper* pKeyBindingHelper = new ::comphelper::OAccessibleKeyBindingHelper(); 98 xKeyBinding = pKeyBindingHelper; 99 100 awt::KeyStroke aKeyStroke; 101 aKeyStroke.Modifiers = 0; 102 aKeyStroke.KeyCode = KEY_RETURN; 103 aKeyStroke.KeyChar = 0; 104 aKeyStroke.KeyFunc = 0; 105 pKeyBindingHelper->AddKeyBinding( aKeyStroke ); 106 } 107 108 return xKeyBinding; 109 } 110 111 // XAccessibleHyperlink 112 uno::Any SAL_CALL AccessibleHyperlink::getAccessibleActionAnchor( sal_Int32 /*nIndex*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 113 { 114 return uno::Any(); 115 } 116 117 uno::Any SAL_CALL AccessibleHyperlink::getAccessibleActionObject( sal_Int32 /*nIndex*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 118 { 119 return uno::Any(); 120 } 121 122 sal_Int32 SAL_CALL AccessibleHyperlink::getStartIndex() throw (uno::RuntimeException) 123 { 124 return nStartIdx; 125 } 126 127 sal_Int32 SAL_CALL AccessibleHyperlink::getEndIndex() throw (uno::RuntimeException) 128 { 129 return nEndIdx; 130 } 131 132 sal_Bool SAL_CALL AccessibleHyperlink::isValid( ) throw (uno::RuntimeException) 133 { 134 return rTA.IsValid(); 135 } 136 137 } // end of namespace accessibility 138 139 //------------------------------------------------------------------------ 140 141 // MT IA2: Accessiblehyperlink.hxx from IA2 CWS - meanwhile we also introduced one in DEV300 (above) 142 // Keeping this for reference - we probably should get support for image maps in our implementation... 143 144 //IAccessibility2 Implementation 2009----- 145 146 /* 147 148 class SVX_DLLPUBLIC SvxAccessibleHyperlink : 149 public ::cppu::WeakImplHelper1< 150 ::com::sun::star::accessibility::XAccessibleHyperlink > 151 { 152 SvxURLField* mpField; 153 sal_Int32 nStartIdx; 154 sal_Int32 nEndIdx; 155 156 ImageMap* mpImageMap; 157 SdrObject* m_pShape; 158 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > shapeParent; 159 160 public: 161 162 SvxAccessibleHyperlink(){}; 163 //SvxAccessibleHyperlink(::rtl::OUString name, const Imagemap* pImageMap); 164 SvxAccessibleHyperlink(const SvxURLField* p, sal_Int32 nStt, sal_Int32 nEnd); 165 SvxAccessibleHyperlink(SdrObject* p, ::accessibility::AccessibleShape* pAcc); 166 virtual ~SvxAccessibleHyperlink(); 167 //void setImageMap(ImageMap* pMap); 168 //void setXAccessibleImage(::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > parent); 169 ::rtl::OUString GetHyperlinkURL(sal_Int32 nIndex) throw (::com::sun::star::lang::IndexOutOfBoundsException); 170 sal_Bool IsValidHyperlink(); 171 172 // XAccessibleAction 173 virtual sal_Int32 SAL_CALL getAccessibleActionCount() 174 throw (::com::sun::star::uno::RuntimeException); 175 virtual sal_Bool SAL_CALL doAccessibleAction( sal_Int32 nIndex ) 176 throw (::com::sun::star::lang::IndexOutOfBoundsException, 177 ::com::sun::star::uno::RuntimeException); 178 virtual ::rtl::OUString SAL_CALL getAccessibleActionDescription( 179 sal_Int32 nIndex ) 180 throw (::com::sun::star::lang::IndexOutOfBoundsException, 181 ::com::sun::star::uno::RuntimeException); 182 virtual ::com::sun::star::uno::Reference< 183 ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL 184 getAccessibleActionKeyBinding( sal_Int32 nIndex ) 185 throw (::com::sun::star::lang::IndexOutOfBoundsException, 186 ::com::sun::star::uno::RuntimeException); 187 188 // XAccessibleHyperlink 189 virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleActionAnchor( 190 sal_Int32 nIndex ) 191 throw (::com::sun::star::lang::IndexOutOfBoundsException, 192 ::com::sun::star::uno::RuntimeException); 193 virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleActionObject( 194 sal_Int32 nIndex ) 195 throw (::com::sun::star::lang::IndexOutOfBoundsException, 196 ::com::sun::star::uno::RuntimeException); 197 virtual sal_Int32 SAL_CALL getStartIndex() 198 throw (::com::sun::star::uno::RuntimeException); 199 virtual sal_Int32 SAL_CALL getEndIndex() 200 throw (::com::sun::star::uno::RuntimeException); 201 virtual sal_Bool SAL_CALL isValid( ) 202 throw (::com::sun::star::uno::RuntimeException); 203 }; 204 205 206 SvxAccessibleHyperlink::SvxAccessibleHyperlink( const SvxURLField *p, 207 sal_Int32 nStt, sal_Int32 nEnd ) : 208 nStartIdx( nStt ), 209 nEndIdx( nEnd ), 210 m_pShape(NULL), 211 shapeParent(NULL) 212 { 213 if(p) 214 mpField = (SvxURLField*)p->Clone(); 215 else 216 mpField = NULL; 217 } 218 219 SvxAccessibleHyperlink::SvxAccessibleHyperlink(SdrObject* p, 220 ::accessibility::AccessibleShape* pAcc) : 221 nStartIdx( -1 ), 222 nEndIdx( -1 ), 223 mpField(NULL), 224 m_pShape(p) 225 { 226 mpImageMap = m_pShape->GetModel()->GetImageMapForObject(m_pShape); 227 shapeParent = dynamic_cast< XAccessible* >(pAcc); 228 } 229 230 SvxAccessibleHyperlink::~SvxAccessibleHyperlink() 231 { 232 if(mpField) 233 delete mpField; 234 } 235 236 ::rtl::OUString SvxAccessibleHyperlink::GetHyperlinkURL(sal_Int32 nIndex) throw (::com::sun::star::lang::IndexOutOfBoundsException) 237 { 238 if( mpField ) 239 { 240 if (nIndex != 0) 241 throw ::com::sun::star::lang::IndexOutOfBoundsException(); 242 return ::rtl::OUString( mpField->GetURL() ); 243 } 244 else if (mpImageMap) 245 { 246 if (nIndex < 0 || nIndex >=mpImageMap->GetIMapObjectCount()) 247 throw IndexOutOfBoundsException(); 248 249 IMapObject* pMapObj = mpImageMap->GetIMapObject(sal_uInt16(nIndex)); 250 if (pMapObj->GetURL().Len()) 251 return ::rtl::OUString( pMapObj->GetURL() ); 252 } 253 else 254 { 255 if (nIndex != 0) 256 throw ::com::sun::star::lang::IndexOutOfBoundsException(); 257 258 SdrUnoObj* pUnoCtrl = dynamic_cast< SdrUnoObj* >( m_pShape ); 259 260 if(pUnoCtrl) 261 { 262 try 263 { 264 uno::Reference< awt::XControlModel > xControlModel( pUnoCtrl->GetUnoControlModel(), uno::UNO_QUERY_THROW ); 265 uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY_THROW ); 266 uno::Reference< beans::XPropertySetInfo > xPropInfo( xPropSet->getPropertySetInfo(), uno::UNO_QUERY_THROW ); 267 268 form::FormButtonType eButtonType = form::FormButtonType_URL; 269 const ::rtl::OUString sButtonType( RTL_CONSTASCII_USTRINGPARAM( "ButtonType" ) ); 270 if(xPropInfo->hasPropertyByName( sButtonType ) && (xPropSet->getPropertyValue( sButtonType ) >>= eButtonType ) ) 271 { 272 ::rtl::OUString aString; 273 274 // URL 275 const ::rtl::OUString sTargetURL(RTL_CONSTASCII_USTRINGPARAM( "TargetURL" )); 276 if(xPropInfo->hasPropertyByName(sTargetURL)) 277 { 278 if( xPropSet->getPropertyValue(sTargetURL) >>= aString ) 279 return aString; 280 } 281 } 282 } 283 catch( uno::Exception& ) 284 { 285 } 286 } 287 // If hyperlink can't be got from sdrobject, query the corresponding document to retrieve the link info 288 uno::Reference< XAccessibleGroupPosition > xGroupPosition (shapeParent, uno::UNO_QUERY); 289 if (xGroupPosition.is()) 290 return xGroupPosition->getObjectLink( uno::makeAny( shapeParent ) ); 291 } 292 return ::rtl::OUString(); 293 } 294 295 // Just check whether the first hyperlink is valid 296 sal_Bool SvxAccessibleHyperlink::IsValidHyperlink() 297 { 298 ::rtl::OUString url = GetHyperlinkURL(0); 299 if (url.getLength() > 0) 300 return sal_True; 301 else 302 return sal_False; 303 } 304 // XAccessibleAction 305 sal_Int32 SAL_CALL SvxAccessibleHyperlink::getAccessibleActionCount() 306 throw (RuntimeException) 307 { 308 if (mpImageMap) 309 return mpImageMap->GetIMapObjectCount(); 310 else 311 return 1; // only shape link or url field 312 313 //return mpField ? 1 : (mpImageMap ? mpImageMap->GetIMapObjectCount() : 0); 314 } 315 316 sal_Bool SAL_CALL SvxAccessibleHyperlink::doAccessibleAction( sal_Int32 nIndex ) 317 throw (IndexOutOfBoundsException, RuntimeException) 318 { 319 vos::OGuard aGuard(Application::GetSolarMutex()); 320 321 sal_Bool bRet = sal_False; 322 323 OUString url = GetHyperlinkURL(nIndex); 324 325 if( url.getLength() > 0 ) 326 { 327 SfxStringItem aStrItem(SID_FILE_NAME, url); 328 const SfxObjectShell* pDocSh = SfxObjectShell::Current(); 329 if( pDocSh ) 330 { 331 SfxMedium* pSfxMedium = pDocSh->GetMedium(); 332 if( pSfxMedium) 333 { 334 SfxStringItem aReferer(SID_REFERER, pSfxMedium->GetName()); 335 SfxBoolItem aBrowseItem( SID_BROWSE, TRUE ); 336 SfxViewFrame* pFrame = SfxViewFrame::Current(); 337 if( pFrame ) 338 { 339 pFrame->GetDispatcher()->Execute(SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, 340 &aStrItem, &aBrowseItem, &aReferer, 0L); 341 bRet = sal_True; 342 } 343 } 344 } 345 } 346 347 return bRet; 348 } 349 350 OUString SAL_CALL SvxAccessibleHyperlink::getAccessibleActionDescription( 351 sal_Int32 nIndex ) 352 throw (IndexOutOfBoundsException, RuntimeException) 353 { 354 return GetHyperlinkURL(nIndex); 355 } 356 357 ::com::sun::star::uno::Reference< XAccessibleKeyBinding > SAL_CALL 358 SvxAccessibleHyperlink::getAccessibleActionKeyBinding( sal_Int32 ) 359 throw (IndexOutOfBoundsException, RuntimeException) 360 { 361 ::com::sun::star::uno::Reference< XAccessibleKeyBinding > xKeyBinding; 362 363 if( mpField || m_pShape) 364 { 365 ::comphelper::OAccessibleKeyBindingHelper* pKeyBindingHelper = 366 new ::comphelper::OAccessibleKeyBindingHelper(); 367 xKeyBinding = pKeyBindingHelper; 368 369 ::com::sun::star::awt::KeyStroke aKeyStroke; 370 aKeyStroke.Modifiers = 0; 371 aKeyStroke.KeyCode = KEY_RETURN; 372 aKeyStroke.KeyChar = 0; 373 aKeyStroke.KeyFunc = 0; 374 pKeyBindingHelper->AddKeyBinding( aKeyStroke ); 375 } 376 377 return xKeyBinding; 378 } 379 380 // XAccessibleHyperlink 381 Any SAL_CALL SvxAccessibleHyperlink::getAccessibleActionAnchor( 382 sal_Int32 nIndex ) 383 throw (IndexOutOfBoundsException, RuntimeException) 384 { 385 Any aRet; 386 387 ::rtl::OUString retText; 388 if(mpField && nIndex == 0) 389 { 390 retText = mpField->GetRepresentation(); 391 aRet <<= retText; 392 return aRet; 393 } 394 else if(mpImageMap) 395 { 396 IMapObject* pMapObj = mpImageMap->GetIMapObject(sal_uInt16(nIndex)); 397 if(pMapObj && pMapObj->GetURL().Len()) 398 aRet <<= shapeParent; 399 return aRet; 400 } 401 else if (nIndex == 0) 402 { 403 aRet <<= shapeParent; 404 return aRet; 405 } 406 return aRet; 407 } 408 409 Any SAL_CALL SvxAccessibleHyperlink::getAccessibleActionObject( 410 sal_Int32 nIndex ) 411 throw (IndexOutOfBoundsException, RuntimeException) 412 { 413 ::rtl::OUString retText = GetHyperlinkURL(nIndex); 414 Any aRet; 415 aRet <<= retText; 416 return aRet; 417 } 418 419 sal_Int32 SAL_CALL SvxAccessibleHyperlink::getStartIndex() 420 throw (RuntimeException) 421 { 422 return nStartIdx; 423 } 424 425 sal_Int32 SAL_CALL SvxAccessibleHyperlink::getEndIndex() 426 throw (RuntimeException) 427 { 428 return nEndIdx; 429 } 430 431 sal_Bool SAL_CALL SvxAccessibleHyperlink::isValid( ) 432 throw (RuntimeException) 433 { 434 vos::OGuard aGuard(Application::GetSolarMutex()); 435 //return mpField ? sal_True: ( mpImageMap ? sal_True : sal_False ); 436 if (mpField || m_pShape) 437 return sal_True; 438 else 439 return sal_False; 440 } 441 442 */ 443 444 //-----IAccessibility2 Implementation 2009 445 446 447