xref: /aoo4110/main/sc/inc/externalrefmgr.hxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef SC_EXTERNALREFMGR_HXX
25 #define SC_EXTERNALREFMGR_HXX
26 
27 #include "global.hxx"
28 #include "address.hxx"
29 #include "sfx2/objsh.hxx"
30 #include "sfx2/lnkbase.hxx"
31 #include "tools/time.hxx"
32 #include "vcl/timer.hxx"
33 #include "svl/zforlist.hxx"
34 #include "scmatrix.hxx"
35 #include "rangelst.hxx"
36 
37 #include <hash_map>
38 #include <hash_set>
39 #include <boost/shared_ptr.hpp>
40 #include <vector>
41 #include <list>
42 #include <set>
43 #include <formula/ExternalReferenceHelper.hxx>
44 
45 class ScDocument;
46 namespace formula
47 {
48     class FormulaToken;
49 }
50 class ScToken;
51 class ScMatrix;
52 class ScTokenArray;
53 class String;
54 class SfxObjectShellRef;
55 class Window;
56 class ScFormulaCell;
57 
58 class ScExternalRefCache;
59 
60 class ScExternalRefLink : public ::sfx2::SvBaseLink
61 {
62 public:
63     ScExternalRefLink(ScDocument* pDoc, sal_uInt16 nFileId, const String& rFilter);
64     virtual ~ScExternalRefLink();
65 
66     virtual void Closed();
67     virtual void DataChanged(const String& rMimeType, const ::com::sun::star::uno::Any & rValue);
68     virtual void Edit(Window* pParent, const Link& rEndEditHdl);
69 
70     void SetDoReferesh(bool b);
71 
72 private:
73     ScExternalRefLink(); // disabled
74     ScExternalRefLink(const ScExternalRefLink&); // disabled
75 
76     DECL_LINK( ExternalRefEndEditHdl, ::sfx2::SvBaseLink* );
77 
78     sal_uInt16  mnFileId;
79     String      maFilterName;
80     ScDocument* mpDoc;
81     bool        mbDoRefresh;
82 };
83 
84 // ============================================================================
85 
86 /**
87  * Cache table for external reference data.
88  */
89 class ScExternalRefCache
90 {
91 public:
92     typedef ::boost::shared_ptr< formula::FormulaToken>     TokenRef;
93     typedef ::boost::shared_ptr<ScTokenArray>               TokenArrayRef;
94 
95     struct TableName
96     {
97         String maUpperName;
98         String maRealName;
99 
100         explicit TableName(const String& rUppper, const String& rReal);
101     };
102 
103     struct CellFormat
104     {
105         bool        mbIsSet;
106         short       mnType;
107         sal_uInt32  mnIndex;
108 
109         explicit CellFormat();
110     };
111 
112 private:
113     /** individual cell within cached external ref table. */
114     struct Cell
115     {
116         TokenRef    mxToken;
117         sal_uInt32  mnFmtIndex;
118     };
119     typedef ::std::hash_map<SCCOL, Cell>            RowDataType;
120     typedef ::std::hash_map<SCROW, RowDataType>     RowsDataType;
121 
122 public:
123     // SUNWS needs a forward declared friend, otherwise types and members
124     // of the outer class are not accessible.
125     class Table;
126     friend class ScExternalRefCache::Table;
127 
128     /**
129      * Represents a single cached table in an external document.  It only
130      * stores non-empty cells; empty cells should never be stored in the data
131      * cache. Instead, cached ranges should be used to determine whether or
132      * not a cell is empty or needs fetching from the source document.  If a
133      * cell's value is not stored but its address is within the cached ranges,
134      * that cell is already queried in the source document and we know it's
135      * empty.
136      */
137     class Table
138     {
139     public:
140 
141         enum ReferencedFlag
142         {
143             UNREFERENCED,
144             REFERENCED_MARKED,      // marked as referenced during store to file
145             REFERENCED_PERMANENT    // permanently marked, e.g. from within interpreter
146         };
147 
148         Table();
149         ~Table();
150 
151         /**
152          * Add cell value to the cache.
153          *
154          * @param bSetCacheRange if true, mark this cell 'cached'.  This is
155          *                       false _only when_ adding a range of cell
156          *                       values, for performance reasons.
157          */
158         SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex = 0, bool bSetCacheRange = true);
159         SC_DLLPUBLIC TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = NULL) const;
160         bool hasRow( SCROW nRow ) const;
161         /** Set/clear referenced status flag only if current status is not
162             REFERENCED_PERMANENT. */
163         void setReferenced( bool bReferenced );
164         /// Unconditionally set the reference status flag.
165         void setReferencedFlag( ReferencedFlag eFlag );
166         ReferencedFlag getReferencedFlag() const;
167         bool isReferenced() const;
168         /// Obtain a sorted vector of rows.
169         void getAllRows(::std::vector<SCROW>& rRows, SCROW nLow = 0, SCROW nHigh = MAXROW) const;
170         /// Returns the half-open range of used rows in this table. Returns [0,0) if table is empty.
171         SC_DLLPUBLIC ::std::pair< SCROW, SCROW > getRowRange() const;
172         /// Obtain a sorted vector of columns.
173         void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols, SCCOL nLow = 0, SCCOL nHigh = MAXCOL) const;
174         /// Returns the half-open range of used columns in the specified row. Returns [0,0) if row is empty.
175         SC_DLLPUBLIC ::std::pair< SCCOL, SCCOL > getColRange( SCROW nRow ) const;
176         void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
177         const ScRangeList& getCachedRanges() const;
178         bool isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
179 
180         void setCachedCell(SCCOL nCol, SCROW nRow);
181         void setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
182 
183         /**
184          * Call this to mark the entire table "cached".  This will prevent all
185          * future attempts to access the source document even when non-cached
186          * cells are queried.  In such case, non-cached cells are treated as
187          * empty cells.  Useful when loading a document with own external data
188          * cache.
189          */
190         SC_DLLPUBLIC void setWholeTableCached();
191     private:
192         bool isInCachedRanges(SCCOL nCol, SCROW nRow) const;
193         TokenRef getEmptyOrNullToken(SCCOL nCol, SCROW nRow) const;
194 
195     private:
196         /** Data cache */
197         RowsDataType                    maRows;
198         /** Collection of individual cached ranges.  The table ranges are
199          *  not used & always zero. */
200         ScRangeList                     maCachedRanges;
201         ReferencedFlag                  meReferenced;
202     };
203 
204     typedef ::boost::shared_ptr<Table>      TableTypeRef;
205     typedef ::std::hash_map<String, size_t, ScStringHashCode>   TableNameIndexMap;
206 
207     ScExternalRefCache();
208     ~ScExternalRefCache();
209 
210     const String* getRealTableName(sal_uInt16 nFileId, const String& rTabName) const;
211     const String* getRealRangeName(sal_uInt16 nFileId, const String& rRangeName) const;
212 
213     /**
214      * Get a cached cell data at specified cell location.
215      *
216      * @param nFileId file ID of an external document
217      * @param rTabName sheet name
218      * @param nCol
219      * @param nRow
220      *
221      * @return pointer to the token instance in the cache.
222      */
223     ScExternalRefCache::TokenRef getCellData(
224         sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex);
225 
226     /**
227      * Get a cached cell range data.
228      *
229      * @return a new token array instance.  Note that <i>the caller must
230      *         manage the life cycle of the returned instance</i>, which is
231      *         guaranteed if the TokenArrayRef is properly used..
232      */
233     ScExternalRefCache::TokenArrayRef getCellRangeData(
234         sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange);
235 
236     ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName);
237     void setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray);
238 
239     void setCellData(sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex);
240 
241     struct SingleRangeData
242     {
243         /** This name must be in upper-case. */
244         String      maTableName;
245         ScMatrixRef mpRangeData;
246     };
247     void setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const ::std::vector<SingleRangeData>& rData,
248                           TokenArrayRef pArray);
249 
250     bool isDocInitialized(sal_uInt16 nFileId);
251     void initializeDoc(sal_uInt16 nFileId, const ::std::vector<String>& rTabNames);
252     String getTableName(sal_uInt16 nFileId, size_t nCacheId) const;
253     void getAllTableNames(sal_uInt16 nFileId, ::std::vector<String>& rTabNames) const;
254     SCsTAB getTabSpan( sal_uInt16 nFileId, const String& rStartTabName, const String& rEndTabName ) const;
255     void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
256 
257     /**
258      * Set all tables of a document as referenced, used only during
259      * store-to-file.
260      * @returns <TRUE/> if ALL tables of ALL documents are marked.
261      */
262     bool setCacheDocReferenced( sal_uInt16 nFileId );
263 
264     /**
265      * Set a table as referenced, used only during store-to-file.
266      * @returns <TRUE/> if ALL tables of ALL documents are marked.
267      */
268     bool setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName, size_t nSheets, bool bPermanent );
269     void setAllCacheTableReferencedStati( bool bReferenced );
270     bool areAllCacheTablesReferenced() const;
271 
272     /**
273      * Set a table as permanently referenced, to be called if not in
274      * mark-during-store-to-file cycle.
275      */
276     void setCacheTableReferencedPermanently( sal_uInt16 nFileId, const String& rTabName, size_t nSheets );
277 
278 private:
279     struct ReferencedStatus
280     {
281         struct DocReferenced
282         {
283             ::std::vector<bool> maTables;
284             bool                mbAllTablesReferenced;
285             // Initially, documents have no tables but all referenced.
DocReferencedScExternalRefCache::ReferencedStatus::DocReferenced286             DocReferenced() : mbAllTablesReferenced(true) {}
287         };
288         typedef ::std::vector<DocReferenced> DocReferencedVec;
289 
290         DocReferencedVec maDocs;
291         bool             mbAllReferenced;
292 
293                     ReferencedStatus();
294         explicit    ReferencedStatus( size_t nDocs );
295         void        reset( size_t nDocs );
296         void        checkAllDocs();
297 
298     } maReferenced;
299     void addCacheTableToReferenced( sal_uInt16 nFileId, size_t nIndex );
300     void addCacheDocToReferenced( sal_uInt16 nFileId );
301 public:
302 
303     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
304     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew, size_t* pnIndex);
305 
306     void clearCache(sal_uInt16 nFileId);
307 
308 private:
309     struct RangeHash
310     {
operator ()ScExternalRefCache::RangeHash311         size_t operator()(const ScRange& rRange) const
312         {
313             const ScAddress& s = rRange.aStart;
314             const ScAddress& e = rRange.aEnd;
315             return s.Tab() + s.Col() + s.Row() + e.Tab() + e.Col() + e.Row();
316         }
317     };
318 
319     typedef ::std::hash_map<String, TokenArrayRef, ScStringHashCode>    RangeNameMap;
320     typedef ::std::hash_map<ScRange, TokenArrayRef, RangeHash>          RangeArrayMap;
321     typedef ::std::hash_map<String, String, ScStringHashCode>           NamePairMap;
322 
323     // SUNWS needs a forward declared friend, otherwise types and members
324     // of the outer class are not accessible.
325     struct DocItem;
326     friend struct ScExternalRefCache::DocItem;
327 
328     /** Represents data cached for a single external document. */
329     struct DocItem
330     {
331         /** The raw cache tables. */
332         ::std::vector<TableTypeRef> maTables;
333         /** Table name list in correct order, in both upper- and real-case. */
334         ::std::vector<TableName>    maTableNames;
335         /** Table name to index map.  The names must be stored upper-case. */
336         TableNameIndexMap           maTableNameIndex;
337         /** Range name cache. */
338         RangeNameMap                maRangeNames;
339         /** Token array cache for cell ranges. */
340         RangeArrayMap               maRangeArrays;
341         /** Upper- to real-case mapping for range names. */
342         NamePairMap                 maRealRangeNameMap;
343 
344         bool mbInitFromSource;
345 
DocItemScExternalRefCache::DocItem346         DocItem() : mbInitFromSource(false) {}
347     };
348     typedef ::std::hash_map<sal_uInt16, DocItem>  DocDataType;
349     DocItem* getDocItem(sal_uInt16 nFileId) const;
350 
351 private:
352     mutable DocDataType maDocs;
353 };
354 
355 // ============================================================================
356 
357 class SC_DLLPUBLIC ScExternalRefManager : public formula::ExternalReferenceHelper
358 {
359 public:
360 
361     typedef ::std::set<ScFormulaCell*>                      RefCellSet;
362     typedef ::std::hash_map<sal_uInt16, RefCellSet>         RefCellMap;
363 
364     enum LinkUpdateType { LINK_MODIFIED, LINK_BROKEN };
365 
366     /**
367      * Base class for objects that need to listen to link updates.  When a
368      * link to a certain external file is updated, the notify() method gets
369      * called.
370      */
371     class LinkListener
372     {
373     public:
374         LinkListener();
375         virtual ~LinkListener() = 0;
376         virtual void notify(sal_uInt16 nFileId, LinkUpdateType eType) = 0;
377 
378         struct Hash
379         {
operator ()ScExternalRefManager::LinkListener::Hash380             size_t operator() (const LinkListener* p) const
381             {
382                 return reinterpret_cast<size_t>(p);
383             }
384         };
385     };
386 
387     /**
388      * Use this guard when performing something from the API that might query
389      * values from external references.  Interpreting formula strings is one
390      * such example.
391      */
392     class ApiGuard
393     {
394     public:
395         ApiGuard(ScDocument* pDoc);
396         ~ApiGuard();
397     private:
398         ScExternalRefManager* mpMgr;
399         bool mbOldInteractionEnabled;
400     };
401 
402 private:
403     /** Shell instance for a source document. */
404     struct SrcShell
405     {
406         SfxObjectShellRef   maShell;
407         Time                maLastAccess;
408     };
409 
410     typedef ::std::hash_map<sal_uInt16, SrcShell>           DocShellMap;
411     typedef ::std::hash_map<sal_uInt16, bool>               LinkedDocMap;
412 
413     typedef ::std::hash_map<sal_uInt16, SvNumberFormatterMergeMap> NumFmtMap;
414 
415 
416     typedef ::std::hash_set<LinkListener*, LinkListener::Hash>  LinkListeners;
417     typedef ::std::hash_map<sal_uInt16, LinkListeners>          LinkListenerMap;
418 
419 public:
420     /** Source document meta-data container. */
421     struct SrcFileData
422     {
423         String maFileName;      /// original file name as loaded from the file.
424         String maRealFileName;  /// file name created from the relative name.
425         String maRelativeName;
426         String maFilterName;
427         String maFilterOptions;
428 
429         void maybeCreateRealFileName(const String& rOwnDocName);
430     };
431 
432 public:
433     explicit ScExternalRefManager(ScDocument* pDoc);
434     virtual ~ScExternalRefManager();
435 
436     virtual String getCacheTableName(sal_uInt16 nFileId, size_t nTabIndex) const;
437 
438     /**
439      * Get a cache table instance for specified table and table index.  Unlike
440      * the other method that takes a table name, this method does not create a
441      * new table when a table is not available for specified index.
442      *
443      * @param nFileId file ID
444      * @param nTabIndex cache table index
445      *
446      * @return shared_ptr to the cache table instance
447      */
448     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
449 
450     /**
451      * Get a cache table instance for specified file and table name.  If the
452      * table instance is not already present, it'll instantiate a new one and
453      * append it to the end of the table array.  <I>It's important to be
454      * aware of this fact especially for multi-table ranges for which
455      * table orders are critical.</I>
456      *
457      * Excel filter calls this method to populate the cache table from the
458      * XCT/CRN records.
459      *
460      * @param nFileId file ID
461      * @param rTabName table name
462      * @param bCreateNew if true, create a new table instance if it's not
463      *                   already present.  If false, it returns NULL if the
464      *                   specified table's cache doesn't exist.
465      * @param pnIndex if non-NULL pointer is passed, it stores the internal
466      *                index of a cache table instance.
467      *
468      * @return shared_ptr to the cache table instance
469      */
470     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew, size_t* pnIndex = 0);
471 
472     /** Returns a vector containing all (real) table names and cache tables of
473         the specified file.
474 
475         The index in the returned vector corresponds to the table index used to
476         access the cache table, e.g. in getCacheTable().
477      */
478     void getAllCachedTableNames(sal_uInt16 nFileId, ::std::vector<String>& rTabNames) const;
479 
480     /**
481      * Get the span (distance+sign(distance)) of two sheets of a specified
482      * file.
483      *
484      * @param nFileId file ID
485      * @param rStartTabName name of first sheet (sheet1)
486      * @param rEndTabName name of second sheet (sheet2)
487      *
488      * @return span
489      *         1 if sheet2 == sheet1
490      *      >  1 if sheet2 > sheet1
491      *      < -1 if sheet2 < sheet1
492      *        -1 if nFileId or rStartTabName not found
493      *         0 if rEndTabName not found
494      */
495     SCsTAB getCachedTabSpan( sal_uInt16 nFileId, const String& rStartTabName, const String& rEndTabName ) const;
496 
497     /**
498      * Get all unique number format indices that are used in the cache tables.
499      * The retrieved indices are sorted in ascending order.
500      *
501      * @param rNumFmts (reference) all unique number format indices.
502      */
503     void getAllCachedNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
504 
505     sal_uInt16 getExternalFileCount() const;
506 
507     /**
508      * Mark all tables as referenced that are used by any LinkListener, used
509      * only during store-to-file.
510      * @returns <TRUE/> if ALL tables of ALL external documents are marked.
511      */
512     bool markUsedByLinkListeners();
513 
514     bool markUsedExternalRefCells();
515 
516     /**
517      * Set a table as referenced, used only during store-to-file.
518      * @returns <TRUE/> if ALL tables of ALL external documents are marked.
519      */
520     bool setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName, size_t nSheets );
521     void setAllCacheTableReferencedStati( bool bReferenced );
522 
523     /**
524      * Set a table as permanently referenced, to be called if not in
525      * mark-during-store-to-file cycle.
526      */
527     void setCacheTableReferencedPermanently( sal_uInt16 nFileId, const String& rTabName, size_t nSheets );
528 
529     /**
530      * @returns <TRUE/> if setAllCacheTableReferencedStati(false) was called,
531      * <FALSE/> if setAllCacheTableReferencedStati(true) was called.
532      */
isInReferenceMarking() const533     bool isInReferenceMarking() const   { return mbInReferenceMarking; }
534 
535     void storeRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScTokenArray& rArray);
536 
537     ScExternalRefCache::TokenRef getSingleRefToken(
538         sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell,
539         const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt = NULL);
540 
541     /**
542      * Get an array of tokens that consist of the specified external cell
543      * range.
544      *
545      * @param nFileId file ID for an external document
546      * @param rTabName referenced sheet name
547      * @param rRange referenced cell range
548      * @param pCurPos current cursor position to keep track of cells that
549      *                reference an external data.
550      *
551      * @return shared_ptr to a token array instance.  <i>The caller must not
552      *         delete the instance returned by this method.</i>
553      */
554     ScExternalRefCache::TokenArrayRef getDoubleRefTokens(
555         sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos);
556 
557     /**
558      * Get an array of tokens corresponding with a specified name in a
559      * specified file.
560      *
561      * @param pCurPos currnet cell address where this name token is used.
562      *                This is purely to keep track of all cells containing
563      *                external names for refreshing purposes.  If this is
564      *                NULL, then the cell will not be added to the list.
565      *
566      * @return shared_ptr to array of tokens composing the name
567      */
568     ScExternalRefCache::TokenArrayRef getRangeNameTokens(
569         sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos = NULL);
570 
571     const String& getOwnDocumentName() const;
572     bool isOwnDocument(const String& rFile) const;
573 
574     /**
575      * Takes a flat file name, and convert it to an absolute URL path.  An
576      * absolute URL path begines with 'file:///.
577      *
578      * @param rFile file name to convert
579      */
580     void convertToAbsName(String& rFile) const;
581     sal_uInt16 getExternalFileId(const String& rFile);
582 
583     /**
584      * It returns a pointer to the name of the URI associated with a given
585      * external file ID.  In case the original document has moved, it returns
586      * an URI adjusted for the relocation.
587      *
588      * @param nFileId file ID for an external document
589      * @param bForceOriginal If true, it always returns the original document
590      *                       URI even if the referring document has relocated.
591      *                       If false, it returns an URI adjusted for
592      *                       relocated document.
593      *
594      * @return const String* external document URI.
595      */
596     const String* getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal = false);
597     bool hasExternalFile(sal_uInt16 nFileId) const;
598     bool hasExternalFile(const String& rFile) const;
599     const SrcFileData* getExternalFileData(sal_uInt16 nFileId) const;
600 
601     const String* getRealTableName(sal_uInt16 nFileId, const String& rTabName) const;
602     const String* getRealRangeName(sal_uInt16 nFileId, const String& rRangeName) const;
603     void refreshNames(sal_uInt16 nFileId);
604     void breakLink(sal_uInt16 nFileId);
605     void switchSrcFile(sal_uInt16 nFileId, const String& rNewFile, const String& rNewFilter);
606 
607     /**
608      * Set a relative file path for the specified file ID.  Note that the
609      * caller must ensure that the passed URL is a valid relative URL.
610      *
611      * @param nFileId file ID for an external document
612      * @param rRelUrl relative URL
613      */
614     void setRelativeFileName(sal_uInt16 nFileId, const String& rRelUrl);
615 
616     /**
617      * Set the filter name and options if any for a given source document.
618      * These values get reset when the source document ever gets reloaded.
619      *
620      * @param nFileId
621      * @param rFilterName
622      * @param rOptions
623      */
624     void setFilterData(sal_uInt16 nFileId, const String& rFilterName, const String& rOptions);
625 
626     void clear();
627 
628     bool hasExternalData() const;
629 
630     /**
631      * Re-generates relative names for all stored source files.  This is
632      * necessary when exporting to an ods document, to ensure that all source
633      * files have their respective relative names for xlink:href export.
634      *
635      * @param rBaseFileUrl Absolute URL of the content.xml fragment of the
636      *                     document being exported.
637      */
638     void resetSrcFileData(const String& rBaseFileUrl);
639 
640     /**
641      * Replace the original URL wirh the real URL that was generated from the relative URL.
642      */
643     void updateAbsAfterLoad();
644 
645     /**
646      * Stop tracking a specific formula cell.
647      *
648      * @param pCell pointer to cell that formerly contained external
649      *              reference.
650      */
651     void removeRefCell(ScFormulaCell* pCell);
652 
653     /**
654      * Register a new link listener to a specified external document.  Note
655      * that the caller is responsible for managing the life cycle of the
656      * listener object.
657      */
658     void addLinkListener(sal_uInt16 nFileId, LinkListener* pListener);
659 
660     /**
661      * Remove an existing link listener.  Note that removing a listener
662      * pointer here does not delete the listener object instance.
663      */
664     void removeLinkListener(sal_uInt16 nFileId, LinkListener* pListener);
665 
666     void removeLinkListener(LinkListener* pListener);
667 
668     /**
669      * Notify all listeners that are listening to a specified external
670      * document.
671      *
672      * @param nFileId file ID for an external document.
673      */
674     void notifyAllLinkListeners(sal_uInt16 nFileId, LinkUpdateType eType);
675 
676 private:
677     ScExternalRefManager();
678     ScExternalRefManager(const ScExternalRefManager&);
679 
680     void refreshAllRefCells(sal_uInt16 nFileId);
681 
682     void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
683 
684     ScDocument* getSrcDocument(sal_uInt16 nFileId);
685     SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, String& rFilter);
686     bool isFileLoadable(const String& rFile) const;
687 
688     void maybeLinkExternalFile(sal_uInt16 nFileId);
689 
690     /**
691      * Try to create a "real" file name from the relative path.  The original
692      * file name may not point to the real document when the referencing and
693      * referenced documents have been moved.
694      *
695      * For the real file name to be created, the relative name should not be
696      * empty before calling this method, or the real file name will not be
697      * created.
698      *
699      * @param nFileId file ID for an external document
700      */
701     void maybeCreateRealFileName(sal_uInt16 nFileId);
702 
703     /**
704      * Purge those source document instances that have not been accessed for
705      * the specified duration.
706      *
707      * @param nTimeOut time out value in 100th of a second
708      */
709     void purgeStaleSrcDocument(sal_Int32 nTimeOut);
710 
711     sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, ScDocument* pSrcDoc);
712 
713 private:
714     /** cache of referenced ranges and names from source documents. */
715     ScExternalRefCache maRefCache;
716 
717     ScDocument* mpDoc;
718 
719     /**
720      * Source document cache.  This stores the original source document shell
721      * instances.  They get purged after a certain period of time.
722      */
723     DocShellMap maDocShells;
724 
725     /** list of source documents that are managed by the link manager. */
726     LinkedDocMap maLinkedDocs;
727 
728     /**
729      * List of referencing cells that may contain external names.  There is
730      * one list per source document.
731      */
732     RefCellMap maRefCells;
733 
734     LinkListenerMap maLinkListeners;
735 
736     NumFmtMap maNumFormatMap;
737 
738     /** original source file index. */
739     ::std::vector<SrcFileData> maSrcFiles;
740 
741     /** Status whether in reference marking state. See isInReferenceMarking(). */
742     bool mbInReferenceMarking:1;
743 
744     /**
745      * Controls whether or not to allow user interaction.  We don't want any
746      * user interaction when calling from the API.
747      */
748     bool mbUserInteractionEnabled:1;
749 
750     AutoTimer maSrcDocTimer;
751     DECL_LINK(TimeOutHdl, AutoTimer*);
752 };
753 
754 
755 #endif
756