1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "vbahyperlink.hxx" 29*cdf0e10cSrcweir #include <vbahelper/helperdecl.hxx> 30*cdf0e10cSrcweir #include <com/sun/star/container/XIndexAccess.hpp> 31*cdf0e10cSrcweir #include <com/sun/star/text/XText.hpp> 32*cdf0e10cSrcweir #include <com/sun/star/text/XTextFieldsSupplier.hpp> 33*cdf0e10cSrcweir #include <com/sun/star/container/XEnumerationAccess.hpp> 34*cdf0e10cSrcweir #include <ooo/vba/office/MsoHyperlinkType.hpp> 35*cdf0e10cSrcweir #include <ooo/vba/msforms/XShape.hpp> 36*cdf0e10cSrcweir #include "vbarange.hxx" 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir using namespace ::ooo::vba; 39*cdf0e10cSrcweir using namespace ::com::sun::star; 40*cdf0e10cSrcweir using ::rtl::OUString; 41*cdf0e10cSrcweir using ::rtl::OUStringBuffer; 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir // ============================================================================ 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir ScVbaHyperlink::ScVbaHyperlink( const uno::Sequence< uno::Any >& rArgs, 46*cdf0e10cSrcweir const uno::Reference< uno::XComponentContext >& rxContext ) throw (lang::IllegalArgumentException) : 47*cdf0e10cSrcweir HyperlinkImpl_BASE( getXSomethingFromArgs< XHelperInterface >( rArgs, 0 ), rxContext ), 48*cdf0e10cSrcweir mxCell( getXSomethingFromArgs< table::XCell >( rArgs, 1, false ) ), 49*cdf0e10cSrcweir mnType( office::MsoHyperlinkType::msoHyperlinkRange ) 50*cdf0e10cSrcweir { 51*cdf0e10cSrcweir uno::Reference< text::XTextFieldsSupplier > xTextFields( mxCell, uno::UNO_QUERY_THROW ); 52*cdf0e10cSrcweir uno::Reference< container::XIndexAccess > xIndex( xTextFields->getTextFields(), uno::UNO_QUERY_THROW ); 53*cdf0e10cSrcweir mxTextField.set( xIndex->getByIndex(0), uno::UNO_QUERY_THROW ); 54*cdf0e10cSrcweir } 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir ScVbaHyperlink::ScVbaHyperlink( const uno::Reference< XHelperInterface >& rxAnchor, 57*cdf0e10cSrcweir const uno::Reference< uno::XComponentContext >& rxContext, 58*cdf0e10cSrcweir const uno::Any& rAddress, const uno::Any& rSubAddress, 59*cdf0e10cSrcweir const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) throw (uno::RuntimeException) : 60*cdf0e10cSrcweir HyperlinkImpl_BASE( rxAnchor, rxContext ) // parent of Hyperlink is the anchor object 61*cdf0e10cSrcweir { 62*cdf0e10cSrcweir // extract parameters, Address must not be empty 63*cdf0e10cSrcweir UrlComponents aUrlComp; 64*cdf0e10cSrcweir OUString aTextToDisplay; 65*cdf0e10cSrcweir if( !(rAddress >>= aUrlComp.first) || (aUrlComp.first.getLength() == 0) ) 66*cdf0e10cSrcweir throw uno::RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot get address" ) ), uno::Reference< uno::XInterface >() ); 67*cdf0e10cSrcweir rSubAddress >>= aUrlComp.second; 68*cdf0e10cSrcweir rScreenTip >>= maScreenTip; 69*cdf0e10cSrcweir rTextToDisplay >>= aTextToDisplay; 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir // get anchor range or anchor shape 72*cdf0e10cSrcweir uno::Reference< excel::XRange > xAnchorRange( rxAnchor, uno::UNO_QUERY ); 73*cdf0e10cSrcweir if( xAnchorRange.is() ) 74*cdf0e10cSrcweir { 75*cdf0e10cSrcweir mnType = office::MsoHyperlinkType::msoHyperlinkRange; 76*cdf0e10cSrcweir // only single ranges are allowed 77*cdf0e10cSrcweir uno::Reference< table::XCellRange > xUnoRange( ScVbaRange::getCellRange( xAnchorRange ), uno::UNO_QUERY_THROW ); 78*cdf0e10cSrcweir // insert the hyperlink into the top-left cell only 79*cdf0e10cSrcweir mxCell.set( xUnoRange->getCellByPosition( 0, 0 ), uno::UNO_SET_THROW ); 80*cdf0e10cSrcweir uno::Reference< text::XText > xText( mxCell, uno::UNO_QUERY_THROW ); 81*cdf0e10cSrcweir // use cell text or URL if no TextToDisplay has been passed 82*cdf0e10cSrcweir if( aTextToDisplay.getLength() == 0 ) 83*cdf0e10cSrcweir { 84*cdf0e10cSrcweir aTextToDisplay = xText->getString(); 85*cdf0e10cSrcweir if( aTextToDisplay.getLength() == 0 ) 86*cdf0e10cSrcweir { 87*cdf0e10cSrcweir OUStringBuffer aBuffer( aUrlComp.first ); 88*cdf0e10cSrcweir if( aUrlComp.second.getLength() > 0 ) 89*cdf0e10cSrcweir aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ) ).append( aUrlComp.second ); 90*cdf0e10cSrcweir aTextToDisplay = aBuffer.makeStringAndClear(); 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir } 93*cdf0e10cSrcweir // create and initialize a new URL text field 94*cdf0e10cSrcweir uno::Reference< lang::XMultiServiceFactory > xFactory( ScVbaRange::getUnoModel( xAnchorRange ), uno::UNO_QUERY_THROW ); 95*cdf0e10cSrcweir uno::Reference< text::XTextContent > xUrlField( xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextField.URL" ) ) ), uno::UNO_QUERY_THROW ); 96*cdf0e10cSrcweir mxTextField.set( xUrlField, uno::UNO_QUERY_THROW ); 97*cdf0e10cSrcweir setUrlComponents( aUrlComp ); 98*cdf0e10cSrcweir setTextToDisplay( aTextToDisplay ); 99*cdf0e10cSrcweir // insert the text field into the document 100*cdf0e10cSrcweir xText->setString( OUString() ); 101*cdf0e10cSrcweir uno::Reference< text::XTextRange > xRange( xText->createTextCursor(), uno::UNO_QUERY_THROW ); 102*cdf0e10cSrcweir xText->insertTextContent( xRange, xUrlField, sal_False ); 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir else 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir uno::Reference< msforms::XShape > xAnchorShape( rxAnchor, uno::UNO_QUERY_THROW ); 107*cdf0e10cSrcweir mnType = office::MsoHyperlinkType::msoHyperlinkShape; 108*cdf0e10cSrcweir // FIXME: insert hyperlink into shape 109*cdf0e10cSrcweir throw uno::RuntimeException(); 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir ScVbaHyperlink::~ScVbaHyperlink() 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir OUString ScVbaHyperlink::getName() throw (uno::RuntimeException) 118*cdf0e10cSrcweir { 119*cdf0e10cSrcweir // it seems this attribute is same as TextToDisplay 120*cdf0e10cSrcweir return getTextToDisplay(); 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir void ScVbaHyperlink::setName( const OUString& rName ) throw (uno::RuntimeException) 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir setTextToDisplay( rName ); 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir OUString ScVbaHyperlink::getAddress() throw (uno::RuntimeException) 129*cdf0e10cSrcweir { 130*cdf0e10cSrcweir return getUrlComponents().first; 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir void ScVbaHyperlink::setAddress( const OUString& rAddress ) throw (uno::RuntimeException) 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir UrlComponents aUrlComp = getUrlComponents(); 136*cdf0e10cSrcweir aUrlComp.first = rAddress; 137*cdf0e10cSrcweir setUrlComponents( aUrlComp ); 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir OUString ScVbaHyperlink::getSubAddress() throw (uno::RuntimeException) 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir return getUrlComponents().second; 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir void ScVbaHyperlink::setSubAddress( const OUString& rSubAddress ) throw (uno::RuntimeException) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir UrlComponents aUrlComp = getUrlComponents(); 148*cdf0e10cSrcweir aUrlComp.second = rSubAddress; 149*cdf0e10cSrcweir setUrlComponents( aUrlComp ); 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir OUString SAL_CALL ScVbaHyperlink::getScreenTip() throw (uno::RuntimeException) 153*cdf0e10cSrcweir { 154*cdf0e10cSrcweir return maScreenTip; 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir void SAL_CALL ScVbaHyperlink::setScreenTip( const OUString& rScreenTip ) throw (uno::RuntimeException) 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir maScreenTip = rScreenTip; 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir OUString ScVbaHyperlink::getTextToDisplay() throw (uno::RuntimeException) 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir ensureTextField(); 165*cdf0e10cSrcweir OUString aTextToDisplay; 166*cdf0e10cSrcweir mxTextField->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ) ) >>= aTextToDisplay; 167*cdf0e10cSrcweir return aTextToDisplay; 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir void ScVbaHyperlink::setTextToDisplay( const OUString& rTextToDisplay ) throw (uno::RuntimeException) 171*cdf0e10cSrcweir { 172*cdf0e10cSrcweir ensureTextField(); 173*cdf0e10cSrcweir mxTextField->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ), uno::Any( rTextToDisplay ) ); 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir sal_Int32 SAL_CALL ScVbaHyperlink::getType() throw (uno::RuntimeException) 177*cdf0e10cSrcweir { 178*cdf0e10cSrcweir return mnType; 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir uno::Reference< excel::XRange > SAL_CALL ScVbaHyperlink::getRange() throw (uno::RuntimeException) 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir if( mnType == office::MsoHyperlinkType::msoHyperlinkRange ) 184*cdf0e10cSrcweir { 185*cdf0e10cSrcweir // if constructed from Hyperlinks object, range has been passed as parent 186*cdf0e10cSrcweir uno::Reference< excel::XRange > xAnchorRange( getParent(), uno::UNO_QUERY ); 187*cdf0e10cSrcweir if( !xAnchorRange.is() ) 188*cdf0e10cSrcweir { 189*cdf0e10cSrcweir // if constructed via service c'tor, create new range based on cell 190*cdf0e10cSrcweir uno::Reference< table::XCellRange > xRange( mxCell, uno::UNO_QUERY_THROW ); 191*cdf0e10cSrcweir // FIXME: need to pass current worksheet as the parent of XRange. 192*cdf0e10cSrcweir xAnchorRange.set( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRange ) ); 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir return xAnchorRange; 195*cdf0e10cSrcweir } 196*cdf0e10cSrcweir // error if called at a shape Hyperlink object 197*cdf0e10cSrcweir throw uno::RuntimeException(); 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir uno::Reference< msforms::XShape > SAL_CALL ScVbaHyperlink::getShape() throw (uno::RuntimeException) 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir // error if called at a range Hyperlink object 203*cdf0e10cSrcweir return uno::Reference< msforms::XShape >( getParent(), uno::UNO_QUERY_THROW ); 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlink, "ooo.vba.excel.Hyperlink" ) 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir // private -------------------------------------------------------------------- 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir void ScVbaHyperlink::ensureTextField() throw (uno::RuntimeException) 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir if( !mxTextField.is() ) 213*cdf0e10cSrcweir throw uno::RuntimeException(); 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir ScVbaHyperlink::UrlComponents ScVbaHyperlink::getUrlComponents() throw (uno::RuntimeException) 217*cdf0e10cSrcweir { 218*cdf0e10cSrcweir ensureTextField(); 219*cdf0e10cSrcweir OUString aUrl; 220*cdf0e10cSrcweir mxTextField->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ) >>= aUrl; 221*cdf0e10cSrcweir sal_Int32 nHashPos = aUrl.indexOf( '#' ); 222*cdf0e10cSrcweir if( nHashPos < 0 ) 223*cdf0e10cSrcweir return UrlComponents( aUrl, OUString() ); 224*cdf0e10cSrcweir return UrlComponents( aUrl.copy( 0, nHashPos ), aUrl.copy( nHashPos + 1 ) ); 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir void ScVbaHyperlink::setUrlComponents( const UrlComponents& rUrlComp ) throw (uno::RuntimeException) 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir ensureTextField(); 230*cdf0e10cSrcweir OUStringBuffer aUrl( rUrlComp.first ); 231*cdf0e10cSrcweir if( rUrlComp.second.getLength() > 0 ) 232*cdf0e10cSrcweir aUrl.append( sal_Unicode( '#' ) ).append( rUrlComp.second ); 233*cdf0e10cSrcweir mxTextField->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ), uno::Any( aUrl.makeStringAndClear() ) ); 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir namespace hyperlink 237*cdf0e10cSrcweir { 238*cdf0e10cSrcweir namespace sdecl = comphelper::service_decl; 239*cdf0e10cSrcweir sdecl::vba_service_class_<ScVbaHyperlink, sdecl::with_args<true> > serviceImpl; 240*cdf0e10cSrcweir extern sdecl::ServiceDecl const serviceDecl( 241*cdf0e10cSrcweir serviceImpl, 242*cdf0e10cSrcweir "ScVbaHyperlink", 243*cdf0e10cSrcweir "ooo.vba.excel.Hyperlink" ); 244*cdf0e10cSrcweir } 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir // ============================================================================ 247