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 #include <comphelper/accessiblekeybindinghelper.hxx> 27 #include <swurl.hxx> 28 #include <vos/mutex.hxx> 29 #include <vcl/svapp.hxx> 30 #include <ndtxt.hxx> 31 #include <txtinet.hxx> 32 #include <accpara.hxx> 33 #include <acchyperlink.hxx> 34 35 #include <comphelper/processfactory.hxx> 36 #ifndef _COM_SUN_STAR_FRAME_XDESKTOP_HPP_ 37 #include <com/sun/star/frame/XDesktop.hpp> 38 #endif 39 #ifndef _COM_SUN_STAR_FRAME_XCOMPONENTLOADER_HPP_ 40 #include <com/sun/star/frame/XComponentLoader.hpp> 41 #endif 42 #ifndef _COM_SUN_STAR_DOCUMENT_XLINKTARGETSUPPLIER_HPP_ 43 #include <com/sun/star/document/XLinkTargetSupplier.hpp> 44 #endif 45 46 using namespace ::com::sun::star; 47 using namespace ::com::sun::star::accessibility; 48 using ::rtl::OUString; 49 using ::com::sun::star::lang::IndexOutOfBoundsException; 50 51 SwAccessibleHyperlink::SwAccessibleHyperlink( sal_uInt16 nHPos, 52 SwAccessibleParagraph *p, sal_Int32 nStt, sal_Int32 nEnd ) : 53 nHintPos( nHPos ), 54 xPara( p ), 55 nStartIdx( nStt ), 56 nEndIdx( nEnd ) 57 { 58 } 59 60 const SwTxtAttr *SwAccessibleHyperlink::GetTxtAttr() const 61 { 62 const SwTxtAttr *pTxtAttr = 0; 63 if( xPara.isValid() && xPara->GetMap() ) 64 { 65 const SwTxtNode *pTxtNd = xPara->GetTxtNode(); 66 const SwpHints *pHints = pTxtNd->GetpSwpHints(); 67 if( pHints && nHintPos < pHints->Count() ) 68 { 69 const SwTxtAttr *pHt = (*pHints)[nHintPos]; 70 if( RES_TXTATR_INETFMT == pHt->Which() ) 71 pTxtAttr = pHt; 72 } 73 } 74 75 return pTxtAttr; 76 } 77 78 79 // XAccessibleAction 80 sal_Int32 SAL_CALL SwAccessibleHyperlink::getAccessibleActionCount() 81 throw (uno::RuntimeException) 82 { 83 return isValid() ? 1 : 0; 84 } 85 86 sal_Bool SAL_CALL SwAccessibleHyperlink::doAccessibleAction( sal_Int32 nIndex ) 87 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 88 { 89 vos::OGuard aGuard(Application::GetSolarMutex()); 90 91 sal_Bool bRet = sal_False; 92 93 if(nIndex != 0) 94 throw new IndexOutOfBoundsException; 95 const SwTxtAttr *pTxtAttr = GetTxtAttr(); 96 if( pTxtAttr /*&& 0 == nIndex*/ ) 97 { 98 const SwFmtINetFmt& rINetFmt = pTxtAttr->GetINetFmt(); 99 if( rINetFmt.GetValue().Len() ) 100 { 101 ViewShell *pVSh = xPara->GetShell(); 102 if( pVSh ) 103 { 104 LoadURL( rINetFmt.GetValue(), pVSh, URLLOAD_NOFILTER, 105 &rINetFmt.GetTargetFrame() ); 106 ASSERT( pTxtAttr == rINetFmt.GetTxtINetFmt(), 107 "lost my txt attr" ); 108 const SwTxtINetFmt* pTxtAttr2 = rINetFmt.GetTxtINetFmt(); 109 if( pTxtAttr2 ) 110 { 111 const_cast<SwTxtINetFmt*>(pTxtAttr2)->SetVisited(true); 112 const_cast<SwTxtINetFmt*>(pTxtAttr2)->SetVisitedValid(true); 113 } 114 bRet = sal_True; 115 } 116 } 117 } 118 119 return bRet; 120 } 121 122 OUString SAL_CALL SwAccessibleHyperlink::getAccessibleActionDescription( 123 sal_Int32 nIndex ) 124 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 125 { 126 OUString sDesc; 127 128 if(nIndex != 0) 129 throw new IndexOutOfBoundsException; 130 const SwTxtAttr *pTxtAttr = GetTxtAttr(); 131 if( pTxtAttr /*&& 0 == nIndex*/ ) 132 { 133 const SwFmtINetFmt& rINetFmt = pTxtAttr->GetINetFmt(); 134 sDesc = OUString( rINetFmt.GetValue() ); 135 } 136 return sDesc; 137 } 138 139 uno::Reference< XAccessibleKeyBinding > SAL_CALL 140 SwAccessibleHyperlink::getAccessibleActionKeyBinding( sal_Int32 ) 141 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 142 { 143 uno::Reference< XAccessibleKeyBinding > xKeyBinding; 144 145 if( isValid() /*&& 0 == nIndex*/ ) 146 { 147 ::comphelper::OAccessibleKeyBindingHelper* pKeyBindingHelper = 148 new ::comphelper::OAccessibleKeyBindingHelper(); 149 xKeyBinding = pKeyBindingHelper; 150 151 awt::KeyStroke aKeyStroke; 152 aKeyStroke.Modifiers = 0; 153 aKeyStroke.KeyCode = KEY_RETURN; 154 aKeyStroke.KeyChar = 0; 155 aKeyStroke.KeyFunc = 0; 156 pKeyBindingHelper->AddKeyBinding( aKeyStroke ); 157 } 158 159 return xKeyBinding; 160 } 161 162 // XAccessibleHyperlink 163 uno::Any SAL_CALL SwAccessibleHyperlink::getAccessibleActionAnchor( 164 sal_Int32 nIndex) 165 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 166 { 167 uno::Any aRet; 168 if(nIndex != 0) 169 throw new IndexOutOfBoundsException; 170 //End Added. 171 ::rtl::OUString text = OUString( xPara->GetString() ); 172 ::rtl::OUString retText = text.copy(nStartIdx, nEndIdx - nStartIdx); 173 aRet <<= retText; 174 return aRet; 175 } 176 177 uno::Any SAL_CALL SwAccessibleHyperlink::getAccessibleActionObject( 178 sal_Int32 nIndex ) 179 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 180 { 181 if(nIndex != 0) 182 throw new IndexOutOfBoundsException; 183 //End Added. 184 const SwTxtAttr *pTxtAttr = GetTxtAttr(); 185 ::rtl::OUString retText; 186 if( pTxtAttr /*&& 0 == nIndex*/ ) 187 { 188 const SwFmtINetFmt& rINetFmt = pTxtAttr->GetINetFmt(); 189 retText = OUString( rINetFmt.GetValue() ); 190 } 191 uno::Any aRet; 192 aRet <<= retText; 193 return aRet; 194 } 195 196 sal_Int32 SAL_CALL SwAccessibleHyperlink::getStartIndex() 197 throw (uno::RuntimeException) 198 { 199 return nStartIdx; 200 } 201 202 sal_Int32 SAL_CALL SwAccessibleHyperlink::getEndIndex() 203 throw (uno::RuntimeException) 204 { 205 return nEndIdx; 206 } 207 208 sal_Bool SAL_CALL SwAccessibleHyperlink::isValid( ) 209 throw (uno::RuntimeException) 210 { 211 vos::OGuard aGuard(Application::GetSolarMutex()); 212 // return xPara.isValid(); 213 if (xPara.isValid()) 214 { 215 const SwTxtAttr *pTxtAttr = GetTxtAttr(); 216 ::rtl::OUString sText; 217 if( pTxtAttr ) 218 { 219 const SwFmtINetFmt& rINetFmt = pTxtAttr->GetINetFmt(); 220 sText = OUString( rINetFmt.GetValue() ); 221 ::rtl::OUString sToken = ::rtl::OUString::createFromAscii("#"); 222 sal_Int32 nPos = sText.indexOf(sToken); 223 if (nPos==0)//document link 224 { 225 uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); 226 if( ! xFactory.is() ) 227 return sal_False; 228 uno::Reference< com::sun::star::frame::XDesktop > xDesktop( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), 229 uno::UNO_QUERY ); 230 if( !xDesktop.is() ) 231 return sal_False; 232 uno::Reference< lang::XComponent > xComp; 233 xComp = xDesktop->getCurrentComponent(); 234 if( !xComp.is() ) 235 return sal_False; 236 uno::Reference< com::sun::star::document::XLinkTargetSupplier > xLTS(xComp, uno::UNO_QUERY); 237 if ( !xLTS.is()) 238 return sal_False; 239 240 uno::Reference< ::com::sun::star::container::XNameAccess > xLinks = xLTS->getLinks(); 241 uno::Reference< ::com::sun::star::container::XNameAccess > xSubLinks; 242 const uno::Sequence< OUString > aNames( xLinks->getElementNames() ); 243 const sal_uLong nLinks = aNames.getLength(); 244 const OUString* pNames = aNames.getConstArray(); 245 246 for( sal_uLong i = 0; i < nLinks; i++ ) 247 { 248 uno::Any aAny; 249 OUString aLink( *pNames++ ); 250 aAny = xLinks->getByName( aLink ); 251 aAny >>= xSubLinks; 252 if (xSubLinks->hasByName(sText.copy(1)) ) 253 return sal_True; 254 } 255 } 256 else//internet 257 return sal_True; 258 } 259 }//xpara valid 260 return sal_False; 261 } 262 263 void SwAccessibleHyperlink::Invalidate() 264 { 265 vos::OGuard aGuard(Application::GetSolarMutex()); 266 xPara = 0; 267 } 268 269