LibreOffice Module sc (master)  1
xilink.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 <xilink.hxx>
21 #include <document.hxx>
22 #include <scextopt.hxx>
23 #include <xistream.hxx>
24 #include <xihelper.hxx>
25 #include <xiname.hxx>
26 #include <xltools.hxx>
27 #include <excform.hxx>
28 #include <tokenarray.hxx>
29 #include <externalrefmgr.hxx>
30 #include <scmatrix.hxx>
31 #include <svl/sharedstringpool.hxx>
32 #include <sal/log.hxx>
33 
34 #include <vector>
35 #include <memory>
36 
37 // *** Helper classes ***
38 
39 // Cached external cells ======================================================
40 
41 namespace {
42 
47 class XclImpCrn : public XclImpCachedValue
48 {
49 public:
51  explicit XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
52 
53  const XclAddress& GetAddress() const { return maXclPos;}
54 
55 private:
56  XclAddress maXclPos;
57 };
58 
59 // Sheet in an external document ==============================================
60 
62 class XclImpSupbookTab
63 {
64 public:
67  explicit XclImpSupbookTab( const OUString& rTabName );
68 
69  const OUString& GetTabName() const { return maTabName; }
70 
72  void ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
73 
74  void LoadCachedValues( const ScExternalRefCache::TableTypeRef& pCacheTable,
75  svl::SharedStringPool& rPool );
76 
77 private:
78  typedef std::shared_ptr< XclImpCrn > XclImpCrnRef;
79 
80  std::vector< XclImpCrnRef > maCrnList;
81  OUString maTabName;
82 };
83 
84 }
85 
86 // External document (SUPBOOK) ================================================
87 
90 class XclImpSupbook : protected XclImpRoot
91 {
92 public:
94  explicit XclImpSupbook( XclImpStream& rStrm );
95 
97  void ReadXct( XclImpStream& rStrm );
99  void ReadCrn( XclImpStream& rStrm );
101  void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv );
102 
104  XclSupbookType GetType() const { return meType; }
105 
107  const OUString& GetXclUrl() const { return maXclUrl; }
108 
110  const XclImpExtName* GetExternName( sal_uInt16 nXclIndex ) const;
115  bool GetLinkData( OUString& rApplic, OUString& rDoc ) const;
117  const OUString& GetMacroName( sal_uInt16 nXclNameIdx ) const;
118 
119  const OUString& GetTabName( sal_uInt16 nXtiTab ) const;
120 
121  sal_uInt16 GetTabCount() const;
122 
123  void LoadCachedValues();
124 
126 
127 private:
128 
129  std::vector< std::unique_ptr<XclImpSupbookTab> >
131  std::vector< std::unique_ptr<XclImpExtName> >
133  OUString maXclUrl;
135  sal_uInt16 mnSBTab;
136 };
137 
138 // Import link manager ========================================================
139 
140 namespace {
141 
145 struct XclImpXti
146 {
147  sal_uInt16 mnSupbook;
148  sal_uInt16 mnSBTabFirst;
149  sal_uInt16 mnSBTabLast;
150  explicit XclImpXti() : mnSupbook( SAL_MAX_UINT16 ), mnSBTabFirst( SAL_MAX_UINT16 ), mnSBTabLast( SAL_MAX_UINT16 ) {}
151 };
152 
153 XclImpStream& operator>>( XclImpStream& rStrm, XclImpXti& rXti )
154 {
155  rXti.mnSupbook = rStrm.ReaduInt16();
156  rXti.mnSBTabFirst = rStrm.ReaduInt16();
157  rXti.mnSBTabLast = rStrm.ReaduInt16();
158  return rStrm;
159 }
160 
161 }
162 
165 {
166 public:
167  explicit XclImpLinkManagerImpl( const XclImpRoot& rRoot );
168 
170  void ReadExternsheet( XclImpStream& rStrm );
172  void ReadSupbook( XclImpStream& rStrm );
174  void ReadXct( XclImpStream& rStrm );
176  void ReadCrn( XclImpStream& rStrm );
178  void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv );
179 
181  bool IsSelfRef( sal_uInt16 nXtiIndex ) const;
184  bool GetScTabRange(
185  SCTAB& rnFirstScTab, SCTAB& rnLastScTab,
186  sal_uInt16 nXtiIndex ) const;
188  const XclImpExtName* GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const;
189 
192  const OUString* GetSupbookUrl( sal_uInt16 nXtiIndex ) const;
193 
194  const OUString& GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const;
195 
200  bool GetLinkData( OUString& rApplic, OUString& rTopic, sal_uInt16 nXtiIndex ) const;
202  const OUString& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const;
203 
204 private:
206  const XclImpXti* GetXti( sal_uInt16 nXtiIndex ) const;
208  const XclImpSupbook* GetSupbook( sal_uInt16 nXtiIndex ) const;
209 
210  void LoadCachedValues();
211 
212 private:
213  typedef std::vector< XclImpXti > XclImpXtiVector;
214 
215  XclImpXtiVector maXtiList;
216  std::vector< std::unique_ptr<XclImpSupbook> >
218 };
219 
220 // *** Implementation ***
221 
222 // Excel sheet indexes ========================================================
223 
224 // original Excel sheet names -------------------------------------------------
225 
226 void XclImpTabInfo::AppendXclTabName( const OUString& rXclTabName, SCTAB nScTab )
227 {
228  maTabNames[ rXclTabName ] = nScTab;
229 }
230 
232 {
233  for( auto& rEntry : maTabNames )
234  if( rEntry.second >= nScTab )
235  ++rEntry.second;
236 }
237 
238 SCTAB XclImpTabInfo::GetScTabFromXclName( const OUString& rXclTabName ) const
239 {
240  XclTabNameMap::const_iterator aIt = maTabNames.find( rXclTabName );
241  return (aIt != maTabNames.end()) ? aIt->second : SCTAB_INVALID;
242 }
243 
244 // record creation order - TABID record ---------------------------------------
245 
247 {
248  OSL_ENSURE_BIFF( rStrm.GetRoot().GetBiff() == EXC_BIFF8 );
249  if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
250  {
251  rStrm.EnableDecryption();
252  std::size_t nReadCount = rStrm.GetRecLeft() / 2;
253  OSL_ENSURE( nReadCount <= 0xFFFF, "XclImpTabInfo::ReadTabid - record too long" );
254  maTabIdVec.clear();
255  maTabIdVec.reserve( nReadCount );
256  for( std::size_t nIndex = 0; rStrm.IsValid() && (nIndex < nReadCount); ++nIndex )
257  // zero index is not allowed in BIFF8, but it seems that it occurs in real life
258  maTabIdVec.push_back( rStrm.ReaduInt16() );
259  }
260 }
261 
262 sal_uInt16 XclImpTabInfo::GetCurrentIndex( sal_uInt16 nCreatedId, sal_uInt16 nMaxTabId ) const
263 {
264  sal_uInt16 nReturn = 0;
265  for( sal_uInt16 nValue : maTabIdVec )
266  {
267  if( nValue == nCreatedId )
268  return nReturn;
269  if( nValue <= nMaxTabId )
270  ++nReturn;
271  }
272  return 0;
273 }
274 
275 // External names =============================================================
276 
278  mxCached(new ScMatrix(0,0))
279 {
280  SCSIZE nLastCol = rStrm.ReaduInt8();
281  SCSIZE nLastRow = rStrm.ReaduInt16();
282 
283  //assuming worst case scenario of nOp + one byte unistring len
284  const size_t nMinRecordSize = 2;
285  const size_t nMaxRows = rStrm.GetRecLeft() / (nMinRecordSize * (nLastCol+1));
286  if (nLastRow >= nMaxRows)
287  {
288  SAL_WARN("sc", "Parsing error: " << nMaxRows <<
289  " max possible rows, but " << nLastRow << " index claimed, truncating");
290  if (nMaxRows > 0)
291  nLastRow = nMaxRows-1;
292  else
293  return;
294  }
295 
296  mxCached->Resize(nLastCol+1, nLastRow+1);
297  for (SCSIZE nRow = 0; nRow <= nLastRow; ++nRow)
298  {
299  for (SCSIZE nCol = 0; nCol <= nLastCol; ++nCol)
300  {
301  sal_uInt8 nOp;
302  nOp = rStrm.ReaduInt8();
303  switch (nOp)
304  {
305  case 0x01:
306  {
307  double fVal = rStrm.ReadDouble();
308  mxCached->PutDouble(fVal, nCol, nRow);
309  }
310  break;
311  case 0x02:
312  {
313  OUString aStr = rStrm.ReadUniString();
314  mxCached->PutString(rPool.intern(aStr), nCol, nRow);
315  }
316  break;
317  case 0x04:
318  {
319  bool bVal = rStrm.ReaduInt8();
320  mxCached->PutBoolean(bVal, nCol, nRow);
321  rStrm.Ignore(7);
322  }
323  break;
324  case 0x10:
325  {
326  sal_uInt8 nErr = rStrm.ReaduInt8();
327  // Map the error code from xls to calc.
328  mxCached->PutError(XclTools::GetScErrorCode(nErr), nCol, nRow);
329  rStrm.Ignore(7);
330  }
331  break;
332  default:
333  rStrm.Ignore(8);
334  }
335  }
336  }
337 }
338 
340 {
341  return *mxCached;
342 }
343 
345  : mnStorageId(0)
346 {
347  sal_uInt16 nFlags(0);
348  sal_uInt8 nLen(0);
349 
350  nFlags = rStrm.ReaduInt16();
351  mnStorageId = rStrm.ReaduInt32();
352  nLen = rStrm.ReaduInt8();
353  maName = rStrm.ReadUniString( nLen );
354  if( ::get_flag( nFlags, EXC_EXTN_BUILTIN ) || !::get_flag( nFlags, EXC_EXTN_OLE_OR_DDE ) )
355  {
356  if( eSubType == XclSupbookType::Addin )
357  {
358  meType = xlExtAddIn;
360  }
361  else if ( (eSubType == XclSupbookType::Eurotool) &&
362  maName.equalsIgnoreAsciiCase( "EUROCONVERT" ) )
364  else
365  {
366  meType = xlExtName;
368  }
369  }
370  else
371  {
373  }
374 
375  switch (meType)
376  {
377  case xlExtDDE:
378  if (rStrm.GetRecLeft() > 1)
379  mxDdeMatrix.reset(new XclImpCachedMatrix(rStrm));
380  break;
381  case xlExtName:
382  // TODO: For now, only global external names are supported. In future
383  // we should extend this to supporting per-sheet external names.
384  if (mnStorageId == 0 && pFormulaConv)
385  {
386  std::unique_ptr<ScTokenArray> pArray;
387  sal_uInt16 nFmlaLen;
388  nFmlaLen = rStrm.ReaduInt16();
389  std::vector<OUString> aTabNames;
390  sal_uInt16 nCount = rSupbook.GetTabCount();
391  aTabNames.reserve(nCount);
392  for (sal_uInt16 i = 0; i < nCount; ++i)
393  aTabNames.push_back(rSupbook.GetTabName(i));
394 
395  pFormulaConv->ConvertExternName(pArray, rStrm, nFmlaLen, rSupbook.GetXclUrl(), aTabNames);
396  if (pArray)
397  mxArray = std::move( pArray );
398  }
399  break;
400  case xlExtOLE:
401  mpMOper.reset( new MOper(rSupbook.GetSharedStringPool(), rStrm) );
402  break;
403  default:
404  ;
405  }
406 }
407 
409 {
410 }
411 
412 void XclImpExtName::CreateDdeData( ScDocument& rDoc, const OUString& rApplic, const OUString& rTopic ) const
413 {
414  ScMatrixRef xResults;
415  if( mxDdeMatrix )
416  xResults = mxDdeMatrix->CreateScMatrix(rDoc.GetSharedStringPool());
417  rDoc.CreateDdeLink( rApplic, rTopic, maName, SC_DDE_DEFAULT, xResults );
418 }
419 
420 void XclImpExtName::CreateExtNameData( const ScDocument& rDoc, sal_uInt16 nFileId ) const
421 {
422  if (!mxArray)
423  return;
424 
426  pRefMgr->storeRangeNameTokens(nFileId, maName, *mxArray);
427 }
428 
429 namespace {
430 
436 bool extractSheetAndRange(const OUString& rName, OUString& rSheet, OUString& rRange)
437 {
438  sal_Int32 n = rName.getLength();
439  const sal_Unicode* p = rName.getStr();
440  OUStringBuffer aBuf;
441  bool bInSheet = true;
442  for (sal_Int32 i = 0; i < n; ++i, ++p)
443  {
444  if (i == 0)
445  {
446  // first character must be '!'.
447  if (*p != '!')
448  return false;
449  continue;
450  }
451 
452  if (*p == '!')
453  {
454  // sheet name to range separator.
455  if (!bInSheet)
456  return false;
457  rSheet = aBuf.makeStringAndClear();
458  bInSheet = false;
459  continue;
460  }
461 
462  aBuf.append(*p);
463  }
464 
465  rRange = aBuf.makeStringAndClear();
466  return true;
467 }
468 
469 }
470 
471 bool XclImpExtName::CreateOleData(const ScDocument& rDoc, const OUString& rUrl,
472  sal_uInt16& rFileId, OUString& rTabName, ScRange& rRange) const
473 {
474  if (!mpMOper)
475  return false;
476 
477  OUString aSheet, aRangeStr;
478  if (!extractSheetAndRange(maName, aSheet, aRangeStr))
479  return false;
480 
481  ScRange aRange;
482  ScRefFlags nRes = aRange.ParseAny(aRangeStr, rDoc, formula::FormulaGrammar::CONV_XL_R1C1);
483  if ((nRes & ScRefFlags::VALID) == ScRefFlags::ZERO)
484  return false;
485 
486  if (aRange.aStart.Tab() != aRange.aEnd.Tab())
487  // We don't support multi-sheet range for this.
488  return false;
489 
490  const ScMatrix& rCache = mpMOper->GetCache();
491  SCSIZE nC, nR;
492  rCache.GetDimensions(nC, nR);
493  if (!nC || !nR)
494  // cache matrix is empty.
495  return false;
496 
498  sal_uInt16 nFileId = pRefMgr->getExternalFileId(rUrl);
499  ScExternalRefCache::TableTypeRef xTab = pRefMgr->getCacheTable(nFileId, aSheet, true);
500  if (!xTab)
501  // cache table creation failed.
502  return false;
503 
504  xTab->setWholeTableCached();
505  for (SCSIZE i = 0; i < nR; ++i)
506  {
507  for (SCSIZE j = 0; j < nC; ++j)
508  {
509  SCCOL nCol = aRange.aStart.Col() + j;
510  SCROW nRow = aRange.aStart.Row() + i;
511 
512  ScMatrixValue aVal = rCache.Get(j, i);
513  switch (aVal.nType)
514  {
516  {
517  bool b = aVal.GetBoolean();
519  xTab->setCell(nCol, nRow, pToken, 0, false);
520  }
521  break;
522  case ScMatValType::Value:
523  {
525  xTab->setCell(nCol, nRow, pToken, 0, false);
526  }
527  break;
529  {
531  xTab->setCell(nCol, nRow, pToken, 0, false);
532  }
533  break;
534  default:
535  ;
536  }
537  }
538  }
539 
540  rFileId = nFileId;
541  rTabName = aSheet;
542  rRange = aRange;
543  return true;
544 }
545 
547 {
548  return bool(mxArray);
549 }
550 
551 // Cached external cells ======================================================
552 
553 XclImpCrn::XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos ) :
554  XclImpCachedValue( rStrm ),
555  maXclPos( rXclPos )
556 {
557 }
558 
559 // Sheet in an external document ==============================================
560 
561 XclImpSupbookTab::XclImpSupbookTab( const OUString& rTabName ) :
562  maTabName( rTabName )
563 {
564 }
565 
566 void XclImpSupbookTab::ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos )
567 {
568  XclImpCrnRef crnRef = std::make_shared<XclImpCrn>(rStrm, rXclPos);
569  maCrnList.push_back( crnRef );
570 }
571 
572 void XclImpSupbookTab::LoadCachedValues( const ScExternalRefCache::TableTypeRef& pCacheTable,
573  svl::SharedStringPool& rPool )
574 {
575  if (maCrnList.empty())
576  return;
577 
578  for (const auto& rxCrn : maCrnList)
579  {
580  const XclImpCrn* const pCrn = rxCrn.get();
581  const XclAddress& rAddr = pCrn->GetAddress();
582  switch (pCrn->GetType())
583  {
584  case EXC_CACHEDVAL_BOOL:
585  {
586  bool b = pCrn->GetBool();
588  pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
589  }
590  break;
592  {
593  double f = pCrn->GetValue();
595  pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
596  }
597  break;
598  case EXC_CACHEDVAL_ERROR:
599  {
600  double fError = XclTools::ErrorToDouble( pCrn->GetXclError() );
602  pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
603  }
604  break;
606  {
607  svl::SharedString aSS( rPool.intern( pCrn->GetString()));
609  pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
610  }
611  break;
612  default:
613  ;
614  }
615  }
616 }
617 
618 // External document (SUPBOOK) ================================================
619 
621  XclImpRoot( rStrm.GetRoot() ),
623  mnSBTab( EXC_TAB_DELETED )
624 {
625  sal_uInt16 nSBTabCnt;
626  nSBTabCnt = rStrm.ReaduInt16();
627 
628  if( rStrm.GetRecLeft() == 2 )
629  {
630  switch( rStrm.ReaduInt16() )
631  {
634  default: OSL_FAIL( "XclImpSupbook::XclImpSupbook - unknown special SUPBOOK type" );
635  }
636  return;
637  }
638 
639  OUString aEncUrl( rStrm.ReadUniString() );
640  bool bSelf = false;
641  XclImpUrlHelper::DecodeUrl( maXclUrl, bSelf, GetRoot(), aEncUrl );
642 
643  if( maXclUrl.equalsIgnoreAsciiCase( "\010EUROTOOL.XLA" ) )
644  {
646  maSupbTabList.push_back( std::make_unique<XclImpSupbookTab>( maXclUrl ) );
647  }
648  else if( nSBTabCnt )
649  {
651 
652  //assuming all empty strings with just len header of 0
653  const size_t nMinRecordSize = sizeof(sal_Int16);
654  const size_t nMaxRecords = rStrm.GetRecLeft() / nMinRecordSize;
655  if (nSBTabCnt > nMaxRecords)
656  {
657  SAL_WARN("sc", "Parsing error: " << nMaxRecords <<
658  " max possible entries, but " << nSBTabCnt << " claimed, truncating");
659  nSBTabCnt = nMaxRecords;
660  }
661 
662  for( sal_uInt16 nSBTab = 0; nSBTab < nSBTabCnt; ++nSBTab )
663  {
664  OUString aTabName( rStrm.ReadUniString() );
665  maSupbTabList.push_back( std::make_unique<XclImpSupbookTab>( aTabName ) );
666  }
667  }
668  else
669  {
671  // create dummy list entry
672  maSupbTabList.push_back( std::make_unique<XclImpSupbookTab>( maXclUrl ) );
673  }
674 }
675 
677 {
678  rStrm.Ignore( 2 );
679  mnSBTab = rStrm.ReaduInt16();
680 }
681 
683 {
684  if (mnSBTab >= maSupbTabList.size())
685  return;
686  XclImpSupbookTab& rSbTab = *maSupbTabList[mnSBTab];
687  sal_uInt8 nXclColLast, nXclColFirst;
688  sal_uInt16 nXclRow;
689  nXclColLast = rStrm.ReaduInt8();
690  nXclColFirst = rStrm.ReaduInt8();
691  nXclRow = rStrm.ReaduInt16();
692 
693  for( sal_uInt8 nXclCol = nXclColFirst; (nXclCol <= nXclColLast) && (rStrm.GetRecLeft() > 1); ++nXclCol )
694  rSbTab.ReadCrn( rStrm, XclAddress( nXclCol, nXclRow ) );
695 }
696 
698 {
699  maExtNameList.push_back( std::make_unique<XclImpExtName>( *this, rStrm, meType, pFormulaConv ) );
700 }
701 
702 const XclImpExtName* XclImpSupbook::GetExternName( sal_uInt16 nXclIndex ) const
703 {
704  if (nXclIndex == 0)
705  {
706  SAL_WARN("sc", "XclImpSupbook::GetExternName - index must be >0");
707  return nullptr;
708  }
709  if (meType == XclSupbookType::Self || nXclIndex > maExtNameList.size())
710  return nullptr;
711  return maExtNameList[nXclIndex-1].get();
712 }
713 
714 bool XclImpSupbook::GetLinkData( OUString& rApplic, OUString& rTopic ) const
715 {
716  return (meType == XclSupbookType::Special) && XclImpUrlHelper::DecodeLink( rApplic, rTopic, maXclUrl );
717 }
718 
719 const OUString& XclImpSupbook::GetMacroName( sal_uInt16 nXclNameIdx ) const
720 {
721  OSL_ENSURE( nXclNameIdx > 0, "XclImpSupbook::GetMacroName - index must be >0" );
722  const XclImpName* pName = (meType == XclSupbookType::Self) ? GetNameManager().GetName( nXclNameIdx ) : nullptr;
723  return (pName && pName->IsVBName()) ? pName->GetScName() : EMPTY_OUSTRING;
724 }
725 
726 const OUString& XclImpSupbook::GetTabName( sal_uInt16 nXtiTab ) const
727 {
728  if (nXtiTab >= maSupbTabList.size())
729  return EMPTY_OUSTRING;
730  return maSupbTabList[nXtiTab]->GetTabName();
731 }
732 
733 sal_uInt16 XclImpSupbook::GetTabCount() const
734 {
735  return ulimit_cast<sal_uInt16>(maSupbTabList.size());
736 }
737 
739 {
740  if (meType != XclSupbookType::Extern || GetExtDocOptions().GetDocSettings().mnLinkCnt > 0 || !GetDocShell())
741  return;
742 
743  OUString aAbsUrl( ScGlobal::GetAbsDocName(maXclUrl, GetDocShell()) );
744 
746  sal_uInt16 nFileId = pRefMgr->getExternalFileId(aAbsUrl);
747 
748  for (auto& rxTab : maSupbTabList)
749  {
750  const OUString& rTabName = rxTab->GetTabName();
751  ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
752  rxTab->LoadCachedValues( pCacheTable, GetSharedStringPool());
753  pCacheTable->setWholeTableCached();
754  }
755 }
756 
758 {
759  return GetDoc().GetSharedStringPool();
760 }
761 
762 // Import link manager ========================================================
763 
765  XclImpRoot( rRoot )
766 {
767 }
768 
770 {
771  sal_uInt16 nXtiCount;
772  nXtiCount = rStrm.ReaduInt16();
773  OSL_ENSURE( static_cast< std::size_t >( nXtiCount * 6 ) == rStrm.GetRecLeft(), "XclImpLinkManagerImpl::ReadExternsheet - invalid count" );
774  nXtiCount = static_cast< sal_uInt16 >( ::std::min< std::size_t >( nXtiCount, rStrm.GetRecLeft() / 6 ) );
775 
776  /* #i104057# A weird external XLS generator writes multiple EXTERNSHEET
777  records instead of only one as expected. Surprisingly, Excel seems to
778  insert the entries of the second record before the entries of the first
779  record. */
780  XclImpXtiVector aNewEntries( nXtiCount );
781  for( auto& rNewEntry : aNewEntries )
782  {
783  if (!rStrm.IsValid())
784  break;
785  rStrm >> rNewEntry;
786  }
787  maXtiList.insert( maXtiList.begin(), aNewEntries.begin(), aNewEntries.end() );
788 
790 }
791 
793 {
794  maSupbookList.push_back( std::make_unique<XclImpSupbook>( rStrm ) );
795 }
796 
798 {
799  if( !maSupbookList.empty() )
800  maSupbookList.back()->ReadXct( rStrm );
801 }
802 
804 {
805  if( !maSupbookList.empty() )
806  maSupbookList.back()->ReadCrn( rStrm );
807 }
808 
810 {
811  if( !maSupbookList.empty() )
812  maSupbookList.back()->ReadExternname( rStrm, pFormulaConv );
813 }
814 
815 bool XclImpLinkManagerImpl::IsSelfRef( sal_uInt16 nXtiIndex ) const
816 {
817  const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
818  return pSupbook && (pSupbook->GetType() == XclSupbookType::Self);
819 }
820 
822  SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
823 {
824  if( const XclImpXti* pXti = GetXti( nXtiIndex ) )
825  {
826  if (!maSupbookList.empty() && (pXti->mnSupbook < maSupbookList.size()) )
827  {
828  rnFirstScTab = pXti->mnSBTabFirst;
829  rnLastScTab = pXti->mnSBTabLast;
830  return true;
831  }
832  }
833  return false;
834 }
835 
836 const XclImpExtName* XclImpLinkManagerImpl::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
837 {
838  const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
839  return pSupbook ? pSupbook->GetExternName( nExtName ) : nullptr;
840 }
841 
842 const OUString* XclImpLinkManagerImpl::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
843 {
844  const XclImpSupbook* p = GetSupbook( nXtiIndex );
845  if (!p)
846  return nullptr;
847  return &p->GetXclUrl();
848 }
849 
850 const OUString& XclImpLinkManagerImpl::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
851 {
852  const XclImpSupbook* p = GetSupbook(nXti);
853  return p ? p->GetTabName(nXtiTab) : EMPTY_OUSTRING;
854 }
855 
856 bool XclImpLinkManagerImpl::GetLinkData( OUString& rApplic, OUString& rTopic, sal_uInt16 nXtiIndex ) const
857 {
858  const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
859  return pSupbook && pSupbook->GetLinkData( rApplic, rTopic );
860 }
861 
862 const OUString& XclImpLinkManagerImpl::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
863 {
864  const XclImpSupbook* pSupbook = GetSupbook( nExtSheet );
865  return pSupbook ? pSupbook->GetMacroName( nExtName ) : EMPTY_OUSTRING;
866 }
867 
868 const XclImpXti* XclImpLinkManagerImpl::GetXti( sal_uInt16 nXtiIndex ) const
869 {
870  return (nXtiIndex < maXtiList.size()) ? &maXtiList[ nXtiIndex ] : nullptr;
871 }
872 
873 const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt16 nXtiIndex ) const
874 {
875  if ( maSupbookList.empty() )
876  return nullptr;
877  const XclImpXti* pXti = GetXti( nXtiIndex );
878  if (!pXti || pXti->mnSupbook >= maSupbookList.size())
879  return nullptr;
880  return maSupbookList.at( pXti->mnSupbook ).get();
881 }
882 
884 {
885  // Read all CRN records which can be accessed via XclImpSupbook, and store
886  // the cached values to the external reference manager.
887  for (auto& rxSupbook : maSupbookList)
888  rxSupbook->LoadCachedValues();
889 }
890 
892  XclImpRoot( rRoot ),
893  mxImpl( new XclImpLinkManagerImpl( rRoot ) )
894 {
895 }
896 
898 {
899 }
900 
902 {
903  mxImpl->ReadExternsheet( rStrm );
904 }
905 
907 {
908  mxImpl->ReadSupbook( rStrm );
909 }
910 
912 {
913  mxImpl->ReadXct( rStrm );
914 }
915 
917 {
918  mxImpl->ReadCrn( rStrm );
919 }
920 
922 {
923  mxImpl->ReadExternname( rStrm, pFormulaConv );
924 }
925 
926 bool XclImpLinkManager::IsSelfRef( sal_uInt16 nXtiIndex ) const
927 {
928  return mxImpl->IsSelfRef( nXtiIndex );
929 }
930 
932  SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
933 {
934  return mxImpl->GetScTabRange( rnFirstScTab, rnLastScTab, nXtiIndex );
935 }
936 
937 const XclImpExtName* XclImpLinkManager::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
938 {
939  return mxImpl->GetExternName( nXtiIndex, nExtName );
940 }
941 
942 const OUString* XclImpLinkManager::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
943 {
944  return mxImpl->GetSupbookUrl(nXtiIndex);
945 }
946 
947 const OUString& XclImpLinkManager::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
948 {
949  return mxImpl->GetSupbookTabName(nXti, nXtiTab);
950 }
951 
952 bool XclImpLinkManager::GetLinkData( OUString& rApplic, OUString& rTopic, sal_uInt16 nXtiIndex ) const
953 {
954  return mxImpl->GetLinkData( rApplic, rTopic, nXtiIndex );
955 }
956 
957 const OUString& XclImpLinkManager::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
958 {
959  return mxImpl->GetMacroName( nExtSheet, nExtName );
960 }
961 
962 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SC_DLLPUBLIC ScRefFlags ParseAny(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1)
Definition: address.cxx:1766
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:113
const XclImpSupbook * GetSupbook(sal_uInt16 nXtiIndex) const
Returns the specified SUPBOOK (external document).
Definition: xilink.cxx:873
MOper, multiple operands, stores cached values of external range specified in the record...
Definition: xilink.hxx:118
static bool DecodeLink(OUString &rApplic, OUString &rTopic, const OUString &rEncUrl)
Decodes the passed URL to OLE or DDE link components.
Definition: xihelper.cxx:757
sal_Int32 nIndex
XclImpSupbook(XclImpStream &rStrm)
Reads the SUPBOOK record from stream.
Definition: xilink.cxx:620
ScAddress aStart
Definition: address.hxx:500
void storeRangeNameTokens(sal_uInt16 nFileId, const OUString &rName, const ScTokenArray &rArray)
SharedString intern(const OUString &rStr)
void ReadExternsheet(XclImpStream &rStrm)
Reads the EXTERNSHEET record.
Definition: xilink.cxx:901
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:563
const OUString & GetMacroName(sal_uInt16 nExtSheet, sal_uInt16 nExtName) const
Returns the specified macro name or an empty string on error.
Definition: xilink.cxx:957
void ReadExternsheet(XclImpStream &rStrm)
Reads the EXTERNSHEET record.
Definition: xilink.cxx:769
#define EMPTY_OUSTRING
Definition: global.hxx:215
ReturnType get_flagvalue(Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset)
Returns nSet, if at least one bit of nMask is set in nBitField, otherwise nUnset. ...
Definition: ftools.hxx:78
SCROW Row() const
Definition: address.hxx:262
void ReadExternname(XclImpStream &rStrm, ExcelToSc *pFormulaConv)
Reads an EXTERNNAME record.
Definition: xilink.cxx:697
void ReadXct(XclImpStream &rStrm)
Reads an XCT record and appends it to the current SUPBOOK.
Definition: xilink.cxx:797
static OUString GetScAddInName(const OUString &rXclName)
Returns the Calc add-in function name for an Excel function name.
Definition: xiroot.cxx:263
static OUString ConvertToScDefinedName(const OUString &rName)
Converts a string to a valid Calc defined name or database range name.
Definition: ftools.cxx:145
std::vector< std::unique_ptr< XclImpSupbookTab > > maSupbTabList
Definition: xilink.cxx:130
const sal_uInt8 SC_DDE_DEFAULT
Definition: document.hxx:291
ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const
: If bString the ScMatrixValue->pS may still be NULL to indicate an empty string! ...
Definition: scmatrix.cxx:3094
sal_Int64 n
bool IsValid() const
Returns record reading state: false = record overread.
Definition: xistream.hxx:352
SC_DLLPUBLIC bool CreateDdeLink(const OUString &rAppl, const OUString &rTopic, const OUString &rItem, sal_uInt8 nMode, const ScMatrixRef &pResults)
Tries to find a DDE link or creates a new, if not extant.
Definition: documen8.cxx:991
const OUString & GetScName() const
Definition: xiname.hxx:53
bool IsVBName() const
Definition: xiname.hxx:57
aBuf
const ScMatrix & GetCache() const
Definition: xilink.cxx:339
ScAddress aEnd
Definition: address.hxx:501
sal_uInt32 mnRow
Definition: xladdress.hxx:33
sal_uInt16 getExternalFileId(const OUString &rFile)
bool GetLinkData(OUString &rApplic, OUString &rTopic, sal_uInt16 nXtiIndex) const
Tries to decode the URL of the specified XTI entry to OLE or DDE link components. ...
Definition: xilink.cxx:856
const sal_uInt8 EXC_CACHEDVAL_ERROR
Definition: xlconst.hxx:119
ScDocument & GetDoc() const
Returns reference to the destination document (import) or source document (export).
Definition: xlroot.cxx:276
const XclImpName * GetName(sal_uInt16 nXclNameIdx) const
Returns the defined name specified by its Excel index.
Definition: xiname.cxx:310
XclImpLinkManagerImpl(const XclImpRoot &rRoot)
Definition: xilink.cxx:764
const XclImpRoot & GetRoot() const
Returns this root instance - for code readability in derived classes.
Definition: xiroot.hxx:132
MOper(svl::SharedStringPool &rPool, XclImpStream &rStrm)
Definition: xilink.cxx:277
Unknown
XclImpXtiVector maXtiList
Definition: xilink.cxx:215
This class represents an external linked document (record SUPBOOK).
Definition: xilink.cxx:90
Try NOT to use this struct.
Definition: scmatrix.hxx:53
static double ErrorToDouble(sal_uInt8 nXclError)
Converts the passed BIFF error to a double containing the respective Calc error code.
Definition: xltools.cxx:241
sal_uInt16 GetTabCount() const
Definition: xilink.cxx:733
const OUString & GetMacroName(sal_uInt16 nExtSheet, sal_uInt16 nExtName) const
Returns the specified macro name or an empty string on error.
Definition: xilink.cxx:862
XclImpExtNameType meType
Storage ID for OLE object storages.
Definition: xilink.hxx:162
const XclImpExtName * GetExternName(sal_uInt16 nXclIndex) const
Returns the external name specified by an index from the Excel document (one-based).
Definition: xilink.cxx:702
sal_uInt16 sal_Unicode
double fVal
Definition: scmatrix.hxx:55
void ReadTabid(XclImpStream &rStrm)
Reads the TABID record.
Definition: xilink.cxx:246
bool GetBoolean() const
Only valid if ScMatrix methods indicate that this is a boolean.
Definition: scmatrix.hxx:66
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:45
void ReadExternname(XclImpStream &rStrm, ExcelToSc *pFormulaConv)
Reads an EXTERNNAME record and appends it to the current SUPBOOK.
Definition: xilink.cxx:921
#define SAL_MAX_UINT16
ScMatrixRef mxCached
Definition: xilink.hxx:124
ReturnType ulimit_cast(Type nValue, ReturnType nMax)
Returns the value, if it is not greater than nMax, otherwise nMax.
Definition: ftools.hxx:51
const SCTAB SCTAB_INVALID
An invalid Excel sheet index, for common use.
Definition: xlconst.hxx:74
bool GetScTabRange(SCTAB &rnFirstScTab, SCTAB &rnLastScTab, sal_uInt16 nXtiIndex) const
Returns the Calc sheet index range of the specified XTI entry.
Definition: xilink.cxx:931
int nCount
void ReadXct(XclImpStream &rStrm)
Reads an XCT record and appends it to the current SUPBOOK.
Definition: xilink.cxx:911
static FormulaError GetScErrorCode(sal_uInt8 nXclError)
Converts an Excel error code to a Calc error code.
Definition: xltools.cxx:225
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:618
::boost::intrusive_ptr< ScMatrix > ScMatrixRef
Definition: types.hxx:26
SCTAB Tab() const
Definition: address.hxx:271
void CreateDdeData(ScDocument &rDoc, const OUString &rApplc, const OUString &rExtDoc) const
Create and apply the cached list of this DDE Link to the document.
Definition: xilink.cxx:412
void ReadSupbook(XclImpStream &rStrm)
Reads a SUPBOOK record.
Definition: xilink.cxx:792
void ReadCrn(XclImpStream &rStrm)
Reads a CRN record (external referenced cell).
Definition: xilink.cxx:682
XclImpLinkManager(const XclImpRoot &rRoot)
Definition: xilink.cxx:891
virtual void ConvertExternName(std::unique_ptr< ScTokenArray > &rpArray, XclImpStream &rStrm, std::size_t nFormulaLen, const OUString &rUrl, const ::std::vector< OUString > &rTabNames)
Definition: excform.cxx:1312
static SC_DLLPUBLIC OUString GetAbsDocName(const OUString &rFileName, const SfxObjectShell *pShell)
Definition: global2.cxx:284
sal_uInt16 GetCurrentIndex(sal_uInt16 nCreatedId, sal_uInt16 nMaxTabId) const
Returns the current sheet index calculated from creation index.
Definition: xilink.cxx:262
sal_uInt16 char * pName
Definition: callform.cxx:58
MS Excel 5.0, MS Excel 7.0 (95)
Definition: xlconst.hxx:36
void ReadExternname(XclImpStream &rStrm, ExcelToSc *pFormulaConv)
Reads an EXTERNNAME record and appends it to the current SUPBOOK.
Definition: xilink.cxx:809
bool GetLinkData(OUString &rApplic, OUString &rDoc) const
Tries to decode the URL to OLE or DDE link components.
Definition: xilink.cxx:714
const OUString & GetTabName(sal_uInt16 nXtiTab) const
Definition: xilink.cxx:726
int i
ScExtDocOptions & GetExtDocOptions() const
Returns the extended document options.
Definition: xlroot.cxx:419
bool IsSelfRef(sal_uInt16 nXtiIndex) const
Returns true, if the specified XTI entry contains an internal reference.
Definition: xilink.cxx:815
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
Definition: scmatrix.cxx:2984
Stores contents of an external name.
Definition: xilink.hxx:112
sal_Int16 SCCOL
Definition: types.hxx:22
bool HasFormulaTokens() const
Definition: xilink.cxx:546
double ReadDouble()
Definition: xistream.cxx:702
const XclImpXti * GetXti(sal_uInt16 nXtiIndex) const
Returns the specified XTI (link entry from BIFF8 EXTERNSHEET record).
Definition: xilink.cxx:868
svl::SharedStringPool & GetSharedStringPool()
Definition: xilink.cxx:757
bool get_flag(Type nBitField, Type nMask)
Returns true, if at least one of the bits set in nMask is set in nBitField.
Definition: ftools.hxx:73
const sal_uInt8 EXC_CACHEDVAL_BOOL
Definition: xlconst.hxx:118
void InsertScTab(SCTAB nScTab)
Inserts a Calc sheet index (increases all following sheet indexes).
Definition: xilink.cxx:231
sal_uInt32 mnStorageId
The name of the external name.
Definition: xilink.hxx:161
XclTabNameMap maTabNames
Definition: xilink.hxx:90
XclImpStream & operator>>(XclImpStream &rStrm, XclImpDffPropSet &rPropSet)
Definition: xiescher.cxx:4416
Contains cached values in a 2-dimensional array.
Definition: xihelper.hxx:334
ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
Get a cache table instance for specified table and table index.
std::vector< std::unique_ptr< XclImpSupbook > > maSupbookList
List of all XTI structures.
Definition: xilink.cxx:217
sal_uInt16 mnCol
Definition: xladdress.hxx:32
XclImpNameManager & GetNameManager() const
Returns the buffer that contains internal defined names.
Definition: xiroot.cxx:183
A 2D cell address struct with Excel column and row indexes.
Definition: xladdress.hxx:30
const OUString & GetSupbookTabName(sal_uInt16 nXti, sal_uInt16 nXtiTab) const
Definition: xilink.cxx:850
sal_uInt16 ReaduInt16()
Definition: xistream.cxx:648
ScMatValType nType
Definition: scmatrix.hxx:57
std::unique_ptr< MOper > mpMOper
Cached results of the DDE link.
Definition: xilink.hxx:158
void EnableDecryption(bool bEnable=true)
Switches usage of current decryption algorithm on/off.
Definition: xistream.cxx:521
std::vector< XclImpXti > XclImpXtiVector
Definition: xilink.cxx:213
SCCOL Col() const
Definition: address.hxx:267
const XclImpExtName * GetExternName(sal_uInt16 nXtiIndex, sal_uInt16 nExtName) const
Returns the specified external name or 0 on error.
Definition: xilink.cxx:937
XclSupbookType GetType() const
Returns the SUPBOOK record type.
Definition: xilink.cxx:104
bool GetLinkData(OUString &rApplic, OUString &rTopic, sal_uInt16 nXtiIndex) const
Tries to decode the URL of the specified XTI entry to OLE or DDE link components. ...
Definition: xilink.cxx:952
XclImpLinkMgrImplPtr mxImpl
Definition: xilink.hxx:225
const svl::SharedString & GetString() const
Only valid if ScMatrix methods indicate so!
Definition: scmatrix.hxx:60
const sal_uInt8 EXC_CACHEDVAL_DOUBLE
Definition: xlconst.hxx:116
virtual ~XclImpLinkManager() override
Definition: xilink.cxx:897
const XclImpRoot & GetRoot() const
Returns the filter root data.
Definition: xistream.hxx:294
::formula::FormulaTokenRef TokenRef
std::size_t GetRecLeft()
Returns remaining data size of the whole record without record headers.
Definition: xistream.cxx:581
OUString maName
Formula tokens for external name.
Definition: xilink.hxx:160
sal_Int32 SCROW
Definition: types.hxx:18
OUString ReadUniString(sal_uInt16 nChars, sal_uInt8 nFlags)
Reads ext.
Definition: xistream.cxx:886
const OUString & GetMacroName(sal_uInt16 nXclNameIdx) const
Returns the specified macro name (1-based) or an empty string on error.
Definition: xilink.cxx:719
bool CreateOleData(const ScDocument &rDoc, const OUString &rUrl, sal_uInt16 &rFileId, OUString &rTabName, ScRange &rRange) const
Create OLE link data.
Definition: xilink.cxx:471
XclSupbookType meType
URL of the external document (Excel mode).
Definition: xilink.cxx:134
#define OSL_ENSURE_BIFF(c)
Definition: xltools.hxx:32
void ReadSupbook(XclImpStream &rStrm)
Reads a SUPBOOK record.
Definition: xilink.cxx:906
const sal_uInt8 EXC_CACHEDVAL_STRING
Definition: xlconst.hxx:117
void Ignore(std::size_t nBytes)
Seeks forward inside the current record.
Definition: xistream.cxx:795
unsigned char sal_uInt8
sal_uInt8 ReaduInt8()
Definition: xistream.cxx:616
std::shared_ptr< Table > TableTypeRef
const OUString & GetXclUrl() const
Returns the URL of the external document.
Definition: xilink.cxx:107
void * p
std::vector< std::unique_ptr< XclImpExtName > > maExtNameList
All sheet names of the document.
Definition: xilink.cxx:132
XclBiff GetBiff() const
Returns the current BIFF version of the importer/exporter.
Definition: xlroot.hxx:141
const OUString * GetSupbookUrl(sal_uInt16 nXtiIndex) const
Definition: xilink.cxx:942
XclImpExtName(XclImpSupbook &rSupbook, XclImpStream &rStrm, XclSupbookType eSubType, ExcelToSc *pFormulaConv)
Reads the external name from the stream.
Definition: xilink.cxx:344
#define SAL_WARN(area, stream)
const XclImpExtName * GetExternName(sal_uInt16 nXtiIndex, sal_uInt16 nExtName) const
Returns the specified external name or 0 on error.
Definition: xilink.cxx:836
void(* f)(TrueTypeTable *)
SfxObjectShell * GetDocShell() const
Returns the object shell of the Calc document.
Definition: xlroot.cxx:281
SCTAB GetScTabFromXclName(const OUString &rXclTabName) const
Returns the Calc sheet index from the passed original Excel sheet name.
Definition: xilink.cxx:238
bool GetScTabRange(SCTAB &rnFirstScTab, SCTAB &rnLastScTab, sal_uInt16 nXtiIndex) const
Returns the Calc sheet index range of the specified XTI entry.
Definition: xilink.cxx:821
ScRefFlags
Definition: address.hxx:145
This class is used to import record oriented streams.
Definition: xistream.hxx:278
TokenArrayPtr mxArray
Cached values for OLE link.
Definition: xilink.hxx:159
const OUString * GetSupbookUrl(sal_uInt16 nXtiIndex) const
Returns the absolute file URL of a supporting workbook specified by the index.
Definition: xilink.cxx:842
XclImpCachedMatrixPtr mxDdeMatrix
Definition: xilink.hxx:157
Implementation of the link manager.
Definition: xilink.cxx:164
bool IsSelfRef(sal_uInt16 nXtiIndex) const
Returns true, if the specified XTI entry contains an internal reference.
Definition: xilink.cxx:926
This class stores one cached value of a cached value list (used for instance in CRN, EXTERNNAME, tArray).
Definition: xihelper.hxx:299
void CreateExtNameData(const ScDocument &rDoc, sal_uInt16 nFileId) const
Definition: xilink.cxx:420
void SvStream & rStrm
sal_uInt16 mnSBTab
Type of the supbook record.
Definition: xilink.cxx:135
Access to global data from other classes.
Definition: xiroot.hxx:126
void LoadCachedValues()
Definition: xilink.cxx:738
sal_uInt32 ReaduInt32()
Definition: xistream.cxx:684
void ReadCrn(XclImpStream &rStrm)
Reads a CRN record and appends it to the current SUPBOOK.
Definition: xilink.cxx:803
void ReadXct(XclImpStream &rStrm)
Reads an XCT record (count of following CRNs and current sheet).
Definition: xilink.cxx:676
RedlineType meType
ScfUInt16Vec maTabIdVec
All Excel sheet names with Calc sheet index.
Definition: xilink.hxx:91
aStr
Represents a defined name.
Definition: xiname.hxx:34
sal_Int16 SCTAB
Definition: types.hxx:23
const OUString & GetSupbookTabName(sal_uInt16 nXti, sal_uInt16 nXtiTab) const
Definition: xilink.cxx:947
OUString maXclUrl
All external names of the document.
Definition: xilink.cxx:133
sal_Int16 nValue
void ReadCrn(XclImpStream &rStrm)
Reads a CRN record and appends it to the current SUPBOOK.
Definition: xilink.cxx:916
void AppendXclTabName(const OUString &rXclTabName, SCTAB nScTab)
Appends an original Excel sheet name with corresponding Calc sheet index.
Definition: xilink.cxx:226
static void DecodeUrl(OUString &rUrl, OUString &rTabName, bool &rbSameWb, const XclImpRoot &rRoot, const OUString &rEncodedUrl)
Decodes an encoded external document URL with optional sheet name.
Definition: xihelper.cxx:603