Update ooo320-m1
[ooovba.git] / sc / source / filter / excel / xilink.cxx
blob00268215a5dcba592189c2031c285b7ac2802a08
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xilink.cxx,v $
10 * $Revision: 1.25.46.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
33 #include "xilink.hxx"
34 #include "document.hxx"
35 #include "cell.hxx"
36 #include "scextopt.hxx"
37 #include "tablink.hxx"
38 #include "xistream.hxx"
39 #include "xihelper.hxx"
40 #include "xiname.hxx"
41 #include "excform.hxx"
42 #include "tokenarray.hxx"
43 #include "externalrefmgr.hxx"
45 #include <vector>
47 using ::std::vector;
49 // ============================================================================
50 // *** Helper classes ***
51 // ============================================================================
53 // Cached external cells ======================================================
55 /** Contains the address and value of an external referenced cell. */
56 class XclImpCrn : public XclImpCachedValue
58 public:
59 /** Reads a cached value and stores it with its cell address. */
60 explicit XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
62 const XclAddress& GetAddress() const;
64 private:
65 XclAddress maXclPos; /// Excel position of the cached cell.
68 // Sheet in an external document ==============================================
70 /** Contains the name and sheet index of one sheet in an external document. */
71 class XclImpSupbookTab
73 public:
74 /** Stores the sheet name and marks the sheet index as invalid.
75 The sheet index is set while creating the Calc sheet with CreateTable(). */
76 explicit XclImpSupbookTab( const String& rTabName );
77 ~XclImpSupbookTab();
79 inline const String& GetTabName() const { return maTabName; }
81 /** Reads a CRN record (external referenced cell) at the specified address. */
82 void ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
84 void LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable);
86 private:
87 typedef ScfDelList< XclImpCrn > XclImpCrnList;
89 XclImpCrnList maCrnList; /// List of CRN records (cached cell values).
90 String maTabName; /// Name of the external sheet.
91 SCTAB mnScTab; /// New sheet index in Calc document.
94 // External document (SUPBOOK) ================================================
96 /** This class represents an external linked document (record SUPBOOK).
97 @descr Contains a list of all referenced sheets in the document. */
98 class XclImpSupbook : protected XclImpRoot
100 public:
101 /** Reads the SUPBOOK record from stream. */
102 explicit XclImpSupbook( XclImpStream& rStrm );
104 /** Reads an XCT record (count of following CRNs and current sheet). */
105 void ReadXct( XclImpStream& rStrm );
106 /** Reads a CRN record (external referenced cell). */
107 void ReadCrn( XclImpStream& rStrm );
108 /** Reads an EXTERNNAME record. */
109 void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
111 /** Returns the SUPBOOK record type. */
112 inline XclSupbookType GetType() const { return meType; }
114 /** Returns the URL of the external document. */
115 inline const String& GetXclUrl() const { return maXclUrl; }
117 /** Returns the external name specified by an index from the Excel document (one-based). */
118 const XclImpExtName* GetExternName( sal_uInt16 nXclIndex ) const;
119 /** Tries to decode the URL to OLE or DDE link components.
120 @descr For DDE links: Decodes to application name and topic.
121 For OLE object links: Decodes to class name and document URL.
122 @return true = decoding was successful, returned strings are valid (not empty). */
123 bool GetLinkData( String& rApplic, String& rDoc ) const;
124 /** Returns the specified macro name (1-based) or an empty string on error. */
125 const String& GetMacroName( sal_uInt16 nXclNameIdx ) const;
127 const String& GetTabName( sal_uInt16 nXtiTab ) const;
129 sal_uInt16 GetTabCount() const;
131 void LoadCachedValues();
133 private:
134 typedef ScfDelList< XclImpSupbookTab > XclImpSupbookTabList;
135 typedef ScfDelList< XclImpExtName > XclImpExtNameList;
137 XclImpSupbookTabList maSupbTabList; /// All sheet names of the document.
138 XclImpExtNameList maExtNameList; /// All external names of the document.
139 String maXclUrl; /// URL of the external document (Excel mode).
140 String maFilterName; /// Detected filer name.
141 String maFilterOpt; /// Detected filer options.
142 XclSupbookType meType; /// Type of the supbook record.
143 sal_uInt16 mnSBTab; /// Current Excel sheet index from SUPBOOK for XCT/CRN records.
146 // Import link manager ========================================================
148 /** Contains the SUPBOOK index and sheet indexes of an external link.
149 @descr It is possible to enter a formula like =SUM(Sheet1:Sheet3!A1),
150 therefore here occurs a sheet range. */
151 struct XclImpXti
153 sal_uInt16 mnSupbook; /// Index to SUPBOOK record.
154 sal_uInt16 mnSBTabFirst; /// Index to the first sheet of the range in the SUPBOOK.
155 sal_uInt16 mnSBTabLast; /// Index to the last sheet of the range in the SUPBOOK.
156 inline explicit XclImpXti() : mnSupbook( SAL_MAX_UINT16 ), mnSBTabFirst( SAL_MAX_UINT16 ), mnSBTabLast( SAL_MAX_UINT16 ) {}
159 inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpXti& rXti )
161 return rStrm >> rXti.mnSupbook >> rXti.mnSBTabFirst >> rXti.mnSBTabLast;
164 // ----------------------------------------------------------------------------
166 /** Implementation of the link manager. */
167 class XclImpLinkManagerImpl : protected XclImpRoot
169 public:
170 explicit XclImpLinkManagerImpl( const XclImpRoot& rRoot );
172 /** Reads the EXTERNSHEET record. */
173 void ReadExternsheet( XclImpStream& rStrm );
174 /** Reads a SUPBOOK record. */
175 void ReadSupbook( XclImpStream& rStrm );
176 /** Reads an XCT record and appends it to the current SUPBOOK. */
177 void ReadXct( XclImpStream& rStrm );
178 /** Reads a CRN record and appends it to the current SUPBOOK. */
179 void ReadCrn( XclImpStream& rStrm );
180 /** Reads an EXTERNNAME record and appends it to the current SUPBOOK. */
181 void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
183 /** Returns true, if the specified XTI entry contains an internal reference. */
184 bool IsSelfRef( sal_uInt16 nXtiIndex ) const;
185 /** Returns the Calc sheet index range of the specified XTI entry.
186 @return true = XTI data found, returned sheet index range is valid. */
187 bool GetScTabRange(
188 SCTAB& rnFirstScTab, SCTAB& rnLastScTab,
189 sal_uInt16 nXtiIndex ) const;
190 /** Returns the specified external name or 0 on error. */
191 const XclImpExtName* GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const;
193 /** Returns the absolute file URL of a supporting workbook specified by
194 the index. */
195 const String* GetSupbookUrl( sal_uInt16 nXtiIndex ) const;
197 const String& GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const;
199 /** Tries to decode the URL of the specified XTI entry to OLE or DDE link components.
200 @descr For DDE links: Decodes to application name and topic.
201 For OLE object links: Decodes to class name and document URL.
202 @return true = decoding was successful, returned strings are valid (not empty). */
203 bool GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const;
204 /** Returns the specified macro name or an empty string on error. */
205 const String& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const;
207 private:
208 /** Returns the specified XTI (link entry from BIFF8 EXTERNSHEET record). */
209 const XclImpXti* GetXti( sal_uInt16 nXtiIndex ) const;
210 /** Returns the specified SUPBOOK (external document). */
211 const XclImpSupbook* GetSupbook( sal_uInt16 nXtiIndex ) const;
212 //UNUSED2009-05 /** Returns the SUPBOOK (external workbook) specified by its URL. */
213 //UNUSED2009-05 const XclImpSupbook* GetSupbook( const String& rUrl ) const;
215 void LoadCachedValues();
217 //UNUSED2009-05 /** Finds the largest range of sheet indexes in a SUPBOOK after a start sheet index.
218 //UNUSED2009-05 @param rnSBTabFirst (out-param) The first sheet index of the range in SUPBOOK is returned here.
219 //UNUSED2009-05 @param rnSBTabLast (out-param) The last sheet index of the range in SUPBOOK is returned here (inclusive).
220 //UNUSED2009-05 @param nSupbook The list index of the SUPBOOK.
221 //UNUSED2009-05 @param nSBTabStart The first allowed sheet index. Sheet ranges with an earlier start index are ignored.
222 //UNUSED2009-05 @return true = the return values are valid; false = nothing found. */
223 //UNUSED2009-05 bool FindNextTabRange(
224 //UNUSED2009-05 sal_uInt16& rnSBTabFirst, sal_uInt16& rnSBTabLast,
225 //UNUSED2009-05 sal_uInt16 nSupbook, sal_uInt16 nSBTabStart ) const;
227 private:
228 typedef ::std::vector< XclImpXti > XclImpXtiVector;
229 typedef ScfDelList< XclImpSupbook > XclImpSupbookList;
231 XclImpXtiVector maXtiList; /// List of all XTI structures.
232 XclImpSupbookList maSupbookList; /// List of external documents.
233 bool mbCreated; /// true = Calc sheets already created.
236 // ============================================================================
237 // *** Implementation ***
238 // ============================================================================
240 // Excel sheet indexes ========================================================
242 // original Excel sheet names -------------------------------------------------
244 void XclImpTabInfo::AppendXclTabName( const String& rXclTabName, SCTAB nScTab )
246 maTabNames[ rXclTabName ] = nScTab;
249 void XclImpTabInfo::InsertScTab( SCTAB nScTab )
251 for( XclTabNameMap::iterator aIt = maTabNames.begin(), aEnd = maTabNames.end(); aIt != aEnd; ++aIt )
252 if( aIt->second >= nScTab )
253 ++aIt->second;
256 SCTAB XclImpTabInfo::GetScTabFromXclName( const String& rXclTabName ) const
258 XclTabNameMap::const_iterator aIt = maTabNames.find( rXclTabName );
259 return (aIt != maTabNames.end()) ? aIt->second : SCTAB_INVALID;
262 // record creation order - TABID record ---------------------------------------
264 void XclImpTabInfo::ReadTabid( XclImpStream& rStrm )
266 DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() == EXC_BIFF8 );
267 if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
269 rStrm.EnableDecryption();
270 sal_Size nReadCount = rStrm.GetRecLeft() / 2;
271 DBG_ASSERT( nReadCount <= 0xFFFF, "XclImpTabInfo::ReadTabid - record too long" );
272 maTabIdVec.clear();
273 maTabIdVec.reserve( nReadCount );
274 for( sal_Size nIndex = 0; rStrm.IsValid() && (nIndex < nReadCount); ++nIndex )
275 // #93471# zero index is not allowed in BIFF8, but it seems that it occurs in real life
276 maTabIdVec.push_back( rStrm.ReaduInt16() );
280 sal_uInt16 XclImpTabInfo::GetCurrentIndex( sal_uInt16 nCreatedId, sal_uInt16 nMaxTabId ) const
282 sal_uInt16 nReturn = 0;
283 for( ScfUInt16Vec::const_iterator aIt = maTabIdVec.begin(), aEnd = maTabIdVec.end(); aIt != aEnd; ++aIt )
285 sal_uInt16 nValue = *aIt;
286 if( nValue == nCreatedId )
287 return nReturn;
288 if( nValue <= nMaxTabId )
289 ++nReturn;
291 return 0;
294 // External names =============================================================
296 XclImpExtName::XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm, XclSupbookType eSubType, ExcelToSc* pFormulaConv )
298 sal_uInt16 nFlags;
299 sal_uInt8 nLen;
301 rStrm >> nFlags >> mnStorageId >> nLen ;
302 maName = rStrm.ReadUniString( nLen );
303 if( ::get_flag( nFlags, EXC_EXTN_BUILTIN ) || !::get_flag( nFlags, EXC_EXTN_OLE_OR_DDE ) )
305 if( eSubType == EXC_SBTYPE_ADDIN )
307 meType = xlExtAddIn;
308 maName = rStrm.GetRoot().GetScAddInName( maName );
310 else if ( (eSubType == EXC_SBTYPE_EUROTOOL) &&
311 maName.EqualsIgnoreCaseAscii( "EUROCONVERT" ) )
312 meType = xlExtEuroConvert;
313 else
315 meType = xlExtName;
316 ScfTools::ConvertToScDefinedName( maName );
319 else
321 meType = ::get_flagvalue( nFlags, EXC_EXTN_OLE, xlExtOLE, xlExtDDE );
324 if( (meType == xlExtDDE) && (rStrm.GetRecLeft() > 1) )
325 mxDdeMatrix.reset( new XclImpCachedMatrix( rStrm ) );
327 if (meType == xlExtName)
329 // TODO: For now, only global external names are supported. In future
330 // we should extend this to supporting per-sheet external names.
331 if (mnStorageId == 0)
333 if (pFormulaConv)
335 const ScTokenArray* pArray = NULL;
336 sal_uInt16 nFmlaLen;
337 rStrm >> nFmlaLen;
338 vector<String> aTabNames;
339 sal_uInt16 nCount = rSupbook.GetTabCount();
340 aTabNames.reserve(nCount);
341 for (sal_uInt16 i = 0; i < nCount; ++i)
342 aTabNames.push_back(rSupbook.GetTabName(i));
344 pFormulaConv->ConvertExternName(pArray, rStrm, nFmlaLen, rSupbook.GetXclUrl(), aTabNames);
345 if (pArray)
346 mxArray.reset(pArray->Clone());
352 XclImpExtName::~XclImpExtName()
356 void XclImpExtName::CreateDdeData( ScDocument& rDoc, const String& rApplic, const String& rTopic ) const
358 ScMatrixRef xResults;
359 if( mxDdeMatrix.get() )
360 xResults = mxDdeMatrix->CreateScMatrix();
361 rDoc.CreateDdeLink( rApplic, rTopic, maName, SC_DDE_DEFAULT, xResults );
364 void XclImpExtName::CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) const
366 if (!mxArray.get())
367 return;
369 ScExternalRefManager* pRefMgr = rDoc.GetExternalRefManager();
370 pRefMgr->storeRangeNameTokens(nFileId, maName, *mxArray);
373 bool XclImpExtName::HasFormulaTokens() const
375 return (mxArray.get() != NULL);
378 // Cached external cells ======================================================
380 XclImpCrn::XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos ) :
381 XclImpCachedValue( rStrm ),
382 maXclPos( rXclPos )
386 const XclAddress& XclImpCrn::GetAddress() const
388 return maXclPos;
391 // Sheet in an external document ==============================================
393 XclImpSupbookTab::XclImpSupbookTab( const String& rTabName ) :
394 maTabName( rTabName ),
395 mnScTab( SCTAB_INVALID )
399 XclImpSupbookTab::~XclImpSupbookTab()
403 void XclImpSupbookTab::ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos )
405 maCrnList.Append( new XclImpCrn( rStrm, rXclPos ) );
408 void XclImpSupbookTab::LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable)
410 if (maCrnList.Empty())
411 return;
413 for (XclImpCrn* p = maCrnList.First(); p; p = maCrnList.Next())
415 const XclAddress& rAddr = p->GetAddress();
416 switch (p->GetType())
418 case EXC_CACHEDVAL_BOOL:
419 break;
420 case EXC_CACHEDVAL_DOUBLE:
422 double f = p->GetValue();
423 ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(f));
424 pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
426 break;
427 case EXC_CACHEDVAL_EMPTY:
428 break;
429 case EXC_CACHEDVAL_ERROR:
430 break;
431 case EXC_CACHEDVAL_STRING:
433 const String& rStr = p->GetString();
434 ScExternalRefCache::TokenRef pToken(new formula::FormulaStringToken(rStr));
435 pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
437 break;
438 default:
444 // External document (SUPBOOK) ================================================
446 XclImpSupbook::XclImpSupbook( XclImpStream& rStrm ) :
447 XclImpRoot( rStrm.GetRoot() ),
448 meType( EXC_SBTYPE_UNKNOWN ),
449 mnSBTab( EXC_TAB_DELETED )
451 sal_uInt16 nSBTabCnt;
452 rStrm >> nSBTabCnt;
454 if( rStrm.GetRecLeft() == 2 )
456 switch( rStrm.ReaduInt16() )
458 case EXC_SUPB_SELF: meType = EXC_SBTYPE_SELF; break;
459 case EXC_SUPB_ADDIN: meType = EXC_SBTYPE_ADDIN; break;
460 default: DBG_ERRORFILE( "XclImpSupbook::XclImpSupbook - unknown special SUPBOOK type" );
462 return;
465 String aEncUrl( rStrm.ReadUniString() );
466 bool bSelf = false;
467 XclImpUrlHelper::DecodeUrl( maXclUrl, bSelf, GetRoot(), aEncUrl );
469 if( maXclUrl.EqualsIgnoreCaseAscii( "\010EUROTOOL.XLA" ) )
471 meType = EXC_SBTYPE_EUROTOOL;
472 maSupbTabList.Append( new XclImpSupbookTab( maXclUrl ) );
474 else if( nSBTabCnt )
476 meType = EXC_SBTYPE_EXTERN;
477 for( sal_uInt16 nSBTab = 0; nSBTab < nSBTabCnt; ++nSBTab )
479 String aTabName( rStrm.ReadUniString() );
480 maSupbTabList.Append( new XclImpSupbookTab( aTabName ) );
483 else
485 meType = EXC_SBTYPE_SPECIAL;
486 // create dummy list entry
487 maSupbTabList.Append( new XclImpSupbookTab( maXclUrl ) );
491 void XclImpSupbook::ReadXct( XclImpStream& rStrm )
493 rStrm.Ignore( 2 );
494 rStrm >> mnSBTab;
497 void XclImpSupbook::ReadCrn( XclImpStream& rStrm )
499 if( XclImpSupbookTab* pSBTab = maSupbTabList.GetObject( mnSBTab ) )
501 sal_uInt8 nXclColLast, nXclColFirst;
502 sal_uInt16 nXclRow;
503 rStrm >> nXclColLast >> nXclColFirst >> nXclRow;
505 for( sal_uInt8 nXclCol = nXclColFirst; (nXclCol <= nXclColLast) && (rStrm.GetRecLeft() > 1); ++nXclCol )
506 pSBTab->ReadCrn( rStrm, XclAddress( nXclCol, nXclRow ) );
510 void XclImpSupbook::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
512 maExtNameList.Append( new XclImpExtName( *this, rStrm, meType, pFormulaConv ) );
515 const XclImpExtName* XclImpSupbook::GetExternName( sal_uInt16 nXclIndex ) const
517 DBG_ASSERT( nXclIndex > 0, "XclImpSupbook::GetExternName - index must be >0" );
518 return (meType == EXC_SBTYPE_SELF) ? 0 : maExtNameList.GetObject( nXclIndex - 1 );
521 bool XclImpSupbook::GetLinkData( String& rApplic, String& rTopic ) const
523 return (meType == EXC_SBTYPE_SPECIAL) && XclImpUrlHelper::DecodeLink( rApplic, rTopic, maXclUrl );
526 const String& XclImpSupbook::GetMacroName( sal_uInt16 nXclNameIdx ) const
528 DBG_ASSERT( nXclNameIdx > 0, "XclImpSupbook::GetMacroName - index must be >0" );
529 const XclImpName* pName = (meType == EXC_SBTYPE_SELF) ? GetNameManager().GetName( nXclNameIdx ) : 0;
530 return (pName && pName->IsVBName()) ? pName->GetScName() : EMPTY_STRING;
533 const String& XclImpSupbook::GetTabName( sal_uInt16 nXtiTab ) const
535 if (maSupbTabList.Empty())
536 return EMPTY_STRING;
538 sal_uInt16 i = 0;
539 for (XclImpSupbookTab* p = maSupbTabList.First(); p; p = maSupbTabList.Next(), ++i)
541 if (i == nXtiTab)
542 return p->GetTabName();
545 return EMPTY_STRING;
548 sal_uInt16 XclImpSupbook::GetTabCount() const
550 return ulimit_cast<sal_uInt16>(maSupbTabList.Count());
553 void XclImpSupbook::LoadCachedValues()
555 if (meType != EXC_SBTYPE_EXTERN || GetExtDocOptions().GetDocSettings().mnLinkCnt > 0 || !GetDocShell())
556 return;
558 String aAbsUrl( ScGlobal::GetAbsDocName(maXclUrl, GetDocShell()) );
560 ScExternalRefManager* pRefMgr = GetRoot().GetDoc().GetExternalRefManager();
561 sal_uInt16 nFileId = pRefMgr->getExternalFileId(aAbsUrl);
563 sal_uInt16 nCount = static_cast< sal_uInt16 >( maSupbTabList.Count() );
564 for (sal_uInt16 i = 0; i < nCount; ++i)
566 XclImpSupbookTab* pTab = maSupbTabList.GetObject(i);
567 if (!pTab)
568 return;
570 const String& rTabName = pTab->GetTabName();
571 ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
572 pTab->LoadCachedValues(pCacheTable);
576 // Import link manager ========================================================
578 XclImpLinkManagerImpl::XclImpLinkManagerImpl( const XclImpRoot& rRoot ) :
579 XclImpRoot( rRoot ),
580 mbCreated( false )
584 void XclImpLinkManagerImpl::ReadExternsheet( XclImpStream& rStrm )
586 sal_uInt16 nXtiCount;
587 rStrm >> nXtiCount;
588 DBG_ASSERT( static_cast< sal_Size >( nXtiCount * 6 ) == rStrm.GetRecLeft(), "XclImpLinkManagerImpl::ReadExternsheet - invalid count" );
589 nXtiCount = static_cast< sal_uInt16 >( ::std::min< sal_Size >( nXtiCount, rStrm.GetRecLeft() / 6 ) );
591 /* #i104057# A weird external XLS generator writes multiple EXTERNSHEET
592 records instead of only one as expected. Surprisingly, Excel seems to
593 insert the entries of the second record before the entries of the first
594 record. */
595 XclImpXtiVector aNewEntries( nXtiCount );
596 for( XclImpXtiVector::iterator aIt = aNewEntries.begin(), aEnd = aNewEntries.end(); rStrm.IsValid() && (aIt != aEnd); ++aIt )
597 rStrm >> *aIt;
598 maXtiList.insert( maXtiList.begin(), aNewEntries.begin(), aNewEntries.end() );
600 LoadCachedValues();
603 void XclImpLinkManagerImpl::ReadSupbook( XclImpStream& rStrm )
605 maSupbookList.Append( new XclImpSupbook( rStrm ) );
608 void XclImpLinkManagerImpl::ReadXct( XclImpStream& rStrm )
610 if( XclImpSupbook* pSupbook = maSupbookList.Last() )
611 pSupbook->ReadXct( rStrm );
614 void XclImpLinkManagerImpl::ReadCrn( XclImpStream& rStrm )
616 if( XclImpSupbook* pSupbook = maSupbookList.Last() )
617 pSupbook->ReadCrn( rStrm );
620 void XclImpLinkManagerImpl::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
622 if( XclImpSupbook* pSupbook = maSupbookList.Last() )
623 pSupbook->ReadExternname( rStrm, pFormulaConv );
626 bool XclImpLinkManagerImpl::IsSelfRef( sal_uInt16 nXtiIndex ) const
628 const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
629 return pSupbook && (pSupbook->GetType() == EXC_SBTYPE_SELF);
632 bool XclImpLinkManagerImpl::GetScTabRange(
633 SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
635 if( const XclImpXti* pXti = GetXti( nXtiIndex ) )
637 if (maSupbookList.GetObject(pXti->mnSupbook))
639 rnFirstScTab = pXti->mnSBTabFirst;
640 rnLastScTab = pXti->mnSBTabLast;
641 return true;
644 return false;
647 const XclImpExtName* XclImpLinkManagerImpl::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
649 const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
650 return pSupbook ? pSupbook->GetExternName( nExtName ) : 0;
653 const String* XclImpLinkManagerImpl::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
655 const XclImpSupbook* p = GetSupbook( nXtiIndex );
656 if (!p)
657 return NULL;
658 return &p->GetXclUrl();
661 const String& XclImpLinkManagerImpl::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
663 const XclImpSupbook* p = GetSupbook(nXti);
664 return p ? p->GetTabName(nXtiTab) : EMPTY_STRING;
667 bool XclImpLinkManagerImpl::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
669 const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
670 return pSupbook && pSupbook->GetLinkData( rApplic, rTopic );
673 const String& XclImpLinkManagerImpl::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
675 const XclImpSupbook* pSupbook = GetSupbook( nExtSheet );
676 return pSupbook ? pSupbook->GetMacroName( nExtName ) : EMPTY_STRING;
679 const XclImpXti* XclImpLinkManagerImpl::GetXti( sal_uInt16 nXtiIndex ) const
681 return (nXtiIndex < maXtiList.size()) ? &maXtiList[ nXtiIndex ] : 0;
684 const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt16 nXtiIndex ) const
686 const XclImpXti* pXti = GetXti( nXtiIndex );
687 return pXti ? maSupbookList.GetObject( pXti->mnSupbook ) : 0;
690 //UNUSED2009-05 const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( const String& rUrl ) const
691 //UNUSED2009-05 {
692 //UNUSED2009-05 for( const XclImpSupbook* pSupbook = maSupbookList.First(); pSupbook; pSupbook = maSupbookList.Next() )
693 //UNUSED2009-05 if( pSupbook->GetXclUrl() == rUrl )
694 //UNUSED2009-05 return pSupbook;
695 //UNUSED2009-05 return 0;
696 //UNUSED2009-05 }
698 void XclImpLinkManagerImpl::LoadCachedValues()
700 // Read all CRN records which can be accessed via XclImpSupbook, and store
701 // the cached values to the external reference manager.
703 sal_uInt32 nCount = maSupbookList.Count();
704 for (sal_uInt16 nSupbook = 0; nSupbook < nCount; ++nSupbook)
706 XclImpSupbook* pSupbook = maSupbookList.GetObject(nSupbook);
707 pSupbook->LoadCachedValues();
711 //UNUSED2009-05 bool XclImpLinkManagerImpl::FindNextTabRange(
712 //UNUSED2009-05 sal_uInt16& rnSBTabFirst, sal_uInt16& rnSBTabLast,
713 //UNUSED2009-05 sal_uInt16 nSupbook, sal_uInt16 nSBTabStart ) const
714 //UNUSED2009-05 {
715 //UNUSED2009-05 rnSBTabFirst = rnSBTabLast = EXC_NOTAB;
716 //UNUSED2009-05 for( const XclImpXti* pXti = maXtiList.First(); pXti; pXti = maXtiList.Next() )
717 //UNUSED2009-05 {
718 //UNUSED2009-05 if( (nSupbook == pXti->mnSupbook) && (nSBTabStart <= pXti->mnSBTabLast) && (pXti->mnSBTabFirst < rnSBTabFirst) )
719 //UNUSED2009-05 {
720 //UNUSED2009-05 rnSBTabFirst = ::std::max( nSBTabStart, pXti->mnSBTabFirst );
721 //UNUSED2009-05 rnSBTabLast = pXti->mnSBTabLast;
722 //UNUSED2009-05 }
723 //UNUSED2009-05 }
724 //UNUSED2009-05 return rnSBTabFirst != EXC_NOTAB;
725 //UNUSED2009-05 }
727 // ============================================================================
729 XclImpLinkManager::XclImpLinkManager( const XclImpRoot& rRoot ) :
730 XclImpRoot( rRoot ),
731 mxImpl( new XclImpLinkManagerImpl( rRoot ) )
735 XclImpLinkManager::~XclImpLinkManager()
739 void XclImpLinkManager::ReadExternsheet( XclImpStream& rStrm )
741 mxImpl->ReadExternsheet( rStrm );
744 void XclImpLinkManager::ReadSupbook( XclImpStream& rStrm )
746 mxImpl->ReadSupbook( rStrm );
749 void XclImpLinkManager::ReadXct( XclImpStream& rStrm )
751 mxImpl->ReadXct( rStrm );
754 void XclImpLinkManager::ReadCrn( XclImpStream& rStrm )
756 mxImpl->ReadCrn( rStrm );
759 void XclImpLinkManager::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
761 mxImpl->ReadExternname( rStrm, pFormulaConv );
764 bool XclImpLinkManager::IsSelfRef( sal_uInt16 nXtiIndex ) const
766 return mxImpl->IsSelfRef( nXtiIndex );
769 bool XclImpLinkManager::GetScTabRange(
770 SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
772 return mxImpl->GetScTabRange( rnFirstScTab, rnLastScTab, nXtiIndex );
775 const XclImpExtName* XclImpLinkManager::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
777 return mxImpl->GetExternName( nXtiIndex, nExtName );
780 const String* XclImpLinkManager::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
782 return mxImpl->GetSupbookUrl(nXtiIndex);
785 const String& XclImpLinkManager::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
787 return mxImpl->GetSupbookTabName(nXti, nXtiTab);
790 bool XclImpLinkManager::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
792 return mxImpl->GetLinkData( rApplic, rTopic, nXtiIndex );
795 const String& XclImpLinkManager::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
797 return mxImpl->GetMacroName( nExtSheet, nExtName );
800 // ============================================================================