LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sc / inc / externalrefmgr.hxx
blob3fe5e591ebfd10c1ada31eae1449f021b937235b
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 #pragma once
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>
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 <o3tl/sorted_vector.hxx>
42 #include <formula/ExternalReferenceHelper.hxx>
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& rDoc, 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 SetDoRefresh(bool b);
68 private:
69 ScExternalRefLink() = delete;
70 ScExternalRefLink(const ScExternalRefLink&) = delete;
72 sal_uInt16 mnFileId;
73 ScDocument& mrDoc;
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& rUpper, 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, SCROW nHigh) const;
148 void getAllRows(::std::vector<SCROW>& rRows) const;
149 /// Returns the half-open range of used rows in this table. Returns [0,0) if table is empty.
150 SC_DLLPUBLIC ::std::pair< SCROW, SCROW > getRowRange() const;
151 /// Obtain a sorted vector of columns.
152 void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols, SCCOL nLow, SCCOL nHigh) const;
153 void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols) const;
154 /// Returns the half-open range of used columns in the specified row. Returns [0,0) if row is empty.
155 SC_DLLPUBLIC ::std::pair< SCCOL, SCCOL > getColRange( SCROW nRow ) const;
156 void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
157 bool isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
159 void setCachedCell(SCCOL nCol, SCROW nRow);
160 void setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
163 * Call this to mark the entire table "cached". This will prevent all
164 * future attempts to access the source document even when non-cached
165 * cells are queried. In such case, non-cached cells are treated as
166 * empty cells. Useful when loading a document with own external data
167 * cache.
169 SC_DLLPUBLIC void setWholeTableCached();
170 private:
171 bool isInCachedRanges(SCCOL nCol, SCROW nRow) const;
172 TokenRef getEmptyOrNullToken(SCCOL nCol, SCROW nRow) const;
173 template< typename P >
174 void getAllRows(::std::vector<SCROW>& rRows, P predicate) const;
175 template< typename P >
176 void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols, P predicate) const;
178 private:
179 /** Data cache */
180 RowsDataType maRows;
181 /** Collection of individual cached ranges. The table ranges are
182 * not used & always zero. */
183 ScRangeList maCachedRanges;
184 bool mbReferenced;
187 typedef std::shared_ptr<Table> TableTypeRef;
188 typedef std::unordered_map< OUString, size_t>
189 TableNameIndexMap;
191 ScExternalRefCache();
192 ~ScExternalRefCache();
194 const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const;
195 const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const;
198 * Get a cached cell data at specified cell location.
200 * @param nFileId file ID of an external document
201 * @param rTabName sheet name
202 * @param nCol
203 * @param nRow
205 * @return pointer to the token instance in the cache.
207 ScExternalRefCache::TokenRef getCellData(
208 sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex);
211 * Get a cached cell range data.
213 * @return a new token array instance. Note that <i>the caller must
214 * manage the life cycle of the returned instance</i>, which is
215 * guaranteed if the TokenArrayRef is properly used...
217 ScExternalRefCache::TokenArrayRef getCellRangeData(
218 sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange);
220 ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const OUString& rName);
221 void setRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, TokenArrayRef pArray);
222 bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName) const;
223 void setRangeName(sal_uInt16 nFileId, const OUString& rName);
225 void setCellData(sal_uInt16 nFileId, const OUString& rTabName,
226 SCCOL nCol, SCROW nRow, TokenRef const & pToken, sal_uLong nFmtIndex);
228 struct SingleRangeData
230 /** This name must be in upper-case. */
231 OUString maTableName;
232 ScMatrixRef mpRangeData;
234 void setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const ::std::vector<SingleRangeData>& rData,
235 const TokenArrayRef& pArray);
237 bool isDocInitialized(sal_uInt16 nFileId);
238 void initializeDoc(sal_uInt16 nFileId, const ::std::vector<OUString>& rTabNames, const OUString& rBaseName);
239 OUString getTableName(sal_uInt16 nFileId, size_t nCacheId) const;
240 void getAllTableNames(sal_uInt16 nFileId, ::std::vector<OUString>& rTabNames) const;
241 SCTAB getTabSpan( sal_uInt16 nFileId, const OUString& rStartTabName, const OUString& rEndTabName ) const;
242 void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
245 * Set all tables of a document as referenced, used only during
246 * store-to-file.
247 * @returns <TRUE/> if ALL tables of ALL documents are marked.
249 bool setCacheDocReferenced( sal_uInt16 nFileId );
252 * Set a table as referenced, used only during store-to-file.
253 * @returns <TRUE/> if ALL tables of ALL documents are marked.
255 bool setCacheTableReferenced( sal_uInt16 nFileId, const OUString& rTabName, size_t nSheets );
256 void setAllCacheTableReferencedStati( bool bReferenced );
257 bool areAllCacheTablesReferenced() const { return maReferenced.mbAllReferenced;}
260 * Collect all cached non-empty cell positions, inferred directly from the
261 * cached data, not the cached range metadata stored separately in the
262 * Table.
264 void getAllCachedDataSpans( const ScDocument& rSrcDoc, sal_uInt16 nFileId, sc::ColumnSpanSet& rSet ) const;
266 bool getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab, sal_uInt16 nFileId ) const;
268 private:
269 struct ReferencedStatus
271 struct DocReferenced
273 ::std::vector<bool> maTables;
274 bool mbAllTablesReferenced;
275 // Initially, documents have no tables but all referenced.
276 DocReferenced() : mbAllTablesReferenced(true) {}
278 typedef ::std::vector<DocReferenced> DocReferencedVec;
280 DocReferencedVec maDocs;
281 bool mbAllReferenced;
283 ReferencedStatus();
284 void reset( size_t nDocs );
285 void checkAllDocs();
287 } maReferenced;
288 void addCacheTableToReferenced( sal_uInt16 nFileId, size_t nIndex );
289 void addCacheDocToReferenced( sal_uInt16 nFileId );
290 public:
292 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
293 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew,
294 size_t* pnIndex, const OUString* pExtUrl);
297 * Clear all caches including the cache tables.
299 void clearCache(sal_uInt16 nFileId);
302 * Clear all caches but keep the tables. All cache tables will be empty
303 * after the call, but the tables will not be removed.
305 void clearCacheTables(sal_uInt16 nFileId);
307 // Get the fake doc used to pass to methods that need an ScDocument in order to do row/col validation
308 const ScDocument* getFakeDoc() const { return mxFakeDoc.get(); }
310 private:
311 struct RangeHash
313 size_t operator()(const ScRange& rRange) const
315 const ScAddress& s = rRange.aStart;
316 const ScAddress& e = rRange.aEnd;
317 size_t hash = 17;
318 hash = hash * 37 + s.Tab();
319 hash = hash * 37 + s.Col();
320 hash = hash * 37 + s.Row();
321 hash = hash * 37 + e.Tab();
322 hash = hash * 37 + e.Col();
323 hash = hash * 37 + e.Row();
324 return hash;
328 typedef std::unordered_map<OUString, TokenArrayRef> RangeNameMap;
329 typedef std::unordered_map<ScRange, TokenArrayRef, RangeHash> RangeArrayMap;
330 typedef std::unordered_map<OUString, OUString> NamePairMap;
332 /** Represents data cached for a single external document. */
333 struct DocItem
335 /** The raw cache tables. */
336 ::std::vector<TableTypeRef> maTables;
337 /** Table name list in correct order, in both upper- and real-case. */
338 ::std::vector<TableName> maTableNames;
339 /** Table name to index map. The names must be stored upper-case. */
340 TableNameIndexMap maTableNameIndex;
341 /** Range name cache. */
342 RangeNameMap maRangeNames;
343 /** Token array cache for cell ranges. */
344 RangeArrayMap maRangeArrays;
345 /** Upper- to real-case mapping for range names. */
346 NamePairMap maRealRangeNameMap;
348 /** Either the base name that was stored as sheet name for CSV files if
349 sheet name is Sheet1, or Sheet1 name if sheet name is base name.
351 OUString maSingleTableNameAlias;
353 bool mbInitFromSource;
355 DocItem() : mbInitFromSource(false) {}
357 TableNameIndexMap::const_iterator findTableNameIndex( const OUString& rTabName ) const;
358 bool getTableDataIndex( const OUString& rTabName, size_t& rIndex ) const;
359 bool getSingleTableNameAlternative( OUString& rTabName ) const;
361 typedef std::unordered_map<sal_uInt16, DocItem> DocDataType;
362 DocItem* getDocItem(sal_uInt16 nFileId) const;
364 private:
365 mutable osl::Mutex maMtxDocs;
366 mutable DocDataType maDocs;
367 ScDocumentUniquePtr mxFakeDoc; // just to have something to pass to the methods that need to validate columns/rows
370 class SC_DLLPUBLIC ScExternalRefManager final : public formula::ExternalReferenceHelper, public SfxListener
372 public:
374 typedef std::set<ScFormulaCell*> RefCellSet;
375 typedef std::unordered_map<sal_uInt16, RefCellSet> RefCellMap;
377 enum LinkUpdateType { LINK_MODIFIED, LINK_BROKEN, OH_NO_WE_ARE_GOING_TO_DIE };
380 * Base class for objects that need to listen to link updates. When a
381 * link to a certain external file is updated, the notify() method gets
382 * called.
384 class SAL_DLLPRIVATE LinkListener
386 public:
387 LinkListener();
388 virtual ~LinkListener() COVERITY_NOEXCEPT_FALSE = 0;
389 virtual void notify(sal_uInt16 nFileId, LinkUpdateType eType) = 0;
393 * Use this guard when performing something from the API that might query
394 * values from external references. Interpreting formula strings is one
395 * such example.
397 class SC_DLLPUBLIC ApiGuard
399 public:
400 ApiGuard(const ScDocument& rDoc);
401 ~ApiGuard();
402 private:
403 ScExternalRefManager* mpMgr;
404 bool mbOldInteractionEnabled;
407 private:
408 /** Shell instance for a source document. */
409 struct SrcShell
411 SfxObjectShellRef maShell;
412 tools::Time maLastAccess;
414 SrcShell() : maLastAccess( tools::Time::SYSTEM ) {}
417 typedef std::unordered_map<sal_uInt16, SrcShell> DocShellMap;
418 typedef std::unordered_map<sal_uInt16, bool> LinkedDocMap;
420 typedef std::unordered_map<sal_uInt16, SvNumberFormatterMergeMap> NumFmtMap;
422 typedef o3tl::sorted_vector<LinkListener*> LinkListeners;
423 typedef std::unordered_map<sal_uInt16, LinkListeners> LinkListenerMap;
425 public:
426 /** Source document meta-data container. */
427 struct SAL_DLLPRIVATE SrcFileData
429 OUString maFileName; /// original file name as loaded from the file.
430 OUString maRealFileName; /// file name created from the relative name.
431 OUString maRelativeName;
432 OUString maFilterName;
433 OUString maFilterOptions;
435 void maybeCreateRealFileName(const OUString& rOwnDocName);
438 public:
439 explicit ScExternalRefManager(ScDocument& rDoc);
440 virtual ~ScExternalRefManager() override;
442 virtual OUString getCacheTableName(sal_uInt16 nFileId, size_t nTabIndex) const override;
445 * Get a cache table instance for specified table and table index. Unlike
446 * the other method that takes a table name, this method does not create a
447 * new table when a table is not available for specified index.
449 * @param nFileId file ID
450 * @param nTabIndex cache table index
452 * @return shared_ptr to the cache table instance
454 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
457 * Get a cache table instance for specified file and table name. If the
458 * table instance is not already present, it'll instantiate a new one and
459 * append it to the end of the table array. <I>It's important to be
460 * aware of this fact especially for multi-table ranges for which
461 * table orders are critical.</I>
463 * Excel filter calls this method to populate the cache table from the
464 * XCT/CRN records. ODF import calls it for cached tables for external
465 * references.
467 * @param nFileId file ID
468 * @param rTabName table name
469 * @param bCreateNew if true, create a new table instance if it's not
470 * already present. If false, it returns NULL if the
471 * specified table's cache doesn't exist.
472 * @param pnIndex if non-NULL pointer is passed, it stores the internal
473 * index of a cache table instance.
474 * @param pExtUrl if non-NULL and bCreateNew==true, the base name will be
475 * propagated as an alias for the first table (and removed
476 * later if further tables are created).
478 * @return shared_ptr to the cache table instance
480 ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew,
481 size_t* pnIndex = nullptr, const OUString* pExtUrl = nullptr);
483 /** Returns a vector containing all (real) table names and cache tables of
484 the specified file.
486 The index in the returned vector corresponds to the table index used to
487 access the cache table, e.g. in getCacheTable().
489 void getAllCachedTableNames(sal_uInt16 nFileId, ::std::vector<OUString>& rTabNames) const;
492 * Get the span (distance+sign(distance)) of two sheets of a specified
493 * file.
495 * @param nFileId file ID
496 * @param rStartTabName name of first sheet (sheet1)
497 * @param rEndTabName name of second sheet (sheet2)
499 * @return span
500 * 1 if sheet2 == sheet1
501 * > 1 if sheet2 > sheet1
502 * < -1 if sheet2 < sheet1
503 * -1 if nFileId or rStartTabName not found
504 * 0 if rEndTabName not found
506 SCTAB getCachedTabSpan(
507 sal_uInt16 nFileId, const OUString& rStartTabName, const OUString& rEndTabName) const;
510 * Get all unique number format indices that are used in the cache tables.
511 * The retrieved indices are sorted in ascending order.
513 * @param rNumFmts (reference) all unique number format indices.
515 void getAllCachedNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
517 sal_uInt16 getExternalFileCount() const;
520 * Mark all tables as referenced that are used by any LinkListener, used
521 * only during store-to-file.
523 void markUsedByLinkListeners();
525 void markUsedExternalRefCells();
528 * Set a table as referenced, used only during store-to-file.
529 * @returns <TRUE/> if ALL tables of ALL external documents are marked.
531 bool setCacheTableReferenced( sal_uInt16 nFileId, const OUString& rTabName, size_t nSheets );
532 void setAllCacheTableReferencedStati( bool bReferenced );
535 * @returns <TRUE/> if setAllCacheTableReferencedStati(false) was called,
536 * <FALSE/> if setAllCacheTableReferencedStati(true) was called.
538 bool isInReferenceMarking() const { return mbInReferenceMarking; }
540 void storeRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, const ScTokenArray& rArray);
542 ScExternalRefCache::TokenRef getSingleRefToken(
543 sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell,
544 const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt = nullptr);
547 * Get an array of tokens that consist of the specified external cell
548 * range.
550 * @param nFileId file ID for an external document
551 * @param rTabName referenced sheet name
552 * @param rRange referenced cell range
553 * @param pCurPos current cursor position to keep track of cells that
554 * reference an external data.
556 * @return shared_ptr to a token array instance. <i>The caller must not
557 * delete the instance returned by this method.</i>
559 ScExternalRefCache::TokenArrayRef getDoubleRefTokens(
560 sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange, const ScAddress* pCurPos);
563 * Get an array of tokens corresponding with a specified name in a
564 * specified file.
566 * @param pCurPos current cell address where this name token is used.
567 * This is purely to keep track of all cells containing
568 * external names for refreshing purposes. If this is
569 * NULL, then the cell will not be added to the list.
571 * @return shared_ptr to array of tokens composing the name
573 ScExternalRefCache::TokenArrayRef getRangeNameTokens(
574 sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos = nullptr);
576 bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName);
578 OUString getOwnDocumentName() const;
579 bool isOwnDocument(std::u16string_view rFile) const;
582 * Takes a flat file name, and convert it to an absolute URL path. An
583 * absolute URL path begins with 'file:///.
585 * @param rFile file name to convert
587 void convertToAbsName(OUString& rFile) const;
588 sal_uInt16 getExternalFileId(const OUString& rFile);
591 * It returns a pointer to the name of the URI associated with a given
592 * external file ID. In case the original document has moved, it returns
593 * a URI adjusted for the relocation.
595 * @param nFileId file ID for an external document
596 * @param bForceOriginal If true, it always returns the original document
597 * URI even if the referring document has relocated.
598 * If false, it returns a URI adjusted for
599 * relocated document.
601 * @return const OUString* external document URI.
603 const OUString* getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal = false);
606 * Reindex external file references to skip unused files, if skipping is enabled.
608 sal_uInt16 convertFileIdToUsedFileId(sal_uInt16 nFileId);
609 void setSkipUnusedFileIds(std::vector<sal_uInt16>& pExternFileIds);
610 void disableSkipUnusedFileIds();
613 * Get all cached external file names as an array. Array indices of the
614 * returned name array correspond with external file ID's.
616 std::vector<OUString> getAllCachedExternalFileNames() const;
618 bool hasExternalFile(sal_uInt16 nFileId) const;
619 bool hasExternalFile(const OUString& rFile) const;
620 const SrcFileData* getExternalFileData(sal_uInt16 nFileId) const;
622 const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const;
623 const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const;
624 void clearCache(sal_uInt16 nFileId);
625 bool refreshSrcDocument(sal_uInt16 nFileId);
626 void breakLink(sal_uInt16 nFileId);
627 void switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter);
630 * Set a relative file path for the specified file ID. Note that the
631 * caller must ensure that the passed URL is a valid relative URL.
633 * @param nFileId file ID for an external document
634 * @param rRelUrl relative URL
636 void setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl);
639 * Set the filter name and options if any for a given source document.
640 * These values get reset when the source document ever gets reloaded.
642 * @param nFileId
643 * @param rFilterName
644 * @param rOptions
646 void setFilterData(sal_uInt16 nFileId, const OUString& rFilterName, const OUString& rOptions);
648 void clear();
650 bool hasExternalData() const;
653 * Re-generates relative names for all stored source files. This is
654 * necessary when exporting to an ods document, to ensure that all source
655 * files have their respective relative names for xlink:href export.
657 * @param rBaseFileUrl Absolute URL of the content.xml fragment of the
658 * document being exported.
660 void resetSrcFileData(const OUString& rBaseFileUrl);
663 * Replace the original URL with the real URL that was generated from the relative URL.
665 void updateAbsAfterLoad();
668 * Stop tracking a specific formula cell.
670 * @param pCell pointer to cell that formerly contained external
671 * reference.
673 void removeRefCell(ScFormulaCell* pCell);
676 * Register a new link listener to a specified external document. Note
677 * that the caller is responsible for managing the life cycle of the
678 * listener object.
680 void addLinkListener(sal_uInt16 nFileId, LinkListener* pListener);
683 * Remove an existing link listener. Note that removing a listener
684 * pointer here does not delete the listener object instance.
686 void removeLinkListener(sal_uInt16 nFileId, LinkListener* pListener);
688 void removeLinkListener(LinkListener* pListener);
691 * Notify all listeners that are listening to a specified external
692 * document.
694 * @param nFileId file ID for an external document.
696 void notifyAllLinkListeners(sal_uInt16 nFileId, LinkUpdateType eType);
699 * Check if the file specified by the path is a legitimate file that
700 * exists & can be loaded.
702 bool isFileLoadable(const OUString& rFile) const;
704 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
707 * If we still contain unsaved files we should warn the user before saving
709 * @return true if the document still contains references to an unsaved file
711 bool containsUnsavedReferences() const { return !maUnsavedDocShells.empty(); }
713 void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
715 * Add a cell to reference the same files as the template cell.
717 void insertRefCellFromTemplate( ScFormulaCell* pTemplateCell, ScFormulaCell* pCell );
719 bool hasCellExternalReference(const ScAddress& rCell);
721 void enableDocTimer( bool bEnable );
723 /** Add all known external files to the LinkManager. */
724 void addFilesToLinkManager();
726 private:
727 ScExternalRefManager(const ScExternalRefManager&) = delete;
729 void refreshAllRefCells(sal_uInt16 nFileId);
731 void fillCellFormat(sal_uLong nFmtIndex, ScExternalRefCache::CellFormat* pFmt) const;
733 bool getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab, sal_uInt16 nFileId ) const;
735 ScExternalRefCache::TokenRef getSingleRefTokenFromSrcDoc(
736 sal_uInt16 nFileId, ScDocument& rSrcDoc, const ScAddress& rPos,
737 ScExternalRefCache::CellFormat* pFmt);
740 * Retrieve a range token array from a source document instance.
742 * @param rSrcDoc reference to the source document instance.
743 * @param rTabName name of the first table.
744 * @param rRange range specified. Upon successful retrieval, this range
745 * gets modified to contain the correct table IDs, and in
746 * case the range is larger than the data area of the source
747 * document, it gets reduced to the data area.
748 * @param rCacheData an array of structs, with each struct containing the
749 * table name and the data in the specified range.
751 * @return range token array
753 ScExternalRefCache::TokenArrayRef getDoubleRefTokensFromSrcDoc(
754 const ScDocument& rSrcDoc, const OUString& rTabName, ScRange& rRange,
755 ::std::vector<ScExternalRefCache::SingleRangeData>& rCacheData);
758 * Retrieve range name token array from a source document instance.
760 * @param nFileId file ID of the source document.
761 * @param rSrcDoc reference to the source document instance
762 * @param rName range name to retrieve. Note that the range name lookup
763 * is case <i>in</i>-sensitive, and upon successful retrieval
764 * of the range name array, this name gets updated to the
765 * actual range name with the correct casing.
767 * @return range name token array
769 static ScExternalRefCache::TokenArrayRef getRangeNameTokensFromSrcDoc(
770 sal_uInt16 nFileId, const ScDocument& rSrcDoc, OUString& rName);
772 ScDocument* getInMemorySrcDocument(sal_uInt16 nFileId);
773 ScDocument* getSrcDocument(sal_uInt16 nFileId);
774 SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter);
777 * Caller must ensure that the passed shell is not already stored.
779 ScDocument& cacheNewDocShell( sal_uInt16 nFileId, SrcShell& rSrcShell );
781 void maybeLinkExternalFile( sal_uInt16 nFileId, bool bDeferFilterDetection = false );
784 * Try to create a "real" file name from the relative path. The original
785 * file name may not point to the real document when the referencing and
786 * referenced documents have been moved.
788 * For the real file name to be created, the relative name should not be
789 * empty before calling this method, or the real file name will not be
790 * created.
792 * @param nFileId file ID for an external document
794 void maybeCreateRealFileName(sal_uInt16 nFileId);
797 * Purge those source document instances that have not been accessed for
798 * the specified duration.
800 * @param nTimeOut time out value in 100th of a second
802 void purgeStaleSrcDocument(sal_Int32 nTimeOut);
804 sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, const ScDocument& rSrcDoc);
807 * If in maUnsavedDocShells move it to maDocShells and create a correct
808 * external reference entry
810 * @param Pointer to the newly saved DocumentShell
812 void transformUnsavedRefToSavedRef( SfxObjectShell* pShell );
814 private:
815 ScDocument& mrDoc;
817 /** cache of referenced ranges and names from source documents. */
818 ScExternalRefCache maRefCache;
821 * Source document cache. This stores the original source document shell
822 * instances. They get purged after a certain period of time.
824 DocShellMap maDocShells;
827 * DocShells to unsaved but referenced documents. If not empty ask before saving!
828 * Move to maDocShells if document referenced here is saved
830 DocShellMap maUnsavedDocShells;
832 /** list of source documents that are managed by the link manager. */
833 LinkedDocMap maLinkedDocs;
836 * List of referencing cells that may contain external names. There is
837 * one list per source document.
839 RefCellMap maRefCells;
841 LinkListenerMap maLinkListeners;
843 NumFmtMap maNumFormatMap;
846 * List of external source document meta-data, used to keep track of
847 * external document identifiers.
849 std::vector<SrcFileData> maSrcFiles;
851 /** Status whether in reference marking state. See isInReferenceMarking(). */
852 bool mbInReferenceMarking:1;
855 * Controls whether or not to allow user interaction. We don't want any
856 * user interaction when calling from the API.
858 bool mbUserInteractionEnabled:1;
860 bool mbSkipUnusedFileIds = false;
861 std::vector<sal_uInt16> maConvertFileIdToUsedFileId;
863 bool mbDocTimerEnabled:1;
865 AutoTimer maSrcDocTimer;
866 DECL_DLLPRIVATE_LINK(TimeOutHdl, Timer*, void);
869 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */