LibreOffice Module sc (master)  1
externallinkbuffer.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <externallinkbuffer.hxx>
21 #include <externalrefmgr.hxx>
22 #include <tokenarray.hxx>
23 #include <tokenstringcontext.hxx>
24 
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/sheet/DDELinkInfo.hpp>
27 #include <com/sun/star/sheet/ExternalLinkType.hpp>
28 #include <com/sun/star/sheet/XDDELinks.hpp>
29 #include <com/sun/star/sheet/XDDELinkResults.hpp>
30 #include <com/sun/star/sheet/XExternalDocLinks.hpp>
31 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
32 
33 #include <comphelper/sequence.hxx>
34 #include <o3tl/safeint.hxx>
35 #include <osl/diagnose.h>
36 #include <sal/log.hxx>
37 #include <oox/core/filterbase.hxx>
40 #include <oox/token/namespaces.hxx>
41 #include <oox/token/properties.hxx>
42 #include <oox/core/relations.hxx>
43 #include <oox/token/tokens.hxx>
44 #include <addressconverter.hxx>
45 #include <biffhelper.hxx>
46 
47 namespace oox::xls {
48 
49 using namespace ::com::sun::star::sheet;
50 using namespace ::com::sun::star::uno;
51 
52 using ::oox::core::Relation;
53 using ::oox::core::Relations;
54 
55 namespace {
56 
57 const sal_uInt16 BIFF12_EXTERNALBOOK_BOOK = 0;
58 const sal_uInt16 BIFF12_EXTERNALBOOK_DDE = 1;
59 const sal_uInt16 BIFF12_EXTERNALBOOK_OLE = 2;
60 
61 const sal_uInt16 BIFF12_EXTNAME_AUTOMATIC = 0x0002;
62 const sal_uInt16 BIFF12_EXTNAME_PREFERPIC = 0x0004;
63 const sal_uInt16 BIFF12_EXTNAME_STDDOCNAME = 0x0008;
64 const sal_uInt16 BIFF12_EXTNAME_OLEOBJECT = 0x0010;
65 const sal_uInt16 BIFF12_EXTNAME_ICONIFIED = 0x0020;
66 
67 } // namespace
68 
70  mbNotify( false ),
71  mbPreferPic( false ),
72  mbStdDocName( false ),
73  mbOleObj( false ),
74  mbIconified( false )
75 {
76 }
77 
79  DefinedNameBase( rParentLink ),
80  mrParentLink( rParentLink ),
81  mbDdeLinkCreated( false )
82 {
83 }
84 
86 {
87  maModel.maName = rAttribs.getXString( XML_name, OUString() );
88  OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importDefinedName - empty name" );
89  maModel.maFormula = rAttribs.getXString(XML_refersTo, OUString());
90  OSL_ENSURE( !maModel.maFormula.isEmpty(), "ExternalName::importDefinedName - empty formula" );
91  // zero-based index into sheet list of externalBook
92  maModel.mnSheet = rAttribs.getInteger( XML_sheetId, -1 );
93  // cache external defined names and formulas
95  aComp.SetExternalLinks(getExternalLinks().getLinkInfos());
96  std::unique_ptr<ScTokenArray> pArray = aComp.CompileString(maModel.maFormula);
97  FormulaError nErr = pArray->GetCodeError();
98  aComp.CompileTokenArray();
100  pArray->DelRPN();
101  pArray->SetCodeError(nErr);
102 
103  if (pArray->HasReferences())
104  {
106  sal_uInt16 nFileId = pRefMgr->getExternalFileId(mrParentLink.getTargetUrl());
107  pRefMgr->storeRangeNameTokens(nFileId, maModel.maName, *pArray);
108  }
109 }
110 
112 {
113  maModel.maName = rAttribs.getXString( XML_name, OUString() );
114  OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importDdeItem - empty name" );
115  maExtNameModel.mbOleObj = false;
116  maExtNameModel.mbStdDocName = rAttribs.getBool( XML_ole, false );
117  maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
118  maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
119 }
120 
122 {
123  setResultSize( rAttribs.getInteger( XML_cols, 1 ), rAttribs.getInteger( XML_rows, 1 ) );
124 }
125 
127 {
128  maModel.maName = rAttribs.getXString( XML_name, OUString() );
129  OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importOleItem - empty name" );
130  maExtNameModel.mbOleObj = true;
131  maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
132  maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
133  maExtNameModel.mbIconified = rAttribs.getBool( XML_icon, false );
134 }
135 
137 {
138  rStrm >> maModel.maName;
139  OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importExternalName - empty name" );
140 }
141 
143 {
144  sal_uInt16 nFlags;
145  sal_Int32 nSheetId;
146  nFlags = rStrm.readuInt16();
147  nSheetId = rStrm.readInt32();
148  // index into sheet list of EXTSHEETNAMES (one-based in BIFF12)
149  maModel.mnSheet = nSheetId - 1;
150  // no flag for built-in names, as in OOXML...
151  maExtNameModel.mbNotify = getFlag( nFlags, BIFF12_EXTNAME_AUTOMATIC );
152  maExtNameModel.mbPreferPic = getFlag( nFlags, BIFF12_EXTNAME_PREFERPIC );
153  maExtNameModel.mbStdDocName = getFlag( nFlags, BIFF12_EXTNAME_STDDOCNAME );
154  maExtNameModel.mbOleObj = getFlag( nFlags, BIFF12_EXTNAME_OLEOBJECT );
155  maExtNameModel.mbIconified = getFlag( nFlags, BIFF12_EXTNAME_ICONIFIED );
157  "ExternalName::importExternalNameFlags - wrong OLE flag in external name" );
158 }
159 
161 {
162  sal_Int32 nRows, nCols;
163  nRows = rStrm.readInt32();
164  nCols = rStrm.readInt32();
165  setResultSize( nCols, nRows );
166 }
167 
169 {
170  appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
171 }
172 
174 {
175  appendResultValue( rStrm.readDouble() );
176 }
177 
179 {
181 }
182 
184 {
186 }
187 
188 bool ExternalName::getDdeItemInfo( DDEItemInfo& orItemInfo ) const
189 {
190  if( (mrParentLink.getLinkType() == ExternalLinkType::DDE) && !maModel.maName.isEmpty() )
191  {
192  orItemInfo.Item = maModel.maName;
194  return true;
195  }
196  return false;
197 }
198 
199 bool ExternalName::getDdeLinkData( OUString& orDdeServer, OUString& orDdeTopic, OUString& orDdeItem )
200 {
201  if( (mrParentLink.getLinkType() == ExternalLinkType::DDE) && !maModel.maName.isEmpty() )
202  {
203  // try to create a DDE link and to set the imported link results
204  if( !mbDdeLinkCreated ) try
205  {
206  PropertySet aDocProps( getDocument() );
207  Reference< XDDELinks > xDdeLinks( aDocProps.getAnyProperty( PROP_DDELinks ), UNO_QUERY_THROW );
208  mxDdeLink = xDdeLinks->addDDELink( mrParentLink.getClassName(), mrParentLink.getTargetUrl(), maModel.maName, css::sheet::DDELinkMode_DEFAULT );
209  mbDdeLinkCreated = true; // ignore if setting results fails
210  if( !maResults.empty() )
211  {
212  Reference< XDDELinkResults > xResults( mxDdeLink, UNO_QUERY_THROW );
213  xResults->setResults( ContainerHelper::matrixToSequenceSequence( maResults ) );
214  }
215  }
216  catch( Exception& )
217  {
218  OSL_FAIL( "ExternalName::getDdeLinkData - cannot create DDE link" );
219  }
220  // get link data from created DDE link
221  if( mxDdeLink.is() )
222  {
223  orDdeServer = mxDdeLink->getApplication();
224  orDdeTopic = mxDdeLink->getTopic();
225  orDdeItem = mxDdeLink->getItem();
226  return true;
227  }
228  }
229  return false;
230 }
231 
232 // private --------------------------------------------------------------------
233 
234 void ExternalName::setResultSize( sal_Int32 nColumns, sal_Int32 nRows )
235 {
237  "ExternalName::setResultSize - wrong link type" );
238  OSL_ENSURE( (nRows > 0) && (nColumns > 0), "ExternalName::setResultSize - invalid matrix size" );
239  const ScAddress& rMaxPos = getAddressConverter().getMaxApiAddress();
240  if( (0 < nRows) && (nRows <= rMaxPos.Row() + 1) && (0 < nColumns) && (nColumns <= rMaxPos.Col() + 1) )
241  maResults.resize( static_cast< size_t >( nColumns ), static_cast< size_t >( nRows ), Any( BiffHelper::calcDoubleFromError( BIFF_ERR_NA ) ) );
242  else
243  maResults.clear();
245 }
246 
248 {
250  mnDocLink = mnFirst = mnLast = -1;
251 }
252 
254 {
256  mnDocLink = -1;
257  mnFirst = mnLast = 0;
258 }
259 
260 void LinkSheetRange::setRange( sal_Int32 nFirst, sal_Int32 nLast )
261 {
263  mnDocLink = -1;
264  mnFirst = ::std::min( nFirst, nLast );
265  mnLast = ::std::max( nFirst, nLast );
266 }
267 
268 void LinkSheetRange::setExternalRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast )
269 {
270  if( nDocLink < 0 )
271  {
272  setDeleted();
273  }
274  else
275  {
277  mnDocLink = nDocLink;
278  mnFirst = ::std::min( nFirst, nLast );
279  mnLast = ::std::max( nFirst, nLast );
280  }
281 }
282 
284  WorkbookHelper( rHelper ),
285  meLinkType( ExternalLinkType::Unknown ),
286  meFuncLibType( FUNCLIB_UNKNOWN )
287 {
288 }
289 
291 {
292  maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
293 }
294 
295 void ExternalLink::importExternalBook( const Relations& rRelations, const AttributeList& rAttribs )
296 {
297  parseExternalReference( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
298 }
299 
301 {
302  insertExternalSheet( rAttribs.getXString( XML_val, OUString() ) );
303 }
304 
306 {
307  createExternalName()->importDefinedName( rAttribs );
308 }
309 
311 {
312  OUString aDdeService = rAttribs.getXString( XML_ddeService, OUString() );
313  OUString aDdeTopic = rAttribs.getXString( XML_ddeTopic, OUString() );
314  setDdeOleTargetUrl( aDdeService, aDdeTopic, ExternalLinkType::DDE );
315 }
316 
318 {
319  ExternalNameRef xExtName = createExternalName();
320  xExtName->importDdeItem( rAttribs );
321  return xExtName;
322 }
323 
324 void ExternalLink::importOleLink( const Relations& rRelations, const AttributeList& rAttribs )
325 {
326  OUString aProgId = rAttribs.getXString( XML_progId, OUString() );
327  OUString aTargetUrl = rRelations.getExternalTargetFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
328  setDdeOleTargetUrl( aProgId, aTargetUrl, ExternalLinkType::OLE );
329 }
330 
332 {
333  ExternalNameRef xExtName = createExternalName();
334  xExtName->importOleItem( rAttribs );
335  return xExtName;
336 }
337 
339 {
340  rStrm >> maRelId;
341 }
342 
344 {
346 }
347 
349 {
351 }
352 
354 {
356 }
357 
358 void ExternalLink::importExternalBook( const Relations& rRelations, SequenceInputStream& rStrm )
359 {
360  switch( rStrm.readuInt16() )
361  {
362  case BIFF12_EXTERNALBOOK_BOOK:
363  parseExternalReference( rRelations, BiffHelper::readString( rStrm ) );
364  break;
365  case BIFF12_EXTERNALBOOK_DDE:
366  {
367  OUString aDdeService, aDdeTopic;
368  rStrm >> aDdeService >> aDdeTopic;
369  setDdeOleTargetUrl( aDdeService, aDdeTopic, ExternalLinkType::DDE );
370  }
371  break;
372  case BIFF12_EXTERNALBOOK_OLE:
373  {
374  OUString aTargetUrl = rRelations.getExternalTargetFromRelId( BiffHelper::readString( rStrm ) );
375  OUString aProgId = BiffHelper::readString( rStrm );
376  setDdeOleTargetUrl( aProgId, aTargetUrl, ExternalLinkType::OLE );
377  }
378  break;
379  default:
380  OSL_FAIL( "ExternalLink::importExternalBook - unknown link type" );
381  }
382 }
383 
385 {
386  // load external sheet names and create the sheet caches in the Calc document
388  "sc.filter",
389  "Invalid link type: " << meLinkType );
390  if( meLinkType == ExternalLinkType::External ) // ignore sheets of external libraries
391  for( sal_Int32 nSheet = 0, nCount = rStrm.readInt32(); !rStrm.isEof() && (nSheet < nCount); ++nSheet )
393 }
394 
396 {
397  ExternalNameRef xExtName = createExternalName();
398  xExtName->importExternalName( rStrm );
399  return xExtName;
400 }
401 
402 ExternalLinkInfo ExternalLink::getLinkInfo() const
403 {
404  ExternalLinkInfo aLinkInfo;
405  switch( meLinkType )
406  {
409  aLinkInfo.Type = css::sheet::ExternalLinkType::SELF;
410  break;
412  aLinkInfo.Type = css::sheet::ExternalLinkType::DOCUMENT;
413  aLinkInfo.Data <<= maTargetUrl;
414  break;
416  // parser will return library function names in OPCODE_BAD string tokens
417  aLinkInfo.Type = css::sheet::ExternalLinkType::SPECIAL;
418  break;
420  {
421  aLinkInfo.Type = css::sheet::ExternalLinkType::DDE;
422  DDELinkInfo aDdeLinkInfo;
423  aDdeLinkInfo.Service = maClassName;
424  aDdeLinkInfo.Topic = maTargetUrl;
425  ::std::vector< DDEItemInfo > aItemInfos;
426  DDEItemInfo aItemInfo;
427  for( const auto& rxExtName : maExtNames )
428  if( rxExtName->getDdeItemInfo( aItemInfo ) )
429  aItemInfos.push_back( aItemInfo );
430  aDdeLinkInfo.Items = comphelper::containerToSequence( aItemInfos );
431  aLinkInfo.Data <<= aDdeLinkInfo;
432  }
433  break;
434  default:
435  aLinkInfo.Type = css::sheet::ExternalLinkType::UNKNOWN;
436  }
437  return aLinkInfo;
438 }
439 
441 {
443 }
444 
446 {
447  OSL_ENSURE( meLinkType == ExternalLinkType::External, "ExternalLink::getDocumentLinkIndex - invalid link type" );
448  return mxDocLink.is() ? mxDocLink->getTokenIndex() : -1;
449 }
450 
451 sal_Int32 ExternalLink::getSheetCacheIndex( sal_Int32 nTabId ) const
452 {
453  OSL_ENSURE( meLinkType == ExternalLinkType::External, "ExternalLink::getSheetCacheIndex - invalid link type" );
454  return ContainerHelper::getVectorElement( maSheetCaches, nTabId, -1 );
455 }
456 
457 Reference< XExternalSheetCache > ExternalLink::getSheetCache( sal_Int32 nTabId ) const
458 {
459  sal_Int32 nCacheIdx = getSheetCacheIndex( nTabId );
460  if( mxDocLink.is() && (nCacheIdx >= 0) ) try
461  {
462  // existing mxDocLink implies that this is an external link
463  Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( nCacheIdx ), UNO_QUERY_THROW );
464  return xSheetCache;
465  }
466  catch( Exception& )
467  {
468  }
469  return nullptr;
470 }
471 
472 void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const
473 {
474  switch( meLinkType )
475  {
477  orSheetRange.setSameSheet();
478  break;
479 
481  orSheetRange.setRange( nTabId1, nTabId2 );
482  break;
483 
485  {
486  sal_Int32 nDocLinkIdx = getDocumentLinkIndex();
487  // BIFF12: passed indexes point into sheet list of EXTSHEETLIST
488  orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
489  }
490  break;
491 
492  default:
493  // unsupported/unexpected link type: #REF! error
494  orSheetRange.setDeleted();
495  }
496 }
497 
499 {
500  return maExtNames.get( nIndex );
501 }
502 
503 // private --------------------------------------------------------------------
504 
505 void ExternalLink::setExternalTargetUrl( const OUString& rTargetUrl, const OUString& rTargetType )
506 {
508  if( rTargetType == CREATE_OFFICEDOC_RELATION_TYPE( "externalLinkPath" ) ||
509  rTargetType == CREATE_OFFICEDOC_RELATION_TYPE_STRICT( "externalLinkPath" ) )
510  {
511  maTargetUrl = getBaseFilter().getAbsoluteUrl( rTargetUrl );
512  if( !maTargetUrl.isEmpty() )
514  }
515  else if( rTargetType == CREATE_MSOFFICE_RELATION_TYPE( "xlExternalLinkPath/xlPathMissing" ) )
516  {
518  }
519  else if( rTargetType == CREATE_MSOFFICE_RELATION_TYPE( "xlExternalLinkPath/xlLibrary" ) )
520  {
523  }
524  SAL_WARN_IF( meLinkType == ExternalLinkType::Unknown, "sc.filter", "Empty target URL or unknown target type, URL='" << rTargetUrl << "', type='" << rTargetType << "'" );
525 
526  // create the external document link API object that will contain the sheet caches
528  {
529  PropertySet aDocProps( getDocument() );
530  Reference< XExternalDocLinks > xDocLinks( aDocProps.getAnyProperty( PROP_ExternalDocLinks ), UNO_QUERY_THROW );
531  mxDocLink = xDocLinks->addDocLink( maTargetUrl );
532  }
533  catch( Exception& )
534  {
535  }
536 }
537 
538 void ExternalLink::setDdeOleTargetUrl( const OUString& rClassName, const OUString& rTargetUrl, ExternalLinkType eLinkType )
539 {
540  maClassName = rClassName;
541  maTargetUrl = rTargetUrl;
542  meLinkType = (maClassName.isEmpty() || maTargetUrl.isEmpty()) ? ExternalLinkType::Unknown : eLinkType;
543  OSL_ENSURE( meLinkType == eLinkType, "ExternalLink::setDdeOleTargetUrl - missing classname or target" );
544 }
545 
546 void ExternalLink::parseExternalReference( const Relations& rRelations, const OUString& rRelId )
547 {
548  if( const Relation* pRelation = rRelations.getRelationFromRelId( rRelId ) )
549  setExternalTargetUrl( pRelation->maTarget, pRelation->maType );
550 }
551 
552 void ExternalLink::insertExternalSheet( const OUString& rSheetName )
553 {
554  OSL_ENSURE( !rSheetName.isEmpty(), "ExternalLink::insertExternalSheet - empty sheet name" );
555  if( mxDocLink.is() )
556  {
557  Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName, false );
558  sal_Int32 nCacheIdx = xSheetCache.is() ? xSheetCache->getTokenIndex() : -1;
559  maSheetCaches.push_back( nCacheIdx );
560  }
561 }
562 
564 {
565  ExternalNameRef xExtName = std::make_shared<ExternalName>( *this );
566  maExtNames.push_back( xExtName );
567  return xExtName;
568 }
569 
571  mnExtRefId( -1 ),
572  mnTabId1( -1 ),
573  mnTabId2( -1 )
574 {
575 }
576 
578 {
579  mnExtRefId = rStrm.readInt32();
580  mnTabId1 = rStrm.readInt32();
581  mnTabId2 = rStrm.readInt32();
582 }
583 
585  WorkbookHelper( rHelper ),
586  mxSelfRef( std::make_shared<ExternalLink>( rHelper ) ),
587  mbUseRefSheets( false )
588 {
589  mxSelfRef->setSelfLinkType();
590 }
591 
593 {
594  ExternalLinkRef xExtLink = createExternalLink();
595  xExtLink->importExternalReference( rAttribs );
596  maExtLinks.push_back( xExtLink );
597  return xExtLink;
598 }
599 
601 {
602  mbUseRefSheets = true;
603  ExternalLinkRef xExtLink = createExternalLink();
604  xExtLink->importExternalRef( rStrm );
605  maExtLinks.push_back( xExtLink );
606  return xExtLink;
607 }
608 
610 {
611  mbUseRefSheets = true;
612  createExternalLink()->importExternalSelf( rStrm );
613 }
614 
616 {
617  mbUseRefSheets = true;
618  createExternalLink()->importExternalSame( rStrm );
619 }
620 
622 {
623  mbUseRefSheets = true;
624  createExternalLink()->importExternalAddin( rStrm );
625 }
626 
628 {
629  OSL_ENSURE( mbUseRefSheets, "ExternalLinkBuffer::importExternalSheets - missing EXTERNALREFS records" );
630  mbUseRefSheets = true;
631  OSL_ENSURE( maRefSheets.empty(), "ExternalLinkBuffer::importExternalSheets - multiple EXTERNALSHEETS records" );
632  maRefSheets.clear();
633  sal_Int32 nRefCount;
634  nRefCount = rStrm.readInt32();
635  size_t nMaxCount = getLimitedValue< size_t, sal_Int64 >( nRefCount, 0, rStrm.getRemaining() / 12 );
636  maRefSheets.reserve( nMaxCount );
637  for( size_t nRefId = 0; !rStrm.isEof() && (nRefId < nMaxCount); ++nRefId )
638  {
639  RefSheetsModel aRefSheets;
640  aRefSheets.readBiff12Data( rStrm );
641  maRefSheets.push_back( aRefSheets );
642  }
643 }
644 
645 Sequence< ExternalLinkInfo > ExternalLinkBuffer::getLinkInfos() const
646 {
647  ::std::vector< ExternalLinkInfo > aLinkInfos;
648  // add entry for implicit index 0 (self reference to this document)
649  aLinkInfos.push_back( mxSelfRef->getLinkInfo() );
650  for( const auto& rxExtLink : maExtLinks )
651  aLinkInfos.push_back( rxExtLink->getLinkInfo() );
652  return comphelper::containerToSequence( aLinkInfos );
653 }
654 
655 ExternalLinkRef ExternalLinkBuffer::getExternalLink( sal_Int32 nRefId, bool bUseRefSheets ) const
656 {
657  ExternalLinkRef xExtLink;
658  // OOXML: 0 = this document, otherwise one-based index into link list
659  if( !bUseRefSheets || !mbUseRefSheets )
660  xExtLink = (nRefId == 0) ? mxSelfRef : maLinks.get( nRefId - 1 );
661  // BIFF12: zero-based index into ref-sheets list
662  else if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
663  xExtLink = maLinks.get( pRefSheets->mnExtRefId );
664  return xExtLink;
665 }
666 
668 {
669  OSL_ENSURE( mbUseRefSheets, "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
670  LinkSheetRange aSheetRange;
671  if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
672  if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
673  pExtLink->getSheetRange( aSheetRange, pRefSheets->mnTabId1, pRefSheets->mnTabId2 );
674  return aSheetRange;
675 }
676 
677 // private --------------------------------------------------------------------
678 
680 {
681  ExternalLinkRef xExtLink = std::make_shared<ExternalLink>( *this );
682  maLinks.push_back( xExtLink );
683  return xExtLink;
684 }
685 
686 const RefSheetsModel* ExternalLinkBuffer::getRefSheets( sal_Int32 nRefId ) const
687 {
688  return ((0 <= nRefId) && (o3tl::make_unsigned( nRefId ) < maRefSheets.size())) ?
689  &maRefSheets[ static_cast< size_t >( nRefId ) ] : nullptr;
690 }
691 
692 } // namespace oox
693 
694 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Helper class to provide access to global workbook data.
void importDdeItem(const AttributeList &rAttribs)
Imports the ddeItem element describing an item of a DDE link.
css::uno::Reference< css::sheet::XDDELink > mxDdeLink
Current position in result matrix.
void importExternalSelf(SequenceInputStream &rStrm)
Imports the EXTERNALSELF record from the passed stream.
void storeRangeNameTokens(sal_uInt16 nFileId, const OUString &rName, const ScTokenArray &rArray)
bool getDdeLinkData(OUString &orDdeServer, OUString &orDdeTopic, OUString &orDdeItem)
Returns the complete DDE link data of this DDE item.
ExternalLinkRef getExternalLink(sal_Int32 nRefId, bool bUseRefSheets=true) const
Returns the external link for the passed reference identifier.
OptValue< bool > getBool(sal_Int32 nAttrToken) const
sal_Int32 nRefCount
ExternalLinkVec maLinks
Implicit self reference at index 0.
SCROW Row() const
Definition: address.hxx:261
const sal_uInt8 BIFF_ERR_NA
Definition: biffhelper.hxx:566
static const VectorType::value_type * getVectorElement(const VectorType &rVector, sal_Int32 nIndex)
OptValue< OUString > getXString(sal_Int32 nAttrToken) const
std::shared_ptr< ExternalLink > ExternalLinkRef
OptValue< sal_Int32 > getInteger(sal_Int32 nAttrToken) const
Link refers to the current sheet.
static double calcDoubleFromError(sal_uInt8 nErrorCode)
Converts the passed BIFF error to a double containing the respective Calc error code.
Definition: biffhelper.cxx:58
sal_Int32 mnSheet
The formula string.
void appendResultValue(const Type &rValue)
Appends the passed value to the result set.
ResultMatrix maResults
Additional name data.
#define CREATE_OFFICEDOC_RELATION_TYPE(ascii)
std::unique_ptr< ScTokenArray > CompileString(const OUString &rFormula)
Tokenize formula expression string into an array of tokens.
Definition: compiler.cxx:4624
Link refers to the current workbook.
css::uno::Any getAnyProperty(sal_Int32 nPropId) const
const ScAddress & getMaxApiAddress() const
Returns the biggest valid cell address in the own Calc document.
void importExternalNameFlags(SequenceInputStream &rStrm)
Imports the EXTERNALNAMEFLAGS record containing the settings of an external name. ...
value_type get(sal_Int32 nIndex) const
Link refers to an external add-in.
sal_uInt16 getExternalFileId(const OUString &rFile)
void SetExternalLinks(const css::uno::Sequence< css::sheet::ExternalLinkInfo > &rLinks)
Set external link info for ScAddress::CONV_XL_OOX.
Definition: compiler.hxx:461
Link refers to an external spreadsheet document.
OptValue< OUString > getString(sal_Int32 nAttrToken) const
ExternalLinkVec maExtLinks
List of link structures for all kinds of links.
std::shared_ptr< T > make_shared(Args &&...args)
void importExternalName(SequenceInputStream &rStrm)
Imports the EXTERNALNAME record containing the name (only).
const ExternalLink & mrParentLink
bool mbOleObj
Name is the StdDocumentName for DDE.
bool mbIconified
Name is an OLE object.
Unknown
OUString maFormula
The original name.
sal_Int32 mnTabId1
Zero-based index into list of external documents.
Base class for defined names and external names.
sal_uInt16 readuInt16()
SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck(const ScTokenArray &rCode)
Check token array and set link check if ocDde/ocWebservice is contained.
Definition: documen8.cxx:1156
sal_Int32 mnTabId2
Zero-based index to first sheet in external document.
int nCount
sal_Int32 mnDocLink
Link sheet range type.
::oox::core::FilterBase & getBaseFilter() const
Returns the base filter object (base class of all filters).
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:623
RefSheetsModel()
Zero-based index to last sheet in external document.
const RefSheetsModel * getRefSheets(sal_Int32 nRefId) const
Returns the specified sheet indexes for a reference identifier.
Just for round-tripping (FIXME: Functionality not actually implemented after all.) ...
bool getFlag(Type nBitField, Type nMask)
ExternalName(const ExternalLink &rParentLink)
void importOleItem(const AttributeList &rAttribs)
Imports the oleItem element describing an object of an OLE link.
#define CREATE_OFFICEDOC_RELATION_TYPE_STRICT(ascii)
void setSameSheet()
Sets this struct to "use current sheet" state.
void importExternalAddin(SequenceInputStream &rStrm)
Imports the EXTERNALADDIN record from the passed stream.
void resize(size_type nWidth, size_type nHeight)
const css::uno::Reference< css::sheet::XSpreadsheetDocument > & getDocument() const
Returns a reference to the source/target spreadsheet document model.
ExternalLinkBuffer & getExternalLinks() const
Returns the external links read from the external links substream.
static OUString readString(SequenceInputStream &rStrm, bool b32BitLen=true)
Reads a BIFF12 string with leading 16-bit or 32-bit length field.
Definition: biffhelper.cxx:80
#define CREATE_MSOFFICE_RELATION_TYPE(ascii)
bool mbUseRefSheets
Sheet indexes for reference ids.
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_Int32 mnLast
Index of the first sheet or index of first external sheet cache.
static FunctionLibraryType getFuncLibTypeFromLibraryName(const OUString &rLibraryName)
Returns the library type associated with the passed URL of a function library (function add-in)...
ExternalLinkBuffer(const WorkbookHelper &rHelper)
void readBiff12Data(SequenceInputStream &rStrm)
sal_Int32 mnFirst
Document link token index for external links.
FormulaError
SCCOL Col() const
Definition: address.hxx:266
void setResultSize(sal_Int32 nColumns, sal_Int32 nRows)
Sets the size of the result matrix.
RefSheetsModelVec maRefSheets
Real external links needed for formula parser.
FunctionLibraryType
This enumeration contains constants for all known external libraries containing supported sheet funct...
void importValues(const AttributeList &rAttribs)
Imports the values element containing the size of the DDE result matrix.
ExternalLinkRef importExternalReference(const AttributeList &rAttribs)
Imports the externalReference element containing .
bool mbPreferPic
Notify application on data change.
css::uno::Sequence< css::sheet::ExternalLinkInfo > getLinkInfos() const
Returns the sequence of link infos needed by the XML formula parser.
sal_Int64 getRemaining() const
void setExternalRange(sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast)
Sets the passed external sheet cache range to the members of this struct.
void clear()
void setDeleted()
Sets this struct to deleted state.
#define SAL_WARN_IF(condition, area, stream)
ExternalNameModel maExtNameModel
External link this name belongs to.
Represents a REF entry in the BIFF12 EXTERNALSHEETS or in the BIFF8 EXTERNSHEET record.
void importDdeItemValues(SequenceInputStream &rStrm)
Imports the DDEITEMVALUES record containing the size of the DDE result matrix.
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
void importExternalSame(SequenceInputStream &rStrm)
Imports the EXTERNALSAME record from the passed stream.
static css::uno::Sequence< css::uno::Sequence< typename MatrixType::value_type > > matrixToSequenceSequence(const MatrixType &rMatrix)
LinkSheetRange getSheetRange(sal_Int32 nRefId) const
Returns the sheet range for the specified reference (BIFF8 only).
void importDdeItemError(SequenceInputStream &rStrm)
Imports the DDEITEM_ERROR record containing an error code in a link result.
SfxItemInfo const aItemInfos[]
Definition: docpool.cxx:91
bool empty() const
iterator begin()
void importExternalSheets(SequenceInputStream &rStrm)
Imports the EXTERNALSHEETS record from the passed stream.
Contains indexes for a range of sheets in the spreadsheet document.
ExternalLinkRef importExternalRef(SequenceInputStream &rStrm)
Imports the EXTERNALREF record from the passed stream.
void importDdeItemString(SequenceInputStream &rStrm)
Imports the DDEITEM_STRING record containing a string in a link result.
OUString getAbsoluteUrl(const OUString &rUrl) const
bool mbDdeLinkCreated
Interface of a DDE link.
bool isEof() const
ExternalLinkRef createExternalLink()
Creates a new external link and inserts it into the list of links.
void importDdeItemBool(SequenceInputStream &rStrm)
Imports the DDEITEM_BOOL record containing a boolean value in a link result.
bool getDdeItemInfo(css::sheet::DDEItemInfo &orItemInfo) const
Returns the DDE item info needed by the XML formula parser.
void setRange(sal_Int32 nFirst, sal_Int32 nLast)
Sets the passed absolute sheet range to the members of this struct.
void importDefinedName(const AttributeList &rAttribs)
Imports the definedName element.
std::shared_ptr< ExternalName > ExternalNameRef
ResultMatrix::iterator maCurrIt
DDE/OLE link results.
void importDdeItemDouble(SequenceInputStream &rStrm)
Imports the DDEITEM_DOUBLE record containing a double value in a link result.
AddressConverter & getAddressConverter() const
Returns the converter for string to cell address/range conversion.
ExternalNameModel()
Iconified object link.