tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / vba / vbahyperlinks.cxx
blob6b748a6cdc28b8621279fa7f5241bb3f37df4aec
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
21 #include <algorithm>
22 #include <vector>
23 #include <cppuhelper/implbase.hxx>
24 #include <ooo/vba/office/MsoHyperlinkType.hpp>
25 #include <rangelst.hxx>
26 #include "vbahyperlink.hxx"
27 #include "vbarange.hxx"
29 using namespace ::ooo::vba;
30 using namespace ::com::sun::star;
32 namespace {
34 /** Returns true, if every range of rxInner is contained in any range of rScOuter.
36 @throws css::uno::RuntimeException
38 bool lclContains( const ScRangeList& rScOuter, const uno::Reference< excel::XRange >& rxInner )
40 const ScRangeList& rScInner = ScVbaRange::getScRangeList( rxInner );
41 if( rScInner.empty() || rScOuter.empty() )
42 throw uno::RuntimeException(u"Empty range objects"_ustr );
44 for( size_t nIndex = 0, nCount = rScInner.size(); nIndex < nCount; ++nIndex )
45 if( !rScOuter.Contains( rScInner[ nIndex ] ) )
46 return false;
47 return true;
50 /** Functor to decide whether the anchors of two Hyperlink objects are equal. */
51 struct EqualAnchorFunctor
53 uno::Reference< excel::XRange > mxAnchorRange;
54 uno::Reference< msforms::XShape > mxAnchorShape;
55 sal_Int32 mnType;
56 /// @throws uno::RuntimeException
57 explicit EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink );
58 /// @throws uno::RuntimeException
59 bool operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const;
62 EqualAnchorFunctor::EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) :
63 mnType( rxHlink->getType() )
65 switch( mnType )
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();
79 bool EqualAnchorFunctor::operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const
81 sal_Int32 nType = rxHlink->getType();
82 if( nType != mnType )
83 return false;
85 switch( nType )
87 case office::MsoHyperlinkType::msoHyperlinkRange:
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 ]);
94 case office::MsoHyperlinkType::msoHyperlinkShape:
95 case office::MsoHyperlinkType::msoHyperlinkInlineShape:
97 uno::Reference< msforms::XShape > xAnchorShape( rxHlink->getShape(), uno::UNO_SET_THROW );
98 return xAnchorShape.get() == mxAnchorShape.get();
100 default:
101 throw uno::RuntimeException();
105 } // namespace
107 namespace detail {
109 class ScVbaHlinkContainer : public ::cppu::WeakImplHelper< container::XIndexAccess >
111 public:
112 /// @throws uno::RuntimeException
113 explicit ScVbaHlinkContainer();
114 /// @throws uno::RuntimeException
115 explicit ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, const ScRangeList& rScRanges );
117 /** Inserts the passed hyperlink into the collection. Will remove a
118 Hyperlink object with the same anchor as the passed Hyperlink object.
120 @throws uno::RuntimeException
122 void insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink );
124 // XIndexAccess
125 virtual sal_Int32 SAL_CALL getCount() override;
126 virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) override;
128 // XElementAccess
129 virtual uno::Type SAL_CALL getElementType() override;
130 virtual sal_Bool SAL_CALL hasElements() override;
132 private:
133 typedef ::std::vector< uno::Reference< excel::XHyperlink > > HyperlinkVector;
134 HyperlinkVector maHlinks;
137 ScVbaHlinkContainer::ScVbaHlinkContainer()
139 // TODO FIXME: fill with existing hyperlinks
142 ScVbaHlinkContainer::ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer,
143 const ScRangeList& rScRanges )
145 for( sal_Int32 nIndex = 0, nCount = rxSheetContainer->getCount(); nIndex < nCount; ++nIndex )
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 );
154 void ScVbaHlinkContainer::insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink )
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;
163 sal_Int32 SAL_CALL ScVbaHlinkContainer::getCount()
165 return static_cast< sal_Int32 >( maHlinks.size() );
168 uno::Any SAL_CALL ScVbaHlinkContainer::getByIndex( sal_Int32 nIndex )
170 if( (0 <= nIndex) && (nIndex < getCount()) )
171 return uno::Any( maHlinks[ static_cast< size_t >( nIndex ) ] );
172 throw lang::IndexOutOfBoundsException();
175 uno::Type SAL_CALL ScVbaHlinkContainer::getElementType()
177 return cppu::UnoType<excel::XHyperlink>::get();
180 sal_Bool SAL_CALL ScVbaHlinkContainer::hasElements()
182 return !maHlinks.empty();
185 ScVbaHlinkContainerMember::ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer ) :
186 mxContainer( pContainer )
190 ScVbaHlinkContainerMember::~ScVbaHlinkContainerMember()
194 } // namespace detail
196 ScVbaHyperlinks::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 ) )
203 ScVbaHyperlinks::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 )
212 ScVbaHyperlinks::~ScVbaHyperlinks()
216 // XHyperlinks ----------------------------------------------------------------
218 uno::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 )
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.
228 if( mxSheetHlinks.is() )
229 return mxSheetHlinks->Add( rAnchor, rAddress, rSubAddress, rScreenTip, rTextToDisplay );
231 // get anchor object (can be a Range or a Shape object)
232 uno::Reference< XHelperInterface > xAnchor( rAnchor, uno::UNO_QUERY_THROW );
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 ) );
239 /* If creation of the hyperlink did not throw, insert it into the
240 collection. */
241 mxContainer->insertHyperlink( xHlink );
242 return xHlink;
245 void SAL_CALL ScVbaHyperlinks::Delete()
247 // FIXME not implemented
248 throw uno::RuntimeException();
251 // XEnumerationAccess ---------------------------------------------------------
253 uno::Reference< container::XEnumeration > SAL_CALL ScVbaHyperlinks::createEnumeration()
255 return new SimpleIndexAccessToEnumeration( m_xIndexAccess );
258 // XElementAccess -------------------------------------------------------------
260 uno::Type SAL_CALL ScVbaHyperlinks::getElementType()
262 return cppu::UnoType<excel::XHyperlink>::get();
265 // ScVbaCollectionBase --------------------------------------------------------
267 uno::Any ScVbaHyperlinks::createCollectionObject( const uno::Any& rSource )
269 // container stores XHyperlink objects, just return the passed object
270 return rSource;
273 // XHelperInterface -----------------------------------------------------------
275 VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlinks, u"ooo.vba.excel.Hyperlinks"_ustr )
277 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */