1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5b3f79822SAndrew Rist * distributed with this work for additional information
6b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10b3f79822SAndrew Rist *
11b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist *
13b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist * software distributed under the License is distributed on an
15b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17b3f79822SAndrew Rist * specific language governing permissions and limitations
18b3f79822SAndrew Rist * under the License.
19b3f79822SAndrew Rist *
20b3f79822SAndrew Rist *************************************************************/
21b3f79822SAndrew Rist
22b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25*b77af630Sdamjan #include "precompiled_scfilt.hxx"
26cdf0e10cSrcweir #include "xilink.hxx"
27cdf0e10cSrcweir #include "document.hxx"
28cdf0e10cSrcweir #include "cell.hxx"
29cdf0e10cSrcweir #include "scextopt.hxx"
30cdf0e10cSrcweir #include "tablink.hxx"
31cdf0e10cSrcweir #include "xistream.hxx"
32cdf0e10cSrcweir #include "xihelper.hxx"
33cdf0e10cSrcweir #include "xiname.hxx"
34cdf0e10cSrcweir #include "excform.hxx"
35cdf0e10cSrcweir #include "tokenarray.hxx"
36cdf0e10cSrcweir #include "externalrefmgr.hxx"
37cdf0e10cSrcweir
38cdf0e10cSrcweir #include <vector>
39cdf0e10cSrcweir
40cdf0e10cSrcweir using ::std::vector;
41cdf0e10cSrcweir
42cdf0e10cSrcweir // ============================================================================
43cdf0e10cSrcweir // *** Helper classes ***
44cdf0e10cSrcweir // ============================================================================
45cdf0e10cSrcweir
46cdf0e10cSrcweir // Cached external cells ======================================================
47cdf0e10cSrcweir
48cdf0e10cSrcweir /** Contains the address and value of an external referenced cell. */
49cdf0e10cSrcweir class XclImpCrn : public XclImpCachedValue
50cdf0e10cSrcweir {
51cdf0e10cSrcweir public:
52cdf0e10cSrcweir /** Reads a cached value and stores it with its cell address. */
53cdf0e10cSrcweir explicit XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
54cdf0e10cSrcweir
55cdf0e10cSrcweir const XclAddress& GetAddress() const;
56cdf0e10cSrcweir
57cdf0e10cSrcweir private:
58cdf0e10cSrcweir XclAddress maXclPos; /// Excel position of the cached cell.
59cdf0e10cSrcweir };
60cdf0e10cSrcweir
61cdf0e10cSrcweir // Sheet in an external document ==============================================
62cdf0e10cSrcweir
63cdf0e10cSrcweir /** Contains the name and sheet index of one sheet in an external document. */
64cdf0e10cSrcweir class XclImpSupbookTab
65cdf0e10cSrcweir {
66cdf0e10cSrcweir public:
67cdf0e10cSrcweir /** Stores the sheet name and marks the sheet index as invalid.
68cdf0e10cSrcweir The sheet index is set while creating the Calc sheet with CreateTable(). */
69cdf0e10cSrcweir explicit XclImpSupbookTab( const String& rTabName );
70cdf0e10cSrcweir ~XclImpSupbookTab();
71cdf0e10cSrcweir
GetTabName() const72cdf0e10cSrcweir inline const String& GetTabName() const { return maTabName; }
73cdf0e10cSrcweir
74cdf0e10cSrcweir /** Reads a CRN record (external referenced cell) at the specified address. */
75cdf0e10cSrcweir void ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
76cdf0e10cSrcweir
77cdf0e10cSrcweir void LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable);
78cdf0e10cSrcweir
79cdf0e10cSrcweir private:
80cdf0e10cSrcweir typedef ScfDelList< XclImpCrn > XclImpCrnList;
81cdf0e10cSrcweir
82cdf0e10cSrcweir XclImpCrnList maCrnList; /// List of CRN records (cached cell values).
83cdf0e10cSrcweir String maTabName; /// Name of the external sheet.
84cdf0e10cSrcweir SCTAB mnScTab; /// New sheet index in Calc document.
85cdf0e10cSrcweir };
86cdf0e10cSrcweir
87cdf0e10cSrcweir // External document (SUPBOOK) ================================================
88cdf0e10cSrcweir
89cdf0e10cSrcweir /** This class represents an external linked document (record SUPBOOK).
90cdf0e10cSrcweir @descr Contains a list of all referenced sheets in the document. */
91cdf0e10cSrcweir class XclImpSupbook : protected XclImpRoot
92cdf0e10cSrcweir {
93cdf0e10cSrcweir public:
94cdf0e10cSrcweir /** Reads the SUPBOOK record from stream. */
95cdf0e10cSrcweir explicit XclImpSupbook( XclImpStream& rStrm );
96cdf0e10cSrcweir
97cdf0e10cSrcweir /** Reads an XCT record (count of following CRNs and current sheet). */
98cdf0e10cSrcweir void ReadXct( XclImpStream& rStrm );
99cdf0e10cSrcweir /** Reads a CRN record (external referenced cell). */
100cdf0e10cSrcweir void ReadCrn( XclImpStream& rStrm );
101cdf0e10cSrcweir /** Reads an EXTERNNAME record. */
102cdf0e10cSrcweir void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
103cdf0e10cSrcweir
104cdf0e10cSrcweir /** Returns the SUPBOOK record type. */
GetType() const105cdf0e10cSrcweir inline XclSupbookType GetType() const { return meType; }
106cdf0e10cSrcweir
107cdf0e10cSrcweir /** Returns the URL of the external document. */
GetXclUrl() const108cdf0e10cSrcweir inline const String& GetXclUrl() const { return maXclUrl; }
109cdf0e10cSrcweir
110cdf0e10cSrcweir /** Returns the external name specified by an index from the Excel document (one-based). */
111cdf0e10cSrcweir const XclImpExtName* GetExternName( sal_uInt16 nXclIndex ) const;
112cdf0e10cSrcweir /** Tries to decode the URL to OLE or DDE link components.
113cdf0e10cSrcweir @descr For DDE links: Decodes to application name and topic.
114cdf0e10cSrcweir For OLE object links: Decodes to class name and document URL.
115cdf0e10cSrcweir @return true = decoding was successful, returned strings are valid (not empty). */
116cdf0e10cSrcweir bool GetLinkData( String& rApplic, String& rDoc ) const;
117cdf0e10cSrcweir /** Returns the specified macro name (1-based) or an empty string on error. */
118cdf0e10cSrcweir const String& GetMacroName( sal_uInt16 nXclNameIdx ) const;
119cdf0e10cSrcweir
120cdf0e10cSrcweir const String& GetTabName( sal_uInt16 nXtiTab ) const;
121cdf0e10cSrcweir
122cdf0e10cSrcweir sal_uInt16 GetTabCount() const;
123cdf0e10cSrcweir
124cdf0e10cSrcweir void LoadCachedValues();
125cdf0e10cSrcweir
126cdf0e10cSrcweir private:
127cdf0e10cSrcweir typedef ScfDelList< XclImpSupbookTab > XclImpSupbookTabList;
128cdf0e10cSrcweir typedef ScfDelList< XclImpExtName > XclImpExtNameList;
129cdf0e10cSrcweir
130cdf0e10cSrcweir XclImpSupbookTabList maSupbTabList; /// All sheet names of the document.
131cdf0e10cSrcweir XclImpExtNameList maExtNameList; /// All external names of the document.
132cdf0e10cSrcweir String maXclUrl; /// URL of the external document (Excel mode).
133cdf0e10cSrcweir String maFilterName; /// Detected filer name.
134cdf0e10cSrcweir String maFilterOpt; /// Detected filer options.
135cdf0e10cSrcweir XclSupbookType meType; /// Type of the supbook record.
136cdf0e10cSrcweir sal_uInt16 mnSBTab; /// Current Excel sheet index from SUPBOOK for XCT/CRN records.
137cdf0e10cSrcweir };
138cdf0e10cSrcweir
139cdf0e10cSrcweir // Import link manager ========================================================
140cdf0e10cSrcweir
141cdf0e10cSrcweir /** Contains the SUPBOOK index and sheet indexes of an external link.
142cdf0e10cSrcweir @descr It is possible to enter a formula like =SUM(Sheet1:Sheet3!A1),
143cdf0e10cSrcweir therefore here occurs a sheet range. */
144cdf0e10cSrcweir struct XclImpXti
145cdf0e10cSrcweir {
146cdf0e10cSrcweir sal_uInt16 mnSupbook; /// Index to SUPBOOK record.
147cdf0e10cSrcweir sal_uInt16 mnSBTabFirst; /// Index to the first sheet of the range in the SUPBOOK.
148cdf0e10cSrcweir sal_uInt16 mnSBTabLast; /// Index to the last sheet of the range in the SUPBOOK.
XclImpXtiXclImpXti149cdf0e10cSrcweir inline explicit XclImpXti() : mnSupbook( SAL_MAX_UINT16 ), mnSBTabFirst( SAL_MAX_UINT16 ), mnSBTabLast( SAL_MAX_UINT16 ) {}
150cdf0e10cSrcweir };
151cdf0e10cSrcweir
operator >>(XclImpStream & rStrm,XclImpXti & rXti)152cdf0e10cSrcweir inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpXti& rXti )
153cdf0e10cSrcweir {
154cdf0e10cSrcweir return rStrm >> rXti.mnSupbook >> rXti.mnSBTabFirst >> rXti.mnSBTabLast;
155cdf0e10cSrcweir }
156cdf0e10cSrcweir
157cdf0e10cSrcweir // ----------------------------------------------------------------------------
158cdf0e10cSrcweir
159cdf0e10cSrcweir /** Implementation of the link manager. */
160cdf0e10cSrcweir class XclImpLinkManagerImpl : protected XclImpRoot
161cdf0e10cSrcweir {
162cdf0e10cSrcweir public:
163cdf0e10cSrcweir explicit XclImpLinkManagerImpl( const XclImpRoot& rRoot );
164cdf0e10cSrcweir
165cdf0e10cSrcweir /** Reads the EXTERNSHEET record. */
166cdf0e10cSrcweir void ReadExternsheet( XclImpStream& rStrm );
167cdf0e10cSrcweir /** Reads a SUPBOOK record. */
168cdf0e10cSrcweir void ReadSupbook( XclImpStream& rStrm );
169cdf0e10cSrcweir /** Reads an XCT record and appends it to the current SUPBOOK. */
170cdf0e10cSrcweir void ReadXct( XclImpStream& rStrm );
171cdf0e10cSrcweir /** Reads a CRN record and appends it to the current SUPBOOK. */
172cdf0e10cSrcweir void ReadCrn( XclImpStream& rStrm );
173cdf0e10cSrcweir /** Reads an EXTERNNAME record and appends it to the current SUPBOOK. */
174cdf0e10cSrcweir void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
175cdf0e10cSrcweir
176cdf0e10cSrcweir /** Returns true, if the specified XTI entry contains an internal reference. */
177cdf0e10cSrcweir bool IsSelfRef( sal_uInt16 nXtiIndex ) const;
178cdf0e10cSrcweir /** Returns the Calc sheet index range of the specified XTI entry.
179cdf0e10cSrcweir @return true = XTI data found, returned sheet index range is valid. */
180cdf0e10cSrcweir bool GetScTabRange(
181cdf0e10cSrcweir SCTAB& rnFirstScTab, SCTAB& rnLastScTab,
182cdf0e10cSrcweir sal_uInt16 nXtiIndex ) const;
183cdf0e10cSrcweir /** Returns the specified external name or 0 on error. */
184cdf0e10cSrcweir const XclImpExtName* GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const;
185cdf0e10cSrcweir
186cdf0e10cSrcweir /** Returns the absolute file URL of a supporting workbook specified by
187cdf0e10cSrcweir the index. */
188cdf0e10cSrcweir const String* GetSupbookUrl( sal_uInt16 nXtiIndex ) const;
189cdf0e10cSrcweir
190cdf0e10cSrcweir const String& GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const;
191cdf0e10cSrcweir
192cdf0e10cSrcweir /** Tries to decode the URL of the specified XTI entry to OLE or DDE link components.
193cdf0e10cSrcweir @descr For DDE links: Decodes to application name and topic.
194cdf0e10cSrcweir For OLE object links: Decodes to class name and document URL.
195cdf0e10cSrcweir @return true = decoding was successful, returned strings are valid (not empty). */
196cdf0e10cSrcweir bool GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const;
197cdf0e10cSrcweir /** Returns the specified macro name or an empty string on error. */
198cdf0e10cSrcweir const String& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const;
199cdf0e10cSrcweir
200cdf0e10cSrcweir private:
201cdf0e10cSrcweir /** Returns the specified XTI (link entry from BIFF8 EXTERNSHEET record). */
202cdf0e10cSrcweir const XclImpXti* GetXti( sal_uInt16 nXtiIndex ) const;
203cdf0e10cSrcweir /** Returns the specified SUPBOOK (external document). */
204cdf0e10cSrcweir const XclImpSupbook* GetSupbook( sal_uInt16 nXtiIndex ) const;
205cdf0e10cSrcweir //UNUSED2009-05 /** Returns the SUPBOOK (external workbook) specified by its URL. */
206cdf0e10cSrcweir //UNUSED2009-05 const XclImpSupbook* GetSupbook( const String& rUrl ) const;
207cdf0e10cSrcweir
208cdf0e10cSrcweir void LoadCachedValues();
209cdf0e10cSrcweir
210cdf0e10cSrcweir //UNUSED2009-05 /** Finds the largest range of sheet indexes in a SUPBOOK after a start sheet index.
211cdf0e10cSrcweir //UNUSED2009-05 @param rnSBTabFirst (out-param) The first sheet index of the range in SUPBOOK is returned here.
212cdf0e10cSrcweir //UNUSED2009-05 @param rnSBTabLast (out-param) The last sheet index of the range in SUPBOOK is returned here (inclusive).
213cdf0e10cSrcweir //UNUSED2009-05 @param nSupbook The list index of the SUPBOOK.
214cdf0e10cSrcweir //UNUSED2009-05 @param nSBTabStart The first allowed sheet index. Sheet ranges with an earlier start index are ignored.
215cdf0e10cSrcweir //UNUSED2009-05 @return true = the return values are valid; false = nothing found. */
216cdf0e10cSrcweir //UNUSED2009-05 bool FindNextTabRange(
217cdf0e10cSrcweir //UNUSED2009-05 sal_uInt16& rnSBTabFirst, sal_uInt16& rnSBTabLast,
218cdf0e10cSrcweir //UNUSED2009-05 sal_uInt16 nSupbook, sal_uInt16 nSBTabStart ) const;
219cdf0e10cSrcweir
220cdf0e10cSrcweir private:
221cdf0e10cSrcweir typedef ::std::vector< XclImpXti > XclImpXtiVector;
222cdf0e10cSrcweir typedef ScfDelList< XclImpSupbook > XclImpSupbookList;
223cdf0e10cSrcweir
224cdf0e10cSrcweir XclImpXtiVector maXtiList; /// List of all XTI structures.
225cdf0e10cSrcweir XclImpSupbookList maSupbookList; /// List of external documents.
226cdf0e10cSrcweir bool mbCreated; /// true = Calc sheets already created.
227cdf0e10cSrcweir };
228cdf0e10cSrcweir
229cdf0e10cSrcweir // ============================================================================
230cdf0e10cSrcweir // *** Implementation ***
231cdf0e10cSrcweir // ============================================================================
232cdf0e10cSrcweir
233cdf0e10cSrcweir // Excel sheet indexes ========================================================
234cdf0e10cSrcweir
235cdf0e10cSrcweir // original Excel sheet names -------------------------------------------------
236cdf0e10cSrcweir
AppendXclTabName(const String & rXclTabName,SCTAB nScTab)237cdf0e10cSrcweir void XclImpTabInfo::AppendXclTabName( const String& rXclTabName, SCTAB nScTab )
238cdf0e10cSrcweir {
239cdf0e10cSrcweir maTabNames[ rXclTabName ] = nScTab;
240cdf0e10cSrcweir }
241cdf0e10cSrcweir
InsertScTab(SCTAB nScTab)242cdf0e10cSrcweir void XclImpTabInfo::InsertScTab( SCTAB nScTab )
243cdf0e10cSrcweir {
244cdf0e10cSrcweir for( XclTabNameMap::iterator aIt = maTabNames.begin(), aEnd = maTabNames.end(); aIt != aEnd; ++aIt )
245cdf0e10cSrcweir if( aIt->second >= nScTab )
246cdf0e10cSrcweir ++aIt->second;
247cdf0e10cSrcweir }
248cdf0e10cSrcweir
GetScTabFromXclName(const String & rXclTabName) const249cdf0e10cSrcweir SCTAB XclImpTabInfo::GetScTabFromXclName( const String& rXclTabName ) const
250cdf0e10cSrcweir {
251cdf0e10cSrcweir XclTabNameMap::const_iterator aIt = maTabNames.find( rXclTabName );
252cdf0e10cSrcweir return (aIt != maTabNames.end()) ? aIt->second : SCTAB_INVALID;
253cdf0e10cSrcweir }
254cdf0e10cSrcweir
255cdf0e10cSrcweir // record creation order - TABID record ---------------------------------------
256cdf0e10cSrcweir
ReadTabid(XclImpStream & rStrm)257cdf0e10cSrcweir void XclImpTabInfo::ReadTabid( XclImpStream& rStrm )
258cdf0e10cSrcweir {
259cdf0e10cSrcweir DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() == EXC_BIFF8 );
260cdf0e10cSrcweir if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
261cdf0e10cSrcweir {
262cdf0e10cSrcweir rStrm.EnableDecryption();
263cdf0e10cSrcweir sal_Size nReadCount = rStrm.GetRecLeft() / 2;
264cdf0e10cSrcweir DBG_ASSERT( nReadCount <= 0xFFFF, "XclImpTabInfo::ReadTabid - record too long" );
265cdf0e10cSrcweir maTabIdVec.clear();
266cdf0e10cSrcweir maTabIdVec.reserve( nReadCount );
267cdf0e10cSrcweir for( sal_Size nIndex = 0; rStrm.IsValid() && (nIndex < nReadCount); ++nIndex )
268cdf0e10cSrcweir // #93471# zero index is not allowed in BIFF8, but it seems that it occurs in real life
269cdf0e10cSrcweir maTabIdVec.push_back( rStrm.ReaduInt16() );
270cdf0e10cSrcweir }
271cdf0e10cSrcweir }
272cdf0e10cSrcweir
GetCurrentIndex(sal_uInt16 nCreatedId,sal_uInt16 nMaxTabId) const273cdf0e10cSrcweir sal_uInt16 XclImpTabInfo::GetCurrentIndex( sal_uInt16 nCreatedId, sal_uInt16 nMaxTabId ) const
274cdf0e10cSrcweir {
275cdf0e10cSrcweir sal_uInt16 nReturn = 0;
276cdf0e10cSrcweir for( ScfUInt16Vec::const_iterator aIt = maTabIdVec.begin(), aEnd = maTabIdVec.end(); aIt != aEnd; ++aIt )
277cdf0e10cSrcweir {
278cdf0e10cSrcweir sal_uInt16 nValue = *aIt;
279cdf0e10cSrcweir if( nValue == nCreatedId )
280cdf0e10cSrcweir return nReturn;
281cdf0e10cSrcweir if( nValue <= nMaxTabId )
282cdf0e10cSrcweir ++nReturn;
283cdf0e10cSrcweir }
284cdf0e10cSrcweir return 0;
285cdf0e10cSrcweir }
286cdf0e10cSrcweir
287cdf0e10cSrcweir // External names =============================================================
288cdf0e10cSrcweir
XclImpExtName(const XclImpSupbook & rSupbook,XclImpStream & rStrm,XclSupbookType eSubType,ExcelToSc * pFormulaConv)289cdf0e10cSrcweir XclImpExtName::XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm, XclSupbookType eSubType, ExcelToSc* pFormulaConv )
290cdf0e10cSrcweir {
291cdf0e10cSrcweir sal_uInt16 nFlags;
292cdf0e10cSrcweir sal_uInt8 nLen;
293cdf0e10cSrcweir
294cdf0e10cSrcweir rStrm >> nFlags >> mnStorageId >> nLen ;
295cdf0e10cSrcweir maName = rStrm.ReadUniString( nLen );
296cdf0e10cSrcweir if( ::get_flag( nFlags, EXC_EXTN_BUILTIN ) || !::get_flag( nFlags, EXC_EXTN_OLE_OR_DDE ) )
297cdf0e10cSrcweir {
298cdf0e10cSrcweir if( eSubType == EXC_SBTYPE_ADDIN )
299cdf0e10cSrcweir {
300cdf0e10cSrcweir meType = xlExtAddIn;
301cdf0e10cSrcweir maName = rStrm.GetRoot().GetScAddInName( maName );
302cdf0e10cSrcweir }
303cdf0e10cSrcweir else if ( (eSubType == EXC_SBTYPE_EUROTOOL) &&
304cdf0e10cSrcweir maName.EqualsIgnoreCaseAscii( "EUROCONVERT" ) )
305cdf0e10cSrcweir meType = xlExtEuroConvert;
306cdf0e10cSrcweir else
307cdf0e10cSrcweir {
308cdf0e10cSrcweir meType = xlExtName;
309cdf0e10cSrcweir ScfTools::ConvertToScDefinedName( maName );
310cdf0e10cSrcweir }
311cdf0e10cSrcweir }
312cdf0e10cSrcweir else
313cdf0e10cSrcweir {
314cdf0e10cSrcweir meType = ::get_flagvalue( nFlags, EXC_EXTN_OLE, xlExtOLE, xlExtDDE );
315cdf0e10cSrcweir }
316cdf0e10cSrcweir
317cdf0e10cSrcweir if( (meType == xlExtDDE) && (rStrm.GetRecLeft() > 1) )
318cdf0e10cSrcweir mxDdeMatrix.reset( new XclImpCachedMatrix( rStrm ) );
319cdf0e10cSrcweir
320cdf0e10cSrcweir if (meType == xlExtName)
321cdf0e10cSrcweir {
322cdf0e10cSrcweir // TODO: For now, only global external names are supported. In future
323cdf0e10cSrcweir // we should extend this to supporting per-sheet external names.
324cdf0e10cSrcweir if (mnStorageId == 0)
325cdf0e10cSrcweir {
326cdf0e10cSrcweir if (pFormulaConv)
327cdf0e10cSrcweir {
328cdf0e10cSrcweir const ScTokenArray* pArray = NULL;
329cdf0e10cSrcweir sal_uInt16 nFmlaLen;
330cdf0e10cSrcweir rStrm >> nFmlaLen;
331cdf0e10cSrcweir vector<String> aTabNames;
332cdf0e10cSrcweir sal_uInt16 nCount = rSupbook.GetTabCount();
333cdf0e10cSrcweir aTabNames.reserve(nCount);
334cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nCount; ++i)
335cdf0e10cSrcweir aTabNames.push_back(rSupbook.GetTabName(i));
336cdf0e10cSrcweir
337cdf0e10cSrcweir pFormulaConv->ConvertExternName(pArray, rStrm, nFmlaLen, rSupbook.GetXclUrl(), aTabNames);
338cdf0e10cSrcweir if (pArray)
339cdf0e10cSrcweir mxArray.reset(pArray->Clone());
340cdf0e10cSrcweir }
341cdf0e10cSrcweir }
342cdf0e10cSrcweir }
343cdf0e10cSrcweir }
344cdf0e10cSrcweir
~XclImpExtName()345cdf0e10cSrcweir XclImpExtName::~XclImpExtName()
346cdf0e10cSrcweir {
347cdf0e10cSrcweir }
348cdf0e10cSrcweir
CreateDdeData(ScDocument & rDoc,const String & rApplic,const String & rTopic) const349cdf0e10cSrcweir void XclImpExtName::CreateDdeData( ScDocument& rDoc, const String& rApplic, const String& rTopic ) const
350cdf0e10cSrcweir {
351cdf0e10cSrcweir ScMatrixRef xResults;
352cdf0e10cSrcweir if( mxDdeMatrix.get() )
353cdf0e10cSrcweir xResults = mxDdeMatrix->CreateScMatrix();
354cdf0e10cSrcweir rDoc.CreateDdeLink( rApplic, rTopic, maName, SC_DDE_DEFAULT, xResults );
355cdf0e10cSrcweir }
356cdf0e10cSrcweir
CreateExtNameData(ScDocument & rDoc,sal_uInt16 nFileId) const357cdf0e10cSrcweir void XclImpExtName::CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) const
358cdf0e10cSrcweir {
359cdf0e10cSrcweir if (!mxArray.get())
360cdf0e10cSrcweir return;
361cdf0e10cSrcweir
362cdf0e10cSrcweir ScExternalRefManager* pRefMgr = rDoc.GetExternalRefManager();
363cdf0e10cSrcweir pRefMgr->storeRangeNameTokens(nFileId, maName, *mxArray);
364cdf0e10cSrcweir }
365cdf0e10cSrcweir
HasFormulaTokens() const366cdf0e10cSrcweir bool XclImpExtName::HasFormulaTokens() const
367cdf0e10cSrcweir {
368cdf0e10cSrcweir return (mxArray.get() != NULL);
369cdf0e10cSrcweir }
370cdf0e10cSrcweir
371cdf0e10cSrcweir // Cached external cells ======================================================
372cdf0e10cSrcweir
XclImpCrn(XclImpStream & rStrm,const XclAddress & rXclPos)373cdf0e10cSrcweir XclImpCrn::XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos ) :
374cdf0e10cSrcweir XclImpCachedValue( rStrm ),
375cdf0e10cSrcweir maXclPos( rXclPos )
376cdf0e10cSrcweir {
377cdf0e10cSrcweir }
378cdf0e10cSrcweir
GetAddress() const379cdf0e10cSrcweir const XclAddress& XclImpCrn::GetAddress() const
380cdf0e10cSrcweir {
381cdf0e10cSrcweir return maXclPos;
382cdf0e10cSrcweir }
383cdf0e10cSrcweir
384cdf0e10cSrcweir // Sheet in an external document ==============================================
385cdf0e10cSrcweir
XclImpSupbookTab(const String & rTabName)386cdf0e10cSrcweir XclImpSupbookTab::XclImpSupbookTab( const String& rTabName ) :
387cdf0e10cSrcweir maTabName( rTabName ),
388cdf0e10cSrcweir mnScTab( SCTAB_INVALID )
389cdf0e10cSrcweir {
390cdf0e10cSrcweir }
391cdf0e10cSrcweir
~XclImpSupbookTab()392cdf0e10cSrcweir XclImpSupbookTab::~XclImpSupbookTab()
393cdf0e10cSrcweir {
394cdf0e10cSrcweir }
395cdf0e10cSrcweir
ReadCrn(XclImpStream & rStrm,const XclAddress & rXclPos)396cdf0e10cSrcweir void XclImpSupbookTab::ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos )
397cdf0e10cSrcweir {
398cdf0e10cSrcweir maCrnList.Append( new XclImpCrn( rStrm, rXclPos ) );
399cdf0e10cSrcweir }
400cdf0e10cSrcweir
LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable)401cdf0e10cSrcweir void XclImpSupbookTab::LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable)
402cdf0e10cSrcweir {
403cdf0e10cSrcweir if (maCrnList.Empty())
404cdf0e10cSrcweir return;
405cdf0e10cSrcweir
406cdf0e10cSrcweir for (XclImpCrn* p = maCrnList.First(); p; p = maCrnList.Next())
407cdf0e10cSrcweir {
408cdf0e10cSrcweir const XclAddress& rAddr = p->GetAddress();
409cdf0e10cSrcweir switch (p->GetType())
410cdf0e10cSrcweir {
411cdf0e10cSrcweir case EXC_CACHEDVAL_BOOL:
412cdf0e10cSrcweir {
413cdf0e10cSrcweir bool b = p->GetBool();
414cdf0e10cSrcweir ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(b ? 1.0 : 0.0));
415cdf0e10cSrcweir pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
416cdf0e10cSrcweir }
417cdf0e10cSrcweir break;
418cdf0e10cSrcweir case EXC_CACHEDVAL_DOUBLE:
419cdf0e10cSrcweir {
420cdf0e10cSrcweir double f = p->GetValue();
421cdf0e10cSrcweir ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(f));
422cdf0e10cSrcweir pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
423cdf0e10cSrcweir }
424cdf0e10cSrcweir break;
425cdf0e10cSrcweir case EXC_CACHEDVAL_ERROR:
426cdf0e10cSrcweir {
427cdf0e10cSrcweir double fError = XclTools::ErrorToDouble( p->GetXclError() );
428cdf0e10cSrcweir ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(fError));
429cdf0e10cSrcweir pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
430cdf0e10cSrcweir }
431cdf0e10cSrcweir break;
432cdf0e10cSrcweir case EXC_CACHEDVAL_STRING:
433cdf0e10cSrcweir {
434cdf0e10cSrcweir const String& rStr = p->GetString();
435cdf0e10cSrcweir ScExternalRefCache::TokenRef pToken(new formula::FormulaStringToken(rStr));
436cdf0e10cSrcweir pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
437cdf0e10cSrcweir }
438cdf0e10cSrcweir break;
439cdf0e10cSrcweir default:
440cdf0e10cSrcweir ;
441cdf0e10cSrcweir }
442cdf0e10cSrcweir }
443cdf0e10cSrcweir }
444cdf0e10cSrcweir
445cdf0e10cSrcweir // External document (SUPBOOK) ================================================
446cdf0e10cSrcweir
XclImpSupbook(XclImpStream & rStrm)447cdf0e10cSrcweir XclImpSupbook::XclImpSupbook( XclImpStream& rStrm ) :
448cdf0e10cSrcweir XclImpRoot( rStrm.GetRoot() ),
449cdf0e10cSrcweir meType( EXC_SBTYPE_UNKNOWN ),
450cdf0e10cSrcweir mnSBTab( EXC_TAB_DELETED )
451cdf0e10cSrcweir {
452cdf0e10cSrcweir sal_uInt16 nSBTabCnt;
453cdf0e10cSrcweir rStrm >> nSBTabCnt;
454cdf0e10cSrcweir
455cdf0e10cSrcweir if( rStrm.GetRecLeft() == 2 )
456cdf0e10cSrcweir {
457cdf0e10cSrcweir switch( rStrm.ReaduInt16() )
458cdf0e10cSrcweir {
459cdf0e10cSrcweir case EXC_SUPB_SELF: meType = EXC_SBTYPE_SELF; break;
460cdf0e10cSrcweir case EXC_SUPB_ADDIN: meType = EXC_SBTYPE_ADDIN; break;
461cdf0e10cSrcweir default: DBG_ERRORFILE( "XclImpSupbook::XclImpSupbook - unknown special SUPBOOK type" );
462cdf0e10cSrcweir }
463cdf0e10cSrcweir return;
464cdf0e10cSrcweir }
465cdf0e10cSrcweir
466cdf0e10cSrcweir String aEncUrl( rStrm.ReadUniString() );
467cdf0e10cSrcweir bool bSelf = false;
468cdf0e10cSrcweir XclImpUrlHelper::DecodeUrl( maXclUrl, bSelf, GetRoot(), aEncUrl );
469cdf0e10cSrcweir
470cdf0e10cSrcweir if( maXclUrl.EqualsIgnoreCaseAscii( "\010EUROTOOL.XLA" ) )
471cdf0e10cSrcweir {
472cdf0e10cSrcweir meType = EXC_SBTYPE_EUROTOOL;
473cdf0e10cSrcweir maSupbTabList.Append( new XclImpSupbookTab( maXclUrl ) );
474cdf0e10cSrcweir }
475cdf0e10cSrcweir else if( nSBTabCnt )
476cdf0e10cSrcweir {
477cdf0e10cSrcweir meType = EXC_SBTYPE_EXTERN;
478cdf0e10cSrcweir for( sal_uInt16 nSBTab = 0; nSBTab < nSBTabCnt; ++nSBTab )
479cdf0e10cSrcweir {
480cdf0e10cSrcweir String aTabName( rStrm.ReadUniString() );
481cdf0e10cSrcweir maSupbTabList.Append( new XclImpSupbookTab( aTabName ) );
482cdf0e10cSrcweir }
483cdf0e10cSrcweir }
484cdf0e10cSrcweir else
485cdf0e10cSrcweir {
486cdf0e10cSrcweir meType = EXC_SBTYPE_SPECIAL;
487cdf0e10cSrcweir // create dummy list entry
488cdf0e10cSrcweir maSupbTabList.Append( new XclImpSupbookTab( maXclUrl ) );
489cdf0e10cSrcweir }
490cdf0e10cSrcweir }
491cdf0e10cSrcweir
ReadXct(XclImpStream & rStrm)492cdf0e10cSrcweir void XclImpSupbook::ReadXct( XclImpStream& rStrm )
493cdf0e10cSrcweir {
494cdf0e10cSrcweir rStrm.Ignore( 2 );
495cdf0e10cSrcweir rStrm >> mnSBTab;
496cdf0e10cSrcweir }
497cdf0e10cSrcweir
ReadCrn(XclImpStream & rStrm)498cdf0e10cSrcweir void XclImpSupbook::ReadCrn( XclImpStream& rStrm )
499cdf0e10cSrcweir {
500cdf0e10cSrcweir if( XclImpSupbookTab* pSBTab = maSupbTabList.GetObject( mnSBTab ) )
501cdf0e10cSrcweir {
502cdf0e10cSrcweir sal_uInt8 nXclColLast, nXclColFirst;
503cdf0e10cSrcweir sal_uInt16 nXclRow;
504cdf0e10cSrcweir rStrm >> nXclColLast >> nXclColFirst >> nXclRow;
505cdf0e10cSrcweir
506cdf0e10cSrcweir for( sal_uInt8 nXclCol = nXclColFirst; (nXclCol <= nXclColLast) && (rStrm.GetRecLeft() > 1); ++nXclCol )
507cdf0e10cSrcweir pSBTab->ReadCrn( rStrm, XclAddress( nXclCol, nXclRow ) );
508cdf0e10cSrcweir }
509cdf0e10cSrcweir }
510cdf0e10cSrcweir
ReadExternname(XclImpStream & rStrm,ExcelToSc * pFormulaConv)511cdf0e10cSrcweir void XclImpSupbook::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
512cdf0e10cSrcweir {
513cdf0e10cSrcweir maExtNameList.Append( new XclImpExtName( *this, rStrm, meType, pFormulaConv ) );
514cdf0e10cSrcweir }
515cdf0e10cSrcweir
GetExternName(sal_uInt16 nXclIndex) const516cdf0e10cSrcweir const XclImpExtName* XclImpSupbook::GetExternName( sal_uInt16 nXclIndex ) const
517cdf0e10cSrcweir {
518cdf0e10cSrcweir DBG_ASSERT( nXclIndex > 0, "XclImpSupbook::GetExternName - index must be >0" );
519cdf0e10cSrcweir return (meType == EXC_SBTYPE_SELF) ? 0 : maExtNameList.GetObject( nXclIndex - 1 );
520cdf0e10cSrcweir }
521cdf0e10cSrcweir
GetLinkData(String & rApplic,String & rTopic) const522cdf0e10cSrcweir bool XclImpSupbook::GetLinkData( String& rApplic, String& rTopic ) const
523cdf0e10cSrcweir {
524cdf0e10cSrcweir return (meType == EXC_SBTYPE_SPECIAL) && XclImpUrlHelper::DecodeLink( rApplic, rTopic, maXclUrl );
525cdf0e10cSrcweir }
526cdf0e10cSrcweir
GetMacroName(sal_uInt16 nXclNameIdx) const527cdf0e10cSrcweir const String& XclImpSupbook::GetMacroName( sal_uInt16 nXclNameIdx ) const
528cdf0e10cSrcweir {
529cdf0e10cSrcweir DBG_ASSERT( nXclNameIdx > 0, "XclImpSupbook::GetMacroName - index must be >0" );
530cdf0e10cSrcweir const XclImpName* pName = (meType == EXC_SBTYPE_SELF) ? GetNameManager().GetName( nXclNameIdx ) : 0;
531cdf0e10cSrcweir return (pName && pName->IsVBName()) ? pName->GetScName() : EMPTY_STRING;
532cdf0e10cSrcweir }
533cdf0e10cSrcweir
GetTabName(sal_uInt16 nXtiTab) const534cdf0e10cSrcweir const String& XclImpSupbook::GetTabName( sal_uInt16 nXtiTab ) const
535cdf0e10cSrcweir {
536cdf0e10cSrcweir if (maSupbTabList.Empty())
537cdf0e10cSrcweir return EMPTY_STRING;
538cdf0e10cSrcweir
539cdf0e10cSrcweir sal_uInt16 i = 0;
540cdf0e10cSrcweir for (XclImpSupbookTab* p = maSupbTabList.First(); p; p = maSupbTabList.Next(), ++i)
541cdf0e10cSrcweir {
542cdf0e10cSrcweir if (i == nXtiTab)
543cdf0e10cSrcweir return p->GetTabName();
544cdf0e10cSrcweir }
545cdf0e10cSrcweir
546cdf0e10cSrcweir return EMPTY_STRING;
547cdf0e10cSrcweir }
548cdf0e10cSrcweir
GetTabCount() const549cdf0e10cSrcweir sal_uInt16 XclImpSupbook::GetTabCount() const
550cdf0e10cSrcweir {
551cdf0e10cSrcweir return ulimit_cast<sal_uInt16>(maSupbTabList.Count());
552cdf0e10cSrcweir }
553cdf0e10cSrcweir
LoadCachedValues()554cdf0e10cSrcweir void XclImpSupbook::LoadCachedValues()
555cdf0e10cSrcweir {
556cdf0e10cSrcweir if (meType != EXC_SBTYPE_EXTERN || GetExtDocOptions().GetDocSettings().mnLinkCnt > 0 || !GetDocShell())
557cdf0e10cSrcweir return;
558cdf0e10cSrcweir
559cdf0e10cSrcweir String aAbsUrl( ScGlobal::GetAbsDocName(maXclUrl, GetDocShell()) );
560cdf0e10cSrcweir
561cdf0e10cSrcweir ScExternalRefManager* pRefMgr = GetRoot().GetDoc().GetExternalRefManager();
562cdf0e10cSrcweir sal_uInt16 nFileId = pRefMgr->getExternalFileId(aAbsUrl);
563cdf0e10cSrcweir
564cdf0e10cSrcweir sal_uInt16 nCount = static_cast< sal_uInt16 >( maSupbTabList.Count() );
565cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nCount; ++i)
566cdf0e10cSrcweir {
567cdf0e10cSrcweir XclImpSupbookTab* pTab = maSupbTabList.GetObject(i);
568cdf0e10cSrcweir if (!pTab)
569cdf0e10cSrcweir return;
570cdf0e10cSrcweir
571cdf0e10cSrcweir const String& rTabName = pTab->GetTabName();
572cdf0e10cSrcweir ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
573cdf0e10cSrcweir pTab->LoadCachedValues(pCacheTable);
574cdf0e10cSrcweir pCacheTable->setWholeTableCached();
575cdf0e10cSrcweir }
576cdf0e10cSrcweir }
577cdf0e10cSrcweir
578cdf0e10cSrcweir // Import link manager ========================================================
579cdf0e10cSrcweir
XclImpLinkManagerImpl(const XclImpRoot & rRoot)580cdf0e10cSrcweir XclImpLinkManagerImpl::XclImpLinkManagerImpl( const XclImpRoot& rRoot ) :
581cdf0e10cSrcweir XclImpRoot( rRoot ),
582cdf0e10cSrcweir mbCreated( false )
583cdf0e10cSrcweir {
584cdf0e10cSrcweir }
585cdf0e10cSrcweir
ReadExternsheet(XclImpStream & rStrm)586cdf0e10cSrcweir void XclImpLinkManagerImpl::ReadExternsheet( XclImpStream& rStrm )
587cdf0e10cSrcweir {
588cdf0e10cSrcweir sal_uInt16 nXtiCount;
589cdf0e10cSrcweir rStrm >> nXtiCount;
590cdf0e10cSrcweir DBG_ASSERT( static_cast< sal_Size >( nXtiCount * 6 ) == rStrm.GetRecLeft(), "XclImpLinkManagerImpl::ReadExternsheet - invalid count" );
591cdf0e10cSrcweir nXtiCount = static_cast< sal_uInt16 >( ::std::min< sal_Size >( nXtiCount, rStrm.GetRecLeft() / 6 ) );
592cdf0e10cSrcweir
593cdf0e10cSrcweir /* #i104057# A weird external XLS generator writes multiple EXTERNSHEET
594cdf0e10cSrcweir records instead of only one as expected. Surprisingly, Excel seems to
595cdf0e10cSrcweir insert the entries of the second record before the entries of the first
596cdf0e10cSrcweir record. */
597cdf0e10cSrcweir XclImpXtiVector aNewEntries( nXtiCount );
598cdf0e10cSrcweir for( XclImpXtiVector::iterator aIt = aNewEntries.begin(), aEnd = aNewEntries.end(); rStrm.IsValid() && (aIt != aEnd); ++aIt )
599cdf0e10cSrcweir rStrm >> *aIt;
600cdf0e10cSrcweir maXtiList.insert( maXtiList.begin(), aNewEntries.begin(), aNewEntries.end() );
601cdf0e10cSrcweir
602cdf0e10cSrcweir LoadCachedValues();
603cdf0e10cSrcweir }
604cdf0e10cSrcweir
ReadSupbook(XclImpStream & rStrm)605cdf0e10cSrcweir void XclImpLinkManagerImpl::ReadSupbook( XclImpStream& rStrm )
606cdf0e10cSrcweir {
607cdf0e10cSrcweir maSupbookList.Append( new XclImpSupbook( rStrm ) );
608cdf0e10cSrcweir }
609cdf0e10cSrcweir
ReadXct(XclImpStream & rStrm)610cdf0e10cSrcweir void XclImpLinkManagerImpl::ReadXct( XclImpStream& rStrm )
611cdf0e10cSrcweir {
612cdf0e10cSrcweir if( XclImpSupbook* pSupbook = maSupbookList.Last() )
613cdf0e10cSrcweir pSupbook->ReadXct( rStrm );
614cdf0e10cSrcweir }
615cdf0e10cSrcweir
ReadCrn(XclImpStream & rStrm)616cdf0e10cSrcweir void XclImpLinkManagerImpl::ReadCrn( XclImpStream& rStrm )
617cdf0e10cSrcweir {
618cdf0e10cSrcweir if( XclImpSupbook* pSupbook = maSupbookList.Last() )
619cdf0e10cSrcweir pSupbook->ReadCrn( rStrm );
620cdf0e10cSrcweir }
621cdf0e10cSrcweir
ReadExternname(XclImpStream & rStrm,ExcelToSc * pFormulaConv)622cdf0e10cSrcweir void XclImpLinkManagerImpl::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
623cdf0e10cSrcweir {
624cdf0e10cSrcweir if( XclImpSupbook* pSupbook = maSupbookList.Last() )
625cdf0e10cSrcweir pSupbook->ReadExternname( rStrm, pFormulaConv );
626cdf0e10cSrcweir }
627cdf0e10cSrcweir
IsSelfRef(sal_uInt16 nXtiIndex) const628cdf0e10cSrcweir bool XclImpLinkManagerImpl::IsSelfRef( sal_uInt16 nXtiIndex ) const
629cdf0e10cSrcweir {
630cdf0e10cSrcweir const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
631cdf0e10cSrcweir return pSupbook && (pSupbook->GetType() == EXC_SBTYPE_SELF);
632cdf0e10cSrcweir }
633cdf0e10cSrcweir
GetScTabRange(SCTAB & rnFirstScTab,SCTAB & rnLastScTab,sal_uInt16 nXtiIndex) const634cdf0e10cSrcweir bool XclImpLinkManagerImpl::GetScTabRange(
635cdf0e10cSrcweir SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
636cdf0e10cSrcweir {
637cdf0e10cSrcweir if( const XclImpXti* pXti = GetXti( nXtiIndex ) )
638cdf0e10cSrcweir {
639cdf0e10cSrcweir if (maSupbookList.GetObject(pXti->mnSupbook))
640cdf0e10cSrcweir {
641cdf0e10cSrcweir rnFirstScTab = pXti->mnSBTabFirst;
642cdf0e10cSrcweir rnLastScTab = pXti->mnSBTabLast;
643cdf0e10cSrcweir return true;
644cdf0e10cSrcweir }
645cdf0e10cSrcweir }
646cdf0e10cSrcweir return false;
647cdf0e10cSrcweir }
648cdf0e10cSrcweir
GetExternName(sal_uInt16 nXtiIndex,sal_uInt16 nExtName) const649cdf0e10cSrcweir const XclImpExtName* XclImpLinkManagerImpl::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
650cdf0e10cSrcweir {
651cdf0e10cSrcweir const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
652cdf0e10cSrcweir return pSupbook ? pSupbook->GetExternName( nExtName ) : 0;
653cdf0e10cSrcweir }
654cdf0e10cSrcweir
GetSupbookUrl(sal_uInt16 nXtiIndex) const655cdf0e10cSrcweir const String* XclImpLinkManagerImpl::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
656cdf0e10cSrcweir {
657cdf0e10cSrcweir const XclImpSupbook* p = GetSupbook( nXtiIndex );
658cdf0e10cSrcweir if (!p)
659cdf0e10cSrcweir return NULL;
660cdf0e10cSrcweir return &p->GetXclUrl();
661cdf0e10cSrcweir }
662cdf0e10cSrcweir
GetSupbookTabName(sal_uInt16 nXti,sal_uInt16 nXtiTab) const663cdf0e10cSrcweir const String& XclImpLinkManagerImpl::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
664cdf0e10cSrcweir {
665cdf0e10cSrcweir const XclImpSupbook* p = GetSupbook(nXti);
666cdf0e10cSrcweir return p ? p->GetTabName(nXtiTab) : EMPTY_STRING;
667cdf0e10cSrcweir }
668cdf0e10cSrcweir
GetLinkData(String & rApplic,String & rTopic,sal_uInt16 nXtiIndex) const669cdf0e10cSrcweir bool XclImpLinkManagerImpl::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
670cdf0e10cSrcweir {
671cdf0e10cSrcweir const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
672cdf0e10cSrcweir return pSupbook && pSupbook->GetLinkData( rApplic, rTopic );
673cdf0e10cSrcweir }
674cdf0e10cSrcweir
GetMacroName(sal_uInt16 nExtSheet,sal_uInt16 nExtName) const675cdf0e10cSrcweir const String& XclImpLinkManagerImpl::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
676cdf0e10cSrcweir {
677cdf0e10cSrcweir const XclImpSupbook* pSupbook = GetSupbook( nExtSheet );
678cdf0e10cSrcweir return pSupbook ? pSupbook->GetMacroName( nExtName ) : EMPTY_STRING;
679cdf0e10cSrcweir }
680cdf0e10cSrcweir
GetXti(sal_uInt16 nXtiIndex) const681cdf0e10cSrcweir const XclImpXti* XclImpLinkManagerImpl::GetXti( sal_uInt16 nXtiIndex ) const
682cdf0e10cSrcweir {
683cdf0e10cSrcweir return (nXtiIndex < maXtiList.size()) ? &maXtiList[ nXtiIndex ] : 0;
684cdf0e10cSrcweir }
685cdf0e10cSrcweir
GetSupbook(sal_uInt16 nXtiIndex) const686cdf0e10cSrcweir const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt16 nXtiIndex ) const
687cdf0e10cSrcweir {
688cdf0e10cSrcweir const XclImpXti* pXti = GetXti( nXtiIndex );
689cdf0e10cSrcweir return pXti ? maSupbookList.GetObject( pXti->mnSupbook ) : 0;
690cdf0e10cSrcweir }
691cdf0e10cSrcweir
692cdf0e10cSrcweir //UNUSED2009-05 const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( const String& rUrl ) const
693cdf0e10cSrcweir //UNUSED2009-05 {
694cdf0e10cSrcweir //UNUSED2009-05 for( const XclImpSupbook* pSupbook = maSupbookList.First(); pSupbook; pSupbook = maSupbookList.Next() )
695cdf0e10cSrcweir //UNUSED2009-05 if( pSupbook->GetXclUrl() == rUrl )
696cdf0e10cSrcweir //UNUSED2009-05 return pSupbook;
697cdf0e10cSrcweir //UNUSED2009-05 return 0;
698cdf0e10cSrcweir //UNUSED2009-05 }
699cdf0e10cSrcweir
LoadCachedValues()700cdf0e10cSrcweir void XclImpLinkManagerImpl::LoadCachedValues()
701cdf0e10cSrcweir {
702cdf0e10cSrcweir // Read all CRN records which can be accessed via XclImpSupbook, and store
703cdf0e10cSrcweir // the cached values to the external reference manager.
704cdf0e10cSrcweir
705cdf0e10cSrcweir sal_uInt32 nCount = maSupbookList.Count();
706cdf0e10cSrcweir for (sal_uInt16 nSupbook = 0; nSupbook < nCount; ++nSupbook)
707cdf0e10cSrcweir {
708cdf0e10cSrcweir XclImpSupbook* pSupbook = maSupbookList.GetObject(nSupbook);
709cdf0e10cSrcweir pSupbook->LoadCachedValues();
710cdf0e10cSrcweir }
711cdf0e10cSrcweir }
712cdf0e10cSrcweir
713cdf0e10cSrcweir //UNUSED2009-05 bool XclImpLinkManagerImpl::FindNextTabRange(
714cdf0e10cSrcweir //UNUSED2009-05 sal_uInt16& rnSBTabFirst, sal_uInt16& rnSBTabLast,
715cdf0e10cSrcweir //UNUSED2009-05 sal_uInt16 nSupbook, sal_uInt16 nSBTabStart ) const
716cdf0e10cSrcweir //UNUSED2009-05 {
717cdf0e10cSrcweir //UNUSED2009-05 rnSBTabFirst = rnSBTabLast = EXC_NOTAB;
718cdf0e10cSrcweir //UNUSED2009-05 for( const XclImpXti* pXti = maXtiList.First(); pXti; pXti = maXtiList.Next() )
719cdf0e10cSrcweir //UNUSED2009-05 {
720cdf0e10cSrcweir //UNUSED2009-05 if( (nSupbook == pXti->mnSupbook) && (nSBTabStart <= pXti->mnSBTabLast) && (pXti->mnSBTabFirst < rnSBTabFirst) )
721cdf0e10cSrcweir //UNUSED2009-05 {
722cdf0e10cSrcweir //UNUSED2009-05 rnSBTabFirst = ::std::max( nSBTabStart, pXti->mnSBTabFirst );
723cdf0e10cSrcweir //UNUSED2009-05 rnSBTabLast = pXti->mnSBTabLast;
724cdf0e10cSrcweir //UNUSED2009-05 }
725cdf0e10cSrcweir //UNUSED2009-05 }
726cdf0e10cSrcweir //UNUSED2009-05 return rnSBTabFirst != EXC_NOTAB;
727cdf0e10cSrcweir //UNUSED2009-05 }
728cdf0e10cSrcweir
729cdf0e10cSrcweir // ============================================================================
730cdf0e10cSrcweir
XclImpLinkManager(const XclImpRoot & rRoot)731cdf0e10cSrcweir XclImpLinkManager::XclImpLinkManager( const XclImpRoot& rRoot ) :
732cdf0e10cSrcweir XclImpRoot( rRoot ),
733cdf0e10cSrcweir mxImpl( new XclImpLinkManagerImpl( rRoot ) )
734cdf0e10cSrcweir {
735cdf0e10cSrcweir }
736cdf0e10cSrcweir
~XclImpLinkManager()737cdf0e10cSrcweir XclImpLinkManager::~XclImpLinkManager()
738cdf0e10cSrcweir {
739cdf0e10cSrcweir }
740cdf0e10cSrcweir
ReadExternsheet(XclImpStream & rStrm)741cdf0e10cSrcweir void XclImpLinkManager::ReadExternsheet( XclImpStream& rStrm )
742cdf0e10cSrcweir {
743cdf0e10cSrcweir mxImpl->ReadExternsheet( rStrm );
744cdf0e10cSrcweir }
745cdf0e10cSrcweir
ReadSupbook(XclImpStream & rStrm)746cdf0e10cSrcweir void XclImpLinkManager::ReadSupbook( XclImpStream& rStrm )
747cdf0e10cSrcweir {
748cdf0e10cSrcweir mxImpl->ReadSupbook( rStrm );
749cdf0e10cSrcweir }
750cdf0e10cSrcweir
ReadXct(XclImpStream & rStrm)751cdf0e10cSrcweir void XclImpLinkManager::ReadXct( XclImpStream& rStrm )
752cdf0e10cSrcweir {
753cdf0e10cSrcweir mxImpl->ReadXct( rStrm );
754cdf0e10cSrcweir }
755cdf0e10cSrcweir
ReadCrn(XclImpStream & rStrm)756cdf0e10cSrcweir void XclImpLinkManager::ReadCrn( XclImpStream& rStrm )
757cdf0e10cSrcweir {
758cdf0e10cSrcweir mxImpl->ReadCrn( rStrm );
759cdf0e10cSrcweir }
760cdf0e10cSrcweir
ReadExternname(XclImpStream & rStrm,ExcelToSc * pFormulaConv)761cdf0e10cSrcweir void XclImpLinkManager::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
762cdf0e10cSrcweir {
763cdf0e10cSrcweir mxImpl->ReadExternname( rStrm, pFormulaConv );
764cdf0e10cSrcweir }
765cdf0e10cSrcweir
IsSelfRef(sal_uInt16 nXtiIndex) const766cdf0e10cSrcweir bool XclImpLinkManager::IsSelfRef( sal_uInt16 nXtiIndex ) const
767cdf0e10cSrcweir {
768cdf0e10cSrcweir return mxImpl->IsSelfRef( nXtiIndex );
769cdf0e10cSrcweir }
770cdf0e10cSrcweir
GetScTabRange(SCTAB & rnFirstScTab,SCTAB & rnLastScTab,sal_uInt16 nXtiIndex) const771cdf0e10cSrcweir bool XclImpLinkManager::GetScTabRange(
772cdf0e10cSrcweir SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
773cdf0e10cSrcweir {
774cdf0e10cSrcweir return mxImpl->GetScTabRange( rnFirstScTab, rnLastScTab, nXtiIndex );
775cdf0e10cSrcweir }
776cdf0e10cSrcweir
GetExternName(sal_uInt16 nXtiIndex,sal_uInt16 nExtName) const777cdf0e10cSrcweir const XclImpExtName* XclImpLinkManager::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
778cdf0e10cSrcweir {
779cdf0e10cSrcweir return mxImpl->GetExternName( nXtiIndex, nExtName );
780cdf0e10cSrcweir }
781cdf0e10cSrcweir
GetSupbookUrl(sal_uInt16 nXtiIndex) const782cdf0e10cSrcweir const String* XclImpLinkManager::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
783cdf0e10cSrcweir {
784cdf0e10cSrcweir return mxImpl->GetSupbookUrl(nXtiIndex);
785cdf0e10cSrcweir }
786cdf0e10cSrcweir
GetSupbookTabName(sal_uInt16 nXti,sal_uInt16 nXtiTab) const787cdf0e10cSrcweir const String& XclImpLinkManager::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
788cdf0e10cSrcweir {
789cdf0e10cSrcweir return mxImpl->GetSupbookTabName(nXti, nXtiTab);
790cdf0e10cSrcweir }
791cdf0e10cSrcweir
GetLinkData(String & rApplic,String & rTopic,sal_uInt16 nXtiIndex) const792cdf0e10cSrcweir bool XclImpLinkManager::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
793cdf0e10cSrcweir {
794cdf0e10cSrcweir return mxImpl->GetLinkData( rApplic, rTopic, nXtiIndex );
795cdf0e10cSrcweir }
796cdf0e10cSrcweir
GetMacroName(sal_uInt16 nExtSheet,sal_uInt16 nExtName) const797cdf0e10cSrcweir const String& XclImpLinkManager::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
798cdf0e10cSrcweir {
799cdf0e10cSrcweir return mxImpl->GetMacroName( nExtSheet, nExtName );
800cdf0e10cSrcweir }
801cdf0e10cSrcweir
802cdf0e10cSrcweir // ============================================================================
803cdf0e10cSrcweir
804