Bump version to 6.4-15
[LibreOffice.git] / sc / inc / externalrefmgr.hxx
blob71fba923d446aa9b6e33dea2aee6925b1db1e3ea
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 "address.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>
30 #include "types.hxx"
31 #include "rangelst.hxx"
32 #include <osl/mutex.hxx>
33 #include <formula/types.hxx>
34 #include <tools/solar.h>
36 #include <memory>
37 #include <unordered_map>
38 #include <unordered_set>
39 #include <vector>
40 #include <set>
41 #include <formula/ExternalReferenceHelper.hxx>
43 class ScDocument;
44 class ScTokenArray;
45 namespace weld { class Window; }
47 class ScFormulaCell;
49 namespace sc {
51 class ColumnSpanSet;
55 class ScExternalRefLink final : public ::sfx2::SvBaseLink
57 public:
58 ScExternalRefLink(ScDocument* pDoc, sal_uInt16 nFileId);
59 virtual ~ScExternalRefLink() override;
61 virtual void Closed() override;
62 virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
63 const OUString& rMimeType, const css::uno::Any & rValue) override;
64 virtual void Edit(weld::Window* pParent, const Link<SvBaseLink&,void>& rEndEditHdl) override;
66 void SetDoReferesh(bool b);
68 private:
69 ScExternalRefLink() = delete;
70 ScExternalRefLink(const ScExternalRefLink&) = delete;
72 sal_uInt16 const mnFileId;
73 ScDocument* const mpDoc;
74 bool mbDoRefresh;
77 /**
78 * Cache table for external reference data.
80 class ScExternalRefCache
82 public:
83 typedef ::formula::FormulaTokenRef TokenRef;
84 typedef std::shared_ptr<ScTokenArray> TokenArrayRef;
86 struct TableName
88 OUString maUpperName;
89 OUString maRealName;
91 explicit TableName(const OUString& rUppper, const OUString& rReal);
94 struct CellFormat
96 bool mbIsSet;
97 SvNumFormatType mnType;
98 sal_uLong mnIndex;
100 explicit CellFormat();
103 private:
104 /** individual cell within cached external ref table. */
105 struct Cell
107 TokenRef mxToken;
108 sal_uLong mnFmtIndex;
110 typedef std::unordered_map<SCCOL, Cell> RowDataType;
111 typedef std::unordered_map<SCROW, RowDataType> RowsDataType;
113 public:
115 * Represents a single cached table in an external document. It only
116 * stores non-empty cells; empty cells should never be stored in the data
117 * cache. Instead, cached ranges should be used to determine whether or
118 * not a cell is empty or needs fetching from the source document. If a
119 * cell's value is not stored but its address is within the cached ranges,
120 * that cell is already queried in the source document and we know it's
121 * empty.
123 class Table
125 public:
127 Table();
128 ~Table();
130 void clear();
133 * Add cell value to the cache.
135 * @param bSetCacheRange if true, mark this cell 'cached'. This is
136 * false _only when_ adding a range of cell
137 * values, for performance reasons.
139 SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef const & pToken, sal_uLong nFmtIndex = 0, bool bSetCacheRange = true);
140 SC_DLLPUBLIC TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = nullptr) const;
141 bool hasRow( SCROW nRow ) const;
142 /** Set/clear referenced status flag only if current status is not
143 REFERENCED_PERMANENT. */
144 void setReferenced( bool bReferenced );
145 bool isReferenced() const;
146 /// Obtain a sorted vector of rows.
147 void getAllRows(::std::vector<SCROW>& rRows, SCROW nLow = 0, SCROW nHigh = MAXROW) const;
148 /// Returns the half-open range of used rows in this table. Returns [0,0) if table is empty.
149 SC_DLLPUBLIC ::std::pair< SCROW, SCROW > getRowRange() const;
150 /// Obtain a sorted vector of columns.
151 void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols, SCCOL nLow = 0, SCCOL nHigh = MAXCOL) const;
152 /// Returns the half-open range of used columns in the specified row. Returns [0,0) if row is empty.
153 SC_DLLPUBLIC ::std::pair< SCCOL, SCCOL > getColRange( SCROW nRow ) const;
154 void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
155 bool isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
157 void setCachedCell(SCCOL nCol, SCROW nRow);
158 void setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
161 * Call this to mark the entire table "cached". This will prevent all
162 * future attempts to access the source document even when non-cached
163 * cells are queried. In such case, non-cached cells are treated as
164 * empty cells. Useful when loading a document with own external data
165 * cache.
167 SC_DLLPUBLIC void setWholeTableCached();
168 private:
169 bool isInCachedRanges(SCCOL nCol, SCROW nRow) const;
170 TokenRef getEmptyOrNullToken(SCCOL nCol, SCROW nRow) const;
172 private:
173 /** Data cache */
174 RowsDataType maRows;
175 /** Collection of individual cached ranges. The table ranges are
176 * not used & always zero. */
177 ScRangeList maCachedRanges;
178 bool mbReferenced;
181 typedef std::shared_ptr<Table> TableTypeRef;
182 typedef std::unordered_map< OUString, size_t>
183 TableNameIndexMap;
185 ScExternalRefCache();
186 ~ScExternalRefCache();
188 const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const;
189 const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const;
192 * Get a cached cell data at specified cell location.
194 * @param nFileId file ID of an external document
195 * @param rTabName sheet name
196 * @param nCol
197 * @param nRow
199 * @return pointer to the token instance in the cache.
201 ScExternalRefCache::TokenRef getCellData(
202 sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex);
205 * Get a cached cell range data.
207 * @return a new token array instance. Note that <i>the caller must
208 * manage the life cycle of the returned instance</i>, which is
209 * guaranteed if the TokenArrayRef is properly used...
211 ScExternalRefCache::TokenArrayRef getCellRangeData(
212 sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange);
214 ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const OUString& rName);
215 void setRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, TokenArrayRef pArray);
216 bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName) const;
217 void setRangeName(sal_uInt16 nFileId, const OUString& rName);
219 void setCellData(sal_uInt16 nFileId, const OUString& rTabName,
220 SCCOL nCol, SCROW nRow, TokenRef const & pToken, sal_uLong nFmtIndex);
222 struct SingleRangeData
224 /** This name must be in upper-case. */
225 OUString maTableName;
226 ScMatrixRef mpRangeData;
228 void setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const ::std::vector<SingleRangeData>& rData,
229 const TokenArrayRef& pArray);
231 bool isDocInitialized(sal_uInt16 nFileId);
232 void initializeDoc(sal_uInt16 nFileId, const ::std::vector<OUString>& rTabNames, const OUString& rBaseName);
233 OUString getTableName(sal_uInt16 nFileId, size_t nCacheId) const;
234 void getAllTableNames(sal_uInt16 nFileId, ::std::vector<OUString>& rTabNames) const;
235 SCTAB getTabSpan( sal_uInt16 nFileId, const OUString& rStartTabName, const OUString& rEndTabName ) const;
236 void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
239 * Set all tables of a document as referenced, used only during
240 * store-to-file.
241 * @returns <TRUE/> if ALL tables of ALL documents are marked.
243 bool setCacheDocReferenced( sal_uInt16 nFileId );
246 * Set a table as referenced, used only during store-to-file.
247 * @returns <TRUE/> if ALL tables of ALL documents are marked.
249 bool setCacheTableReferenced( sal_uInt16 nFileId, const OUString& rTabName, size_t nSheets );
250 void setAllCacheTableReferencedStati( bool bReferenced );
251 bool areAllCacheTablesReferenced() const { return maReferenced.mbAllReferenced;}
254 * Collect all cached non-empty cell positions, inferred directly from the
255 * cached data, not the cached range metadata stored separately in the
256 * Table.
258 void getAllCachedDataSpans( const ScDocument& rSrcDoc, sal_uInt16 nFileId, sc::ColumnSpanSet& rSet ) const;
260 bool getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab, sal_uInt16 nFileId ) const;
262 private:
263 struct ReferencedStatus
265 struct DocReferenced
267 ::std::vector<bool> maTables;
268 bool mbAllTablesReferenced;
269 // Initially, documents have no tables but all referenced.
270 DocReferenced() : mbAllTablesReferenced(true) {}
272 typedef ::std::vector<DocReferenced> DocReferencedVec;
274 DocReferencedVec maDocs;
275 bool mbAllReferenced;
277 ReferencedStatus();
278 void reset( size_t nDocs );
279 void checkAllDocs();
281 } maReferenced;
282 void addCacheTableToReferenced( sal_uInt16 nFileId, size_t nIndex );
283 void addCacheDocToReferenced( sal_uInt16 nFileId );
284 public:
286 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
287 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew,
288 size_t* pnIndex, const OUString* pExtUrl);
291 * Clear all caches including the cache tables.
293 void clearCache(sal_uInt16 nFileId);
296 * Clear all caches but keep the tables. All cache tables will be empty
297 * after the call, but the tables will not be removed.
299 void clearCacheTables(sal_uInt16 nFileId);
301 private:
302 struct RangeHash
304 size_t operator()(const ScRange& rRange) const
306 const ScAddress& s = rRange.aStart;
307 const ScAddress& e = rRange.aEnd;
308 size_t hash = 17;
309 hash = hash * 37 + s.Tab();
310 hash = hash * 37 + s.Col();
311 hash = hash * 37 + s.Row();
312 hash = hash * 37 + e.Tab();
313 hash = hash * 37 + e.Col();
314 hash = hash * 37 + e.Row();
315 return hash;
319 typedef std::unordered_map<OUString, TokenArrayRef> RangeNameMap;
320 typedef std::unordered_map<ScRange, TokenArrayRef, RangeHash> RangeArrayMap;
321 typedef std::unordered_map<OUString, OUString> NamePairMap;
323 /** Represents data cached for a single external document. */
324 struct DocItem
326 /** The raw cache tables. */
327 ::std::vector<TableTypeRef> maTables;
328 /** Table name list in correct order, in both upper- and real-case. */
329 ::std::vector<TableName> maTableNames;
330 /** Table name to index map. The names must be stored upper-case. */
331 TableNameIndexMap maTableNameIndex;
332 /** Range name cache. */
333 RangeNameMap maRangeNames;
334 /** Token array cache for cell ranges. */
335 RangeArrayMap maRangeArrays;
336 /** Upper- to real-case mapping for range names. */
337 NamePairMap maRealRangeNameMap;
339 /** Either the base name that was stored as sheet name for CSV files if
340 sheet name is Sheet1, or Sheet1 name if sheet name is base name.
342 OUString maSingleTableNameAlias;
344 bool mbInitFromSource;
346 DocItem() : mbInitFromSource(false) {}
348 TableNameIndexMap::const_iterator findTableNameIndex( const OUString& rTabName ) const;
349 bool getTableDataIndex( const OUString& rTabName, size_t& rIndex ) const;
350 bool getSingleTableNameAlternative( OUString& rTabName ) const;
352 typedef std::unordered_map<sal_uInt16, DocItem> DocDataType;
353 DocItem* getDocItem(sal_uInt16 nFileId) const;
355 private:
356 mutable osl::Mutex maMtxDocs;
357 mutable DocDataType maDocs;
360 class SC_DLLPUBLIC ScExternalRefManager final : public formula::ExternalReferenceHelper, public SfxListener
362 public:
364 typedef std::set<ScFormulaCell*> RefCellSet;
365 typedef std::unordered_map<sal_uInt16, RefCellSet> RefCellMap;
367 enum LinkUpdateType { LINK_MODIFIED, LINK_BROKEN };
370 * Base class for objects that need to listen to link updates. When a
371 * link to a certain external file is updated, the notify() method gets
372 * called.
374 class LinkListener
376 public:
377 LinkListener();
378 virtual ~LinkListener() = 0;
379 virtual void notify(sal_uInt16 nFileId, LinkUpdateType eType) = 0;
381 struct Hash
383 size_t operator() (const LinkListener* p) const
385 return reinterpret_cast<size_t>(p);
391 * Use this guard when performing something from the API that might query
392 * values from external references. Interpreting formula strings is one
393 * such example.
395 class SC_DLLPUBLIC ApiGuard
397 public:
398 ApiGuard(const ScDocument* pDoc);
399 ~ApiGuard();
400 private:
401 ScExternalRefManager* mpMgr;
402 bool const mbOldInteractionEnabled;
405 private:
406 /** Shell instance for a source document. */
407 struct SrcShell
409 SfxObjectShellRef maShell;
410 tools::Time maLastAccess;
412 SrcShell() : maLastAccess( tools::Time::SYSTEM ) {}
415 typedef std::unordered_map<sal_uInt16, SrcShell> DocShellMap;
416 typedef std::unordered_map<sal_uInt16, bool> LinkedDocMap;
418 typedef std::unordered_map<sal_uInt16, SvNumberFormatterMergeMap> NumFmtMap;
420 typedef std::unordered_set<LinkListener*, LinkListener::Hash> LinkListeners;
421 typedef std::unordered_map<sal_uInt16, LinkListeners> LinkListenerMap;
423 public:
424 /** Source document meta-data container. */
425 struct SrcFileData
427 OUString maFileName; /// original file name as loaded from the file.
428 OUString maRealFileName; /// file name created from the relative name.
429 OUString maRelativeName;
430 OUString maFilterName;
431 OUString maFilterOptions;
433 void maybeCreateRealFileName(const OUString& rOwnDocName);
436 public:
437 explicit ScExternalRefManager(ScDocument* pDoc);
438 virtual ~ScExternalRefManager() override;
440 virtual OUString getCacheTableName(sal_uInt16 nFileId, size_t nTabIndex) const override;
443 * Get a cache table instance for specified table and table index. Unlike
444 * the other method that takes a table name, this method does not create a
445 * new table when a table is not available for specified index.
447 * @param nFileId file ID
448 * @param nTabIndex cache table index
450 * @return shared_ptr to the cache table instance
452 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
455 * Get a cache table instance for specified file and table name. If the
456 * table instance is not already present, it'll instantiate a new one and
457 * append it to the end of the table array. <I>It's important to be
458 * aware of this fact especially for multi-table ranges for which
459 * table orders are critical.</I>
461 * Excel filter calls this method to populate the cache table from the
462 * XCT/CRN records. ODF import calls it for cached tables for external
463 * references.
465 * @param nFileId file ID
466 * @param rTabName table name
467 * @param bCreateNew if true, create a new table instance if it's not
468 * already present. If false, it returns NULL if the
469 * specified table's cache doesn't exist.
470 * @param pnIndex if non-NULL pointer is passed, it stores the internal
471 * index of a cache table instance.
472 * @param pExtUrl if non-NULL and bCreateNew==true, the base name will be
473 * propagated as an alias for the first table (and removed
474 * later if further tables are created).
476 * @return shared_ptr to the cache table instance
478 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew,
479 size_t* pnIndex = nullptr, const OUString* pExtUrl = nullptr);
481 /** Returns a vector containing all (real) table names and cache tables of
482 the specified file.
484 The index in the returned vector corresponds to the table index used to
485 access the cache table, e.g. in getCacheTable().
487 void getAllCachedTableNames(sal_uInt16 nFileId, ::std::vector<OUString>& rTabNames) const;
490 * Get the span (distance+sign(distance)) of two sheets of a specified
491 * file.
493 * @param nFileId file ID
494 * @param rStartTabName name of first sheet (sheet1)
495 * @param rEndTabName name of second sheet (sheet2)
497 * @return span
498 * 1 if sheet2 == sheet1
499 * > 1 if sheet2 > sheet1
500 * < -1 if sheet2 < sheet1
501 * -1 if nFileId or rStartTabName not found
502 * 0 if rEndTabName not found
504 SCTAB getCachedTabSpan(
505 sal_uInt16 nFileId, const OUString& rStartTabName, const OUString& rEndTabName) const;
508 * Get all unique number format indices that are used in the cache tables.
509 * The retrieved indices are sorted in ascending order.
511 * @param rNumFmts (reference) all unique number format indices.
513 void getAllCachedNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
515 sal_uInt16 getExternalFileCount() const;
518 * Mark all tables as referenced that are used by any LinkListener, used
519 * only during store-to-file.
521 void markUsedByLinkListeners();
523 void markUsedExternalRefCells();
526 * Set a table as referenced, used only during store-to-file.
527 * @returns <TRUE/> if ALL tables of ALL external documents are marked.
529 bool setCacheTableReferenced( sal_uInt16 nFileId, const OUString& rTabName, size_t nSheets );
530 void setAllCacheTableReferencedStati( bool bReferenced );
533 * @returns <TRUE/> if setAllCacheTableReferencedStati(false) was called,
534 * <FALSE/> if setAllCacheTableReferencedStati(true) was called.
536 bool isInReferenceMarking() const { return mbInReferenceMarking; }
538 void storeRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, const ScTokenArray& rArray);
540 ScExternalRefCache::TokenRef getSingleRefToken(
541 sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell,
542 const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt = nullptr);
545 * Get an array of tokens that consist of the specified external cell
546 * range.
548 * @param nFileId file ID for an external document
549 * @param rTabName referenced sheet name
550 * @param rRange referenced cell range
551 * @param pCurPos current cursor position to keep track of cells that
552 * reference an external data.
554 * @return shared_ptr to a token array instance. <i>The caller must not
555 * delete the instance returned by this method.</i>
557 ScExternalRefCache::TokenArrayRef getDoubleRefTokens(
558 sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange, const ScAddress* pCurPos);
561 * Get an array of tokens corresponding with a specified name in a
562 * specified file.
564 * @param pCurPos current cell address where this name token is used.
565 * This is purely to keep track of all cells containing
566 * external names for refreshing purposes. If this is
567 * NULL, then the cell will not be added to the list.
569 * @return shared_ptr to array of tokens composing the name
571 ScExternalRefCache::TokenArrayRef getRangeNameTokens(
572 sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos = nullptr);
574 bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName);
576 OUString getOwnDocumentName() const;
577 bool isOwnDocument(const OUString& rFile) const;
580 * Takes a flat file name, and convert it to an absolute URL path. An
581 * absolute URL path begins with 'file:///.
583 * @param rFile file name to convert
585 void convertToAbsName(OUString& rFile) const;
586 sal_uInt16 getExternalFileId(const OUString& rFile);
589 * It returns a pointer to the name of the URI associated with a given
590 * external file ID. In case the original document has moved, it returns
591 * a URI adjusted for the relocation.
593 * @param nFileId file ID for an external document
594 * @param bForceOriginal If true, it always returns the original document
595 * URI even if the referring document has relocated.
596 * If false, it returns a URI adjusted for
597 * relocated document.
599 * @return const OUString* external document URI.
601 const OUString* getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal = false);
604 * Get all cached external file names as an array. Array indices of the
605 * returned name array correspond with external file ID's.
607 std::vector<OUString> getAllCachedExternalFileNames() const;
609 bool hasExternalFile(sal_uInt16 nFileId) const;
610 bool hasExternalFile(const OUString& rFile) const;
611 const SrcFileData* getExternalFileData(sal_uInt16 nFileId) const;
613 const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const;
614 const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const;
615 void clearCache(sal_uInt16 nFileId);
616 bool refreshSrcDocument(sal_uInt16 nFileId);
617 void breakLink(sal_uInt16 nFileId);
618 void switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter);
621 * Set a relative file path for the specified file ID. Note that the
622 * caller must ensure that the passed URL is a valid relative URL.
624 * @param nFileId file ID for an external document
625 * @param rRelUrl relative URL
627 void setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl);
630 * Set the filter name and options if any for a given source document.
631 * These values get reset when the source document ever gets reloaded.
633 * @param nFileId
634 * @param rFilterName
635 * @param rOptions
637 void setFilterData(sal_uInt16 nFileId, const OUString& rFilterName, const OUString& rOptions);
639 void clear();
641 bool hasExternalData() const;
644 * Re-generates relative names for all stored source files. This is
645 * necessary when exporting to an ods document, to ensure that all source
646 * files have their respective relative names for xlink:href export.
648 * @param rBaseFileUrl Absolute URL of the content.xml fragment of the
649 * document being exported.
651 void resetSrcFileData(const OUString& rBaseFileUrl);
654 * Replace the original URL with the real URL that was generated from the relative URL.
656 void updateAbsAfterLoad();
659 * Stop tracking a specific formula cell.
661 * @param pCell pointer to cell that formerly contained external
662 * reference.
664 void removeRefCell(ScFormulaCell* pCell);
667 * Register a new link listener to a specified external document. Note
668 * that the caller is responsible for managing the life cycle of the
669 * listener object.
671 void addLinkListener(sal_uInt16 nFileId, LinkListener* pListener);
674 * Remove an existing link listener. Note that removing a listener
675 * pointer here does not delete the listener object instance.
677 void removeLinkListener(sal_uInt16 nFileId, LinkListener* pListener);
679 void removeLinkListener(LinkListener* pListener);
682 * Notify all listeners that are listening to a specified external
683 * document.
685 * @param nFileId file ID for an external document.
687 void notifyAllLinkListeners(sal_uInt16 nFileId, LinkUpdateType eType);
690 * Check if the file specified by the path is a legitimate file that
691 * exists & can be loaded.
693 bool isFileLoadable(const OUString& rFile) const;
695 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
698 * If we still contain unsaved files we should warn the user before saving
700 * @return true if the document still contains references to an unsaved file
702 bool containsUnsavedReferences() const { return !maUnsavedDocShells.empty(); }
704 void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
706 * Add a cell to reference the same files as the template cell.
708 void insertRefCellFromTemplate( ScFormulaCell* pTemplateCell, ScFormulaCell* pCell );
710 bool hasCellExternalReference(const ScAddress& rCell);
712 void enableDocTimer( bool bEnable );
714 /** Add all known external files to the LinkManager. */
715 void addFilesToLinkManager();
717 private:
718 ScExternalRefManager(const ScExternalRefManager&) = delete;
720 void refreshAllRefCells(sal_uInt16 nFileId);
722 void fillCellFormat(sal_uLong nFmtIndex, ScExternalRefCache::CellFormat* pFmt) const;
724 bool getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab, sal_uInt16 nFileId ) const;
726 ScExternalRefCache::TokenRef getSingleRefTokenFromSrcDoc(
727 sal_uInt16 nFileId, ScDocument* pSrcDoc, const ScAddress& rPos,
728 ScExternalRefCache::CellFormat* pFmt);
731 * Retrieve a range token array from a source document instance.
733 * @param pSrcDoc pointer to the source document instance.
734 * @param rTabName name of the first table.
735 * @param rRange range specified. Upon successful retrieval, this range
736 * gets modified to contain the correct table IDs, and in
737 * case the range is larger than the data area of the source
738 * document, it gets reduced to the data area.
739 * @param rCacheData an array of structs, with each struct containing the
740 * table name and the data in the specified range.
742 * @return range token array
744 ScExternalRefCache::TokenArrayRef getDoubleRefTokensFromSrcDoc(
745 const ScDocument* pSrcDoc, const OUString& rTabName, ScRange& rRange,
746 ::std::vector<ScExternalRefCache::SingleRangeData>& rCacheData);
749 * Retrieve range name token array from a source document instance.
751 * @param nFileId file ID of the source document.
752 * @param pSrcDoc pointer to the source document instance
753 * @param rName range name to retrieve. Note that the range name lookup
754 * is case <i>in</i>-sensitive, and upon successful retrieval
755 * of the range name array, this name gets updated to the
756 * actual range name with the correct casing.
758 * @return range name token array
760 static ScExternalRefCache::TokenArrayRef getRangeNameTokensFromSrcDoc(
761 sal_uInt16 nFileId, const ScDocument* pSrcDoc, OUString& rName);
763 ScDocument* getInMemorySrcDocument(sal_uInt16 nFileId);
764 ScDocument* getSrcDocument(sal_uInt16 nFileId);
765 SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter);
768 * Caller must ensure that the passed shell is not already stored.
770 ScDocument& cacheNewDocShell( sal_uInt16 nFileId, SrcShell& rSrcShell );
772 void maybeLinkExternalFile( sal_uInt16 nFileId, bool bDeferFilterDetection = false );
775 * Try to create a "real" file name from the relative path. The original
776 * file name may not point to the real document when the referencing and
777 * referenced documents have been moved.
779 * For the real file name to be created, the relative name should not be
780 * empty before calling this method, or the real file name will not be
781 * created.
783 * @param nFileId file ID for an external document
785 void maybeCreateRealFileName(sal_uInt16 nFileId);
788 * Purge those source document instances that have not been accessed for
789 * the specified duration.
791 * @param nTimeOut time out value in 100th of a second
793 void purgeStaleSrcDocument(sal_Int32 nTimeOut);
795 sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, const ScDocument* pSrcDoc);
798 * If in maUnsavedDocShells move it to maDocShells and create a correct
799 * external reference entry
801 * @param Pointer to the newly saved DocumentShell
803 void transformUnsavedRefToSavedRef( SfxObjectShell* pShell );
805 private:
806 ScDocument* mpDoc;
808 /** cache of referenced ranges and names from source documents. */
809 ScExternalRefCache maRefCache;
812 * Source document cache. This stores the original source document shell
813 * instances. They get purged after a certain period of time.
815 DocShellMap maDocShells;
818 * DocShells to unsaved but referenced documents. If not empty ask before saving!
819 * Move to maDocShells if document referenced here is saved
821 DocShellMap maUnsavedDocShells;
823 /** list of source documents that are managed by the link manager. */
824 LinkedDocMap maLinkedDocs;
827 * List of referencing cells that may contain external names. There is
828 * one list per source document.
830 RefCellMap maRefCells;
832 LinkListenerMap maLinkListeners;
834 NumFmtMap maNumFormatMap;
837 * List of external source document meta-data, used to keep track of
838 * external document identifiers.
840 std::vector<SrcFileData> maSrcFiles;
842 /** Status whether in reference marking state. See isInReferenceMarking(). */
843 bool mbInReferenceMarking:1;
846 * Controls whether or not to allow user interaction. We don't want any
847 * user interaction when calling from the API.
849 bool mbUserInteractionEnabled:1;
851 bool mbDocTimerEnabled:1;
853 AutoTimer maSrcDocTimer;
854 DECL_LINK(TimeOutHdl, Timer*, void);
857 #endif
859 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */