1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
44 using namespace ::com::sun::star::sheet
;
45 using namespace ::com::sun::star::uno
;
47 using ::oox::core::Relation
;
48 using ::oox::core::Relations
;
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;
64 ExternalNameModel::ExternalNameModel() :
67 mbStdDocName( 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
)
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
);
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
) );
195 OSL_FAIL( "ExternalName::getDdeLinkData - cannot create DDE link" );
197 // get link data from created DDE link
200 orDdeServer
= mxDdeLink
->getApplication();
201 orDdeTopic
= mxDdeLink
->getTopic();
202 orDdeItem
= mxDdeLink
->getItem();
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
) ) );
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
;
234 mnFirst
= mnLast
= 0;
237 void LinkSheetRange::setRange( sal_Int32 nFirst
, sal_Int32 nLast
)
239 meType
= LINKSHEETRANGE_INTERNAL
;
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
)
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
);
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
);
315 void ExternalLink::importExternalRef( SequenceInputStream
& rStrm
)
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
) );
342 case BIFF12_EXTERNALBOOK_DDE
:
344 OUString aDdeService
, aDdeTopic
;
345 rStrm
>> aDdeService
>> aDdeTopic
;
346 setDdeOleTargetUrl( aDdeService
, aDdeTopic
, ExternalLinkType::DDE
);
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
);
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
),
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
);
379 ExternalLinkInfo
ExternalLink::getLinkInfo() const
381 ExternalLinkInfo aLinkInfo
;
384 case ExternalLinkType::Self
:
385 case ExternalLinkType::Same
:
386 aLinkInfo
.Type
= css::sheet::ExternalLinkType::SELF
;
388 case ExternalLinkType::External
:
389 aLinkInfo
.Type
= css::sheet::ExternalLinkType::DOCUMENT
;
390 aLinkInfo
.Data
<<= maTargetUrl
;
392 case ExternalLinkType::Library
:
393 // parser will return library function names in OPCODE_BAD string tokens
394 aLinkInfo
.Type
= css::sheet::ExternalLinkType::SPECIAL
;
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
;
412 aLinkInfo
.Type
= css::sheet::ExternalLinkType::UNKNOWN
;
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
);
449 void ExternalLink::getSheetRange( LinkSheetRange
& orSheetRange
, sal_Int32 nTabId1
, sal_Int32 nTabId2
) const
453 case ExternalLinkType::Same
:
454 orSheetRange
.setSameSheet();
457 case ExternalLinkType::Self
:
458 orSheetRange
.setRange( nTabId1
, nTabId2
);
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
) );
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
);
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" );
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
);
547 RefSheetsModel::RefSheetsModel() :
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
);
577 ExternalLinkRef
ExternalLinkBuffer::importExternalRef( SequenceInputStream
& rStrm
)
579 mbUseRefSheets
= true;
580 ExternalLinkRef xExtLink
= createExternalLink();
581 xExtLink
->importExternalRef( rStrm
);
582 maExtLinks
.push_back( 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" );
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
);
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
);
654 // private --------------------------------------------------------------------
656 ExternalLinkRef
ExternalLinkBuffer::createExternalLink()
658 ExternalLinkRef xExtLink
= std::make_shared
<ExternalLink
>( *this );
659 maLinks
.push_back( 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;
671 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */