1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "vbahyperlink.hxx"
21 #include <vbahelper/helperdecl.hxx>
22 #include <com/sun/star/container/XIndexAccess.hpp>
23 #include <com/sun/star/text/XText.hpp>
24 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
25 #include <com/sun/star/container/XEnumerationAccess.hpp>
26 #include <ooo/vba/office/MsoHyperlinkType.hpp>
27 #include <ooo/vba/msforms/XShape.hpp>
28 #include "vbarange.hxx"
30 using namespace ::ooo::vba
;
31 using namespace ::com::sun::star
;
33 ScVbaHyperlink::ScVbaHyperlink( const uno::Sequence
< uno::Any
>& rArgs
,
34 const uno::Reference
< uno::XComponentContext
>& rxContext
) throw (lang::IllegalArgumentException
, uno::RuntimeException
) :
35 HyperlinkImpl_BASE( getXSomethingFromArgs
< XHelperInterface
>( rArgs
, 0 ), rxContext
),
36 mxCell( getXSomethingFromArgs
< table::XCell
>( rArgs
, 1, false ) ),
37 mnType( office::MsoHyperlinkType::msoHyperlinkRange
)
39 uno::Reference
< text::XTextFieldsSupplier
> xTextFields( mxCell
, uno::UNO_QUERY_THROW
);
40 uno::Reference
< container::XIndexAccess
> xIndex( xTextFields
->getTextFields(), uno::UNO_QUERY_THROW
);
41 mxTextField
.set( xIndex
->getByIndex(0), uno::UNO_QUERY_THROW
);
44 ScVbaHyperlink::ScVbaHyperlink( const uno::Reference
< XHelperInterface
>& rxAnchor
,
45 const uno::Reference
< uno::XComponentContext
>& rxContext
,
46 const uno::Any
& rAddress
, const uno::Any
& rSubAddress
,
47 const uno::Any
& rScreenTip
, const uno::Any
& rTextToDisplay
) throw (uno::RuntimeException
) :
48 HyperlinkImpl_BASE( rxAnchor
, rxContext
) // parent of Hyperlink is the anchor object
50 // extract parameters, Address must not be empty
51 UrlComponents aUrlComp
;
52 OUString aTextToDisplay
;
53 if( !(rAddress
>>= aUrlComp
.first
) || aUrlComp
.first
.isEmpty() )
54 throw uno::RuntimeException("Cannot get address" );
55 rSubAddress
>>= aUrlComp
.second
;
56 rScreenTip
>>= maScreenTip
;
57 rTextToDisplay
>>= aTextToDisplay
;
59 // get anchor range or anchor shape
60 uno::Reference
< excel::XRange
> xAnchorRange( rxAnchor
, uno::UNO_QUERY
);
61 if( xAnchorRange
.is() )
63 mnType
= office::MsoHyperlinkType::msoHyperlinkRange
;
64 // only single ranges are allowed
65 uno::Reference
< table::XCellRange
> xUnoRange( ScVbaRange::getCellRange( xAnchorRange
), uno::UNO_QUERY_THROW
);
66 // insert the hyperlink into the top-left cell only
67 mxCell
.set( xUnoRange
->getCellByPosition( 0, 0 ), uno::UNO_SET_THROW
);
68 uno::Reference
< text::XText
> xText( mxCell
, uno::UNO_QUERY_THROW
);
69 // use cell text or URL if no TextToDisplay has been passed
70 if( aTextToDisplay
.isEmpty() )
72 aTextToDisplay
= xText
->getString();
73 if( aTextToDisplay
.isEmpty() )
75 OUStringBuffer
aBuffer( aUrlComp
.first
);
76 if( !aUrlComp
.second
.isEmpty() )
77 aBuffer
.append( " - " ).append( aUrlComp
.second
);
78 aTextToDisplay
= aBuffer
.makeStringAndClear();
81 // create and initialize a new URL text field
82 uno::Reference
< lang::XMultiServiceFactory
> xFactory( ScVbaRange::getUnoModel( xAnchorRange
), uno::UNO_QUERY_THROW
);
83 uno::Reference
< text::XTextContent
> xUrlField( xFactory
->createInstance("com.sun.star.text.TextField.URL"), uno::UNO_QUERY_THROW
);
84 mxTextField
.set( xUrlField
, uno::UNO_QUERY_THROW
);
85 setUrlComponents( aUrlComp
);
86 setTextToDisplay( aTextToDisplay
);
87 // insert the text field into the document
88 xText
->setString( OUString() );
89 uno::Reference
< text::XTextRange
> xRange( xText
->createTextCursor(), uno::UNO_QUERY_THROW
);
90 xText
->insertTextContent( xRange
, xUrlField
, false );
94 uno::Reference
< msforms::XShape
> xAnchorShape( rxAnchor
, uno::UNO_QUERY_THROW
);
95 mnType
= office::MsoHyperlinkType::msoHyperlinkShape
;
96 // FIXME: insert hyperlink into shape
97 throw uno::RuntimeException();
101 ScVbaHyperlink::~ScVbaHyperlink()
105 OUString
ScVbaHyperlink::getName() throw (uno::RuntimeException
, std::exception
)
107 // it seems this attribute is same as TextToDisplay
108 return getTextToDisplay();
111 void ScVbaHyperlink::setName( const OUString
& rName
) throw (uno::RuntimeException
, std::exception
)
113 setTextToDisplay( rName
);
116 OUString
ScVbaHyperlink::getAddress() throw (uno::RuntimeException
, std::exception
)
118 return getUrlComponents().first
;
121 void ScVbaHyperlink::setAddress( const OUString
& rAddress
) throw (uno::RuntimeException
, std::exception
)
123 UrlComponents aUrlComp
= getUrlComponents();
124 aUrlComp
.first
= rAddress
;
125 setUrlComponents( aUrlComp
);
128 OUString
ScVbaHyperlink::getSubAddress() throw (uno::RuntimeException
, std::exception
)
130 return getUrlComponents().second
;
133 void ScVbaHyperlink::setSubAddress( const OUString
& rSubAddress
) throw (uno::RuntimeException
, std::exception
)
135 UrlComponents aUrlComp
= getUrlComponents();
136 aUrlComp
.second
= rSubAddress
;
137 setUrlComponents( aUrlComp
);
140 OUString SAL_CALL
ScVbaHyperlink::getScreenTip() throw (uno::RuntimeException
, std::exception
)
145 void SAL_CALL
ScVbaHyperlink::setScreenTip( const OUString
& rScreenTip
) throw (uno::RuntimeException
, std::exception
)
147 maScreenTip
= rScreenTip
;
150 OUString
ScVbaHyperlink::getTextToDisplay() throw (uno::RuntimeException
, std::exception
)
153 OUString aTextToDisplay
;
154 mxTextField
->getPropertyValue("Representation") >>= aTextToDisplay
;
155 return aTextToDisplay
;
158 void ScVbaHyperlink::setTextToDisplay( const OUString
& rTextToDisplay
) throw (uno::RuntimeException
, std::exception
)
161 mxTextField
->setPropertyValue("Representation", uno::Any( rTextToDisplay
) );
164 sal_Int32 SAL_CALL
ScVbaHyperlink::getType() throw (uno::RuntimeException
, std::exception
)
169 uno::Reference
< excel::XRange
> SAL_CALL
ScVbaHyperlink::getRange() throw (uno::RuntimeException
, std::exception
)
171 if( mnType
== office::MsoHyperlinkType::msoHyperlinkRange
)
173 // if constructed from Hyperlinks object, range has been passed as parent
174 uno::Reference
< excel::XRange
> xAnchorRange( getParent(), uno::UNO_QUERY
);
175 if( !xAnchorRange
.is() )
177 // if constructed via service c'tor, create new range based on cell
178 uno::Reference
< table::XCellRange
> xRange( mxCell
, uno::UNO_QUERY_THROW
);
179 // FIXME: need to pass current worksheet as the parent of XRange.
180 xAnchorRange
.set( new ScVbaRange( uno::Reference
< XHelperInterface
>(), mxContext
, xRange
) );
184 // error if called at a shape Hyperlink object
185 throw uno::RuntimeException();
188 uno::Reference
< msforms::XShape
> SAL_CALL
ScVbaHyperlink::getShape() throw (uno::RuntimeException
, std::exception
)
190 // error if called at a range Hyperlink object
191 return uno::Reference
< msforms::XShape
>( getParent(), uno::UNO_QUERY_THROW
);
194 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlink
, "ooo.vba.excel.Hyperlink" )
196 // private --------------------------------------------------------------------
198 void ScVbaHyperlink::ensureTextField() throw (uno::RuntimeException
)
200 if( !mxTextField
.is() )
201 throw uno::RuntimeException();
204 ScVbaHyperlink::UrlComponents
ScVbaHyperlink::getUrlComponents() throw (uno::RuntimeException
)
208 mxTextField
->getPropertyValue("URL") >>= aUrl
;
209 sal_Int32 nHashPos
= aUrl
.indexOf( '#' );
211 return UrlComponents( aUrl
, OUString() );
212 return UrlComponents( aUrl
.copy( 0, nHashPos
), aUrl
.copy( nHashPos
+ 1 ) );
215 void ScVbaHyperlink::setUrlComponents( const UrlComponents
& rUrlComp
) throw (uno::RuntimeException
)
218 OUStringBuffer
aUrl( rUrlComp
.first
);
219 if( !rUrlComp
.second
.isEmpty() )
220 aUrl
.append( '#' ).append( rUrlComp
.second
);
221 mxTextField
->setPropertyValue("URL", uno::Any( aUrl
.makeStringAndClear() ) );
226 namespace sdecl
= comphelper::service_decl
;
227 sdecl::vba_service_class_
<ScVbaHyperlink
, sdecl::with_args
<true> > serviceImpl
;
228 extern sdecl::ServiceDecl
const serviceDecl(
231 "ooo.vba.excel.Hyperlink" );
234 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */