LOK: tilebench improvements
[LibreOffice.git] / sc / inc / externalrefmgr.hxx
blob70cf8f99a65f6a3cb20b22b8f1773ad9be6a6dc3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #ifndef INCLUDED_SC_INC_EXTERNALREFMGR_HXX
21 #define INCLUDED_SC_INC_EXTERNALREFMGR_HXX
23 #include "global.hxx"
24 #include "address.hxx"
25 #include <sfx2/objsh.hxx>
26 #include <sfx2/lnkbase.hxx>
27 #include <sfx2/event.hxx>
28 #include <tools/time.hxx>
29 #include <vcl/timer.hxx>
30 #include <svl/zforlist.hxx>
31 #include <svl/lstner.hxx>
32 #include "types.hxx"
33 #include "rangelst.hxx"
34 #include <formula/token.hxx>
35 #include <osl/mutex.hxx>
37 #include <memory>
38 #include <unordered_map>
39 #include <unordered_set>
40 #include <vector>
41 #include <list>
42 #include <set>
43 #include <formula/ExternalReferenceHelper.hxx>
45 class ScDocument;
46 class ScTokenArray;
47 namespace vcl { class Window; }
48 class ScFormulaCell;
50 class ScExternalRefCache;
52 namespace svl {
54 class SharedStringPool;
58 namespace sc {
60 class ColumnSpanSet;
64 class ScExternalRefLink : public ::sfx2::SvBaseLink
66 public:
67 ScExternalRefLink(ScDocument* pDoc, sal_uInt16 nFileId, const OUString& rFilter);
68 virtual ~ScExternalRefLink() override;
70 virtual void Closed() override;
71 virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
72 const OUString& rMimeType, const css::uno::Any & rValue) override;
73 virtual void Edit(vcl::Window* pParent, const Link<SvBaseLink&,void>& rEndEditHdl) override;
75 void SetDoReferesh(bool b);
77 private:
78 ScExternalRefLink() = delete;
79 ScExternalRefLink(const ScExternalRefLink&) = delete;
81 sal_uInt16 mnFileId;
82 OUString maFilterName;
83 ScDocument* mpDoc;
84 bool mbDoRefresh;
87 /**
88 * Cache table for external reference data.
90 class ScExternalRefCache
92 public:
93 typedef ::formula::FormulaTokenRef TokenRef;
94 typedef std::shared_ptr<ScTokenArray> TokenArrayRef;
96 struct TableName
98 OUString maUpperName;
99 OUString maRealName;
101 explicit TableName(const OUString& rUppper, const OUString& rReal);
104 struct CellFormat
106 bool mbIsSet;
107 SvNumFormatType mnType;
108 sal_uLong mnIndex;
110 explicit CellFormat();
113 private:
114 /** individual cell within cached external ref table. */
115 struct Cell
117 TokenRef mxToken;
118 sal_uLong mnFmtIndex;
120 typedef std::unordered_map<SCCOL, Cell> RowDataType;
121 typedef std::unordered_map<SCROW, RowDataType> RowsDataType;
123 public:
125 * Represents a single cached table in an external document. It only
126 * stores non-empty cells; empty cells should never be stored in the data
127 * cache. Instead, cached ranges should be used to determine whether or
128 * not a cell is empty or needs fetching from the source document. If a
129 * cell's value is not stored but its address is within the cached ranges,
130 * that cell is already queried in the source document and we know it's
131 * empty.
133 class Table
135 public:
137 Table();
138 ~Table();
140 void clear();
143 * Add cell value to the cache.
145 * @param bSetCacheRange if true, mark this cell 'cached'. This is
146 * false _only when_ adding a range of cell
147 * values, for performance reasons.
149 SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef const & pToken, sal_uLong nFmtIndex = 0, bool bSetCacheRange = true);
150 SC_DLLPUBLIC TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = nullptr) const;
151 bool hasRow( SCROW nRow ) const;
152 /** Set/clear referenced status flag only if current status is not
153 REFERENCED_PERMANENT. */
154 void setReferenced( bool bReferenced );
155 bool isReferenced() const;
156 /// Obtain a sorted vector of rows.
157 void getAllRows(::std::vector<SCROW>& rRows, SCROW nLow = 0, SCROW nHigh = MAXROW) const;
158 /// Returns the half-open range of used rows in this table. Returns [0,0) if table is empty.
159 SC_DLLPUBLIC ::std::pair< SCROW, SCROW > getRowRange() const;
160 /// Obtain a sorted vector of columns.
161 void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols, SCCOL nLow = 0, SCCOL nHigh = MAXCOL) const;
162 /// Returns the half-open range of used columns in the specified row. Returns [0,0) if row is empty.
163 SC_DLLPUBLIC ::std::pair< SCCOL, SCCOL > getColRange( SCROW nRow ) const;
164 void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
165 bool isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
167 void setCachedCell(SCCOL nCol, SCROW nRow);
168 void setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
171 * Call this to mark the entire table "cached". This will prevent all
172 * future attempts to access the source document even when non-cached
173 * cells are queried. In such case, non-cached cells are treated as
174 * empty cells. Useful when loading a document with own external data
175 * cache.
177 SC_DLLPUBLIC void setWholeTableCached();
178 private:
179 bool isInCachedRanges(SCCOL nCol, SCROW nRow) const;
180 TokenRef getEmptyOrNullToken(SCCOL nCol, SCROW nRow) const;
182 private:
183 /** Data cache */
184 RowsDataType maRows;
185 /** Collection of individual cached ranges. The table ranges are
186 * not used & always zero. */
187 ScRangeList maCachedRanges;
188 bool mbReferenced;
191 typedef std::shared_ptr<Table> TableTypeRef;
192 typedef std::unordered_map< OUString, size_t>
193 TableNameIndexMap;
195 ScExternalRefCache();
196 ~ScExternalRefCache();
198 const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const;
199 const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const;
202 * Get a cached cell data at specified cell location.
204 * @param nFileId file ID of an external document
205 * @param rTabName sheet name
206 * @param nCol
207 * @param nRow
209 * @return pointer to the token instance in the cache.
211 ScExternalRefCache::TokenRef getCellData(
212 sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex);
215 * Get a cached cell range data.
217 * @return a new token array instance. Note that <i>the caller must
218 * manage the life cycle of the returned instance</i>, which is
219 * guaranteed if the TokenArrayRef is properly used..
221 ScExternalRefCache::TokenArrayRef getCellRangeData(
222 sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange);
224 ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const OUString& rName);
225 void setRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, TokenArrayRef pArray);
226 bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName) const;
227 void setRangeName(sal_uInt16 nFileId, const OUString& rName);
229 void setCellData(sal_uInt16 nFileId, const OUString& rTabName,
230 SCCOL nCol, SCROW nRow, TokenRef const & pToken, sal_uLong nFmtIndex);
232 struct SingleRangeData
234 /** This name must be in upper-case. */
235 OUString maTableName;
236 ScMatrixRef mpRangeData;
238 void setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const ::std::vector<SingleRangeData>& rData,
239 const TokenArrayRef& pArray);
241 bool isDocInitialized(sal_uInt16 nFileId);
242 void initializeDoc(sal_uInt16 nFileId, const ::std::vector<OUString>& rTabNames, const OUString& rBaseName);
243 OUString getTableName(sal_uInt16 nFileId, size_t nCacheId) const;
244 void getAllTableNames(sal_uInt16 nFileId, ::std::vector<OUString>& rTabNames) const;
245 SCTAB getTabSpan( sal_uInt16 nFileId, const OUString& rStartTabName, const OUString& rEndTabName ) const;
246 void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
249 * Set all tables of a document as referenced, used only during
250 * store-to-file.
251 * @returns <TRUE/> if ALL tables of ALL documents are marked.
253 bool setCacheDocReferenced( sal_uInt16 nFileId );
256 * Set a table as referenced, used only during store-to-file.
257 * @returns <TRUE/> if ALL tables of ALL documents are marked.
259 bool setCacheTableReferenced( sal_uInt16 nFileId, const OUString& rTabName, size_t nSheets );
260 void setAllCacheTableReferencedStati( bool bReferenced );
261 bool areAllCacheTablesReferenced() const { return maReferenced.mbAllReferenced;}
264 * Collect all cached non-empty cell positions, inferred directly from the
265 * cached data, not the cached range metadata stored separately in the
266 * Table.
268 void getAllCachedDataSpans( sal_uInt16 nFileId, sc::ColumnSpanSet& rSet ) const;
270 bool getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab, sal_uInt16 nFileId ) const;
272 private:
273 struct ReferencedStatus
275 struct DocReferenced
277 ::std::vector<bool> maTables;
278 bool mbAllTablesReferenced;
279 // Initially, documents have no tables but all referenced.
280 DocReferenced() : mbAllTablesReferenced(true) {}
282 typedef ::std::vector<DocReferenced> DocReferencedVec;
284 DocReferencedVec maDocs;
285 bool mbAllReferenced;
287 ReferencedStatus();
288 void reset( size_t nDocs );
289 void checkAllDocs();
291 } maReferenced;
292 void addCacheTableToReferenced( sal_uInt16 nFileId, size_t nIndex );
293 void addCacheDocToReferenced( sal_uInt16 nFileId );
294 public:
296 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
297 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew,
298 size_t* pnIndex, const OUString* pExtUrl);
301 * Clear all caches including the cache tables.
303 void clearCache(sal_uInt16 nFileId);
306 * Clear all caches but keep the tables. All cache tables will be empty
307 * after the call, but the tables will not be removed.
309 void clearCacheTables(sal_uInt16 nFileId);
311 private:
312 struct RangeHash
314 size_t operator()(const ScRange& rRange) const
316 const ScAddress& s = rRange.aStart;
317 const ScAddress& e = rRange.aEnd;
318 return s.Tab() + s.Col() + s.Row() + e.Tab() + e.Col() + e.Row();
322 typedef std::unordered_map<OUString, TokenArrayRef> RangeNameMap;
323 typedef std::unordered_map<ScRange, TokenArrayRef, RangeHash> RangeArrayMap;
324 typedef std::unordered_map<OUString, OUString> NamePairMap;
326 /** Represents data cached for a single external document. */
327 struct DocItem
329 /** The raw cache tables. */
330 ::std::vector<TableTypeRef> maTables;
331 /** Table name list in correct order, in both upper- and real-case. */
332 ::std::vector<TableName> maTableNames;
333 /** Table name to index map. The names must be stored upper-case. */
334 TableNameIndexMap maTableNameIndex;
335 /** Range name cache. */
336 RangeNameMap maRangeNames;
337 /** Token array cache for cell ranges. */
338 RangeArrayMap maRangeArrays;
339 /** Upper- to real-case mapping for range names. */
340 NamePairMap maRealRangeNameMap;
342 /** Either the base name that was stored as sheet name for CSV files if
343 sheet name is Sheet1, or Sheet1 name if sheet name is base name.
345 OUString maSingleTableNameAlias;
347 bool mbInitFromSource;
349 DocItem() : mbInitFromSource(false) {}
351 TableNameIndexMap::const_iterator findTableNameIndex( const OUString& rTabName ) const;
352 bool getTableDataIndex( const OUString& rTabName, size_t& rIndex ) const;
353 bool getSingleTableNameAlternative( OUString& rTabName ) const;
355 typedef std::unordered_map<sal_uInt16, DocItem> DocDataType;
356 DocItem* getDocItem(sal_uInt16 nFileId) const;
358 private:
359 mutable osl::Mutex maMtxDocs;
360 mutable DocDataType maDocs;
363 class SC_DLLPUBLIC ScExternalRefManager : public formula::ExternalReferenceHelper, public SfxListener
365 public:
367 typedef std::set<ScFormulaCell*> RefCellSet;
368 typedef std::unordered_map<sal_uInt16, RefCellSet> RefCellMap;
370 enum LinkUpdateType { LINK_MODIFIED, LINK_BROKEN };
373 * Base class for objects that need to listen to link updates. When a
374 * link to a certain external file is updated, the notify() method gets
375 * called.
377 class LinkListener
379 public:
380 LinkListener();
381 virtual ~LinkListener() = 0;
382 virtual void notify(sal_uInt16 nFileId, LinkUpdateType eType) = 0;
384 struct Hash
386 size_t operator() (const LinkListener* p) const
388 return reinterpret_cast<size_t>(p);
394 * Use this guard when performing something from the API that might query
395 * values from external references. Interpreting formula strings is one
396 * such example.
398 class SC_DLLPUBLIC ApiGuard
400 public:
401 ApiGuard(const ScDocument* pDoc);
402 ~ApiGuard();
403 private:
404 ScExternalRefManager* mpMgr;
405 bool mbOldInteractionEnabled;
408 private:
409 /** Shell instance for a source document. */
410 struct SrcShell
412 SfxObjectShellRef maShell;
413 tools::Time maLastAccess;
415 SrcShell() : maLastAccess( tools::Time::SYSTEM ) {}
418 typedef std::unordered_map<sal_uInt16, SrcShell> DocShellMap;
419 typedef std::unordered_map<sal_uInt16, bool> LinkedDocMap;
421 typedef std::unordered_map<sal_uInt16, SvNumberFormatterMergeMap> NumFmtMap;
423 typedef std::unordered_set<LinkListener*, LinkListener::Hash> LinkListeners;
424 typedef std::unordered_map<sal_uInt16, LinkListeners> LinkListenerMap;
426 public:
427 /** Source document meta-data container. */
428 struct SrcFileData
430 OUString maFileName; /// original file name as loaded from the file.
431 OUString maRealFileName; /// file name created from the relative name.
432 OUString maRelativeName;
433 OUString maFilterName;
434 OUString maFilterOptions;
436 void maybeCreateRealFileName(const OUString& rOwnDocName);
439 public:
440 explicit ScExternalRefManager(ScDocument* pDoc);
441 virtual ~ScExternalRefManager() override;
443 virtual OUString getCacheTableName(sal_uInt16 nFileId, size_t nTabIndex) const override;
446 * Get a cache table instance for specified table and table index. Unlike
447 * the other method that takes a table name, this method does not create a
448 * new table when a table is not available for specified index.
450 * @param nFileId file ID
451 * @param nTabIndex cache table index
453 * @return shared_ptr to the cache table instance
455 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
458 * Get a cache table instance for specified file and table name. If the
459 * table instance is not already present, it'll instantiate a new one and
460 * append it to the end of the table array. <I>It's important to be
461 * aware of this fact especially for multi-table ranges for which
462 * table orders are critical.</I>
464 * Excel filter calls this method to populate the cache table from the
465 * XCT/CRN records. ODF import calls it for cached tables for external
466 * references.
468 * @param nFileId file ID
469 * @param rTabName table name
470 * @param bCreateNew if true, create a new table instance if it's not
471 * already present. If false, it returns NULL if the
472 * specified table's cache doesn't exist.
473 * @param pnIndex if non-NULL pointer is passed, it stores the internal
474 * index of a cache table instance.
475 * @param pExtUrl if non-NULL and bCreateNew==true, the base name will be
476 * propagated as an alias for the first table (and removed
477 * later if further tables are created).
479 * @return shared_ptr to the cache table instance
481 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew,
482 size_t* pnIndex = nullptr, const OUString* pExtUrl = nullptr);
484 /** Returns a vector containing all (real) table names and cache tables of
485 the specified file.
487 The index in the returned vector corresponds to the table index used to
488 access the cache table, e.g. in getCacheTable().
490 void getAllCachedTableNames(sal_uInt16 nFileId, ::std::vector<OUString>& rTabNames) const;
493 * Get the span (distance+sign(distance)) of two sheets of a specified
494 * file.
496 * @param nFileId file ID
497 * @param rStartTabName name of first sheet (sheet1)
498 * @param rEndTabName name of second sheet (sheet2)
500 * @return span
501 * 1 if sheet2 == sheet1
502 * > 1 if sheet2 > sheet1
503 * < -1 if sheet2 < sheet1
504 * -1 if nFileId or rStartTabName not found
505 * 0 if rEndTabName not found
507 SCTAB getCachedTabSpan(
508 sal_uInt16 nFileId, const OUString& rStartTabName, const OUString& rEndTabName) const;
511 * Get all unique number format indices that are used in the cache tables.
512 * The retrieved indices are sorted in ascending order.
514 * @param rNumFmts (reference) all unique number format indices.
516 void getAllCachedNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
518 sal_uInt16 getExternalFileCount() const;
521 * Mark all tables as referenced that are used by any LinkListener, used
522 * only during store-to-file.
524 void markUsedByLinkListeners();
526 void markUsedExternalRefCells();
529 * Set a table as referenced, used only during store-to-file.
530 * @returns <TRUE/> if ALL tables of ALL external documents are marked.
532 bool setCacheTableReferenced( sal_uInt16 nFileId, const OUString& rTabName, size_t nSheets );
533 void setAllCacheTableReferencedStati( bool bReferenced );
536 * @returns <TRUE/> if setAllCacheTableReferencedStati(false) was called,
537 * <FALSE/> if setAllCacheTableReferencedStati(true) was called.
539 bool isInReferenceMarking() const { return mbInReferenceMarking; }
541 void storeRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, const ScTokenArray& rArray);
543 ScExternalRefCache::TokenRef getSingleRefToken(
544 sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell,
545 const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt = nullptr);
548 * Get an array of tokens that consist of the specified external cell
549 * range.
551 * @param nFileId file ID for an external document
552 * @param rTabName referenced sheet name
553 * @param rRange referenced cell range
554 * @param pCurPos current cursor position to keep track of cells that
555 * reference an external data.
557 * @return shared_ptr to a token array instance. <i>The caller must not
558 * delete the instance returned by this method.</i>
560 ScExternalRefCache::TokenArrayRef getDoubleRefTokens(
561 sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange, const ScAddress* pCurPos);
564 * Get an array of tokens corresponding with a specified name in a
565 * specified file.
567 * @param pCurPos current cell address where this name token is used.
568 * This is purely to keep track of all cells containing
569 * external names for refreshing purposes. If this is
570 * NULL, then the cell will not be added to the list.
572 * @return shared_ptr to array of tokens composing the name
574 ScExternalRefCache::TokenArrayRef getRangeNameTokens(
575 sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos = nullptr);
577 bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName);
579 OUString getOwnDocumentName() const;
580 bool isOwnDocument(const OUString& rFile) const;
583 * Takes a flat file name, and convert it to an absolute URL path. An
584 * absolute URL path begins with 'file:///.
586 * @param rFile file name to convert
588 void convertToAbsName(OUString& rFile) const;
589 sal_uInt16 getExternalFileId(const OUString& rFile);
592 * It returns a pointer to the name of the URI associated with a given
593 * external file ID. In case the original document has moved, it returns
594 * an URI adjusted for the relocation.
596 * @param nFileId file ID for an external document
597 * @param bForceOriginal If true, it always returns the original document
598 * URI even if the referring document has relocated.
599 * If false, it returns an URI adjusted for
600 * relocated document.
602 * @return const OUString* external document URI.
604 const OUString* getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal = false);
607 * Get all cached external file names as an array. Array indices of the
608 * returned name array correspond with external file ID's.
610 std::vector<OUString> getAllCachedExternalFileNames() const;
612 bool hasExternalFile(sal_uInt16 nFileId) const;
613 bool hasExternalFile(const OUString& rFile) const;
614 const SrcFileData* getExternalFileData(sal_uInt16 nFileId) const;
616 const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const;
617 const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const;
618 void clearCache(sal_uInt16 nFileId);
619 bool refreshSrcDocument(sal_uInt16 nFileId);
620 void breakLink(sal_uInt16 nFileId);
621 void switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter);
624 * Set a relative file path for the specified file ID. Note that the
625 * caller must ensure that the passed URL is a valid relative URL.
627 * @param nFileId file ID for an external document
628 * @param rRelUrl relative URL
630 void setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl);
633 * Set the filter name and options if any for a given source document.
634 * These values get reset when the source document ever gets reloaded.
636 * @param nFileId
637 * @param rFilterName
638 * @param rOptions
640 void setFilterData(sal_uInt16 nFileId, const OUString& rFilterName, const OUString& rOptions);
642 void clear();
644 bool hasExternalData() const;
647 * Re-generates relative names for all stored source files. This is
648 * necessary when exporting to an ods document, to ensure that all source
649 * files have their respective relative names for xlink:href export.
651 * @param rBaseFileUrl Absolute URL of the content.xml fragment of the
652 * document being exported.
654 void resetSrcFileData(const OUString& rBaseFileUrl);
657 * Replace the original URL with the real URL that was generated from the relative URL.
659 void updateAbsAfterLoad();
662 * Stop tracking a specific formula cell.
664 * @param pCell pointer to cell that formerly contained external
665 * reference.
667 void removeRefCell(ScFormulaCell* pCell);
670 * Register a new link listener to a specified external document. Note
671 * that the caller is responsible for managing the life cycle of the
672 * listener object.
674 void addLinkListener(sal_uInt16 nFileId, LinkListener* pListener);
677 * Remove an existing link listener. Note that removing a listener
678 * pointer here does not delete the listener object instance.
680 void removeLinkListener(sal_uInt16 nFileId, LinkListener* pListener);
682 void removeLinkListener(LinkListener* pListener);
685 * Notify all listeners that are listening to a specified external
686 * document.
688 * @param nFileId file ID for an external document.
690 void notifyAllLinkListeners(sal_uInt16 nFileId, LinkUpdateType eType);
693 * Check if the file specified by the path is a legitimate file that
694 * exists & can be loaded.
696 bool isFileLoadable(const OUString& rFile) const;
698 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
701 * If we still contain unsaved files we should warn the user before saving
703 * @return true if the document still contains references to an unsaved file
705 bool containsUnsavedReferences() const { return !maUnsavedDocShells.empty(); }
707 void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
709 * Add a cell to reference the same files as the template cell.
711 void insertRefCellFromTemplate( ScFormulaCell* pTemplateCell, ScFormulaCell* pCell );
713 bool hasCellExternalReference(const ScAddress& rCell);
715 void enableDocTimer( bool bEnable );
717 /** Add all known external files to the LinkManager. */
718 void addFilesToLinkManager();
720 private:
721 ScExternalRefManager(const ScExternalRefManager&) = delete;
723 void refreshAllRefCells(sal_uInt16 nFileId);
725 void fillCellFormat(sal_uLong nFmtIndex, ScExternalRefCache::CellFormat* pFmt) const;
727 bool getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab, sal_uInt16 nFileId ) const;
729 ScExternalRefCache::TokenRef getSingleRefTokenFromSrcDoc(
730 sal_uInt16 nFileId, ScDocument* pSrcDoc, const ScAddress& rPos,
731 ScExternalRefCache::CellFormat* pFmt);
734 * Retrieve a range token array from a source document instance.
736 * @param pSrcDoc pointer to the source document instance.
737 * @param rTabName name of the first table.
738 * @param rRange range specified. Upon successful retrieval, this range
739 * gets modified to contain the correct table IDs, and in
740 * case the range is larger than the data area of the source
741 * document, it gets reduced to the data area.
742 * @param rCacheData an array of structs, with each struct containing the
743 * table name and the data in the specified range.
745 * @return range token array
747 ScExternalRefCache::TokenArrayRef getDoubleRefTokensFromSrcDoc(
748 const ScDocument* pSrcDoc, const OUString& rTabName, ScRange& rRange,
749 ::std::vector<ScExternalRefCache::SingleRangeData>& rCacheData);
752 * Retrieve range name token array from a source document instance.
754 * @param nFileId file ID of the source document.
755 * @param pSrcDoc pointer to the source document instance
756 * @param rName range name to retrieve. Note that the range name lookup
757 * is case <i>in</i>-sensitive, and upon successful retrieval
758 * of the range name array, this name gets updated to the
759 * actual range name with the correct casing.
761 * @return range name token array
763 static ScExternalRefCache::TokenArrayRef getRangeNameTokensFromSrcDoc(
764 sal_uInt16 nFileId, const ScDocument* pSrcDoc, OUString& rName);
766 ScDocument* getInMemorySrcDocument(sal_uInt16 nFileId);
767 ScDocument* getSrcDocument(sal_uInt16 nFileId);
768 SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter);
771 * Caller must ensure that the passed shell is not already stored.
773 ScDocument& cacheNewDocShell( sal_uInt16 nFileId, SrcShell& rSrcShell );
775 void maybeLinkExternalFile( sal_uInt16 nFileId, bool bDeferFilterDetection = false );
778 * Try to create a "real" file name from the relative path. The original
779 * file name may not point to the real document when the referencing and
780 * referenced documents have been moved.
782 * For the real file name to be created, the relative name should not be
783 * empty before calling this method, or the real file name will not be
784 * created.
786 * @param nFileId file ID for an external document
788 void maybeCreateRealFileName(sal_uInt16 nFileId);
791 * Purge those source document instances that have not been accessed for
792 * the specified duration.
794 * @param nTimeOut time out value in 100th of a second
796 void purgeStaleSrcDocument(sal_Int32 nTimeOut);
798 sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, const ScDocument* pSrcDoc);
801 * If in maUnsavedDocShells move it to maDocShells and create a correct
802 * external reference entry
804 * @param Pointer to the newly saved DocumentShell
806 void transformUnsavedRefToSavedRef( SfxObjectShell* pShell );
808 private:
809 ScDocument* mpDoc;
811 /** cache of referenced ranges and names from source documents. */
812 ScExternalRefCache maRefCache;
815 * Source document cache. This stores the original source document shell
816 * instances. They get purged after a certain period of time.
818 DocShellMap maDocShells;
821 * DocShells to unsaved but referenced documents. If not empty ask before saving!
822 * Move to maDocShells if document referenced here is saved
824 DocShellMap maUnsavedDocShells;
826 /** list of source documents that are managed by the link manager. */
827 LinkedDocMap maLinkedDocs;
830 * List of referencing cells that may contain external names. There is
831 * one list per source document.
833 RefCellMap maRefCells;
835 LinkListenerMap maLinkListeners;
837 NumFmtMap maNumFormatMap;
840 * List of external source document meta-data, used to keep track of
841 * external document identifiers.
843 std::vector<SrcFileData> maSrcFiles;
845 /** Status whether in reference marking state. See isInReferenceMarking(). */
846 bool mbInReferenceMarking:1;
849 * Controls whether or not to allow user interaction. We don't want any
850 * user interaction when calling from the API.
852 bool mbUserInteractionEnabled:1;
854 bool mbDocTimerEnabled:1;
856 AutoTimer maSrcDocTimer;
857 DECL_LINK(TimeOutHdl, Timer*, void);
860 #endif
862 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */