nss: upgrade to release 3.73
[LibreOffice.git] / sc / source / filter / oox / externallinkbuffer.cxx
blob93f10d4d6264230077ce4e8a98354566544a09c1
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 <com/sun/star/sheet/XSpreadsheetDocument.hpp>
29 #include <o3tl/safeint.hxx>
30 #include <osl/diagnose.h>
31 #include <sal/log.hxx>
32 #include <oox/core/filterbase.hxx>
33 #include <oox/helper/attributelist.hxx>
34 #include <oox/helper/binaryinputstream.hxx>
35 #include <oox/token/namespaces.hxx>
36 #include <oox/token/properties.hxx>
37 #include <oox/core/relations.hxx>
38 #include <oox/token/tokens.hxx>
39 #include <addressconverter.hxx>
40 #include <biffhelper.hxx>
42 namespace oox::xls {
44 using namespace ::com::sun::star::sheet;
45 using namespace ::com::sun::star::uno;
47 using ::oox::core::Relation;
48 using ::oox::core::Relations;
50 namespace {
52 const sal_uInt16 BIFF12_EXTERNALBOOK_BOOK = 0;
53 const sal_uInt16 BIFF12_EXTERNALBOOK_DDE = 1;
54 const sal_uInt16 BIFF12_EXTERNALBOOK_OLE = 2;
56 const sal_uInt16 BIFF12_EXTNAME_AUTOMATIC = 0x0002;
57 const sal_uInt16 BIFF12_EXTNAME_PREFERPIC = 0x0004;
58 const sal_uInt16 BIFF12_EXTNAME_STDDOCNAME = 0x0008;
59 const sal_uInt16 BIFF12_EXTNAME_OLEOBJECT = 0x0010;
60 const sal_uInt16 BIFF12_EXTNAME_ICONIFIED = 0x0020;
62 } // namespace
64 ExternalNameModel::ExternalNameModel() :
65 mbNotify( false ),
66 mbPreferPic( false ),
67 mbStdDocName( false ),
68 mbOleObj( false ),
69 mbIconified( false )
73 ExternalName::ExternalName( const ExternalLink& rParentLink ) :
74 DefinedNameBase( rParentLink ),
75 mrParentLink( rParentLink ),
76 mbDdeLinkCreated( false )
80 void ExternalName::importDefinedName( const AttributeList& rAttribs )
82 maModel.maName = rAttribs.getXString( XML_name, OUString() );
83 OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importDefinedName - empty name" );
84 // zero-based index into sheet list of externalBook
85 maModel.mnSheet = rAttribs.getInteger( XML_sheetId, -1 );
88 void ExternalName::importDdeItem( const AttributeList& rAttribs )
90 maModel.maName = rAttribs.getXString( XML_name, OUString() );
91 OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importDdeItem - empty name" );
92 maExtNameModel.mbOleObj = false;
93 maExtNameModel.mbStdDocName = rAttribs.getBool( XML_ole, false );
94 maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
95 maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
98 void ExternalName::importValues( const AttributeList& rAttribs )
100 setResultSize( rAttribs.getInteger( XML_cols, 1 ), rAttribs.getInteger( XML_rows, 1 ) );
103 void ExternalName::importOleItem( const AttributeList& rAttribs )
105 maModel.maName = rAttribs.getXString( XML_name, OUString() );
106 OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importOleItem - empty name" );
107 maExtNameModel.mbOleObj = true;
108 maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
109 maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
110 maExtNameModel.mbIconified = rAttribs.getBool( XML_icon, false );
113 void ExternalName::importExternalName( SequenceInputStream& rStrm )
115 rStrm >> maModel.maName;
116 OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importExternalName - empty name" );
119 void ExternalName::importExternalNameFlags( SequenceInputStream& rStrm )
121 sal_uInt16 nFlags;
122 sal_Int32 nSheetId;
123 nFlags = rStrm.readuInt16();
124 nSheetId = rStrm.readInt32();
125 // index into sheet list of EXTSHEETNAMES (one-based in BIFF12)
126 maModel.mnSheet = nSheetId - 1;
127 // no flag for built-in names, as in OOXML...
128 maExtNameModel.mbNotify = getFlag( nFlags, BIFF12_EXTNAME_AUTOMATIC );
129 maExtNameModel.mbPreferPic = getFlag( nFlags, BIFF12_EXTNAME_PREFERPIC );
130 maExtNameModel.mbStdDocName = getFlag( nFlags, BIFF12_EXTNAME_STDDOCNAME );
131 maExtNameModel.mbOleObj = getFlag( nFlags, BIFF12_EXTNAME_OLEOBJECT );
132 maExtNameModel.mbIconified = getFlag( nFlags, BIFF12_EXTNAME_ICONIFIED );
133 OSL_ENSURE( (mrParentLink.getLinkType() == ExternalLinkType::OLE) == maExtNameModel.mbOleObj,
134 "ExternalName::importExternalNameFlags - wrong OLE flag in external name" );
137 void ExternalName::importDdeItemValues( SequenceInputStream& rStrm )
139 sal_Int32 nRows, nCols;
140 nRows = rStrm.readInt32();
141 nCols = rStrm.readInt32();
142 setResultSize( nCols, nRows );
145 void ExternalName::importDdeItemBool( SequenceInputStream& rStrm )
147 appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
150 void ExternalName::importDdeItemDouble( SequenceInputStream& rStrm )
152 appendResultValue( rStrm.readDouble() );
155 void ExternalName::importDdeItemError( SequenceInputStream& rStrm )
157 appendResultValue( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) );
160 void ExternalName::importDdeItemString( SequenceInputStream& rStrm )
162 appendResultValue( BiffHelper::readString( rStrm ) );
165 bool ExternalName::getDdeItemInfo( DDEItemInfo& orItemInfo ) const
167 if( (mrParentLink.getLinkType() == ExternalLinkType::DDE) && !maModel.maName.isEmpty() )
169 orItemInfo.Item = maModel.maName;
170 orItemInfo.Results = ContainerHelper::matrixToSequenceSequence( maResults );
171 return true;
173 return false;
176 bool ExternalName::getDdeLinkData( OUString& orDdeServer, OUString& orDdeTopic, OUString& orDdeItem )
178 if( (mrParentLink.getLinkType() == ExternalLinkType::DDE) && !maModel.maName.isEmpty() )
180 // try to create a DDE link and to set the imported link results
181 if( !mbDdeLinkCreated ) try
183 PropertySet aDocProps( getDocument() );
184 Reference< XDDELinks > xDdeLinks( aDocProps.getAnyProperty( PROP_DDELinks ), UNO_QUERY_THROW );
185 mxDdeLink = xDdeLinks->addDDELink( mrParentLink.getClassName(), mrParentLink.getTargetUrl(), maModel.maName, css::sheet::DDELinkMode_DEFAULT );
186 mbDdeLinkCreated = true; // ignore if setting results fails
187 if( !maResults.empty() )
189 Reference< XDDELinkResults > xResults( mxDdeLink, UNO_QUERY_THROW );
190 xResults->setResults( ContainerHelper::matrixToSequenceSequence( maResults ) );
193 catch( Exception& )
195 OSL_FAIL( "ExternalName::getDdeLinkData - cannot create DDE link" );
197 // get link data from created DDE link
198 if( mxDdeLink.is() )
200 orDdeServer = mxDdeLink->getApplication();
201 orDdeTopic = mxDdeLink->getTopic();
202 orDdeItem = mxDdeLink->getItem();
203 return true;
206 return false;
209 // private --------------------------------------------------------------------
211 void ExternalName::setResultSize( sal_Int32 nColumns, sal_Int32 nRows )
213 OSL_ENSURE( (mrParentLink.getLinkType() == ExternalLinkType::DDE) || (mrParentLink.getLinkType() == ExternalLinkType::OLE),
214 "ExternalName::setResultSize - wrong link type" );
215 OSL_ENSURE( (nRows > 0) && (nColumns > 0), "ExternalName::setResultSize - invalid matrix size" );
216 const ScAddress& rMaxPos = getAddressConverter().getMaxApiAddress();
217 if( (0 < nRows) && (nRows <= rMaxPos.Row() + 1) && (0 < nColumns) && (nColumns <= rMaxPos.Col() + 1) )
218 maResults.resize( static_cast< size_t >( nColumns ), static_cast< size_t >( nRows ), Any( BiffHelper::calcDoubleFromError( BIFF_ERR_NA ) ) );
219 else
220 maResults.clear();
221 maCurrIt = maResults.begin();
224 void LinkSheetRange::setDeleted()
226 meType = LINKSHEETRANGE_INTERNAL;
227 mnDocLink = mnFirst = mnLast = -1;
230 void LinkSheetRange::setSameSheet()
232 meType = LINKSHEETRANGE_SAMESHEET;
233 mnDocLink = -1;
234 mnFirst = mnLast = 0;
237 void LinkSheetRange::setRange( sal_Int32 nFirst, sal_Int32 nLast )
239 meType = LINKSHEETRANGE_INTERNAL;
240 mnDocLink = -1;
241 mnFirst = ::std::min( nFirst, nLast );
242 mnLast = ::std::max( nFirst, nLast );
245 void LinkSheetRange::setExternalRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast )
247 if( nDocLink < 0 )
249 setDeleted();
251 else
253 meType = LINKSHEETRANGE_EXTERNAL;
254 mnDocLink = nDocLink;
255 mnFirst = ::std::min( nFirst, nLast );
256 mnLast = ::std::max( nFirst, nLast );
260 ExternalLink::ExternalLink( const WorkbookHelper& rHelper ) :
261 WorkbookHelper( rHelper ),
262 meLinkType( ExternalLinkType::Unknown ),
263 meFuncLibType( FUNCLIB_UNKNOWN )
267 void ExternalLink::importExternalReference( const AttributeList& rAttribs )
269 maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
272 void ExternalLink::importExternalBook( const Relations& rRelations, const AttributeList& rAttribs )
274 parseExternalReference( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
277 void ExternalLink::importSheetName( const AttributeList& rAttribs )
279 insertExternalSheet( rAttribs.getXString( XML_val, OUString() ) );
282 void ExternalLink::importDefinedName( const AttributeList& rAttribs )
284 createExternalName()->importDefinedName( rAttribs );
287 void ExternalLink::importDdeLink( const AttributeList& rAttribs )
289 OUString aDdeService = rAttribs.getXString( XML_ddeService, OUString() );
290 OUString aDdeTopic = rAttribs.getXString( XML_ddeTopic, OUString() );
291 setDdeOleTargetUrl( aDdeService, aDdeTopic, ExternalLinkType::DDE );
294 ExternalNameRef ExternalLink::importDdeItem( const AttributeList& rAttribs )
296 ExternalNameRef xExtName = createExternalName();
297 xExtName->importDdeItem( rAttribs );
298 return xExtName;
301 void ExternalLink::importOleLink( const Relations& rRelations, const AttributeList& rAttribs )
303 OUString aProgId = rAttribs.getXString( XML_progId, OUString() );
304 OUString aTargetUrl = rRelations.getExternalTargetFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
305 setDdeOleTargetUrl( aProgId, aTargetUrl, ExternalLinkType::OLE );
308 ExternalNameRef ExternalLink::importOleItem( const AttributeList& rAttribs )
310 ExternalNameRef xExtName = createExternalName();
311 xExtName->importOleItem( rAttribs );
312 return xExtName;
315 void ExternalLink::importExternalRef( SequenceInputStream& rStrm )
317 rStrm >> maRelId;
320 void ExternalLink::importExternalSelf( SequenceInputStream& )
322 meLinkType = ExternalLinkType::Self;
325 void ExternalLink::importExternalSame( SequenceInputStream& )
327 meLinkType = ExternalLinkType::Same;
330 void ExternalLink::importExternalAddin( SequenceInputStream& )
332 meLinkType = ExternalLinkType::Unknown;
335 void ExternalLink::importExternalBook( const Relations& rRelations, SequenceInputStream& rStrm )
337 switch( rStrm.readuInt16() )
339 case BIFF12_EXTERNALBOOK_BOOK:
340 parseExternalReference( rRelations, BiffHelper::readString( rStrm ) );
341 break;
342 case BIFF12_EXTERNALBOOK_DDE:
344 OUString aDdeService, aDdeTopic;
345 rStrm >> aDdeService >> aDdeTopic;
346 setDdeOleTargetUrl( aDdeService, aDdeTopic, ExternalLinkType::DDE );
348 break;
349 case BIFF12_EXTERNALBOOK_OLE:
351 OUString aTargetUrl = rRelations.getExternalTargetFromRelId( BiffHelper::readString( rStrm ) );
352 OUString aProgId = BiffHelper::readString( rStrm );
353 setDdeOleTargetUrl( aProgId, aTargetUrl, ExternalLinkType::OLE );
355 break;
356 default:
357 OSL_FAIL( "ExternalLink::importExternalBook - unknown link type" );
361 void ExternalLink::importExtSheetNames( SequenceInputStream& rStrm )
363 // load external sheet names and create the sheet caches in the Calc document
364 SAL_WARN_IF( (meLinkType != ExternalLinkType::External) && (meLinkType != ExternalLinkType::Library),
365 "sc.filter",
366 "Invalid link type: " << meLinkType );
367 if( meLinkType == ExternalLinkType::External ) // ignore sheets of external libraries
368 for( sal_Int32 nSheet = 0, nCount = rStrm.readInt32(); !rStrm.isEof() && (nSheet < nCount); ++nSheet )
369 insertExternalSheet( BiffHelper::readString( rStrm ) );
372 ExternalNameRef ExternalLink::importExternalName( SequenceInputStream& rStrm )
374 ExternalNameRef xExtName = createExternalName();
375 xExtName->importExternalName( rStrm );
376 return xExtName;
379 ExternalLinkInfo ExternalLink::getLinkInfo() const
381 ExternalLinkInfo aLinkInfo;
382 switch( meLinkType )
384 case ExternalLinkType::Self:
385 case ExternalLinkType::Same:
386 aLinkInfo.Type = css::sheet::ExternalLinkType::SELF;
387 break;
388 case ExternalLinkType::External:
389 aLinkInfo.Type = css::sheet::ExternalLinkType::DOCUMENT;
390 aLinkInfo.Data <<= maTargetUrl;
391 break;
392 case ExternalLinkType::Library:
393 // parser will return library function names in OPCODE_BAD string tokens
394 aLinkInfo.Type = css::sheet::ExternalLinkType::SPECIAL;
395 break;
396 case ExternalLinkType::DDE:
398 aLinkInfo.Type = css::sheet::ExternalLinkType::DDE;
399 DDELinkInfo aDdeLinkInfo;
400 aDdeLinkInfo.Service = maClassName;
401 aDdeLinkInfo.Topic = maTargetUrl;
402 ::std::vector< DDEItemInfo > aItemInfos;
403 DDEItemInfo aItemInfo;
404 for( const auto& rxExtName : maExtNames )
405 if( rxExtName->getDdeItemInfo( aItemInfo ) )
406 aItemInfos.push_back( aItemInfo );
407 aDdeLinkInfo.Items = ContainerHelper::vectorToSequence( aItemInfos );
408 aLinkInfo.Data <<= aDdeLinkInfo;
410 break;
411 default:
412 aLinkInfo.Type = css::sheet::ExternalLinkType::UNKNOWN;
414 return aLinkInfo;
417 FunctionLibraryType ExternalLink::getFuncLibraryType() const
419 return (meLinkType == ExternalLinkType::Library) ? meFuncLibType : FUNCLIB_UNKNOWN;
422 sal_Int32 ExternalLink::getDocumentLinkIndex() const
424 OSL_ENSURE( meLinkType == ExternalLinkType::External, "ExternalLink::getDocumentLinkIndex - invalid link type" );
425 return mxDocLink.is() ? mxDocLink->getTokenIndex() : -1;
428 sal_Int32 ExternalLink::getSheetCacheIndex( sal_Int32 nTabId ) const
430 OSL_ENSURE( meLinkType == ExternalLinkType::External, "ExternalLink::getSheetCacheIndex - invalid link type" );
431 return ContainerHelper::getVectorElement( maSheetCaches, nTabId, -1 );
434 Reference< XExternalSheetCache > ExternalLink::getSheetCache( sal_Int32 nTabId ) const
436 sal_Int32 nCacheIdx = getSheetCacheIndex( nTabId );
437 if( mxDocLink.is() && (nCacheIdx >= 0) ) try
439 // existing mxDocLink implies that this is an external link
440 Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( nCacheIdx ), UNO_QUERY_THROW );
441 return xSheetCache;
443 catch( Exception& )
446 return nullptr;
449 void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const
451 switch( meLinkType )
453 case ExternalLinkType::Same:
454 orSheetRange.setSameSheet();
455 break;
457 case ExternalLinkType::Self:
458 orSheetRange.setRange( nTabId1, nTabId2 );
459 break;
461 case ExternalLinkType::External:
463 sal_Int32 nDocLinkIdx = getDocumentLinkIndex();
464 // BIFF12: passed indexes point into sheet list of EXTSHEETLIST
465 orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
467 break;
469 default:
470 // unsupported/unexpected link type: #REF! error
471 orSheetRange.setDeleted();
475 ExternalNameRef ExternalLink::getNameByIndex( sal_Int32 nIndex ) const
477 return maExtNames.get( nIndex );
480 // private --------------------------------------------------------------------
482 void ExternalLink::setExternalTargetUrl( const OUString& rTargetUrl, const OUString& rTargetType )
484 meLinkType = ExternalLinkType::Unknown;
485 if( rTargetType == CREATE_OFFICEDOC_RELATION_TYPE( "externalLinkPath" ) ||
486 rTargetType == CREATE_OFFICEDOC_RELATION_TYPE_STRICT( "externalLinkPath" ) )
488 maTargetUrl = getBaseFilter().getAbsoluteUrl( rTargetUrl );
489 if( !maTargetUrl.isEmpty() )
490 meLinkType = ExternalLinkType::External;
492 else if( rTargetType == CREATE_MSOFFICE_RELATION_TYPE( "xlExternalLinkPath/xlPathMissing" ) )
494 meLinkType = ExternalLinkType::PathMissing;
496 else if( rTargetType == CREATE_MSOFFICE_RELATION_TYPE( "xlExternalLinkPath/xlLibrary" ) )
498 meLinkType = ExternalLinkType::Library;
499 meFuncLibType = FunctionProvider::getFuncLibTypeFromLibraryName( rTargetUrl );
501 SAL_WARN_IF( meLinkType == ExternalLinkType::Unknown, "sc.filter", "Empty target URL or unknown target type, URL='" << rTargetUrl << "', type='" << rTargetType << "'" );
503 // create the external document link API object that will contain the sheet caches
504 if( meLinkType == ExternalLinkType::External ) try
506 PropertySet aDocProps( getDocument() );
507 Reference< XExternalDocLinks > xDocLinks( aDocProps.getAnyProperty( PROP_ExternalDocLinks ), UNO_QUERY_THROW );
508 mxDocLink = xDocLinks->addDocLink( maTargetUrl );
510 catch( Exception& )
515 void ExternalLink::setDdeOleTargetUrl( const OUString& rClassName, const OUString& rTargetUrl, ExternalLinkType eLinkType )
517 maClassName = rClassName;
518 maTargetUrl = rTargetUrl;
519 meLinkType = (maClassName.isEmpty() || maTargetUrl.isEmpty()) ? ExternalLinkType::Unknown : eLinkType;
520 OSL_ENSURE( meLinkType == eLinkType, "ExternalLink::setDdeOleTargetUrl - missing classname or target" );
523 void ExternalLink::parseExternalReference( const Relations& rRelations, const OUString& rRelId )
525 if( const Relation* pRelation = rRelations.getRelationFromRelId( rRelId ) )
526 setExternalTargetUrl( pRelation->maTarget, pRelation->maType );
529 void ExternalLink::insertExternalSheet( const OUString& rSheetName )
531 OSL_ENSURE( !rSheetName.isEmpty(), "ExternalLink::insertExternalSheet - empty sheet name" );
532 if( mxDocLink.is() )
534 Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName, false );
535 sal_Int32 nCacheIdx = xSheetCache.is() ? xSheetCache->getTokenIndex() : -1;
536 maSheetCaches.push_back( nCacheIdx );
540 ExternalNameRef ExternalLink::createExternalName()
542 ExternalNameRef xExtName = std::make_shared<ExternalName>( *this );
543 maExtNames.push_back( xExtName );
544 return xExtName;
547 RefSheetsModel::RefSheetsModel() :
548 mnExtRefId( -1 ),
549 mnTabId1( -1 ),
550 mnTabId2( -1 )
554 void RefSheetsModel::readBiff12Data( SequenceInputStream& rStrm )
556 mnExtRefId = rStrm.readInt32();
557 mnTabId1 = rStrm.readInt32();
558 mnTabId2 = rStrm.readInt32();
561 ExternalLinkBuffer::ExternalLinkBuffer( const WorkbookHelper& rHelper ) :
562 WorkbookHelper( rHelper ),
563 mxSelfRef( std::make_shared<ExternalLink>( rHelper ) ),
564 mbUseRefSheets( false )
566 mxSelfRef->setSelfLinkType();
569 ExternalLinkRef ExternalLinkBuffer::importExternalReference( const AttributeList& rAttribs )
571 ExternalLinkRef xExtLink = createExternalLink();
572 xExtLink->importExternalReference( rAttribs );
573 maExtLinks.push_back( xExtLink );
574 return xExtLink;
577 ExternalLinkRef ExternalLinkBuffer::importExternalRef( SequenceInputStream& rStrm )
579 mbUseRefSheets = true;
580 ExternalLinkRef xExtLink = createExternalLink();
581 xExtLink->importExternalRef( rStrm );
582 maExtLinks.push_back( xExtLink );
583 return xExtLink;
586 void ExternalLinkBuffer::importExternalSelf( SequenceInputStream& rStrm )
588 mbUseRefSheets = true;
589 createExternalLink()->importExternalSelf( rStrm );
592 void ExternalLinkBuffer::importExternalSame( SequenceInputStream& rStrm )
594 mbUseRefSheets = true;
595 createExternalLink()->importExternalSame( rStrm );
598 void ExternalLinkBuffer::importExternalAddin( SequenceInputStream& rStrm )
600 mbUseRefSheets = true;
601 createExternalLink()->importExternalAddin( rStrm );
604 void ExternalLinkBuffer::importExternalSheets( SequenceInputStream& rStrm )
606 OSL_ENSURE( mbUseRefSheets, "ExternalLinkBuffer::importExternalSheets - missing EXTERNALREFS records" );
607 mbUseRefSheets = true;
608 OSL_ENSURE( maRefSheets.empty(), "ExternalLinkBuffer::importExternalSheets - multiple EXTERNALSHEETS records" );
609 maRefSheets.clear();
610 sal_Int32 nRefCount;
611 nRefCount = rStrm.readInt32();
612 size_t nMaxCount = getLimitedValue< size_t, sal_Int64 >( nRefCount, 0, rStrm.getRemaining() / 12 );
613 maRefSheets.reserve( nMaxCount );
614 for( size_t nRefId = 0; !rStrm.isEof() && (nRefId < nMaxCount); ++nRefId )
616 RefSheetsModel aRefSheets;
617 aRefSheets.readBiff12Data( rStrm );
618 maRefSheets.push_back( aRefSheets );
622 Sequence< ExternalLinkInfo > ExternalLinkBuffer::getLinkInfos() const
624 ::std::vector< ExternalLinkInfo > aLinkInfos;
625 // add entry for implicit index 0 (self reference to this document)
626 aLinkInfos.push_back( mxSelfRef->getLinkInfo() );
627 for( const auto& rxExtLink : maExtLinks )
628 aLinkInfos.push_back( rxExtLink->getLinkInfo() );
629 return ContainerHelper::vectorToSequence( aLinkInfos );
632 ExternalLinkRef ExternalLinkBuffer::getExternalLink( sal_Int32 nRefId, bool bUseRefSheets ) const
634 ExternalLinkRef xExtLink;
635 // OOXML: 0 = this document, otherwise one-based index into link list
636 if( !bUseRefSheets || !mbUseRefSheets )
637 xExtLink = (nRefId == 0) ? mxSelfRef : maLinks.get( nRefId - 1 );
638 // BIFF12: zero-based index into ref-sheets list
639 else if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
640 xExtLink = maLinks.get( pRefSheets->mnExtRefId );
641 return xExtLink;
644 LinkSheetRange ExternalLinkBuffer::getSheetRange( sal_Int32 nRefId ) const
646 OSL_ENSURE( mbUseRefSheets, "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
647 LinkSheetRange aSheetRange;
648 if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
649 if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
650 pExtLink->getSheetRange( aSheetRange, pRefSheets->mnTabId1, pRefSheets->mnTabId2 );
651 return aSheetRange;
654 // private --------------------------------------------------------------------
656 ExternalLinkRef ExternalLinkBuffer::createExternalLink()
658 ExternalLinkRef xExtLink = std::make_shared<ExternalLink>( *this );
659 maLinks.push_back( xExtLink );
660 return xExtLink;
663 const RefSheetsModel* ExternalLinkBuffer::getRefSheets( sal_Int32 nRefId ) const
665 return ((0 <= nRefId) && (o3tl::make_unsigned( nRefId ) < maRefSheets.size())) ?
666 &maRefSheets[ static_cast< size_t >( nRefId ) ] : nullptr;
669 } // namespace oox
671 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */