Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / source / filter / oox / externallinkbuffer.cxx
blob152841b2c932227f23a6582df79f6eced8ddfbd2
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 <externallinkbuffer.hxx>
22 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include <com/sun/star/sheet/DDELinkInfo.hpp>
24 #include <com/sun/star/sheet/ExternalLinkType.hpp>
25 #include <com/sun/star/sheet/XDDELinks.hpp>
26 #include <com/sun/star/sheet/XDDELinkResults.hpp>
27 #include <com/sun/star/sheet/XExternalDocLinks.hpp>
28 #include <osl/diagnose.h>
29 #include <sal/log.hxx>
30 #include <oox/core/filterbase.hxx>
31 #include <oox/helper/attributelist.hxx>
32 #include <oox/helper/binaryinputstream.hxx>
33 #include <oox/token/namespaces.hxx>
34 #include <oox/token/properties.hxx>
35 #include <oox/core/relations.hxx>
36 #include <oox/token/tokens.hxx>
37 #include <addressconverter.hxx>
38 #include <biffhelper.hxx>
40 namespace oox {
41 namespace xls {
43 using namespace ::com::sun::star::sheet;
44 using namespace ::com::sun::star::uno;
46 using ::oox::core::Relation;
47 using ::oox::core::Relations;
49 namespace {
51 const sal_uInt16 BIFF12_EXTERNALBOOK_BOOK = 0;
52 const sal_uInt16 BIFF12_EXTERNALBOOK_DDE = 1;
53 const sal_uInt16 BIFF12_EXTERNALBOOK_OLE = 2;
55 const sal_uInt16 BIFF12_EXTNAME_AUTOMATIC = 0x0002;
56 const sal_uInt16 BIFF12_EXTNAME_PREFERPIC = 0x0004;
57 const sal_uInt16 BIFF12_EXTNAME_STDDOCNAME = 0x0008;
58 const sal_uInt16 BIFF12_EXTNAME_OLEOBJECT = 0x0010;
59 const sal_uInt16 BIFF12_EXTNAME_ICONIFIED = 0x0020;
61 } // namespace
63 ExternalNameModel::ExternalNameModel() :
64 mbNotify( false ),
65 mbPreferPic( false ),
66 mbStdDocName( false ),
67 mbOleObj( false ),
68 mbIconified( false )
72 ExternalName::ExternalName( const ExternalLink& rParentLink ) :
73 DefinedNameBase( rParentLink ),
74 mrParentLink( rParentLink ),
75 mbDdeLinkCreated( false )
79 void ExternalName::importDefinedName( const AttributeList& rAttribs )
81 maModel.maName = rAttribs.getXString( XML_name, OUString() );
82 OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importDefinedName - empty name" );
83 // zero-based index into sheet list of externalBook
84 maModel.mnSheet = rAttribs.getInteger( XML_sheetId, -1 );
87 void ExternalName::importDdeItem( const AttributeList& rAttribs )
89 maModel.maName = rAttribs.getXString( XML_name, OUString() );
90 OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importDdeItem - empty name" );
91 maExtNameModel.mbOleObj = false;
92 maExtNameModel.mbStdDocName = rAttribs.getBool( XML_ole, false );
93 maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
94 maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
97 void ExternalName::importValues( const AttributeList& rAttribs )
99 setResultSize( rAttribs.getInteger( XML_cols, 1 ), rAttribs.getInteger( XML_rows, 1 ) );
102 void ExternalName::importOleItem( const AttributeList& rAttribs )
104 maModel.maName = rAttribs.getXString( XML_name, OUString() );
105 OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importOleItem - empty name" );
106 maExtNameModel.mbOleObj = true;
107 maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
108 maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
109 maExtNameModel.mbIconified = rAttribs.getBool( XML_icon, false );
112 void ExternalName::importExternalName( SequenceInputStream& rStrm )
114 rStrm >> maModel.maName;
115 OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importExternalName - empty name" );
118 void ExternalName::importExternalNameFlags( SequenceInputStream& rStrm )
120 sal_uInt16 nFlags;
121 sal_Int32 nSheetId;
122 nFlags = rStrm.readuInt16();
123 nSheetId = rStrm.readInt32();
124 // index into sheet list of EXTSHEETNAMES (one-based in BIFF12)
125 maModel.mnSheet = nSheetId - 1;
126 // no flag for built-in names, as in OOXML...
127 maExtNameModel.mbNotify = getFlag( nFlags, BIFF12_EXTNAME_AUTOMATIC );
128 maExtNameModel.mbPreferPic = getFlag( nFlags, BIFF12_EXTNAME_PREFERPIC );
129 maExtNameModel.mbStdDocName = getFlag( nFlags, BIFF12_EXTNAME_STDDOCNAME );
130 maExtNameModel.mbOleObj = getFlag( nFlags, BIFF12_EXTNAME_OLEOBJECT );
131 maExtNameModel.mbIconified = getFlag( nFlags, BIFF12_EXTNAME_ICONIFIED );
132 OSL_ENSURE( (mrParentLink.getLinkType() == ExternalLinkType::OLE) == maExtNameModel.mbOleObj,
133 "ExternalName::importExternalNameFlags - wrong OLE flag in external name" );
136 void ExternalName::importDdeItemValues( SequenceInputStream& rStrm )
138 sal_Int32 nRows, nCols;
139 nRows = rStrm.readInt32();
140 nCols = rStrm.readInt32();
141 setResultSize( nCols, nRows );
144 void ExternalName::importDdeItemBool( SequenceInputStream& rStrm )
146 appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
149 void ExternalName::importDdeItemDouble( SequenceInputStream& rStrm )
151 appendResultValue( rStrm.readDouble() );
154 void ExternalName::importDdeItemError( SequenceInputStream& rStrm )
156 appendResultValue( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) );
159 void ExternalName::importDdeItemString( SequenceInputStream& rStrm )
161 appendResultValue( BiffHelper::readString( rStrm ) );
164 bool ExternalName::getDdeItemInfo( DDEItemInfo& orItemInfo ) const
166 if( (mrParentLink.getLinkType() == ExternalLinkType::DDE) && !maModel.maName.isEmpty() )
168 orItemInfo.Item = maModel.maName;
169 orItemInfo.Results = ContainerHelper::matrixToSequenceSequence( maResults );
170 return true;
172 return false;
175 bool ExternalName::getDdeLinkData( OUString& orDdeServer, OUString& orDdeTopic, OUString& orDdeItem )
177 if( (mrParentLink.getLinkType() == ExternalLinkType::DDE) && !maModel.maName.isEmpty() )
179 // try to create a DDE link and to set the imported link results
180 if( !mbDdeLinkCreated ) try
182 PropertySet aDocProps( getDocument() );
183 Reference< XDDELinks > xDdeLinks( aDocProps.getAnyProperty( PROP_DDELinks ), UNO_QUERY_THROW );
184 mxDdeLink = xDdeLinks->addDDELink( mrParentLink.getClassName(), mrParentLink.getTargetUrl(), maModel.maName, css::sheet::DDELinkMode_DEFAULT );
185 mbDdeLinkCreated = true; // ignore if setting results fails
186 if( !maResults.empty() )
188 Reference< XDDELinkResults > xResults( mxDdeLink, UNO_QUERY_THROW );
189 xResults->setResults( ContainerHelper::matrixToSequenceSequence( maResults ) );
192 catch( Exception& )
194 OSL_FAIL( "ExternalName::getDdeLinkData - cannot create DDE link" );
196 // get link data from created DDE link
197 if( mxDdeLink.is() )
199 orDdeServer = mxDdeLink->getApplication();
200 orDdeTopic = mxDdeLink->getTopic();
201 orDdeItem = mxDdeLink->getItem();
202 return true;
205 return false;
208 // private --------------------------------------------------------------------
210 void ExternalName::setResultSize( sal_Int32 nColumns, sal_Int32 nRows )
212 OSL_ENSURE( (mrParentLink.getLinkType() == ExternalLinkType::DDE) || (mrParentLink.getLinkType() == ExternalLinkType::OLE),
213 "ExternalName::setResultSize - wrong link type" );
214 OSL_ENSURE( (nRows > 0) && (nColumns > 0), "ExternalName::setResultSize - invalid matrix size" );
215 const ScAddress& rMaxPos = getAddressConverter().getMaxApiAddress();
216 if( (0 < nRows) && (nRows <= rMaxPos.Row() + 1) && (0 < nColumns) && (nColumns <= rMaxPos.Col() + 1) )
217 maResults.resize( static_cast< size_t >( nColumns ), static_cast< size_t >( nRows ), Any( BiffHelper::calcDoubleFromError( BIFF_ERR_NA ) ) );
218 else
219 maResults.clear();
220 maCurrIt = maResults.begin();
223 void LinkSheetRange::setDeleted()
225 meType = LINKSHEETRANGE_INTERNAL;
226 mnDocLink = mnFirst = mnLast = -1;
229 void LinkSheetRange::setSameSheet()
231 meType = LINKSHEETRANGE_SAMESHEET;
232 mnDocLink = -1;
233 mnFirst = mnLast = 0;
236 void LinkSheetRange::setRange( sal_Int32 nFirst, sal_Int32 nLast )
238 meType = LINKSHEETRANGE_INTERNAL;
239 mnDocLink = -1;
240 mnFirst = ::std::min( nFirst, nLast );
241 mnLast = ::std::max( nFirst, nLast );
244 void LinkSheetRange::setExternalRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast )
246 if( nDocLink < 0 )
248 setDeleted();
250 else
252 meType = LINKSHEETRANGE_EXTERNAL;
253 mnDocLink = nDocLink;
254 mnFirst = ::std::min( nFirst, nLast );
255 mnLast = ::std::max( nFirst, nLast );
259 ExternalLink::ExternalLink( const WorkbookHelper& rHelper ) :
260 WorkbookHelper( rHelper ),
261 meLinkType( ExternalLinkType::Unknown ),
262 meFuncLibType( FUNCLIB_UNKNOWN )
266 void ExternalLink::importExternalReference( const AttributeList& rAttribs )
268 maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
271 void ExternalLink::importExternalBook( const Relations& rRelations, const AttributeList& rAttribs )
273 parseExternalReference( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
276 void ExternalLink::importSheetName( const AttributeList& rAttribs )
278 insertExternalSheet( rAttribs.getXString( XML_val, OUString() ) );
281 void ExternalLink::importDefinedName( const AttributeList& rAttribs )
283 createExternalName()->importDefinedName( rAttribs );
286 void ExternalLink::importDdeLink( const AttributeList& rAttribs )
288 OUString aDdeService = rAttribs.getXString( XML_ddeService, OUString() );
289 OUString aDdeTopic = rAttribs.getXString( XML_ddeTopic, OUString() );
290 setDdeOleTargetUrl( aDdeService, aDdeTopic, ExternalLinkType::DDE );
293 ExternalNameRef ExternalLink::importDdeItem( const AttributeList& rAttribs )
295 ExternalNameRef xExtName = createExternalName();
296 xExtName->importDdeItem( rAttribs );
297 return xExtName;
300 void ExternalLink::importOleLink( const Relations& rRelations, const AttributeList& rAttribs )
302 OUString aProgId = rAttribs.getXString( XML_progId, OUString() );
303 OUString aTargetUrl = rRelations.getExternalTargetFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
304 setDdeOleTargetUrl( aProgId, aTargetUrl, ExternalLinkType::OLE );
307 ExternalNameRef ExternalLink::importOleItem( const AttributeList& rAttribs )
309 ExternalNameRef xExtName = createExternalName();
310 xExtName->importOleItem( rAttribs );
311 return xExtName;
314 void ExternalLink::importExternalRef( SequenceInputStream& rStrm )
316 rStrm >> maRelId;
319 void ExternalLink::importExternalSelf( SequenceInputStream& )
321 meLinkType = ExternalLinkType::Self;
324 void ExternalLink::importExternalSame( SequenceInputStream& )
326 meLinkType = ExternalLinkType::Same;
329 void ExternalLink::importExternalAddin( SequenceInputStream& )
331 meLinkType = ExternalLinkType::Unknown;
334 void ExternalLink::importExternalBook( const Relations& rRelations, SequenceInputStream& rStrm )
336 switch( rStrm.readuInt16() )
338 case BIFF12_EXTERNALBOOK_BOOK:
339 parseExternalReference( rRelations, BiffHelper::readString( rStrm ) );
340 break;
341 case BIFF12_EXTERNALBOOK_DDE:
343 OUString aDdeService, aDdeTopic;
344 rStrm >> aDdeService >> aDdeTopic;
345 setDdeOleTargetUrl( aDdeService, aDdeTopic, ExternalLinkType::DDE );
347 break;
348 case BIFF12_EXTERNALBOOK_OLE:
350 OUString aTargetUrl = rRelations.getExternalTargetFromRelId( BiffHelper::readString( rStrm ) );
351 OUString aProgId = BiffHelper::readString( rStrm );
352 setDdeOleTargetUrl( aProgId, aTargetUrl, ExternalLinkType::OLE );
354 break;
355 default:
356 OSL_FAIL( "ExternalLink::importExternalBook - unknown link type" );
360 void ExternalLink::importExtSheetNames( SequenceInputStream& rStrm )
362 // load external sheet names and create the sheet caches in the Calc document
363 SAL_WARN_IF( (meLinkType != ExternalLinkType::External) && (meLinkType != ExternalLinkType::Library),
364 "sc.filter",
365 "Invalid link type: " << meLinkType );
366 if( meLinkType == ExternalLinkType::External ) // ignore sheets of external libraries
367 for( sal_Int32 nSheet = 0, nCount = rStrm.readInt32(); !rStrm.isEof() && (nSheet < nCount); ++nSheet )
368 insertExternalSheet( BiffHelper::readString( rStrm ) );
371 ExternalNameRef ExternalLink::importExternalName( SequenceInputStream& rStrm )
373 ExternalNameRef xExtName = createExternalName();
374 xExtName->importExternalName( rStrm );
375 return xExtName;
378 ExternalLinkInfo ExternalLink::getLinkInfo() const
380 ExternalLinkInfo aLinkInfo;
381 switch( meLinkType )
383 case ExternalLinkType::Self:
384 case ExternalLinkType::Same:
385 aLinkInfo.Type = css::sheet::ExternalLinkType::SELF;
386 break;
387 case ExternalLinkType::External:
388 aLinkInfo.Type = css::sheet::ExternalLinkType::DOCUMENT;
389 aLinkInfo.Data <<= maTargetUrl;
390 break;
391 case ExternalLinkType::Library:
392 // parser will return library function names in OPCODE_BAD string tokens
393 aLinkInfo.Type = css::sheet::ExternalLinkType::SPECIAL;
394 break;
395 case ExternalLinkType::DDE:
397 aLinkInfo.Type = css::sheet::ExternalLinkType::DDE;
398 DDELinkInfo aDdeLinkInfo;
399 aDdeLinkInfo.Service = maClassName;
400 aDdeLinkInfo.Topic = maTargetUrl;
401 ::std::vector< DDEItemInfo > aItemInfos;
402 DDEItemInfo aItemInfo;
403 for( const auto& rxExtName : maExtNames )
404 if( rxExtName->getDdeItemInfo( aItemInfo ) )
405 aItemInfos.push_back( aItemInfo );
406 aDdeLinkInfo.Items = ContainerHelper::vectorToSequence( aItemInfos );
407 aLinkInfo.Data <<= aDdeLinkInfo;
409 break;
410 default:
411 aLinkInfo.Type = css::sheet::ExternalLinkType::UNKNOWN;
413 return aLinkInfo;
416 FunctionLibraryType ExternalLink::getFuncLibraryType() const
418 return (meLinkType == ExternalLinkType::Library) ? meFuncLibType : FUNCLIB_UNKNOWN;
421 sal_Int32 ExternalLink::getDocumentLinkIndex() const
423 OSL_ENSURE( meLinkType == ExternalLinkType::External, "ExternalLink::getDocumentLinkIndex - invalid link type" );
424 return mxDocLink.is() ? mxDocLink->getTokenIndex() : -1;
427 sal_Int32 ExternalLink::getSheetCacheIndex( sal_Int32 nTabId ) const
429 OSL_ENSURE( meLinkType == ExternalLinkType::External, "ExternalLink::getSheetCacheIndex - invalid link type" );
430 return ContainerHelper::getVectorElement( maSheetCaches, nTabId, -1 );
433 Reference< XExternalSheetCache > ExternalLink::getSheetCache( sal_Int32 nTabId ) const
435 sal_Int32 nCacheIdx = getSheetCacheIndex( nTabId );
436 if( mxDocLink.is() && (nCacheIdx >= 0) ) try
438 // existing mxDocLink implies that this is an external link
439 Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( nCacheIdx ), UNO_QUERY_THROW );
440 return xSheetCache;
442 catch( Exception& )
445 return nullptr;
448 void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const
450 switch( meLinkType )
452 case ExternalLinkType::Same:
453 orSheetRange.setSameSheet();
454 break;
456 case ExternalLinkType::Self:
457 orSheetRange.setRange( nTabId1, nTabId2 );
458 break;
460 case ExternalLinkType::External:
462 sal_Int32 nDocLinkIdx = getDocumentLinkIndex();
463 // BIFF12: passed indexes point into sheet list of EXTSHEETLIST
464 orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
466 break;
468 default:
469 // unsupported/unexpected link type: #REF! error
470 orSheetRange.setDeleted();
474 ExternalNameRef ExternalLink::getNameByIndex( sal_Int32 nIndex ) const
476 return maExtNames.get( nIndex );
479 // private --------------------------------------------------------------------
481 void ExternalLink::setExternalTargetUrl( const OUString& rTargetUrl, const OUString& rTargetType )
483 meLinkType = ExternalLinkType::Unknown;
484 if( rTargetType == CREATE_OFFICEDOC_RELATION_TYPE( "externalLinkPath" ) ||
485 rTargetType == CREATE_OFFICEDOC_RELATION_TYPE_STRICT( "externalLinkPath" ) )
487 maTargetUrl = getBaseFilter().getAbsoluteUrl( rTargetUrl );
488 if( !maTargetUrl.isEmpty() )
489 meLinkType = ExternalLinkType::External;
491 else if( rTargetType == CREATE_MSOFFICE_RELATION_TYPE( "xlExternalLinkPath/xlPathMissing" ) )
493 meLinkType = ExternalLinkType::PathMissing;
495 else if( rTargetType == CREATE_MSOFFICE_RELATION_TYPE( "xlExternalLinkPath/xlLibrary" ) )
497 meLinkType = ExternalLinkType::Library;
498 meFuncLibType = FunctionProvider::getFuncLibTypeFromLibraryName( rTargetUrl );
500 SAL_WARN_IF( meLinkType == ExternalLinkType::Unknown, "sc.filter", "Empty target URL or unknown target type, URL='" << rTargetUrl << "', type='" << rTargetType << "'" );
502 // create the external document link API object that will contain the sheet caches
503 if( meLinkType == ExternalLinkType::External ) try
505 PropertySet aDocProps( getDocument() );
506 Reference< XExternalDocLinks > xDocLinks( aDocProps.getAnyProperty( PROP_ExternalDocLinks ), UNO_QUERY_THROW );
507 mxDocLink = xDocLinks->addDocLink( maTargetUrl );
509 catch( Exception& )
514 void ExternalLink::setDdeOleTargetUrl( const OUString& rClassName, const OUString& rTargetUrl, ExternalLinkType eLinkType )
516 maClassName = rClassName;
517 maTargetUrl = rTargetUrl;
518 meLinkType = (maClassName.isEmpty() || maTargetUrl.isEmpty()) ? ExternalLinkType::Unknown : eLinkType;
519 OSL_ENSURE( meLinkType == eLinkType, "ExternalLink::setDdeOleTargetUrl - missing classname or target" );
522 void ExternalLink::parseExternalReference( const Relations& rRelations, const OUString& rRelId )
524 if( const Relation* pRelation = rRelations.getRelationFromRelId( rRelId ) )
525 setExternalTargetUrl( pRelation->maTarget, pRelation->maType );
528 void ExternalLink::insertExternalSheet( const OUString& rSheetName )
530 OSL_ENSURE( !rSheetName.isEmpty(), "ExternalLink::insertExternalSheet - empty sheet name" );
531 if( mxDocLink.is() )
533 Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName, false );
534 sal_Int32 nCacheIdx = xSheetCache.is() ? xSheetCache->getTokenIndex() : -1;
535 maSheetCaches.push_back( nCacheIdx );
539 ExternalNameRef ExternalLink::createExternalName()
541 ExternalNameRef xExtName( new ExternalName( *this ) );
542 maExtNames.push_back( xExtName );
543 return xExtName;
546 RefSheetsModel::RefSheetsModel() :
547 mnExtRefId( -1 ),
548 mnTabId1( -1 ),
549 mnTabId2( -1 )
553 void RefSheetsModel::readBiff12Data( SequenceInputStream& rStrm )
555 mnExtRefId = rStrm.readInt32();
556 mnTabId1 = rStrm.readInt32();
557 mnTabId2 = rStrm.readInt32();
560 ExternalLinkBuffer::ExternalLinkBuffer( const WorkbookHelper& rHelper ) :
561 WorkbookHelper( rHelper ),
562 mxSelfRef( new ExternalLink( rHelper ) ),
563 mbUseRefSheets( false )
565 mxSelfRef->setSelfLinkType();
568 ExternalLinkRef ExternalLinkBuffer::importExternalReference( const AttributeList& rAttribs )
570 ExternalLinkRef xExtLink = createExternalLink();
571 xExtLink->importExternalReference( rAttribs );
572 maExtLinks.push_back( xExtLink );
573 return xExtLink;
576 ExternalLinkRef ExternalLinkBuffer::importExternalRef( SequenceInputStream& rStrm )
578 mbUseRefSheets = true;
579 ExternalLinkRef xExtLink = createExternalLink();
580 xExtLink->importExternalRef( rStrm );
581 maExtLinks.push_back( xExtLink );
582 return xExtLink;
585 void ExternalLinkBuffer::importExternalSelf( SequenceInputStream& rStrm )
587 mbUseRefSheets = true;
588 createExternalLink()->importExternalSelf( rStrm );
591 void ExternalLinkBuffer::importExternalSame( SequenceInputStream& rStrm )
593 mbUseRefSheets = true;
594 createExternalLink()->importExternalSame( rStrm );
597 void ExternalLinkBuffer::importExternalAddin( SequenceInputStream& rStrm )
599 mbUseRefSheets = true;
600 createExternalLink()->importExternalAddin( rStrm );
603 void ExternalLinkBuffer::importExternalSheets( SequenceInputStream& rStrm )
605 OSL_ENSURE( mbUseRefSheets, "ExternalLinkBuffer::importExternalSheets - missing EXTERNALREFS records" );
606 mbUseRefSheets = true;
607 OSL_ENSURE( maRefSheets.empty(), "ExternalLinkBuffer::importExternalSheets - multiple EXTERNALSHEETS records" );
608 maRefSheets.clear();
609 sal_Int32 nRefCount;
610 nRefCount = rStrm.readInt32();
611 size_t nMaxCount = getLimitedValue< size_t, sal_Int64 >( nRefCount, 0, rStrm.getRemaining() / 12 );
612 maRefSheets.reserve( nMaxCount );
613 for( size_t nRefId = 0; !rStrm.isEof() && (nRefId < nMaxCount); ++nRefId )
615 RefSheetsModel aRefSheets;
616 aRefSheets.readBiff12Data( rStrm );
617 maRefSheets.push_back( aRefSheets );
621 Sequence< ExternalLinkInfo > ExternalLinkBuffer::getLinkInfos() const
623 ::std::vector< ExternalLinkInfo > aLinkInfos;
624 // add entry for implicit index 0 (self reference to this document)
625 aLinkInfos.push_back( mxSelfRef->getLinkInfo() );
626 for( const auto& rxExtLink : maExtLinks )
627 aLinkInfos.push_back( rxExtLink->getLinkInfo() );
628 return ContainerHelper::vectorToSequence( aLinkInfos );
631 ExternalLinkRef ExternalLinkBuffer::getExternalLink( sal_Int32 nRefId, bool bUseRefSheets ) const
633 ExternalLinkRef xExtLink;
634 // OOXML: 0 = this document, otherwise one-based index into link list
635 if( !bUseRefSheets || !mbUseRefSheets )
636 xExtLink = (nRefId == 0) ? mxSelfRef : maLinks.get( nRefId - 1 );
637 // BIFF12: zero-based index into ref-sheets list
638 else if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
639 xExtLink = maLinks.get( pRefSheets->mnExtRefId );
640 return xExtLink;
643 LinkSheetRange ExternalLinkBuffer::getSheetRange( sal_Int32 nRefId ) const
645 OSL_ENSURE( mbUseRefSheets, "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
646 LinkSheetRange aSheetRange;
647 if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
648 if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
649 pExtLink->getSheetRange( aSheetRange, pRefSheets->mnTabId1, pRefSheets->mnTabId2 );
650 return aSheetRange;
653 // private --------------------------------------------------------------------
655 ExternalLinkRef ExternalLinkBuffer::createExternalLink()
657 ExternalLinkRef xExtLink( new ExternalLink( *this ) );
658 maLinks.push_back( xExtLink );
659 return xExtLink;
662 const RefSheetsModel* ExternalLinkBuffer::getRefSheets( sal_Int32 nRefId ) const
664 return ((0 <= nRefId) && (static_cast< size_t >( nRefId ) < maRefSheets.size())) ?
665 &maRefSheets[ static_cast< size_t >( nRefId ) ] : nullptr;
668 } // namespace xls
669 } // namespace oox
671 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */