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 <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>
43 using namespace ::com::sun::star::sheet
;
44 using namespace ::com::sun::star::uno
;
46 using ::oox::core::Relation
;
47 using ::oox::core::Relations
;
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;
63 ExternalNameModel::ExternalNameModel() :
66 mbStdDocName( 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
)
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
);
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
) );
194 OSL_FAIL( "ExternalName::getDdeLinkData - cannot create DDE link" );
196 // get link data from created DDE link
199 orDdeServer
= mxDdeLink
->getApplication();
200 orDdeTopic
= mxDdeLink
->getTopic();
201 orDdeItem
= mxDdeLink
->getItem();
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
) ) );
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
;
233 mnFirst
= mnLast
= 0;
236 void LinkSheetRange::setRange( sal_Int32 nFirst
, sal_Int32 nLast
)
238 meType
= LINKSHEETRANGE_INTERNAL
;
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
)
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
);
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
);
314 void ExternalLink::importExternalRef( SequenceInputStream
& rStrm
)
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
) );
341 case BIFF12_EXTERNALBOOK_DDE
:
343 OUString aDdeService
, aDdeTopic
;
344 rStrm
>> aDdeService
>> aDdeTopic
;
345 setDdeOleTargetUrl( aDdeService
, aDdeTopic
, ExternalLinkType::DDE
);
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
);
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
),
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
);
378 ExternalLinkInfo
ExternalLink::getLinkInfo() const
380 ExternalLinkInfo aLinkInfo
;
383 case ExternalLinkType::Self
:
384 case ExternalLinkType::Same
:
385 aLinkInfo
.Type
= css::sheet::ExternalLinkType::SELF
;
387 case ExternalLinkType::External
:
388 aLinkInfo
.Type
= css::sheet::ExternalLinkType::DOCUMENT
;
389 aLinkInfo
.Data
<<= maTargetUrl
;
391 case ExternalLinkType::Library
:
392 // parser will return library function names in OPCODE_BAD string tokens
393 aLinkInfo
.Type
= css::sheet::ExternalLinkType::SPECIAL
;
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
;
411 aLinkInfo
.Type
= css::sheet::ExternalLinkType::UNKNOWN
;
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
);
448 void ExternalLink::getSheetRange( LinkSheetRange
& orSheetRange
, sal_Int32 nTabId1
, sal_Int32 nTabId2
) const
452 case ExternalLinkType::Same
:
453 orSheetRange
.setSameSheet();
456 case ExternalLinkType::Self
:
457 orSheetRange
.setRange( nTabId1
, nTabId2
);
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
) );
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
);
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" );
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
);
546 RefSheetsModel::RefSheetsModel() :
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
);
576 ExternalLinkRef
ExternalLinkBuffer::importExternalRef( SequenceInputStream
& rStrm
)
578 mbUseRefSheets
= true;
579 ExternalLinkRef xExtLink
= createExternalLink();
580 xExtLink
->importExternalRef( rStrm
);
581 maExtLinks
.push_back( 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" );
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
);
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
);
653 // private --------------------------------------------------------------------
655 ExternalLinkRef
ExternalLinkBuffer::createExternalLink()
657 ExternalLinkRef
xExtLink( new ExternalLink( *this ) );
658 maLinks
.push_back( 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;
671 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */