/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_editeng.hxx" #include #include #include #include "AccessibleHyperlink.hxx" #include "editeng/unoedprx.hxx" #include #include using namespace ::com::sun::star; //------------------------------------------------------------------------ // // AccessibleHyperlink implementation // //------------------------------------------------------------------------ namespace accessibility { AccessibleHyperlink::AccessibleHyperlink( SvxAccessibleTextAdapter& r, SvxFieldItem* p, sal_uInt16 nP, sal_uInt16 nR, sal_Int32 nStt, sal_Int32 nEnd, const ::rtl::OUString& rD ) : rTA( r ) { pFld = p; nPara = nP; nRealIdx = nR; nStartIdx = nStt; nEndIdx = nEnd; aDescription = rD; } AccessibleHyperlink::~AccessibleHyperlink() { delete pFld; } // XAccessibleAction sal_Int32 SAL_CALL AccessibleHyperlink::getAccessibleActionCount() throw (uno::RuntimeException) { return isValid() ? 1 : 0; } sal_Bool SAL_CALL AccessibleHyperlink::doAccessibleAction( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) { sal_Bool bRet = sal_False; if ( isValid() && ( nIndex == 0 ) ) { rTA.FieldClicked( *pFld, nPara, nRealIdx ); bRet = sal_True; } return bRet; } ::rtl::OUString SAL_CALL AccessibleHyperlink::getAccessibleActionDescription( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) { ::rtl::OUString aDesc; if ( isValid() && ( nIndex == 0 ) ) aDesc = aDescription; return aDesc; } uno::Reference< ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL AccessibleHyperlink::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) { uno::Reference< ::com::sun::star::accessibility::XAccessibleKeyBinding > xKeyBinding; if( isValid() && ( nIndex == 0 ) ) { ::comphelper::OAccessibleKeyBindingHelper* pKeyBindingHelper = new ::comphelper::OAccessibleKeyBindingHelper(); xKeyBinding = pKeyBindingHelper; awt::KeyStroke aKeyStroke; aKeyStroke.Modifiers = 0; aKeyStroke.KeyCode = KEY_RETURN; aKeyStroke.KeyChar = 0; aKeyStroke.KeyFunc = 0; pKeyBindingHelper->AddKeyBinding( aKeyStroke ); } return xKeyBinding; } // XAccessibleHyperlink uno::Any SAL_CALL AccessibleHyperlink::getAccessibleActionAnchor( sal_Int32 /*nIndex*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) { return uno::Any(); } uno::Any SAL_CALL AccessibleHyperlink::getAccessibleActionObject( sal_Int32 /*nIndex*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) { return uno::Any(); } sal_Int32 SAL_CALL AccessibleHyperlink::getStartIndex() throw (uno::RuntimeException) { return nStartIdx; } sal_Int32 SAL_CALL AccessibleHyperlink::getEndIndex() throw (uno::RuntimeException) { return nEndIdx; } sal_Bool SAL_CALL AccessibleHyperlink::isValid( ) throw (uno::RuntimeException) { return rTA.IsValid(); } } // end of namespace accessibility //------------------------------------------------------------------------ // MT IA2: Accessiblehyperlink.hxx from IA2 CWS - meanwhile we also introduced one in DEV300 (above) // Keeping this for reference - we probably should get support for image maps in our implementation... /* class SVX_DLLPUBLIC SvxAccessibleHyperlink : public ::cppu::WeakImplHelper1< ::com::sun::star::accessibility::XAccessibleHyperlink > { SvxURLField* mpField; sal_Int32 nStartIdx; sal_Int32 nEndIdx; ImageMap* mpImageMap; SdrObject* m_pShape; ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > shapeParent; public: SvxAccessibleHyperlink(){}; //SvxAccessibleHyperlink(::rtl::OUString name, const Imagemap* pImageMap); SvxAccessibleHyperlink(const SvxURLField* p, sal_Int32 nStt, sal_Int32 nEnd); SvxAccessibleHyperlink(SdrObject* p, ::accessibility::AccessibleShape* pAcc); virtual ~SvxAccessibleHyperlink(); //void setImageMap(ImageMap* pMap); //void setXAccessibleImage(::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > parent); ::rtl::OUString GetHyperlinkURL(sal_Int32 nIndex) throw (::com::sun::star::lang::IndexOutOfBoundsException); sal_Bool IsValidHyperlink(); // XAccessibleAction virtual sal_Int32 SAL_CALL getAccessibleActionCount() throw (::com::sun::star::uno::RuntimeException); virtual sal_Bool SAL_CALL doAccessibleAction( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getAccessibleActionDescription( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); // XAccessibleHyperlink virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleActionAnchor( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleActionObject( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); virtual sal_Int32 SAL_CALL getStartIndex() throw (::com::sun::star::uno::RuntimeException); virtual sal_Int32 SAL_CALL getEndIndex() throw (::com::sun::star::uno::RuntimeException); virtual sal_Bool SAL_CALL isValid( ) throw (::com::sun::star::uno::RuntimeException); }; SvxAccessibleHyperlink::SvxAccessibleHyperlink( const SvxURLField *p, sal_Int32 nStt, sal_Int32 nEnd ) : nStartIdx( nStt ), nEndIdx( nEnd ), m_pShape(NULL), shapeParent(NULL) { if(p) mpField = (SvxURLField*)p->Clone(); else mpField = NULL; } SvxAccessibleHyperlink::SvxAccessibleHyperlink(SdrObject* p, ::accessibility::AccessibleShape* pAcc) : nStartIdx( -1 ), nEndIdx( -1 ), mpField(NULL), m_pShape(p) { mpImageMap = m_pShape->GetModel()->GetImageMapForObject(m_pShape); shapeParent = dynamic_cast< XAccessible* >(pAcc); } SvxAccessibleHyperlink::~SvxAccessibleHyperlink() { if(mpField) delete mpField; } ::rtl::OUString SvxAccessibleHyperlink::GetHyperlinkURL(sal_Int32 nIndex) throw (::com::sun::star::lang::IndexOutOfBoundsException) { if( mpField ) { if (nIndex != 0) throw ::com::sun::star::lang::IndexOutOfBoundsException(); return ::rtl::OUString( mpField->GetURL() ); } else if (mpImageMap) { if (nIndex < 0 || nIndex >=mpImageMap->GetIMapObjectCount()) throw IndexOutOfBoundsException(); IMapObject* pMapObj = mpImageMap->GetIMapObject(sal_uInt16(nIndex)); if (pMapObj->GetURL().Len()) return ::rtl::OUString( pMapObj->GetURL() ); } else { if (nIndex != 0) throw ::com::sun::star::lang::IndexOutOfBoundsException(); SdrUnoObj* pUnoCtrl = dynamic_cast< SdrUnoObj* >( m_pShape ); if(pUnoCtrl) { try { uno::Reference< awt::XControlModel > xControlModel( pUnoCtrl->GetUnoControlModel(), uno::UNO_QUERY_THROW ); uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY_THROW ); uno::Reference< beans::XPropertySetInfo > xPropInfo( xPropSet->getPropertySetInfo(), uno::UNO_QUERY_THROW ); form::FormButtonType eButtonType = form::FormButtonType_URL; const ::rtl::OUString sButtonType( RTL_CONSTASCII_USTRINGPARAM( "ButtonType" ) ); if(xPropInfo->hasPropertyByName( sButtonType ) && (xPropSet->getPropertyValue( sButtonType ) >>= eButtonType ) ) { ::rtl::OUString aString; // URL const ::rtl::OUString sTargetURL(RTL_CONSTASCII_USTRINGPARAM( "TargetURL" )); if(xPropInfo->hasPropertyByName(sTargetURL)) { if( xPropSet->getPropertyValue(sTargetURL) >>= aString ) return aString; } } } catch( uno::Exception& ) { } } // If hyperlink can't be got from sdrobject, query the corresponding document to retrieve the link info uno::Reference< XAccessibleGroupPosition > xGroupPosition (shapeParent, uno::UNO_QUERY); if (xGroupPosition.is()) return xGroupPosition->getObjectLink( uno::makeAny( shapeParent ) ); } return ::rtl::OUString(); } // Just check whether the first hyperlink is valid sal_Bool SvxAccessibleHyperlink::IsValidHyperlink() { ::rtl::OUString url = GetHyperlinkURL(0); if (url.getLength() > 0) return sal_True; else return sal_False; } // XAccessibleAction sal_Int32 SAL_CALL SvxAccessibleHyperlink::getAccessibleActionCount() throw (RuntimeException) { if (mpImageMap) return mpImageMap->GetIMapObjectCount(); else return 1; // only shape link or url field //return mpField ? 1 : (mpImageMap ? mpImageMap->GetIMapObjectCount() : 0); } sal_Bool SAL_CALL SvxAccessibleHyperlink::doAccessibleAction( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); sal_Bool bRet = sal_False; OUString url = GetHyperlinkURL(nIndex); if( url.getLength() > 0 ) { SfxStringItem aStrItem(SID_FILE_NAME, url); const SfxObjectShell* pDocSh = SfxObjectShell::Current(); if( pDocSh ) { SfxMedium* pSfxMedium = pDocSh->GetMedium(); if( pSfxMedium) { SfxStringItem aReferer(SID_REFERER, pSfxMedium->GetName()); SfxBoolItem aBrowseItem( SID_BROWSE, TRUE ); SfxViewFrame* pFrame = SfxViewFrame::Current(); if( pFrame ) { pFrame->GetDispatcher()->Execute(SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aStrItem, &aBrowseItem, &aReferer, 0L); bRet = sal_True; } } } } return bRet; } OUString SAL_CALL SvxAccessibleHyperlink::getAccessibleActionDescription( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) { return GetHyperlinkURL(nIndex); } ::com::sun::star::uno::Reference< XAccessibleKeyBinding > SAL_CALL SvxAccessibleHyperlink::getAccessibleActionKeyBinding( sal_Int32 ) throw (IndexOutOfBoundsException, RuntimeException) { ::com::sun::star::uno::Reference< XAccessibleKeyBinding > xKeyBinding; if( mpField || m_pShape) { ::comphelper::OAccessibleKeyBindingHelper* pKeyBindingHelper = new ::comphelper::OAccessibleKeyBindingHelper(); xKeyBinding = pKeyBindingHelper; ::com::sun::star::awt::KeyStroke aKeyStroke; aKeyStroke.Modifiers = 0; aKeyStroke.KeyCode = KEY_RETURN; aKeyStroke.KeyChar = 0; aKeyStroke.KeyFunc = 0; pKeyBindingHelper->AddKeyBinding( aKeyStroke ); } return xKeyBinding; } // XAccessibleHyperlink Any SAL_CALL SvxAccessibleHyperlink::getAccessibleActionAnchor( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) { Any aRet; ::rtl::OUString retText; if(mpField && nIndex == 0) { retText = mpField->GetRepresentation(); aRet <<= retText; return aRet; } else if(mpImageMap) { IMapObject* pMapObj = mpImageMap->GetIMapObject(sal_uInt16(nIndex)); if(pMapObj && pMapObj->GetURL().Len()) aRet <<= shapeParent; return aRet; } else if (nIndex == 0) { aRet <<= shapeParent; return aRet; } return aRet; } Any SAL_CALL SvxAccessibleHyperlink::getAccessibleActionObject( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) { ::rtl::OUString retText = GetHyperlinkURL(nIndex); Any aRet; aRet <<= retText; return aRet; } sal_Int32 SAL_CALL SvxAccessibleHyperlink::getStartIndex() throw (RuntimeException) { return nStartIdx; } sal_Int32 SAL_CALL SvxAccessibleHyperlink::getEndIndex() throw (RuntimeException) { return nEndIdx; } sal_Bool SAL_CALL SvxAccessibleHyperlink::isValid( ) throw (RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); //return mpField ? sal_True: ( mpImageMap ? sal_True : sal_False ); if (mpField || m_pShape) return sal_True; else return sal_False; } */