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 "vbahyperlinks.hxx"
23 #include <ooo/vba/office/MsoHyperlinkType.hpp>
24 #include "rangelst.hxx"
25 #include "vbahyperlink.hxx"
26 #include "vbarange.hxx"
28 using namespace ::ooo::vba
;
29 using namespace ::com::sun::star
;
33 /** Returns true, if every range of rxInner is contained in any range of rScOuter. */
34 bool lclContains( const ScRangeList
& rScOuter
, const uno::Reference
< excel::XRange
>& rxInner
) throw (uno::RuntimeException
)
36 const ScRangeList
& rScInner
= ScVbaRange::getScRangeList( rxInner
);
37 if( rScInner
.empty() || rScOuter
.empty() )
38 throw uno::RuntimeException("Empty range objects" );
40 for( size_t nIndex
= 0, nCount
= rScInner
.size(); nIndex
< nCount
; ++nIndex
)
41 if( !rScOuter
.In( *rScInner
[ nIndex
] ) )
46 /** Functor to decide whether the anchors of two Hyperlink objects are equal. */
47 struct EqualAnchorFunctor
49 uno::Reference
< excel::XRange
> mxAnchorRange
;
50 uno::Reference
< msforms::XShape
> mxAnchorShape
;
52 EqualAnchorFunctor( const uno::Reference
< excel::XHyperlink
>& rxHlink
) throw (uno::RuntimeException
);
53 bool operator()( const uno::Reference
< excel::XHyperlink
>& rxHlink
) const throw (uno::RuntimeException
);
56 EqualAnchorFunctor::EqualAnchorFunctor( const uno::Reference
< excel::XHyperlink
>& rxHlink
) throw (uno::RuntimeException
) :
57 mnType( rxHlink
->getType() )
61 case office::MsoHyperlinkType::msoHyperlinkRange
:
62 mxAnchorRange
.set( rxHlink
->getRange(), uno::UNO_QUERY_THROW
);
64 case office::MsoHyperlinkType::msoHyperlinkShape
:
65 case office::MsoHyperlinkType::msoHyperlinkInlineShape
:
66 mxAnchorShape
.set( rxHlink
->getShape(), uno::UNO_QUERY_THROW
);
69 throw uno::RuntimeException();
73 bool EqualAnchorFunctor::operator()( const uno::Reference
< excel::XHyperlink
>& rxHlink
) const throw (uno::RuntimeException
)
75 sal_Int32 nType
= rxHlink
->getType();
81 case office::MsoHyperlinkType::msoHyperlinkRange
:
83 uno::Reference
< excel::XRange
> xAnchorRange( rxHlink
->getRange(), uno::UNO_QUERY_THROW
);
84 const ScRangeList
& rScRanges1
= ScVbaRange::getScRangeList( xAnchorRange
);
85 const ScRangeList
& rScRanges2
= ScVbaRange::getScRangeList( mxAnchorRange
);
86 return (rScRanges1
.size() == 1) && (rScRanges2
.size() == 1) && (*rScRanges1
[ 0 ] == *rScRanges2
[ 0 ]);
88 case office::MsoHyperlinkType::msoHyperlinkShape
:
89 case office::MsoHyperlinkType::msoHyperlinkInlineShape
:
91 uno::Reference
< msforms::XShape
> xAnchorShape( rxHlink
->getShape(), uno::UNO_QUERY_THROW
);
92 return xAnchorShape
.get() == mxAnchorShape
.get();
95 throw uno::RuntimeException();
103 class ScVbaHlinkContainer
: public ::cppu::WeakImplHelper1
< container::XIndexAccess
>
106 explicit ScVbaHlinkContainer() throw (uno::RuntimeException
);
107 explicit ScVbaHlinkContainer( const ScVbaHlinkContainerRef
& rxSheetContainer
, const ScRangeList
& rScRanges
) throw (uno::RuntimeException
);
108 virtual ~ScVbaHlinkContainer();
110 /** Inserts the passed hyperlink into the collection. Will remove a
111 Hyperlink object with the same anchor as the passed Hyperlink object. */
112 void insertHyperlink( const uno::Reference
< excel::XHyperlink
>& rxHlink
) throw (uno::RuntimeException
);
115 virtual sal_Int32 SAL_CALL
getCount() throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
116 virtual uno::Any SAL_CALL
getByIndex( sal_Int32 nIndex
) throw (lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
119 virtual uno::Type SAL_CALL
getElementType() throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
120 virtual sal_Bool SAL_CALL
hasElements() throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
123 typedef ::std::vector
< uno::Reference
< excel::XHyperlink
> > HyperlinkVector
;
124 HyperlinkVector maHlinks
;
127 ScVbaHlinkContainer::ScVbaHlinkContainer() throw (uno::RuntimeException
)
129 // TODO FIXME: fill with existing hyperlinks
132 ScVbaHlinkContainer::ScVbaHlinkContainer( const ScVbaHlinkContainerRef
& rxSheetContainer
,
133 const ScRangeList
& rScRanges
) throw (uno::RuntimeException
)
135 for( sal_Int32 nIndex
= 0, nCount
= rxSheetContainer
->getCount(); nIndex
< nCount
; ++nIndex
)
137 uno::Reference
< excel::XHyperlink
> xHlink( rxSheetContainer
->getByIndex( nIndex
), uno::UNO_QUERY_THROW
);
138 uno::Reference
< excel::XRange
> xHlinkRange( xHlink
->getRange(), uno::UNO_QUERY_THROW
);
139 if( lclContains( rScRanges
, xHlinkRange
) )
140 maHlinks
.push_back( xHlink
);
144 ScVbaHlinkContainer::~ScVbaHlinkContainer()
148 void ScVbaHlinkContainer::insertHyperlink( const uno::Reference
< excel::XHyperlink
>& rxHlink
) throw (uno::RuntimeException
)
150 HyperlinkVector::iterator aIt
= ::std::find_if( maHlinks
.begin(), maHlinks
.end(), EqualAnchorFunctor( rxHlink
) );
151 if( aIt
== maHlinks
.end() )
152 maHlinks
.push_back( rxHlink
);
157 sal_Int32 SAL_CALL
ScVbaHlinkContainer::getCount() throw (uno::RuntimeException
, std::exception
)
159 return static_cast< sal_Int32
>( maHlinks
.size() );
162 uno::Any SAL_CALL
ScVbaHlinkContainer::getByIndex( sal_Int32 nIndex
)
163 throw (lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
, std::exception
)
165 if( (0 <= nIndex
) && (nIndex
< getCount()) )
166 return uno::Any( maHlinks
[ static_cast< size_t >( nIndex
) ] );
167 throw lang::IndexOutOfBoundsException();
170 uno::Type SAL_CALL
ScVbaHlinkContainer::getElementType() throw (uno::RuntimeException
, std::exception
)
172 return cppu::UnoType
<excel::XHyperlink
>::get();
175 sal_Bool SAL_CALL
ScVbaHlinkContainer::hasElements() throw (uno::RuntimeException
, std::exception
)
177 return !maHlinks
.empty();
180 ScVbaHlinkContainerMember::ScVbaHlinkContainerMember( ScVbaHlinkContainer
* pContainer
) :
181 mxContainer( pContainer
)
185 ScVbaHlinkContainerMember::~ScVbaHlinkContainerMember()
189 } // namespace detail
191 ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference
< XHelperInterface
>& rxParent
,
192 const uno::Reference
< uno::XComponentContext
>& rxContext
) throw (uno::RuntimeException
) :
193 detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer
),
194 ScVbaHyperlinks_BASE( rxParent
, rxContext
, uno::Reference
< container::XIndexAccess
>( mxContainer
.get() ) )
198 ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference
< XHelperInterface
>& rxParent
,
199 const uno::Reference
< uno::XComponentContext
>& rxContext
,
200 const ScVbaHyperlinksRef
& rxSheetHlinks
, const ScRangeList
& rScRanges
) throw (uno::RuntimeException
) :
201 detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer( rxSheetHlinks
->mxContainer
, rScRanges
) ),
202 ScVbaHyperlinks_BASE( rxParent
, rxContext
, uno::Reference
< container::XIndexAccess
>( mxContainer
.get() ) ),
203 mxSheetHlinks( rxSheetHlinks
)
207 ScVbaHyperlinks::~ScVbaHyperlinks()
211 // XHyperlinks ----------------------------------------------------------------
213 uno::Reference
< excel::XHyperlink
> SAL_CALL
ScVbaHyperlinks::Add(
214 const uno::Any
& rAnchor
, const uno::Any
& rAddress
, const uno::Any
& rSubAddress
,
215 const uno::Any
& rScreenTip
, const uno::Any
& rTextToDisplay
) throw (uno::RuntimeException
, std::exception
)
217 /* If this Hyperlinks object has been craeted from a Range object, the
218 call to Add() is passed to the Hyperlinks object of the parent
219 worksheet. This container will not be modified (it will not contain the
221 For details, see documentation in hyperlinks.hxx.
223 if( mxSheetHlinks
.is() )
224 return mxSheetHlinks
->Add( rAnchor
, rAddress
, rSubAddress
, rScreenTip
, rTextToDisplay
);
226 // get anchor object (can be a Range or a Shape object)
227 uno::Reference
< XHelperInterface
> xAnchor( rAnchor
, uno::UNO_QUERY_THROW
);
229 /* Create the Hyperlink object, this tries to insert the hyperlink into
230 the spreadsheet document. Parent of the Hyperlink is the anchor object. */
231 uno::Reference
< excel::XHyperlink
> xHlink( new ScVbaHyperlink(
232 xAnchor
, mxContext
, rAddress
, rSubAddress
, rScreenTip
, rTextToDisplay
) );
234 /* If creation of the hyperlink did not throw, insert it into the
236 mxContainer
->insertHyperlink( xHlink
);
240 void SAL_CALL
ScVbaHyperlinks::Delete() throw (uno::RuntimeException
, std::exception
)
242 // FIXME not implemented
243 throw uno::RuntimeException();
246 // XEnumerationAccess ---------------------------------------------------------
248 uno::Reference
< container::XEnumeration
> SAL_CALL
ScVbaHyperlinks::createEnumeration() throw (uno::RuntimeException
)
250 return new SimpleIndexAccessToEnumeration( m_xIndexAccess
);
253 // XElementAccess -------------------------------------------------------------
255 uno::Type SAL_CALL
ScVbaHyperlinks::getElementType() throw (uno::RuntimeException
)
257 return cppu::UnoType
<excel::XHyperlink
>::get();
260 // ScVbaCollectionBase --------------------------------------------------------
262 uno::Any
ScVbaHyperlinks::createCollectionObject( const uno::Any
& rSource
)
264 // container stores XHyperlink objects, just return the passed object
268 // XHelperInterface -----------------------------------------------------------
270 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlinks
, "ooo.vba.excel.Hyperlinks" )
272 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */