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