xref: /trunk/main/sc/source/ui/vba/vbahyperlink.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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