1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include "address.hxx"
23 #include "document.hxx"
24 #include <sfx2/objsh.hxx>
25 #include <sfx2/lnkbase.hxx>
26 #include <tools/time.hxx>
27 #include <vcl/timer.hxx>
28 #include <svl/zforlist.hxx>
29 #include <svl/lstner.hxx>
31 #include "rangelst.hxx"
32 #include <osl/mutex.hxx>
33 #include <formula/types.hxx>
34 #include <tools/solar.h>
38 #include <unordered_map>
39 #include <unordered_set>
42 #include <o3tl/sorted_vector.hxx>
43 #include <formula/ExternalReferenceHelper.hxx>
46 namespace weld
{ class Window
; }
56 class ScExternalRefLink final
: public ::sfx2::SvBaseLink
59 ScExternalRefLink(ScDocument
& rDoc
, sal_uInt16 nFileId
);
60 virtual ~ScExternalRefLink() override
;
62 virtual void Closed() override
;
63 virtual ::sfx2::SvBaseLink::UpdateResult
DataChanged(
64 const OUString
& rMimeType
, const css::uno::Any
& rValue
) override
;
65 virtual void Edit(weld::Window
* pParent
, const Link
<SvBaseLink
&,void>& rEndEditHdl
) override
;
67 void SetDoRefresh(bool b
);
70 ScExternalRefLink() = delete;
71 ScExternalRefLink(const ScExternalRefLink
&) = delete;
79 * Cache table for external reference data.
81 class ScExternalRefCache
84 typedef ::formula::FormulaTokenRef TokenRef
;
85 typedef std::shared_ptr
<ScTokenArray
> TokenArrayRef
;
92 explicit TableName(OUString aUpper
, OUString aReal
);
98 SvNumFormatType mnType
;
101 explicit CellFormat();
105 /** individual cell within cached external ref table. */
109 sal_uLong mnFmtIndex
;
111 typedef std::unordered_map
<SCCOL
, Cell
> RowDataType
;
112 typedef std::unordered_map
<SCROW
, RowDataType
> RowsDataType
;
116 * Represents a single cached table in an external document. It only
117 * stores non-empty cells; empty cells should never be stored in the data
118 * cache. Instead, cached ranges should be used to determine whether or
119 * not a cell is empty or needs fetching from the source document. If a
120 * cell's value is not stored but its address is within the cached ranges,
121 * that cell is already queried in the source document and we know it's
134 * Add cell value to the cache.
136 * @param bSetCacheRange if true, mark this cell 'cached'. This is
137 * false _only when_ adding a range of cell
138 * values, for performance reasons.
140 SC_DLLPUBLIC
void setCell(SCCOL nCol
, SCROW nRow
, TokenRef
const & pToken
, sal_uLong nFmtIndex
= 0, bool bSetCacheRange
= true);
141 SC_DLLPUBLIC TokenRef
getCell(SCCOL nCol
, SCROW nRow
, sal_uInt32
* pnFmtIndex
= nullptr) const;
142 bool hasRow( SCROW nRow
) const;
143 /** Set/clear referenced status flag only if current status is not
144 REFERENCED_PERMANENT. */
145 void setReferenced( bool bReferenced
);
146 bool isReferenced() const;
147 /// Obtain a sorted vector of rows.
148 void getAllRows(::std::vector
<SCROW
>& rRows
, SCROW nLow
, SCROW nHigh
) const;
149 void getAllRows(::std::vector
<SCROW
>& rRows
) const;
150 /// Returns the half-open range of used rows in this table. Returns [0,0) if table is empty.
151 SC_DLLPUBLIC ::std::pair
< SCROW
, SCROW
> getRowRange() const;
152 /// Obtain a sorted vector of columns.
153 void getAllCols(SCROW nRow
, ::std::vector
<SCCOL
>& rCols
, SCCOL nLow
, SCCOL nHigh
) const;
154 void getAllCols(SCROW nRow
, ::std::vector
<SCCOL
>& rCols
) const;
155 /// Returns the half-open range of used columns in the specified row. Returns [0,0) if row is empty.
156 SC_DLLPUBLIC ::std::pair
< SCCOL
, SCCOL
> getColRange( SCROW nRow
) const;
157 void getAllNumberFormats(::std::vector
<sal_uInt32
>& rNumFmts
) const;
158 bool isRangeCached(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const;
160 void setCachedCell(SCCOL nCol
, SCROW nRow
);
161 void setCachedCellRange(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
164 * Call this to mark the entire table "cached". This will prevent all
165 * future attempts to access the source document even when non-cached
166 * cells are queried. In such case, non-cached cells are treated as
167 * empty cells. Useful when loading a document with own external data
170 SC_DLLPUBLIC
void setWholeTableCached();
172 bool isInCachedRanges(SCCOL nCol
, SCROW nRow
) const;
173 TokenRef
getEmptyOrNullToken(SCCOL nCol
, SCROW nRow
) const;
174 template< typename P
>
175 void getAllRows(::std::vector
<SCROW
>& rRows
, P predicate
) const;
176 template< typename P
>
177 void getAllCols(SCROW nRow
, ::std::vector
<SCCOL
>& rCols
, P predicate
) const;
182 /** Collection of individual cached ranges. The table ranges are
183 * not used & always zero. */
184 ScRangeList maCachedRanges
;
188 typedef std::shared_ptr
<Table
> TableTypeRef
;
189 typedef std::unordered_map
< OUString
, size_t>
192 ScExternalRefCache(const ScDocument
& rDoc
);
193 ~ScExternalRefCache();
195 const OUString
* getRealTableName(sal_uInt16 nFileId
, const OUString
& rTabName
) const;
196 const OUString
* getRealRangeName(sal_uInt16 nFileId
, const OUString
& rRangeName
) const;
199 * Get a cached cell data at specified cell location.
201 * @param nFileId file ID of an external document
202 * @param rTabName sheet name
206 * @return pointer to the token instance in the cache.
208 ScExternalRefCache::TokenRef
getCellData(
209 sal_uInt16 nFileId
, const OUString
& rTabName
, SCCOL nCol
, SCROW nRow
, sal_uInt32
* pnFmtIndex
);
212 * Get a cached cell range data.
214 * @return a new token array instance. Note that <i>the caller must
215 * manage the life cycle of the returned instance</i>, which is
216 * guaranteed if the TokenArrayRef is properly used...
218 ScExternalRefCache::TokenArrayRef
getCellRangeData(
219 sal_uInt16 nFileId
, const OUString
& rTabName
, const ScRange
& rRange
);
221 ScExternalRefCache::TokenArrayRef
getRangeNameTokens(sal_uInt16 nFileId
, const OUString
& rName
);
222 void setRangeNameTokens(sal_uInt16 nFileId
, const OUString
& rName
, const TokenArrayRef
& pArray
);
223 bool isValidRangeName(sal_uInt16 nFileId
, const OUString
& rName
) const;
224 void setRangeName(sal_uInt16 nFileId
, const OUString
& rName
);
226 void setCellData(sal_uInt16 nFileId
, const OUString
& rTabName
,
227 SCCOL nCol
, SCROW nRow
, TokenRef
const & pToken
, sal_uLong nFmtIndex
);
229 struct SingleRangeData
231 /** This name must be in upper-case. */
232 OUString maTableName
;
233 ScMatrixRef mpRangeData
;
235 void setCellRangeData(sal_uInt16 nFileId
, const ScRange
& rRange
, const ::std::vector
<SingleRangeData
>& rData
,
236 const TokenArrayRef
& pArray
);
238 bool isDocInitialized(sal_uInt16 nFileId
);
239 void initializeDoc(sal_uInt16 nFileId
, const ::std::vector
<OUString
>& rTabNames
, const OUString
& rBaseName
);
240 OUString
getTableName(sal_uInt16 nFileId
, size_t nCacheId
) const;
241 void getAllTableNames(sal_uInt16 nFileId
, ::std::vector
<OUString
>& rTabNames
) const;
242 SCTAB
getTabSpan( sal_uInt16 nFileId
, const OUString
& rStartTabName
, const OUString
& rEndTabName
) const;
243 void getAllNumberFormats(::std::vector
<sal_uInt32
>& rNumFmts
) const;
246 * Set all tables of a document as referenced, used only during
248 * @returns <TRUE/> if ALL tables of ALL documents are marked.
250 bool setCacheDocReferenced( sal_uInt16 nFileId
);
253 * Set a table as referenced, used only during store-to-file.
254 * @returns <TRUE/> if ALL tables of ALL documents are marked.
256 bool setCacheTableReferenced( sal_uInt16 nFileId
, const OUString
& rTabName
, size_t nSheets
);
257 void setAllCacheTableReferencedStati( bool bReferenced
);
258 bool areAllCacheTablesReferenced() const { return maReferenced
.mbAllReferenced
;}
261 * Collect all cached non-empty cell positions, inferred directly from the
262 * cached data, not the cached range metadata stored separately in the
265 void getAllCachedDataSpans( const ScDocument
& rSrcDoc
, sal_uInt16 nFileId
, sc::ColumnSpanSet
& rSet
) const;
267 bool getSrcDocTable( const ScDocument
& rSrcDoc
, const OUString
& rTabName
, SCTAB
& rTab
, sal_uInt16 nFileId
) const;
270 struct ReferencedStatus
274 ::std::vector
<bool> maTables
;
275 bool mbAllTablesReferenced
;
276 // Initially, documents have no tables but all referenced.
277 DocReferenced() : mbAllTablesReferenced(true) {}
279 typedef ::std::vector
<DocReferenced
> DocReferencedVec
;
281 DocReferencedVec maDocs
;
282 bool mbAllReferenced
;
285 void reset( size_t nDocs
);
289 void addCacheTableToReferenced( sal_uInt16 nFileId
, size_t nIndex
);
290 void addCacheDocToReferenced( sal_uInt16 nFileId
);
293 SC_DLLPUBLIC
ScExternalRefCache::TableTypeRef
getCacheTable(sal_uInt16 nFileId
, size_t nTabIndex
) const;
294 ScExternalRefCache::TableTypeRef
getCacheTable(sal_uInt16 nFileId
, const OUString
& rTabName
, bool bCreateNew
,
295 size_t* pnIndex
, const OUString
* pExtUrl
);
298 * Clear all caches including the cache tables.
300 void clearCache(sal_uInt16 nFileId
);
303 * Clear all caches but keep the tables. All cache tables will be empty
304 * after the call, but the tables will not be removed.
306 void clearCacheTables(sal_uInt16 nFileId
);
308 // Get the doc used to pass to methods that need an ScDocument in order to do row/col validation
309 const ScDocument
& getDoc() const { return mrDoc
; }
314 size_t operator()(const ScRange
& rRange
) const
316 const ScAddress
& s
= rRange
.aStart
;
317 const ScAddress
& e
= rRange
.aEnd
;
319 hash
= hash
* 37 + s
.Tab();
320 hash
= hash
* 37 + s
.Col();
321 hash
= hash
* 37 + s
.Row();
322 hash
= hash
* 37 + e
.Tab();
323 hash
= hash
* 37 + e
.Col();
324 hash
= hash
* 37 + e
.Row();
329 typedef std::unordered_map
<OUString
, TokenArrayRef
> RangeNameMap
;
330 typedef std::unordered_map
<ScRange
, TokenArrayRef
, RangeHash
> RangeArrayMap
;
331 typedef std::unordered_map
<OUString
, OUString
> NamePairMap
;
333 /** Represents data cached for a single external document. */
336 /** The raw cache tables. */
337 ::std::vector
<TableTypeRef
> maTables
;
338 /** Table name list in correct order, in both upper- and real-case. */
339 ::std::vector
<TableName
> maTableNames
;
340 /** Table name to index map. The names must be stored upper-case. */
341 TableNameIndexMap maTableNameIndex
;
342 /** Range name cache. */
343 RangeNameMap maRangeNames
;
344 /** Token array cache for cell ranges. */
345 RangeArrayMap maRangeArrays
;
346 /** Upper- to real-case mapping for range names. */
347 NamePairMap maRealRangeNameMap
;
349 /** Either the base name that was stored as sheet name for CSV files if
350 sheet name is Sheet1, or Sheet1 name if sheet name is base name.
352 OUString maSingleTableNameAlias
;
354 bool mbInitFromSource
;
356 DocItem() : mbInitFromSource(false) {}
358 TableNameIndexMap::const_iterator
findTableNameIndex( const OUString
& rTabName
) const;
359 bool getTableDataIndex( const OUString
& rTabName
, size_t& rIndex
) const;
360 bool getSingleTableNameAlternative( OUString
& rTabName
) const;
362 typedef std::unordered_map
<sal_uInt16
, DocItem
> DocDataType
;
363 DocItem
* getDocItem(sal_uInt16 nFileId
) const;
364 DocItem
* getDocItem(std::unique_lock
<std::mutex
>& rGuard
, sal_uInt16 nFileId
) const;
367 mutable std::mutex maMtxDocs
;
368 mutable DocDataType maDocs
;
369 const ScDocument
& mrDoc
;
372 class SAL_DLLPUBLIC_RTTI ScExternalRefManager final
: public formula::ExternalReferenceHelper
, public SfxListener
376 typedef std::set
<ScFormulaCell
*> RefCellSet
;
377 typedef std::unordered_map
<sal_uInt16
, RefCellSet
> RefCellMap
;
379 enum LinkUpdateType
{ LINK_MODIFIED
, LINK_BROKEN
, OH_NO_WE_ARE_GOING_TO_DIE
};
382 * Base class for objects that need to listen to link updates. When a
383 * link to a certain external file is updated, the notify() method gets
390 virtual ~LinkListener() COVERITY_NOEXCEPT_FALSE
= 0;
391 virtual void notify(sal_uInt16 nFileId
, LinkUpdateType eType
) = 0;
395 * Use this guard when performing something from the API that might query
396 * values from external references. Interpreting formula strings is one
399 class SC_DLLPUBLIC ApiGuard
402 ApiGuard(const ScDocument
& rDoc
);
405 ScExternalRefManager
* mpMgr
;
406 bool mbOldInteractionEnabled
;
410 /** Shell instance for a source document. */
413 SfxObjectShellRef maShell
;
414 tools::Time maLastAccess
;
416 SrcShell() : maLastAccess( tools::Time::SYSTEM
) {}
419 typedef std::unordered_map
<sal_uInt16
, SrcShell
> DocShellMap
;
420 typedef std::unordered_map
<sal_uInt16
, bool> LinkedDocMap
;
422 typedef std::unordered_map
<sal_uInt16
, SvNumberFormatterMergeMap
> NumFmtMap
;
424 typedef o3tl::sorted_vector
<LinkListener
*> LinkListeners
;
425 typedef std::unordered_map
<sal_uInt16
, LinkListeners
> LinkListenerMap
;
428 /** Source document meta-data container. */
431 OUString maFileName
; /// original file name as loaded from the file.
432 OUString maRealFileName
; /// file name created from the relative name.
433 OUString maRelativeName
;
434 OUString maFilterName
;
435 OUString maFilterOptions
;
437 void maybeCreateRealFileName(std::u16string_view rOwnDocName
);
441 explicit ScExternalRefManager(ScDocument
& rDoc
);
442 virtual ~ScExternalRefManager() override
;
444 virtual OUString
getCacheTableName(sal_uInt16 nFileId
, size_t nTabIndex
) const override
;
447 * Get a cache table instance for specified table and table index. Unlike
448 * the other method that takes a table name, this method does not create a
449 * new table when a table is not available for specified index.
451 * @param nFileId file ID
452 * @param nTabIndex cache table index
454 * @return shared_ptr to the cache table instance
456 SC_DLLPUBLIC
ScExternalRefCache::TableTypeRef
getCacheTable(sal_uInt16 nFileId
, size_t nTabIndex
) const;
459 * Get a cache table instance for specified file and table name. If the
460 * table instance is not already present, it'll instantiate a new one and
461 * append it to the end of the table array. <I>It's important to be
462 * aware of this fact especially for multi-table ranges for which
463 * table orders are critical.</I>
465 * Excel filter calls this method to populate the cache table from the
466 * XCT/CRN records. ODF import calls it for cached tables for external
469 * @param nFileId file ID
470 * @param rTabName table name
471 * @param bCreateNew if true, create a new table instance if it's not
472 * already present. If false, it returns NULL if the
473 * specified table's cache doesn't exist.
474 * @param pnIndex if non-NULL pointer is passed, it stores the internal
475 * index of a cache table instance.
476 * @param pExtUrl if non-NULL and bCreateNew==true, the base name will be
477 * propagated as an alias for the first table (and removed
478 * later if further tables are created).
480 * @return shared_ptr to the cache table instance
482 SC_DLLPUBLIC
ScExternalRefCache::TableTypeRef
getCacheTable(sal_uInt16 nFileId
, const OUString
& rTabName
, bool bCreateNew
,
483 size_t* pnIndex
= nullptr, const OUString
* pExtUrl
= nullptr);
485 /** Returns a vector containing all (real) table names and cache tables of
488 The index in the returned vector corresponds to the table index used to
489 access the cache table, e.g. in getCacheTable().
491 SC_DLLPUBLIC
void getAllCachedTableNames(sal_uInt16 nFileId
, ::std::vector
<OUString
>& rTabNames
) const;
494 * Get the span (distance+sign(distance)) of two sheets of a specified
497 * @param nFileId file ID
498 * @param rStartTabName name of first sheet (sheet1)
499 * @param rEndTabName name of second sheet (sheet2)
502 * 1 if sheet2 == sheet1
503 * > 1 if sheet2 > sheet1
504 * < -1 if sheet2 < sheet1
505 * -1 if nFileId or rStartTabName not found
506 * 0 if rEndTabName not found
508 SCTAB
getCachedTabSpan(
509 sal_uInt16 nFileId
, const OUString
& rStartTabName
, const OUString
& rEndTabName
) const;
512 * Get all unique number format indices that are used in the cache tables.
513 * The retrieved indices are sorted in ascending order.
515 * @param rNumFmts (reference) all unique number format indices.
517 void getAllCachedNumberFormats(::std::vector
<sal_uInt32
>& rNumFmts
) const;
519 sal_uInt16
getExternalFileCount() const;
522 * Mark all tables as referenced that are used by any LinkListener, used
523 * only during store-to-file.
525 void markUsedByLinkListeners();
527 void markUsedExternalRefCells();
530 * Set a table as referenced, used only during store-to-file.
531 * @returns <TRUE/> if ALL tables of ALL external documents are marked.
533 bool setCacheTableReferenced( sal_uInt16 nFileId
, const OUString
& rTabName
, size_t nSheets
);
534 void setAllCacheTableReferencedStati( bool bReferenced
);
537 * @returns <TRUE/> if setAllCacheTableReferencedStati(false) was called,
538 * <FALSE/> if setAllCacheTableReferencedStati(true) was called.
540 bool isInReferenceMarking() const { return mbInReferenceMarking
; }
542 SC_DLLPUBLIC
void storeRangeNameTokens(sal_uInt16 nFileId
, const OUString
& rName
, const ScTokenArray
& rArray
);
544 ScExternalRefCache::TokenRef
getSingleRefToken(
545 sal_uInt16 nFileId
, const OUString
& rTabName
, const ScAddress
& rCell
,
546 const ScAddress
* pCurPos
, SCTAB
* pTab
, ScExternalRefCache::CellFormat
* pFmt
= nullptr);
549 * Get an array of tokens that consist of the specified external cell
552 * @param nFileId file ID for an external document
553 * @param rTabName referenced sheet name
554 * @param rRange referenced cell range
555 * @param pCurPos current cursor position to keep track of cells that
556 * reference an external data.
558 * @return shared_ptr to a token array instance. <i>The caller must not
559 * delete the instance returned by this method.</i>
561 SC_DLLPUBLIC
ScExternalRefCache::TokenArrayRef
getDoubleRefTokens(
562 sal_uInt16 nFileId
, const OUString
& rTabName
, const ScRange
& rRange
, const ScAddress
* pCurPos
);
565 * Get an array of tokens corresponding with a specified name in a
568 * @param pCurPos current cell address where this name token is used.
569 * This is purely to keep track of all cells containing
570 * external names for refreshing purposes. If this is
571 * NULL, then the cell will not be added to the list.
573 * @return shared_ptr to array of tokens composing the name
575 SC_DLLPUBLIC
ScExternalRefCache::TokenArrayRef
getRangeNameTokens(
576 sal_uInt16 nFileId
, const OUString
& rName
, const ScAddress
* pCurPos
= nullptr);
578 bool isValidRangeName(sal_uInt16 nFileId
, const OUString
& rName
);
580 OUString
getOwnDocumentName() const;
581 bool isOwnDocument(std::u16string_view rFile
) const;
584 * Takes a flat file name, and convert it to an absolute URL path. An
585 * absolute URL path begins with 'file:///.
587 * @param rFile file name to convert
589 SC_DLLPUBLIC
void convertToAbsName(OUString
& rFile
) const;
590 SC_DLLPUBLIC sal_uInt16
getExternalFileId(const OUString
& rFile
);
593 * It returns a pointer to the name of the URI associated with a given
594 * external file ID. In case the original document has moved, it returns
595 * a URI adjusted for the relocation.
597 * @param nFileId file ID for an external document
598 * @param bForceOriginal If true, it always returns the original document
599 * URI even if the referring document has relocated.
600 * If false, it returns a URI adjusted for
601 * relocated document.
603 * @return const OUString* external document URI.
605 SC_DLLPUBLIC
const OUString
* getExternalFileName(sal_uInt16 nFileId
, bool bForceOriginal
= false);
608 * Reindex external file references to skip unused files, if skipping is enabled.
610 SC_DLLPUBLIC sal_uInt16
convertFileIdToUsedFileId(sal_uInt16 nFileId
);
611 SC_DLLPUBLIC
void setSkipUnusedFileIds(std::vector
<sal_uInt16
>& pExternFileIds
);
612 SC_DLLPUBLIC
void disableSkipUnusedFileIds();
615 * Get all cached external file names as an array. Array indices of the
616 * returned name array correspond with external file ID's.
618 std::vector
<OUString
> getAllCachedExternalFileNames() const;
620 bool hasExternalFile(sal_uInt16 nFileId
) const;
621 bool hasExternalFile(const OUString
& rFile
) const;
622 const SrcFileData
* getExternalFileData(sal_uInt16 nFileId
) const;
624 const OUString
* getRealTableName(sal_uInt16 nFileId
, const OUString
& rTabName
) const;
625 const OUString
* getRealRangeName(sal_uInt16 nFileId
, const OUString
& rRangeName
) const;
626 void clearCache(sal_uInt16 nFileId
);
627 bool refreshSrcDocument(sal_uInt16 nFileId
);
628 void breakLink(sal_uInt16 nFileId
);
629 void switchSrcFile(sal_uInt16 nFileId
, const OUString
& rNewFile
, const OUString
& rNewFilter
);
632 * Set a relative file path for the specified file ID. Note that the
633 * caller must ensure that the passed URL is a valid relative URL.
635 * @param nFileId file ID for an external document
636 * @param rRelUrl relative URL
638 void setRelativeFileName(sal_uInt16 nFileId
, const OUString
& rRelUrl
);
641 * Set the filter name and options if any for a given source document.
642 * These values get reset when the source document ever gets reloaded.
648 void setFilterData(sal_uInt16 nFileId
, const OUString
& rFilterName
, const OUString
& rOptions
);
652 bool hasExternalData() const;
655 * Re-generates relative names for all stored source files. This is
656 * necessary when exporting to an ods document, to ensure that all source
657 * files have their respective relative names for xlink:href export.
659 * @param rBaseFileUrl Absolute URL of the content.xml fragment of the
660 * document being exported.
662 void resetSrcFileData(const OUString
& rBaseFileUrl
);
665 * Replace the original URL with the real URL that was generated from the relative URL.
667 void updateAbsAfterLoad();
670 * Stop tracking a specific formula cell.
672 * @param pCell pointer to cell that formerly contained external
675 void removeRefCell(ScFormulaCell
* pCell
);
678 * Register a new link listener to a specified external document. Note
679 * that the caller is responsible for managing the life cycle of the
682 void addLinkListener(sal_uInt16 nFileId
, LinkListener
* pListener
);
685 * Remove an existing link listener. Note that removing a listener
686 * pointer here does not delete the listener object instance.
688 void removeLinkListener(sal_uInt16 nFileId
, LinkListener
* pListener
);
690 void removeLinkListener(LinkListener
* pListener
);
693 * Notify all listeners that are listening to a specified external
696 * @param nFileId file ID for an external document.
698 void notifyAllLinkListeners(sal_uInt16 nFileId
, LinkUpdateType eType
);
701 * Check if the file specified by the path is a legitimate file that
702 * exists & can be loaded.
704 bool isFileLoadable(const OUString
& rFile
) const;
706 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
) override
;
709 * If we still contain unsaved files we should warn the user before saving
711 * @return true if the document still contains references to an unsaved file
713 bool containsUnsavedReferences() const { return !maUnsavedDocShells
.empty(); }
715 void insertRefCell(sal_uInt16 nFileId
, const ScAddress
& rCell
);
717 * Add a cell to reference the same files as the template cell.
719 void insertRefCellFromTemplate( ScFormulaCell
* pTemplateCell
, ScFormulaCell
* pCell
);
721 SC_DLLPUBLIC
bool hasCellExternalReference(const ScAddress
& rCell
);
723 void enableDocTimer( bool bEnable
);
725 /** Add all known external files to the LinkManager. */
726 SC_DLLPUBLIC
void addFilesToLinkManager();
729 ScExternalRefManager(const ScExternalRefManager
&) = delete;
731 void refreshAllRefCells(sal_uInt16 nFileId
);
733 void fillCellFormat(sal_uLong nFmtIndex
, ScExternalRefCache::CellFormat
* pFmt
) const;
735 bool getSrcDocTable( const ScDocument
& rSrcDoc
, const OUString
& rTabName
, SCTAB
& rTab
, sal_uInt16 nFileId
) const;
737 ScExternalRefCache::TokenRef
getSingleRefTokenFromSrcDoc(
738 sal_uInt16 nFileId
, ScDocument
& rSrcDoc
, const ScAddress
& rPos
,
739 ScExternalRefCache::CellFormat
* pFmt
);
742 * Retrieve a range token array from a source document instance.
744 * @param rSrcDoc reference to the source document instance.
745 * @param rTabName name of the first table.
746 * @param rRange range specified. Upon successful retrieval, this range
747 * gets modified to contain the correct table IDs, and in
748 * case the range is larger than the data area of the source
749 * document, it gets reduced to the data area.
750 * @param rCacheData an array of structs, with each struct containing the
751 * table name and the data in the specified range.
753 * @return range token array
755 ScExternalRefCache::TokenArrayRef
getDoubleRefTokensFromSrcDoc(
756 const ScDocument
& rSrcDoc
, const OUString
& rTabName
, ScRange
& rRange
,
757 ::std::vector
<ScExternalRefCache::SingleRangeData
>& rCacheData
);
760 * Retrieve range name token array from a source document instance.
762 * @param nFileId file ID of the source document.
763 * @param rSrcDoc reference to the source document instance
764 * @param rName range name to retrieve. Note that the range name lookup
765 * is case <i>in</i>-sensitive, and upon successful retrieval
766 * of the range name array, this name gets updated to the
767 * actual range name with the correct casing.
769 * @return range name token array
771 static ScExternalRefCache::TokenArrayRef
getRangeNameTokensFromSrcDoc(
772 sal_uInt16 nFileId
, const ScDocument
& rSrcDoc
, OUString
& rName
);
774 ScDocument
* getInMemorySrcDocument(sal_uInt16 nFileId
);
775 ScDocument
* getSrcDocument(sal_uInt16 nFileId
);
776 SfxObjectShellRef
loadSrcDocument(sal_uInt16 nFileId
, OUString
& rFilter
);
779 * Caller must ensure that the passed shell is not already stored.
781 ScDocument
& cacheNewDocShell( sal_uInt16 nFileId
, SrcShell
& rSrcShell
);
783 void maybeLinkExternalFile( sal_uInt16 nFileId
, bool bDeferFilterDetection
= false );
786 * Try to create a "real" file name from the relative path. The original
787 * file name may not point to the real document when the referencing and
788 * referenced documents have been moved.
790 * For the real file name to be created, the relative name should not be
791 * empty before calling this method, or the real file name will not be
794 * @param nFileId file ID for an external document
796 void maybeCreateRealFileName(sal_uInt16 nFileId
);
799 * Purge those source document instances that have not been accessed for
800 * the specified duration.
802 * @param nTimeOut time out value in 100th of a second
804 void purgeStaleSrcDocument(sal_Int32 nTimeOut
);
806 sal_uInt32
getMappedNumberFormat(sal_uInt16 nFileId
, sal_uInt32 nNumFmt
, const ScDocument
& rSrcDoc
);
809 * If in maUnsavedDocShells move it to maDocShells and create a correct
810 * external reference entry
812 * @param Pointer to the newly saved DocumentShell
814 void transformUnsavedRefToSavedRef( SfxObjectShell
* pShell
);
819 /** cache of referenced ranges and names from source documents. */
820 ScExternalRefCache maRefCache
;
823 * Source document cache. This stores the original source document shell
824 * instances. They get purged after a certain period of time.
826 DocShellMap maDocShells
;
829 * DocShells to unsaved but referenced documents. If not empty ask before saving!
830 * Move to maDocShells if document referenced here is saved
832 DocShellMap maUnsavedDocShells
;
834 /** list of source documents that are managed by the link manager. */
835 LinkedDocMap maLinkedDocs
;
838 * List of referencing cells that may contain external names. There is
839 * one list per source document.
841 RefCellMap maRefCells
;
843 LinkListenerMap maLinkListeners
;
845 NumFmtMap maNumFormatMap
;
848 * List of external source document meta-data, used to keep track of
849 * external document identifiers.
851 std::vector
<SrcFileData
> maSrcFiles
;
853 /** Status whether in reference marking state. See isInReferenceMarking(). */
854 bool mbInReferenceMarking
:1;
857 * Controls whether or not to allow user interaction. We don't want any
858 * user interaction when calling from the API.
860 bool mbUserInteractionEnabled
:1;
862 bool mbSkipUnusedFileIds
= false;
863 std::vector
<sal_uInt16
> maConvertFileIdToUsedFileId
;
865 bool mbDocTimerEnabled
:1;
867 AutoTimer maSrcDocTimer
;
868 DECL_LINK(TimeOutHdl
, Timer
*, void);
871 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */