build fix
[LibreOffice.git] / sc / inc / externalrefmgr.hxx
blob4863757f9eb7e1e9ad4fecc6b34ea80e85de90a9
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 short 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 enum ReferencedFlag
139 UNREFERENCED,
140 REFERENCED_MARKED, // marked as referenced during store to file
141 REFERENCED_PERMANENT // permanently marked, e.g. from within interpreter
144 Table();
145 ~Table();
147 void clear();
150 * Add cell value to the cache.
152 * @param bSetCacheRange if true, mark this cell 'cached'. This is
153 * false _only when_ adding a range of cell
154 * values, for performance reasons.
156 SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef const & pToken, sal_uLong nFmtIndex = 0, bool bSetCacheRange = true);
157 SC_DLLPUBLIC TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = nullptr) const;
158 bool hasRow( SCROW nRow ) const;
159 /** Set/clear referenced status flag only if current status is not
160 REFERENCED_PERMANENT. */
161 void setReferenced( bool bReferenced );
162 /// Unconditionally set the reference status flag.
163 void setReferencedFlag( ReferencedFlag eFlag );
164 ReferencedFlag getReferencedFlag() const { return meReferenced;}
165 bool isReferenced() const;
166 /// Obtain a sorted vector of rows.
167 void getAllRows(::std::vector<SCROW>& rRows, SCROW nLow = 0, SCROW nHigh = MAXROW) const;
168 /// Returns the half-open range of used rows in this table. Returns [0,0) if table is empty.
169 SC_DLLPUBLIC ::std::pair< SCROW, SCROW > getRowRange() const;
170 /// Obtain a sorted vector of columns.
171 void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols, SCCOL nLow = 0, SCCOL nHigh = MAXCOL) const;
172 /// Returns the half-open range of used columns in the specified row. Returns [0,0) if row is empty.
173 SC_DLLPUBLIC ::std::pair< SCCOL, SCCOL > getColRange( SCROW nRow ) const;
174 void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
175 bool isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
177 void setCachedCell(SCCOL nCol, SCROW nRow);
178 void setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
181 * Call this to mark the entire table "cached". This will prevent all
182 * future attempts to access the source document even when non-cached
183 * cells are queried. In such case, non-cached cells are treated as
184 * empty cells. Useful when loading a document with own external data
185 * cache.
187 SC_DLLPUBLIC void setWholeTableCached();
188 private:
189 bool isInCachedRanges(SCCOL nCol, SCROW nRow) const;
190 TokenRef getEmptyOrNullToken(SCCOL nCol, SCROW nRow) const;
192 private:
193 /** Data cache */
194 RowsDataType maRows;
195 /** Collection of individual cached ranges. The table ranges are
196 * not used & always zero. */
197 ScRangeList maCachedRanges;
198 ReferencedFlag meReferenced;
201 typedef std::shared_ptr<Table> TableTypeRef;
202 typedef std::unordered_map< OUString, size_t, OUStringHash>
203 TableNameIndexMap;
205 ScExternalRefCache();
206 ~ScExternalRefCache();
208 const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const;
209 const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const;
212 * Get a cached cell data at specified cell location.
214 * @param nFileId file ID of an external document
215 * @param rTabName sheet name
216 * @param nCol
217 * @param nRow
219 * @return pointer to the token instance in the cache.
221 ScExternalRefCache::TokenRef getCellData(
222 sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex);
225 * Get a cached cell range data.
227 * @return a new token array instance. Note that <i>the caller must
228 * manage the life cycle of the returned instance</i>, which is
229 * guaranteed if the TokenArrayRef is properly used..
231 ScExternalRefCache::TokenArrayRef getCellRangeData(
232 sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange);
234 ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const OUString& rName);
235 void setRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, TokenArrayRef pArray);
236 bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName) const;
237 void setRangeName(sal_uInt16 nFileId, const OUString& rName);
239 void setCellData(sal_uInt16 nFileId, const OUString& rTabName,
240 SCCOL nCol, SCROW nRow, TokenRef const & pToken, sal_uLong nFmtIndex);
242 struct SingleRangeData
244 /** This name must be in upper-case. */
245 OUString maTableName;
246 ScMatrixRef mpRangeData;
248 void setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const ::std::vector<SingleRangeData>& rData,
249 const TokenArrayRef& pArray);
251 bool isDocInitialized(sal_uInt16 nFileId);
252 void initializeDoc(sal_uInt16 nFileId, const ::std::vector<OUString>& rTabNames, const OUString& rBaseName);
253 OUString getTableName(sal_uInt16 nFileId, size_t nCacheId) const;
254 void getAllTableNames(sal_uInt16 nFileId, ::std::vector<OUString>& rTabNames) const;
255 SCsTAB getTabSpan( sal_uInt16 nFileId, const OUString& rStartTabName, const OUString& rEndTabName ) const;
256 void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
259 * Set all tables of a document as referenced, used only during
260 * store-to-file.
261 * @returns <TRUE/> if ALL tables of ALL documents are marked.
263 bool setCacheDocReferenced( sal_uInt16 nFileId );
266 * Set a table as referenced, used only during store-to-file.
267 * @returns <TRUE/> if ALL tables of ALL documents are marked.
269 bool setCacheTableReferenced( sal_uInt16 nFileId, const OUString& rTabName, size_t nSheets );
270 void setAllCacheTableReferencedStati( bool bReferenced );
271 bool areAllCacheTablesReferenced() const { return maReferenced.mbAllReferenced;}
274 * Collect all cached non-empty cell positions, inferred directly from the
275 * cached data, not the cached range metadata stored separately in the
276 * Table.
278 void getAllCachedDataSpans( sal_uInt16 nFileId, sc::ColumnSpanSet& rSet ) const;
280 bool getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab, sal_uInt16 nFileId ) const;
282 private:
283 struct ReferencedStatus
285 struct DocReferenced
287 ::std::vector<bool> maTables;
288 bool mbAllTablesReferenced;
289 // Initially, documents have no tables but all referenced.
290 DocReferenced() : mbAllTablesReferenced(true) {}
292 typedef ::std::vector<DocReferenced> DocReferencedVec;
294 DocReferencedVec maDocs;
295 bool mbAllReferenced;
297 ReferencedStatus();
298 void reset( size_t nDocs );
299 void checkAllDocs();
301 } maReferenced;
302 void addCacheTableToReferenced( sal_uInt16 nFileId, size_t nIndex );
303 void addCacheDocToReferenced( sal_uInt16 nFileId );
304 public:
306 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
307 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew,
308 size_t* pnIndex, const OUString* pExtUrl);
311 * Clear all caches including the cache tables.
313 void clearCache(sal_uInt16 nFileId);
316 * Clear all caches but keep the tables. All cache tables will be empty
317 * after the call, but the tables will not be removed.
319 void clearCacheTables(sal_uInt16 nFileId);
321 private:
322 struct RangeHash
324 size_t operator()(const ScRange& rRange) const
326 const ScAddress& s = rRange.aStart;
327 const ScAddress& e = rRange.aEnd;
328 return s.Tab() + s.Col() + s.Row() + e.Tab() + e.Col() + e.Row();
332 typedef std::unordered_map<OUString, TokenArrayRef, OUStringHash> RangeNameMap;
333 typedef std::unordered_map<ScRange, TokenArrayRef, RangeHash> RangeArrayMap;
334 typedef std::unordered_map<OUString, OUString, OUStringHash> NamePairMap;
336 /** Represents data cached for a single external document. */
337 struct DocItem
339 /** The raw cache tables. */
340 ::std::vector<TableTypeRef> maTables;
341 /** Table name list in correct order, in both upper- and real-case. */
342 ::std::vector<TableName> maTableNames;
343 /** Table name to index map. The names must be stored upper-case. */
344 TableNameIndexMap maTableNameIndex;
345 /** Range name cache. */
346 RangeNameMap maRangeNames;
347 /** Token array cache for cell ranges. */
348 RangeArrayMap maRangeArrays;
349 /** Upper- to real-case mapping for range names. */
350 NamePairMap maRealRangeNameMap;
352 /** Either the base name that was stored as sheet name for CSV files if
353 sheet name is Sheet1, or Sheet1 name if sheet name is base name.
355 OUString maSingleTableNameAlias;
357 bool mbInitFromSource;
359 DocItem() : mbInitFromSource(false) {}
361 TableNameIndexMap::const_iterator findTableNameIndex( const OUString& rTabName ) const;
362 bool getTableDataIndex( const OUString& rTabName, size_t& rIndex ) const;
363 bool getSingleTableNameAlternative( OUString& rTabName ) const;
365 typedef std::unordered_map<sal_uInt16, DocItem> DocDataType;
366 DocItem* getDocItem(sal_uInt16 nFileId) const;
368 private:
369 mutable osl::Mutex maMtxDocs;
370 mutable DocDataType maDocs;
373 class SC_DLLPUBLIC ScExternalRefManager : public formula::ExternalReferenceHelper, public SfxListener
375 public:
377 typedef std::set<ScFormulaCell*> RefCellSet;
378 typedef std::unordered_map<sal_uInt16, RefCellSet> RefCellMap;
380 enum LinkUpdateType { LINK_MODIFIED, LINK_BROKEN };
383 * Base class for objects that need to listen to link updates. When a
384 * link to a certain external file is updated, the notify() method gets
385 * called.
387 class LinkListener
389 public:
390 LinkListener();
391 virtual ~LinkListener() = 0;
392 virtual void notify(sal_uInt16 nFileId, LinkUpdateType eType) = 0;
394 struct Hash
396 size_t operator() (const LinkListener* p) const
398 return reinterpret_cast<size_t>(p);
404 * Use this guard when performing something from the API that might query
405 * values from external references. Interpreting formula strings is one
406 * such example.
408 class SC_DLLPUBLIC ApiGuard
410 public:
411 ApiGuard(ScDocument* pDoc);
412 ~ApiGuard();
413 private:
414 ScExternalRefManager* mpMgr;
415 bool mbOldInteractionEnabled;
418 private:
419 /** Shell instance for a source document. */
420 struct SrcShell
422 SfxObjectShellRef maShell;
423 tools::Time maLastAccess;
425 SrcShell() : maLastAccess( tools::Time::SYSTEM ) {}
428 typedef std::unordered_map<sal_uInt16, SrcShell> DocShellMap;
429 typedef std::unordered_map<sal_uInt16, bool> LinkedDocMap;
431 typedef std::unordered_map<sal_uInt16, SvNumberFormatterMergeMap> NumFmtMap;
433 typedef std::unordered_set<LinkListener*, LinkListener::Hash> LinkListeners;
434 typedef std::unordered_map<sal_uInt16, LinkListeners> LinkListenerMap;
436 public:
437 /** Source document meta-data container. */
438 struct SrcFileData
440 OUString maFileName; /// original file name as loaded from the file.
441 OUString maRealFileName; /// file name created from the relative name.
442 OUString maRelativeName;
443 OUString maFilterName;
444 OUString maFilterOptions;
446 void maybeCreateRealFileName(const OUString& rOwnDocName);
449 public:
450 explicit ScExternalRefManager(ScDocument* pDoc);
451 virtual ~ScExternalRefManager() override;
453 virtual OUString getCacheTableName(sal_uInt16 nFileId, size_t nTabIndex) const override;
456 * Get a cache table instance for specified table and table index. Unlike
457 * the other method that takes a table name, this method does not create a
458 * new table when a table is not available for specified index.
460 * @param nFileId file ID
461 * @param nTabIndex cache table index
463 * @return shared_ptr to the cache table instance
465 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
468 * Get a cache table instance for specified file and table name. If the
469 * table instance is not already present, it'll instantiate a new one and
470 * append it to the end of the table array. <I>It's important to be
471 * aware of this fact especially for multi-table ranges for which
472 * table orders are critical.</I>
474 * Excel filter calls this method to populate the cache table from the
475 * XCT/CRN records. ODF import calls it for cached tables for external
476 * references.
478 * @param nFileId file ID
479 * @param rTabName table name
480 * @param bCreateNew if true, create a new table instance if it's not
481 * already present. If false, it returns NULL if the
482 * specified table's cache doesn't exist.
483 * @param pnIndex if non-NULL pointer is passed, it stores the internal
484 * index of a cache table instance.
485 * @param pExtUrl if non-NULL and bCreateNew==true, the base name will be
486 * propagated as an alias for the first table (and removed
487 * later if further tables are created).
489 * @return shared_ptr to the cache table instance
491 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew,
492 size_t* pnIndex = nullptr, const OUString* pExtUrl = nullptr);
494 /** Returns a vector containing all (real) table names and cache tables of
495 the specified file.
497 The index in the returned vector corresponds to the table index used to
498 access the cache table, e.g. in getCacheTable().
500 void getAllCachedTableNames(sal_uInt16 nFileId, ::std::vector<OUString>& rTabNames) const;
503 * Get the span (distance+sign(distance)) of two sheets of a specified
504 * file.
506 * @param nFileId file ID
507 * @param rStartTabName name of first sheet (sheet1)
508 * @param rEndTabName name of second sheet (sheet2)
510 * @return span
511 * 1 if sheet2 == sheet1
512 * > 1 if sheet2 > sheet1
513 * < -1 if sheet2 < sheet1
514 * -1 if nFileId or rStartTabName not found
515 * 0 if rEndTabName not found
517 SCsTAB getCachedTabSpan(
518 sal_uInt16 nFileId, const OUString& rStartTabName, const OUString& rEndTabName) const;
521 * Get all unique number format indices that are used in the cache tables.
522 * The retrieved indices are sorted in ascending order.
524 * @param rNumFmts (reference) all unique number format indices.
526 void getAllCachedNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
528 sal_uInt16 getExternalFileCount() const;
531 * Mark all tables as referenced that are used by any LinkListener, used
532 * only during store-to-file.
534 void markUsedByLinkListeners();
536 void markUsedExternalRefCells();
539 * Set a table as referenced, used only during store-to-file.
540 * @returns <TRUE/> if ALL tables of ALL external documents are marked.
542 bool setCacheTableReferenced( sal_uInt16 nFileId, const OUString& rTabName, size_t nSheets );
543 void setAllCacheTableReferencedStati( bool bReferenced );
546 * @returns <TRUE/> if setAllCacheTableReferencedStati(false) was called,
547 * <FALSE/> if setAllCacheTableReferencedStati(true) was called.
549 bool isInReferenceMarking() const { return mbInReferenceMarking; }
551 void storeRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, const ScTokenArray& rArray);
553 ScExternalRefCache::TokenRef getSingleRefToken(
554 sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell,
555 const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt = nullptr);
558 * Get an array of tokens that consist of the specified external cell
559 * range.
561 * @param nFileId file ID for an external document
562 * @param rTabName referenced sheet name
563 * @param rRange referenced cell range
564 * @param pCurPos current cursor position to keep track of cells that
565 * reference an external data.
567 * @return shared_ptr to a token array instance. <i>The caller must not
568 * delete the instance returned by this method.</i>
570 ScExternalRefCache::TokenArrayRef getDoubleRefTokens(
571 sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange, const ScAddress* pCurPos);
574 * Get an array of tokens corresponding with a specified name in a
575 * specified file.
577 * @param pCurPos current cell address where this name token is used.
578 * This is purely to keep track of all cells containing
579 * external names for refreshing purposes. If this is
580 * NULL, then the cell will not be added to the list.
582 * @return shared_ptr to array of tokens composing the name
584 ScExternalRefCache::TokenArrayRef getRangeNameTokens(
585 sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos = nullptr);
587 bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName);
589 OUString getOwnDocumentName() const;
590 bool isOwnDocument(const OUString& rFile) const;
593 * Takes a flat file name, and convert it to an absolute URL path. An
594 * absolute URL path begins with 'file:///.
596 * @param rFile file name to convert
598 void convertToAbsName(OUString& rFile) const;
599 sal_uInt16 getExternalFileId(const OUString& rFile);
602 * It returns a pointer to the name of the URI associated with a given
603 * external file ID. In case the original document has moved, it returns
604 * an URI adjusted for the relocation.
606 * @param nFileId file ID for an external document
607 * @param bForceOriginal If true, it always returns the original document
608 * URI even if the referring document has relocated.
609 * If false, it returns an URI adjusted for
610 * relocated document.
612 * @return const OUString* external document URI.
614 const OUString* getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal = false);
617 * Get all cached external file names as an array. Array indices of the
618 * returned name array correspond with external file ID's.
620 std::vector<OUString> getAllCachedExternalFileNames() const;
622 bool hasExternalFile(sal_uInt16 nFileId) const;
623 bool hasExternalFile(const OUString& rFile) const;
624 const SrcFileData* getExternalFileData(sal_uInt16 nFileId) const;
626 const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const;
627 const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const;
628 void clearCache(sal_uInt16 nFileId);
629 bool refreshSrcDocument(sal_uInt16 nFileId);
630 void breakLink(sal_uInt16 nFileId);
631 void switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter);
634 * Set a relative file path for the specified file ID. Note that the
635 * caller must ensure that the passed URL is a valid relative URL.
637 * @param nFileId file ID for an external document
638 * @param rRelUrl relative URL
640 void setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl);
643 * Set the filter name and options if any for a given source document.
644 * These values get reset when the source document ever gets reloaded.
646 * @param nFileId
647 * @param rFilterName
648 * @param rOptions
650 void setFilterData(sal_uInt16 nFileId, const OUString& rFilterName, const OUString& rOptions);
652 void clear();
654 bool hasExternalData() const;
657 * Re-generates relative names for all stored source files. This is
658 * necessary when exporting to an ods document, to ensure that all source
659 * files have their respective relative names for xlink:href export.
661 * @param rBaseFileUrl Absolute URL of the content.xml fragment of the
662 * document being exported.
664 void resetSrcFileData(const OUString& rBaseFileUrl);
667 * Replace the original URL with the real URL that was generated from the relative URL.
669 void updateAbsAfterLoad();
672 * Stop tracking a specific formula cell.
674 * @param pCell pointer to cell that formerly contained external
675 * reference.
677 void removeRefCell(ScFormulaCell* pCell);
680 * Register a new link listener to a specified external document. Note
681 * that the caller is responsible for managing the life cycle of the
682 * listener object.
684 void addLinkListener(sal_uInt16 nFileId, LinkListener* pListener);
687 * Remove an existing link listener. Note that removing a listener
688 * pointer here does not delete the listener object instance.
690 void removeLinkListener(sal_uInt16 nFileId, LinkListener* pListener);
692 void removeLinkListener(LinkListener* pListener);
695 * Notify all listeners that are listening to a specified external
696 * document.
698 * @param nFileId file ID for an external document.
700 void notifyAllLinkListeners(sal_uInt16 nFileId, LinkUpdateType eType);
703 * Check if the file specified by the path is a legitimate file that
704 * exists & can be loaded.
706 bool isFileLoadable(const OUString& rFile) const;
708 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
711 * If we still contain unsaved files we should warn the user before saving
713 * @return true if the document still contains references to an unsaved file
715 bool containsUnsavedReferences() const { return !maUnsavedDocShells.empty(); }
717 void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
719 * Add a cell to reference the same files as the template cell.
721 void insertRefCellFromTemplate( ScFormulaCell* pTemplateCell, ScFormulaCell* pCell );
723 bool hasCellExternalReference(const ScAddress& rCell);
725 void enableDocTimer( bool bEnable );
727 /** Add all known external files to the LinkManager. */
728 void addFilesToLinkManager();
730 private:
731 ScExternalRefManager(const ScExternalRefManager&) = delete;
733 void refreshAllRefCells(sal_uInt16 nFileId);
735 void fillCellFormat(sal_uLong nFmtIndex, ScExternalRefCache::CellFormat* pFmt) const;
737 bool getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab, sal_uInt16 nFileId ) const;
739 ScExternalRefCache::TokenRef getSingleRefTokenFromSrcDoc(
740 sal_uInt16 nFileId, ScDocument* pSrcDoc, const ScAddress& rPos,
741 ScExternalRefCache::CellFormat* pFmt);
744 * Retrieve a range token array from a source document instance.
746 * @param pSrcDoc pointer to the source document instance.
747 * @param rTabName name of the first table.
748 * @param rRange range specified. Upon successful retrieval, this range
749 * gets modified to contain the correct table IDs, and in
750 * case the range is larger than the data area of the source
751 * document, it gets reduced to the data area.
752 * @param rCacheData an array of structs, with each struct containing the
753 * table name and the data in the specified range.
755 * @return range token array
757 ScExternalRefCache::TokenArrayRef getDoubleRefTokensFromSrcDoc(
758 ScDocument* pSrcDoc, const OUString& rTabName, ScRange& rRange,
759 ::std::vector<ScExternalRefCache::SingleRangeData>& rCacheData);
762 * Retrieve range name token array from a source document instance.
764 * @param nFileId file ID of the source document.
765 * @param pSrcDoc pointer to the source document instance
766 * @param rName range name to retrieve. Note that the range name lookup
767 * is case <i>in</i>-sensitive, and upon successful retrieval
768 * of the range name array, this name gets updated to the
769 * actual range name with the correct casing.
771 * @return range name token array
773 static ScExternalRefCache::TokenArrayRef getRangeNameTokensFromSrcDoc(
774 sal_uInt16 nFileId, ScDocument* pSrcDoc, OUString& rName);
776 ScDocument* getInMemorySrcDocument(sal_uInt16 nFileId);
777 ScDocument* getSrcDocument(sal_uInt16 nFileId);
778 SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter);
781 * Caller must ensure that the passed shell is not already stored.
783 ScDocument& cacheNewDocShell( sal_uInt16 nFileId, SrcShell& rSrcShell );
785 void maybeLinkExternalFile( sal_uInt16 nFileId, bool bDeferFilterDetection = false );
788 * Try to create a "real" file name from the relative path. The original
789 * file name may not point to the real document when the referencing and
790 * referenced documents have been moved.
792 * For the real file name to be created, the relative name should not be
793 * empty before calling this method, or the real file name will not be
794 * created.
796 * @param nFileId file ID for an external document
798 void maybeCreateRealFileName(sal_uInt16 nFileId);
801 * Purge those source document instances that have not been accessed for
802 * the specified duration.
804 * @param nTimeOut time out value in 100th of a second
806 void purgeStaleSrcDocument(sal_Int32 nTimeOut);
808 sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, const ScDocument* pSrcDoc);
811 * If in maUnsavedDocShells move it to maDocShells and create a correct
812 * external reference entry
814 * @param Pointer to the newly saved DocumentShell
816 void transformUnsavedRefToSavedRef( SfxObjectShell* pShell );
818 private:
819 ScDocument* mpDoc;
821 /** cache of referenced ranges and names from source documents. */
822 ScExternalRefCache maRefCache;
825 * Source document cache. This stores the original source document shell
826 * instances. They get purged after a certain period of time.
828 DocShellMap maDocShells;
831 * DocShells to unsaved but referenced documents. If not empty ask before saving!
832 * Move to maDocShells if document referenced here is saved
834 DocShellMap maUnsavedDocShells;
836 /** list of source documents that are managed by the link manager. */
837 LinkedDocMap maLinkedDocs;
840 * List of referencing cells that may contain external names. There is
841 * one list per source document.
843 RefCellMap maRefCells;
845 LinkListenerMap maLinkListeners;
847 NumFmtMap maNumFormatMap;
850 * List of external source document meta-data, used to keep track of
851 * external document identifiers.
853 std::vector<SrcFileData> maSrcFiles;
855 /** Status whether in reference marking state. See isInReferenceMarking(). */
856 bool mbInReferenceMarking:1;
859 * Controls whether or not to allow user interaction. We don't want any
860 * user interaction when calling from the API.
862 bool mbUserInteractionEnabled:1;
864 bool mbDocTimerEnabled:1;
866 AutoTimer maSrcDocTimer;
867 DECL_LINK(TimeOutHdl, Timer*, void);
870 #endif
872 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */