Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "xilink.hxx"
30 : : #include "document.hxx"
31 : : #include "cell.hxx"
32 : : #include "scextopt.hxx"
33 : : #include "tablink.hxx"
34 : : #include "xistream.hxx"
35 : : #include "xihelper.hxx"
36 : : #include "xiname.hxx"
37 : : #include "excform.hxx"
38 : : #include "tokenarray.hxx"
39 : : #include "externalrefmgr.hxx"
40 : :
41 : : #include <vector>
42 : : #include <boost/ptr_container/ptr_vector.hpp>
43 : :
44 : : using ::std::vector;
45 : : using ::rtl::OUString;
46 : : using ::rtl::OUStringBuffer;
47 : :
48 : :
49 : : // ============================================================================
50 : : // *** Helper classes ***
51 : : // ============================================================================
52 : :
53 : : // Cached external cells ======================================================
54 : :
55 : : /**
56 : : * Contains the address and value of an external referenced cell.
57 : : * Note that this is non-copyable, so cannot be used in most stl/boost containers.
58 : : */
59 [ # # ]: 0 : class XclImpCrn : public XclImpCachedValue
60 : : {
61 : : public:
62 : : /** Reads a cached value and stores it with its cell address. */
63 : : explicit XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
64 : :
65 : : const XclAddress& GetAddress() const;
66 : :
67 : : private:
68 : : XclAddress maXclPos; /// Excel position of the cached cell.
69 : : };
70 : :
71 : : // Sheet in an external document ==============================================
72 : :
73 : : /** Contains the name and sheet index of one sheet in an external document. */
74 : : class XclImpSupbookTab
75 : : {
76 : : public:
77 : : /** Stores the sheet name and marks the sheet index as invalid.
78 : : The sheet index is set while creating the Calc sheet with CreateTable(). */
79 : : explicit XclImpSupbookTab( const String& rTabName );
80 : : ~XclImpSupbookTab();
81 : :
82 : 0 : inline const String& GetTabName() const { return maTabName; }
83 : :
84 : : /** Reads a CRN record (external referenced cell) at the specified address. */
85 : : void ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
86 : :
87 : : void LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable);
88 : :
89 : : private:
90 : : typedef boost::shared_ptr< XclImpCrn > XclImpCrnRef;
91 : : typedef std::vector< XclImpCrnRef > XclImpCrnList;
92 : :
93 : : XclImpCrnList maCrnList; /// List of CRN records (cached cell values).
94 : : String maTabName; /// Name of the external sheet.
95 : : SCTAB mnScTab; /// New sheet index in Calc document.
96 : : };
97 : :
98 : : // External document (SUPBOOK) ================================================
99 : :
100 : : /** This class represents an external linked document (record SUPBOOK).
101 : : @descr Contains a list of all referenced sheets in the document. */
102 [ + - ][ + - ]: 50 : class XclImpSupbook : protected XclImpRoot
[ + - ][ + - ]
[ + - ][ - + ]
103 : : {
104 : : public:
105 : : /** Reads the SUPBOOK record from stream. */
106 : : explicit XclImpSupbook( XclImpStream& rStrm );
107 : :
108 : : /** Reads an XCT record (count of following CRNs and current sheet). */
109 : : void ReadXct( XclImpStream& rStrm );
110 : : /** Reads a CRN record (external referenced cell). */
111 : : void ReadCrn( XclImpStream& rStrm );
112 : : /** Reads an EXTERNNAME record. */
113 : : void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
114 : :
115 : : /** Returns the SUPBOOK record type. */
116 : 2763 : inline XclSupbookType GetType() const { return meType; }
117 : :
118 : : /** Returns the URL of the external document. */
119 : 0 : inline const String& GetXclUrl() const { return maXclUrl; }
120 : :
121 : : /** Returns the external name specified by an index from the Excel document (one-based). */
122 : : const XclImpExtName* GetExternName( sal_uInt16 nXclIndex ) const;
123 : : /** Tries to decode the URL to OLE or DDE link components.
124 : : @descr For DDE links: Decodes to application name and topic.
125 : : For OLE object links: Decodes to class name and document URL.
126 : : @return true = decoding was successful, returned strings are valid (not empty). */
127 : : bool GetLinkData( String& rApplic, String& rDoc ) const;
128 : : /** Returns the specified macro name (1-based) or an empty string on error. */
129 : : const String& GetMacroName( sal_uInt16 nXclNameIdx ) const;
130 : :
131 : : const String& GetTabName( sal_uInt16 nXtiTab ) const;
132 : :
133 : : sal_uInt16 GetTabCount() const;
134 : :
135 : : void LoadCachedValues();
136 : :
137 : : private:
138 : : typedef boost::ptr_vector< XclImpSupbookTab > XclImpSupbookTabList;
139 : : typedef boost::ptr_vector< XclImpExtName > XclImpExtNameList;
140 : :
141 : : XclImpSupbookTabList maSupbTabList; /// All sheet names of the document.
142 : : XclImpExtNameList maExtNameList; /// All external names of the document.
143 : : String maXclUrl; /// URL of the external document (Excel mode).
144 : : String maFilterName; /// Detected filer name.
145 : : String maFilterOpt; /// Detected filer options.
146 : : XclSupbookType meType; /// Type of the supbook record.
147 : : sal_uInt16 mnSBTab; /// Current Excel sheet index from SUPBOOK for XCT/CRN records.
148 : : };
149 : :
150 : : // Import link manager ========================================================
151 : :
152 : : /** Contains the SUPBOOK index and sheet indexes of an external link.
153 : : @descr It is possible to enter a formula like =SUM(Sheet1:Sheet3!A1),
154 : : therefore here occurs a sheet range. */
155 : : struct XclImpXti
156 : : {
157 : : sal_uInt16 mnSupbook; /// Index to SUPBOOK record.
158 : : sal_uInt16 mnSBTabFirst; /// Index to the first sheet of the range in the SUPBOOK.
159 : : sal_uInt16 mnSBTabLast; /// Index to the last sheet of the range in the SUPBOOK.
160 : 61 : inline explicit XclImpXti() : mnSupbook( SAL_MAX_UINT16 ), mnSBTabFirst( SAL_MAX_UINT16 ), mnSBTabLast( SAL_MAX_UINT16 ) {}
161 : : };
162 : :
163 : 61 : inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpXti& rXti )
164 : : {
165 : 61 : return rStrm >> rXti.mnSupbook >> rXti.mnSBTabFirst >> rXti.mnSBTabLast;
166 : : }
167 : :
168 : : // ----------------------------------------------------------------------------
169 : :
170 : : /** Implementation of the link manager. */
171 [ + - ][ - + ]: 110 : class XclImpLinkManagerImpl : protected XclImpRoot
172 : : {
173 : : public:
174 : : explicit XclImpLinkManagerImpl( const XclImpRoot& rRoot );
175 : :
176 : : /** Reads the EXTERNSHEET record. */
177 : : void ReadExternsheet( XclImpStream& rStrm );
178 : : /** Reads a SUPBOOK record. */
179 : : void ReadSupbook( XclImpStream& rStrm );
180 : : /** Reads an XCT record and appends it to the current SUPBOOK. */
181 : : void ReadXct( XclImpStream& rStrm );
182 : : /** Reads a CRN record and appends it to the current SUPBOOK. */
183 : : void ReadCrn( XclImpStream& rStrm );
184 : : /** Reads an EXTERNNAME record and appends it to the current SUPBOOK. */
185 : : void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
186 : :
187 : : /** Returns true, if the specified XTI entry contains an internal reference. */
188 : : bool IsSelfRef( sal_uInt16 nXtiIndex ) const;
189 : : /** Returns the Calc sheet index range of the specified XTI entry.
190 : : @return true = XTI data found, returned sheet index range is valid. */
191 : : bool GetScTabRange(
192 : : SCTAB& rnFirstScTab, SCTAB& rnLastScTab,
193 : : sal_uInt16 nXtiIndex ) const;
194 : : /** Returns the specified external name or 0 on error. */
195 : : const XclImpExtName* GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const;
196 : :
197 : : /** Returns the absolute file URL of a supporting workbook specified by
198 : : the index. */
199 : : const String* GetSupbookUrl( sal_uInt16 nXtiIndex ) const;
200 : :
201 : : const String& GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const;
202 : :
203 : : /** Tries to decode the URL of the specified XTI entry to OLE or DDE link components.
204 : : @descr For DDE links: Decodes to application name and topic.
205 : : For OLE object links: Decodes to class name and document URL.
206 : : @return true = decoding was successful, returned strings are valid (not empty). */
207 : : bool GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const;
208 : : /** Returns the specified macro name or an empty string on error. */
209 : : const String& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const;
210 : :
211 : : private:
212 : : /** Returns the specified XTI (link entry from BIFF8 EXTERNSHEET record). */
213 : : const XclImpXti* GetXti( sal_uInt16 nXtiIndex ) const;
214 : : /** Returns the specified SUPBOOK (external document). */
215 : : const XclImpSupbook* GetSupbook( sal_uInt16 nXtiIndex ) const;
216 : :
217 : : void LoadCachedValues();
218 : :
219 : : private:
220 : : typedef ::std::vector< XclImpXti > XclImpXtiVector;
221 : : typedef boost::ptr_vector< XclImpSupbook > XclImpSupbookList;
222 : :
223 : : XclImpXtiVector maXtiList; /// List of all XTI structures.
224 : : XclImpSupbookList maSupbookList; /// List of external documents.
225 : : bool mbCreated; /// true = Calc sheets already created.
226 : : };
227 : :
228 : : // ============================================================================
229 : : // *** Implementation ***
230 : : // ============================================================================
231 : :
232 : : // Excel sheet indexes ========================================================
233 : :
234 : : // original Excel sheet names -------------------------------------------------
235 : :
236 : 165 : void XclImpTabInfo::AppendXclTabName( const String& rXclTabName, SCTAB nScTab )
237 : : {
238 : 165 : maTabNames[ rXclTabName ] = nScTab;
239 : 165 : }
240 : :
241 : 0 : void XclImpTabInfo::InsertScTab( SCTAB nScTab )
242 : : {
243 [ # # ][ # # ]: 0 : for( XclTabNameMap::iterator aIt = maTabNames.begin(), aEnd = maTabNames.end(); aIt != aEnd; ++aIt )
[ # # ]
244 [ # # ][ # # ]: 0 : if( aIt->second >= nScTab )
245 [ # # ]: 0 : ++aIt->second;
246 : 0 : }
247 : :
248 : 3 : SCTAB XclImpTabInfo::GetScTabFromXclName( const String& rXclTabName ) const
249 : : {
250 [ + - ]: 3 : XclTabNameMap::const_iterator aIt = maTabNames.find( rXclTabName );
251 [ + - ][ + - ]: 3 : return (aIt != maTabNames.end()) ? aIt->second : SCTAB_INVALID;
[ + - ]
252 : : }
253 : :
254 : : // record creation order - TABID record ---------------------------------------
255 : :
256 : 46 : void XclImpTabInfo::ReadTabid( XclImpStream& rStrm )
257 : : {
258 : : OSL_ENSURE_BIFF( rStrm.GetRoot().GetBiff() == EXC_BIFF8 );
259 [ + - ]: 46 : if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
260 : : {
261 : 46 : rStrm.EnableDecryption();
262 : 46 : sal_Size nReadCount = rStrm.GetRecLeft() / 2;
263 : : OSL_ENSURE( nReadCount <= 0xFFFF, "XclImpTabInfo::ReadTabid - record too long" );
264 : 46 : maTabIdVec.clear();
265 : 46 : maTabIdVec.reserve( nReadCount );
266 [ + - ][ + + ]: 208 : for( sal_Size nIndex = 0; rStrm.IsValid() && (nIndex < nReadCount); ++nIndex )
[ + + ]
267 : : // zero index is not allowed in BIFF8, but it seems that it occurs in real life
268 [ + - ]: 162 : maTabIdVec.push_back( rStrm.ReaduInt16() );
269 : : }
270 : 46 : }
271 : :
272 : 0 : sal_uInt16 XclImpTabInfo::GetCurrentIndex( sal_uInt16 nCreatedId, sal_uInt16 nMaxTabId ) const
273 : : {
274 : 0 : sal_uInt16 nReturn = 0;
275 [ # # ][ # # ]: 0 : for( ScfUInt16Vec::const_iterator aIt = maTabIdVec.begin(), aEnd = maTabIdVec.end(); aIt != aEnd; ++aIt )
[ # # ]
276 : : {
277 [ # # ]: 0 : sal_uInt16 nValue = *aIt;
278 [ # # ]: 0 : if( nValue == nCreatedId )
279 : 0 : return nReturn;
280 [ # # ]: 0 : if( nValue <= nMaxTabId )
281 : 0 : ++nReturn;
282 : : }
283 : 0 : return 0;
284 : : }
285 : :
286 : : // External names =============================================================
287 : :
288 : 0 : XclImpExtName::MOper::MOper(XclImpStream& rStrm) :
289 [ # # ]: 0 : mxCached(new ScMatrix(0,0))
290 : : {
291 [ # # ]: 0 : SCSIZE nLastCol = rStrm.ReaduInt8();
292 [ # # ]: 0 : SCSIZE nLastRow = rStrm.ReaduInt16();
293 [ # # ]: 0 : mxCached->Resize(nLastCol+1, nLastRow+1);
294 [ # # ]: 0 : for (SCSIZE nRow = 0; nRow <= nLastRow; ++nRow)
295 : : {
296 [ # # ]: 0 : for (SCSIZE nCol = 0; nCol <= nLastCol; ++nCol)
297 : : {
298 : : sal_uInt8 nOp;
299 [ # # ]: 0 : rStrm >> nOp;
300 [ # # # # : 0 : switch (nOp)
# ]
301 : : {
302 : : case 0x01:
303 : : {
304 [ # # ]: 0 : double fVal = rStrm.ReadDouble();
305 [ # # ]: 0 : mxCached->PutDouble(fVal, nCol, nRow);
306 : : }
307 : 0 : break;
308 : : case 0x02:
309 : : {
310 [ # # ][ # # ]: 0 : OUString aStr = rStrm.ReadUniString();
[ # # ]
311 [ # # ]: 0 : mxCached->PutString(aStr, nCol, nRow);
312 : : }
313 : 0 : break;
314 : : case 0x04:
315 : : {
316 [ # # ]: 0 : bool bVal = rStrm.ReaduInt8();
317 [ # # ]: 0 : mxCached->PutBoolean(bVal, nCol, nRow);
318 [ # # ]: 0 : rStrm.Ignore(7);
319 : : }
320 : 0 : break;
321 : : case 0x10:
322 : : {
323 [ # # ]: 0 : sal_uInt8 nErr = rStrm.ReaduInt8();
324 : : // TODO: Map the error code from xls to calc.
325 [ # # ]: 0 : mxCached->PutError(nErr, nCol, nRow);
326 [ # # ]: 0 : rStrm.Ignore(7);
327 : : }
328 : 0 : break;
329 : : default:
330 [ # # ]: 0 : rStrm.Ignore(8);
331 : : }
332 : : }
333 : : }
334 : 0 : }
335 : :
336 : 0 : const ScMatrix& XclImpExtName::MOper::GetCache() const
337 : : {
338 : 0 : return *mxCached;
339 : : }
340 : :
341 : 0 : XclImpExtName::XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm, XclSupbookType eSubType, ExcelToSc* pFormulaConv ) :
342 [ # # ]: 0 : mpMOper(NULL)
343 : : {
344 : : sal_uInt16 nFlags;
345 : : sal_uInt8 nLen;
346 : :
347 [ # # ][ # # ]: 0 : rStrm >> nFlags >> mnStorageId >> nLen ;
[ # # ]
348 [ # # ][ # # ]: 0 : maName = rStrm.ReadUniString( nLen );
[ # # ]
349 [ # # ][ # # ]: 0 : if( ::get_flag( nFlags, EXC_EXTN_BUILTIN ) || !::get_flag( nFlags, EXC_EXTN_OLE_OR_DDE ) )
[ # # ]
350 : : {
351 [ # # ]: 0 : if( eSubType == EXC_SBTYPE_ADDIN )
352 : : {
353 : 0 : meType = xlExtAddIn;
354 [ # # ][ # # ]: 0 : maName = rStrm.GetRoot().GetScAddInName( maName );
[ # # ]
355 : : }
356 [ # # ][ # # ]: 0 : else if ( (eSubType == EXC_SBTYPE_EUROTOOL) &&
[ # # ]
357 [ # # ]: 0 : maName.EqualsIgnoreCaseAscii( "EUROCONVERT" ) )
358 : 0 : meType = xlExtEuroConvert;
359 : : else
360 : : {
361 : 0 : meType = xlExtName;
362 [ # # ]: 0 : ScfTools::ConvertToScDefinedName( maName );
363 : : }
364 : : }
365 : : else
366 : : {
367 : 0 : meType = ::get_flagvalue( nFlags, EXC_EXTN_OLE, xlExtOLE, xlExtDDE );
368 : : }
369 : :
370 [ # # # # ]: 0 : switch (meType)
371 : : {
372 : : case xlExtDDE:
373 [ # # ][ # # ]: 0 : if (rStrm.GetRecLeft() > 1)
374 [ # # ][ # # ]: 0 : mxDdeMatrix.reset(new XclImpCachedMatrix(rStrm));
375 : 0 : break;
376 : : case xlExtName:
377 : : // TODO: For now, only global external names are supported. In future
378 : : // we should extend this to supporting per-sheet external names.
379 [ # # ]: 0 : if (mnStorageId == 0)
380 : : {
381 [ # # ]: 0 : if (pFormulaConv)
382 : : {
383 : 0 : const ScTokenArray* pArray = NULL;
384 : : sal_uInt16 nFmlaLen;
385 [ # # ]: 0 : rStrm >> nFmlaLen;
386 [ # # ]: 0 : vector<String> aTabNames;
387 [ # # ]: 0 : sal_uInt16 nCount = rSupbook.GetTabCount();
388 [ # # ]: 0 : aTabNames.reserve(nCount);
389 [ # # ]: 0 : for (sal_uInt16 i = 0; i < nCount; ++i)
390 [ # # ][ # # ]: 0 : aTabNames.push_back(rSupbook.GetTabName(i));
391 : :
392 [ # # ]: 0 : pFormulaConv->ConvertExternName(pArray, rStrm, nFmlaLen, rSupbook.GetXclUrl(), aTabNames);
393 [ # # ]: 0 : if (pArray)
394 [ # # ]: 0 : mxArray.reset(pArray->Clone());
395 : : }
396 : : }
397 : 0 : break;
398 : : case xlExtOLE:
399 [ # # ][ # # ]: 0 : mpMOper = new MOper(rStrm);
400 : 0 : break;
401 : : default:
402 : : ;
403 : : }
404 : 0 : }
405 : :
406 [ # # ][ # # ]: 0 : XclImpExtName::~XclImpExtName()
407 : : {
408 [ # # ][ # # ]: 0 : delete mpMOper;
409 : 0 : }
410 : :
411 : 0 : void XclImpExtName::CreateDdeData( ScDocument& rDoc, const String& rApplic, const String& rTopic ) const
412 : : {
413 : 0 : ScMatrixRef xResults;
414 [ # # ]: 0 : if( mxDdeMatrix.get() )
415 [ # # ][ # # ]: 0 : xResults = mxDdeMatrix->CreateScMatrix();
[ # # ]
416 [ # # ][ # # ]: 0 : rDoc.CreateDdeLink( rApplic, rTopic, maName, SC_DDE_DEFAULT, xResults );
[ # # ][ # # ]
[ # # ][ # # ]
417 : 0 : }
418 : :
419 : 0 : void XclImpExtName::CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) const
420 : : {
421 [ # # ]: 0 : if (!mxArray.get())
422 : 0 : return;
423 : :
424 : 0 : ScExternalRefManager* pRefMgr = rDoc.GetExternalRefManager();
425 [ # # ]: 0 : pRefMgr->storeRangeNameTokens(nFileId, maName, *mxArray);
426 : : }
427 : :
428 : : namespace {
429 : :
430 : : /**
431 : : * Decompose the name into sheet name and range name. An OLE link name is
432 : : * always formatted like this [ !Sheet1!R1C1:R5C2 ] and it always uses R1C1
433 : : * notation.
434 : : */
435 : 0 : bool extractSheetAndRange(const OUString& rName, OUString& rSheet, OUString& rRange)
436 : : {
437 : 0 : sal_Int32 n = rName.getLength();
438 : 0 : const sal_Unicode* p = rName.getStr();
439 : 0 : OUStringBuffer aBuf;
440 : 0 : bool bInSheet = true;
441 [ # # ]: 0 : for (sal_Int32 i = 0; i < n; ++i, ++p)
442 : : {
443 [ # # ]: 0 : if (i == 0)
444 : : {
445 : : // first character must be '!'.
446 [ # # ]: 0 : if (*p != '!')
447 : 0 : return false;
448 : 0 : continue;
449 : : }
450 : :
451 [ # # ]: 0 : if (*p == '!')
452 : : {
453 : : // sheet name to range separator.
454 [ # # ]: 0 : if (!bInSheet)
455 : 0 : return false;
456 [ # # ]: 0 : rSheet = aBuf.makeStringAndClear();
457 : 0 : bInSheet = false;
458 : 0 : continue;
459 : : }
460 : :
461 [ # # ]: 0 : aBuf.append(*p);
462 : : }
463 : :
464 [ # # ]: 0 : rRange = aBuf.makeStringAndClear();
465 : 0 : return true;
466 : : }
467 : :
468 : : }
469 : :
470 : 0 : bool XclImpExtName::CreateOleData(ScDocument& rDoc, const OUString& rUrl,
471 : : sal_uInt16& rFileId, OUString& rTabName, ScRange& rRange) const
472 : : {
473 [ # # ]: 0 : if (!mpMOper)
474 : 0 : return false;
475 : :
476 : 0 : OUString aSheet, aRangeStr;
477 [ # # ][ # # ]: 0 : if (!extractSheetAndRange(maName, aSheet, aRangeStr))
[ # # ]
478 : 0 : return false;
479 : :
480 : 0 : ScRange aRange;
481 [ # # ][ # # ]: 0 : sal_uInt16 nRes = aRange.ParseAny(aRangeStr, &rDoc, formula::FormulaGrammar::CONV_XL_R1C1);
[ # # ]
482 [ # # ]: 0 : if ((nRes & SCA_VALID) != SCA_VALID)
483 : 0 : return false;
484 : :
485 [ # # ]: 0 : if (aRange.aStart.Tab() != aRange.aEnd.Tab())
486 : : // We don't support multi-sheet range for this.
487 : 0 : return false;
488 : :
489 [ # # ]: 0 : const ScMatrix& rCache = mpMOper->GetCache();
490 : : SCSIZE nC, nR;
491 [ # # ]: 0 : rCache.GetDimensions(nC, nR);
492 [ # # ][ # # ]: 0 : if (!nC || !nR)
493 : : // cache matrix is empty.
494 : 0 : return false;
495 : :
496 [ # # ]: 0 : ScExternalRefManager* pRefMgr = rDoc.GetExternalRefManager();
497 [ # # ]: 0 : sal_uInt16 nFileId = pRefMgr->getExternalFileId(rUrl);
498 [ # # ]: 0 : ScExternalRefCache::TableTypeRef xTab = pRefMgr->getCacheTable(nFileId, aSheet, true, NULL);
499 [ # # ]: 0 : if (!xTab)
500 : : // cache table creation failed.
501 : 0 : return false;
502 : :
503 [ # # ]: 0 : xTab->setWholeTableCached();
504 [ # # ]: 0 : for (SCSIZE i = 0; i < nR; ++i)
505 : : {
506 [ # # ]: 0 : for (SCSIZE j = 0; j < nC; ++j)
507 : : {
508 : 0 : SCCOL nCol = aRange.aStart.Col() + j;
509 : 0 : SCROW nRow = aRange.aStart.Row() + i;
510 : :
511 [ # # ]: 0 : ScMatrixValue aVal = rCache.Get(j, i);
512 [ # # # # ]: 0 : switch (aVal.nType)
513 : : {
514 : : case SC_MATVAL_BOOLEAN:
515 : : {
516 : 0 : bool b = aVal.GetBoolean();
517 [ # # ][ # # ]: 0 : ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(b ? 1.0 : 0.0));
[ # # ]
518 [ # # ][ # # ]: 0 : xTab->setCell(nCol, nRow, pToken, 0, false);
[ # # ]
519 : : }
520 : 0 : break;
521 : : case SC_MATVAL_VALUE:
522 : : {
523 [ # # ][ # # ]: 0 : ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(aVal.fVal));
524 [ # # ][ # # ]: 0 : xTab->setCell(nCol, nRow, pToken, 0, false);
[ # # ]
525 : : }
526 : 0 : break;
527 : : case SC_MATVAL_STRING:
528 : : {
529 [ # # ]: 0 : const String& rStr = aVal.GetString();
530 [ # # ][ # # ]: 0 : ScExternalRefCache::TokenRef pToken(new formula::FormulaStringToken(rStr));
531 [ # # ][ # # ]: 0 : xTab->setCell(nCol, nRow, pToken, 0, false);
[ # # ][ # # ]
532 : : }
533 : 0 : break;
534 : : default:
535 : : ;
536 : : }
537 : 0 : }
538 : : }
539 : :
540 : 0 : rFileId = nFileId;
541 : 0 : rTabName = aSheet;
542 : 0 : rRange = aRange;
543 [ # # ]: 0 : return true;
544 : : }
545 : :
546 : 0 : bool XclImpExtName::HasFormulaTokens() const
547 : : {
548 : 0 : return (mxArray.get() != NULL);
549 : : }
550 : :
551 : : // Cached external cells ======================================================
552 : :
553 : 0 : XclImpCrn::XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos ) :
554 : : XclImpCachedValue( rStrm ),
555 : 0 : maXclPos( rXclPos )
556 : : {
557 : 0 : }
558 : :
559 : 0 : const XclAddress& XclImpCrn::GetAddress() const
560 : : {
561 : 0 : return maXclPos;
562 : : }
563 : :
564 : : // Sheet in an external document ==============================================
565 : :
566 : 0 : XclImpSupbookTab::XclImpSupbookTab( const String& rTabName ) :
567 : : maTabName( rTabName ),
568 [ # # ]: 0 : mnScTab( SCTAB_INVALID )
569 : : {
570 : 0 : }
571 : :
572 [ # # ]: 0 : XclImpSupbookTab::~XclImpSupbookTab()
573 : : {
574 : 0 : }
575 : :
576 : 0 : void XclImpSupbookTab::ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos )
577 : : {
578 [ # # ][ # # ]: 0 : XclImpCrnRef crnRef( new XclImpCrn(rStrm, rXclPos) );
[ # # ]
579 [ # # ][ # # ]: 0 : maCrnList.push_back( crnRef );
580 : 0 : }
581 : :
582 : 0 : void XclImpSupbookTab::LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable)
583 : : {
584 [ # # ]: 0 : if (maCrnList.empty())
585 : 0 : return;
586 : :
587 [ # # ][ # # ]: 0 : for (XclImpCrnList::iterator itCrnRef = maCrnList.begin(); itCrnRef != maCrnList.end(); ++itCrnRef)
588 : : {
589 : 0 : const XclImpCrn* const pCrn = itCrnRef->get();
590 : 0 : const XclAddress& rAddr = pCrn->GetAddress();
591 [ # # # # : 0 : switch (pCrn->GetType())
# ]
592 : : {
593 : : case EXC_CACHEDVAL_BOOL:
594 : : {
595 : 0 : bool b = pCrn->GetBool();
596 [ # # ][ # # ]: 0 : ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(b ? 1.0 : 0.0));
[ # # ]
597 [ # # ][ # # ]: 0 : pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
[ # # ]
598 : : }
599 : 0 : break;
600 : : case EXC_CACHEDVAL_DOUBLE:
601 : : {
602 : 0 : double f = pCrn->GetValue();
603 [ # # ][ # # ]: 0 : ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(f));
604 [ # # ][ # # ]: 0 : pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
[ # # ]
605 : : }
606 : 0 : break;
607 : : case EXC_CACHEDVAL_ERROR:
608 : : {
609 [ # # ]: 0 : double fError = XclTools::ErrorToDouble( pCrn->GetXclError() );
610 [ # # ][ # # ]: 0 : ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(fError));
611 [ # # ][ # # ]: 0 : pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
[ # # ]
612 : : }
613 : 0 : break;
614 : : case EXC_CACHEDVAL_STRING:
615 : : {
616 [ # # ]: 0 : const String& rStr = pCrn->GetString();
617 [ # # ][ # # ]: 0 : ScExternalRefCache::TokenRef pToken(new formula::FormulaStringToken(rStr));
618 [ # # ][ # # ]: 0 : pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
[ # # ]
619 : : }
620 : 0 : break;
621 : : default:
622 : : ;
623 : : }
624 : : }
625 : : }
626 : :
627 : : // External document (SUPBOOK) ================================================
628 : :
629 : 25 : XclImpSupbook::XclImpSupbook( XclImpStream& rStrm ) :
630 : 25 : XclImpRoot( rStrm.GetRoot() ),
631 : : meType( EXC_SBTYPE_UNKNOWN ),
632 [ + - ][ + - ]: 25 : mnSBTab( EXC_TAB_DELETED )
[ + - ][ + - ]
[ + - ]
633 : : {
634 : : sal_uInt16 nSBTabCnt;
635 [ + - ]: 25 : rStrm >> nSBTabCnt;
636 : :
637 [ + - ][ + - ]: 25 : if( rStrm.GetRecLeft() == 2 )
638 : : {
639 [ + - ]: 25 : switch( rStrm.ReaduInt16() )
[ + - - ]
640 : : {
641 : 25 : case EXC_SUPB_SELF: meType = EXC_SBTYPE_SELF; break;
642 : 25 : case EXC_SUPB_ADDIN: meType = EXC_SBTYPE_ADDIN; break;
643 : : default: OSL_FAIL( "XclImpSupbook::XclImpSupbook - unknown special SUPBOOK type" );
644 : : }
645 : 25 : return;
646 : : }
647 : :
648 [ # # ]: 0 : String aEncUrl( rStrm.ReadUniString() );
649 : 0 : bool bSelf = false;
650 [ # # ]: 0 : XclImpUrlHelper::DecodeUrl( maXclUrl, bSelf, GetRoot(), aEncUrl );
651 : :
652 [ # # ][ # # ]: 0 : if( maXclUrl.EqualsIgnoreCaseAscii( "\010EUROTOOL.XLA" ) )
653 : : {
654 : 0 : meType = EXC_SBTYPE_EUROTOOL;
655 [ # # ][ # # ]: 0 : maSupbTabList.push_back( new XclImpSupbookTab( maXclUrl ) );
[ # # ]
656 : : }
657 [ # # ]: 0 : else if( nSBTabCnt )
658 : : {
659 : 0 : meType = EXC_SBTYPE_EXTERN;
660 [ # # ]: 0 : for( sal_uInt16 nSBTab = 0; nSBTab < nSBTabCnt; ++nSBTab )
661 : : {
662 [ # # ]: 0 : String aTabName( rStrm.ReadUniString() );
663 [ # # ][ # # ]: 0 : maSupbTabList.push_back( new XclImpSupbookTab( aTabName ) );
[ # # ]
664 [ # # ]: 0 : }
665 : : }
666 : : else
667 : : {
668 : 0 : meType = EXC_SBTYPE_SPECIAL;
669 : : // create dummy list entry
670 [ # # ][ # # ]: 0 : maSupbTabList.push_back( new XclImpSupbookTab( maXclUrl ) );
[ # # ]
671 [ # # ]: 0 : }
672 : : }
673 : :
674 : 0 : void XclImpSupbook::ReadXct( XclImpStream& rStrm )
675 : : {
676 : 0 : rStrm.Ignore( 2 );
677 : 0 : rStrm >> mnSBTab;
678 : 0 : }
679 : :
680 : 0 : void XclImpSupbook::ReadCrn( XclImpStream& rStrm )
681 : : {
682 [ # # ]: 0 : if (mnSBTab >= maSupbTabList.size())
683 : 0 : return;
684 [ # # ]: 0 : XclImpSupbookTab& rSbTab = maSupbTabList[mnSBTab];
685 : : sal_uInt8 nXclColLast, nXclColFirst;
686 : : sal_uInt16 nXclRow;
687 [ # # ][ # # ]: 0 : rStrm >> nXclColLast >> nXclColFirst >> nXclRow;
[ # # ]
688 : :
689 [ # # ][ # # ]: 0 : for( sal_uInt8 nXclCol = nXclColFirst; (nXclCol <= nXclColLast) && (rStrm.GetRecLeft() > 1); ++nXclCol )
[ # # ][ # # ]
690 [ # # ]: 0 : rSbTab.ReadCrn( rStrm, XclAddress( nXclCol, nXclRow ) );
691 : : }
692 : :
693 : 0 : void XclImpSupbook::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
694 : : {
695 [ # # ]: 0 : maExtNameList.push_back( new XclImpExtName( *this, rStrm, meType, pFormulaConv ) );
696 : 0 : }
697 : :
698 : 0 : const XclImpExtName* XclImpSupbook::GetExternName( sal_uInt16 nXclIndex ) const
699 : : {
700 : : OSL_ENSURE( nXclIndex > 0, "XclImpSupbook::GetExternName - index must be >0" );
701 [ # # ][ # # ]: 0 : if (meType == EXC_SBTYPE_SELF || nXclIndex > maExtNameList.size())
[ # # ]
702 : 0 : return NULL;
703 : 0 : return &maExtNameList[nXclIndex-1];
704 : : }
705 : :
706 : 0 : bool XclImpSupbook::GetLinkData( String& rApplic, String& rTopic ) const
707 : : {
708 [ # # ][ # # ]: 0 : return (meType == EXC_SBTYPE_SPECIAL) && XclImpUrlHelper::DecodeLink( rApplic, rTopic, maXclUrl );
[ # # ][ # # ]
[ # # ][ # # ]
709 : : }
710 : :
711 : 0 : const String& XclImpSupbook::GetMacroName( sal_uInt16 nXclNameIdx ) const
712 : : {
713 : : OSL_ENSURE( nXclNameIdx > 0, "XclImpSupbook::GetMacroName - index must be >0" );
714 [ # # ]: 0 : const XclImpName* pName = (meType == EXC_SBTYPE_SELF) ? GetNameManager().GetName( nXclNameIdx ) : 0;
715 [ # # ][ # # ]: 0 : return (pName && pName->IsVBName()) ? pName->GetScName() : EMPTY_STRING;
716 : : }
717 : :
718 : 0 : const String& XclImpSupbook::GetTabName( sal_uInt16 nXtiTab ) const
719 : : {
720 [ # # ]: 0 : if (nXtiTab >= maSupbTabList.size())
721 : 0 : return EMPTY_STRING;
722 : 0 : return maSupbTabList[nXtiTab].GetTabName();
723 : : }
724 : :
725 : 0 : sal_uInt16 XclImpSupbook::GetTabCount() const
726 : : {
727 : 0 : return ulimit_cast<sal_uInt16>(maSupbTabList.size());
728 : : }
729 : :
730 : 25 : void XclImpSupbook::LoadCachedValues()
731 : : {
732 [ - + ][ # # ]: 25 : if (meType != EXC_SBTYPE_EXTERN || GetExtDocOptions().GetDocSettings().mnLinkCnt > 0 || !GetDocShell())
[ # # ][ # # ]
[ # # ][ # # ]
[ - + ]
733 : 25 : return;
734 : :
735 [ # # ][ # # ]: 0 : String aAbsUrl( ScGlobal::GetAbsDocName(maXclUrl, GetDocShell()) );
736 : :
737 [ # # ]: 0 : ScExternalRefManager* pRefMgr = GetRoot().GetDoc().GetExternalRefManager();
738 [ # # ][ # # ]: 0 : sal_uInt16 nFileId = pRefMgr->getExternalFileId(aAbsUrl);
739 : :
740 [ # # ][ # # ]: 0 : for (XclImpSupbookTabList::iterator itTab = maSupbTabList.begin(); itTab != maSupbTabList.end(); ++itTab)
[ # # ][ # # ]
[ # # ]
741 : : {
742 [ # # ]: 0 : const String& rTabName = itTab->GetTabName();
743 [ # # ][ # # ]: 0 : ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
744 [ # # ][ # # ]: 0 : itTab->LoadCachedValues(pCacheTable);
[ # # ][ # # ]
745 [ # # ]: 0 : pCacheTable->setWholeTableCached();
746 [ # # ][ # # ]: 25 : }
747 : : }
748 : :
749 : : // Import link manager ========================================================
750 : :
751 : 55 : XclImpLinkManagerImpl::XclImpLinkManagerImpl( const XclImpRoot& rRoot ) :
752 : : XclImpRoot( rRoot ),
753 [ + - ][ + - ]: 55 : mbCreated( false )
754 : : {
755 : 55 : }
756 : :
757 : 25 : void XclImpLinkManagerImpl::ReadExternsheet( XclImpStream& rStrm )
758 : : {
759 : : sal_uInt16 nXtiCount;
760 [ + - ]: 25 : rStrm >> nXtiCount;
761 : : OSL_ENSURE( static_cast< sal_Size >( nXtiCount * 6 ) == rStrm.GetRecLeft(), "XclImpLinkManagerImpl::ReadExternsheet - invalid count" );
762 [ + - ][ + - ]: 25 : nXtiCount = static_cast< sal_uInt16 >( ::std::min< sal_Size >( nXtiCount, rStrm.GetRecLeft() / 6 ) );
763 : :
764 : : /* #i104057# A weird external XLS generator writes multiple EXTERNSHEET
765 : : records instead of only one as expected. Surprisingly, Excel seems to
766 : : insert the entries of the second record before the entries of the first
767 : : record. */
768 [ + - ]: 25 : XclImpXtiVector aNewEntries( nXtiCount );
769 [ + - ][ + - ]: 86 : for( XclImpXtiVector::iterator aIt = aNewEntries.begin(), aEnd = aNewEntries.end(); rStrm.IsValid() && (aIt != aEnd); ++aIt )
[ + + ][ + + ]
770 [ + - ]: 61 : rStrm >> *aIt;
771 [ + - ]: 25 : maXtiList.insert( maXtiList.begin(), aNewEntries.begin(), aNewEntries.end() );
772 : :
773 [ + - ]: 25 : LoadCachedValues();
774 : 25 : }
775 : :
776 : 25 : void XclImpLinkManagerImpl::ReadSupbook( XclImpStream& rStrm )
777 : : {
778 [ + - ]: 25 : maSupbookList.push_back( new XclImpSupbook( rStrm ) );
779 : 25 : }
780 : :
781 : 0 : void XclImpLinkManagerImpl::ReadXct( XclImpStream& rStrm )
782 : : {
783 [ # # ]: 0 : if( !maSupbookList.empty() )
784 : 0 : maSupbookList.back().ReadXct( rStrm );
785 : 0 : }
786 : :
787 : 0 : void XclImpLinkManagerImpl::ReadCrn( XclImpStream& rStrm )
788 : : {
789 [ # # ]: 0 : if( !maSupbookList.empty() )
790 : 0 : maSupbookList.back().ReadCrn( rStrm );
791 : 0 : }
792 : :
793 : 0 : void XclImpLinkManagerImpl::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
794 : : {
795 [ # # ]: 0 : if( !maSupbookList.empty() )
796 : 0 : maSupbookList.back().ReadExternname( rStrm, pFormulaConv );
797 : 0 : }
798 : :
799 : 2763 : bool XclImpLinkManagerImpl::IsSelfRef( sal_uInt16 nXtiIndex ) const
800 : : {
801 : 2763 : const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
802 [ + - ][ + - ]: 2763 : return pSupbook && (pSupbook->GetType() == EXC_SBTYPE_SELF);
803 : : }
804 : :
805 : 2763 : bool XclImpLinkManagerImpl::GetScTabRange(
806 : : SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
807 : : {
808 [ + - ]: 2763 : if( const XclImpXti* pXti = GetXti( nXtiIndex ) )
809 : : {
810 [ + - ][ + - ]: 2763 : if (!maSupbookList.empty() && (pXti->mnSupbook < maSupbookList.size()) )
[ + - ]
811 : : {
812 : 2763 : rnFirstScTab = pXti->mnSBTabFirst;
813 : 2763 : rnLastScTab = pXti->mnSBTabLast;
814 : 2763 : return true;
815 : : }
816 : : }
817 : 2763 : return false;
818 : : }
819 : :
820 : 0 : const XclImpExtName* XclImpLinkManagerImpl::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
821 : : {
822 : 0 : const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
823 [ # # ]: 0 : return pSupbook ? pSupbook->GetExternName( nExtName ) : 0;
824 : : }
825 : :
826 : 0 : const String* XclImpLinkManagerImpl::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
827 : : {
828 : 0 : const XclImpSupbook* p = GetSupbook( nXtiIndex );
829 [ # # ]: 0 : if (!p)
830 : 0 : return NULL;
831 : 0 : return &p->GetXclUrl();
832 : : }
833 : :
834 : 0 : const String& XclImpLinkManagerImpl::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
835 : : {
836 : 0 : const XclImpSupbook* p = GetSupbook(nXti);
837 [ # # ]: 0 : return p ? p->GetTabName(nXtiTab) : EMPTY_STRING;
838 : : }
839 : :
840 : 0 : bool XclImpLinkManagerImpl::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
841 : : {
842 : 0 : const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
843 [ # # ][ # # ]: 0 : return pSupbook && pSupbook->GetLinkData( rApplic, rTopic );
844 : : }
845 : :
846 : 0 : const String& XclImpLinkManagerImpl::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
847 : : {
848 : 0 : const XclImpSupbook* pSupbook = GetSupbook( nExtSheet );
849 [ # # ]: 0 : return pSupbook ? pSupbook->GetMacroName( nExtName ) : EMPTY_STRING;
850 : : }
851 : :
852 : 5526 : const XclImpXti* XclImpLinkManagerImpl::GetXti( sal_uInt16 nXtiIndex ) const
853 : : {
854 [ + - ]: 5526 : return (nXtiIndex < maXtiList.size()) ? &maXtiList[ nXtiIndex ] : 0;
855 : : }
856 : :
857 : 2763 : const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt16 nXtiIndex ) const
858 : : {
859 [ - + ]: 2763 : if ( maSupbookList.empty() )
860 : 0 : return NULL;
861 : 2763 : const XclImpXti* pXti = GetXti( nXtiIndex );
862 [ - + ][ - + ]: 2763 : if (!pXti || pXti->mnSupbook >= maSupbookList.size())
[ + - ]
863 : 0 : return NULL;
864 : 2763 : return &(maSupbookList.at( pXti->mnSupbook ));
865 : : }
866 : :
867 : 25 : void XclImpLinkManagerImpl::LoadCachedValues()
868 : : {
869 : : // Read all CRN records which can be accessed via XclImpSupbook, and store
870 : : // the cached values to the external reference manager.
871 [ + - ][ + - ]: 50 : for (XclImpSupbookList::iterator itSupbook = maSupbookList.begin(); itSupbook != maSupbookList.end(); ++itSupbook)
[ + - ][ + - ]
[ + + ]
872 [ + - ][ + - ]: 25 : itSupbook->LoadCachedValues();
873 : 25 : }
874 : :
875 : : // ============================================================================
876 : :
877 : 55 : XclImpLinkManager::XclImpLinkManager( const XclImpRoot& rRoot ) :
878 : : XclImpRoot( rRoot ),
879 [ + - ][ + - ]: 55 : mxImpl( new XclImpLinkManagerImpl( rRoot ) )
880 : : {
881 : 55 : }
882 : :
883 [ + - ]: 55 : XclImpLinkManager::~XclImpLinkManager()
884 : : {
885 [ - + ]: 110 : }
886 : :
887 : 25 : void XclImpLinkManager::ReadExternsheet( XclImpStream& rStrm )
888 : : {
889 : 25 : mxImpl->ReadExternsheet( rStrm );
890 : 25 : }
891 : :
892 : 25 : void XclImpLinkManager::ReadSupbook( XclImpStream& rStrm )
893 : : {
894 : 25 : mxImpl->ReadSupbook( rStrm );
895 : 25 : }
896 : :
897 : 0 : void XclImpLinkManager::ReadXct( XclImpStream& rStrm )
898 : : {
899 : 0 : mxImpl->ReadXct( rStrm );
900 : 0 : }
901 : :
902 : 0 : void XclImpLinkManager::ReadCrn( XclImpStream& rStrm )
903 : : {
904 : 0 : mxImpl->ReadCrn( rStrm );
905 : 0 : }
906 : :
907 : 0 : void XclImpLinkManager::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
908 : : {
909 : 0 : mxImpl->ReadExternname( rStrm, pFormulaConv );
910 : 0 : }
911 : :
912 : 2763 : bool XclImpLinkManager::IsSelfRef( sal_uInt16 nXtiIndex ) const
913 : : {
914 : 2763 : return mxImpl->IsSelfRef( nXtiIndex );
915 : : }
916 : :
917 : 2763 : bool XclImpLinkManager::GetScTabRange(
918 : : SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
919 : : {
920 : 2763 : return mxImpl->GetScTabRange( rnFirstScTab, rnLastScTab, nXtiIndex );
921 : : }
922 : :
923 : 0 : const XclImpExtName* XclImpLinkManager::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
924 : : {
925 : 0 : return mxImpl->GetExternName( nXtiIndex, nExtName );
926 : : }
927 : :
928 : 0 : const String* XclImpLinkManager::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
929 : : {
930 : 0 : return mxImpl->GetSupbookUrl(nXtiIndex);
931 : : }
932 : :
933 : 0 : const String& XclImpLinkManager::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
934 : : {
935 : 0 : return mxImpl->GetSupbookTabName(nXti, nXtiTab);
936 : : }
937 : :
938 : 0 : bool XclImpLinkManager::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
939 : : {
940 : 0 : return mxImpl->GetLinkData( rApplic, rTopic, nXtiIndex );
941 : : }
942 : :
943 : 0 : const String& XclImpLinkManager::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
944 : : {
945 : 0 : return mxImpl->GetMacroName( nExtSheet, nExtName );
946 : : }
947 : :
948 : : // ============================================================================
949 : :
950 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|