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