LibreOffice Module sc (master) 1
vbahyperlinks.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include "vbahyperlinks.hxx"
21#include <algorithm>
22#include <vector>
24#include <ooo/vba/office/MsoHyperlinkType.hpp>
25#include <rangelst.hxx>
26#include "vbahyperlink.hxx"
27#include "vbarange.hxx"
28
29using namespace ::ooo::vba;
30using namespace ::com::sun::star;
31
32namespace {
33
38bool lclContains( const ScRangeList& rScOuter, const uno::Reference< excel::XRange >& rxInner )
39{
40 const ScRangeList& rScInner = ScVbaRange::getScRangeList( rxInner );
41 if( rScInner.empty() || rScOuter.empty() )
42 throw uno::RuntimeException("Empty range objects" );
43
44 for( size_t nIndex = 0, nCount = rScInner.size(); nIndex < nCount; ++nIndex )
45 if( !rScOuter.Contains( rScInner[ nIndex ] ) )
46 return false;
47 return true;
48}
49
51struct EqualAnchorFunctor
52{
53 uno::Reference< excel::XRange > mxAnchorRange;
54 uno::Reference< msforms::XShape > mxAnchorShape;
55 sal_Int32 mnType;
57 explicit EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink );
59 bool operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const;
60};
61
62EqualAnchorFunctor::EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) :
63 mnType( rxHlink->getType() )
64{
65 switch( mnType )
66 {
67 case office::MsoHyperlinkType::msoHyperlinkRange:
68 mxAnchorRange.set( rxHlink->getRange(), uno::UNO_SET_THROW );
69 break;
70 case office::MsoHyperlinkType::msoHyperlinkShape:
71 case office::MsoHyperlinkType::msoHyperlinkInlineShape:
72 mxAnchorShape.set( rxHlink->getShape(), uno::UNO_SET_THROW );
73 break;
74 default:
75 throw uno::RuntimeException();
76 }
77}
78
79bool EqualAnchorFunctor::operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const
80{
81 sal_Int32 nType = rxHlink->getType();
82 if( nType != mnType )
83 return false;
84
85 switch( nType )
86 {
87 case office::MsoHyperlinkType::msoHyperlinkRange:
88 {
89 uno::Reference< excel::XRange > xAnchorRange( rxHlink->getRange(), uno::UNO_SET_THROW );
90 const ScRangeList& rScRanges1 = ScVbaRange::getScRangeList( xAnchorRange );
91 const ScRangeList& rScRanges2 = ScVbaRange::getScRangeList( mxAnchorRange );
92 return (rScRanges1.size() == 1) && (rScRanges2.size() == 1) && (rScRanges1[ 0 ] == rScRanges2[ 0 ]);
93 }
94 case office::MsoHyperlinkType::msoHyperlinkShape:
95 case office::MsoHyperlinkType::msoHyperlinkInlineShape:
96 {
97 uno::Reference< msforms::XShape > xAnchorShape( rxHlink->getShape(), uno::UNO_SET_THROW );
98 return xAnchorShape.get() == mxAnchorShape.get();
99 }
100 default:
101 throw uno::RuntimeException();
102 }
103}
104
105} // namespace
106
107namespace detail {
108
109class ScVbaHlinkContainer : public ::cppu::WeakImplHelper< container::XIndexAccess >
110{
111public:
113 explicit ScVbaHlinkContainer();
115 explicit ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, const ScRangeList& rScRanges );
116
122 void insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink );
123
124 // XIndexAccess
125 virtual sal_Int32 SAL_CALL getCount() override;
126 virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) override;
127
128 // XElementAccess
129 virtual uno::Type SAL_CALL getElementType() override;
130 virtual sal_Bool SAL_CALL hasElements() override;
131
132private:
133 typedef ::std::vector< uno::Reference< excel::XHyperlink > > HyperlinkVector;
135};
136
138{
139 // TODO FIXME: fill with existing hyperlinks
140}
141
143 const ScRangeList& rScRanges )
144{
145 for( sal_Int32 nIndex = 0, nCount = rxSheetContainer->getCount(); nIndex < nCount; ++nIndex )
146 {
147 uno::Reference< excel::XHyperlink > xHlink( rxSheetContainer->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
148 uno::Reference< excel::XRange > xHlinkRange( xHlink->getRange(), uno::UNO_SET_THROW );
149 if( lclContains( rScRanges, xHlinkRange ) )
150 maHlinks.push_back( xHlink );
151 }
152}
153
154void ScVbaHlinkContainer::insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink )
155{
156 HyperlinkVector::iterator aIt = ::std::find_if( maHlinks.begin(), maHlinks.end(), EqualAnchorFunctor( rxHlink ) );
157 if( aIt == maHlinks.end() )
158 maHlinks.push_back( rxHlink );
159 else
160 *aIt = rxHlink;
161}
162
164{
165 return static_cast< sal_Int32 >( maHlinks.size() );
166}
167
168uno::Any SAL_CALL ScVbaHlinkContainer::getByIndex( sal_Int32 nIndex )
169{
170 if( (0 <= nIndex) && (nIndex < getCount()) )
171 return uno::Any( maHlinks[ static_cast< size_t >( nIndex ) ] );
172 throw lang::IndexOutOfBoundsException();
173}
174
176{
178}
179
181{
182 return !maHlinks.empty();
183}
184
186 mxContainer( pContainer )
187{
188}
189
191{
192}
193
194} // namespace detail
195
196ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent,
197 const uno::Reference< uno::XComponentContext >& rxContext ) :
198 detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer ),
199 ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer ) )
200{
201}
202
203ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent,
204 const uno::Reference< uno::XComponentContext >& rxContext,
205 const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) :
206 detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer( rxSheetHlinks->mxContainer, rScRanges ) ),
207 ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer ) ),
208 mxSheetHlinks( rxSheetHlinks )
209{
210}
211
213{
214}
215
216// XHyperlinks ----------------------------------------------------------------
217
218uno::Reference< excel::XHyperlink > SAL_CALL ScVbaHyperlinks::Add(
219 const uno::Any& rAnchor, const uno::Any& rAddress, const uno::Any& rSubAddress,
220 const uno::Any& rScreenTip, const uno::Any& rTextToDisplay )
221{
222 /* If this Hyperlinks object has been created from a Range object, the
223 call to Add() is passed to the Hyperlinks object of the parent
224 worksheet. This container will not be modified (it will not contain the
225 inserted hyperlink).
226 For details, see documentation in hyperlinks.hxx.
227 */
228 if( mxSheetHlinks.is() )
229 return mxSheetHlinks->Add( rAnchor, rAddress, rSubAddress, rScreenTip, rTextToDisplay );
230
231 // get anchor object (can be a Range or a Shape object)
232 uno::Reference< XHelperInterface > xAnchor( rAnchor, uno::UNO_QUERY_THROW );
233
234 /* Create the Hyperlink object, this tries to insert the hyperlink into
235 the spreadsheet document. Parent of the Hyperlink is the anchor object. */
236 uno::Reference< excel::XHyperlink > xHlink( new ScVbaHyperlink(
237 xAnchor, mxContext, rAddress, rSubAddress, rScreenTip, rTextToDisplay ) );
238
239 /* If creation of the hyperlink did not throw, insert it into the
240 collection. */
241 mxContainer->insertHyperlink( xHlink );
242 return xHlink;
243}
244
246{
247 // FIXME not implemented
248 throw uno::RuntimeException();
249}
250
251// XEnumerationAccess ---------------------------------------------------------
252
253uno::Reference< container::XEnumeration > SAL_CALL ScVbaHyperlinks::createEnumeration()
254{
255 return new SimpleIndexAccessToEnumeration( m_xIndexAccess );
256}
257
258// XElementAccess -------------------------------------------------------------
259
261{
263}
264
265// ScVbaCollectionBase --------------------------------------------------------
266
268{
269 // container stores XHyperlink objects, just return the passed object
270 return rSource;
271}
272
273// XHelperInterface -----------------------------------------------------------
274
275VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlinks, "ooo.vba.excel.Hyperlinks" )
276
277/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< container::XNameAccess > mxContainer
bool Contains(const ScRange &) const
Definition: rangelst.cxx:1082
bool empty() const
Definition: rangelst.hxx:88
size_t size() const
Definition: rangelst.hxx:89
const ScRangeList & getScRangeList()
Definition: vbarange.cxx:462
css::uno::Type const & get()
int nCount
uno::Reference< uno::XComponentContext > mxContext
sal_Int32 nIndex
Reference
bool getType(BSTR name, Type &type)
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
sal_Int32 mnType
ScVbaHlinkContainerMember(ScVbaHlinkContainer *pContainer)
unsigned char sal_Bool
#define VBAHELPER_IMPL_XHELPERINTERFACE(classname, servicename)