LCOV - code coverage report
Current view: top level - libreoffice/sc/inc - externalrefmgr.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 11 19 57.9 %
Date: 2012-12-27 Functions: 17 25 68.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10