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