1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5b3f79822SAndrew Rist * distributed with this work for additional information
6b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10b3f79822SAndrew Rist *
11b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist *
13b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist * software distributed under the License is distributed on an
15b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17b3f79822SAndrew Rist * specific language governing permissions and limitations
18b3f79822SAndrew Rist * under the License.
19b3f79822SAndrew Rist *
20b3f79822SAndrew Rist *************************************************************/
21b3f79822SAndrew Rist
22b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "vbahyperlinks.hxx"
25cdf0e10cSrcweir #include <algorithm>
26cdf0e10cSrcweir #include <vector>
27cdf0e10cSrcweir #include <ooo/vba/office/MsoHyperlinkType.hpp>
28cdf0e10cSrcweir #include "rangelst.hxx"
29cdf0e10cSrcweir #include "vbahyperlink.hxx"
30cdf0e10cSrcweir #include "vbarange.hxx"
31cdf0e10cSrcweir
32cdf0e10cSrcweir using namespace ::ooo::vba;
33cdf0e10cSrcweir using namespace ::com::sun::star;
34cdf0e10cSrcweir using ::rtl::OUString;
35cdf0e10cSrcweir
36cdf0e10cSrcweir // ============================================================================
37cdf0e10cSrcweir
38cdf0e10cSrcweir namespace {
39cdf0e10cSrcweir
40cdf0e10cSrcweir /** Returns true, if every range of rxInner is contained in any range of rScOuter. */
lclContains(const ScRangeList & rScOuter,const uno::Reference<excel::XRange> & rxInner)41cdf0e10cSrcweir bool lclContains( const ScRangeList& rScOuter, const uno::Reference< excel::XRange >& rxInner ) throw (uno::RuntimeException)
42cdf0e10cSrcweir {
43cdf0e10cSrcweir const ScRangeList& rScInner = ScVbaRange::getScRangeList( rxInner );
44cdf0e10cSrcweir if( (rScInner.Count() == 0) || (rScOuter.Count() == 0) )
45cdf0e10cSrcweir throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Empty range objects" ) ), uno::Reference< uno::XInterface >() );
46cdf0e10cSrcweir
47cdf0e10cSrcweir for( sal_uLong nIndex = 0, nCount = rScInner.Count(); nIndex < nCount; ++nIndex )
48cdf0e10cSrcweir if( !rScOuter.In( *rScInner.GetObject( nIndex ) ) )
49cdf0e10cSrcweir return false;
50cdf0e10cSrcweir return true;
51cdf0e10cSrcweir }
52cdf0e10cSrcweir
53cdf0e10cSrcweir // ----------------------------------------------------------------------------
54cdf0e10cSrcweir
55cdf0e10cSrcweir /** Functor to decide whether the anchors of two Hyperlink objects are equal. */
56cdf0e10cSrcweir struct EqualAnchorFunctor
57cdf0e10cSrcweir {
58cdf0e10cSrcweir uno::Reference< excel::XRange > mxAnchorRange;
59cdf0e10cSrcweir uno::Reference< msforms::XShape > mxAnchorShape;
60cdf0e10cSrcweir sal_Int32 mnType;
61cdf0e10cSrcweir EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException);
62cdf0e10cSrcweir bool operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const throw (uno::RuntimeException);
63cdf0e10cSrcweir };
64cdf0e10cSrcweir
EqualAnchorFunctor(const uno::Reference<excel::XHyperlink> & rxHlink)65cdf0e10cSrcweir EqualAnchorFunctor::EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException) :
66cdf0e10cSrcweir mnType( rxHlink->getType() )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir switch( mnType )
69cdf0e10cSrcweir {
70cdf0e10cSrcweir case office::MsoHyperlinkType::msoHyperlinkRange:
71cdf0e10cSrcweir mxAnchorRange.set( rxHlink->getRange(), uno::UNO_QUERY_THROW );
72cdf0e10cSrcweir break;
73cdf0e10cSrcweir case office::MsoHyperlinkType::msoHyperlinkShape:
74cdf0e10cSrcweir case office::MsoHyperlinkType::msoHyperlinkInlineShape:
75cdf0e10cSrcweir mxAnchorShape.set( rxHlink->getShape(), uno::UNO_QUERY_THROW );
76cdf0e10cSrcweir break;
77cdf0e10cSrcweir default:
78cdf0e10cSrcweir throw uno::RuntimeException();
79cdf0e10cSrcweir }
80cdf0e10cSrcweir }
81cdf0e10cSrcweir
operator ()(const uno::Reference<excel::XHyperlink> & rxHlink) const82cdf0e10cSrcweir bool EqualAnchorFunctor::operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const throw (uno::RuntimeException)
83cdf0e10cSrcweir {
84cdf0e10cSrcweir sal_Int32 nType = rxHlink->getType();
85cdf0e10cSrcweir if( nType != mnType )
86cdf0e10cSrcweir return false;
87cdf0e10cSrcweir
88cdf0e10cSrcweir switch( nType )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir case office::MsoHyperlinkType::msoHyperlinkRange:
91cdf0e10cSrcweir {
92cdf0e10cSrcweir uno::Reference< excel::XRange > xAnchorRange( rxHlink->getRange(), uno::UNO_QUERY_THROW );
93cdf0e10cSrcweir const ScRangeList& rScRanges1 = ScVbaRange::getScRangeList( xAnchorRange );
94cdf0e10cSrcweir const ScRangeList& rScRanges2 = ScVbaRange::getScRangeList( mxAnchorRange );
95cdf0e10cSrcweir return (rScRanges1.Count() == 1) && (rScRanges2.Count() == 1) && (*rScRanges1.GetObject( 0 ) == *rScRanges2.GetObject( 0 ));
96cdf0e10cSrcweir }
97cdf0e10cSrcweir case office::MsoHyperlinkType::msoHyperlinkShape:
98cdf0e10cSrcweir case office::MsoHyperlinkType::msoHyperlinkInlineShape:
99cdf0e10cSrcweir {
100cdf0e10cSrcweir uno::Reference< msforms::XShape > xAnchorShape( rxHlink->getShape(), uno::UNO_QUERY_THROW );
101cdf0e10cSrcweir return xAnchorShape.get() == mxAnchorShape.get();
102cdf0e10cSrcweir }
103cdf0e10cSrcweir default:
104cdf0e10cSrcweir throw uno::RuntimeException();
105cdf0e10cSrcweir }
106cdf0e10cSrcweir }
107cdf0e10cSrcweir
108cdf0e10cSrcweir } // namespace
109cdf0e10cSrcweir
110cdf0e10cSrcweir // ============================================================================
111cdf0e10cSrcweir
112*d16f1dcaSPedro Giffuni namespace vba_detail {
113cdf0e10cSrcweir
114cdf0e10cSrcweir class ScVbaHlinkContainer : public ::cppu::WeakImplHelper1< container::XIndexAccess >
115cdf0e10cSrcweir {
116cdf0e10cSrcweir public:
117cdf0e10cSrcweir explicit ScVbaHlinkContainer() throw (uno::RuntimeException);
118cdf0e10cSrcweir explicit ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, const ScRangeList& rScRanges ) throw (uno::RuntimeException);
119cdf0e10cSrcweir virtual ~ScVbaHlinkContainer();
120cdf0e10cSrcweir
121cdf0e10cSrcweir /** Inserts the passed hyperlink into the collection. Will remove a
122cdf0e10cSrcweir Hyperlink object with the same anchor as the passed Hyperlink object. */
123cdf0e10cSrcweir void insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException);
124cdf0e10cSrcweir
125cdf0e10cSrcweir // XIndexAccess
126cdf0e10cSrcweir virtual sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException);
127cdf0e10cSrcweir virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException);
128cdf0e10cSrcweir
129cdf0e10cSrcweir // XElementAccess
130cdf0e10cSrcweir virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException);
131cdf0e10cSrcweir virtual sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException);
132cdf0e10cSrcweir
133cdf0e10cSrcweir private:
134cdf0e10cSrcweir typedef ::std::vector< uno::Reference< excel::XHyperlink > > HyperlinkVector;
135cdf0e10cSrcweir HyperlinkVector maHlinks;
136cdf0e10cSrcweir };
137cdf0e10cSrcweir
138cdf0e10cSrcweir // ----------------------------------------------------------------------------
139cdf0e10cSrcweir
ScVbaHlinkContainer()140cdf0e10cSrcweir ScVbaHlinkContainer::ScVbaHlinkContainer() throw (uno::RuntimeException)
141cdf0e10cSrcweir {
142cdf0e10cSrcweir // TODO FIXME: fill with existing hyperlinks
143cdf0e10cSrcweir }
144cdf0e10cSrcweir
ScVbaHlinkContainer(const ScVbaHlinkContainerRef & rxSheetContainer,const ScRangeList & rScRanges)145cdf0e10cSrcweir ScVbaHlinkContainer::ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer,
146cdf0e10cSrcweir const ScRangeList& rScRanges ) throw (uno::RuntimeException)
147cdf0e10cSrcweir {
148cdf0e10cSrcweir for( sal_Int32 nIndex = 0, nCount = rxSheetContainer->getCount(); nIndex < nCount; ++nIndex )
149cdf0e10cSrcweir {
150cdf0e10cSrcweir uno::Reference< excel::XHyperlink > xHlink( rxSheetContainer->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
151cdf0e10cSrcweir uno::Reference< excel::XRange > xHlinkRange( xHlink->getRange(), uno::UNO_QUERY_THROW );
152cdf0e10cSrcweir if( lclContains( rScRanges, xHlinkRange ) )
153cdf0e10cSrcweir maHlinks.push_back( xHlink );
154cdf0e10cSrcweir }
155cdf0e10cSrcweir }
156cdf0e10cSrcweir
~ScVbaHlinkContainer()157cdf0e10cSrcweir ScVbaHlinkContainer::~ScVbaHlinkContainer()
158cdf0e10cSrcweir {
159cdf0e10cSrcweir }
160cdf0e10cSrcweir
insertHyperlink(const uno::Reference<excel::XHyperlink> & rxHlink)161cdf0e10cSrcweir void ScVbaHlinkContainer::insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException)
162cdf0e10cSrcweir {
163cdf0e10cSrcweir HyperlinkVector::iterator aIt = ::std::find_if( maHlinks.begin(), maHlinks.end(), EqualAnchorFunctor( rxHlink ) );
164cdf0e10cSrcweir if( aIt == maHlinks.end() )
165cdf0e10cSrcweir maHlinks.push_back( rxHlink );
166cdf0e10cSrcweir else
167cdf0e10cSrcweir *aIt = rxHlink;
168cdf0e10cSrcweir }
169cdf0e10cSrcweir
getCount()170cdf0e10cSrcweir sal_Int32 SAL_CALL ScVbaHlinkContainer::getCount() throw (uno::RuntimeException)
171cdf0e10cSrcweir {
172cdf0e10cSrcweir return static_cast< sal_Int32 >( maHlinks.size() );
173cdf0e10cSrcweir }
174cdf0e10cSrcweir
getByIndex(sal_Int32 nIndex)175cdf0e10cSrcweir uno::Any SAL_CALL ScVbaHlinkContainer::getByIndex( sal_Int32 nIndex )
176cdf0e10cSrcweir throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
177cdf0e10cSrcweir {
178cdf0e10cSrcweir if( (0 <= nIndex) && (nIndex < getCount()) )
179cdf0e10cSrcweir return uno::Any( maHlinks[ static_cast< size_t >( nIndex ) ] );
180cdf0e10cSrcweir throw lang::IndexOutOfBoundsException();
181cdf0e10cSrcweir }
182cdf0e10cSrcweir
getElementType()183cdf0e10cSrcweir uno::Type SAL_CALL ScVbaHlinkContainer::getElementType() throw (uno::RuntimeException)
184cdf0e10cSrcweir {
185cdf0e10cSrcweir return excel::XHyperlink::static_type( 0 );
186cdf0e10cSrcweir }
187cdf0e10cSrcweir
hasElements()188cdf0e10cSrcweir sal_Bool SAL_CALL ScVbaHlinkContainer::hasElements() throw (uno::RuntimeException)
189cdf0e10cSrcweir {
190cdf0e10cSrcweir return !maHlinks.empty();
191cdf0e10cSrcweir }
192cdf0e10cSrcweir
193cdf0e10cSrcweir // ============================================================================
194cdf0e10cSrcweir
ScVbaHlinkContainerMember(ScVbaHlinkContainer * pContainer)195cdf0e10cSrcweir ScVbaHlinkContainerMember::ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer ) :
196cdf0e10cSrcweir mxContainer( pContainer )
197cdf0e10cSrcweir {
198cdf0e10cSrcweir }
199cdf0e10cSrcweir
~ScVbaHlinkContainerMember()200cdf0e10cSrcweir ScVbaHlinkContainerMember::~ScVbaHlinkContainerMember()
201cdf0e10cSrcweir {
202cdf0e10cSrcweir }
203cdf0e10cSrcweir
204*d16f1dcaSPedro Giffuni } // namespace vba_detail
205cdf0e10cSrcweir
206cdf0e10cSrcweir // ============================================================================
207cdf0e10cSrcweir
ScVbaHyperlinks(const uno::Reference<XHelperInterface> & rxParent,const uno::Reference<uno::XComponentContext> & rxContext)208cdf0e10cSrcweir ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent,
209cdf0e10cSrcweir const uno::Reference< uno::XComponentContext >& rxContext ) throw (uno::RuntimeException) :
210*d16f1dcaSPedro Giffuni vba_detail::ScVbaHlinkContainerMember( new vba_detail::ScVbaHlinkContainer ),
211cdf0e10cSrcweir ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer.get() ) )
212cdf0e10cSrcweir {
213cdf0e10cSrcweir }
214cdf0e10cSrcweir
ScVbaHyperlinks(const uno::Reference<XHelperInterface> & rxParent,const uno::Reference<uno::XComponentContext> & rxContext,const ScVbaHyperlinksRef & rxSheetHlinks,const ScRangeList & rScRanges)215cdf0e10cSrcweir ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent,
216cdf0e10cSrcweir const uno::Reference< uno::XComponentContext >& rxContext,
217cdf0e10cSrcweir const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) throw (uno::RuntimeException) :
218*d16f1dcaSPedro Giffuni vba_detail::ScVbaHlinkContainerMember( new vba_detail::ScVbaHlinkContainer( rxSheetHlinks->mxContainer, rScRanges ) ),
219cdf0e10cSrcweir ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer.get() ) ),
220cdf0e10cSrcweir mxSheetHlinks( rxSheetHlinks )
221cdf0e10cSrcweir {
222cdf0e10cSrcweir }
223cdf0e10cSrcweir
~ScVbaHyperlinks()224cdf0e10cSrcweir ScVbaHyperlinks::~ScVbaHyperlinks()
225cdf0e10cSrcweir {
226cdf0e10cSrcweir }
227cdf0e10cSrcweir
228cdf0e10cSrcweir // XHyperlinks ----------------------------------------------------------------
229cdf0e10cSrcweir
Add(const uno::Any & rAnchor,const uno::Any & rAddress,const uno::Any & rSubAddress,const uno::Any & rScreenTip,const uno::Any & rTextToDisplay)230cdf0e10cSrcweir uno::Reference< excel::XHyperlink > SAL_CALL ScVbaHyperlinks::Add(
231cdf0e10cSrcweir const uno::Any& rAnchor, const uno::Any& rAddress, const uno::Any& rSubAddress,
232cdf0e10cSrcweir const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) throw (uno::RuntimeException)
233cdf0e10cSrcweir {
234cdf0e10cSrcweir /* If this Hyperlinks object has been craeted from a Range object, the
235cdf0e10cSrcweir call to Add() is passed to the Hyperlinks object of the parent
236cdf0e10cSrcweir worksheet. This container will not be modified (it will not contain the
237cdf0e10cSrcweir inserted hyperlink).
238cdf0e10cSrcweir For details, see documentation in hyperlinks.hxx.
239cdf0e10cSrcweir */
240cdf0e10cSrcweir if( mxSheetHlinks.is() )
241cdf0e10cSrcweir return mxSheetHlinks->Add( rAnchor, rAddress, rSubAddress, rScreenTip, rTextToDisplay );
242cdf0e10cSrcweir
243cdf0e10cSrcweir // get anchor object (can be a Range or a Shape object)
244cdf0e10cSrcweir uno::Reference< XHelperInterface > xAnchor( rAnchor, uno::UNO_QUERY_THROW );
245cdf0e10cSrcweir
246cdf0e10cSrcweir /* Create the Hyperlink object, this tries to insert the hyperlink into
247cdf0e10cSrcweir the spreadsheet document. Parent of the Hyperlink is the anchor object. */
248cdf0e10cSrcweir uno::Reference< excel::XHyperlink > xHlink( new ScVbaHyperlink(
249cdf0e10cSrcweir xAnchor, mxContext, rAddress, rSubAddress, rScreenTip, rTextToDisplay ) );
250cdf0e10cSrcweir
251cdf0e10cSrcweir /* If creation of the hyperlink did not throw, insert it into the
252cdf0e10cSrcweir collection. */
253cdf0e10cSrcweir mxContainer->insertHyperlink( xHlink );
254cdf0e10cSrcweir return xHlink;
255cdf0e10cSrcweir }
256cdf0e10cSrcweir
Delete()257cdf0e10cSrcweir void SAL_CALL ScVbaHyperlinks::Delete() throw (uno::RuntimeException)
258cdf0e10cSrcweir {
259cdf0e10cSrcweir // FIXME not implemented
260cdf0e10cSrcweir throw uno::RuntimeException();
261cdf0e10cSrcweir }
262cdf0e10cSrcweir
263cdf0e10cSrcweir // XEnumerationAccess ---------------------------------------------------------
264cdf0e10cSrcweir
createEnumeration()265cdf0e10cSrcweir uno::Reference< container::XEnumeration > SAL_CALL ScVbaHyperlinks::createEnumeration() throw (uno::RuntimeException)
266cdf0e10cSrcweir {
267cdf0e10cSrcweir return new SimpleIndexAccessToEnumeration( m_xIndexAccess );
268cdf0e10cSrcweir }
269cdf0e10cSrcweir
270cdf0e10cSrcweir // XElementAccess -------------------------------------------------------------
271cdf0e10cSrcweir
getElementType()272cdf0e10cSrcweir uno::Type SAL_CALL ScVbaHyperlinks::getElementType() throw (uno::RuntimeException)
273cdf0e10cSrcweir {
274cdf0e10cSrcweir return excel::XHyperlink::static_type( 0 );
275cdf0e10cSrcweir }
276cdf0e10cSrcweir
277cdf0e10cSrcweir // ScVbaCollectionBase --------------------------------------------------------
278cdf0e10cSrcweir
createCollectionObject(const uno::Any & rSource)279cdf0e10cSrcweir uno::Any ScVbaHyperlinks::createCollectionObject( const uno::Any& rSource )
280cdf0e10cSrcweir {
281cdf0e10cSrcweir // container stores XHyperlink objects, just return the passed object
282cdf0e10cSrcweir return rSource;
283cdf0e10cSrcweir }
284cdf0e10cSrcweir
285cdf0e10cSrcweir // XHelperInterface -----------------------------------------------------------
286cdf0e10cSrcweir
287cdf0e10cSrcweir VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlinks, "ooo.vba.excel.Hyperlinks" )
288cdf0e10cSrcweir
289cdf0e10cSrcweir // ============================================================================
290