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 "externallinkbuffer.hxx"
30 : :
31 : : #include <com/sun/star/sheet/ComplexReference.hpp>
32 : : #include <com/sun/star/sheet/DDELinkInfo.hpp>
33 : : #include <com/sun/star/sheet/ExternalLinkType.hpp>
34 : : #include <com/sun/star/sheet/ExternalReference.hpp>
35 : : #include <com/sun/star/sheet/ReferenceFlags.hpp>
36 : : #include <com/sun/star/sheet/SingleReference.hpp>
37 : : #include <com/sun/star/sheet/XDDELinks.hpp>
38 : : #include <com/sun/star/sheet/XDDELink.hpp>
39 : : #include <com/sun/star/sheet/XDDELinkResults.hpp>
40 : : #include <com/sun/star/sheet/XExternalDocLink.hpp>
41 : : #include <com/sun/star/sheet/XExternalDocLinks.hpp>
42 : : #include <rtl/strbuf.hxx>
43 : : #include "oox/core/filterbase.hxx"
44 : : #include "oox/helper/attributelist.hxx"
45 : : #include "oox/token/properties.hxx"
46 : : #include "addressconverter.hxx"
47 : : #include "biffinputstream.hxx"
48 : : #include "excelhandlers.hxx"
49 : : #include "formulaparser.hxx"
50 : : #include "worksheetbuffer.hxx"
51 : :
52 : : namespace oox {
53 : : namespace xls {
54 : :
55 : : // ============================================================================
56 : :
57 : : using namespace ::com::sun::star::sheet;
58 : : using namespace ::com::sun::star::table;
59 : : using namespace ::com::sun::star::uno;
60 : :
61 : : using ::oox::core::Relation;
62 : : using ::oox::core::Relations;
63 : : using ::rtl::OString;
64 : : using ::rtl::OStringBuffer;
65 : : using ::rtl::OStringToOUString;
66 : : using ::rtl::OUString;
67 : :
68 : : // ============================================================================
69 : :
70 : : namespace {
71 : :
72 : : const sal_uInt16 BIFF12_EXTERNALBOOK_BOOK = 0;
73 : : const sal_uInt16 BIFF12_EXTERNALBOOK_DDE = 1;
74 : : const sal_uInt16 BIFF12_EXTERNALBOOK_OLE = 2;
75 : :
76 : : const sal_uInt16 BIFF12_EXTNAME_AUTOMATIC = 0x0002;
77 : : const sal_uInt16 BIFF12_EXTNAME_PREFERPIC = 0x0004;
78 : : const sal_uInt16 BIFF12_EXTNAME_STDDOCNAME = 0x0008;
79 : : const sal_uInt16 BIFF12_EXTNAME_OLEOBJECT = 0x0010;
80 : : const sal_uInt16 BIFF12_EXTNAME_ICONIFIED = 0x0020;
81 : :
82 : : const sal_uInt16 BIFF_EXTNAME_BUILTIN = 0x0001;
83 : : const sal_uInt16 BIFF_EXTNAME_AUTOMATIC = 0x0002;
84 : : const sal_uInt16 BIFF_EXTNAME_PREFERPIC = 0x0004;
85 : : const sal_uInt16 BIFF_EXTNAME_STDDOCNAME = 0x0008;
86 : : const sal_uInt16 BIFF_EXTNAME_OLEOBJECT = 0x0010;
87 : : const sal_uInt16 BIFF_EXTNAME_ICONIFIED = 0x8000;
88 : :
89 : : } // namespace
90 : :
91 : : // ============================================================================
92 : :
93 : 0 : ExternalNameModel::ExternalNameModel() :
94 : : mbBuiltIn( false ),
95 : : mbNotify( false ),
96 : : mbPreferPic( false ),
97 : : mbStdDocName( false ),
98 : : mbOleObj( false ),
99 : 0 : mbIconified( false )
100 : : {
101 : 0 : }
102 : :
103 : : // ============================================================================
104 : :
105 : 0 : ExternalName::ExternalName( const ExternalLink& rParentLink ) :
106 : : DefinedNameBase( rParentLink ),
107 : : mrParentLink( rParentLink ),
108 : : mnStorageId( 0 ),
109 [ # # ]: 0 : mbDdeLinkCreated( false )
110 : : {
111 : 0 : }
112 : :
113 : 0 : void ExternalName::importDefinedName( const AttributeList& rAttribs )
114 : : {
115 [ # # ]: 0 : maModel.maName = rAttribs.getXString( XML_name, OUString() );
116 : : OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importDefinedName - empty name" );
117 : : // zero-based index into sheet list of externalBook
118 : 0 : maModel.mnSheet = rAttribs.getInteger( XML_sheetId, -1 );
119 : 0 : }
120 : :
121 : 0 : void ExternalName::importDdeItem( const AttributeList& rAttribs )
122 : : {
123 [ # # ]: 0 : maModel.maName = rAttribs.getXString( XML_name, OUString() );
124 : : OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importDdeItem - empty name" );
125 : 0 : maExtNameModel.mbOleObj = false;
126 : 0 : maExtNameModel.mbStdDocName = rAttribs.getBool( XML_ole, false );
127 : 0 : maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
128 : 0 : maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
129 : 0 : }
130 : :
131 : 0 : void ExternalName::importValues( const AttributeList& rAttribs )
132 : : {
133 : 0 : setResultSize( rAttribs.getInteger( XML_cols, 1 ), rAttribs.getInteger( XML_rows, 1 ) );
134 : 0 : }
135 : :
136 : 0 : void ExternalName::importOleItem( const AttributeList& rAttribs )
137 : : {
138 [ # # ]: 0 : maModel.maName = rAttribs.getXString( XML_name, OUString() );
139 : : OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importOleItem - empty name" );
140 : 0 : maExtNameModel.mbOleObj = true;
141 : 0 : maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
142 : 0 : maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
143 : 0 : maExtNameModel.mbIconified = rAttribs.getBool( XML_icon, false );
144 : 0 : }
145 : :
146 : 0 : void ExternalName::importExternalName( SequenceInputStream& rStrm )
147 : : {
148 : 0 : rStrm >> maModel.maName;
149 : : OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importExternalName - empty name" );
150 : 0 : }
151 : :
152 : 0 : void ExternalName::importExternalNameFlags( SequenceInputStream& rStrm )
153 : : {
154 : : sal_uInt16 nFlags;
155 : : sal_Int32 nSheetId;
156 [ # # ][ # # ]: 0 : rStrm >> nFlags >> nSheetId;
157 : : // index into sheet list of EXTSHEETNAMES (one-based in BIFF12)
158 : 0 : maModel.mnSheet = nSheetId - 1;
159 : : // no flag for built-in names, as in OOXML...
160 : 0 : maExtNameModel.mbNotify = getFlag( nFlags, BIFF12_EXTNAME_AUTOMATIC );
161 : 0 : maExtNameModel.mbPreferPic = getFlag( nFlags, BIFF12_EXTNAME_PREFERPIC );
162 : 0 : maExtNameModel.mbStdDocName = getFlag( nFlags, BIFF12_EXTNAME_STDDOCNAME );
163 : 0 : maExtNameModel.mbOleObj = getFlag( nFlags, BIFF12_EXTNAME_OLEOBJECT );
164 : 0 : maExtNameModel.mbIconified = getFlag( nFlags, BIFF12_EXTNAME_ICONIFIED );
165 : : OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_OLE) == maExtNameModel.mbOleObj,
166 : : "ExternalName::importExternalNameFlags - wrong OLE flag in external name" );
167 : 0 : }
168 : :
169 : 0 : void ExternalName::importDdeItemValues( SequenceInputStream& rStrm )
170 : : {
171 : : sal_Int32 nRows, nCols;
172 [ # # ][ # # ]: 0 : rStrm >> nRows >> nCols;
173 [ # # ]: 0 : setResultSize( nCols, nRows );
174 : 0 : }
175 : :
176 : 0 : void ExternalName::importDdeItemBool( SequenceInputStream& rStrm )
177 : : {
178 [ # # ][ # # ]: 0 : appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
179 : 0 : }
180 : :
181 : 0 : void ExternalName::importDdeItemDouble( SequenceInputStream& rStrm )
182 : : {
183 [ # # ]: 0 : appendResultValue( rStrm.readDouble() );
184 : 0 : }
185 : :
186 : 0 : void ExternalName::importDdeItemError( SequenceInputStream& rStrm )
187 : : {
188 [ # # ]: 0 : appendResultValue( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) );
189 : 0 : }
190 : :
191 : 0 : void ExternalName::importDdeItemString( SequenceInputStream& rStrm )
192 : : {
193 [ # # ]: 0 : appendResultValue( BiffHelper::readString( rStrm ) );
194 : 0 : }
195 : :
196 : : #if 0
197 : : sal_Int32 ExternalName::getSheetCacheIndex() const
198 : : {
199 : : OSL_ENSURE( mrParentLink.getLinkType() == LINKTYPE_DDE, "ExternalName::getSheetCacheIndex - unexpected link type" );
200 : : sal_Int32 nCacheIdx = -1;
201 : : switch( getFilterType() )
202 : : {
203 : : case FILTER_OOXML:
204 : : // OOXML/BIFF12: zero-based index into sheet list, -1 means global name
205 : : if( maModel.mnSheet >= 0 )
206 : : nCacheIdx = mrParentLink.getSheetIndex( maModel.mnSheet );
207 : : break;
208 : : case FILTER_BIFF:
209 : : switch( getBiff() )
210 : : {
211 : : case BIFF2:
212 : : case BIFF3:
213 : : case BIFF4:
214 : : break;
215 : : case BIFF5:
216 : : if( maModel.mnSheet > 0 )
217 : : if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( maModel.mnSheet ).get() )
218 : : if( pExtLink->getLinkType() == LINKTYPE_EXTERNAL )
219 : : nCacheIdx = pExtLink->getSheetIndex();
220 : : break;
221 : : case BIFF8:
222 : : if( maModel.mnSheet > 0 )
223 : : nCacheIdx = mrParentLink.getSheetIndex( maModel.mnSheet - 1 );
224 : : break;
225 : : case BIFF_UNKNOWN:
226 : : break;
227 : : }
228 : : break;
229 : : case FILTER_UNKNOWN:
230 : : break;
231 : : }
232 : : return nCacheIdx;
233 : : }
234 : : #endif
235 : :
236 : 0 : bool ExternalName::getDdeItemInfo( DDEItemInfo& orItemInfo ) const
237 : : {
238 [ # # ][ # # ]: 0 : if( (mrParentLink.getLinkType() == LINKTYPE_DDE) && !maModel.maName.isEmpty() )
[ # # ]
239 : : {
240 : 0 : orItemInfo.Item = maModel.maName;
241 [ # # ]: 0 : orItemInfo.Results = ContainerHelper::matrixToSequenceSequence( maResults );
242 : 0 : return true;
243 : : }
244 : 0 : return false;
245 : : }
246 : :
247 : 0 : bool ExternalName::getDdeLinkData( OUString& orDdeServer, OUString& orDdeTopic, OUString& orDdeItem )
248 : : {
249 [ # # ][ # # ]: 0 : if( (mrParentLink.getLinkType() == LINKTYPE_DDE) && !maModel.maName.isEmpty() )
[ # # ]
250 : : {
251 : : // try to create a DDE link and to set the imported link results
252 [ # # ]: 0 : if( !mbDdeLinkCreated ) try
253 : : {
254 [ # # ][ # # ]: 0 : PropertySet aDocProps( getDocument() );
255 [ # # ][ # # ]: 0 : Reference< XDDELinks > xDdeLinks( aDocProps.getAnyProperty( PROP_DDELinks ), UNO_QUERY_THROW );
256 [ # # ][ # # ]: 0 : mxDdeLink = xDdeLinks->addDDELink( mrParentLink.getClassName(), mrParentLink.getTargetUrl(), maModel.maName, ::com::sun::star::sheet::DDELinkMode_DEFAULT );
[ # # ]
257 : 0 : mbDdeLinkCreated = true; // ignore if setting results fails
258 [ # # ]: 0 : if( !maResults.empty() )
259 : : {
260 [ # # ]: 0 : Reference< XDDELinkResults > xResults( mxDdeLink, UNO_QUERY_THROW );
261 [ # # ][ # # ]: 0 : xResults->setResults( ContainerHelper::matrixToSequenceSequence( maResults ) );
[ # # ][ # # ]
262 [ # # ][ # # ]: 0 : }
263 : : }
264 : 0 : catch( Exception& )
265 : : {
266 : : OSL_FAIL( "ExternalName::getDdeLinkData - cannot create DDE link" );
267 : : }
268 : : // get link data from created DDE link
269 [ # # ]: 0 : if( mxDdeLink.is() )
270 : : {
271 : 0 : orDdeServer = mxDdeLink->getApplication();
272 : 0 : orDdeTopic = mxDdeLink->getTopic();
273 : 0 : orDdeItem = mxDdeLink->getItem();
274 : 0 : return true;
275 : : }
276 : : }
277 : 0 : return false;
278 : : }
279 : :
280 : : // private --------------------------------------------------------------------
281 : :
282 : 0 : void ExternalName::setResultSize( sal_Int32 nColumns, sal_Int32 nRows )
283 : : {
284 : : OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_DDE) || (mrParentLink.getLinkType() == LINKTYPE_OLE) ||
285 : : (mrParentLink.getLinkType() == LINKTYPE_MAYBE_DDE_OLE), "ExternalName::setResultSize - wrong link type" );
286 : : OSL_ENSURE( (nRows > 0) && (nColumns > 0), "ExternalName::setResultSize - invalid matrix size" );
287 : 0 : const CellAddress& rMaxPos = getAddressConverter().getMaxApiAddress();
288 [ # # ][ # # ]: 0 : if( (0 < nRows) && (nRows <= rMaxPos.Row + 1) && (0 < nColumns) && (nColumns <= rMaxPos.Column + 1) )
[ # # ][ # # ]
289 [ # # ][ # # ]: 0 : maResults.resize( static_cast< size_t >( nColumns ), static_cast< size_t >( nRows ), Any( BiffHelper::calcDoubleFromError( BIFF_ERR_NA ) ) );
290 : : else
291 : 0 : maResults.clear();
292 : 0 : maCurrIt = maResults.begin();
293 : 0 : }
294 : :
295 : : // ============================================================================
296 : :
297 : 0 : void LinkSheetRange::setDeleted()
298 : : {
299 : 0 : meType = LINKSHEETRANGE_INTERNAL;
300 : 0 : mnDocLink = mnFirst = mnLast = -1;
301 : 0 : }
302 : :
303 : 0 : void LinkSheetRange::setSameSheet()
304 : : {
305 : 0 : meType = LINKSHEETRANGE_SAMESHEET;
306 : 0 : mnDocLink = -1;
307 : 0 : mnFirst = mnLast = 0;
308 : 0 : }
309 : :
310 : 0 : void LinkSheetRange::setRange( sal_Int32 nFirst, sal_Int32 nLast )
311 : : {
312 : 0 : meType = LINKSHEETRANGE_INTERNAL;
313 : 0 : mnDocLink = -1;
314 : 0 : mnFirst = ::std::min( nFirst, nLast );
315 : 0 : mnLast = ::std::max( nFirst, nLast );
316 : 0 : }
317 : :
318 : 0 : void LinkSheetRange::setExternalRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast )
319 : : {
320 [ # # ]: 0 : if( nDocLink < 0 )
321 : : {
322 : 0 : setDeleted();
323 : : }
324 : : else
325 : : {
326 : 0 : meType = LINKSHEETRANGE_EXTERNAL;
327 : 0 : mnDocLink = nDocLink;
328 : 0 : mnFirst = ::std::min( nFirst, nLast );
329 : 0 : mnLast = ::std::max( nFirst, nLast );
330 : : }
331 : 0 : }
332 : :
333 : : // ============================================================================
334 : :
335 : 24 : ExternalLink::ExternalLink( const WorkbookHelper& rHelper ) :
336 : : WorkbookHelper( rHelper ),
337 : : meLinkType( LINKTYPE_UNKNOWN ),
338 [ + - ][ + - ]: 24 : meFuncLibType( FUNCLIB_UNKNOWN )
[ + - ]
339 : : {
340 : 24 : }
341 : :
342 : 0 : void ExternalLink::importExternalReference( const AttributeList& rAttribs )
343 : : {
344 [ # # ]: 0 : maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
345 : 0 : }
346 : :
347 : 0 : void ExternalLink::importExternalBook( const Relations& rRelations, const AttributeList& rAttribs )
348 : : {
349 [ # # ][ # # ]: 0 : parseExternalReference( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
350 : 0 : }
351 : :
352 : 0 : void ExternalLink::importSheetName( const AttributeList& rAttribs )
353 : : {
354 [ # # ][ # # ]: 0 : insertExternalSheet( rAttribs.getXString( XML_val, OUString() ) );
355 : 0 : }
356 : :
357 : 0 : void ExternalLink::importDefinedName( const AttributeList& rAttribs )
358 : : {
359 [ # # ]: 0 : createExternalName()->importDefinedName( rAttribs );
360 : 0 : }
361 : :
362 : 0 : void ExternalLink::importDdeLink( const AttributeList& rAttribs )
363 : : {
364 [ # # ]: 0 : OUString aDdeService = rAttribs.getXString( XML_ddeService, OUString() );
365 [ # # ]: 0 : OUString aDdeTopic = rAttribs.getXString( XML_ddeTopic, OUString() );
366 : 0 : setDdeOleTargetUrl( aDdeService, aDdeTopic, LINKTYPE_DDE );
367 : 0 : }
368 : :
369 : 0 : ExternalNameRef ExternalLink::importDdeItem( const AttributeList& rAttribs )
370 : : {
371 : 0 : ExternalNameRef xExtName = createExternalName();
372 [ # # ]: 0 : xExtName->importDdeItem( rAttribs );
373 : 0 : return xExtName;
374 : : }
375 : :
376 : 0 : void ExternalLink::importOleLink( const Relations& rRelations, const AttributeList& rAttribs )
377 : : {
378 [ # # ]: 0 : OUString aProgId = rAttribs.getXString( XML_progId, OUString() );
379 [ # # ][ # # ]: 0 : OUString aTargetUrl = rRelations.getExternalTargetFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
380 : 0 : setDdeOleTargetUrl( aProgId, aTargetUrl, LINKTYPE_OLE );
381 : 0 : }
382 : :
383 : 0 : ExternalNameRef ExternalLink::importOleItem( const AttributeList& rAttribs )
384 : : {
385 : 0 : ExternalNameRef xExtName = createExternalName();
386 [ # # ]: 0 : xExtName->importOleItem( rAttribs );
387 : 0 : return xExtName;
388 : : }
389 : :
390 : 0 : void ExternalLink::importExternalRef( SequenceInputStream& rStrm )
391 : : {
392 : 0 : rStrm >> maRelId;
393 : 0 : }
394 : :
395 : 0 : void ExternalLink::importExternalSelf( SequenceInputStream& )
396 : : {
397 : 0 : meLinkType = LINKTYPE_SELF;
398 : 0 : }
399 : :
400 : 0 : void ExternalLink::importExternalSame( SequenceInputStream& )
401 : : {
402 : 0 : meLinkType = LINKTYPE_SAME;
403 : 0 : }
404 : :
405 : 0 : void ExternalLink::importExternalAddin( SequenceInputStream& )
406 : : {
407 : 0 : meLinkType = LINKTYPE_UNKNOWN;
408 : 0 : }
409 : :
410 : 0 : void ExternalLink::importExternalBook( const Relations& rRelations, SequenceInputStream& rStrm )
411 : : {
412 [ # # # # ]: 0 : switch( rStrm.readuInt16() )
413 : : {
414 : : case BIFF12_EXTERNALBOOK_BOOK:
415 [ # # ]: 0 : parseExternalReference( rRelations, BiffHelper::readString( rStrm ) );
416 : 0 : break;
417 : : case BIFF12_EXTERNALBOOK_DDE:
418 : : {
419 : 0 : OUString aDdeService, aDdeTopic;
420 [ # # ][ # # ]: 0 : rStrm >> aDdeService >> aDdeTopic;
421 : 0 : setDdeOleTargetUrl( aDdeService, aDdeTopic, LINKTYPE_DDE );
422 : : }
423 : 0 : break;
424 : : case BIFF12_EXTERNALBOOK_OLE:
425 : : {
426 [ # # ][ # # ]: 0 : OUString aTargetUrl = rRelations.getExternalTargetFromRelId( BiffHelper::readString( rStrm ) );
427 [ # # ]: 0 : OUString aProgId = BiffHelper::readString( rStrm );
428 : 0 : setDdeOleTargetUrl( aProgId, aTargetUrl, LINKTYPE_OLE );
429 : : }
430 : 0 : break;
431 : : default:
432 : : OSL_FAIL( "ExternalLink::importExternalBook - unknown link type" );
433 : : }
434 : 0 : }
435 : :
436 : 0 : void ExternalLink::importExtSheetNames( SequenceInputStream& rStrm )
437 : : {
438 : : // load external sheet names and create the sheet caches in the Calc document
439 : : OSL_ENSURE( (meLinkType == LINKTYPE_EXTERNAL) || (meLinkType == LINKTYPE_LIBRARY),
440 : : "ExternalLink::importExtSheetNames - invalid link type" );
441 [ # # ]: 0 : if( meLinkType == LINKTYPE_EXTERNAL ) // ignore sheets of external libraries
442 [ # # ][ # # ]: 0 : for( sal_Int32 nSheet = 0, nCount = rStrm.readInt32(); !rStrm.isEof() && (nSheet < nCount); ++nSheet )
[ # # ]
443 [ # # ]: 0 : insertExternalSheet( BiffHelper::readString( rStrm ) );
444 : 0 : }
445 : :
446 : 0 : ExternalNameRef ExternalLink::importExternalName( SequenceInputStream& rStrm )
447 : : {
448 : 0 : ExternalNameRef xExtName = createExternalName();
449 [ # # ]: 0 : xExtName->importExternalName( rStrm );
450 : 0 : return xExtName;
451 : : }
452 : :
453 : 18 : ExternalLinkInfo ExternalLink::getLinkInfo() const
454 : : {
455 : 18 : ExternalLinkInfo aLinkInfo;
456 [ - - + ]: 18 : switch( meLinkType )
457 : : {
458 : : case LINKTYPE_EXTERNAL:
459 : 0 : aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::DOCUMENT;
460 [ # # ]: 0 : aLinkInfo.Data <<= maTargetUrl;
461 : 0 : break;
462 : : case LINKTYPE_DDE:
463 : : {
464 : 0 : aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::DDE;
465 [ # # ]: 0 : DDELinkInfo aDdeLinkInfo;
466 : 0 : aDdeLinkInfo.Service = maClassName;
467 : 0 : aDdeLinkInfo.Topic = maTargetUrl;
468 [ # # ]: 0 : ::std::vector< DDEItemInfo > aItemInfos;
469 [ # # ]: 0 : DDEItemInfo aItemInfo;
470 [ # # ][ # # ]: 0 : for( ExternalNameVector::const_iterator aIt = maExtNames.begin(), aEnd = maExtNames.end(); aIt != aEnd; ++aIt )
471 [ # # ][ # # ]: 0 : if( (*aIt)->getDdeItemInfo( aItemInfo ) )
472 [ # # ]: 0 : aItemInfos.push_back( aItemInfo );
473 [ # # ][ # # ]: 0 : aDdeLinkInfo.Items = ContainerHelper::vectorToSequence( aItemInfos );
[ # # ]
474 [ # # ][ # # ]: 0 : aLinkInfo.Data <<= aDdeLinkInfo;
[ # # ]
475 : : }
476 : 0 : break;
477 : : default:
478 : 18 : aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::UNKNOWN;
479 : : }
480 : 18 : return aLinkInfo;
481 : : }
482 : :
483 : 0 : FunctionLibraryType ExternalLink::getFuncLibraryType() const
484 : : {
485 [ # # ]: 0 : return (meLinkType == LINKTYPE_LIBRARY) ? meFuncLibType : FUNCLIB_UNKNOWN;
486 : : }
487 : :
488 : 0 : sal_Int32 ExternalLink::getDocumentLinkIndex() const
489 : : {
490 : : OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getDocumentLinkIndex - invalid link type" );
491 [ # # ]: 0 : return mxDocLink.is() ? mxDocLink->getTokenIndex() : -1;
492 : : }
493 : :
494 : 0 : sal_Int32 ExternalLink::getSheetCacheIndex( sal_Int32 nTabId ) const
495 : : {
496 : : OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getSheetCacheIndex - invalid link type" );
497 : : OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOXML) || (getBiff() == BIFF8),
498 : : "ExternalLink::getSheetCacheIndex - invalid sheet index" );
499 [ # # ]: 0 : return ContainerHelper::getVectorElement( maSheetCaches, nTabId, -1 );
500 : : }
501 : :
502 : 0 : Reference< XExternalSheetCache > ExternalLink::getSheetCache( sal_Int32 nTabId ) const
503 : : {
504 : 0 : sal_Int32 nCacheIdx = getSheetCacheIndex( nTabId );
505 [ # # ][ # # ]: 0 : if( mxDocLink.is() && (nCacheIdx >= 0) ) try
[ # # ]
506 : : {
507 : : // existing mxDocLink implies that this is an external link
508 [ # # ][ # # ]: 0 : Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( nCacheIdx ), UNO_QUERY_THROW );
[ # # ][ # # ]
509 : 0 : return xSheetCache;
510 : : }
511 : 0 : catch( Exception& )
512 : : {
513 : : }
514 : 0 : return 0;
515 : : }
516 : :
517 : 0 : void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const
518 : : {
519 [ # # # # ]: 0 : switch( meLinkType )
520 : : {
521 : : case LINKTYPE_SAME:
522 : 0 : orSheetRange.setSameSheet();
523 : 0 : break;
524 : :
525 : : case LINKTYPE_SELF:
526 : : case LINKTYPE_INTERNAL:
527 : 0 : orSheetRange.setRange( nTabId1, nTabId2 );
528 : 0 : break;
529 : :
530 : : case LINKTYPE_EXTERNAL:
531 : : {
532 : 0 : sal_Int32 nDocLinkIdx = getDocumentLinkIndex();
533 [ # # # # ]: 0 : switch( getFilterType() )
534 : : {
535 : : case FILTER_OOXML:
536 : : // BIFF12: passed indexes point into sheet list of EXTSHEETLIST
537 : 0 : orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
538 : 0 : break;
539 : : case FILTER_BIFF:
540 [ # # # # : 0 : switch( getBiff() )
# ]
541 : : {
542 : : case BIFF2:
543 : : case BIFF3:
544 : : case BIFF4:
545 : 0 : orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
546 : 0 : break;
547 : : case BIFF5:
548 : : // BIFF5: first sheet from this external link, last sheet is passed in nTabId2
549 [ # # ]: 0 : if( const ExternalLink* pExtLink2 = getExternalLinks().getExternalLink( nTabId2 ).get() )
550 [ # # ][ # # ]: 0 : if( (pExtLink2->getLinkType() == LINKTYPE_EXTERNAL) && (maTargetUrl == pExtLink2->getTargetUrl()) )
[ # # ]
551 : 0 : orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex(), pExtLink2->getSheetCacheIndex() );
552 : 0 : break;
553 : : case BIFF8:
554 : : // BIFF8: passed indexes point into sheet list of EXTERNALBOOK
555 : 0 : orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
556 : 0 : break;
557 : 0 : case BIFF_UNKNOWN: break;
558 : : }
559 : 0 : break;
560 : 0 : case FILTER_UNKNOWN: break;
561 : : }
562 : : }
563 : 0 : break;
564 : :
565 : : default:
566 : : // unsupported/unexpected link type: #REF! error
567 : 0 : orSheetRange.setDeleted();
568 : : }
569 : 0 : }
570 : :
571 : 0 : ExternalNameRef ExternalLink::getNameByIndex( sal_Int32 nIndex ) const
572 : : {
573 : 0 : return maExtNames.get( nIndex );
574 : : }
575 : :
576 : : // private --------------------------------------------------------------------
577 : :
578 : : #define OOX_TARGETTYPE_EXTLINK CREATE_OFFICEDOC_RELATION_TYPE( "externalLinkPath" )
579 : : #define OOX_TARGETTYPE_LIBRARY CREATE_MSOFFICE_RELATION_TYPE( "xlExternalLinkPath/xlLibrary" )
580 : :
581 : 0 : void ExternalLink::setExternalTargetUrl( const OUString& rTargetUrl, const OUString& rTargetType )
582 : : {
583 : 0 : meLinkType = LINKTYPE_UNKNOWN;
584 [ # # ]: 0 : if( rTargetType == OOX_TARGETTYPE_EXTLINK )
585 : : {
586 : 0 : maTargetUrl = getBaseFilter().getAbsoluteUrl( rTargetUrl );
587 [ # # ]: 0 : if( !maTargetUrl.isEmpty() )
588 : 0 : meLinkType = LINKTYPE_EXTERNAL;
589 : : }
590 [ # # ]: 0 : else if( rTargetType == OOX_TARGETTYPE_LIBRARY )
591 : : {
592 : 0 : meLinkType = LINKTYPE_LIBRARY;
593 : 0 : meFuncLibType = getFormulaParser().getFuncLibTypeFromLibraryName( rTargetUrl );
594 : : }
595 : : OSL_ENSURE( meLinkType != LINKTYPE_UNKNOWN, "ExternalLink::setExternalTargetUrl - empty target URL or unknown target type" );
596 : :
597 : : // create the external document link API object that will contain the sheet caches
598 [ # # ]: 0 : if( meLinkType == LINKTYPE_EXTERNAL ) try
599 : : {
600 [ # # ][ # # ]: 0 : PropertySet aDocProps( getDocument() );
601 [ # # ][ # # ]: 0 : Reference< XExternalDocLinks > xDocLinks( aDocProps.getAnyProperty( PROP_ExternalDocLinks ), UNO_QUERY_THROW );
602 [ # # ][ # # ]: 0 : mxDocLink = xDocLinks->addDocLink( maTargetUrl );
[ # # ][ # # ]
[ # # ]
603 : : }
604 : 0 : catch( Exception& )
605 : : {
606 : : }
607 : 0 : }
608 : :
609 : 0 : void ExternalLink::setDdeOleTargetUrl( const OUString& rClassName, const OUString& rTargetUrl, ExternalLinkType eLinkType )
610 : : {
611 : 0 : maClassName = rClassName;
612 : 0 : maTargetUrl = rTargetUrl;
613 [ # # ][ # # ]: 0 : meLinkType = (maClassName.isEmpty() || maTargetUrl.isEmpty()) ? LINKTYPE_UNKNOWN : eLinkType;
614 : : OSL_ENSURE( meLinkType == eLinkType, "ExternalLink::setDdeOleTargetUrl - missing classname or target" );
615 : 0 : }
616 : :
617 : 0 : void ExternalLink::parseExternalReference( const Relations& rRelations, const OUString& rRelId )
618 : : {
619 [ # # ]: 0 : if( const Relation* pRelation = rRelations.getRelationFromRelId( rRelId ) )
620 : 0 : setExternalTargetUrl( pRelation->maTarget, pRelation->maType );
621 : 0 : }
622 : :
623 : 0 : void ExternalLink::insertExternalSheet( const OUString& rSheetName )
624 : : {
625 : : OSL_ENSURE( !rSheetName.isEmpty(), "ExternalLink::insertExternalSheet - empty sheet name" );
626 [ # # ]: 0 : if( mxDocLink.is() )
627 : : {
628 [ # # ][ # # ]: 0 : Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName, false );
629 [ # # ][ # # ]: 0 : sal_Int32 nCacheIdx = xSheetCache.is() ? xSheetCache->getTokenIndex() : -1;
[ # # ]
630 [ # # ]: 0 : maSheetCaches.push_back( nCacheIdx );
631 : : }
632 : 0 : }
633 : :
634 : 0 : ExternalNameRef ExternalLink::createExternalName()
635 : : {
636 [ # # ][ # # ]: 0 : ExternalNameRef xExtName( new ExternalName( *this ) );
637 [ # # ]: 0 : maExtNames.push_back( xExtName );
638 : 0 : return xExtName;
639 : : }
640 : :
641 : : // ============================================================================
642 : :
643 : 0 : RefSheetsModel::RefSheetsModel() :
644 : : mnExtRefId( -1 ),
645 : : mnTabId1( -1 ),
646 : 0 : mnTabId2( -1 )
647 : : {
648 : 0 : }
649 : :
650 : 0 : void RefSheetsModel::readBiff12Data( SequenceInputStream& rStrm )
651 : : {
652 : 0 : rStrm >> mnExtRefId >> mnTabId1 >> mnTabId2;
653 : 0 : }
654 : :
655 : : // ----------------------------------------------------------------------------
656 : :
657 : 24 : ExternalLinkBuffer::ExternalLinkBuffer( const WorkbookHelper& rHelper ) :
658 : : WorkbookHelper( rHelper ),
659 [ + - ]: 24 : mxSelfRef( new ExternalLink( rHelper ) ),
660 [ + - ][ + - ]: 48 : mbUseRefSheets( false )
[ + - ][ + - ]
[ + - ]
661 : : {
662 : 24 : mxSelfRef->setSelfLinkType();
663 : 24 : }
664 : :
665 : 0 : ExternalLinkRef ExternalLinkBuffer::importExternalReference( const AttributeList& rAttribs )
666 : : {
667 : 0 : ExternalLinkRef xExtLink = createExternalLink();
668 [ # # ]: 0 : xExtLink->importExternalReference( rAttribs );
669 [ # # ]: 0 : maExtLinks.push_back( xExtLink );
670 : 0 : return xExtLink;
671 : : }
672 : :
673 : 0 : ExternalLinkRef ExternalLinkBuffer::importExternalRef( SequenceInputStream& rStrm )
674 : : {
675 : 0 : mbUseRefSheets = true;
676 : 0 : ExternalLinkRef xExtLink = createExternalLink();
677 [ # # ]: 0 : xExtLink->importExternalRef( rStrm );
678 [ # # ]: 0 : maExtLinks.push_back( xExtLink );
679 : 0 : return xExtLink;
680 : : }
681 : :
682 : 0 : void ExternalLinkBuffer::importExternalSelf( SequenceInputStream& rStrm )
683 : : {
684 : 0 : mbUseRefSheets = true;
685 : 0 : createExternalLink()->importExternalSelf( rStrm );
686 : 0 : }
687 : :
688 : 0 : void ExternalLinkBuffer::importExternalSame( SequenceInputStream& rStrm )
689 : : {
690 : 0 : mbUseRefSheets = true;
691 : 0 : createExternalLink()->importExternalSame( rStrm );
692 : 0 : }
693 : :
694 : 0 : void ExternalLinkBuffer::importExternalAddin( SequenceInputStream& rStrm )
695 : : {
696 : 0 : mbUseRefSheets = true;
697 : 0 : createExternalLink()->importExternalAddin( rStrm );
698 : 0 : }
699 : :
700 : 0 : void ExternalLinkBuffer::importExternalSheets( SequenceInputStream& rStrm )
701 : : {
702 : : OSL_ENSURE( mbUseRefSheets, "ExternalLinkBuffer::importExternalSheets - missing EXTERNALREFS records" );
703 : 0 : mbUseRefSheets = true;
704 : : OSL_ENSURE( maRefSheets.empty(), "ExternalLinkBuffer::importExternalSheets - multiple EXTERNALSHEETS records" );
705 : 0 : maRefSheets.clear();
706 : : sal_Int32 nRefCount;
707 [ # # ]: 0 : rStrm >> nRefCount;
708 [ # # ][ # # ]: 0 : size_t nMaxCount = getLimitedValue< size_t, sal_Int64 >( nRefCount, 0, rStrm.getRemaining() / 12 );
709 [ # # ]: 0 : maRefSheets.reserve( nMaxCount );
710 [ # # ][ # # ]: 0 : for( size_t nRefId = 0; !rStrm.isEof() && (nRefId < nMaxCount); ++nRefId )
[ # # ]
711 : : {
712 : 0 : RefSheetsModel aRefSheets;
713 [ # # ]: 0 : aRefSheets.readBiff12Data( rStrm );
714 [ # # ]: 0 : maRefSheets.push_back( aRefSheets );
715 : : }
716 : 0 : }
717 : :
718 : 18 : Sequence< ExternalLinkInfo > ExternalLinkBuffer::getLinkInfos() const
719 : : {
720 [ + - ]: 18 : ::std::vector< ExternalLinkInfo > aLinkInfos;
721 : : // should not be used for BIFF12 documents
722 : : OSL_ENSURE( (getFilterType() == FILTER_OOXML) && !mbUseRefSheets, "ExternalLinkBuffer::getLinkInfos - unexpected file format" );
723 : : // add entry for implicit index 0 (self reference to this document)
724 [ + - ][ + - ]: 18 : aLinkInfos.push_back( mxSelfRef->getLinkInfo() );
725 [ + - ][ - + ]: 18 : for( ExternalLinkVec::const_iterator aIt = maExtLinks.begin(), aEnd = maExtLinks.end(); aIt != aEnd; ++aIt )
726 [ # # ][ # # ]: 0 : aLinkInfos.push_back( (*aIt)->getLinkInfo() );
727 [ + - ]: 18 : return ContainerHelper::vectorToSequence( aLinkInfos );
728 : : }
729 : :
730 : 0 : ExternalLinkRef ExternalLinkBuffer::getExternalLink( sal_Int32 nRefId, bool bUseRefSheets ) const
731 : : {
732 : 0 : ExternalLinkRef xExtLink;
733 [ # # # # ]: 0 : switch( getFilterType() )
[ # # ]
734 : : {
735 : : case FILTER_OOXML:
736 : : // OOXML: 0 = this document, otherwise one-based index into link list
737 [ # # ][ # # ]: 0 : if( !bUseRefSheets || !mbUseRefSheets )
738 [ # # ][ # # ]: 0 : xExtLink = (nRefId == 0) ? mxSelfRef : maLinks.get( nRefId - 1 );
[ # # ][ # # ]
[ # # ]
739 : : // BIFF12: zero-based index into ref-sheets list
740 [ # # ][ # # ]: 0 : else if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
741 [ # # ][ # # ]: 0 : xExtLink = maLinks.get( pRefSheets->mnExtRefId );
[ # # ]
742 : 0 : break;
743 : : case FILTER_BIFF:
744 [ # # ][ # # : 0 : switch( getBiff() )
# # # ]
745 : : {
746 : : case BIFF2:
747 : : case BIFF3:
748 : : case BIFF4:
749 : : // one-based index to EXTERNSHEET records
750 [ # # ][ # # ]: 0 : xExtLink = maLinks.get( nRefId - 1 );
[ # # ]
751 : 0 : break;
752 : : case BIFF5:
753 [ # # ]: 0 : if( nRefId < 0 )
754 : : {
755 : : // internal links in formula tokens have negative index
756 [ # # ][ # # ]: 0 : xExtLink = maLinks.get( -nRefId - 1 );
[ # # ]
757 [ # # ][ # # ]: 0 : if( xExtLink.get() && !xExtLink->isInternalLink() )
[ # # ]
758 [ # # ]: 0 : xExtLink.reset();
759 : : }
760 : : else
761 : : {
762 : : // one-based index to EXTERNSHEET records
763 [ # # ][ # # ]: 0 : xExtLink = maLinks.get( nRefId - 1 );
[ # # ]
764 : : }
765 : 0 : break;
766 : : case BIFF8:
767 : : // zero-based index into REF list in EXTERNSHEET record
768 [ # # ][ # # ]: 0 : if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
769 [ # # ][ # # ]: 0 : xExtLink = maLinks.get( pRefSheets->mnExtRefId );
[ # # ]
770 : 0 : break;
771 : 0 : case BIFF_UNKNOWN: break;
772 : : }
773 : 0 : break;
774 : 0 : case FILTER_UNKNOWN: break;
775 : : }
776 : 0 : return xExtLink;
777 : : }
778 : :
779 : 0 : LinkSheetRange ExternalLinkBuffer::getSheetRange( sal_Int32 nRefId, sal_Int16 nTabId1, sal_Int16 nTabId2 ) const
780 : : {
781 : : OSL_ENSURE( getBiff() <= BIFF5, "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
782 : 0 : LinkSheetRange aSheetRange;
783 [ # # ]: 0 : if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
784 : 0 : pExtLink->getSheetRange( aSheetRange, nTabId1, nTabId2 );
785 : 0 : return aSheetRange;
786 : : }
787 : :
788 : 0 : LinkSheetRange ExternalLinkBuffer::getSheetRange( sal_Int32 nRefId ) const
789 : : {
790 : : OSL_ENSURE( ((getFilterType() == FILTER_OOXML) && mbUseRefSheets) || (getBiff() == BIFF8), "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
791 : 0 : LinkSheetRange aSheetRange;
792 [ # # ]: 0 : if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
793 [ # # ]: 0 : if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
794 : 0 : pExtLink->getSheetRange( aSheetRange, pRefSheets->mnTabId1, pRefSheets->mnTabId2 );
795 : 0 : return aSheetRange;
796 : : }
797 : :
798 : : // private --------------------------------------------------------------------
799 : :
800 : 0 : ExternalLinkRef ExternalLinkBuffer::createExternalLink()
801 : : {
802 [ # # ][ # # ]: 0 : ExternalLinkRef xExtLink( new ExternalLink( *this ) );
803 [ # # ]: 0 : maLinks.push_back( xExtLink );
804 : 0 : return xExtLink;
805 : : }
806 : :
807 : 0 : const RefSheetsModel* ExternalLinkBuffer::getRefSheets( sal_Int32 nRefId ) const
808 : : {
809 : 0 : return ((0 <= nRefId) && (static_cast< size_t >( nRefId ) < maRefSheets.size())) ?
810 [ # # # # ]: 0 : &maRefSheets[ static_cast< size_t >( nRefId ) ] : 0;
811 : : }
812 : :
813 : : // ============================================================================
814 : :
815 : : } // namespace xls
816 [ + - ][ + - ]: 24 : } // namespace oox
817 : :
818 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|