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