LibreOffice Module sc (master) 1
xelink.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 <xelink.hxx>
22
23#include <algorithm>
25#include <oox/token/namespaces.hxx>
28#include <svl/numformat.hxx>
29#include <svl/zforlist.hxx>
30#include <sal/log.hxx>
31#include <document.hxx>
32#include <scextopt.hxx>
33#include <externalrefmgr.hxx>
34#include <tokenarray.hxx>
35#include <xecontent.hxx>
36#include <xeformula.hxx>
37#include <xehelper.hxx>
38#include <xllink.hxx>
39#include <xltools.hxx>
40
41#include <vector>
42#include <memory>
43#include <string_view>
44
45using ::std::unique_ptr;
46using ::std::vector;
47using ::com::sun::star::uno::Any;
48
49using namespace oox;
50
51// *** Helper classes ***
52
53// External names =============================================================
54
55namespace {
56
59class XclExpExtNameBase : public XclExpRecord, protected XclExpRoot
60{
61public:
63 explicit XclExpExtNameBase( const XclExpRoot& rRoot,
64 const OUString& rName, sal_uInt16 nFlags = 0 );
65
67 const OUString& GetName() const { return maName; }
68
69private:
71 virtual void WriteBody( XclExpStream& rStrm ) override;
74 virtual void WriteAddData( XclExpStream& rStrm );
75
76protected:
77 OUString maName;
78 XclExpStringRef mxName;
79 sal_uInt16 mnFlags;
80};
81
83class XclExpExtNameAddIn : public XclExpExtNameBase
84{
85public:
86 explicit XclExpExtNameAddIn( const XclExpRoot& rRoot, const OUString& rName );
87
88private:
90 virtual void WriteAddData( XclExpStream& rStrm ) override;
91};
92
94class XclExpExtNameDde : public XclExpExtNameBase
95{
96public:
97 explicit XclExpExtNameDde( const XclExpRoot& rRoot, const OUString& rName,
98 sal_uInt16 nFlags, const ScMatrix* pResults = nullptr );
99
100private:
102 virtual void WriteAddData( XclExpStream& rStrm ) override;
103
104private:
105 typedef std::shared_ptr< XclExpCachedMatrix > XclExpCachedMatRef;
106 XclExpCachedMatRef mxMatrix;
107};
108
109class XclExpSupbook;
110
111class XclExpExtName : public XclExpExtNameBase
112{
113public:
114 explicit XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook, const OUString& rName,
115 const ScExternalRefCache::TokenArrayRef& rArray );
116
117 virtual void SaveXml(XclExpXmlStream& rStrm) override;
118
119private:
121 virtual void WriteAddData( XclExpStream& rStrm ) override;
122
123private:
124 const XclExpSupbook& mrSupbook;
125 unique_ptr<ScTokenArray> mpArray;
126};
127
128// List of external names =====================================================
129
131class XclExpExtNameBuffer : public XclExpRecordBase, protected XclExpRoot
132{
133public:
134 explicit XclExpExtNameBuffer( const XclExpRoot& rRoot );
135
138 sal_uInt16 InsertAddIn( const OUString& rName );
140 sal_uInt16 InsertEuroTool( const OUString& rName );
143 sal_uInt16 InsertDde( std::u16string_view rApplic, std::u16string_view rTopic, const OUString& rItem );
144
145 sal_uInt16 InsertExtName( const XclExpSupbook& rSupbook, const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray );
146
148 virtual void Save( XclExpStream& rStrm ) override;
149
150 virtual void SaveXml(XclExpXmlStream& rStrm) override;
151
152private:
154 sal_uInt16 GetIndex( std::u16string_view rName ) const;
157 sal_uInt16 AppendNew( XclExpExtNameBase* pExtName );
158
160};
161
162// Cached external cells ======================================================
163
165class XclExpCrn : public XclExpRecord
166{
167public:
168 explicit XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue );
169
171 bool InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue );
172
174 virtual void SaveXml( XclExpXmlStream& rStrm ) override;
175
176private:
177 virtual void WriteBody( XclExpStream& rStrm ) override;
178
179 static void WriteBool( XclExpStream& rStrm, bool bValue );
180 static void WriteDouble( XclExpStream& rStrm, double fValue );
181 static void WriteString( XclExpStream& rStrm, const OUString& rValue );
182 static void WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode );
183 static void WriteEmpty( XclExpStream& rStrm );
184
185private:
186 typedef ::std::vector< Any > CachedValues;
187
188 CachedValues maValues;
189 SCCOL mnScCol;
190 SCROW mnScRow;
191};
192
193class XclExpCrnList;
194
197class XclExpXct : public XclExpRecordBase, protected XclExpRoot
198{
199public:
200 explicit XclExpXct( const XclExpRoot& rRoot,
201 const OUString& rTabName, sal_uInt16 nSBTab,
203
205 const XclExpString& GetTabName() const { return maTabName; }
206
208 void StoreCellRange( const ScRange& rRange );
209
210 void StoreCell_( const ScAddress& rCell );
211 void StoreCellRange_( const ScRange& rRange );
212
214 virtual void Save( XclExpStream& rStrm ) override;
215
217 virtual void SaveXml( XclExpXmlStream& rStrm ) override;
218
219private:
221 ScMarkData maUsedCells;
222 ScRange maBoundRange;
223 XclExpString maTabName;
224 sal_uInt16 mnSBTab;
225
227 bool BuildCrnList( XclExpCrnList& rCrnRecs );
228};
229
230// External documents (EXTERNSHEET/SUPBOOK), base class =======================
231
239class XclExpExternSheetBase : public XclExpRecord, protected XclExpRoot
240{
241public:
242 explicit XclExpExternSheetBase( const XclExpRoot& rRoot,
243 sal_uInt16 nRecId, sal_uInt32 nRecSize = 0 );
244
245protected:
247 XclExpExtNameBuffer& GetExtNameBuffer();
249 void WriteExtNameBuffer( XclExpStream& rStrm );
251 void WriteExtNameBufferXml( XclExpXmlStream& rStrm );
252
253protected:
254 typedef std::shared_ptr< XclExpExtNameBuffer > XclExpExtNameBfrRef;
255 XclExpExtNameBfrRef mxExtNameBfr;
256};
257
258// External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
259
263class XclExpExternSheet : public XclExpExternSheetBase
264{
265public:
267 explicit XclExpExternSheet( const XclExpRoot& rRoot, sal_Unicode cCode );
269 explicit XclExpExternSheet( const XclExpRoot& rRoot, std::u16string_view rTabName );
270
273 sal_uInt16 InsertAddIn( const OUString& rName );
274
276 virtual void Save( XclExpStream& rStrm ) override;
277
278private:
280 void Init( std::u16string_view rEncUrl );
282 virtual void WriteBody( XclExpStream& rStrm ) override;
283
284private:
285 XclExpString maTabName;
286};
287
288// External documents (SUPBOOK, BIFF8) ========================================
289
291class XclExpSupbook : public XclExpExternSheetBase
292{
293public:
295 explicit XclExpSupbook( const XclExpRoot& rRoot, sal_uInt16 nXclTabCount );
297 explicit XclExpSupbook( const XclExpRoot& rRoot );
299 explicit XclExpSupbook( const XclExpRoot& rRoot, const OUString& rUrl, XclSupbookType );
301 explicit XclExpSupbook( const XclExpRoot& rRoot, const OUString& rUrl );
303 explicit XclExpSupbook( const XclExpRoot& rRoot, const OUString& rApplic, const OUString& rTopic );
304
306 bool IsUrlLink( std::u16string_view rUrl ) const;
308 bool IsDdeLink( std::u16string_view rApplic, std::u16string_view rTopic ) const;
310 void FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry,
311 sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) const;
312
314 void StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab );
315
316 void StoreCell_( sal_uInt16 nSBTab, const ScAddress& rCell );
317 void StoreCellRange_( sal_uInt16 nSBTab, const ScRange& rRange );
318
319 sal_uInt16 GetTabIndex( const OUString& rTabName ) const;
320 sal_uInt16 GetTabCount() const;
321
323 sal_uInt16 InsertTabName( const OUString& rTabName, ScExternalRefCache::TableTypeRef const & xCacheTable );
326 sal_uInt16 InsertAddIn( const OUString& rName );
328 sal_uInt16 InsertEuroTool( const OUString& rName );
331 sal_uInt16 InsertDde( const OUString& rItem );
332
333 sal_uInt16 InsertExtName( const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray );
334
336 XclSupbookType GetType() const;
337
339 sal_uInt16 GetFileId() const;
340
342 const OUString& GetUrl() const;
343
345 virtual void Save( XclExpStream& rStrm ) override;
346
348 virtual void SaveXml( XclExpXmlStream& rStrm ) override;
349
350private:
352 const XclExpString* GetTabName( sal_uInt16 nSBTab ) const;
353
355 virtual void WriteBody( XclExpStream& rStrm ) override;
356
357private:
358 typedef XclExpRecordList< XclExpXct > XclExpXctList;
359 typedef XclExpXctList::RecordRefType XclExpXctRef;
360
361 XclExpXctList maXctList;
362 OUString maUrl;
363 OUString maDdeTopic;
364 XclExpString maUrlEncoded;
366 sal_uInt16 mnXclTabCount;
367 sal_uInt16 mnFileId;
368};
369
370// All SUPBOOKS in a document =================================================
371
375struct XclExpXti
376{
377 sal_uInt16 mnSupbook;
378 sal_uInt16 mnFirstSBTab;
379 sal_uInt16 mnLastSBTab;
380
381 explicit XclExpXti() : mnSupbook( 0 ), mnFirstSBTab( 0 ), mnLastSBTab( 0 ) {}
382 explicit XclExpXti( sal_uInt16 nSupbook, sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) :
383 mnSupbook( nSupbook ), mnFirstSBTab( nFirstSBTab ), mnLastSBTab( nLastSBTab ) {}
384
386 void Save( XclExpStream& rStrm ) const
387 { rStrm << mnSupbook << mnFirstSBTab << mnLastSBTab; }
388};
389
390bool operator==( const XclExpXti& rLeft, const XclExpXti& rRight )
391{
392 return
393 (rLeft.mnSupbook == rRight.mnSupbook) &&
394 (rLeft.mnFirstSBTab == rRight.mnFirstSBTab) &&
395 (rLeft.mnLastSBTab == rRight.mnLastSBTab);
396}
397
399class XclExpSupbookBuffer : public XclExpRecordBase, protected XclExpRoot
400{
401public:
402 explicit XclExpSupbookBuffer( const XclExpRoot& rRoot );
403
406 XclExpXti GetXti( sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
407 XclExpRefLogEntry* pRefLogEntry = nullptr ) const;
408
410 void StoreCellRange( const ScRange& rRange );
411
412 void StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell );
413 void StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange );
414
418 bool InsertAddIn(
419 sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
420 const OUString& rName );
422 bool InsertEuroTool(
423 sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
424 const OUString& rName );
428 bool InsertDde(
429 sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
430 const OUString& rApplic, const OUString& rTopic, const OUString& rItem );
431
432 bool InsertExtName(
433 sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const OUString& rUrl,
434 const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray );
435
436 XclExpXti GetXti( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
437 XclExpRefLogEntry* pRefLogEntry );
438
440 virtual void Save( XclExpStream& rStrm ) override;
441
443 virtual void SaveXml( XclExpXmlStream& rStrm ) override;
444
446 bool HasExternalReferences() const;
447
448 struct XclExpSBIndex
449 {
450 sal_uInt16 mnSupbook;
451 sal_uInt16 mnSBTab;
452 void Set( sal_uInt16 nSupbook, sal_uInt16 nSBTab )
453 { mnSupbook = nSupbook; mnSBTab = nSBTab; }
454 };
455
456private:
457 typedef XclExpRecordList< XclExpSupbook > XclExpSupbookList;
458 typedef XclExpSupbookList::RecordRefType XclExpSupbookRef;
459
460private:
465 bool GetSupbookUrl( XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex,
466 std::u16string_view rUrl ) const;
471 bool GetSupbookDde( XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex,
472 std::u16string_view rApplic, std::u16string_view rTopic ) const;
473
476 sal_uInt16 Append( XclExpSupbookRef const & xSupbook );
477
478private:
479 XclExpSupbookList maSupbookList;
480 std::vector< XclExpSBIndex >
481 maSBIndexVec;
482 sal_uInt16 mnOwnDocSB;
483 sal_uInt16 mnAddInSB;
484};
485
486}
487
488// Export link manager ========================================================
489
492{
493public:
495 virtual void FindExtSheet( sal_uInt16& rnExtSheet,
496 sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
497 SCTAB nFirstScTab, SCTAB nLastScTab,
498 XclExpRefLogEntry* pRefLogEntry ) = 0;
500 virtual sal_uInt16 FindExtSheet( sal_Unicode cCode ) = 0;
501
502 virtual void FindExtSheet( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
503 sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
504 XclExpRefLogEntry* pRefLogEntry ) = 0;
505
507 virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2, const ScAddress& rPos ) = 0;
508
509 virtual void StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rPos ) = 0;
510 virtual void StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange ) = 0;
511
513 virtual bool InsertAddIn(
514 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
515 const OUString& rName ) = 0;
517 virtual bool InsertEuroTool(
518 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
519 const OUString& rName ) = 0;
520
522 virtual bool InsertDde(
523 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
524 const OUString& rApplic, const OUString& rTopic, const OUString& rItem ) = 0;
525
526 virtual bool InsertExtName(
527 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rUrl,
528 const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray ) = 0;
529
531 virtual void Save( XclExpStream& rStrm ) = 0;
532
534 virtual void SaveXml( XclExpXmlStream& rStrm ) = 0;
535
536protected:
537 explicit XclExpLinkManagerImpl( const XclExpRoot& rRoot );
538};
539
540namespace {
541
543class XclExpLinkManagerImpl5 : public XclExpLinkManagerImpl
544{
545public:
546 explicit XclExpLinkManagerImpl5( const XclExpRoot& rRoot );
547
548 virtual void FindExtSheet( sal_uInt16& rnExtSheet,
549 sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
550 SCTAB nFirstScTab, SCTAB nLastScTab,
551 XclExpRefLogEntry* pRefLogEntry ) override;
552 virtual sal_uInt16 FindExtSheet( sal_Unicode cCode ) override;
553
554 virtual void FindExtSheet( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
555 sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
556 XclExpRefLogEntry* pRefLogEntry ) override;
557
558 virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2, const ScAddress& rPos ) override;
559
560 virtual void StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rPos ) override;
561 virtual void StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange ) override;
562
563 virtual bool InsertAddIn(
564 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
565 const OUString& rName ) override;
566
568 virtual bool InsertEuroTool(
569 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
570 const OUString& rName ) override;
571
572 virtual bool InsertDde(
573 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
574 const OUString& rApplic, const OUString& rTopic, const OUString& rItem ) override;
575
576 virtual bool InsertExtName(
577 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rUrl,
578 const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray ) override;
579
580 virtual void Save( XclExpStream& rStrm ) override;
581
582 virtual void SaveXml( XclExpXmlStream& rStrm ) override;
583
584private:
585 typedef XclExpRecordList< XclExpExternSheet > XclExpExtSheetList;
586 typedef XclExpExtSheetList::RecordRefType XclExpExtSheetRef;
587 typedef ::std::map< SCTAB, sal_uInt16 > XclExpIntTabMap;
588 typedef ::std::map< sal_Unicode, sal_uInt16 > XclExpCodeMap;
589
590private:
592 sal_uInt16 GetExtSheetCount() const;
593
595 sal_uInt16 AppendInternal( XclExpExtSheetRef const & xExtSheet );
597 void CreateInternal();
598
600 XclExpExtSheetRef GetInternal( sal_uInt16 nExtSheet );
602 XclExpExtSheetRef FindInternal( sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab, SCTAB nScTab );
604 XclExpExtSheetRef FindInternal( sal_uInt16& rnExtSheet, sal_Unicode cCode );
605
606private:
607 XclExpExtSheetList maExtSheetList;
608 XclExpIntTabMap maIntTabMap;
609 XclExpCodeMap maCodeMap;
610};
611
613class XclExpLinkManagerImpl8 : public XclExpLinkManagerImpl
614{
615public:
616 explicit XclExpLinkManagerImpl8( const XclExpRoot& rRoot );
617
618 virtual void FindExtSheet( sal_uInt16& rnExtSheet,
619 sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
620 SCTAB nFirstScTab, SCTAB nLastScTab,
621 XclExpRefLogEntry* pRefLogEntry ) override;
622 virtual sal_uInt16 FindExtSheet( sal_Unicode cCode ) override;
623
624 virtual void FindExtSheet( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
625 sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
626 XclExpRefLogEntry* pRefLogEntry ) override;
627
628 virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2, const ScAddress& rPos ) override;
629
630 virtual void StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rPos ) override;
631 virtual void StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange ) override;
632
633 virtual bool InsertAddIn(
634 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
635 const OUString& rName ) override;
637 virtual bool InsertEuroTool(
638 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
639 const OUString& rName ) override;
640
641 virtual bool InsertDde(
642 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
643 const OUString& rApplic, const OUString& rTopic, const OUString& rItem ) override;
644
645 virtual bool InsertExtName(
646 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rUrl,
647 const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray ) override;
648
649 virtual void Save( XclExpStream& rStrm ) override;
650
651 virtual void SaveXml( XclExpXmlStream& rStrm ) override;
652
653private:
656 sal_uInt16 InsertXti( const XclExpXti& rXti );
657
658private:
659
660 XclExpSupbookBuffer maSBBuffer;
661 std::vector< XclExpXti > maXtiVec;
662};
663
664}
665
666// *** Implementation ***
667
668// Excel sheet indexes ========================================================
669
670
672 XclExpRoot( rRoot ),
673 mnScCnt( 0 ),
674 mnXclCnt( 0 ),
675 mnXclExtCnt( 0 ),
676 mnXclSelCnt( 0 ),
677 mnDisplXclTab( 0 ),
678 mnFirstVisXclTab( 0 )
679{
680 ScDocument& rDoc = GetDoc();
682
683 mnScCnt = rDoc.GetTableCount();
684
685 SCTAB nScTab;
686 SCTAB nFirstVisScTab = SCTAB_INVALID; // first visible sheet
687 SCTAB nFirstExpScTab = SCTAB_INVALID; // first exported sheet
688
689 // --- initialize the flags in the index buffer ---
690
691 maTabInfoVec.resize( mnScCnt );
692 for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
693 {
694 // ignored sheets (skipped by export, with invalid Excel sheet index)
695 if( rDoc.IsScenario( nScTab ) )
696 {
698 }
699
700 // external sheets (skipped, but with valid Excel sheet index for ref's)
701 else if( rDoc.GetLinkMode( nScTab ) == ScLinkMode::VALUE )
702 {
704 }
705
706 // exported sheets
707 else
708 {
709 // sheet name
710 rDoc.GetName( nScTab, maTabInfoVec[ nScTab ].maScName );
711
712 // remember first exported sheet
713 if( nFirstExpScTab == SCTAB_INVALID )
714 nFirstExpScTab = nScTab;
715 // remember first visible exported sheet
716 if( (nFirstVisScTab == SCTAB_INVALID) && rDoc.IsVisible( nScTab ) )
717 nFirstVisScTab = nScTab;
718
719 // sheet visible (only exported sheets)
720 SetFlag( nScTab, ExcTabBufFlags::Visible, rDoc.IsVisible( nScTab ) );
721
722 // sheet selected (only exported sheets)
723 if( const ScExtTabSettings* pTabSett = rDocOpt.GetTabSettings( nScTab ) )
724 SetFlag( nScTab, ExcTabBufFlags::Selected, pTabSett->mbSelected );
725
726 // sheet mirrored (only exported sheets)
727 SetFlag( nScTab, ExcTabBufFlags::Mirrored, rDoc.IsLayoutRTL( nScTab ) );
728 }
729 }
730
731 // --- visible/selected sheets ---
732
733 SCTAB nDisplScTab = rDocOpt.GetDocSettings().mnDisplTab;
734
735 // missing viewdata at embedded XLSX OLE objects
736 if (nDisplScTab == -1 )
737 nDisplScTab = rDoc.GetVisibleTab();
738
739 // find first visible exported sheet
740 if( (nFirstVisScTab == SCTAB_INVALID) || !IsExportTab( nFirstVisScTab ) )
741 {
742 // no exportable visible sheet -> use first exportable sheet
743 nFirstVisScTab = nFirstExpScTab;
744 if( (nFirstVisScTab == SCTAB_INVALID) || !IsExportTab( nFirstVisScTab ) )
745 {
746 // no exportable sheet at all -> use active sheet and export it
747 nFirstVisScTab = nDisplScTab;
748 SetFlag( nFirstVisScTab, ExcTabBufFlags::SkipMask, false ); // clear skip flags
749 }
750 SetFlag( nFirstVisScTab, ExcTabBufFlags::Visible ); // must be visible, even if originally hidden
751 }
752
753 // find currently displayed sheet
754 if( !IsExportTab( nDisplScTab ) ) // selected sheet not exported (i.e. scenario) -> use first visible
755 nDisplScTab = nFirstVisScTab;
757
758 // number of selected sheets
759 for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
760 if( IsSelectedTab( nScTab ) )
761 ++mnXclSelCnt;
762
763 // --- calculate resulting Excel sheet indexes ---
764
766 mnFirstVisXclTab = GetXclTab( nFirstVisScTab );
767 mnDisplXclTab = GetXclTab( nDisplScTab );
768
769 // --- sorted vectors for index lookup ---
770
772}
773
775{
776 /* Check sheet index before to avoid assertion in GetFlag(). */
777 return (nScTab < mnScCnt && nScTab >= 0) && !GetFlag( nScTab, ExcTabBufFlags::SkipMask );
778}
779
781{
782 /* Check sheet index before to avoid assertion (called from formula
783 compiler also for deleted references). */
784 return (nScTab < mnScCnt && nScTab >= 0) && GetFlag( nScTab, ExcTabBufFlags::Extern );
785}
786
788{
789 return GetFlag( nScTab, ExcTabBufFlags::Visible );
790}
791
793{
794 return GetFlag( nScTab, ExcTabBufFlags::Selected );
795}
796
798{
799 OSL_ENSURE( nScTab < mnScCnt && nScTab >= 0, "XclExpTabInfo::IsActiveTab - sheet out of range" );
800 return GetXclTab( nScTab ) == mnDisplXclTab;
801}
802
804{
805 return GetFlag( nScTab, ExcTabBufFlags::Mirrored );
806}
807
808OUString XclExpTabInfo::GetScTabName( SCTAB nScTab ) const
809{
810 OSL_ENSURE( nScTab < mnScCnt && nScTab >= 0, "XclExpTabInfo::IsActiveTab - sheet out of range" );
811 return (nScTab < mnScCnt && nScTab >= 0) ? maTabInfoVec[ nScTab ].maScName : OUString();
812}
813
814sal_uInt16 XclExpTabInfo::GetXclTab( SCTAB nScTab ) const
815{
816 return (nScTab < mnScCnt && nScTab >= 0) ? maTabInfoVec[ nScTab ].mnXclTab : EXC_TAB_DELETED;
817}
818
820{
821 OSL_ENSURE( nSortedScTab < mnScCnt && nSortedScTab >= 0, "XclExpTabInfo::GetRealScTab - sheet out of range" );
822 return (nSortedScTab < mnScCnt && nSortedScTab >= 0) ? maFromSortedVec[ nSortedScTab ] : SCTAB_INVALID;
823}
824
825bool XclExpTabInfo::GetFlag( SCTAB nScTab, ExcTabBufFlags nFlags ) const
826{
827 OSL_ENSURE( nScTab < mnScCnt && nScTab >= 0, "XclExpTabInfo::GetFlag - sheet out of range" );
828 return (nScTab < mnScCnt && nScTab >= 0) && (maTabInfoVec[ nScTab ].mnFlags & nFlags);
829}
830
831void XclExpTabInfo::SetFlag( SCTAB nScTab, ExcTabBufFlags nFlags, bool bSet )
832{
833 OSL_ENSURE( nScTab < mnScCnt && nScTab >= 0, "XclExpTabInfo::SetFlag - sheet out of range" );
834 if( nScTab < mnScCnt && nScTab >= 0 )
835 {
836 if (bSet)
837 maTabInfoVec[ nScTab ].mnFlags |= nFlags;
838 else
839 maTabInfoVec[ nScTab ].mnFlags &= ~nFlags;
840 }
841}
842
844{
845 sal_uInt16 nXclTab = 0;
846 SCTAB nScTab = 0;
847
848 // --- pass 1: process regular sheets ---
849 for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
850 {
851 if( IsExportTab( nScTab ) )
852 {
853 maTabInfoVec[ nScTab ].mnXclTab = nXclTab;
854 ++nXclTab;
855 }
856 else
857 maTabInfoVec[ nScTab ].mnXclTab = EXC_TAB_DELETED;
858 }
859 mnXclCnt = nXclTab;
860
861 // --- pass 2: process external sheets (nXclTab continues) ---
862 for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
863 {
864 if( IsExternalTab( nScTab ) )
865 {
866 maTabInfoVec[ nScTab ].mnXclTab = nXclTab;
867 ++nXclTab;
868 ++mnXclExtCnt;
869 }
870 }
871
872 // result: first occur all exported sheets, followed by all external sheets
873}
874
875typedef ::std::pair< OUString, SCTAB > XclExpTabName;
876
877namespace {
878
879struct XclExpTabNameSort {
880 bool operator ()( const XclExpTabName& rArg1, const XclExpTabName& rArg2 )
881 {
882 // compare the sheet names only
883 return ScGlobal::GetCollator().compareString( rArg1.first, rArg2.first ) < 0;
884 }
885};
886
887}
888
890{
891 ScDocument& rDoc = GetDoc();
892 ::std::vector< XclExpTabName > aVec( mnScCnt );
893 SCTAB nScTab;
894
895 // fill with sheet names
896 for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
897 {
898 rDoc.GetName( nScTab, aVec[ nScTab ].first );
899 aVec[ nScTab ].second = nScTab;
900 }
901 ::std::sort( aVec.begin(), aVec.end(), XclExpTabNameSort() );
902
903 // fill index vectors from sorted sheet name vector
904 maFromSortedVec.resize( mnScCnt );
905 maToSortedVec.resize( mnScCnt );
906 for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
907 {
908 maFromSortedVec[ nScTab ] = aVec[ nScTab ].second;
909 maToSortedVec[ aVec[ nScTab ].second ] = nScTab;
910 }
911}
912
913// External names =============================================================
914
915XclExpExtNameBase::XclExpExtNameBase(
916 const XclExpRoot& rRoot, const OUString& rName, sal_uInt16 nFlags ) :
918 XclExpRoot( rRoot ),
919 maName( rName ),
920 mxName( XclExpStringHelper::CreateString( rRoot, rName, XclStrFlags::EightBitLength ) ),
921 mnFlags( nFlags )
922{
923 OSL_ENSURE( maName.getLength() <= 255, "XclExpExtNameBase::XclExpExtNameBase - string too long" );
924 SetRecSize( 6 + mxName->GetSize() );
925}
926
927void XclExpExtNameBase::WriteBody( XclExpStream& rStrm )
928{
929 rStrm << mnFlags
930 << sal_uInt32( 0 )
931 << *mxName;
932 WriteAddData( rStrm );
933}
934
935void XclExpExtNameBase::WriteAddData( XclExpStream& /*rStrm*/ )
936{
937}
938
939XclExpExtNameAddIn::XclExpExtNameAddIn( const XclExpRoot& rRoot, const OUString& rName ) :
940 XclExpExtNameBase( rRoot, rName )
941{
942 AddRecSize( 4 );
943}
944
945void XclExpExtNameAddIn::WriteAddData( XclExpStream& rStrm )
946{
947 // write a #REF! error formula
948 rStrm << sal_uInt16( 2 ) << EXC_TOKID_ERR << EXC_ERR_REF;
949}
950
951XclExpExtNameDde::XclExpExtNameDde( const XclExpRoot& rRoot,
952 const OUString& rName, sal_uInt16 nFlags, const ScMatrix* pResults ) :
953 XclExpExtNameBase( rRoot, rName, nFlags )
954{
955 if( pResults )
956 {
957 mxMatrix = std::make_shared<XclExpCachedMatrix>( *pResults );
958 AddRecSize( mxMatrix->GetSize() );
959 }
960}
961
962void XclExpExtNameDde::WriteAddData( XclExpStream& rStrm )
963{
964 if( mxMatrix )
965 mxMatrix->Save( rStrm );
966}
967
968XclExpExtName::XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook,
969 const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray ) :
970 XclExpExtNameBase( rRoot, rName ),
971 mrSupbook(rSupbook),
972 mpArray(rArray->Clone())
973{
974}
975
976void XclExpExtName::WriteAddData( XclExpStream& rStrm )
977{
978 // Write only if it only has a single token that is either a cell or cell
979 // range address. Excel just writes '02 00 1C 17' for all the other types
980 // of external names.
981
982 using namespace ::formula;
983 do
984 {
985 if (mpArray->GetLen() != 1)
986 break;
987
988 const formula::FormulaToken* p = mpArray->FirstToken();
989 if (!p->IsExternalRef())
990 break;
991
992 switch (p->GetType())
993 {
995 {
996 const ScSingleRefData& rRef = *p->GetSingleRef();
997 if (rRef.IsTabRel())
998 break;
999
1000 bool bColRel = rRef.IsColRel();
1001 bool bRowRel = rRef.IsRowRel();
1002 sal_uInt16 nCol = static_cast<sal_uInt16>(rRef.Col());
1003 sal_uInt16 nRow = static_cast<sal_uInt16>(rRef.Row());
1004 if (bColRel) nCol |= 0x4000;
1005 if (bRowRel) nCol |= 0x8000;
1006
1007 OUString aTabName = p->GetString().getString();
1008 sal_uInt16 nSBTab = mrSupbook.GetTabIndex(aTabName);
1009
1010 // size is always 9
1011 rStrm << static_cast<sal_uInt16>(9);
1012 // operator token (3A for cell reference)
1013 rStrm << static_cast<sal_uInt8>(0x3A);
1014 // cell address (Excel's address has 2 sheet IDs.)
1015 rStrm << nSBTab << nSBTab << nRow << nCol;
1016 return;
1017 }
1019 {
1020 const ScComplexRefData& rRef = *p->GetDoubleRef();
1021 const ScSingleRefData& r1 = rRef.Ref1;
1022 const ScSingleRefData& r2 = rRef.Ref2;
1023 if (r1.IsTabRel() || r2.IsTabRel())
1024 break;
1025
1026 sal_uInt16 nTab1 = r1.Tab();
1027 sal_uInt16 nTab2 = r2.Tab();
1028 bool bCol1Rel = r1.IsColRel();
1029 bool bRow1Rel = r1.IsRowRel();
1030 bool bCol2Rel = r2.IsColRel();
1031 bool bRow2Rel = r2.IsRowRel();
1032
1033 sal_uInt16 nCol1 = static_cast<sal_uInt16>(r1.Col());
1034 sal_uInt16 nCol2 = static_cast<sal_uInt16>(r2.Col());
1035 sal_uInt16 nRow1 = static_cast<sal_uInt16>(r1.Row());
1036 sal_uInt16 nRow2 = static_cast<sal_uInt16>(r2.Row());
1037 if (bCol1Rel) nCol1 |= 0x4000;
1038 if (bRow1Rel) nCol1 |= 0x8000;
1039 if (bCol2Rel) nCol2 |= 0x4000;
1040 if (bRow2Rel) nCol2 |= 0x8000;
1041
1042 OUString aTabName = p->GetString().getString();
1043 sal_uInt16 nSBTab = mrSupbook.GetTabIndex(aTabName);
1044
1045 // size is always 13 (0x0D)
1046 rStrm << static_cast<sal_uInt16>(13);
1047 // operator token (3B for area reference)
1048 rStrm << static_cast<sal_uInt8>(0x3B);
1049 // range (area) address
1050 sal_uInt16 nSBTab2 = nSBTab + nTab2 - nTab1;
1051 rStrm << nSBTab << nSBTab2 << nRow1 << nRow2 << nCol1 << nCol2;
1052 return;
1053 }
1054 default:
1055 ; // nothing
1056 }
1057 }
1058 while (false);
1059
1060 // special value for #REF! (02 00 1C 17)
1061 rStrm << static_cast<sal_uInt16>(2) << EXC_TOKID_ERR << EXC_ERR_REF;
1062}
1063
1064void XclExpExtName::SaveXml(XclExpXmlStream& rStrm)
1065{
1066 sax_fastparser::FSHelperPtr pExternalLink = rStrm.GetCurrentStream();
1067
1068 /* TODO: mpArray contains external references. It doesn't cause any problems, but it's enough
1069 to export it without the external document identifier. */
1070 if (mpArray->GetLen())
1071 {
1072 const OUString aFormula = XclXmlUtils::ToOUString(GetCompileFormulaContext(), ScAddress(0, 0, 0), mpArray.get());
1073 pExternalLink->startElement(XML_definedName,
1074 XML_name, maName.toUtf8(),
1075 XML_refersTo, aFormula.toUtf8(),
1076 XML_sheetId, nullptr);
1077 }
1078 else
1079 {
1080 pExternalLink->startElement(XML_definedName,
1081 XML_name, maName.toUtf8(),
1082 XML_refersTo, nullptr,
1083 XML_sheetId, nullptr);
1084 }
1085
1086 pExternalLink->endElement(XML_definedName);
1087}
1088
1089// List of external names =====================================================
1090
1091XclExpExtNameBuffer::XclExpExtNameBuffer( const XclExpRoot& rRoot ) :
1092 XclExpRoot( rRoot )
1093{
1094}
1095
1096sal_uInt16 XclExpExtNameBuffer::InsertAddIn( const OUString& rName )
1097{
1098 sal_uInt16 nIndex = GetIndex( rName );
1099 return nIndex ? nIndex : AppendNew( new XclExpExtNameAddIn( GetRoot(), rName ) );
1100}
1101
1102sal_uInt16 XclExpExtNameBuffer::InsertEuroTool( const OUString& rName )
1103{
1104 sal_uInt16 nIndex = GetIndex( rName );
1105 return nIndex ? nIndex : AppendNew( new XclExpExtNameBase( GetRoot(), rName ) );
1106}
1107
1108sal_uInt16 XclExpExtNameBuffer::InsertDde(
1109 std::u16string_view rApplic, std::u16string_view rTopic, const OUString& rItem )
1110{
1111 sal_uInt16 nIndex = GetIndex( rItem );
1112 if( nIndex == 0 )
1113 {
1114 size_t nPos;
1115 if( GetDoc().FindDdeLink( rApplic, rTopic, rItem, SC_DDE_IGNOREMODE, nPos ) )
1116 {
1117 // create the leading 'StdDocumentName' EXTERNNAME record
1118 if( maNameList.IsEmpty() )
1119 AppendNew( new XclExpExtNameDde(
1120 GetRoot(), "StdDocumentName", EXC_EXTN_EXPDDE_STDDOC ) );
1121
1122 // try to find DDE result array, but create EXTERNNAME record without them too
1123 const ScMatrix* pScMatrix = GetDoc().GetDdeLinkResultMatrix( nPos );
1124 nIndex = AppendNew( new XclExpExtNameDde( GetRoot(), rItem, EXC_EXTN_EXPDDE, pScMatrix ) );
1125 }
1126 }
1127 return nIndex;
1128}
1129
1130sal_uInt16 XclExpExtNameBuffer::InsertExtName( const XclExpSupbook& rSupbook,
1131 const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray )
1132{
1133 sal_uInt16 nIndex = GetIndex( rName );
1134 return nIndex ? nIndex : AppendNew( new XclExpExtName( GetRoot(), rSupbook, rName, rArray ) );
1135}
1136
1137void XclExpExtNameBuffer::Save( XclExpStream& rStrm )
1138{
1139 maNameList.Save( rStrm );
1140}
1141
1142void XclExpExtNameBuffer::SaveXml(XclExpXmlStream& rStrm)
1143{
1144 maNameList.SaveXml(rStrm);
1145}
1146
1147sal_uInt16 XclExpExtNameBuffer::GetIndex( std::u16string_view rName ) const
1148{
1149 for( size_t nPos = 0, nSize = maNameList.GetSize(); nPos < nSize; ++nPos )
1150 if( maNameList.GetRecord( nPos )->GetName() == rName )
1151 return static_cast< sal_uInt16 >( nPos + 1 );
1152 return 0;
1153}
1154
1155sal_uInt16 XclExpExtNameBuffer::AppendNew( XclExpExtNameBase* pExtName )
1156{
1157 size_t nSize = maNameList.GetSize();
1158 if( nSize < 0x7FFF )
1159 {
1160 maNameList.AppendRecord( pExtName );
1161 return static_cast< sal_uInt16 >( nSize + 1 );
1162 }
1163 return 0;
1164}
1165
1166// Cached external cells ======================================================
1167
1168XclExpCrn::XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue ) :
1170 mnScCol( nScCol ),
1171 mnScRow( nScRow )
1172{
1173 maValues.push_back( rValue );
1174}
1175
1176bool XclExpCrn::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue )
1177{
1178 if( (nScRow != mnScRow) || (nScCol != static_cast< SCCOL >( mnScCol + maValues.size() )) )
1179 return false;
1180 maValues.push_back( rValue );
1181 return true;
1182}
1183
1184void XclExpCrn::WriteBody( XclExpStream& rStrm )
1185{
1186 rStrm << static_cast< sal_uInt8 >( mnScCol + maValues.size() - 1 )
1187 << static_cast< sal_uInt8 >( mnScCol )
1188 << static_cast< sal_uInt16 >( mnScRow );
1189 for( const auto& rValue : maValues )
1190 {
1191 if( rValue.has< bool >() )
1192 WriteBool( rStrm, rValue.get< bool >() );
1193 else if( rValue.has< double >() )
1194 WriteDouble( rStrm, rValue.get< double >() );
1195 else if( rValue.has< OUString >() )
1196 WriteString( rStrm, rValue.get< OUString >() );
1197 else
1198 WriteEmpty( rStrm );
1199 }
1200}
1201
1202void XclExpCrn::WriteBool( XclExpStream& rStrm, bool bValue )
1203{
1204 rStrm << EXC_CACHEDVAL_BOOL << sal_uInt8( bValue ? 1 : 0);
1205 rStrm.WriteZeroBytes( 7 );
1206}
1207
1208void XclExpCrn::WriteDouble( XclExpStream& rStrm, double fValue )
1209{
1210 if( !std::isfinite( fValue ) )
1211 {
1212 FormulaError nScError = GetDoubleErrorValue(fValue);
1213 WriteError( rStrm, XclTools::GetXclErrorCode( nScError ) );
1214 }
1215 else
1216 {
1217 rStrm << EXC_CACHEDVAL_DOUBLE << fValue;
1218 }
1219}
1220
1221void XclExpCrn::WriteString( XclExpStream& rStrm, const OUString& rValue )
1222{
1223 rStrm << EXC_CACHEDVAL_STRING << XclExpString( rValue );
1224}
1225
1226void XclExpCrn::WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode )
1227{
1228 rStrm << EXC_CACHEDVAL_ERROR << nErrCode;
1229 rStrm.WriteZeroBytes( 7 );
1230}
1231
1232void XclExpCrn::WriteEmpty( XclExpStream& rStrm )
1233{
1235 rStrm.WriteZeroBytes( 8 );
1236}
1237
1238void XclExpCrn::SaveXml( XclExpXmlStream& rStrm )
1239{
1240 sax_fastparser::FSHelperPtr pFS = rStrm.GetCurrentStream();
1241
1242 pFS->startElement(XML_row, XML_r, OString::number(mnScRow + 1));
1243
1244 ScAddress aAdr( mnScCol, mnScRow, 0); // Tab number doesn't matter
1245 for( const auto& rValue : maValues )
1246 {
1247 bool bCloseCell = true;
1248 if( rValue.has< double >() )
1249 {
1250 double fVal = rValue.get< double >();
1251 if (std::isfinite( fVal))
1252 {
1253 // t='n' is omitted
1254 pFS->startElement(XML_cell, XML_r, XclXmlUtils::ToOString(rStrm.GetRoot().GetDoc(), aAdr));
1255 pFS->startElement(XML_v);
1256 pFS->write( fVal );
1257 }
1258 else
1259 {
1260 pFS->startElement(XML_cell, XML_r, XclXmlUtils::ToOString(rStrm.GetRoot().GetDoc(), aAdr), XML_t, "e");
1261 pFS->startElement(XML_v);
1262 pFS->write( "#VALUE!" ); // OOXTODO: support other error values
1263 }
1264 }
1265 else if( rValue.has< OUString >() )
1266 {
1267 pFS->startElement(XML_cell, XML_r, XclXmlUtils::ToOString(rStrm.GetRoot().GetDoc(), aAdr), XML_t, "str");
1268 pFS->startElement(XML_v);
1269 pFS->write( rValue.get< OUString >() );
1270 }
1271 else if( rValue.has< bool >() )
1272 {
1273 pFS->startElement(XML_cell, XML_r, XclXmlUtils::ToOString(rStrm.GetRoot().GetDoc(), aAdr), XML_t, "b");
1274 pFS->startElement(XML_v);
1275 pFS->write( rValue.get< bool >() ? "1" : "0" );
1276 }
1277 // OOXTODO: error type cell t='e'
1278 else
1279 {
1280 // Empty/blank cell not stored, only aAdr is incremented.
1281 bCloseCell = false;
1282 }
1283 if (bCloseCell)
1284 {
1285 pFS->endElement(XML_v);
1286 pFS->endElement(XML_cell);
1287 }
1288 aAdr.IncCol();
1289 }
1290
1291 pFS->endElement( XML_row);
1292}
1293
1294// Cached cells of a sheet ====================================================
1295
1296XclExpXct::XclExpXct( const XclExpRoot& rRoot, const OUString& rTabName,
1297 sal_uInt16 nSBTab, ScExternalRefCache::TableTypeRef xCacheTable ) :
1298 XclExpRoot( rRoot ),
1299 mxCacheTable(std::move( xCacheTable )),
1300 maUsedCells( rRoot.GetDoc().GetSheetLimits() ),
1301 maBoundRange( ScAddress::INITIALIZE_INVALID ),
1302 maTabName( rTabName ),
1303 mnSBTab( nSBTab )
1304{
1305}
1306
1307void XclExpXct::StoreCellRange( const ScRange& rRange )
1308{
1309 // #i70418# restrict size of external range to prevent memory overflow
1310 if( (rRange.aEnd.Col() - rRange.aStart.Col()) * (rRange.aEnd.Row() - rRange.aStart.Row()) > 1024 )
1311 return;
1312
1313 maUsedCells.SetMultiMarkArea( rRange );
1314 maBoundRange.ExtendTo( rRange );
1315}
1316
1317void XclExpXct::StoreCell_( const ScAddress& rCell )
1318{
1319 maUsedCells.SetMultiMarkArea( ScRange( rCell ) );
1320 maBoundRange.ExtendTo( ScRange( rCell ) );
1321}
1322
1323void XclExpXct::StoreCellRange_( const ScRange& rRange )
1324{
1325 maUsedCells.SetMultiMarkArea( rRange );
1326 maBoundRange.ExtendTo( rRange );
1327}
1328
1329namespace {
1330
1331class XclExpCrnList : public XclExpRecordList< XclExpCrn >
1332{
1333public:
1336 bool InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue );
1337};
1338
1339bool XclExpCrnList::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue )
1340{
1341 RecordRefType xLastRec = GetLastRecord();
1342 if( xLastRec && xLastRec->InsertValue( nScCol, nScRow, rValue ) )
1343 return true;
1344 if( GetSize() == SAL_MAX_UINT16 )
1345 return false;
1346 AppendNewRecord( new XclExpCrn( nScCol, nScRow, rValue ) );
1347 return true;
1348}
1349
1350} // namespace
1351
1352bool XclExpXct::BuildCrnList( XclExpCrnList& rCrnRecs )
1353{
1354 if( !mxCacheTable )
1355 return false;
1356
1357 /* Get the range of used rows in the cache table. This may help to
1358 optimize building the CRN record list if the cache table does not
1359 contain all referred cells, e.g. if big empty ranges are used in the
1360 formulas. */
1361 ::std::pair< SCROW, SCROW > aRowRange = mxCacheTable->getRowRange();
1362 if( aRowRange.first >= aRowRange.second )
1363 return false;
1364
1365 /* Crop the bounding range of used cells in this table to Excel limits.
1366 Return if there is no external cell inside these limits. */
1367 if( !GetAddressConverter().ValidateRange( maBoundRange, false ) )
1368 return false;
1369
1370 /* Find the resulting row range that needs to be processed. */
1371 SCROW nScRow1 = ::std::max( aRowRange.first, maBoundRange.aStart.Row() );
1372 SCROW nScRow2 = ::std::min( aRowRange.second - 1, maBoundRange.aEnd.Row() );
1373 if( nScRow1 > nScRow2 )
1374 return false;
1375
1376 /* Build and collect all CRN records before writing the XCT record. This
1377 is needed to determine the total number of CRN records which must be
1378 known when writing the XCT record (possibly encrypted, so seeking the
1379 output stream back after writing the CRN records is not an option). */
1380 SvNumberFormatter& rFormatter = GetFormatter();
1381 bool bValid = true;
1382 for( SCROW nScRow = nScRow1; bValid && (nScRow <= nScRow2); ++nScRow )
1383 {
1384 ::std::pair< SCCOL, SCCOL > aColRange = mxCacheTable->getColRange( nScRow );
1385 const SCCOL nScEnd = ::std::min( aColRange.second, GetDoc().GetSheetLimits().GetMaxColCount() );
1386 for( SCCOL nScCol = aColRange.first; bValid && (nScCol < nScEnd); ++nScCol )
1387 {
1388 if( maUsedCells.IsCellMarked( nScCol, nScRow, true ) )
1389 {
1390 sal_uInt32 nScNumFmt = 0;
1391 ScExternalRefCache::TokenRef xToken = mxCacheTable->getCell( nScCol, nScRow, &nScNumFmt );
1392 using namespace ::formula;
1393 if( xToken )
1394 switch( xToken->GetType() )
1395 {
1396 case svDouble:
1397 bValid = (rFormatter.GetType( nScNumFmt ) == SvNumFormatType::LOGICAL) ?
1398 rCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() != 0 ) ) :
1399 rCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() ) );
1400 break;
1401 case svString:
1402 // do not save empty strings (empty cells) to cache
1403 if( !xToken->GetString().isEmpty() )
1404 bValid = rCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetString().getString() ) );
1405 break;
1406 default:
1407 break;
1408 }
1409 }
1410 }
1411 }
1412 return true;
1413}
1414
1415void XclExpXct::Save( XclExpStream& rStrm )
1416{
1417 XclExpCrnList aCrnRecs;
1418 if (!BuildCrnList( aCrnRecs))
1419 return;
1420
1421 // write the XCT record and the list of CRN records
1422 rStrm.StartRecord( EXC_ID_XCT, 4 );
1423 rStrm << static_cast< sal_uInt16 >( aCrnRecs.GetSize() ) << mnSBTab;
1424 rStrm.EndRecord();
1425 aCrnRecs.Save( rStrm );
1426}
1427
1428void XclExpXct::SaveXml( XclExpXmlStream& rStrm )
1429{
1430 XclExpCrnList aCrnRecs;
1431
1432 sax_fastparser::FSHelperPtr pFS = rStrm.GetCurrentStream();
1433
1434 bool bValid = BuildCrnList( aCrnRecs);
1435 pFS->startElement(XML_sheetData, XML_sheetId, OString::number(mnSBTab));
1436 if (bValid)
1437 {
1438 // row elements
1439 aCrnRecs.SaveXml( rStrm );
1440 }
1441 pFS->endElement( XML_sheetData);
1442}
1443
1444// External documents (EXTERNSHEET/SUPBOOK), base class =======================
1445
1446XclExpExternSheetBase::XclExpExternSheetBase( const XclExpRoot& rRoot, sal_uInt16 nRecId, sal_uInt32 nRecSize ) :
1447 XclExpRecord( nRecId, nRecSize ),
1448 XclExpRoot( rRoot )
1449{
1450}
1451
1452XclExpExtNameBuffer& XclExpExternSheetBase::GetExtNameBuffer()
1453{
1454 if( !mxExtNameBfr )
1455 mxExtNameBfr = std::make_shared<XclExpExtNameBuffer>( GetRoot() );
1456 return *mxExtNameBfr;
1457}
1458
1459void XclExpExternSheetBase::WriteExtNameBuffer( XclExpStream& rStrm )
1460{
1461 if( mxExtNameBfr )
1462 mxExtNameBfr->Save( rStrm );
1463}
1464
1465void XclExpExternSheetBase::WriteExtNameBufferXml( XclExpXmlStream& rStrm )
1466{
1467 if( mxExtNameBfr )
1468 mxExtNameBfr->SaveXml( rStrm );
1469}
1470
1471// External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
1472
1473XclExpExternSheet::XclExpExternSheet( const XclExpRoot& rRoot, sal_Unicode cCode ) :
1474 XclExpExternSheetBase( rRoot, EXC_ID_EXTERNSHEET )
1475{
1476 Init( OUStringChar(cCode) );
1477}
1478
1479XclExpExternSheet::XclExpExternSheet( const XclExpRoot& rRoot, std::u16string_view rTabName ) :
1480 XclExpExternSheetBase( rRoot, EXC_ID_EXTERNSHEET )
1481{
1482 // reference to own sheet: \03<sheetname>
1483 Init(Concat2View(OUStringChar(EXC_EXTSH_TABNAME) + rTabName));
1484}
1485
1486void XclExpExternSheet::Save( XclExpStream& rStrm )
1487{
1488 // EXTERNSHEET record
1489 XclExpRecord::Save( rStrm );
1490 // EXTERNNAME records
1491 WriteExtNameBuffer( rStrm );
1492}
1493
1494void XclExpExternSheet::Init( std::u16string_view rEncUrl )
1495{
1496 OSL_ENSURE_BIFF( GetBiff() <= EXC_BIFF5 );
1497 maTabName.AssignByte( rEncUrl, GetTextEncoding(), XclStrFlags::EightBitLength );
1498 SetRecSize( maTabName.GetSize() );
1499}
1500
1501sal_uInt16 XclExpExternSheet::InsertAddIn( const OUString& rName )
1502{
1503 return GetExtNameBuffer().InsertAddIn( rName );
1504}
1505
1506void XclExpExternSheet::WriteBody( XclExpStream& rStrm )
1507{
1508 sal_uInt8 nNameSize = static_cast< sal_uInt8 >( maTabName.Len() );
1509 // special case: reference to own sheet (starting with '\03') needs wrong string length
1510 if( maTabName.GetChar( 0 ) == EXC_EXTSH_TABNAME )
1511 --nNameSize;
1512 rStrm << nNameSize;
1513 maTabName.WriteBuffer( rStrm );
1514}
1515
1516// External document (SUPBOOK, BIFF8) =========================================
1517
1518XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, sal_uInt16 nXclTabCount ) :
1519 XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
1521 mnXclTabCount( nXclTabCount ),
1522 mnFileId( 0 )
1523{
1524}
1525
1526XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot ) :
1527 XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
1529 mnXclTabCount( 1 ),
1530 mnFileId( 0 )
1531{
1532}
1533
1534XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const OUString& rUrl, XclSupbookType ) :
1535 XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK ),
1536 maUrl( rUrl ),
1537 maUrlEncoded( rUrl ),
1539 mnXclTabCount( 0 ),
1540 mnFileId( 0 )
1541{
1542 SetRecSize( 2 + maUrlEncoded.GetSize() );
1543}
1544
1545XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const OUString& rUrl ) :
1546 XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK ),
1547 maUrl( rUrl ),
1548 maUrlEncoded( XclExpUrlHelper::EncodeUrl( rRoot, rUrl ) ),
1550 mnXclTabCount( 0 ),
1551 mnFileId( 0 )
1552{
1553 SetRecSize( 2 + maUrlEncoded.GetSize() );
1554
1555 // We need to create all tables up front to ensure the correct table order.
1557 sal_uInt16 nFileId = pRefMgr->getExternalFileId( rUrl );
1558 mnFileId = nFileId + 1;
1559 ScfStringVec aTabNames;
1560 pRefMgr->getAllCachedTableNames( nFileId, aTabNames );
1561 size_t nTabIndex = 0;
1562 for( const auto& rTabName : aTabNames )
1563 {
1564 InsertTabName( rTabName, pRefMgr->getCacheTable( nFileId, nTabIndex ) );
1565 ++nTabIndex;
1566 }
1567}
1568
1569XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const OUString& rApplic, const OUString& rTopic ) :
1570 XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
1571 maUrl( rApplic ),
1572 maDdeTopic( rTopic ),
1573 maUrlEncoded( XclExpUrlHelper::EncodeDde( rApplic, rTopic ) ),
1575 mnXclTabCount( 0 ),
1576 mnFileId( 0 )
1577{
1578 SetRecSize( 2 + maUrlEncoded.GetSize() );
1579}
1580
1581bool XclExpSupbook::IsUrlLink( std::u16string_view rUrl ) const
1582{
1583 return (meType == XclSupbookType::Extern || meType == XclSupbookType::Eurotool) && (maUrl == rUrl);
1584}
1585
1586bool XclExpSupbook::IsDdeLink( std::u16string_view rApplic, std::u16string_view rTopic ) const
1587{
1588 return (meType == XclSupbookType::Special) && (maUrl == rApplic) && (maDdeTopic == rTopic);
1589}
1590
1591void XclExpSupbook::FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry,
1592 sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) const
1593{
1594 rRefLogEntry.mpUrl = maUrlEncoded.IsEmpty() ? nullptr : &maUrlEncoded;
1595 rRefLogEntry.mpFirstTab = GetTabName( nFirstSBTab );
1596 rRefLogEntry.mpLastTab = GetTabName( nLastSBTab );
1597}
1598
1599void XclExpSupbook::StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab )
1600{
1601 if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ) )
1602 pXct->StoreCellRange( rRange );
1603}
1604
1605void XclExpSupbook::StoreCell_( sal_uInt16 nSBTab, const ScAddress& rCell )
1606{
1607 if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ) )
1608 pXct->StoreCell_( rCell );
1609}
1610
1611void XclExpSupbook::StoreCellRange_( sal_uInt16 nSBTab, const ScRange& rRange )
1612{
1613 // multi-table range is not allowed!
1614 if( rRange.aStart.Tab() == rRange.aEnd.Tab() )
1615 if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ) )
1616 pXct->StoreCellRange_( rRange );
1617}
1618
1619sal_uInt16 XclExpSupbook::GetTabIndex( const OUString& rTabName ) const
1620{
1621 XclExpString aXclName(rTabName);
1622 size_t nSize = maXctList.GetSize();
1623 for (size_t i = 0; i < nSize; ++i)
1624 {
1625 XclExpXctRef aRec = maXctList.GetRecord(i);
1626 if (aXclName == aRec->GetTabName())
1627 return ulimit_cast<sal_uInt16>(i);
1628 }
1629 return EXC_NOTAB;
1630}
1631
1632sal_uInt16 XclExpSupbook::GetTabCount() const
1633{
1634 return ulimit_cast<sal_uInt16>(maXctList.GetSize());
1635}
1636
1637sal_uInt16 XclExpSupbook::InsertTabName( const OUString& rTabName, ScExternalRefCache::TableTypeRef const & xCacheTable )
1638{
1639 SAL_WARN_IF( meType != XclSupbookType::Extern, "sc.filter", "Don't insert sheet names here" );
1640 sal_uInt16 nSBTab = ulimit_cast< sal_uInt16 >( maXctList.GetSize() );
1641 XclExpXctRef xXct = new XclExpXct( GetRoot(), rTabName, nSBTab, xCacheTable );
1642 AddRecSize( xXct->GetTabName().GetSize() );
1643 maXctList.AppendRecord( xXct );
1644 return nSBTab;
1645}
1646
1647sal_uInt16 XclExpSupbook::InsertAddIn( const OUString& rName )
1648{
1649 return GetExtNameBuffer().InsertAddIn( rName );
1650}
1651
1652sal_uInt16 XclExpSupbook::InsertEuroTool( const OUString& rName )
1653{
1654 return GetExtNameBuffer().InsertEuroTool( rName );
1655}
1656
1657sal_uInt16 XclExpSupbook::InsertDde( const OUString& rItem )
1658{
1659 return GetExtNameBuffer().InsertDde( maUrl, maDdeTopic, rItem );
1660}
1661
1662sal_uInt16 XclExpSupbook::InsertExtName( const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray )
1663{
1664 return GetExtNameBuffer().InsertExtName(*this, rName, rArray);
1665}
1666
1667XclSupbookType XclExpSupbook::GetType() const
1668{
1669 return meType;
1670}
1671
1672sal_uInt16 XclExpSupbook::GetFileId() const
1673{
1674 return mnFileId;
1675}
1676
1677const OUString& XclExpSupbook::GetUrl() const
1678{
1679 return maUrl;
1680}
1681
1682void XclExpSupbook::Save( XclExpStream& rStrm )
1683{
1684 // SUPBOOK record
1685 XclExpRecord::Save( rStrm );
1686 // XCT record, CRN records
1687 maXctList.Save( rStrm );
1688 // EXTERNNAME records
1689 WriteExtNameBuffer( rStrm );
1690}
1691
1692void XclExpSupbook::SaveXml( XclExpXmlStream& rStrm )
1693{
1694 sax_fastparser::FSHelperPtr pExternalLink = rStrm.GetCurrentStream();
1695
1696 // Add relation for this stream, e.g. xl/externalLinks/_rels/externalLink1.xml.rels
1697 sal_uInt16 nLevel = 0;
1698 bool bRel = true;
1699
1700 // BuildFileName delete ../ and convert them to nLevel
1701 // but addrelation needs ../ instead of nLevel, so we have to convert it back
1702 OUString sFile = XclExpHyperlink::BuildFileName(nLevel, bRel, maUrl, GetRoot(), true);
1703 while (nLevel-- > 0)
1704 sFile = "../" + sFile;
1705
1706 OUString sId = rStrm.addRelation( pExternalLink->getOutputStream(),
1707 oox::getRelationship(Relationship::EXTERNALLINKPATH), sFile, true );
1708
1709 pExternalLink->startElement( XML_externalLink,
1710 XML_xmlns, rStrm.getNamespaceURL(OOX_NS(xls)).toUtf8());
1711
1712 pExternalLink->startElement( XML_externalBook,
1713 FSNS(XML_xmlns, XML_r), rStrm.getNamespaceURL(OOX_NS(officeRel)).toUtf8(),
1714 FSNS(XML_r, XML_id), sId.toUtf8());
1715
1716 if (!maXctList.IsEmpty())
1717 {
1718 pExternalLink->startElement(XML_sheetNames);
1719 for (size_t nPos = 0, nSize = maXctList.GetSize(); nPos < nSize; ++nPos)
1720 {
1721 pExternalLink->singleElement(XML_sheetName,
1722 XML_val, XclXmlUtils::ToOString(maXctList.GetRecord(nPos)->GetTabName()));
1723 }
1724 pExternalLink->endElement( XML_sheetNames);
1725
1726 }
1727
1728 if (mxExtNameBfr)
1729 {
1730 pExternalLink->startElement(XML_definedNames);
1731 // externalName elements
1732 WriteExtNameBufferXml( rStrm );
1733 pExternalLink->endElement(XML_definedNames);
1734 }
1735
1736 if (!maXctList.IsEmpty())
1737 {
1738 pExternalLink->startElement(XML_sheetDataSet);
1739
1740 // sheetData elements
1741 maXctList.SaveXml( rStrm );
1742
1743 pExternalLink->endElement( XML_sheetDataSet);
1744
1745 }
1746 pExternalLink->endElement( XML_externalBook);
1747 pExternalLink->endElement( XML_externalLink);
1748}
1749
1750const XclExpString* XclExpSupbook::GetTabName( sal_uInt16 nSBTab ) const
1751{
1752 XclExpXctRef xXct = maXctList.GetRecord( nSBTab );
1753 return xXct ? &xXct->GetTabName() : nullptr;
1754}
1755
1756void XclExpSupbook::WriteBody( XclExpStream& rStrm )
1757{
1758 switch( meType )
1759 {
1761 rStrm << mnXclTabCount << EXC_SUPB_SELF;
1762 break;
1766 {
1767 sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maXctList.GetSize() );
1768 rStrm << nCount << maUrlEncoded;
1769
1770 for( size_t nPos = 0, nSize = maXctList.GetSize(); nPos < nSize; ++nPos )
1771 rStrm << maXctList.GetRecord( nPos )->GetTabName();
1772 }
1773 break;
1775 rStrm << mnXclTabCount << EXC_SUPB_ADDIN;
1776 break;
1777 default:
1778 SAL_WARN( "sc.filter", "Unhandled SUPBOOK type " << meType);
1779 }
1780}
1781
1782// All SUPBOOKS in a document =================================================
1783
1784XclExpSupbookBuffer::XclExpSupbookBuffer( const XclExpRoot& rRoot ) :
1785 XclExpRoot( rRoot ),
1786 mnOwnDocSB( SAL_MAX_UINT16 ),
1787 mnAddInSB( SAL_MAX_UINT16 )
1788{
1789 XclExpTabInfo& rTabInfo = GetTabInfo();
1790 sal_uInt16 nXclCnt = rTabInfo.GetXclTabCount();
1791 sal_uInt16 nCodeCnt = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
1792 size_t nCount = nXclCnt + rTabInfo.GetXclExtTabCount();
1793
1794 OSL_ENSURE( nCount > 0, "XclExpSupbookBuffer::XclExpSupbookBuffer - no sheets to export" );
1795 if( nCount )
1796 {
1797 maSBIndexVec.resize( nCount );
1798
1799 // self-ref SUPBOOK first of list
1800 XclExpSupbookRef xSupbook = new XclExpSupbook( GetRoot(), ::std::max( nXclCnt, nCodeCnt ) );
1801 mnOwnDocSB = Append( xSupbook );
1802 for( sal_uInt16 nXclTab = 0; nXclTab < nXclCnt; ++nXclTab )
1803 maSBIndexVec[ nXclTab ].Set( mnOwnDocSB, nXclTab );
1804 }
1805}
1806
1807XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
1808 XclExpRefLogEntry* pRefLogEntry ) const
1809{
1810 XclExpXti aXti;
1811 size_t nSize = maSBIndexVec.size();
1812 if( (nFirstXclTab < nSize) && (nLastXclTab < nSize) )
1813 {
1814 // index of the SUPBOOK record
1815 aXti.mnSupbook = maSBIndexVec[ nFirstXclTab ].mnSupbook;
1816
1817 // all sheets in the same supbook?
1818 bool bSameSB = true;
1819 for( sal_uInt16 nXclTab = nFirstXclTab + 1; bSameSB && (nXclTab <= nLastXclTab); ++nXclTab )
1820 {
1821 bSameSB = maSBIndexVec[ nXclTab ].mnSupbook == aXti.mnSupbook;
1822 if( !bSameSB )
1823 nLastXclTab = nXclTab - 1;
1824 }
1825 aXti.mnFirstSBTab = maSBIndexVec[ nFirstXclTab ].mnSBTab;
1826 aXti.mnLastSBTab = maSBIndexVec[ nLastXclTab ].mnSBTab;
1827
1828 // fill external reference log entry (for change tracking)
1829 if( pRefLogEntry )
1830 {
1831 pRefLogEntry->mnFirstXclTab = nFirstXclTab;
1832 pRefLogEntry->mnLastXclTab = nLastXclTab;
1833 XclExpSupbookRef xSupbook = maSupbookList.GetRecord( aXti.mnSupbook );
1834 if( xSupbook )
1835 xSupbook->FillRefLogEntry( *pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab );
1836 }
1837 }
1838 else
1839 {
1840 // special range, i.e. for deleted sheets or add-ins
1841 aXti.mnSupbook = mnOwnDocSB;
1842 aXti.mnFirstSBTab = nFirstXclTab;
1843 aXti.mnLastSBTab = nLastXclTab;
1844 }
1845
1846 return aXti;
1847}
1848
1849void XclExpSupbookBuffer::StoreCellRange( const ScRange& rRange )
1850{
1851 sal_uInt16 nXclTab = GetTabInfo().GetXclTab( rRange.aStart.Tab() );
1852 if( nXclTab < maSBIndexVec.size() )
1853 {
1854 const XclExpSBIndex& rSBIndex = maSBIndexVec[ nXclTab ];
1855 XclExpSupbookRef xSupbook = maSupbookList.GetRecord( rSBIndex.mnSupbook );
1856 OSL_ENSURE( xSupbook , "XclExpSupbookBuffer::StoreCellRange - missing SUPBOOK record" );
1857 if( xSupbook )
1858 xSupbook->StoreCellRange( rRange, rSBIndex.mnSBTab );
1859 }
1860}
1861
1862namespace {
1863
1864class FindSBIndexEntry
1865{
1866public:
1867 explicit FindSBIndexEntry(sal_uInt16 nSupbookId, sal_uInt16 nTabId) :
1868 mnSupbookId(nSupbookId), mnTabId(nTabId) {}
1869
1870 bool operator()(const XclExpSupbookBuffer::XclExpSBIndex& r) const
1871 {
1872 return mnSupbookId == r.mnSupbook && mnTabId == r.mnSBTab;
1873 }
1874
1875private:
1876 sal_uInt16 mnSupbookId;
1877 sal_uInt16 mnTabId;
1878};
1879
1880}
1881
1882void XclExpSupbookBuffer::StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell )
1883{
1884 ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
1885 const OUString* pUrl = pRefMgr->getExternalFileName(nFileId);
1886 if (!pUrl)
1887 return;
1888
1889 XclExpSupbookRef xSupbook;
1890 sal_uInt16 nSupbookId;
1891 if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
1892 {
1893 xSupbook = new XclExpSupbook(GetRoot(), *pUrl);
1894 nSupbookId = Append(xSupbook);
1895 }
1896
1897 sal_uInt16 nSheetId = xSupbook->GetTabIndex(rTabName);
1898 if (nSheetId == EXC_NOTAB)
1899 // specified table name not found in this SUPBOOK.
1900 return;
1901
1902 FindSBIndexEntry f(nSupbookId, nSheetId);
1903 if (::std::none_of(maSBIndexVec.begin(), maSBIndexVec.end(), f))
1904 {
1905 maSBIndexVec.emplace_back();
1906 XclExpSBIndex& r = maSBIndexVec.back();
1907 r.mnSupbook = nSupbookId;
1908 r.mnSBTab = nSheetId;
1909 }
1910
1911 xSupbook->StoreCell_(nSheetId, rCell);
1912}
1913
1914void XclExpSupbookBuffer::StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange )
1915{
1916 ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
1917 const OUString* pUrl = pRefMgr->getExternalFileName(nFileId);
1918 if (!pUrl)
1919 return;
1920
1921 XclExpSupbookRef xSupbook;
1922 sal_uInt16 nSupbookId;
1923 if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
1924 {
1925 xSupbook = new XclExpSupbook(GetRoot(), *pUrl);
1926 nSupbookId = Append(xSupbook);
1927 }
1928
1929 SCTAB nTabCount = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
1930
1931 // If this is a multi-table range, get token for each table.
1932 using namespace ::formula;
1933 SCTAB aMatrixListSize = 0;
1934
1935 // This is a new'ed instance, so we must manage its life cycle here.
1936 ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, rRange, nullptr);
1937 if (!pArray)
1938 return;
1939
1940 FormulaTokenArrayPlainIterator aIter(*pArray);
1941 for (FormulaToken* p = aIter.First(); p; p = aIter.Next())
1942 {
1943 if (p->GetType() == svMatrix)
1944 ++aMatrixListSize;
1945 else if (p->GetOpCode() != ocSep)
1946 {
1947 // This is supposed to be ocSep!!!
1948 return;
1949 }
1950 }
1951
1952 if (aMatrixListSize != nTabCount)
1953 {
1954 // matrix size mismatch!
1955 return;
1956 }
1957
1958 sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
1959
1960 ScRange aRange(rRange);
1961 aRange.aStart.SetTab(0);
1962 aRange.aEnd.SetTab(0);
1963 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
1964 {
1965 sal_uInt16 nSheetId = nFirstSheetId + static_cast<sal_uInt16>(nTab);
1966 FindSBIndexEntry f(nSupbookId, nSheetId);
1967 if (::std::none_of(maSBIndexVec.begin(), maSBIndexVec.end(), f))
1968 {
1969 maSBIndexVec.emplace_back();
1970 XclExpSBIndex& r = maSBIndexVec.back();
1971 r.mnSupbook = nSupbookId;
1972 r.mnSBTab = nSheetId;
1973 }
1974
1975 xSupbook->StoreCellRange_(nSheetId, aRange);
1976 }
1977}
1978
1979bool XclExpSupbookBuffer::InsertAddIn(
1980 sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const OUString& rName )
1981{
1982 XclExpSupbookRef xSupbook;
1983 if( mnAddInSB == SAL_MAX_UINT16 )
1984 {
1985 xSupbook = new XclExpSupbook( GetRoot() );
1986 mnAddInSB = Append( xSupbook );
1987 }
1988 else
1989 xSupbook = maSupbookList.GetRecord( mnAddInSB );
1990 OSL_ENSURE( xSupbook, "XclExpSupbookBuffer::InsertAddin - missing add-in supbook" );
1991 rnSupbook = mnAddInSB;
1992 rnExtName = xSupbook->InsertAddIn( rName );
1993 return rnExtName > 0;
1994}
1995
1996bool XclExpSupbookBuffer::InsertEuroTool(
1997 sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const OUString& rName )
1998{
1999 XclExpSupbookRef xSupbook;
2000 OUString aUrl( "\001\010EUROTOOL.XLA" );
2001 if( !GetSupbookUrl( xSupbook, rnSupbook, aUrl ) )
2002 {
2003 xSupbook = new XclExpSupbook( GetRoot(), aUrl, XclSupbookType::Eurotool );
2004 rnSupbook = Append( xSupbook );
2005 }
2006 rnExtName = xSupbook->InsertEuroTool( rName );
2007 return rnExtName > 0;
2008}
2009
2010bool XclExpSupbookBuffer::InsertDde(
2011 sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
2012 const OUString& rApplic, const OUString& rTopic, const OUString& rItem )
2013{
2014 XclExpSupbookRef xSupbook;
2015 if( !GetSupbookDde( xSupbook, rnSupbook, rApplic, rTopic ) )
2016 {
2017 xSupbook = new XclExpSupbook( GetRoot(), rApplic, rTopic );
2018 rnSupbook = Append( xSupbook );
2019 }
2020 rnExtName = xSupbook->InsertDde( rItem );
2021 return rnExtName > 0;
2022}
2023
2024bool XclExpSupbookBuffer::InsertExtName(
2025 sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const OUString& rUrl,
2026 const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray )
2027{
2028 XclExpSupbookRef xSupbook;
2029 if (!GetSupbookUrl(xSupbook, rnSupbook, rUrl))
2030 {
2031 xSupbook = new XclExpSupbook(GetRoot(), rUrl);
2032 rnSupbook = Append(xSupbook);
2033 }
2034 rnExtName = xSupbook->InsertExtName(rName, rArray);
2035 return rnExtName > 0;
2036}
2037
2038XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
2039 XclExpRefLogEntry* pRefLogEntry )
2040{
2041 XclExpXti aXti(0, EXC_NOTAB, EXC_NOTAB);
2042 ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
2043 const OUString* pUrl = pRefMgr->getExternalFileName(nFileId);
2044 if (!pUrl)
2045 return aXti;
2046
2047 XclExpSupbookRef xSupbook;
2048 sal_uInt16 nSupbookId;
2049 if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
2050 {
2051 xSupbook = new XclExpSupbook(GetRoot(), *pUrl);
2052 nSupbookId = Append(xSupbook);
2053 }
2054 aXti.mnSupbook = nSupbookId;
2055
2056 sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
2057 if (nFirstSheetId == EXC_NOTAB)
2058 {
2059 // first sheet not found in SUPBOOK.
2060 return aXti;
2061 }
2062 sal_uInt16 nSheetCount = xSupbook->GetTabCount();
2063 for (sal_uInt16 i = 0; i < nXclTabSpan; ++i)
2064 {
2065 sal_uInt16 nSheetId = nFirstSheetId + i;
2066 if (nSheetId >= nSheetCount)
2067 return aXti;
2068
2069 FindSBIndexEntry f(nSupbookId, nSheetId);
2070 if (::std::none_of(maSBIndexVec.begin(), maSBIndexVec.end(), f))
2071 {
2072 maSBIndexVec.emplace_back();
2073 XclExpSBIndex& r = maSBIndexVec.back();
2074 r.mnSupbook = nSupbookId;
2075 r.mnSBTab = nSheetId;
2076 }
2077 if (i == 0)
2078 aXti.mnFirstSBTab = nSheetId;
2079 if (i == nXclTabSpan - 1)
2080 aXti.mnLastSBTab = nSheetId;
2081 }
2082
2083 if (pRefLogEntry)
2084 {
2085 pRefLogEntry->mnFirstXclTab = 0;
2086 pRefLogEntry->mnLastXclTab = 0;
2087 if (xSupbook)
2088 xSupbook->FillRefLogEntry(*pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab);
2089 }
2090
2091 return aXti;
2092}
2093
2094void XclExpSupbookBuffer::Save( XclExpStream& rStrm )
2095{
2096 maSupbookList.Save( rStrm );
2097}
2098
2099void XclExpSupbookBuffer::SaveXml( XclExpXmlStream& rStrm )
2100{
2101 // Unused external references are not saved, only kept in memory.
2102 // Those that are saved must be indexed from 1, so indexes must be reordered
2103 ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
2104 vector<sal_uInt16> aExternFileIds;
2105 for (size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos)
2106 {
2107 XclExpSupbookRef xRef(maSupbookList.GetRecord(nPos));
2108 // fileIDs are indexed from 1 in xlsx, and from 0 in ScExternalRefManager
2109 // converting between them require a -1 or +1
2110 if (xRef->GetType() == XclSupbookType::Extern)
2111 aExternFileIds.push_back(xRef->GetFileId() - 1);
2112 }
2113 if (aExternFileIds.size() > 0)
2114 pRefMgr->setSkipUnusedFileIds(aExternFileIds);
2115
2116 ::std::map< sal_uInt16, OUString > aMap;
2117 for (size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos)
2118 {
2119 XclExpSupbookRef xRef( maSupbookList.GetRecord( nPos));
2120 if (xRef->GetType() != XclSupbookType::Extern)
2121 continue; // handle only external reference (for now?)
2122
2123 sal_uInt16 nId = xRef->GetFileId();
2124 sal_uInt16 nUsedId = pRefMgr->convertFileIdToUsedFileId(nId - 1) + 1;
2125 const OUString& rUrl = xRef->GetUrl();
2126 ::std::pair< ::std::map< sal_uInt16, OUString >::iterator, bool > aInsert(
2127 aMap.insert( ::std::make_pair( nId, rUrl)));
2128 if (!aInsert.second)
2129 {
2130 SAL_WARN( "sc.filter", "XclExpSupbookBuffer::SaveXml: file ID already used: " << nId <<
2131 " wanted for " << rUrl << " and is " << (*aInsert.first).second <<
2132 (rUrl == (*aInsert.first).second ? " multiple Supbook not supported" : ""));
2133 continue;
2134 }
2135 OUString sId;
2136 sax_fastparser::FSHelperPtr pExternalLink = rStrm.CreateOutputStream(
2137 XclXmlUtils::GetStreamName( "xl/", "externalLinks/externalLink", nUsedId),
2138 XclXmlUtils::GetStreamName( nullptr, "externalLinks/externalLink", nUsedId),
2139 rStrm.GetCurrentStream()->getOutputStream(),
2140 "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml",
2141 CREATE_OFFICEDOC_RELATION_TYPE("externalLink"),
2142 &sId );
2143
2144 // externalReference entry in workbook externalReferences
2145 rStrm.GetCurrentStream()->singleElement( XML_externalReference,
2146 FSNS(XML_r, XML_id), sId.toUtf8() );
2147
2148 // Each externalBook in a separate stream.
2149 rStrm.PushStream( pExternalLink );
2150 xRef->SaveXml( rStrm );
2151 rStrm.PopStream();
2152 }
2153}
2154
2155bool XclExpSupbookBuffer::HasExternalReferences() const
2156{
2157 for (size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos)
2158 {
2159 if (maSupbookList.GetRecord( nPos)->GetType() == XclSupbookType::Extern)
2160 return true;
2161 }
2162 return false;
2163}
2164
2165bool XclExpSupbookBuffer::GetSupbookUrl(
2166 XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex, std::u16string_view rUrl ) const
2167{
2168 for( size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos )
2169 {
2170 rxSupbook = maSupbookList.GetRecord( nPos );
2171 if( rxSupbook->IsUrlLink( rUrl ) )
2172 {
2173 rnIndex = ulimit_cast< sal_uInt16 >( nPos );
2174 return true;
2175 }
2176 }
2177 return false;
2178}
2179
2180bool XclExpSupbookBuffer::GetSupbookDde( XclExpSupbookRef& rxSupbook,
2181 sal_uInt16& rnIndex, std::u16string_view rApplic, std::u16string_view rTopic ) const
2182{
2183 for( size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos )
2184 {
2185 rxSupbook = maSupbookList.GetRecord( nPos );
2186 if( rxSupbook->IsDdeLink( rApplic, rTopic ) )
2187 {
2188 rnIndex = ulimit_cast< sal_uInt16 >( nPos );
2189 return true;
2190 }
2191 }
2192 return false;
2193}
2194
2195sal_uInt16 XclExpSupbookBuffer::Append( XclExpSupbookRef const & xSupbook )
2196{
2197 maSupbookList.AppendRecord( xSupbook );
2198 return ulimit_cast< sal_uInt16 >( maSupbookList.GetSize() - 1 );
2199}
2200
2201// Export link manager ========================================================
2202
2204 XclExpRoot( rRoot )
2205{
2206}
2207
2208XclExpLinkManagerImpl5::XclExpLinkManagerImpl5( const XclExpRoot& rRoot ) :
2209 XclExpLinkManagerImpl( rRoot )
2210{
2211}
2212
2213void XclExpLinkManagerImpl5::FindExtSheet(
2214 sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
2215 SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
2216{
2217 FindInternal( rnExtSheet, rnFirstXclTab, nFirstScTab );
2218 if( (rnFirstXclTab == EXC_TAB_DELETED) || (nFirstScTab == nLastScTab) )
2219 {
2220 rnLastXclTab = rnFirstXclTab;
2221 }
2222 else
2223 {
2224 sal_uInt16 nDummyExtSheet;
2225 FindInternal( nDummyExtSheet, rnLastXclTab, nLastScTab );
2226 }
2227
2228 OSL_ENSURE( !pRefLogEntry, "XclExpLinkManagerImpl5::FindExtSheet - fill reflog entry not implemented" );
2229}
2230
2231sal_uInt16 XclExpLinkManagerImpl5::FindExtSheet( sal_Unicode cCode )
2232{
2233 sal_uInt16 nExtSheet;
2234 FindInternal( nExtSheet, cCode );
2235 return nExtSheet;
2236}
2237
2238void XclExpLinkManagerImpl5::FindExtSheet(
2239 sal_uInt16 /*nFileId*/, const OUString& /*rTabName*/, sal_uInt16 /*nXclTabSpan*/,
2240 sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnFirstSBTab*/, sal_uInt16& /*rnLastSBTab*/,
2241 XclExpRefLogEntry* /*pRefLogEntry*/ )
2242{
2243 // not implemented
2244}
2245
2246void XclExpLinkManagerImpl5::StoreCellRange( const ScSingleRefData& /*rRef1*/, const ScSingleRefData& /*rRef2*/, const ScAddress& /*rPos*/ )
2247{
2248 // not implemented
2249}
2250
2251void XclExpLinkManagerImpl5::StoreCell( sal_uInt16 /*nFileId*/, const OUString& /*rTabName*/, const ScAddress& /*rPos*/ )
2252{
2253 // not implemented
2254}
2255
2256void XclExpLinkManagerImpl5::StoreCellRange( sal_uInt16 /*nFileId*/, const OUString& /*rTabName*/, const ScRange& /*rRange*/ )
2257{
2258 // not implemented
2259}
2260
2261bool XclExpLinkManagerImpl5::InsertAddIn(
2262 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName )
2263{
2264 XclExpExtSheetRef xExtSheet = FindInternal( rnExtSheet, EXC_EXTSH_ADDIN );
2265 if( xExtSheet )
2266 {
2267 rnExtName = xExtSheet->InsertAddIn( rName );
2268 return rnExtName > 0;
2269 }
2270 return false;
2271}
2272
2273bool XclExpLinkManagerImpl5::InsertEuroTool(
2274 sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const OUString& /*rName*/ )
2275{
2276 return false;
2277}
2278
2279bool XclExpLinkManagerImpl5::InsertDde(
2280 sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/,
2281 const OUString& /*rApplic*/, const OUString& /*rTopic*/, const OUString& /*rItem*/ )
2282{
2283 // not implemented
2284 return false;
2285}
2286
2287bool XclExpLinkManagerImpl5::InsertExtName(
2288 sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const OUString& /*rUrl*/,
2289 const OUString& /*rName*/, const ScExternalRefCache::TokenArrayRef& /*rArray*/ )
2290{
2291 // not implemented
2292 return false;
2293}
2294
2295void XclExpLinkManagerImpl5::Save( XclExpStream& rStrm )
2296{
2297 if( sal_uInt16 nExtSheetCount = GetExtSheetCount() )
2298 {
2299 // EXTERNCOUNT record
2300 XclExpUInt16Record( EXC_ID_EXTERNCOUNT, nExtSheetCount ).Save( rStrm );
2301 // list of EXTERNSHEET records with EXTERNNAME, XCT, CRN records
2302 maExtSheetList.Save( rStrm );
2303 }
2304}
2305
2306void XclExpLinkManagerImpl5::SaveXml( XclExpXmlStream& /*rStrm*/ )
2307{
2308 // not applicable
2309}
2310
2311sal_uInt16 XclExpLinkManagerImpl5::GetExtSheetCount() const
2312{
2313 return static_cast< sal_uInt16 >( maExtSheetList.GetSize() );
2314}
2315
2316sal_uInt16 XclExpLinkManagerImpl5::AppendInternal( XclExpExtSheetRef const & xExtSheet )
2317{
2318 if( GetExtSheetCount() < 0x7FFF )
2319 {
2320 maExtSheetList.AppendRecord( xExtSheet );
2321 // return negated one-based EXTERNSHEET index (i.e. 0xFFFD for 3rd record)
2322 return static_cast< sal_uInt16 >( -GetExtSheetCount() );
2323 }
2324 return 0;
2325}
2326
2327void XclExpLinkManagerImpl5::CreateInternal()
2328{
2329 if( !maIntTabMap.empty() )
2330 return;
2331
2332 // create EXTERNSHEET records for all internal exported sheets
2333 XclExpTabInfo& rTabInfo = GetTabInfo();
2334 for( SCTAB nScTab = 0, nScCnt = rTabInfo.GetScTabCount(); nScTab < nScCnt; ++nScTab )
2335 {
2336 if( rTabInfo.IsExportTab( nScTab ) )
2337 {
2338 XclExpExtSheetRef xRec;
2339 if( nScTab == GetCurrScTab() )
2340 xRec = new XclExpExternSheet( GetRoot(), EXC_EXTSH_OWNTAB );
2341 else
2342 xRec = new XclExpExternSheet( GetRoot(), rTabInfo.GetScTabName( nScTab ) );
2343 maIntTabMap[ nScTab ] = AppendInternal( xRec );
2344 }
2345 }
2346}
2347
2348XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::GetInternal( sal_uInt16 nExtSheet )
2349{
2350 return maExtSheetList.GetRecord( static_cast< sal_uInt16 >( -nExtSheet - 1 ) );
2351}
2352
2353XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::FindInternal(
2354 sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab, SCTAB nScTab )
2355{
2356 // create internal EXTERNSHEET records on demand
2357 CreateInternal();
2358
2359 // try to find an EXTERNSHEET record - if not, return a "deleted sheet" reference
2360 XclExpExtSheetRef xExtSheet;
2361 XclExpIntTabMap::const_iterator aIt = maIntTabMap.find( nScTab );
2362 if( aIt == maIntTabMap.end() )
2363 {
2364 xExtSheet = FindInternal( rnExtSheet, EXC_EXTSH_OWNDOC );
2365 rnXclTab = EXC_TAB_DELETED;
2366 }
2367 else
2368 {
2369 rnExtSheet = aIt->second;
2370 xExtSheet = GetInternal( rnExtSheet );
2371 rnXclTab = GetTabInfo().GetXclTab( nScTab );
2372 }
2373 return xExtSheet;
2374}
2375
2376XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::FindInternal(
2377 sal_uInt16& rnExtSheet, sal_Unicode cCode )
2378{
2379 XclExpExtSheetRef xExtSheet;
2380 XclExpCodeMap::const_iterator aIt = maCodeMap.find( cCode );
2381 if( aIt == maCodeMap.end() )
2382 {
2383 xExtSheet = new XclExpExternSheet( GetRoot(), cCode );
2384 rnExtSheet = maCodeMap[ cCode ] = AppendInternal( xExtSheet );
2385 }
2386 else
2387 {
2388 rnExtSheet = aIt->second;
2389 xExtSheet = GetInternal( rnExtSheet );
2390 }
2391 return xExtSheet;
2392}
2393
2394XclExpLinkManagerImpl8::XclExpLinkManagerImpl8( const XclExpRoot& rRoot ) :
2395 XclExpLinkManagerImpl( rRoot ),
2396 maSBBuffer( rRoot )
2397{
2398}
2399
2400void XclExpLinkManagerImpl8::FindExtSheet(
2401 sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
2402 SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
2403{
2404 XclExpTabInfo& rTabInfo = GetTabInfo();
2405 rnFirstXclTab = rTabInfo.GetXclTab( nFirstScTab );
2406 rnLastXclTab = rTabInfo.GetXclTab( nLastScTab );
2407 rnExtSheet = InsertXti( maSBBuffer.GetXti( rnFirstXclTab, rnLastXclTab, pRefLogEntry ) );
2408}
2409
2410sal_uInt16 XclExpLinkManagerImpl8::FindExtSheet( sal_Unicode cCode )
2411{
2412 OSL_ENSURE( (cCode == EXC_EXTSH_OWNDOC) || (cCode == EXC_EXTSH_ADDIN),
2413 "XclExpLinkManagerImpl8::FindExtSheet - unknown externsheet code" );
2414 return InsertXti( maSBBuffer.GetXti( EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
2415}
2416
2417void XclExpLinkManagerImpl8::FindExtSheet(
2418 sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
2419 sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
2420 XclExpRefLogEntry* pRefLogEntry )
2421{
2422 XclExpXti aXti = maSBBuffer.GetXti(nFileId, rTabName, nXclTabSpan, pRefLogEntry);
2423 rnExtSheet = InsertXti(aXti);
2424 rnFirstSBTab = aXti.mnFirstSBTab;
2425 rnLastSBTab = aXti.mnLastSBTab;
2426}
2427
2428void XclExpLinkManagerImpl8::StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2, const ScAddress& rPos )
2429{
2430 ScAddress aAbs1 = rRef1.toAbs(GetRoot().GetDoc(), rPos);
2431 ScAddress aAbs2 = rRef2.toAbs(GetRoot().GetDoc(), rPos);
2432 if (!(!rRef1.IsDeleted() && !rRef2.IsDeleted() && (aAbs1.Tab() >= 0) && (aAbs2.Tab() >= 0)))
2433 return;
2434
2435 const XclExpTabInfo& rTabInfo = GetTabInfo();
2436 SCTAB nFirstScTab = aAbs1.Tab();
2437 SCTAB nLastScTab = aAbs2.Tab();
2438 ScRange aRange(aAbs1.Col(), aAbs1.Row(), 0, aAbs2.Col(), aAbs2.Row(), 0);
2439 for (SCTAB nScTab = nFirstScTab; nScTab <= nLastScTab; ++nScTab)
2440 {
2441 if( rTabInfo.IsExternalTab( nScTab ) )
2442 {
2443 aRange.aStart.SetTab( nScTab );
2444 aRange.aEnd.SetTab( nScTab );
2445 maSBBuffer.StoreCellRange( aRange );
2446 }
2447 }
2448}
2449
2450void XclExpLinkManagerImpl8::StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rPos )
2451{
2452 maSBBuffer.StoreCell(nFileId, rTabName, rPos);
2453}
2454
2455void XclExpLinkManagerImpl8::StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange )
2456{
2457 maSBBuffer.StoreCellRange(nFileId, rTabName, rRange);
2458}
2459
2460bool XclExpLinkManagerImpl8::InsertAddIn(
2461 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName )
2462{
2463 sal_uInt16 nSupbook;
2464 if( maSBBuffer.InsertAddIn( nSupbook, rnExtName, rName ) )
2465 {
2466 rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
2467 return true;
2468 }
2469 return false;
2470}
2471
2472bool XclExpLinkManagerImpl8::InsertEuroTool(
2473 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName )
2474{
2475 sal_uInt16 nSupbook;
2476 if( maSBBuffer.InsertEuroTool( nSupbook, rnExtName, rName ) )
2477 {
2478 rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
2479 return true;
2480 }
2481 return false;
2482}
2483
2484bool XclExpLinkManagerImpl8::InsertDde(
2485 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
2486 const OUString& rApplic, const OUString& rTopic, const OUString& rItem )
2487{
2488 sal_uInt16 nSupbook;
2489 if( maSBBuffer.InsertDde( nSupbook, rnExtName, rApplic, rTopic, rItem ) )
2490 {
2491 rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
2492 return true;
2493 }
2494 return false;
2495}
2496
2497bool XclExpLinkManagerImpl8::InsertExtName( sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
2498 const OUString& rUrl, const OUString& rName, const ScExternalRefCache::TokenArrayRef& rArray )
2499{
2500 sal_uInt16 nSupbook;
2501 if( maSBBuffer.InsertExtName( nSupbook, rnExtName, rUrl, rName, rArray ) )
2502 {
2503 rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
2504 return true;
2505 }
2506 return false;
2507}
2508
2509void XclExpLinkManagerImpl8::Save( XclExpStream& rStrm )
2510{
2511 if( maXtiVec.empty() )
2512 return;
2513
2514 // SUPBOOKs, XCTs, CRNs, EXTERNNAMEs
2515 maSBBuffer.Save( rStrm );
2516
2517 // EXTERNSHEET
2518 sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maXtiVec.size() );
2519 rStrm.StartRecord( EXC_ID_EXTERNSHEET, 2 + 6 * nCount );
2520 rStrm << nCount;
2521 rStrm.SetSliceSize( 6 );
2522 for( const auto& rXti : maXtiVec )
2523 rXti.Save( rStrm );
2524 rStrm.EndRecord();
2525}
2526
2527void XclExpLinkManagerImpl8::SaveXml( XclExpXmlStream& rStrm )
2528{
2529 if (maSBBuffer.HasExternalReferences())
2530 {
2531 sax_fastparser::FSHelperPtr pWorkbook = rStrm.GetCurrentStream();
2532 pWorkbook->startElement(XML_externalReferences);
2533
2534 // externalLink, externalBook, sheetNames, sheetDataSet, externalName
2535 maSBBuffer.SaveXml( rStrm );
2536
2537 pWorkbook->endElement( XML_externalReferences);
2538 }
2539
2540 // TODO: equivalent for EXTERNSHEET in OOXML?
2541#if 0
2542 if( !maXtiVec.empty() )
2543 {
2544 for( const auto& rXti : maXtiVec )
2545 rXti.SaveXml( rStrm );
2546 }
2547#endif
2548}
2549
2550sal_uInt16 XclExpLinkManagerImpl8::InsertXti( const XclExpXti& rXti )
2551{
2552 auto aIt = std::find(maXtiVec.begin(), maXtiVec.end(), rXti);
2553 if (aIt != maXtiVec.end())
2554 return ulimit_cast< sal_uInt16 >( std::distance(maXtiVec.begin(), aIt) );
2555 maXtiVec.push_back( rXti );
2556 return ulimit_cast< sal_uInt16 >( maXtiVec.size() - 1 );
2557}
2558
2560 XclExpRoot( rRoot )
2561{
2562 switch( GetBiff() )
2563 {
2564 case EXC_BIFF5:
2565 mxImpl = std::make_shared<XclExpLinkManagerImpl5>( rRoot );
2566 break;
2567 case EXC_BIFF8:
2568 mxImpl = std::make_shared<XclExpLinkManagerImpl8>( rRoot );
2569 break;
2570 default:
2572 }
2573}
2574
2576{
2577}
2578
2580 sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab,
2581 SCTAB nScTab, XclExpRefLogEntry* pRefLogEntry )
2582{
2583 mxImpl->FindExtSheet( rnExtSheet, rnXclTab, rnXclTab, nScTab, nScTab, pRefLogEntry );
2584}
2585
2587 sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
2588 SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
2589{
2590 mxImpl->FindExtSheet( rnExtSheet, rnFirstXclTab, rnLastXclTab, nFirstScTab, nLastScTab, pRefLogEntry );
2591}
2592
2594{
2595 return mxImpl->FindExtSheet( cCode );
2596}
2597
2598void XclExpLinkManager::FindExtSheet( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
2599 sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
2600 XclExpRefLogEntry* pRefLogEntry )
2601{
2602 mxImpl->FindExtSheet( nFileId, rTabName, nXclTabSpan, rnExtSheet, rnFirstSBTab, rnLastSBTab, pRefLogEntry );
2603}
2604
2606{
2607 mxImpl->StoreCellRange(rRef, rRef, rPos);
2608}
2609
2611{
2612 mxImpl->StoreCellRange(rRef.Ref1, rRef.Ref2, rPos);
2613}
2614
2615void XclExpLinkManager::StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rPos )
2616{
2617 mxImpl->StoreCell(nFileId, rTabName, rPos);
2618}
2619
2620void XclExpLinkManager::StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange )
2621{
2622 mxImpl->StoreCellRange(nFileId, rTabName, rRange);
2623}
2624
2626 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName )
2627{
2628 return mxImpl->InsertAddIn( rnExtSheet, rnExtName, rName );
2629}
2630
2632 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName )
2633{
2634 return mxImpl->InsertEuroTool( rnExtSheet, rnExtName, rName );
2635}
2636
2638 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
2639 const OUString& rApplic, const OUString& rTopic, const OUString& rItem )
2640{
2641 return mxImpl->InsertDde( rnExtSheet, rnExtName, rApplic, rTopic, rItem );
2642}
2643
2645 sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rUrl, const OUString& rName,
2646 const ScExternalRefCache::TokenArrayRef& rArray )
2647{
2648 return mxImpl->InsertExtName(rnExtSheet, rnExtName, rUrl, rName, rArray);
2649}
2650
2652{
2653 mxImpl->Save( rStrm );
2654}
2655
2657{
2658 mxImpl->SaveXml( rStrm );
2659}
2660
2661/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ValueVectorType maValues
SbxDimArrayRef mpArray
OUString maName
sal_Int32 compareString(const OUString &s1, const OUString &s2) const
SCTAB Tab() const
Definition: address.hxx:283
SCROW Row() const
Definition: address.hxx:274
SCCOL Col() const
Definition: address.hxx:279
SC_DLLPUBLIC bool IsScenario(SCTAB nTab) const
Definition: documen3.cxx:432
SCTAB GetVisibleTab() const
Definition: document.hxx:879
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:625
SC_DLLPUBLIC ScLinkMode GetLinkMode(SCTAB nTab) const
Definition: documen3.cxx:502
SC_DLLPUBLIC bool IsVisible(SCTAB nTab) const
Definition: document.cxx:890
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:974
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:204
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:297
Extended options held by an ScDocument containing additional settings for filters.
Definition: scextopt.hxx:77
const ScExtDocSettings & GetDocSettings() const
Definition: scextopt.cxx:170
SCTAB GetCodeNameCount() const
Definition: scextopt.cxx:195
const ScExtTabSettings * GetTabSettings(SCTAB nTab) const
Definition: scextopt.cxx:180
std::shared_ptr< Table > TableTypeRef
::formula::FormulaTokenRef TokenRef
std::shared_ptr< ScTokenArray > TokenArrayRef
sal_uInt16 getExternalFileId(const OUString &rFile)
void setSkipUnusedFileIds(std::vector< sal_uInt16 > &pExternFileIds)
sal_uInt16 convertFileIdToUsedFileId(sal_uInt16 nFileId)
Reindex external file references to skip unused files, if skipping is enabled.
ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
Get a cache table instance for specified table and table index.
const OUString * getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal=false)
It returns a pointer to the name of the URI associated with a given external file ID.
ScExternalRefCache::TokenArrayRef getDoubleRefTokens(sal_uInt16 nFileId, const OUString &rTabName, const ScRange &rRange, const ScAddress *pCurPos)
Get an array of tokens that consist of the specified external cell range.
void getAllCachedTableNames(sal_uInt16 nFileId, ::std::vector< OUString > &rTabNames) const
Returns a vector containing all (real) table names and cache tables of the specified file.
static SC_DLLPUBLIC CollatorWrapper & GetCollator()
case-insensitive collator
Definition: global.cxx:1095
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:101
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
SvNumFormatType GetType(sal_uInt32 nFIndex) const
Abstract base class for implementation classes of the link manager.
Definition: xelink.cxx:492
virtual void FindExtSheet(sal_uInt16 nFileId, const OUString &rTabName, sal_uInt16 nXclTabSpan, sal_uInt16 &rnExtSheet, sal_uInt16 &rnFirstSBTab, sal_uInt16 &rnLastSBTab, XclExpRefLogEntry *pRefLogEntry)=0
virtual void StoreCell(sal_uInt16 nFileId, const OUString &rTabName, const ScAddress &rPos)=0
virtual void StoreCellRange(const ScSingleRefData &rRef1, const ScSingleRefData &rRef2, const ScAddress &rPos)=0
Derived classes store all cells in the given range in a CRN record list.
XclExpLinkManagerImpl(const XclExpRoot &rRoot)
Definition: xelink.cxx:2203
virtual bool InsertEuroTool(sal_uInt16 &rnExtSheet, sal_uInt16 &rnExtName, const OUString &rName)=0
InsertEuroTool.
virtual void SaveXml(XclExpXmlStream &rStrm)=0
Derived classes write the entire link table to the passed OOXML stream.
virtual void StoreCellRange(sal_uInt16 nFileId, const OUString &rTabName, const ScRange &rRange)=0
virtual void Save(XclExpStream &rStrm)=0
Derived classes write the entire link table to the passed stream.
virtual void FindExtSheet(sal_uInt16 &rnExtSheet, sal_uInt16 &rnFirstXclTab, sal_uInt16 &rnLastXclTab, SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry *pRefLogEntry)=0
Derived classes search for an EXTSHEET structure for the given Calc sheet range.
virtual bool InsertAddIn(sal_uInt16 &rnExtSheet, sal_uInt16 &rnExtName, const OUString &rName)=0
Derived classes find or insert an EXTERNNAME record for an add-in function name.
virtual sal_uInt16 FindExtSheet(sal_Unicode cCode)=0
Derived classes search for a special EXTERNSHEET index for the own document.
virtual bool InsertDde(sal_uInt16 &rnExtSheet, sal_uInt16 &rnExtName, const OUString &rApplic, const OUString &rTopic, const OUString &rItem)=0
Derived classes find or insert an EXTERNNAME record for DDE links.
virtual bool InsertExtName(sal_uInt16 &rnExtSheet, sal_uInt16 &rnExtName, const OUString &rUrl, const OUString &rName, const ScExternalRefCache::TokenArrayRef &rArray)=0
bool InsertExtName(sal_uInt16 &rnExtSheet, sal_uInt16 &rnExtName, const OUString &rUrl, const OUString &rName, const ScExternalRefCache::TokenArrayRef &rArray)
Definition: xelink.cxx:2644
bool InsertDde(sal_uInt16 &rnExtSheet, sal_uInt16 &rnExtName, const OUString &rApplic, const OUString &rTopic, const OUString &rItem)
Finds or inserts an EXTERNNAME record for DDE links.
Definition: xelink.cxx:2637
void FindExtSheet(sal_uInt16 &rnExtSheet, sal_uInt16 &rnXclTab, SCTAB nScTab, XclExpRefLogEntry *pRefLogEntry=nullptr)
Searches for an EXTERNSHEET index for the given Calc sheet.
Definition: xelink.cxx:2579
void StoreCell(const ScSingleRefData &rRef, const ScAddress &rPos)
Stores the cell with the given address in a CRN record list.
Definition: xelink.cxx:2605
XclExpLinkManager(const XclExpRoot &rRoot)
Definition: xelink.cxx:2559
virtual void Save(XclExpStream &rStrm) override
Writes the entire Link table.
Definition: xelink.cxx:2651
void StoreCellRange(const ScComplexRefData &rRef, const ScAddress &rPos)
Stores all cells in the given range in a CRN record list.
Definition: xelink.cxx:2610
virtual void SaveXml(XclExpXmlStream &rStrm) override
Writes the entire Link table to OOXML.
Definition: xelink.cxx:2656
virtual ~XclExpLinkManager() override
Definition: xelink.cxx:2575
bool InsertAddIn(sal_uInt16 &rnExtSheet, sal_uInt16 &rnExtName, const OUString &rName)
Finds or inserts an EXTERNNAME record for an add-in function name.
Definition: xelink.cxx:2625
XclExpLinkMgrImplPtr mxImpl
Definition: xelink.hxx:219
bool InsertEuroTool(sal_uInt16 &rnExtSheet, sal_uInt16 &rnExtName, const OUString &rName)
InsertEuroTool.
Definition: xelink.cxx:2631
Base class for all Excel records.
Definition: xerecord.hxx:39
virtual void SaveXml(XclExpXmlStream &rStrm)
Definition: xerecord.cxx:40
virtual void Save(XclExpStream &rStrm)
Overwrite this method to do any operation while saving the record.
Definition: xerecord.cxx:36
A list of Excel record objects.
Definition: xerecord.hxx:322
rtl::Reference< RecType > RecordRefType
Definition: xerecord.hxx:324
Base class for single records with any content.
Definition: xerecord.hxx:143
virtual void Save(XclExpStream &rStrm) override
Writes the record header and calls WriteBody().
Definition: xerecord.cxx:150
virtual void WriteBody(XclExpStream &rStrm)
Writes the body of the record (without record header).
Definition: xerecord.cxx:146
Access to global data from other classes.
Definition: xeroot.hxx:113
XclExpTabInfo & GetTabInfo() const
Returns the buffer for Calc->Excel sheet index conversion.
Definition: xeroot.cxx:76
const XclExpRoot & GetRoot() const
Returns this root instance - for code readability in derived classes.
Definition: xeroot.hxx:118
This class is used to export Excel record streams.
Definition: xestream.hxx:73
This class provides methods to create an XclExpString.
Definition: xehelper.hxx:215
This class stores an unformatted or formatted string for Excel export.
Definition: xestring.hxx:48
bool IsEmpty() const
Returns true, if the string is empty.
Definition: xestring.hxx:120
Stores the correct Excel sheet index for each Calc sheet.
Definition: xelink.hxx:62
bool IsMirroredTab(SCTAB nScTab) const
Returns true, if the specified Calc sheet is displayed in right-to-left mode.
Definition: xelink.cxx:803
SCTAB GetScTabCount() const
Returns the number of Calc sheets.
Definition: xelink.hxx:89
bool GetFlag(SCTAB nScTab, ExcTabBufFlags nFlags) const
Returns true, if any of the passed flags is set for the specified Calc sheet.
Definition: xelink.cxx:825
void SetFlag(SCTAB nScTab, ExcTabBufFlags nFlags, bool bSet=true)
Sets or clears (depending on bSet) all passed flags for the specified Calc sheet.
Definition: xelink.cxx:831
SCTAB GetRealScTab(SCTAB nSortedScTab) const
Returns the Calc sheet index of the nSortedTab-th entry in the sorted sheet names list.
Definition: xelink.cxx:819
bool IsDisplayedTab(SCTAB nScTab) const
Returns true, if the specified Calc sheet is the displayed (active) sheet.
Definition: xelink.cxx:797
bool IsVisibleTab(SCTAB nScTab) const
Returns true, if the specified Calc sheet is visible and will be exported.
Definition: xelink.cxx:787
sal_uInt16 mnFirstVisXclTab
Displayed (active) sheet.
Definition: xelink.hxx:134
SCTAB mnScCnt
Array of Calc sheet index information.
Definition: xelink.hxx:129
sal_uInt16 mnXclSelCnt
Count of external link sheets.
Definition: xelink.hxx:132
sal_uInt16 GetXclTab(SCTAB nScTab) const
Returns the Excel sheet index for a given Calc sheet.
Definition: xelink.cxx:814
XclExpTabInfo(const XclExpRoot &rRoot)
Initializes the complete buffer from the current exported document.
Definition: xelink.cxx:671
std::vector< XclExpTabInfoEntry > maTabInfoVec
Definition: xelink.hxx:127
OUString GetScTabName(SCTAB nScTab) const
Returns the Calc name of the specified sheet.
Definition: xelink.cxx:808
void CalcXclIndexes()
Searches for sheets not to be exported.
Definition: xelink.cxx:843
sal_uInt16 mnDisplXclTab
Count of selected and exported sheets.
Definition: xelink.hxx:133
sal_uInt16 mnXclCnt
Count of Calc sheets.
Definition: xelink.hxx:130
ScTabVec maFromSortedVec
First visible sheet.
Definition: xelink.hxx:136
bool IsSelectedTab(SCTAB nScTab) const
Returns true, if the specified Calc sheet is selected and will be exported.
Definition: xelink.cxx:792
bool IsExternalTab(SCTAB nScTab) const
Returns true, if the specified Calc sheet is used to store external cell contents.
Definition: xelink.cxx:780
sal_uInt16 GetXclTabCount() const
Returns the number of Excel sheets to be exported.
Definition: xelink.hxx:92
bool IsExportTab(SCTAB nScTab) const
Returns true, if the specified Calc sheet will be exported.
Definition: xelink.cxx:774
sal_uInt16 GetXclExtTabCount() const
Returns the number of external linked sheets.
Definition: xelink.hxx:94
ScTabVec maToSortedVec
Sorted Calc sheet index -> real Calc sheet index.
Definition: xelink.hxx:137
sal_uInt16 mnXclExtCnt
Count of Excel sheets to be exported.
Definition: xelink.hxx:131
void CalcSortedIndexes()
Sorts the names of all tables and stores the indexes of the sorted indexes.
Definition: xelink.cxx:889
This class contains static methods to encode a file URL.
Definition: xehelper.hxx:400
ScExtDocOptions & GetExtDocOptions() const
Returns the extended document options.
Definition: xlroot.cxx:429
XclBiff GetBiff() const
Returns the current BIFF version of the importer/exporter.
Definition: xlroot.hxx:141
ScDocument & GetDoc() const
Returns reference to the destination document (import) or source document (export).
Definition: xlroot.cxx:285
static sal_uInt8 GetXclErrorCode(FormulaError nScError)
Converts a Calc error code to an Excel error code.
Definition: xltools.cxx:201
static OString ToOString(const Color &rColor)
Definition: xestream.cxx:712
static OUString ToOUString(const char *s)
Definition: xestream.cxx:788
static OUString GetStreamName(const char *sStreamDir, const char *sStream, sal_Int32 nId)
Definition: xestream.cxx:697
T * get() const
void Init()
int nCount
virtual OUString GetName() const override
const sal_uInt8 SC_DDE_IGNOREMODE
Definition: document.hxx:304
FormulaError
FormulaError GetDoubleErrorValue(double fVal)
OUString maUrl
FuncFlags mnFlags
Information about all parameters.
constexpr sal_Int32 FSNS(sal_Int32 namespc, sal_Int32 element)
::std::vector< OUString > ScfStringVec
Definition: ftools.hxx:258
sal_Int32 nIndex
void * p
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
svExternalDoubleRef
svDouble
svExternalSingleRef
svString
int i
constexpr OUStringLiteral first
void SvStream & rStrm
OUString getRelationship(Relationship eRelationship)
std::shared_ptr< FastSerializerHelper > FSHelperPtr
css::uno::Reference< css::animations::XAnimationNode > Clone(const css::uno::Reference< css::animations::XAnimationNode > &xSourceNode, const SdPage *pSource=nullptr, const SdPage *pTarget=nullptr)
HashMap_OWString_Interface aMap
sal_Int16 nId
#define CREATE_OFFICEDOC_RELATION_TYPE(ascii)
Complex reference (a range) into the sheet.
Definition: refdata.hxx:123
ScSingleRefData Ref2
Definition: refdata.hxx:125
ScSingleRefData Ref1
Definition: refdata.hxx:124
SCTAB mnDisplTab
Index of displayed sheet.
Definition: scextopt.hxx:32
Extended settings for a sheet, used in import/export filters.
Definition: scextopt.hxx:48
Single reference (one address) into the sheet.
Definition: refdata.hxx:30
SCCOL Col() const
Definition: refdata.cxx:247
bool IsDeleted() const
Definition: refdata.cxx:125
SCTAB Tab() const
Definition: refdata.cxx:254
bool IsTabRel() const
Definition: refdata.hxx:69
SCROW Row() const
Definition: refdata.cxx:240
bool IsRowRel() const
Definition: refdata.hxx:67
ScAddress toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
Definition: refdata.cxx:193
bool IsColRel() const
Definition: refdata.hxx:65
Log entry for external references in a formula, used i.e.
Definition: xeformula.hxx:32
const XclExpString * mpUrl
Definition: xeformula.hxx:33
const XclExpString * mpLastTab
Name of the first sheet.
Definition: xeformula.hxx:35
sal_uInt16 mnLastXclTab
Calc index of the first sheet.
Definition: xeformula.hxx:37
const XclExpString * mpFirstTab
URL of the document containing the first sheet.
Definition: xeformula.hxx:34
sal_uInt16 mnFirstXclTab
Name of the last sheet.
Definition: xeformula.hxx:36
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
sal_Int32 SCROW
Definition: types.hxx:17
OUString sId
RedlineType meType
XclExpValueRecord< sal_uInt16 > XclExpUInt16Record
A record containing an unsigned 16-bit value.
Definition: xerecord.hxx:247
std::shared_ptr< XclExpString > XclExpStringRef
Definition: xeroot.hxx:35
const SCTAB SCTAB_INVALID
An invalid Excel sheet index, for common use.
Definition: xlconst.hxx:73
const sal_uInt8 EXC_ERR_REF
Definition: xlconst.hxx:107
const sal_uInt16 EXC_NOTAB
Definition: xlconst.hxx:72
const sal_uInt8 EXC_CACHEDVAL_ERROR
Definition: xlconst.hxx:118
const sal_uInt8 EXC_CACHEDVAL_STRING
Definition: xlconst.hxx:116
@ EXC_BIFF5
MS Excel 4.0.
Definition: xlconst.hxx:34
@ EXC_BIFF8
MS Excel 5.0, MS Excel 7.0 (95)
Definition: xlconst.hxx:35
const sal_uInt8 EXC_CACHEDVAL_EMPTY
Definition: xlconst.hxx:114
const sal_uInt8 EXC_CACHEDVAL_BOOL
Definition: xlconst.hxx:117
const sal_uInt8 EXC_CACHEDVAL_DOUBLE
Definition: xlconst.hxx:115
const sal_uInt8 EXC_TOKID_ERR
End of a sheet reference (BIFF2-BIFF4).
Definition: xlformula.hxx:79
XclStrFlags
Flags used to specify import/export mode of strings.
Definition: xlstring.hxx:29
@ EightBitLength
Always use UCS-2 characters (default: try to compress). BIFF8 only.
bool operator==(const XclFontData &rLeft, const XclFontData &rRight)
Definition: xlstyle.cxx:518
#define OSL_ENSURE_BIFF(c)
Definition: xltools.hxx:34
#define DBG_ERROR_BIFF()
Definition: xltools.hxx:33