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