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 <sal/config.h>
22 #include "vbahyperlink.hxx"
23 #include <com/sun/star/beans/XPropertySet.hpp>
24 #include <com/sun/star/container/XIndexAccess.hpp>
25 #include <com/sun/star/frame/XModel.hpp>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/table/XCellRange.hpp>
28 #include <com/sun/star/text/XText.hpp>
29 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
30 #include <ooo/vba/office/MsoHyperlinkType.hpp>
31 #include <ooo/vba/msforms/XShape.hpp>
32 #include "vbarange.hxx"
34 using namespace ::ooo::vba
;
35 using namespace ::com::sun::star
;
37 ScVbaHyperlink::ScVbaHyperlink( const uno::Sequence
< uno::Any
>& rArgs
,
38 const uno::Reference
< uno::XComponentContext
>& rxContext
) :
39 HyperlinkImpl_BASE( getXSomethingFromArgs
< XHelperInterface
>( rArgs
, 0 ), rxContext
),
40 mxCell( getXSomethingFromArgs
< table::XCell
>( rArgs
, 1, false ) ),
41 mnType( office::MsoHyperlinkType::msoHyperlinkRange
)
43 uno::Reference
< text::XTextFieldsSupplier
> xTextFields( mxCell
, uno::UNO_QUERY_THROW
);
44 uno::Reference
< container::XIndexAccess
> xIndex( xTextFields
->getTextFields(), uno::UNO_QUERY_THROW
);
45 mxTextField
.set( xIndex
->getByIndex(0), uno::UNO_QUERY_THROW
);
48 ScVbaHyperlink::ScVbaHyperlink( const uno::Reference
< XHelperInterface
>& rxAnchor
,
49 const uno::Reference
< uno::XComponentContext
>& rxContext
,
50 const uno::Any
& rAddress
, const uno::Any
& rSubAddress
,
51 const uno::Any
& rScreenTip
, const uno::Any
& rTextToDisplay
) :
52 HyperlinkImpl_BASE( rxAnchor
, rxContext
) // parent of Hyperlink is the anchor object
54 // extract parameters, Address must not be empty
55 UrlComponents aUrlComp
;
56 OUString aTextToDisplay
;
57 if( !(rAddress
>>= aUrlComp
.first
) || aUrlComp
.first
.isEmpty() )
58 throw uno::RuntimeException(u
"Cannot get address"_ustr
);
59 rSubAddress
>>= aUrlComp
.second
;
60 rScreenTip
>>= maScreenTip
;
61 rTextToDisplay
>>= aTextToDisplay
;
63 // get anchor range or anchor shape
64 uno::Reference
< excel::XRange
> xAnchorRange( rxAnchor
, uno::UNO_QUERY
);
65 if( xAnchorRange
.is() )
67 mnType
= office::MsoHyperlinkType::msoHyperlinkRange
;
68 // only single ranges are allowed
69 uno::Reference
< table::XCellRange
> xUnoRange( ScVbaRange::getCellRange( xAnchorRange
), uno::UNO_QUERY_THROW
);
70 // insert the hyperlink into the top-left cell only
71 mxCell
.set( xUnoRange
->getCellByPosition( 0, 0 ), uno::UNO_SET_THROW
);
72 uno::Reference
< text::XText
> xText( mxCell
, uno::UNO_QUERY_THROW
);
73 // use cell text or URL if no TextToDisplay has been passed
74 if( aTextToDisplay
.isEmpty() )
76 aTextToDisplay
= xText
->getString();
77 if( aTextToDisplay
.isEmpty() )
79 OUStringBuffer
aBuffer( aUrlComp
.first
);
80 if( !aUrlComp
.second
.isEmpty() )
81 aBuffer
.append( " - " + aUrlComp
.second
);
82 aTextToDisplay
= aBuffer
.makeStringAndClear();
85 // create and initialize a new URL text field
86 uno::Reference
< lang::XMultiServiceFactory
> xFactory( ScVbaRange::getUnoModel( xAnchorRange
), uno::UNO_QUERY_THROW
);
87 uno::Reference
< text::XTextContent
> xUrlField( xFactory
->createInstance(u
"com.sun.star.text.TextField.URL"_ustr
), uno::UNO_QUERY_THROW
);
88 mxTextField
.set( xUrlField
, uno::UNO_QUERY_THROW
);
89 setUrlComponents( aUrlComp
);
90 setTextToDisplay( aTextToDisplay
);
91 // insert the text field into the document
92 xText
->setString( OUString() );
93 uno::Reference
< text::XTextRange
> xRange( xText
->createTextCursor(), uno::UNO_QUERY_THROW
);
94 xText
->insertTextContent( xRange
, xUrlField
, false );
98 uno::Reference
< msforms::XShape
> xAnchorShape( rxAnchor
, uno::UNO_QUERY_THROW
);
99 mnType
= office::MsoHyperlinkType::msoHyperlinkShape
;
100 // FIXME: insert hyperlink into shape
101 throw uno::RuntimeException();
105 ScVbaHyperlink::~ScVbaHyperlink()
109 OUString
ScVbaHyperlink::getName()
111 // it seems this attribute is same as TextToDisplay
112 return getTextToDisplay();
115 void ScVbaHyperlink::setName( const OUString
& rName
)
117 setTextToDisplay( rName
);
120 OUString
ScVbaHyperlink::getAddress()
122 return getUrlComponents().first
;
125 void ScVbaHyperlink::setAddress( const OUString
& rAddress
)
127 UrlComponents aUrlComp
= getUrlComponents();
128 aUrlComp
.first
= rAddress
;
129 setUrlComponents( aUrlComp
);
132 OUString
ScVbaHyperlink::getSubAddress()
134 return getUrlComponents().second
;
137 void ScVbaHyperlink::setSubAddress( const OUString
& rSubAddress
)
139 UrlComponents aUrlComp
= getUrlComponents();
140 aUrlComp
.second
= rSubAddress
;
141 setUrlComponents( aUrlComp
);
144 OUString SAL_CALL
ScVbaHyperlink::getScreenTip()
149 void SAL_CALL
ScVbaHyperlink::setScreenTip( const OUString
& rScreenTip
)
151 maScreenTip
= rScreenTip
;
154 OUString
ScVbaHyperlink::getTextToDisplay()
157 OUString aTextToDisplay
;
158 mxTextField
->getPropertyValue(u
"Representation"_ustr
) >>= aTextToDisplay
;
159 return aTextToDisplay
;
162 void ScVbaHyperlink::setTextToDisplay( const OUString
& rTextToDisplay
)
165 mxTextField
->setPropertyValue(u
"Representation"_ustr
, uno::Any( rTextToDisplay
) );
168 sal_Int32 SAL_CALL
ScVbaHyperlink::getType()
173 uno::Reference
< excel::XRange
> SAL_CALL
ScVbaHyperlink::getRange()
175 if( mnType
== office::MsoHyperlinkType::msoHyperlinkRange
)
177 // if constructed from Hyperlinks object, range has been passed as parent
178 uno::Reference
< excel::XRange
> xAnchorRange( getParent(), uno::UNO_QUERY
);
179 if( !xAnchorRange
.is() )
181 // if constructed via service c'tor, create new range based on cell
182 uno::Reference
< table::XCellRange
> xRange( mxCell
, uno::UNO_QUERY_THROW
);
183 // FIXME: need to pass current worksheet as the parent of XRange.
184 xAnchorRange
.set( new ScVbaRange( uno::Reference
< XHelperInterface
>(), mxContext
, xRange
) );
188 // error if called at a shape Hyperlink object
189 throw uno::RuntimeException();
192 uno::Reference
< msforms::XShape
> SAL_CALL
ScVbaHyperlink::getShape()
194 // error if called at a range Hyperlink object
195 return uno::Reference
< msforms::XShape
>( getParent(), uno::UNO_QUERY_THROW
);
198 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlink
, u
"ooo.vba.excel.Hyperlink"_ustr
)
200 // private --------------------------------------------------------------------
202 void ScVbaHyperlink::ensureTextField()
204 if( !mxTextField
.is() )
205 throw uno::RuntimeException();
208 ScVbaHyperlink::UrlComponents
ScVbaHyperlink::getUrlComponents()
212 mxTextField
->getPropertyValue(u
"URL"_ustr
) >>= aUrl
;
213 sal_Int32 nHashPos
= aUrl
.indexOf( '#' );
215 return UrlComponents( aUrl
, OUString() );
216 return UrlComponents( aUrl
.copy( 0, nHashPos
), aUrl
.copy( nHashPos
+ 1 ) );
219 void ScVbaHyperlink::setUrlComponents( const UrlComponents
& rUrlComp
)
222 OUStringBuffer
aUrl( rUrlComp
.first
);
223 if( !rUrlComp
.second
.isEmpty() )
224 aUrl
.append( "#" + rUrlComp
.second
);
225 mxTextField
->setPropertyValue(u
"URL"_ustr
, uno::Any( aUrl
.makeStringAndClear() ) );
228 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
229 Calc_ScVbaHyperlink_get_implementation(
230 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& args
)
232 return cppu::acquire(new ScVbaHyperlink(args
, context
));
236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */