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 "xelink.hxx"
30 : :
31 : : #include <algorithm>
32 : : #include <unotools/collatorwrapper.hxx>
33 : : #include <svl/zforlist.hxx>
34 : : #include "document.hxx"
35 : : #include "cell.hxx"
36 : : #include "scextopt.hxx"
37 : : #include "externalrefmgr.hxx"
38 : :
39 : : #include <vector>
40 : : #include <memory>
41 : :
42 : : using ::std::auto_ptr;
43 : : using ::std::find_if;
44 : : using ::std::vector;
45 : : using ::rtl::OUString;
46 : : using ::com::sun::star::uno::Any;
47 : :
48 : : // ============================================================================
49 : : // *** Helper classes ***
50 : : // ============================================================================
51 : :
52 : : // External names =============================================================
53 : :
54 : : /** This is a base class for any external name (i.e. add-in names or DDE links).
55 : : @descr Derived classes implement creation and export of the external names. */
56 : : class XclExpExtNameBase : public XclExpRecord, protected XclExpRoot
57 : : {
58 : : public:
59 : : /** @param nFlags The flags to export. */
60 : : explicit XclExpExtNameBase( const XclExpRoot& rRoot,
61 : : const String& rName, sal_uInt16 nFlags = 0 );
62 : : virtual ~XclExpExtNameBase();
63 : :
64 : : /** Returns the name string of the external name. */
65 : 0 : inline const String& GetName() const { return maName; }
66 : :
67 : : private:
68 : : /** Writes the start of the record that is equal in all EXTERNNAME records and calls WriteAddData(). */
69 : : virtual void WriteBody( XclExpStream& rStrm );
70 : : /** Called to write additional data following the common record contents.
71 : : @descr Derived classes should overwrite this function to write their data. */
72 : : virtual void WriteAddData( XclExpStream& rStrm );
73 : :
74 : : private:
75 : : String maName; /// Calc name (title) of the external name.
76 : : XclExpStringRef mxName; /// Excel name (title) of the external name.
77 : : sal_uInt16 mnFlags; /// Flags for record export.
78 : : };
79 : :
80 : : // ----------------------------------------------------------------------------
81 : :
82 : : /** Represents an EXTERNNAME record for an add-in function name. */
83 [ # # ]: 0 : class XclExpExtNameAddIn : public XclExpExtNameBase
84 : : {
85 : : public:
86 : : explicit XclExpExtNameAddIn( const XclExpRoot& rRoot, const String& rName );
87 : :
88 : : private:
89 : : /** Writes additional record contents. */
90 : : virtual void WriteAddData( XclExpStream& rStrm );
91 : : };
92 : :
93 : : // ----------------------------------------------------------------------------
94 : :
95 : : /** Represents an EXTERNNAME record for a DDE link. */
96 [ # # ][ # # ]: 0 : class XclExpExtNameDde : public XclExpExtNameBase
97 : : {
98 : : public:
99 : : explicit XclExpExtNameDde( const XclExpRoot& rRoot, const String& rName,
100 : : sal_uInt16 nFlags, const ScMatrix* pResults = 0 );
101 : :
102 : : private:
103 : : /** Writes additional record contents. */
104 : : virtual void WriteAddData( XclExpStream& rStrm );
105 : :
106 : : private:
107 : : typedef boost::shared_ptr< XclExpCachedMatrix > XclExpCachedMatRef;
108 : : XclExpCachedMatRef mxMatrix; /// Cached results of the DDE link.
109 : : };
110 : :
111 : : // ----------------------------------------------------------------------------
112 : :
113 : : class XclExpSupbook;
114 : :
115 [ # # ][ # # ]: 0 : class XclExpExtName : public XclExpExtNameBase
116 : : {
117 : : public:
118 : : explicit XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook, const String& rName,
119 : : const ScExternalRefCache::TokenArrayRef pArray );
120 : :
121 : : private:
122 : : /** Writes additional record contents. */
123 : : virtual void WriteAddData( XclExpStream& rStrm );
124 : :
125 : : private:
126 : : const XclExpSupbook& mrSupbook;
127 : : auto_ptr<ScTokenArray> mpArray;
128 : : };
129 : :
130 : : // List of external names =====================================================
131 : :
132 : : /** List of all external names of a sheet. */
133 [ # # ][ # # ]: 0 : class XclExpExtNameBuffer : public XclExpRecordBase, protected XclExpRoot
[ # # ]
134 : : {
135 : : public:
136 : : explicit XclExpExtNameBuffer( const XclExpRoot& rRoot );
137 : :
138 : : /** Inserts an add-in function name
139 : : @return The 1-based (Excel-like) list index of the name. */
140 : : sal_uInt16 InsertAddIn( const String& rName );
141 : : /** InsertEuroTool */
142 : : sal_uInt16 InsertEuroTool( const String& rName );
143 : : /** Inserts a DDE link.
144 : : @return The 1-based (Excel-like) list index of the DDE link. */
145 : : sal_uInt16 InsertDde( const String& rApplic, const String& rTopic, const String& rItem );
146 : :
147 : : sal_uInt16 InsertExtName( const XclExpSupbook& rSupbook, const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
148 : :
149 : : /** Writes the EXTERNNAME record list. */
150 : : virtual void Save( XclExpStream& rStrm );
151 : :
152 : : private:
153 : : typedef XclExpRecordList< XclExpExtNameBase > XclExpExtNameList;
154 : : typedef XclExpExtNameList::RecordRefType XclExpExtNameRef;
155 : :
156 : : private:
157 : : /** Returns the 1-based (Excel-like) list index of the external name or 0, if not found. */
158 : : sal_uInt16 GetIndex( const String& rName ) const;
159 : : /** Appends the passed newly crested external name.
160 : : @return The 1-based (Excel-like) list index of the appended name. */
161 : : sal_uInt16 AppendNew( XclExpExtNameBase* pExtName );
162 : :
163 : : private:
164 : : XclExpExtNameList maNameList; /// The list with all EXTERNNAME records.
165 : : };
166 : :
167 : : // Cached external cells ======================================================
168 : :
169 : : /** Stores the contents of a consecutive row of external cells (record CRN). */
170 [ # # ]: 0 : class XclExpCrn : public XclExpRecord
171 : : {
172 : : public:
173 : : explicit XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue );
174 : :
175 : : /** Returns true, if the passed value could be appended to this record. */
176 : : bool InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue );
177 : :
178 : : private:
179 : : virtual void WriteBody( XclExpStream& rStrm );
180 : :
181 : : void WriteBool( XclExpStream& rStrm, bool bValue );
182 : : void WriteDouble( XclExpStream& rStrm, double fValue );
183 : : void WriteString( XclExpStream& rStrm, const OUString& rValue );
184 : : void WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode );
185 : : void WriteEmpty( XclExpStream& rStrm );
186 : :
187 : : private:
188 : : typedef ::std::vector< Any > CachedValues;
189 : :
190 : : CachedValues maValues; /// All cached values.
191 : : SCCOL mnScCol; /// Column index of the first external cell.
192 : : SCROW mnScRow; /// Row index of the external cells.
193 : : };
194 : :
195 : : // ----------------------------------------------------------------------------
196 : :
197 : : /** Represents the record XCT which is the header record of a CRN record list.
198 : : */
199 [ # # ][ # # ]: 0 : class XclExpXct : public XclExpRecordBase, protected XclExpRoot
[ # # ][ # # ]
200 : : {
201 : : public:
202 : : explicit XclExpXct( const XclExpRoot& rRoot,
203 : : const String& rTabName, sal_uInt16 nSBTab,
204 : : ScExternalRefCache::TableTypeRef xCacheTable );
205 : :
206 : : /** Returns the external sheet name. */
207 : 0 : inline const XclExpString& GetTabName() const { return maTabName; }
208 : :
209 : : /** Stores all cells in the given range in the CRN list. */
210 : : void StoreCellRange( const ScRange& rRange );
211 : :
212 : : void StoreCell( const ScAddress& rCell, const ::formula::FormulaToken& rToken );
213 : : void StoreCellRange( const ScRange& rRange, const ::formula::FormulaToken& rToken );
214 : :
215 : : /** Writes the XCT and all CRN records. */
216 : : virtual void Save( XclExpStream& rStrm );
217 : :
218 : : private:
219 : : ScExternalRefCache::TableTypeRef mxCacheTable;
220 : : ScMarkData maUsedCells; /// Contains addresses of all stored cells.
221 : : ScRange maBoundRange; /// Bounding box of maUsedCells.
222 : : XclExpString maTabName; /// Sheet name of the external sheet.
223 : : sal_uInt16 mnSBTab; /// Referred sheet index in SUPBOOK record.
224 : : };
225 : :
226 : : // External documents (EXTERNSHEET/SUPBOOK), base class =======================
227 : :
228 : : /** Base class for records representing external sheets/documents.
229 : :
230 : : In BIFF5/BIFF7, this record is the EXTERNSHEET record containing one sheet
231 : : of the own or an external document. In BIFF8, this record is the SUPBOOK
232 : : record representing the entire own or external document with all referenced
233 : : sheets.
234 : : */
235 [ # # ][ # # ]: 0 : class XclExpExternSheetBase : public XclExpRecord, protected XclExpRoot
[ # # ]
236 : : {
237 : : public:
238 : : explicit XclExpExternSheetBase( const XclExpRoot& rRoot,
239 : : sal_uInt16 nRecId, sal_uInt32 nRecSize = 0 );
240 : :
241 : : protected:
242 : : /** Creates and returns the list of EXTERNNAME records. */
243 : : XclExpExtNameBuffer& GetExtNameBuffer();
244 : : /** Creates and returns the list of EXTERNNAME records. */
245 : : void WriteExtNameBuffer( XclExpStream& rStrm );
246 : :
247 : : private:
248 : : typedef boost::shared_ptr< XclExpExtNameBuffer > XclExpExtNameBfrRef;
249 : : XclExpExtNameBfrRef mxExtNameBfr; /// List of EXTERNNAME records.
250 : : };
251 : :
252 : : // External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
253 : :
254 : : /** Represents an EXTERNSHEET record containing the URL and sheet name of a sheet.
255 : : @descr This class is used up to BIFF7 only, writing a BIFF8 EXTERNSHEET
256 : : record is implemented directly in the link manager. */
257 [ # # ]: 0 : class XclExpExternSheet : public XclExpExternSheetBase
258 : : {
259 : : public:
260 : : /** Creates an EXTERNSHEET record containing a special code (i.e. own document or sheet). */
261 : : explicit XclExpExternSheet( const XclExpRoot& rRoot, sal_Unicode cCode );
262 : : /** Creates an EXTERNSHEET record referring to an internal sheet. */
263 : : explicit XclExpExternSheet( const XclExpRoot& rRoot, const String& rTabName );
264 : :
265 : : /** Finds or inserts an EXTERNNAME record for add-ins.
266 : : @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
267 : : sal_uInt16 InsertAddIn( const String& rName );
268 : :
269 : : /** Writes the EXTERNSHEET and all EXTERNNAME, XCT and CRN records. */
270 : : virtual void Save( XclExpStream& rStrm );
271 : :
272 : : private:
273 : : /** Initializes the record data with the passed encoded URL. */
274 : : void Init( const String& rEncUrl );
275 : : /** Writes the contents of the EXTERNSHEET record. */
276 : : virtual void WriteBody( XclExpStream& rStrm );
277 : :
278 : : private:
279 : : XclExpString maTabName; /// The name of the sheet.
280 : : };
281 : :
282 : : // External documents (SUPBOOK, BIFF8) ========================================
283 : :
284 : : /** The SUPBOOK record contains data for an external document (URL, sheet names, external values). */
285 [ # # ][ # # ]: 0 : class XclExpSupbook : public XclExpExternSheetBase
[ # # ][ # # ]
286 : : {
287 : : public:
288 : : /** Creates a SUPBOOK record for internal references. */
289 : : explicit XclExpSupbook( const XclExpRoot& rRoot, sal_uInt16 nXclTabCount );
290 : : /** Creates a SUPBOOK record for add-in functions. */
291 : : explicit XclExpSupbook( const XclExpRoot& rRoot );
292 : : /** EUROTOOL SUPBOOK */
293 : : explicit XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl, XclSupbookType );
294 : : /** Creates a SUPBOOK record for an external document. */
295 : : explicit XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl );
296 : : /** Creates a SUPBOOK record for a DDE link. */
297 : : explicit XclExpSupbook( const XclExpRoot& rRoot, const String& rApplic, const String& rTopic );
298 : :
299 : : /** Returns true, if this SUPBOOK contains the passed URL of an external document. */
300 : : bool IsUrlLink( const String& rUrl ) const;
301 : : /** Returns true, if this SUPBOOK contains the passed DDE link. */
302 : : bool IsDdeLink( const String& rApplic, const String& rTopic ) const;
303 : : /** Fills the passed reference log entry with the URL and sheet names. */
304 : : void FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry,
305 : : sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) const;
306 : :
307 : : /** Stores all cells in the given range in the CRN list of the specified SUPBOOK sheet. */
308 : : void StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab );
309 : :
310 : : void StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const ::formula::FormulaToken& rToken );
311 : : void StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const ::formula::FormulaToken& rToken );
312 : :
313 : : sal_uInt16 GetTabIndex( const String& rTabName ) const;
314 : : sal_uInt16 GetTabCount() const;
315 : :
316 : : /** Inserts a new sheet name into the SUPBOOK and returns the SUPBOOK internal sheet index. */
317 : : sal_uInt16 InsertTabName( const String& rTabName, ScExternalRefCache::TableTypeRef xCacheTable );
318 : : /** Finds or inserts an EXTERNNAME record for add-ins.
319 : : @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
320 : : sal_uInt16 InsertAddIn( const String& rName );
321 : : /** InsertEuroTool */
322 : : sal_uInt16 InsertEuroTool( const String& rName );
323 : : /** Finds or inserts an EXTERNNAME record for DDE links.
324 : : @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
325 : : sal_uInt16 InsertDde( const String& rItem );
326 : :
327 : : sal_uInt16 InsertExtName( const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
328 : :
329 : : /** Writes the SUPBOOK and all EXTERNNAME, XCT and CRN records. */
330 : : virtual void Save( XclExpStream& rStrm );
331 : :
332 : : private:
333 : : /** Returns the sheet name inside of this SUPBOOK. */
334 : : const XclExpString* GetTabName( sal_uInt16 nSBTab ) const;
335 : :
336 : : /** Writes the SUPBOOK record contents. */
337 : : virtual void WriteBody( XclExpStream& rStrm );
338 : :
339 : : private:
340 : : typedef XclExpRecordList< XclExpXct > XclExpXctList;
341 : : typedef XclExpXctList::RecordRefType XclExpXctRef;
342 : :
343 : : XclExpXctList maXctList; /// List of XCT records (which contain CRN records).
344 : : String maUrl; /// URL of the external document or application name for DDE.
345 : : String maDdeTopic; /// Topic of an DDE link.
346 : : XclExpString maUrlEncoded; /// Document name encoded for Excel.
347 : : XclSupbookType meType; /// Type of this SUPBOOK record.
348 : : sal_uInt16 mnXclTabCount; /// Number of internal sheets.
349 : : };
350 : :
351 : : // All SUPBOOKS in a document =================================================
352 : :
353 : : /** This struct contains a sheet index range for 3D references.
354 : : @descr This reference consists of an index to a SUPBOOK record and indexes
355 : : to SUPBOOK sheet names. */
356 : : struct XclExpXti
357 : : {
358 : : sal_uInt16 mnSupbook; /// Index to SUPBOOK record.
359 : : sal_uInt16 mnFirstSBTab; /// Index to the first sheet of the range in the SUPBOOK.
360 : : sal_uInt16 mnLastSBTab; /// Index to the last sheet of the range in the SUPBOOK.
361 : :
362 : 0 : inline explicit XclExpXti() : mnSupbook( 0 ), mnFirstSBTab( 0 ), mnLastSBTab( 0 ) {}
363 : 0 : inline explicit XclExpXti( sal_uInt16 nSupbook, sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) :
364 : 0 : mnSupbook( nSupbook ), mnFirstSBTab( nFirstSBTab ), mnLastSBTab( nLastSBTab ) {}
365 : :
366 : : /** Writes this XTI structure (inside of the EXTERNSHEET record). */
367 : 0 : inline void Save( XclExpStream& rStrm ) const
368 : 0 : { rStrm << mnSupbook << mnFirstSBTab << mnLastSBTab; }
369 : : };
370 : :
371 : 0 : inline bool operator==( const XclExpXti& rLeft, const XclExpXti& rRight )
372 : : {
373 : : return
374 : : (rLeft.mnSupbook == rRight.mnSupbook) &&
375 : : (rLeft.mnFirstSBTab == rRight.mnFirstSBTab) &&
376 [ # # ][ # # ]: 0 : (rLeft.mnLastSBTab == rRight.mnLastSBTab);
[ # # ]
377 : : }
378 : :
379 : : // ----------------------------------------------------------------------------
380 : :
381 : : /** Contains a list of all SUPBOOK records and index arrays of external sheets. */
382 [ # # ][ # # ]: 0 : class XclExpSupbookBuffer : public XclExpRecordBase, protected XclExpRoot
[ # # ]
383 : : {
384 : : public:
385 : : explicit XclExpSupbookBuffer( const XclExpRoot& rRoot );
386 : :
387 : : /** Finds SUPBOOK index and SUPBOOK sheet range from given Excel sheet range.
388 : : @return An XTI structure containing SUPBOOK and sheet indexes. */
389 : : XclExpXti GetXti( sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
390 : : XclExpRefLogEntry* pRefLogEntry = 0 ) const;
391 : :
392 : : /** Stores all cells in the given range in a CRN record list. */
393 : : void StoreCellRange( const ScRange& rRange );
394 : :
395 : : void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell );
396 : : void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange );
397 : :
398 : : /** Finds or inserts an EXTERNNAME record for an add-in function name.
399 : : @param rnSupbook Returns the index of the SUPBOOK record which contains the add-in function name.
400 : : @param rnExtName Returns the 1-based EXTERNNAME record index. */
401 : : bool InsertAddIn(
402 : : sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
403 : : const String& rName );
404 : : /** InsertEuroTool */
405 : : bool InsertEuroTool(
406 : : sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
407 : : const String& rName );
408 : : /** Finds or inserts an EXTERNNAME record for DDE links.
409 : : @param rnSupbook Returns the index of the SUPBOOK record which contains the DDE link.
410 : : @param rnExtName Returns the 1-based EXTERNNAME record index. */
411 : : bool InsertDde(
412 : : sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
413 : : const String& rApplic, const String& rTopic, const String& rItem );
414 : :
415 : : bool InsertExtName(
416 : : sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rUrl,
417 : : const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
418 : :
419 : : XclExpXti GetXti( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
420 : : XclExpRefLogEntry* pRefLogEntry = NULL );
421 : :
422 : : /** Writes all SUPBOOK records with their sub records. */
423 : : virtual void Save( XclExpStream& rStrm );
424 : :
425 : : struct XclExpSBIndex
426 : : {
427 : : sal_uInt16 mnSupbook; /// SUPBOOK index for an Excel sheet.
428 : : sal_uInt16 mnSBTab; /// Sheet name index in SUPBOOK for an Excel sheet.
429 : 0 : inline void Set( sal_uInt16 nSupbook, sal_uInt16 nSBTab )
430 : 0 : { mnSupbook = nSupbook; mnSBTab = nSBTab; }
431 : : };
432 : : typedef ::std::vector< XclExpSBIndex > XclExpSBIndexVec;
433 : :
434 : : private:
435 : : typedef XclExpRecordList< XclExpSupbook > XclExpSupbookList;
436 : : typedef XclExpSupbookList::RecordRefType XclExpSupbookRef;
437 : :
438 : : private:
439 : : /** Searches for the SUPBOOK record containing the passed document URL.
440 : : @param rxSupbook (out-param) Returns a reference to the SUPBOOK record, or 0.
441 : : @param rnIndex (out-param) Returns the list index, if the SUPBOOK exists.
442 : : @return True, if the SUPBOOK record exists (out-parameters are valid). */
443 : : bool GetSupbookUrl( XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex,
444 : : const String& rUrl ) const;
445 : : /** Searches for the SUPBOOK record containing the passed DDE link.
446 : : @param rxSupbook (out-param) Returns a reference to the SUPBOOK record, or 0.
447 : : @param rnIndex (out-param) Returns the list index, if the SUPBOOK exists.
448 : : @return True, if the SUPBOOK record exists (out-parameters are valid). */
449 : : bool GetSupbookDde( XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex,
450 : : const String& rApplic, const String& rTopic ) const;
451 : :
452 : : /** Appends a new SUPBOOK to the list.
453 : : @return The list index of the SUPBOOK record. */
454 : : sal_uInt16 Append( XclExpSupbookRef xSupbook );
455 : :
456 : : private:
457 : : XclExpSupbookList maSupbookList; /// List of all SUPBOOK records.
458 : : XclExpSBIndexVec maSBIndexVec; /// SUPBOOK and sheet name index for each Excel sheet.
459 : : sal_uInt16 mnOwnDocSB; /// Index to SUPBOOK for own document.
460 : : sal_uInt16 mnAddInSB; /// Index to add-in SUPBOOK.
461 : : };
462 : :
463 : : // Export link manager ========================================================
464 : :
465 : : /** Abstract base class for implementation classes of the link manager. */
466 [ # # ]: 0 : class XclExpLinkManagerImpl : protected XclExpRoot
467 : : {
468 : : public:
469 : : /** Derived classes search for an EXTSHEET structure for the given Calc sheet range. */
470 : : virtual void FindExtSheet( sal_uInt16& rnExtSheet,
471 : : sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
472 : : SCTAB nFirstScTab, SCTAB nLastScTab,
473 : : XclExpRefLogEntry* pRefLogEntry ) = 0;
474 : : /** Derived classes search for a special EXTERNSHEET index for the own document. */
475 : : virtual sal_uInt16 FindExtSheet( sal_Unicode cCode ) = 0;
476 : :
477 : : virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
478 : : sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
479 : : XclExpRefLogEntry* pRefLogEntry ) = 0;
480 : :
481 : : /** Derived classes store all cells in the given range in a CRN record list. */
482 : : virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 ) = 0;
483 : :
484 : : virtual void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef ) = 0;
485 : : virtual void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 ) = 0;
486 : :
487 : : /** Derived classes find or insert an EXTERNNAME record for an add-in function name. */
488 : : virtual bool InsertAddIn(
489 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
490 : : const String& rName ) = 0;
491 : : /** InsertEuroTool */
492 : : virtual bool InsertEuroTool(
493 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
494 : : const String& rName ) = 0;
495 : :
496 : : /** Derived classes find or insert an EXTERNNAME record for DDE links. */
497 : : virtual bool InsertDde(
498 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
499 : : const String& rApplic, const String& rTopic, const String& rItem ) = 0;
500 : :
501 : : virtual bool InsertExtName(
502 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
503 : : const String& rName, const ScExternalRefCache::TokenArrayRef pArray ) = 0;
504 : :
505 : : /** Derived classes write the entire link table to the passed stream. */
506 : : virtual void Save( XclExpStream& rStrm ) = 0;
507 : :
508 : : protected:
509 : : explicit XclExpLinkManagerImpl( const XclExpRoot& rRoot );
510 : : };
511 : :
512 : : // ----------------------------------------------------------------------------
513 : :
514 : : /** Implementation of the link manager for BIFF5/BIFF7. */
515 [ # # ][ # # ]: 0 : class XclExpLinkManagerImpl5 : public XclExpLinkManagerImpl
516 : : {
517 : : public:
518 : : explicit XclExpLinkManagerImpl5( const XclExpRoot& rRoot );
519 : :
520 : : virtual void FindExtSheet( sal_uInt16& rnExtSheet,
521 : : sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
522 : : SCTAB nFirstScTab, SCTAB nLastScTab,
523 : : XclExpRefLogEntry* pRefLogEntry );
524 : : virtual sal_uInt16 FindExtSheet( sal_Unicode cCode );
525 : :
526 : : virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
527 : : sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
528 : : XclExpRefLogEntry* pRefLogEntry );
529 : :
530 : : virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
531 : :
532 : : virtual void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
533 : : virtual void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
534 : :
535 : : virtual bool InsertAddIn(
536 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
537 : : const String& rName );
538 : :
539 : : /** InsertEuroTool */
540 : : virtual bool InsertEuroTool(
541 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
542 : : const String& rName );
543 : :
544 : : virtual bool InsertDde(
545 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
546 : : const String& rApplic, const String& rTopic, const String& rItem );
547 : :
548 : : virtual bool InsertExtName(
549 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
550 : : const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
551 : :
552 : : virtual void Save( XclExpStream& rStrm );
553 : :
554 : : private:
555 : : typedef XclExpRecordList< XclExpExternSheet > XclExpExtSheetList;
556 : : typedef XclExpExtSheetList::RecordRefType XclExpExtSheetRef;
557 : : typedef ::std::map< SCTAB, sal_uInt16 > XclExpIntTabMap;
558 : : typedef ::std::map< sal_Unicode, sal_uInt16 > XclExpCodeMap;
559 : :
560 : : private:
561 : : /** Returns the number of EXTERNSHEET records. */
562 : : sal_uInt16 GetExtSheetCount() const;
563 : :
564 : : /** Appends an internal EXTERNSHEET record and returns the one-based index. */
565 : : sal_uInt16 AppendInternal( XclExpExtSheetRef xExtSheet );
566 : : /** Creates all EXTERNSHEET records for internal sheets on first call. */
567 : : void CreateInternal();
568 : :
569 : : /** Returns the specified internal EXTERNSHEET record. */
570 : : XclExpExtSheetRef GetInternal( sal_uInt16 nExtSheet );
571 : : /** Returns the EXTERNSHEET index of an internal Calc sheet, or a deleted reference. */
572 : : XclExpExtSheetRef FindInternal( sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab, SCTAB nScTab );
573 : : /** Finds or creates the EXTERNSHEET index of an internal special EXTERNSHEET. */
574 : : XclExpExtSheetRef FindInternal( sal_uInt16& rnExtSheet, sal_Unicode cCode );
575 : :
576 : : private:
577 : : XclExpExtSheetList maExtSheetList; /// List with EXTERNSHEET records.
578 : : XclExpIntTabMap maIntTabMap; /// Maps internal Calc sheets to EXTERNSHEET records.
579 : : XclExpCodeMap maCodeMap; /// Maps special external codes to EXTERNSHEET records.
580 : : };
581 : :
582 : : // ----------------------------------------------------------------------------
583 : :
584 : : /** Implementation of the link manager for BIFF8. */
585 [ # # ][ # # ]: 0 : class XclExpLinkManagerImpl8 : public XclExpLinkManagerImpl
586 : : {
587 : : public:
588 : : explicit XclExpLinkManagerImpl8( const XclExpRoot& rRoot );
589 : :
590 : : virtual void FindExtSheet( sal_uInt16& rnExtSheet,
591 : : sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
592 : : SCTAB nFirstScTab, SCTAB nLastScTab,
593 : : XclExpRefLogEntry* pRefLogEntry );
594 : : virtual sal_uInt16 FindExtSheet( sal_Unicode cCode );
595 : :
596 : : virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
597 : : sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
598 : : XclExpRefLogEntry* pRefLogEntry );
599 : :
600 : : virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
601 : :
602 : : virtual void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
603 : : virtual void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
604 : :
605 : : virtual bool InsertAddIn(
606 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
607 : : const String& rName );
608 : : /** InsertEuroTool */
609 : : virtual bool InsertEuroTool(
610 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
611 : : const String& rName );
612 : :
613 : : virtual bool InsertDde(
614 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
615 : : const String& rApplic, const String& rTopic, const String& rItem );
616 : :
617 : : virtual bool InsertExtName(
618 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
619 : : const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
620 : :
621 : : virtual void Save( XclExpStream& rStrm );
622 : :
623 : : private:
624 : : /** Searches for or inserts a new XTI structure.
625 : : @return The 0-based list index of the XTI structure. */
626 : : sal_uInt16 InsertXti( const XclExpXti& rXti );
627 : :
628 : : private:
629 : : typedef ::std::vector< XclExpXti > XclExpXtiVec;
630 : :
631 : : XclExpSupbookBuffer maSBBuffer; /// List of all SUPBOOK records.
632 : : XclExpXtiVec maXtiVec; /// List of XTI structures for the EXTERNSHEET record.
633 : : };
634 : :
635 : : // ============================================================================
636 : : // *** Implementation ***
637 : : // ============================================================================
638 : :
639 : : // Excel sheet indexes ========================================================
640 : :
641 : : const sal_uInt8 EXC_TABBUF_IGNORE = 0x01; /// Sheet will be ignored completely.
642 : : const sal_uInt8 EXC_TABBUF_EXTERN = 0x02; /// Sheet is linked externally.
643 : : const sal_uInt8 EXC_TABBUF_SKIPMASK = 0x0F; /// Sheet will be skipped, if any flag is set.
644 : : const sal_uInt8 EXC_TABBUF_VISIBLE = 0x10; /// Sheet is visible.
645 : : const sal_uInt8 EXC_TABBUF_SELECTED = 0x20; /// Sheet is selected.
646 : : const sal_uInt8 EXC_TABBUF_MIRRORED = 0x40; /// Sheet is mirrored (right-to-left).
647 : :
648 : : // ----------------------------------------------------------------------------
649 : :
650 : 0 : XclExpTabInfo::XclExpTabInfo( const XclExpRoot& rRoot ) :
651 : : XclExpRoot( rRoot ),
652 : : mnScCnt( 0 ),
653 : : mnXclCnt( 0 ),
654 : : mnXclExtCnt( 0 ),
655 : : mnXclSelCnt( 0 ),
656 : : mnDisplXclTab( 0 ),
657 [ # # ][ # # ]: 0 : mnFirstVisXclTab( 0 )
[ # # ]
658 : : {
659 : 0 : ScDocument& rDoc = GetDoc();
660 [ # # ]: 0 : ScExtDocOptions& rDocOpt = GetExtDocOptions();
661 : :
662 [ # # ]: 0 : mnScCnt = rDoc.GetTableCount();
663 : :
664 : : SCTAB nScTab;
665 : 0 : SCTAB nFirstVisScTab = SCTAB_INVALID; // first visible sheet
666 : 0 : SCTAB nFirstExpScTab = SCTAB_INVALID; // first exported sheet
667 : :
668 : : // --- initialize the flags in the index buffer ---
669 : :
670 [ # # ]: 0 : maTabInfoVec.resize( mnScCnt );
671 [ # # ]: 0 : for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
672 : : {
673 : : // ignored sheets (skipped by export, with invalid Excel sheet index)
674 [ # # ][ # # ]: 0 : if( rDoc.IsScenario( nScTab ) )
675 : : {
676 [ # # ]: 0 : SetFlag( nScTab, EXC_TABBUF_IGNORE );
677 : : }
678 : :
679 : : // external sheets (skipped, but with valid Excel sheet index for ref's)
680 [ # # ][ # # ]: 0 : else if( rDoc.GetLinkMode( nScTab ) == SC_LINK_VALUE )
681 : : {
682 [ # # ]: 0 : SetFlag( nScTab, EXC_TABBUF_EXTERN );
683 : : }
684 : :
685 : : // exported sheets
686 : : else
687 : : {
688 : : // sheet name
689 [ # # ]: 0 : rDoc.GetName( nScTab, maTabInfoVec[ nScTab ].maScName );
690 : :
691 : : // remember first exported sheet
692 [ # # ]: 0 : if( nFirstExpScTab == SCTAB_INVALID )
693 : 0 : nFirstExpScTab = nScTab;
694 : : // remember first visible exported sheet
695 [ # # ][ # # ]: 0 : if( (nFirstVisScTab == SCTAB_INVALID) && rDoc.IsVisible( nScTab ) )
[ # # ][ # # ]
696 : 0 : nFirstVisScTab = nScTab;
697 : :
698 : : // sheet visible (only exported sheets)
699 [ # # ][ # # ]: 0 : SetFlag( nScTab, EXC_TABBUF_VISIBLE, rDoc.IsVisible( nScTab ) );
700 : :
701 : : // sheet selected (only exported sheets)
702 [ # # ][ # # ]: 0 : if( const ScExtTabSettings* pTabSett = rDocOpt.GetTabSettings( nScTab ) )
703 [ # # ]: 0 : SetFlag( nScTab, EXC_TABBUF_SELECTED, pTabSett->mbSelected );
704 : :
705 : : // sheet mirrored (only exported sheets)
706 [ # # ][ # # ]: 0 : SetFlag( nScTab, EXC_TABBUF_MIRRORED, rDoc.IsLayoutRTL( nScTab ) );
707 : : }
708 : : }
709 : :
710 : : // --- visible/selected sheets ---
711 : :
712 [ # # ]: 0 : SCTAB nDisplScTab = rDocOpt.GetDocSettings().mnDisplTab;
713 : :
714 : : // find first visible exported sheet
715 [ # # ][ # # ]: 0 : if( (nFirstVisScTab == SCTAB_INVALID) || !IsExportTab( nFirstVisScTab ) )
[ # # ][ # # ]
716 : : {
717 : : // no exportable visible sheet -> use first exportable sheet
718 : 0 : nFirstVisScTab = nFirstExpScTab;
719 [ # # ][ # # ]: 0 : if( (nFirstVisScTab == SCTAB_INVALID) || !IsExportTab( nFirstVisScTab ) )
[ # # ][ # # ]
720 : : {
721 : : // no exportable sheet at all -> use active sheet and export it
722 : 0 : nFirstVisScTab = nDisplScTab;
723 [ # # ]: 0 : SetFlag( nFirstVisScTab, EXC_TABBUF_SKIPMASK, false ); // clear skip flags
724 : : }
725 [ # # ]: 0 : SetFlag( nFirstVisScTab, EXC_TABBUF_VISIBLE ); // must be visible, even if originally hidden
726 : : }
727 : :
728 : : // find currently displayed sheet
729 [ # # ][ # # ]: 0 : if( !IsExportTab( nDisplScTab ) ) // selected sheet not exported (i.e. scenario) -> use first visible
730 : 0 : nDisplScTab = nFirstVisScTab;
731 [ # # ]: 0 : SetFlag( nDisplScTab, EXC_TABBUF_VISIBLE | EXC_TABBUF_SELECTED );
732 : :
733 : : // number of selected sheets
734 [ # # ]: 0 : for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
735 [ # # ][ # # ]: 0 : if( IsSelectedTab( nScTab ) )
736 : 0 : ++mnXclSelCnt;
737 : :
738 : : // --- calculate resulting Excel sheet indexes ---
739 : :
740 [ # # ]: 0 : CalcXclIndexes();
741 [ # # ]: 0 : mnFirstVisXclTab = GetXclTab( nFirstVisScTab );
742 [ # # ]: 0 : mnDisplXclTab = GetXclTab( nDisplScTab );
743 : :
744 : : // --- sorted vectors for index lookup ---
745 : :
746 [ # # ]: 0 : CalcSortedIndexes();
747 : 0 : }
748 : :
749 : 0 : bool XclExpTabInfo::IsExportTab( SCTAB nScTab ) const
750 : : {
751 : : /* Check sheet index before to avoid assertion in GetFlag(). */
752 [ # # ][ # # ]: 0 : return (nScTab < mnScCnt) && !GetFlag( nScTab, EXC_TABBUF_SKIPMASK );
753 : : }
754 : :
755 : 0 : bool XclExpTabInfo::IsExternalTab( SCTAB nScTab ) const
756 : : {
757 : : /* Check sheet index before to avoid assertion (called from formula
758 : : compiler also for deleted references). */
759 [ # # ][ # # ]: 0 : return (nScTab < mnScCnt) && GetFlag( nScTab, EXC_TABBUF_EXTERN );
760 : : }
761 : :
762 : 0 : bool XclExpTabInfo::IsVisibleTab( SCTAB nScTab ) const
763 : : {
764 : 0 : return GetFlag( nScTab, EXC_TABBUF_VISIBLE );
765 : : }
766 : :
767 : 0 : bool XclExpTabInfo::IsSelectedTab( SCTAB nScTab ) const
768 : : {
769 : 0 : return GetFlag( nScTab, EXC_TABBUF_SELECTED );
770 : : }
771 : :
772 : 0 : bool XclExpTabInfo::IsDisplayedTab( SCTAB nScTab ) const
773 : : {
774 : : OSL_ENSURE( nScTab < mnScCnt, "XclExpTabInfo::IsActiveTab - sheet out of range" );
775 : 0 : return GetXclTab( nScTab ) == mnDisplXclTab;
776 : : }
777 : :
778 : 0 : bool XclExpTabInfo::IsMirroredTab( SCTAB nScTab ) const
779 : : {
780 : 0 : return GetFlag( nScTab, EXC_TABBUF_MIRRORED );
781 : : }
782 : :
783 : 0 : rtl::OUString XclExpTabInfo::GetScTabName( SCTAB nScTab ) const
784 : : {
785 : : OSL_ENSURE( nScTab < mnScCnt, "XclExpTabInfo::IsActiveTab - sheet out of range" );
786 [ # # ]: 0 : return (nScTab < mnScCnt) ? maTabInfoVec[ nScTab ].maScName : rtl::OUString();
787 : : }
788 : :
789 : 0 : sal_uInt16 XclExpTabInfo::GetXclTab( SCTAB nScTab ) const
790 : : {
791 [ # # ]: 0 : return (nScTab < mnScCnt) ? maTabInfoVec[ nScTab ].mnXclTab : EXC_TAB_DELETED;
792 : : }
793 : :
794 : 0 : SCTAB XclExpTabInfo::GetRealScTab( SCTAB nSortedScTab ) const
795 : : {
796 : : OSL_ENSURE( nSortedScTab < mnScCnt, "XclExpTabInfo::GetRealScTab - sheet out of range" );
797 [ # # ]: 0 : return (nSortedScTab < mnScCnt) ? maFromSortedVec[ nSortedScTab ] : SCTAB_INVALID;
798 : : }
799 : :
800 : 0 : bool XclExpTabInfo::GetFlag( SCTAB nScTab, sal_uInt8 nFlags ) const
801 : : {
802 : : OSL_ENSURE( nScTab < mnScCnt, "XclExpTabInfo::GetFlag - sheet out of range" );
803 [ # # ][ # # ]: 0 : return (nScTab < mnScCnt) && ::get_flag( maTabInfoVec[ nScTab ].mnFlags, nFlags );
804 : : }
805 : :
806 : 0 : void XclExpTabInfo::SetFlag( SCTAB nScTab, sal_uInt8 nFlags, bool bSet )
807 : : {
808 : : OSL_ENSURE( nScTab < mnScCnt, "XclExpTabInfo::SetFlag - sheet out of range" );
809 [ # # ]: 0 : if( nScTab < mnScCnt )
810 : 0 : ::set_flag( maTabInfoVec[ nScTab ].mnFlags, nFlags, bSet );
811 : 0 : }
812 : :
813 : 0 : void XclExpTabInfo::CalcXclIndexes()
814 : : {
815 : 0 : sal_uInt16 nXclTab = 0;
816 : 0 : SCTAB nScTab = 0;
817 : :
818 : : // --- pass 1: process regular sheets ---
819 [ # # ]: 0 : for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
820 : : {
821 [ # # ]: 0 : if( IsExportTab( nScTab ) )
822 : : {
823 : 0 : maTabInfoVec[ nScTab ].mnXclTab = nXclTab;
824 : 0 : ++nXclTab;
825 : : }
826 : : else
827 : 0 : maTabInfoVec[ nScTab ].mnXclTab = EXC_TAB_DELETED;
828 : : }
829 : 0 : mnXclCnt = nXclTab;
830 : :
831 : : // --- pass 2: process external sheets (nXclTab continues) ---
832 [ # # ]: 0 : for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
833 : : {
834 [ # # ]: 0 : if( IsExternalTab( nScTab ) )
835 : : {
836 : 0 : maTabInfoVec[ nScTab ].mnXclTab = nXclTab;
837 : 0 : ++nXclTab;
838 : 0 : ++mnXclExtCnt;
839 : : }
840 : : }
841 : :
842 : : // result: first occur all exported sheets, followed by all external sheets
843 : 0 : }
844 : :
845 : : typedef ::std::pair< rtl::OUString, SCTAB > XclExpTabName;
846 : : typedef ::std::vector< XclExpTabName > XclExpTabNameVec;
847 : :
848 : : inline bool operator<( const XclExpTabName& rArg1, const XclExpTabName& rArg2 )
849 : : {
850 : : // compare the sheet names only
851 : : return ScGlobal::GetCollator()->compareString( rArg1.first, rArg2.first ) == COMPARE_LESS;
852 : : }
853 : :
854 : 0 : void XclExpTabInfo::CalcSortedIndexes()
855 : : {
856 : 0 : ScDocument& rDoc = GetDoc();
857 [ # # ]: 0 : XclExpTabNameVec aVec( mnScCnt );
858 : : SCTAB nScTab;
859 : :
860 : : // fill with sheet names
861 [ # # ]: 0 : for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
862 : : {
863 [ # # ]: 0 : rDoc.GetName( nScTab, aVec[ nScTab ].first );
864 : 0 : aVec[ nScTab ].second = nScTab;
865 : : }
866 [ # # ]: 0 : ::std::sort( aVec.begin(), aVec.end() );
867 : :
868 : : // fill index vectors from sorted sheet name vector
869 [ # # ]: 0 : maFromSortedVec.resize( mnScCnt );
870 [ # # ]: 0 : maToSortedVec.resize( mnScCnt );
871 [ # # ]: 0 : for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
872 : : {
873 [ # # ]: 0 : maFromSortedVec[ nScTab ] = aVec[ nScTab ].second;
874 [ # # ]: 0 : maToSortedVec[ aVec[ nScTab ].second ] = nScTab;
875 : 0 : }
876 : 0 : }
877 : :
878 : : // External names =============================================================
879 : :
880 : 0 : XclExpExtNameBase::XclExpExtNameBase(
881 : : const XclExpRoot& rRoot, const String& rName, sal_uInt16 nFlags ) :
882 : : XclExpRecord( EXC_ID_EXTERNNAME ),
883 : : XclExpRoot( rRoot ),
884 : : maName( rName ),
885 : : mxName( XclExpStringHelper::CreateString( rRoot, rName, EXC_STR_8BITLENGTH ) ),
886 [ # # ][ # # ]: 0 : mnFlags( nFlags )
[ # # ]
887 : : {
888 : : OSL_ENSURE( maName.Len() <= 255, "XclExpExtNameBase::XclExpExtNameBase - string too long" );
889 [ # # ]: 0 : SetRecSize( 6 + mxName->GetSize() );
890 : 0 : }
891 : :
892 [ # # ][ # # ]: 0 : XclExpExtNameBase::~XclExpExtNameBase()
[ # # ]
893 : : {
894 [ # # ]: 0 : }
895 : :
896 : 0 : void XclExpExtNameBase::WriteBody( XclExpStream& rStrm )
897 : : {
898 : 0 : rStrm << mnFlags
899 : 0 : << sal_uInt32( 0 )
900 : 0 : << *mxName;
901 : 0 : WriteAddData( rStrm );
902 : 0 : }
903 : :
904 : 0 : void XclExpExtNameBase::WriteAddData( XclExpStream& /*rStrm*/ )
905 : : {
906 : 0 : }
907 : :
908 : : // ----------------------------------------------------------------------------
909 : :
910 : 0 : XclExpExtNameAddIn::XclExpExtNameAddIn( const XclExpRoot& rRoot, const String& rName ) :
911 : 0 : XclExpExtNameBase( rRoot, rName )
912 : : {
913 : 0 : AddRecSize( 4 );
914 : 0 : }
915 : :
916 : 0 : void XclExpExtNameAddIn::WriteAddData( XclExpStream& rStrm )
917 : : {
918 : : // write a #REF! error formula
919 : 0 : rStrm << sal_uInt16( 2 ) << EXC_TOKID_ERR << EXC_ERR_REF;
920 : 0 : }
921 : :
922 : : // ----------------------------------------------------------------------------
923 : :
924 : 0 : XclExpExtNameDde::XclExpExtNameDde( const XclExpRoot& rRoot,
925 : : const String& rName, sal_uInt16 nFlags, const ScMatrix* pResults ) :
926 [ # # ]: 0 : XclExpExtNameBase( rRoot, rName, nFlags )
927 : : {
928 [ # # ]: 0 : if( pResults )
929 : : {
930 [ # # ][ # # ]: 0 : mxMatrix.reset( new XclExpCachedMatrix( *pResults ) );
[ # # ]
931 [ # # ]: 0 : AddRecSize( mxMatrix->GetSize() );
932 : : }
933 : 0 : }
934 : :
935 : 0 : void XclExpExtNameDde::WriteAddData( XclExpStream& rStrm )
936 : : {
937 [ # # ]: 0 : if( mxMatrix )
938 : 0 : mxMatrix->Save( rStrm );
939 : 0 : }
940 : :
941 : : // ----------------------------------------------------------------------------
942 : :
943 : 0 : XclExpExtName::XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook,
944 : : const String& rName, const ScExternalRefCache::TokenArrayRef pArray ) :
945 : : XclExpExtNameBase( rRoot, rName ),
946 : : mrSupbook(rSupbook),
947 [ # # ]: 0 : mpArray(pArray->Clone())
948 : : {
949 : 0 : }
950 : :
951 : 0 : void XclExpExtName::WriteAddData( XclExpStream& rStrm )
952 : : {
953 : : // Write only if it only has a single token that is either a cell or cell
954 : : // range address. Excel just writes '02 00 1C 17' for all the other types
955 : : // of external names.
956 : :
957 : : using namespace ::formula;
958 : : do
959 : : {
960 [ # # ]: 0 : if (mpArray->GetLen() != 1)
961 : 0 : break;
962 : :
963 : 0 : const ScToken* p = static_cast<const ScToken*>(mpArray->First());
964 [ # # ]: 0 : if (!p->IsExternalRef())
965 : 0 : break;
966 : :
967 [ # # # ]: 0 : switch (p->GetType())
968 : : {
969 : : case svExternalSingleRef:
970 : : {
971 : 0 : const ScSingleRefData& rRef = p->GetSingleRef();
972 [ # # ]: 0 : if (rRef.IsTabRel())
973 : 0 : break;
974 : :
975 : 0 : bool bColRel = rRef.IsColRel();
976 : 0 : bool bRowRel = rRef.IsRowRel();
977 [ # # ]: 0 : sal_uInt16 nCol = static_cast< sal_uInt16 >( bColRel ? rRef.nRelCol : rRef.nCol );
978 [ # # ]: 0 : sal_uInt16 nRow = static_cast< sal_uInt16 >( bRowRel ? rRef.nRelRow : rRef.nRow );
979 [ # # ]: 0 : if (bColRel) nCol |= 0x4000;
980 [ # # ]: 0 : if (bRowRel) nCol |= 0x8000;
981 : :
982 : 0 : const String& rTabName = p->GetString();
983 : 0 : sal_uInt16 nSBTab = mrSupbook.GetTabIndex(rTabName);
984 : :
985 : : // size is always 9
986 : 0 : rStrm << static_cast<sal_uInt16>(9);
987 : : // operator token (3A for cell reference)
988 : 0 : rStrm << static_cast<sal_uInt8>(0x3A);
989 : : // cell address (Excel's address has 2 sheet IDs.)
990 : 0 : rStrm << nSBTab << nSBTab << nRow << nCol;
991 : 0 : return;
992 : : }
993 : : case svExternalDoubleRef:
994 : : {
995 : 0 : const ScComplexRefData& rRef = p->GetDoubleRef();
996 : 0 : const ScSingleRefData& r1 = rRef.Ref1;
997 : 0 : const ScSingleRefData& r2 = rRef.Ref2;
998 [ # # ][ # # ]: 0 : if (r1.IsTabRel() || r2.IsTabRel())
[ # # ]
999 : 0 : break;
1000 : :
1001 : 0 : sal_uInt16 nTab1 = r1.nTab;
1002 : 0 : sal_uInt16 nTab2 = r2.nTab;
1003 : 0 : bool bCol1Rel = r1.IsColRel();
1004 : 0 : bool bRow1Rel = r1.IsRowRel();
1005 : 0 : bool bCol2Rel = r2.IsColRel();
1006 : 0 : bool bRow2Rel = r2.IsRowRel();
1007 : :
1008 [ # # ]: 0 : sal_uInt16 nCol1 = static_cast< sal_uInt16 >( bCol1Rel ? r1.nRelCol : r1.nCol );
1009 [ # # ]: 0 : sal_uInt16 nCol2 = static_cast< sal_uInt16 >( bCol2Rel ? r2.nRelCol : r2.nCol );
1010 [ # # ]: 0 : sal_uInt16 nRow1 = static_cast< sal_uInt16 >( bRow1Rel ? r1.nRelRow : r1.nRow );
1011 [ # # ]: 0 : sal_uInt16 nRow2 = static_cast< sal_uInt16 >( bRow2Rel ? r2.nRelRow : r2.nRow );
1012 [ # # ]: 0 : if (bCol1Rel) nCol1 |= 0x4000;
1013 [ # # ]: 0 : if (bRow1Rel) nCol1 |= 0x8000;
1014 [ # # ]: 0 : if (bCol2Rel) nCol2 |= 0x4000;
1015 [ # # ]: 0 : if (bRow2Rel) nCol2 |= 0x8000;
1016 : :
1017 : 0 : const String& rTabName = p->GetString();
1018 : 0 : sal_uInt16 nSBTab = mrSupbook.GetTabIndex(rTabName);
1019 : :
1020 : : // size is always 13 (0x0D)
1021 : 0 : rStrm << static_cast<sal_uInt16>(13);
1022 : : // operator token (3B for area reference)
1023 : 0 : rStrm << static_cast<sal_uInt8>(0x3B);
1024 : : // range (area) address
1025 : 0 : sal_uInt16 nSBTab2 = nSBTab + nTab2 - nTab1;
1026 : 0 : rStrm << nSBTab << nSBTab2 << nRow1 << nRow2 << nCol1 << nCol2;
1027 : 0 : return;
1028 : : }
1029 : : default:
1030 : : ; // nothing
1031 : : }
1032 : : }
1033 : : while (false);
1034 : :
1035 : : // special value for #REF! (02 00 1C 17)
1036 : 0 : rStrm << static_cast<sal_uInt16>(2) << EXC_TOKID_ERR << EXC_ERR_REF;
1037 : : }
1038 : :
1039 : : // List of external names =====================================================
1040 : :
1041 : 0 : XclExpExtNameBuffer::XclExpExtNameBuffer( const XclExpRoot& rRoot ) :
1042 [ # # ][ # # ]: 0 : XclExpRoot( rRoot )
1043 : : {
1044 : 0 : }
1045 : :
1046 : 0 : sal_uInt16 XclExpExtNameBuffer::InsertAddIn( const String& rName )
1047 : : {
1048 : 0 : sal_uInt16 nIndex = GetIndex( rName );
1049 [ # # ][ # # ]: 0 : return nIndex ? nIndex : AppendNew( new XclExpExtNameAddIn( GetRoot(), rName ) );
1050 : : }
1051 : :
1052 : 0 : sal_uInt16 XclExpExtNameBuffer::InsertEuroTool( const String& rName )
1053 : : {
1054 : 0 : sal_uInt16 nIndex = GetIndex( rName );
1055 [ # # ][ # # ]: 0 : return nIndex ? nIndex : AppendNew( new XclExpExtNameBase( GetRoot(), rName ) );
1056 : : }
1057 : :
1058 : 0 : sal_uInt16 XclExpExtNameBuffer::InsertDde(
1059 : : const String& rApplic, const String& rTopic, const String& rItem )
1060 : : {
1061 : 0 : sal_uInt16 nIndex = GetIndex( rItem );
1062 [ # # ]: 0 : if( nIndex == 0 )
1063 : : {
1064 : : sal_uInt16 nPos;
1065 [ # # ][ # # ]: 0 : if( GetDoc().FindDdeLink( rApplic, rTopic, rItem, SC_DDE_IGNOREMODE, nPos ) )
[ # # ][ # # ]
[ # # ]
1066 : : {
1067 : : // create the leading 'StdDocumentName' EXTERNNAME record
1068 [ # # ]: 0 : if( maNameList.IsEmpty() )
1069 : : AppendNew( new XclExpExtNameDde(
1070 [ # # ][ # # ]: 0 : GetRoot(), CREATE_STRING( "StdDocumentName" ), EXC_EXTN_EXPDDE_STDDOC ) );
[ # # ][ # # ]
[ # # ]
1071 : :
1072 : : // try to find DDE result array, but create EXTERNNAME record without them too
1073 [ # # ]: 0 : const ScMatrix* pScMatrix = GetDoc().GetDdeLinkResultMatrix( nPos );
1074 [ # # ][ # # ]: 0 : nIndex = AppendNew( new XclExpExtNameDde( GetRoot(), rItem, EXC_EXTN_EXPDDE, pScMatrix ) );
[ # # ]
1075 : : }
1076 : : }
1077 : 0 : return nIndex;
1078 : : }
1079 : :
1080 : 0 : sal_uInt16 XclExpExtNameBuffer::InsertExtName( const XclExpSupbook& rSupbook,
1081 : : const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
1082 : : {
1083 : 0 : sal_uInt16 nIndex = GetIndex( rName );
1084 [ # # ][ # # ]: 0 : return nIndex ? nIndex : AppendNew( new XclExpExtName( GetRoot(), rSupbook, rName, pArray ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1085 : : }
1086 : :
1087 : 0 : void XclExpExtNameBuffer::Save( XclExpStream& rStrm )
1088 : : {
1089 : 0 : maNameList.Save( rStrm );
1090 : 0 : }
1091 : :
1092 : 0 : sal_uInt16 XclExpExtNameBuffer::GetIndex( const String& rName ) const
1093 : : {
1094 [ # # ]: 0 : for( size_t nPos = 0, nSize = maNameList.GetSize(); nPos < nSize; ++nPos )
1095 [ # # ][ # # ]: 0 : if( maNameList.GetRecord( nPos )->GetName() == rName )
1096 : 0 : return static_cast< sal_uInt16 >( nPos + 1 );
1097 : 0 : return 0;
1098 : : }
1099 : :
1100 : 0 : sal_uInt16 XclExpExtNameBuffer::AppendNew( XclExpExtNameBase* pExtName )
1101 : : {
1102 [ # # ]: 0 : XclExpExtNameRef xExtName( pExtName );
1103 : 0 : size_t nSize = maNameList.GetSize();
1104 [ # # ]: 0 : if( nSize < 0x7FFF )
1105 : : {
1106 [ # # ][ # # ]: 0 : maNameList.AppendRecord( xExtName );
[ # # ]
1107 : 0 : return static_cast< sal_uInt16 >( nSize + 1 );
1108 : : }
1109 [ # # ]: 0 : return 0;
1110 : : }
1111 : :
1112 : : // Cached external cells ======================================================
1113 : :
1114 : 0 : XclExpCrn::XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue ) :
1115 : : XclExpRecord( EXC_ID_CRN, 4 ),
1116 : : mnScCol( nScCol ),
1117 [ # # ]: 0 : mnScRow( nScRow )
1118 : : {
1119 [ # # ]: 0 : maValues.push_back( rValue );
1120 : 0 : }
1121 : :
1122 : 0 : bool XclExpCrn::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue )
1123 : : {
1124 [ # # ][ # # ]: 0 : if( (nScRow != mnScRow) || (nScCol != static_cast< SCCOL >( mnScCol + maValues.size() )) )
[ # # ]
1125 : 0 : return false;
1126 : 0 : maValues.push_back( rValue );
1127 : 0 : return true;
1128 : : }
1129 : :
1130 : 0 : void XclExpCrn::WriteBody( XclExpStream& rStrm )
1131 : : {
1132 : 0 : rStrm << static_cast< sal_uInt8 >( mnScCol + maValues.size() - 1 )
1133 : 0 : << static_cast< sal_uInt8 >( mnScCol )
1134 : 0 : << static_cast< sal_uInt16 >( mnScRow );
1135 [ # # ][ # # ]: 0 : for( CachedValues::iterator aIt = maValues.begin(), aEnd = maValues.end(); aIt != aEnd; ++aIt )
1136 : : {
1137 [ # # ][ # # ]: 0 : if( aIt->has< bool >() )
1138 [ # # ][ # # ]: 0 : WriteBool( rStrm, aIt->get< bool >() );
1139 [ # # ][ # # ]: 0 : else if( aIt->has< double >() )
1140 [ # # ][ # # ]: 0 : WriteDouble( rStrm, aIt->get< double >() );
1141 [ # # ][ # # ]: 0 : else if( aIt->has< OUString >() )
1142 [ # # ][ # # ]: 0 : WriteString( rStrm, aIt->get< OUString >() );
1143 : : else
1144 [ # # ]: 0 : WriteEmpty( rStrm );
1145 : : }
1146 : 0 : }
1147 : :
1148 : 0 : void XclExpCrn::WriteBool( XclExpStream& rStrm, bool bValue )
1149 : : {
1150 [ # # ]: 0 : rStrm << EXC_CACHEDVAL_BOOL << sal_uInt8( bValue ? 1 : 0);
1151 : 0 : rStrm.WriteZeroBytes( 7 );
1152 : 0 : }
1153 : :
1154 : 0 : void XclExpCrn::WriteDouble( XclExpStream& rStrm, double fValue )
1155 : : {
1156 [ # # ]: 0 : if( ::rtl::math::isNan( fValue ) )
1157 : : {
1158 : 0 : sal_uInt16 nScError = static_cast< sal_uInt16 >( reinterpret_cast< const sal_math_Double* >( &fValue )->nan_parts.fraction_lo );
1159 : 0 : WriteError( rStrm, XclTools::GetXclErrorCode( nScError ) );
1160 : : }
1161 : : else
1162 : : {
1163 : 0 : rStrm << EXC_CACHEDVAL_DOUBLE << fValue;
1164 : : }
1165 : 0 : }
1166 : :
1167 : 0 : void XclExpCrn::WriteString( XclExpStream& rStrm, const OUString& rValue )
1168 : : {
1169 [ # # ][ # # ]: 0 : rStrm << EXC_CACHEDVAL_STRING << XclExpString( rValue );
1170 : 0 : }
1171 : :
1172 : 0 : void XclExpCrn::WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode )
1173 : : {
1174 : 0 : rStrm << EXC_CACHEDVAL_ERROR << nErrCode;
1175 : 0 : rStrm.WriteZeroBytes( 7 );
1176 : 0 : }
1177 : :
1178 : 0 : void XclExpCrn::WriteEmpty( XclExpStream& rStrm )
1179 : : {
1180 : 0 : rStrm << EXC_CACHEDVAL_EMPTY;
1181 : 0 : rStrm.WriteZeroBytes( 8 );
1182 : 0 : }
1183 : :
1184 : : // Cached cells of a sheet ====================================================
1185 : :
1186 : 0 : XclExpXct::XclExpXct( const XclExpRoot& rRoot, const String& rTabName,
1187 : : sal_uInt16 nSBTab, ScExternalRefCache::TableTypeRef xCacheTable ) :
1188 : : XclExpRoot( rRoot ),
1189 : : mxCacheTable( xCacheTable ),
1190 : : maBoundRange( ScAddress::INITIALIZE_INVALID ),
1191 : : maTabName( rTabName ),
1192 [ # # ][ # # ]: 0 : mnSBTab( nSBTab )
[ # # ][ # # ]
1193 : : {
1194 : 0 : }
1195 : :
1196 : 0 : void XclExpXct::StoreCellRange( const ScRange& rRange )
1197 : : {
1198 : : // #i70418# restrict size of external range to prevent memory overflow
1199 [ # # ]: 0 : if( (rRange.aEnd.Col() - rRange.aStart.Col()) * (rRange.aEnd.Row() - rRange.aStart.Row()) > 1024 )
1200 : 0 : return;
1201 : :
1202 : 0 : maUsedCells.SetMultiMarkArea( rRange );
1203 : 0 : maBoundRange.ExtendTo( rRange );
1204 : : }
1205 : :
1206 : 0 : void XclExpXct::StoreCell( const ScAddress& rCell, const ::formula::FormulaToken& rToken )
1207 : : {
1208 [ # # ]: 0 : maUsedCells.SetMultiMarkArea( ScRange( rCell ) );
1209 [ # # ]: 0 : maBoundRange.ExtendTo( ScRange( rCell ) );
1210 : : (void)rToken;
1211 : 0 : }
1212 : :
1213 : 0 : void XclExpXct::StoreCellRange( const ScRange& rRange, const ::formula::FormulaToken& rToken )
1214 : : {
1215 : 0 : maUsedCells.SetMultiMarkArea( rRange );
1216 : 0 : maBoundRange.ExtendTo( rRange );
1217 : : (void)rToken;
1218 : 0 : }
1219 : :
1220 : : namespace {
1221 : :
1222 [ # # ]: 0 : class XclExpCrnList : public XclExpRecordList< XclExpCrn >
1223 : : {
1224 : : public:
1225 : : /** Inserts the passed value into an existing or new CRN record.
1226 : : @return True = value inserted successfully, false = CRN list is full. */
1227 : : bool InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue );
1228 : : };
1229 : :
1230 : 0 : bool XclExpCrnList::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue )
1231 : : {
1232 [ # # ]: 0 : RecordRefType xLastRec = GetLastRecord();
1233 [ # # ][ # # ]: 0 : if( xLastRec && xLastRec->InsertValue( nScCol, nScRow, rValue ) )
[ # # ][ # # ]
1234 : 0 : return true;
1235 [ # # ]: 0 : if( GetSize() == SAL_MAX_UINT16 )
1236 : 0 : return false;
1237 [ # # ][ # # ]: 0 : AppendNewRecord( new XclExpCrn( nScCol, nScRow, rValue ) );
[ # # ]
1238 [ # # ]: 0 : return true;
1239 : : }
1240 : :
1241 : : } // namespace
1242 : :
1243 : 0 : void XclExpXct::Save( XclExpStream& rStrm )
1244 : : {
1245 [ # # ]: 0 : if( !mxCacheTable )
1246 : : return;
1247 : :
1248 : : /* Get the range of used rows in the cache table. This may help to
1249 : : optimize building the CRN record list if the cache table does not
1250 : : contain all referred cells, e.g. if big empty ranges are used in the
1251 : : formulas. */
1252 [ # # ]: 0 : ::std::pair< SCROW, SCROW > aRowRange = mxCacheTable->getRowRange();
1253 [ # # ]: 0 : if( aRowRange.first >= aRowRange.second )
1254 : : return;
1255 : :
1256 : : /* Crop the bounding range of used cells in this table to Excel limits.
1257 : : Return if there is no external cell inside these limits. */
1258 [ # # ][ # # ]: 0 : if( !GetAddressConverter().ValidateRange( maBoundRange, false ) )
[ # # ]
1259 : : return;
1260 : :
1261 : : /* Find the resulting row range that needs to be processed. */
1262 [ # # ]: 0 : SCROW nScRow1 = ::std::max( aRowRange.first, maBoundRange.aStart.Row() );
1263 [ # # ]: 0 : SCROW nScRow2 = ::std::min( aRowRange.second - 1, maBoundRange.aEnd.Row() );
1264 [ # # ]: 0 : if( nScRow1 > nScRow2 )
1265 : : return;
1266 : :
1267 : : /* Build and collect all CRN records before writing the XCT record. This
1268 : : is needed to determine the total number of CRN records which must be
1269 : : known when writing the XCT record (possibly encrypted, so seeking the
1270 : : output strem back after writing the CRN records is not an option). */
1271 [ # # ]: 0 : XclExpCrnList aCrnRecs;
1272 [ # # ]: 0 : SvNumberFormatter& rFormatter = GetFormatter();
1273 : 0 : bool bValid = true;
1274 [ # # ][ # # ]: 0 : for( SCROW nScRow = nScRow1; bValid && (nScRow <= nScRow2); ++nScRow )
[ # # ]
1275 : : {
1276 [ # # ]: 0 : ::std::pair< SCCOL, SCCOL > aColRange = mxCacheTable->getColRange( nScRow );
1277 [ # # ][ # # ]: 0 : for( SCCOL nScCol = aColRange.first; bValid && (nScCol < aColRange.second); ++nScCol )
[ # # ]
1278 : : {
1279 [ # # ][ # # ]: 0 : if( maUsedCells.IsCellMarked( nScCol, nScRow, sal_True ) )
1280 : : {
1281 : 0 : sal_uInt32 nScNumFmt = 0;
1282 [ # # ]: 0 : ScExternalRefCache::TokenRef xToken = mxCacheTable->getCell( nScCol, nScRow, &nScNumFmt );
1283 : : using namespace ::formula;
1284 [ # # ]: 0 : if( xToken.get() ) switch( xToken->GetType() )
[ # # # ]
1285 : : {
1286 : : case svDouble:
1287 [ # # ]: 0 : bValid = (rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL) ?
1288 [ # # ][ # # ]: 0 : aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() != 0 ) ) :
[ # # ][ # # ]
1289 [ # # ][ # # ]: 0 : aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
1290 : 0 : break;
1291 : : case svString:
1292 : : // do not save empty strings (empty cells) to cache
1293 [ # # ][ # # ]: 0 : if( xToken->GetString().Len() > 0 )
1294 [ # # ][ # # ]: 0 : bValid = aCrnRecs.InsertValue( nScCol, nScRow, Any( OUString( xToken->GetString() ) ) );
[ # # ][ # # ]
1295 : 0 : break;
1296 : : default:
1297 : 0 : break;
1298 [ # # ]: 0 : }
1299 : : }
1300 : : }
1301 : : }
1302 : :
1303 : : // write the XCT record and the list of CRN records
1304 [ # # ]: 0 : rStrm.StartRecord( EXC_ID_XCT, 4 );
1305 [ # # ][ # # ]: 0 : rStrm << static_cast< sal_uInt16 >( aCrnRecs.GetSize() ) << mnSBTab;
1306 [ # # ]: 0 : rStrm.EndRecord();
1307 [ # # ][ # # ]: 0 : aCrnRecs.Save( rStrm );
1308 : : }
1309 : :
1310 : : // External documents (EXTERNSHEET/SUPBOOK), base class =======================
1311 : :
1312 : 0 : XclExpExternSheetBase::XclExpExternSheetBase( const XclExpRoot& rRoot, sal_uInt16 nRecId, sal_uInt32 nRecSize ) :
1313 : : XclExpRecord( nRecId, nRecSize ),
1314 [ # # ][ # # ]: 0 : XclExpRoot( rRoot )
1315 : : {
1316 : 0 : }
1317 : :
1318 : 0 : XclExpExtNameBuffer& XclExpExternSheetBase::GetExtNameBuffer()
1319 : : {
1320 [ # # ]: 0 : if( !mxExtNameBfr )
1321 [ # # ]: 0 : mxExtNameBfr.reset( new XclExpExtNameBuffer( GetRoot() ) );
1322 : 0 : return *mxExtNameBfr;
1323 : : }
1324 : :
1325 : 0 : void XclExpExternSheetBase::WriteExtNameBuffer( XclExpStream& rStrm )
1326 : : {
1327 [ # # ]: 0 : if( mxExtNameBfr )
1328 : 0 : mxExtNameBfr->Save( rStrm );
1329 : 0 : }
1330 : :
1331 : : // External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
1332 : :
1333 : 0 : XclExpExternSheet::XclExpExternSheet( const XclExpRoot& rRoot, sal_Unicode cCode ) :
1334 [ # # ]: 0 : XclExpExternSheetBase( rRoot, EXC_ID_EXTERNSHEET )
1335 : : {
1336 [ # # ][ # # ]: 0 : Init( rtl::OUString(cCode) );
[ # # ]
1337 : 0 : }
1338 : :
1339 : 0 : XclExpExternSheet::XclExpExternSheet( const XclExpRoot& rRoot, const String& rTabName ) :
1340 [ # # ]: 0 : XclExpExternSheetBase( rRoot, EXC_ID_EXTERNSHEET )
1341 : : {
1342 : : // reference to own sheet: \03<sheetname>
1343 [ # # ][ # # ]: 0 : Init(rtl::OUString(EXC_EXTSH_TABNAME) + rTabName);
[ # # ][ # # ]
1344 : 0 : }
1345 : :
1346 : 0 : void XclExpExternSheet::Save( XclExpStream& rStrm )
1347 : : {
1348 : : // EXTERNSHEET record
1349 : 0 : XclExpRecord::Save( rStrm );
1350 : : // EXTERNNAME records
1351 : 0 : WriteExtNameBuffer( rStrm );
1352 : 0 : }
1353 : :
1354 : 0 : void XclExpExternSheet::Init( const String& rEncUrl )
1355 : : {
1356 : : OSL_ENSURE_BIFF( GetBiff() <= EXC_BIFF5 );
1357 : 0 : maTabName.AssignByte( rEncUrl, GetTextEncoding(), EXC_STR_8BITLENGTH );
1358 : 0 : SetRecSize( maTabName.GetSize() );
1359 : 0 : }
1360 : :
1361 : 0 : sal_uInt16 XclExpExternSheet::InsertAddIn( const String& rName )
1362 : : {
1363 : 0 : return GetExtNameBuffer().InsertAddIn( rName );
1364 : : }
1365 : :
1366 : 0 : void XclExpExternSheet::WriteBody( XclExpStream& rStrm )
1367 : : {
1368 : 0 : sal_uInt8 nNameSize = static_cast< sal_uInt8 >( maTabName.Len() );
1369 : : // special case: reference to own sheet (starting with '\03') needs wrong string length
1370 [ # # ]: 0 : if( maTabName.GetChar( 0 ) == EXC_EXTSH_TABNAME )
1371 : 0 : --nNameSize;
1372 : 0 : rStrm << nNameSize;
1373 : 0 : maTabName.WriteBuffer( rStrm );
1374 : 0 : }
1375 : :
1376 : : // External document (SUPBOOK, BIFF8) =========================================
1377 : :
1378 : 0 : XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, sal_uInt16 nXclTabCount ) :
1379 : : XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
1380 : : meType( EXC_SBTYPE_SELF ),
1381 [ # # ][ # # ]: 0 : mnXclTabCount( nXclTabCount )
[ # # ][ # # ]
1382 : : {
1383 : 0 : }
1384 : :
1385 : 0 : XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot ) :
1386 : : XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
1387 : : meType( EXC_SBTYPE_ADDIN ),
1388 [ # # ][ # # ]: 0 : mnXclTabCount( 1 )
[ # # ][ # # ]
1389 : : {
1390 : 0 : }
1391 : :
1392 : 0 : XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl, XclSupbookType ) :
1393 : : XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK ),
1394 : : maUrl( rUrl ),
1395 : : maUrlEncoded( rUrl ),
1396 : : meType( EXC_SBTYPE_EUROTOOL ),
1397 [ # # ][ # # ]: 0 : mnXclTabCount( 0 )
[ # # ][ # # ]
1398 : : {
1399 [ # # ]: 0 : SetRecSize( 2 + maUrlEncoded.GetSize() );
1400 : 0 : }
1401 : :
1402 : :
1403 : 0 : XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl ) :
1404 : : XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK ),
1405 : : maUrl( rUrl ),
1406 : : maUrlEncoded( XclExpUrlHelper::EncodeUrl( rRoot, rUrl ) ),
1407 : : meType( EXC_SBTYPE_EXTERN ),
1408 [ # # ][ # # ]: 0 : mnXclTabCount( 0 )
[ # # ][ # # ]
[ # # ][ # # ]
1409 : : {
1410 [ # # ]: 0 : SetRecSize( 2 + maUrlEncoded.GetSize() );
1411 : :
1412 : : // We need to create all tables up front to ensure the correct table order.
1413 [ # # ]: 0 : ScExternalRefManager* pRefMgr = rRoot.GetDoc().GetExternalRefManager();
1414 [ # # ][ # # ]: 0 : sal_uInt16 nFileId = pRefMgr->getExternalFileId( rUrl );
1415 [ # # ]: 0 : ScfStringVec aTabNames;
1416 [ # # ]: 0 : pRefMgr->getAllCachedTableNames( nFileId, aTabNames );
1417 [ # # ][ # # ]: 0 : for( ScfStringVec::const_iterator aBeg = aTabNames.begin(), aIt = aBeg, aEnd = aTabNames.end(); aIt != aEnd; ++aIt )
[ # # ][ # # ]
1418 [ # # ][ # # ]: 0 : InsertTabName( *aIt, pRefMgr->getCacheTable( nFileId, aIt - aBeg ) );
[ # # ][ # # ]
[ # # ][ # # ]
1419 : 0 : }
1420 : :
1421 : 0 : XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rApplic, const String& rTopic ) :
1422 : : XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
1423 : : maUrl( rApplic ),
1424 : : maDdeTopic( rTopic ),
1425 : : maUrlEncoded( XclExpUrlHelper::EncodeDde( rApplic, rTopic ) ),
1426 : : meType( EXC_SBTYPE_SPECIAL ),
1427 [ # # ][ # # ]: 0 : mnXclTabCount( 0 )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1428 : : {
1429 [ # # ]: 0 : SetRecSize( 2 + maUrlEncoded.GetSize() );
1430 : 0 : }
1431 : :
1432 : 0 : bool XclExpSupbook::IsUrlLink( const String& rUrl ) const
1433 : : {
1434 [ # # ][ # # ]: 0 : return (meType == EXC_SBTYPE_EXTERN || meType == EXC_SBTYPE_EUROTOOL) && (maUrl == rUrl);
[ # # ]
1435 : : }
1436 : :
1437 : 0 : bool XclExpSupbook::IsDdeLink( const String& rApplic, const String& rTopic ) const
1438 : : {
1439 [ # # ][ # # ]: 0 : return (meType == EXC_SBTYPE_SPECIAL) && (maUrl == rApplic) && (maDdeTopic == rTopic);
[ # # ]
1440 : : }
1441 : :
1442 : 0 : void XclExpSupbook::FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry,
1443 : : sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) const
1444 : : {
1445 [ # # ]: 0 : rRefLogEntry.mpUrl = maUrlEncoded.IsEmpty() ? 0 : &maUrlEncoded;
1446 : 0 : rRefLogEntry.mpFirstTab = GetTabName( nFirstSBTab );
1447 : 0 : rRefLogEntry.mpLastTab = GetTabName( nLastSBTab );
1448 : 0 : }
1449 : :
1450 : 0 : void XclExpSupbook::StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab )
1451 : : {
1452 [ # # ]: 0 : if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
1453 : 0 : pXct->StoreCellRange( rRange );
1454 : 0 : }
1455 : :
1456 : 0 : void XclExpSupbook::StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const formula::FormulaToken& rToken )
1457 : : {
1458 [ # # ]: 0 : if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
1459 : 0 : pXct->StoreCell( rCell, rToken );
1460 : 0 : }
1461 : :
1462 : 0 : void XclExpSupbook::StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const formula::FormulaToken& rToken )
1463 : : {
1464 : : // multi-table range is not allowed!
1465 [ # # ]: 0 : if( rRange.aStart.Tab() == rRange.aEnd.Tab() )
1466 [ # # ]: 0 : if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
1467 : 0 : pXct->StoreCellRange( rRange, rToken );
1468 : 0 : }
1469 : :
1470 : 0 : sal_uInt16 XclExpSupbook::GetTabIndex( const String& rTabName ) const
1471 : : {
1472 [ # # ]: 0 : XclExpString aXclName(rTabName);
1473 : 0 : size_t nSize = maXctList.GetSize();
1474 [ # # ]: 0 : for (size_t i = 0; i < nSize; ++i)
1475 : : {
1476 [ # # ]: 0 : XclExpXctRef aRec = maXctList.GetRecord(i);
1477 [ # # ][ # # ]: 0 : if (aXclName == aRec->GetTabName())
1478 [ # # ]: 0 : return ulimit_cast<sal_uInt16>(i);
1479 [ # # ][ # # ]: 0 : }
1480 : 0 : return EXC_NOTAB;
1481 : : }
1482 : :
1483 : 0 : sal_uInt16 XclExpSupbook::GetTabCount() const
1484 : : {
1485 : 0 : return ulimit_cast<sal_uInt16>(maXctList.GetSize());
1486 : : }
1487 : :
1488 : 0 : sal_uInt16 XclExpSupbook::InsertTabName( const String& rTabName, ScExternalRefCache::TableTypeRef xCacheTable )
1489 : : {
1490 : : OSL_ENSURE( meType == EXC_SBTYPE_EXTERN, "XclExpSupbook::InsertTabName - don't insert sheet names here" );
1491 [ # # ]: 0 : sal_uInt16 nSBTab = ulimit_cast< sal_uInt16 >( maXctList.GetSize() );
1492 [ # # ][ # # ]: 0 : XclExpXctRef xXct( new XclExpXct( GetRoot(), rTabName, nSBTab, xCacheTable ) );
[ # # ][ # # ]
[ # # ]
1493 [ # # ]: 0 : AddRecSize( xXct->GetTabName().GetSize() );
1494 [ # # ][ # # ]: 0 : maXctList.AppendRecord( xXct );
[ # # ]
1495 [ # # ]: 0 : return nSBTab;
1496 : : }
1497 : :
1498 : 0 : sal_uInt16 XclExpSupbook::InsertAddIn( const String& rName )
1499 : : {
1500 : 0 : return GetExtNameBuffer().InsertAddIn( rName );
1501 : : }
1502 : :
1503 : 0 : sal_uInt16 XclExpSupbook::InsertEuroTool( const String& rName )
1504 : : {
1505 : 0 : return GetExtNameBuffer().InsertEuroTool( rName );
1506 : : }
1507 : :
1508 : 0 : sal_uInt16 XclExpSupbook::InsertDde( const String& rItem )
1509 : : {
1510 : 0 : return GetExtNameBuffer().InsertDde( maUrl, maDdeTopic, rItem );
1511 : : }
1512 : :
1513 : 0 : sal_uInt16 XclExpSupbook::InsertExtName( const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
1514 : : {
1515 [ # # ][ # # ]: 0 : return GetExtNameBuffer().InsertExtName(*this, rName, pArray);
1516 : : }
1517 : :
1518 : 0 : void XclExpSupbook::Save( XclExpStream& rStrm )
1519 : : {
1520 : : // SUPBOOK record
1521 : 0 : XclExpRecord::Save( rStrm );
1522 : : // XCT record, CRN records
1523 : 0 : maXctList.Save( rStrm );
1524 : : // EXTERNNAME records
1525 : 0 : WriteExtNameBuffer( rStrm );
1526 : 0 : }
1527 : :
1528 : 0 : const XclExpString* XclExpSupbook::GetTabName( sal_uInt16 nSBTab ) const
1529 : : {
1530 [ # # ]: 0 : XclExpXctRef xXct = maXctList.GetRecord( nSBTab );
1531 [ # # ][ # # ]: 0 : return xXct ? &xXct->GetTabName() : 0;
1532 : : }
1533 : :
1534 : 0 : void XclExpSupbook::WriteBody( XclExpStream& rStrm )
1535 : : {
1536 [ # # # # ]: 0 : switch( meType )
1537 : : {
1538 : : case EXC_SBTYPE_SELF:
1539 : 0 : rStrm << mnXclTabCount << EXC_SUPB_SELF;
1540 : 0 : break;
1541 : : case EXC_SBTYPE_EXTERN:
1542 : : case EXC_SBTYPE_SPECIAL:
1543 : : case EXC_SBTYPE_EUROTOOL:
1544 : : {
1545 : 0 : sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maXctList.GetSize() );
1546 : 0 : rStrm << nCount << maUrlEncoded;
1547 : :
1548 [ # # ]: 0 : for( size_t nPos = 0, nSize = maXctList.GetSize(); nPos < nSize; ++nPos )
1549 [ # # ]: 0 : rStrm << maXctList.GetRecord( nPos )->GetTabName();
1550 : : }
1551 : 0 : break;
1552 : : case EXC_SBTYPE_ADDIN:
1553 : 0 : rStrm << mnXclTabCount << EXC_SUPB_ADDIN;
1554 : 0 : break;
1555 : : default:
1556 : : OSL_FAIL( "XclExpSupbook::WriteBody - unknown SUPBOOK type" );
1557 : : }
1558 : 0 : }
1559 : :
1560 : : // All SUPBOOKS in a document =================================================
1561 : :
1562 : 0 : XclExpSupbookBuffer::XclExpSupbookBuffer( const XclExpRoot& rRoot ) :
1563 : : XclExpRoot( rRoot ),
1564 : : mnOwnDocSB( SAL_MAX_UINT16 ),
1565 [ # # ][ # # ]: 0 : mnAddInSB( SAL_MAX_UINT16 )
[ # # ]
1566 : : {
1567 [ # # ]: 0 : XclExpTabInfo& rTabInfo = GetTabInfo();
1568 : 0 : sal_uInt16 nXclCnt = rTabInfo.GetXclTabCount();
1569 [ # # ][ # # ]: 0 : sal_uInt16 nCodeCnt = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
1570 : 0 : size_t nCount = nXclCnt + rTabInfo.GetXclExtTabCount();
1571 : :
1572 : : OSL_ENSURE( nCount > 0, "XclExpSupbookBuffer::XclExpSupbookBuffer - no sheets to export" );
1573 [ # # ]: 0 : if( nCount )
1574 : : {
1575 [ # # ]: 0 : maSBIndexVec.resize( nCount );
1576 : :
1577 : : // self-ref SUPBOOK first of list
1578 [ # # ][ # # ]: 0 : XclExpSupbookRef xSupbook( new XclExpSupbook( GetRoot(), ::std::max( nXclCnt, nCodeCnt ) ) );
[ # # ][ # # ]
1579 [ # # ][ # # ]: 0 : mnOwnDocSB = Append( xSupbook );
[ # # ]
1580 [ # # ]: 0 : for( sal_uInt16 nXclTab = 0; nXclTab < nXclCnt; ++nXclTab )
1581 [ # # ]: 0 : maSBIndexVec[ nXclTab ].Set( mnOwnDocSB, nXclTab );
1582 : : }
1583 : 0 : }
1584 : :
1585 : 0 : XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
1586 : : XclExpRefLogEntry* pRefLogEntry ) const
1587 : : {
1588 : 0 : XclExpXti aXti;
1589 : 0 : size_t nSize = maSBIndexVec.size();
1590 [ # # ][ # # ]: 0 : if( (nFirstXclTab < nSize) && (nLastXclTab < nSize) )
1591 : : {
1592 : : // index of the SUPBOOK record
1593 : 0 : aXti.mnSupbook = maSBIndexVec[ nFirstXclTab ].mnSupbook;
1594 : :
1595 : : // all sheets in the same supbook?
1596 : 0 : bool bSameSB = true;
1597 [ # # ][ # # ]: 0 : for( sal_uInt16 nXclTab = nFirstXclTab + 1; bSameSB && (nXclTab <= nLastXclTab); ++nXclTab )
[ # # ]
1598 : : {
1599 : 0 : bSameSB = maSBIndexVec[ nXclTab ].mnSupbook == aXti.mnSupbook;
1600 [ # # ]: 0 : if( !bSameSB )
1601 : 0 : nLastXclTab = nXclTab - 1;
1602 : : }
1603 : 0 : aXti.mnFirstSBTab = maSBIndexVec[ nFirstXclTab ].mnSBTab;
1604 : 0 : aXti.mnLastSBTab = maSBIndexVec[ nLastXclTab ].mnSBTab;
1605 : :
1606 : : // fill external reference log entry (for change tracking)
1607 [ # # ]: 0 : if( pRefLogEntry )
1608 : : {
1609 : 0 : pRefLogEntry->mnFirstXclTab = nFirstXclTab;
1610 : 0 : pRefLogEntry->mnLastXclTab = nLastXclTab;
1611 [ # # ]: 0 : XclExpSupbookRef xSupbook = maSupbookList.GetRecord( aXti.mnSupbook );
1612 [ # # ]: 0 : if( xSupbook )
1613 [ # # ][ # # ]: 0 : xSupbook->FillRefLogEntry( *pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab );
1614 : 0 : }
1615 : : }
1616 : : else
1617 : : {
1618 : : // special range, i.e. for deleted sheets or add-ins
1619 : 0 : aXti.mnSupbook = mnOwnDocSB;
1620 : 0 : aXti.mnFirstSBTab = nFirstXclTab;
1621 : 0 : aXti.mnLastSBTab = nLastXclTab;
1622 : : }
1623 : :
1624 : 0 : return aXti;
1625 : : }
1626 : :
1627 : 0 : void XclExpSupbookBuffer::StoreCellRange( const ScRange& rRange )
1628 : : {
1629 : 0 : sal_uInt16 nXclTab = GetTabInfo().GetXclTab( rRange.aStart.Tab() );
1630 [ # # ]: 0 : if( nXclTab < maSBIndexVec.size() )
1631 : : {
1632 : 0 : const XclExpSBIndex& rSBIndex = maSBIndexVec[ nXclTab ];
1633 [ # # ]: 0 : XclExpSupbookRef xSupbook = maSupbookList.GetRecord( rSBIndex.mnSupbook );
1634 : : OSL_ENSURE( xSupbook , "XclExpSupbookBuffer::StoreCellRange - missing SUPBOOK record" );
1635 [ # # ]: 0 : if( xSupbook )
1636 [ # # ][ # # ]: 0 : xSupbook->StoreCellRange( rRange, rSBIndex.mnSBTab );
1637 : : }
1638 : 0 : }
1639 : :
1640 : : namespace {
1641 : :
1642 : : class FindSBIndexEntry
1643 : : {
1644 : : public:
1645 : 0 : explicit FindSBIndexEntry(sal_uInt16 nSupbookId, sal_uInt16 nTabId) :
1646 : 0 : mnSupbookId(nSupbookId), mnTabId(nTabId) {}
1647 : :
1648 : 0 : bool operator()(const XclExpSupbookBuffer::XclExpSBIndex& r) const
1649 : : {
1650 [ # # ][ # # ]: 0 : return mnSupbookId == r.mnSupbook && mnTabId == r.mnSBTab;
1651 : : }
1652 : :
1653 : : private:
1654 : : sal_uInt16 mnSupbookId;
1655 : : sal_uInt16 mnTabId;
1656 : : };
1657 : :
1658 : : }
1659 : :
1660 : 0 : void XclExpSupbookBuffer::StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell )
1661 : : {
1662 [ # # ]: 0 : ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
1663 [ # # ]: 0 : const OUString* pUrl = pRefMgr->getExternalFileName(nFileId);
1664 [ # # ]: 0 : if (!pUrl)
1665 : : return;
1666 : :
1667 [ # # ]: 0 : XclExpSupbookRef xSupbook;
1668 : : sal_uInt16 nSupbookId;
1669 [ # # ][ # # ]: 0 : if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
[ # # ][ # # ]
1670 : : {
1671 [ # # ][ # # ]: 0 : xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
[ # # ][ # # ]
[ # # ]
1672 [ # # ][ # # ]: 0 : nSupbookId = Append(xSupbook);
[ # # ]
1673 : : }
1674 : :
1675 [ # # ][ # # ]: 0 : ScExternalRefCache::TokenRef pToken = pRefMgr->getSingleRefToken(nFileId, rTabName, rCell, NULL, NULL);
1676 [ # # ]: 0 : if (!pToken.get())
1677 : : return;
1678 : :
1679 [ # # ]: 0 : sal_uInt16 nSheetId = xSupbook->GetTabIndex(rTabName);
1680 [ # # ]: 0 : if (nSheetId == EXC_NOTAB)
1681 : : // specified table name not found in this SUPBOOK.
1682 : : return;
1683 : :
1684 : 0 : FindSBIndexEntry f(nSupbookId, nSheetId);
1685 : 0 : XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
1686 [ # # ][ # # ]: 0 : XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
1687 [ # # ][ # # ]: 0 : if (itr == itrEnd)
1688 : : {
1689 [ # # ]: 0 : maSBIndexVec.push_back(XclExpSBIndex());
1690 [ # # ]: 0 : XclExpSBIndex& r = maSBIndexVec.back();
1691 : 0 : r.mnSupbook = nSupbookId;
1692 : 0 : r.mnSBTab = nSheetId;
1693 : : }
1694 : :
1695 [ # # ][ # # ]: 0 : xSupbook->StoreCell(nSheetId, rCell, *pToken);
[ # # ][ # # ]
[ # # ]
1696 : : }
1697 : :
1698 : 0 : void XclExpSupbookBuffer::StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange )
1699 : : {
1700 [ # # ]: 0 : ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
1701 [ # # ]: 0 : const OUString* pUrl = pRefMgr->getExternalFileName(nFileId);
1702 [ # # ]: 0 : if (!pUrl)
1703 : : return;
1704 : :
1705 [ # # ]: 0 : XclExpSupbookRef xSupbook;
1706 : : sal_uInt16 nSupbookId;
1707 [ # # ][ # # ]: 0 : if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
[ # # ][ # # ]
1708 : : {
1709 [ # # ][ # # ]: 0 : xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
[ # # ][ # # ]
[ # # ]
1710 [ # # ][ # # ]: 0 : nSupbookId = Append(xSupbook);
[ # # ]
1711 : : }
1712 : :
1713 : 0 : SCTAB nTabCount = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
1714 : :
1715 : : // If this is a multi-table range, get token for each table.
1716 : : using namespace ::formula;
1717 [ # # ]: 0 : vector<FormulaToken*> aMatrixList;
1718 [ # # ]: 0 : aMatrixList.reserve(nTabCount);
1719 : :
1720 : : // This is a new'ed instance, so we must manage its life cycle here.
1721 [ # # ][ # # ]: 0 : ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, rRange, NULL);
1722 [ # # ]: 0 : if (!pArray.get())
1723 : : return;
1724 : :
1725 [ # # ][ # # ]: 0 : for (FormulaToken* p = pArray->First(); p; p = pArray->Next())
[ # # ]
1726 : : {
1727 [ # # ]: 0 : if (p->GetType() == svMatrix)
1728 [ # # ]: 0 : aMatrixList.push_back(p);
1729 [ # # ]: 0 : else if (p->GetOpCode() != ocSep)
1730 : : {
1731 : : // This is supposed to be ocSep!!!
1732 : : return;
1733 : : }
1734 : : }
1735 : :
1736 [ # # ]: 0 : if (aMatrixList.size() != static_cast<size_t>(nTabCount))
1737 : : {
1738 : : // matrix size mis-match !
1739 : : return;
1740 : : }
1741 : :
1742 [ # # ]: 0 : sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
1743 : :
1744 : 0 : ScRange aRange(rRange);
1745 : 0 : aRange.aStart.SetTab(0);
1746 : 0 : aRange.aEnd.SetTab(0);
1747 [ # # ]: 0 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
1748 : : {
1749 : 0 : sal_uInt16 nSheetId = nFirstSheetId + static_cast<sal_uInt16>(nTab);
1750 : 0 : FindSBIndexEntry f(nSupbookId, nSheetId);
1751 : 0 : XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
1752 [ # # ][ # # ]: 0 : XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
1753 [ # # ][ # # ]: 0 : if (itr == itrEnd)
1754 : : {
1755 [ # # ]: 0 : maSBIndexVec.push_back(XclExpSBIndex());
1756 [ # # ]: 0 : XclExpSBIndex& r = maSBIndexVec.back();
1757 : 0 : r.mnSupbook = nSupbookId;
1758 : 0 : r.mnSBTab = nSheetId;
1759 : : }
1760 : :
1761 [ # # ][ # # ]: 0 : xSupbook->StoreCellRange(nSheetId, aRange, *aMatrixList[nTab]);
1762 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ]
1763 : : }
1764 : :
1765 : 0 : bool XclExpSupbookBuffer::InsertAddIn(
1766 : : sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rName )
1767 : : {
1768 [ # # ]: 0 : XclExpSupbookRef xSupbook;
1769 [ # # ]: 0 : if( mnAddInSB == SAL_MAX_UINT16 )
1770 : : {
1771 [ # # ][ # # ]: 0 : xSupbook.reset( new XclExpSupbook( GetRoot() ) );
[ # # ]
1772 [ # # ][ # # ]: 0 : mnAddInSB = Append( xSupbook );
[ # # ]
1773 : : }
1774 : : else
1775 [ # # ][ # # ]: 0 : xSupbook = maSupbookList.GetRecord( mnAddInSB );
[ # # ]
1776 : : OSL_ENSURE( xSupbook, "XclExpSupbookBuffer::InsertAddin - missing add-in supbook" );
1777 : 0 : rnSupbook = mnAddInSB;
1778 [ # # ]: 0 : rnExtName = xSupbook->InsertAddIn( rName );
1779 [ # # ]: 0 : return rnExtName > 0;
1780 : : }
1781 : :
1782 : 0 : bool XclExpSupbookBuffer::InsertEuroTool(
1783 : : sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rName )
1784 : : {
1785 [ # # ]: 0 : XclExpSupbookRef xSupbook;
1786 [ # # ]: 0 : String aUrl( RTL_CONSTASCII_USTRINGPARAM("\001\010EUROTOOL.XLA"));
1787 [ # # ][ # # ]: 0 : if( !GetSupbookUrl( xSupbook, rnSupbook, aUrl ) )
1788 : : {
1789 [ # # ][ # # ]: 0 : xSupbook.reset( new XclExpSupbook( GetRoot(), aUrl, EXC_SBTYPE_EUROTOOL ) );
[ # # ]
1790 [ # # ][ # # ]: 0 : rnSupbook = Append( xSupbook );
[ # # ]
1791 : : }
1792 [ # # ]: 0 : rnExtName = xSupbook->InsertEuroTool( rName );
1793 [ # # ][ # # ]: 0 : return rnExtName > 0;
1794 : : }
1795 : :
1796 : 0 : bool XclExpSupbookBuffer::InsertDde(
1797 : : sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
1798 : : const String& rApplic, const String& rTopic, const String& rItem )
1799 : : {
1800 [ # # ]: 0 : XclExpSupbookRef xSupbook;
1801 [ # # ][ # # ]: 0 : if( !GetSupbookDde( xSupbook, rnSupbook, rApplic, rTopic ) )
1802 : : {
1803 [ # # ][ # # ]: 0 : xSupbook.reset( new XclExpSupbook( GetRoot(), rApplic, rTopic ) );
[ # # ]
1804 [ # # ][ # # ]: 0 : rnSupbook = Append( xSupbook );
[ # # ]
1805 : : }
1806 [ # # ]: 0 : rnExtName = xSupbook->InsertDde( rItem );
1807 [ # # ]: 0 : return rnExtName > 0;
1808 : : }
1809 : :
1810 : 0 : bool XclExpSupbookBuffer::InsertExtName(
1811 : : sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rUrl,
1812 : : const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
1813 : : {
1814 [ # # ]: 0 : XclExpSupbookRef xSupbook;
1815 [ # # ][ # # ]: 0 : if (!GetSupbookUrl(xSupbook, rnSupbook, rUrl))
1816 : : {
1817 [ # # ][ # # ]: 0 : xSupbook.reset( new XclExpSupbook(GetRoot(), rUrl) );
[ # # ]
1818 [ # # ][ # # ]: 0 : rnSupbook = Append(xSupbook);
[ # # ]
1819 : : }
1820 [ # # ][ # # ]: 0 : rnExtName = xSupbook->InsertExtName(rName, pArray);
[ # # ]
1821 [ # # ]: 0 : return rnExtName > 0;
1822 : : }
1823 : :
1824 : 0 : XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
1825 : : XclExpRefLogEntry* pRefLogEntry )
1826 : : {
1827 : 0 : XclExpXti aXti(0, EXC_NOTAB, EXC_NOTAB);
1828 [ # # ]: 0 : ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
1829 [ # # ]: 0 : const OUString* pUrl = pRefMgr->getExternalFileName(nFileId);
1830 [ # # ]: 0 : if (!pUrl)
1831 : : return aXti;
1832 : :
1833 [ # # ]: 0 : XclExpSupbookRef xSupbook;
1834 : : sal_uInt16 nSupbookId;
1835 [ # # ][ # # ]: 0 : if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
[ # # ][ # # ]
1836 : : {
1837 [ # # ][ # # ]: 0 : xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
[ # # ][ # # ]
[ # # ]
1838 [ # # ][ # # ]: 0 : nSupbookId = Append(xSupbook);
[ # # ]
1839 : : }
1840 : 0 : aXti.mnSupbook = nSupbookId;
1841 : :
1842 [ # # ]: 0 : sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
1843 [ # # ]: 0 : if (nFirstSheetId == EXC_NOTAB)
1844 : : {
1845 : : // first sheet not found in SUPBOOK.
1846 : : return aXti;
1847 : : }
1848 [ # # ]: 0 : sal_uInt16 nSheetCount = xSupbook->GetTabCount();
1849 [ # # ]: 0 : for (sal_uInt16 i = 0; i < nXclTabSpan; ++i)
1850 : : {
1851 : 0 : sal_uInt16 nSheetId = nFirstSheetId + i;
1852 [ # # ]: 0 : if (nSheetId >= nSheetCount)
1853 : : return aXti;
1854 : :
1855 : 0 : FindSBIndexEntry f(nSupbookId, nSheetId);
1856 : 0 : XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
1857 [ # # ][ # # ]: 0 : XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
1858 [ # # ][ # # ]: 0 : if (itr == itrEnd)
1859 : : {
1860 [ # # ]: 0 : maSBIndexVec.push_back(XclExpSBIndex());
1861 [ # # ]: 0 : XclExpSBIndex& r = maSBIndexVec.back();
1862 : 0 : r.mnSupbook = nSupbookId;
1863 : 0 : r.mnSBTab = nSheetId;
1864 : : }
1865 [ # # ]: 0 : if (i == 0)
1866 : 0 : aXti.mnFirstSBTab = nSheetId;
1867 [ # # ]: 0 : if (i == nXclTabSpan - 1)
1868 : 0 : aXti.mnLastSBTab = nSheetId;
1869 : : }
1870 : :
1871 [ # # ]: 0 : if (pRefLogEntry)
1872 : : {
1873 : 0 : pRefLogEntry->mnFirstXclTab = 0;
1874 : 0 : pRefLogEntry->mnLastXclTab = 0;
1875 [ # # ]: 0 : if (xSupbook)
1876 [ # # ]: 0 : xSupbook->FillRefLogEntry(*pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab);
1877 : : }
1878 : :
1879 [ # # ]: 0 : return aXti;
1880 : : }
1881 : :
1882 : 0 : void XclExpSupbookBuffer::Save( XclExpStream& rStrm )
1883 : : {
1884 : 0 : maSupbookList.Save( rStrm );
1885 : 0 : }
1886 : :
1887 : 0 : bool XclExpSupbookBuffer::GetSupbookUrl(
1888 : : XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex, const String& rUrl ) const
1889 : : {
1890 [ # # ]: 0 : for( size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos )
1891 : : {
1892 [ # # ]: 0 : rxSupbook = maSupbookList.GetRecord( nPos );
1893 [ # # ]: 0 : if( rxSupbook->IsUrlLink( rUrl ) )
1894 : : {
1895 : 0 : rnIndex = ulimit_cast< sal_uInt16 >( nPos );
1896 : 0 : return true;
1897 : : }
1898 : : }
1899 : 0 : return false;
1900 : : }
1901 : :
1902 : 0 : bool XclExpSupbookBuffer::GetSupbookDde( XclExpSupbookRef& rxSupbook,
1903 : : sal_uInt16& rnIndex, const String& rApplic, const String& rTopic ) const
1904 : : {
1905 [ # # ]: 0 : for( size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos )
1906 : : {
1907 [ # # ]: 0 : rxSupbook = maSupbookList.GetRecord( nPos );
1908 [ # # ]: 0 : if( rxSupbook->IsDdeLink( rApplic, rTopic ) )
1909 : : {
1910 : 0 : rnIndex = ulimit_cast< sal_uInt16 >( nPos );
1911 : 0 : return true;
1912 : : }
1913 : : }
1914 : 0 : return false;
1915 : : }
1916 : :
1917 : 0 : sal_uInt16 XclExpSupbookBuffer::Append( XclExpSupbookRef xSupbook )
1918 : : {
1919 [ # # ]: 0 : maSupbookList.AppendRecord( xSupbook );
1920 : 0 : return ulimit_cast< sal_uInt16 >( maSupbookList.GetSize() - 1 );
1921 : : }
1922 : :
1923 : : // Export link manager ========================================================
1924 : :
1925 : 0 : XclExpLinkManagerImpl::XclExpLinkManagerImpl( const XclExpRoot& rRoot ) :
1926 : 0 : XclExpRoot( rRoot )
1927 : : {
1928 : 0 : }
1929 : :
1930 : : // ----------------------------------------------------------------------------
1931 : :
1932 : 0 : XclExpLinkManagerImpl5::XclExpLinkManagerImpl5( const XclExpRoot& rRoot ) :
1933 [ # # ][ # # ]: 0 : XclExpLinkManagerImpl( rRoot )
[ # # ]
1934 : : {
1935 : 0 : }
1936 : :
1937 : 0 : void XclExpLinkManagerImpl5::FindExtSheet(
1938 : : sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
1939 : : SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
1940 : : {
1941 : 0 : FindInternal( rnExtSheet, rnFirstXclTab, nFirstScTab );
1942 [ # # ][ # # ]: 0 : if( (rnFirstXclTab == EXC_TAB_DELETED) || (nFirstScTab == nLastScTab) )
1943 : : {
1944 : 0 : rnLastXclTab = rnFirstXclTab;
1945 : : }
1946 : : else
1947 : : {
1948 : : sal_uInt16 nDummyExtSheet;
1949 [ # # ][ # # ]: 0 : FindInternal( nDummyExtSheet, rnLastXclTab, nLastScTab );
1950 : : }
1951 : :
1952 : : (void)pRefLogEntry; // avoid compiler warning
1953 : : OSL_ENSURE( !pRefLogEntry, "XclExpLinkManagerImpl5::FindExtSheet - fill reflog entry not implemented" );
1954 : 0 : }
1955 : :
1956 : 0 : sal_uInt16 XclExpLinkManagerImpl5::FindExtSheet( sal_Unicode cCode )
1957 : : {
1958 : : sal_uInt16 nExtSheet;
1959 [ # # ][ # # ]: 0 : FindInternal( nExtSheet, cCode );
1960 : 0 : return nExtSheet;
1961 : : }
1962 : :
1963 : 0 : void XclExpLinkManagerImpl5::FindExtSheet(
1964 : : sal_uInt16 /*nFileId*/, const String& /*rTabName*/, sal_uInt16 /*nXclTabSpan*/,
1965 : : sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnFirstSBTab*/, sal_uInt16& /*rnLastSBTab*/,
1966 : : XclExpRefLogEntry* /*pRefLogEntry*/ )
1967 : : {
1968 : : // not implemented
1969 : 0 : }
1970 : :
1971 : 0 : void XclExpLinkManagerImpl5::StoreCellRange( const ScSingleRefData& /*rRef1*/, const ScSingleRefData& /*rRef2*/ )
1972 : : {
1973 : : // not implemented
1974 : 0 : }
1975 : :
1976 : 0 : void XclExpLinkManagerImpl5::StoreCell( sal_uInt16 /*nFileId*/, const String& /*rTabName*/, const ScSingleRefData& /*rRef*/ )
1977 : : {
1978 : : // not implemented
1979 : 0 : }
1980 : :
1981 : 0 : void XclExpLinkManagerImpl5::StoreCellRange( sal_uInt16 /*nFileId*/, const String& /*rTabName*/, const ScSingleRefData& /*rRef1*/, const ScSingleRefData& /*rRef2*/ )
1982 : : {
1983 : : // not implemented
1984 : 0 : }
1985 : :
1986 : 0 : bool XclExpLinkManagerImpl5::InsertAddIn(
1987 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
1988 : : {
1989 [ # # ]: 0 : XclExpExtSheetRef xExtSheet = FindInternal( rnExtSheet, EXC_EXTSH_ADDIN );
1990 [ # # ]: 0 : if( xExtSheet )
1991 : : {
1992 [ # # ]: 0 : rnExtName = xExtSheet->InsertAddIn( rName );
1993 : 0 : return rnExtName > 0;
1994 : : }
1995 [ # # ]: 0 : return false;
1996 : : }
1997 : :
1998 : 0 : bool XclExpLinkManagerImpl5::InsertEuroTool(
1999 : : sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const String& /*rName*/ )
2000 : : {
2001 : 0 : return false;
2002 : : }
2003 : :
2004 : :
2005 : 0 : bool XclExpLinkManagerImpl5::InsertDde(
2006 : : sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/,
2007 : : const String& /*rApplic*/, const String& /*rTopic*/, const String& /*rItem*/ )
2008 : : {
2009 : : // not implemented
2010 : 0 : return false;
2011 : : }
2012 : :
2013 : 0 : bool XclExpLinkManagerImpl5::InsertExtName(
2014 : : sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const String& /*rUrl*/,
2015 : : const String& /*rName*/, const ScExternalRefCache::TokenArrayRef /*pArray*/ )
2016 : : {
2017 : : // not implemented
2018 : 0 : return false;
2019 : : }
2020 : :
2021 : 0 : void XclExpLinkManagerImpl5::Save( XclExpStream& rStrm )
2022 : : {
2023 [ # # ][ # # ]: 0 : if( sal_uInt16 nExtSheetCount = GetExtSheetCount() )
2024 : : {
2025 : : // EXTERNCOUNT record
2026 [ # # ][ # # ]: 0 : XclExpUInt16Record( EXC_ID_EXTERNCOUNT, nExtSheetCount ).Save( rStrm );
[ # # ]
2027 : : // list of EXTERNSHEET records with EXTERNNAME, XCT, CRN records
2028 [ # # ]: 0 : maExtSheetList.Save( rStrm );
2029 : : }
2030 : 0 : }
2031 : :
2032 : 0 : sal_uInt16 XclExpLinkManagerImpl5::GetExtSheetCount() const
2033 : : {
2034 : 0 : return static_cast< sal_uInt16 >( maExtSheetList.GetSize() );
2035 : : }
2036 : :
2037 : 0 : sal_uInt16 XclExpLinkManagerImpl5::AppendInternal( XclExpExtSheetRef xExtSheet )
2038 : : {
2039 [ # # ]: 0 : if( GetExtSheetCount() < 0x7FFF )
2040 : : {
2041 [ # # ]: 0 : maExtSheetList.AppendRecord( xExtSheet );
2042 : : // return negated one-based EXTERNSHEET index (i.e. 0xFFFD for 3rd record)
2043 : 0 : return static_cast< sal_uInt16 >( -GetExtSheetCount() );
2044 : : }
2045 : 0 : return 0;
2046 : : }
2047 : :
2048 : 0 : void XclExpLinkManagerImpl5::CreateInternal()
2049 : : {
2050 [ # # ]: 0 : if( maIntTabMap.empty() )
2051 : : {
2052 : : // create EXTERNSHEET records for all internal exported sheets
2053 : 0 : XclExpTabInfo& rTabInfo = GetTabInfo();
2054 [ # # ]: 0 : for( SCTAB nScTab = 0, nScCnt = rTabInfo.GetScTabCount(); nScTab < nScCnt; ++nScTab )
2055 : : {
2056 [ # # ][ # # ]: 0 : if( rTabInfo.IsExportTab( nScTab ) )
2057 : : {
2058 [ # # ]: 0 : XclExpExtSheetRef xRec;
2059 [ # # ]: 0 : if( nScTab == GetCurrScTab() )
2060 [ # # ][ # # ]: 0 : xRec.reset( new XclExpExternSheet( GetRoot(), EXC_EXTSH_OWNTAB ) );
[ # # ]
2061 : : else
2062 [ # # ][ # # ]: 0 : xRec.reset( new XclExpExternSheet( GetRoot(), rTabInfo.GetScTabName( nScTab ) ) );
[ # # ][ # # ]
[ # # ][ # # ]
2063 [ # # ][ # # ]: 0 : maIntTabMap[ nScTab ] = AppendInternal( xRec );
[ # # ][ # # ]
[ # # ]
2064 : : }
2065 : : }
2066 : : }
2067 : 0 : }
2068 : :
2069 : 0 : XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::GetInternal( sal_uInt16 nExtSheet )
2070 : : {
2071 : 0 : return maExtSheetList.GetRecord( static_cast< sal_uInt16 >( -nExtSheet - 1 ) );
2072 : : }
2073 : :
2074 : 0 : XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::FindInternal(
2075 : : sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab, SCTAB nScTab )
2076 : : {
2077 : : // create internal EXTERNSHEET records on demand
2078 [ # # ]: 0 : CreateInternal();
2079 : :
2080 : : // try to find an EXTERNSHEET record - if not, return a "deleted sheet" reference
2081 [ # # ]: 0 : XclExpExtSheetRef xExtSheet;
2082 [ # # ][ # # ]: 0 : XclExpIntTabMap::const_iterator aIt = maIntTabMap.find( nScTab );
2083 [ # # ][ # # ]: 0 : if( aIt == maIntTabMap.end() )
[ # # ]
2084 : : {
2085 [ # # ][ # # ]: 0 : xExtSheet = FindInternal( rnExtSheet, EXC_EXTSH_OWNDOC );
[ # # ]
2086 : 0 : rnXclTab = EXC_TAB_DELETED;
2087 : : }
2088 : : else
2089 : : {
2090 [ # # ]: 0 : rnExtSheet = aIt->second;
2091 [ # # ][ # # ]: 0 : xExtSheet = GetInternal( rnExtSheet );
[ # # ]
2092 [ # # ][ # # ]: 0 : rnXclTab = GetTabInfo().GetXclTab( nScTab );
2093 : : }
2094 : 0 : return xExtSheet;
2095 : : }
2096 : :
2097 : 0 : XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::FindInternal(
2098 : : sal_uInt16& rnExtSheet, sal_Unicode cCode )
2099 : : {
2100 [ # # ]: 0 : XclExpExtSheetRef xExtSheet;
2101 [ # # ][ # # ]: 0 : XclExpCodeMap::const_iterator aIt = maCodeMap.find( cCode );
2102 [ # # ][ # # ]: 0 : if( aIt == maCodeMap.end() )
[ # # ]
2103 : : {
2104 [ # # ][ # # ]: 0 : xExtSheet.reset( new XclExpExternSheet( GetRoot(), cCode ) );
[ # # ]
2105 [ # # ][ # # ]: 0 : rnExtSheet = maCodeMap[ cCode ] = AppendInternal( xExtSheet );
[ # # ][ # # ]
2106 : : }
2107 : : else
2108 : : {
2109 [ # # ]: 0 : rnExtSheet = aIt->second;
2110 [ # # ][ # # ]: 0 : xExtSheet = GetInternal( rnExtSheet );
[ # # ]
2111 : : }
2112 : 0 : return xExtSheet;
2113 : : }
2114 : :
2115 : : // ----------------------------------------------------------------------------
2116 : :
2117 : 0 : XclExpLinkManagerImpl8::XclExpLinkManagerImpl8( const XclExpRoot& rRoot ) :
2118 : : XclExpLinkManagerImpl( rRoot ),
2119 [ # # ][ # # ]: 0 : maSBBuffer( rRoot )
2120 : : {
2121 : 0 : }
2122 : :
2123 : 0 : void XclExpLinkManagerImpl8::FindExtSheet(
2124 : : sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
2125 : : SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
2126 : : {
2127 : 0 : XclExpTabInfo& rTabInfo = GetTabInfo();
2128 : 0 : rnFirstXclTab = rTabInfo.GetXclTab( nFirstScTab );
2129 : 0 : rnLastXclTab = rTabInfo.GetXclTab( nLastScTab );
2130 [ # # ]: 0 : rnExtSheet = InsertXti( maSBBuffer.GetXti( rnFirstXclTab, rnLastXclTab, pRefLogEntry ) );
2131 : 0 : }
2132 : :
2133 : 0 : sal_uInt16 XclExpLinkManagerImpl8::FindExtSheet( sal_Unicode cCode )
2134 : : {
2135 : : (void)cCode; // avoid compiler warning
2136 : : OSL_ENSURE( (cCode == EXC_EXTSH_OWNDOC) || (cCode == EXC_EXTSH_ADDIN),
2137 : : "XclExpLinkManagerImpl8::FindExtSheet - unknown externsheet code" );
2138 [ # # ]: 0 : return InsertXti( maSBBuffer.GetXti( EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
2139 : : }
2140 : :
2141 : 0 : void XclExpLinkManagerImpl8::FindExtSheet(
2142 : : sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
2143 : : sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
2144 : : XclExpRefLogEntry* pRefLogEntry )
2145 : : {
2146 [ # # ]: 0 : XclExpXti aXti = maSBBuffer.GetXti(nFileId, rTabName, nXclTabSpan, pRefLogEntry);
2147 [ # # ]: 0 : rnExtSheet = InsertXti(aXti);
2148 : 0 : rnFirstSBTab = aXti.mnFirstSBTab;
2149 : 0 : rnLastSBTab = aXti.mnLastSBTab;
2150 : 0 : }
2151 : :
2152 : 0 : void XclExpLinkManagerImpl8::StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 )
2153 : : {
2154 [ # # ][ # # ]: 0 : if( !rRef1.IsDeleted() && !rRef2.IsDeleted() && (rRef1.nTab >= 0) && (rRef2.nTab >= 0) )
[ # # ][ # # ]
[ # # ]
2155 : : {
2156 [ # # ]: 0 : const XclExpTabInfo& rTabInfo = GetTabInfo();
2157 : 0 : SCTAB nFirstScTab = static_cast< SCTAB >( rRef1.nTab );
2158 : 0 : SCTAB nLastScTab = static_cast< SCTAB >( rRef2.nTab );
2159 : : ScRange aRange(
2160 : : static_cast< SCCOL >( rRef1.nCol ), static_cast< SCROW >( rRef1.nRow ), 0,
2161 : 0 : static_cast< SCCOL >( rRef2.nCol ), static_cast< SCROW >( rRef2.nRow ), 0 );
2162 [ # # ]: 0 : for( SCTAB nScTab = nFirstScTab; nScTab <= nLastScTab; ++nScTab )
2163 : : {
2164 [ # # ][ # # ]: 0 : if( rTabInfo.IsExternalTab( nScTab ) )
2165 : : {
2166 : 0 : aRange.aStart.SetTab( nScTab );
2167 : 0 : aRange.aEnd.SetTab( nScTab );
2168 [ # # ]: 0 : maSBBuffer.StoreCellRange( aRange );
2169 : : }
2170 : : }
2171 : : }
2172 : 0 : }
2173 : :
2174 : 0 : void XclExpLinkManagerImpl8::StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
2175 : : {
2176 : 0 : ScAddress aAddr(rRef.nCol, rRef.nRow, rRef.nTab);
2177 [ # # ]: 0 : maSBBuffer.StoreCell(nFileId, rTabName, aAddr);
2178 : 0 : }
2179 : :
2180 : 0 : void XclExpLinkManagerImpl8::StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 )
2181 : : {
2182 : : ScRange aRange(static_cast<SCCOL>(rRef1.nCol), static_cast<SCROW>(rRef1.nRow), static_cast<SCTAB>(rRef1.nTab),
2183 : 0 : static_cast<SCCOL>(rRef2.nCol), static_cast<SCROW>(rRef2.nRow), static_cast<SCTAB>(rRef2.nTab));
2184 [ # # ]: 0 : maSBBuffer.StoreCellRange(nFileId, rTabName, aRange);
2185 : 0 : }
2186 : :
2187 : 0 : bool XclExpLinkManagerImpl8::InsertAddIn(
2188 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
2189 : : {
2190 : : sal_uInt16 nSupbook;
2191 [ # # ][ # # ]: 0 : if( maSBBuffer.InsertAddIn( nSupbook, rnExtName, rName ) )
2192 : : {
2193 [ # # ]: 0 : rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
2194 : 0 : return true;
2195 : : }
2196 : 0 : return false;
2197 : : }
2198 : :
2199 : 0 : bool XclExpLinkManagerImpl8::InsertEuroTool(
2200 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
2201 : : {
2202 : : sal_uInt16 nSupbook;
2203 [ # # ][ # # ]: 0 : if( maSBBuffer.InsertEuroTool( nSupbook, rnExtName, rName ) )
2204 : : {
2205 [ # # ]: 0 : rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
2206 : 0 : return true;
2207 : : }
2208 : 0 : return false;
2209 : : }
2210 : :
2211 : :
2212 : 0 : bool XclExpLinkManagerImpl8::InsertDde(
2213 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
2214 : : const String& rApplic, const String& rTopic, const String& rItem )
2215 : : {
2216 : : sal_uInt16 nSupbook;
2217 [ # # ][ # # ]: 0 : if( maSBBuffer.InsertDde( nSupbook, rnExtName, rApplic, rTopic, rItem ) )
2218 : : {
2219 [ # # ]: 0 : rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
2220 : 0 : return true;
2221 : : }
2222 : 0 : return false;
2223 : : }
2224 : :
2225 : 0 : bool XclExpLinkManagerImpl8::InsertExtName( sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
2226 : : const String& rName, const String& rUrl, const ScExternalRefCache::TokenArrayRef pArray )
2227 : : {
2228 : : sal_uInt16 nSupbook;
2229 [ # # ][ # # ]: 0 : if( maSBBuffer.InsertExtName( nSupbook, rnExtName, rUrl, rName, pArray ) )
[ # # ][ # # ]
2230 : : {
2231 [ # # ]: 0 : rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
2232 : 0 : return true;
2233 : : }
2234 : 0 : return false;
2235 : : }
2236 : :
2237 : 0 : void XclExpLinkManagerImpl8::Save( XclExpStream& rStrm )
2238 : : {
2239 [ # # ]: 0 : if( !maXtiVec.empty() )
2240 : : {
2241 : : // SUPBOOKs, XCTs, CRNs, EXTERNNAMEs
2242 : 0 : maSBBuffer.Save( rStrm );
2243 : :
2244 : : // EXTERNSHEET
2245 : 0 : sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maXtiVec.size() );
2246 : 0 : rStrm.StartRecord( EXC_ID_EXTERNSHEET, 2 + 6 * nCount );
2247 : 0 : rStrm << nCount;
2248 : 0 : rStrm.SetSliceSize( 6 );
2249 [ # # ][ # # ]: 0 : for( XclExpXtiVec::const_iterator aIt = maXtiVec.begin(), aEnd = maXtiVec.end(); aIt != aEnd; ++aIt )
[ # # ][ # # ]
2250 [ # # ]: 0 : aIt->Save( rStrm );
2251 : 0 : rStrm.EndRecord();
2252 : : }
2253 : 0 : }
2254 : :
2255 : 0 : sal_uInt16 XclExpLinkManagerImpl8::InsertXti( const XclExpXti& rXti )
2256 : : {
2257 [ # # ][ # # ]: 0 : for( XclExpXtiVec::const_iterator aIt = maXtiVec.begin(), aEnd = maXtiVec.end(); aIt != aEnd; ++aIt )
[ # # ][ # # ]
2258 [ # # ]: 0 : if( *aIt == rXti )
2259 [ # # ][ # # ]: 0 : return ulimit_cast< sal_uInt16 >( aIt - maXtiVec.begin() );
2260 : 0 : maXtiVec.push_back( rXti );
2261 : 0 : return ulimit_cast< sal_uInt16 >( maXtiVec.size() - 1 );
2262 : : }
2263 : :
2264 : : // ============================================================================
2265 : :
2266 : 0 : XclExpLinkManager::XclExpLinkManager( const XclExpRoot& rRoot ) :
2267 [ # # ][ # # ]: 0 : XclExpRoot( rRoot )
2268 : : {
2269 [ # # # ]: 0 : switch( GetBiff() )
2270 : : {
2271 : : case EXC_BIFF5:
2272 [ # # ][ # # ]: 0 : mxImpl.reset( new XclExpLinkManagerImpl5( rRoot ) );
[ # # ]
2273 : 0 : break;
2274 : : case EXC_BIFF8:
2275 [ # # ][ # # ]: 0 : mxImpl.reset( new XclExpLinkManagerImpl8( rRoot ) );
[ # # ]
2276 : 0 : break;
2277 : : default:
2278 : : DBG_ERROR_BIFF();
2279 : : }
2280 : 0 : }
2281 : :
2282 [ # # ][ # # ]: 0 : XclExpLinkManager::~XclExpLinkManager()
2283 : : {
2284 [ # # ]: 0 : }
2285 : :
2286 : 0 : void XclExpLinkManager::FindExtSheet(
2287 : : sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab,
2288 : : SCTAB nScTab, XclExpRefLogEntry* pRefLogEntry )
2289 : : {
2290 : 0 : mxImpl->FindExtSheet( rnExtSheet, rnXclTab, rnXclTab, nScTab, nScTab, pRefLogEntry );
2291 : 0 : }
2292 : :
2293 : 0 : void XclExpLinkManager::FindExtSheet(
2294 : : sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
2295 : : SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
2296 : : {
2297 : 0 : mxImpl->FindExtSheet( rnExtSheet, rnFirstXclTab, rnLastXclTab, nFirstScTab, nLastScTab, pRefLogEntry );
2298 : 0 : }
2299 : :
2300 : 0 : sal_uInt16 XclExpLinkManager::FindExtSheet( sal_Unicode cCode )
2301 : : {
2302 : 0 : return mxImpl->FindExtSheet( cCode );
2303 : : }
2304 : :
2305 : 0 : void XclExpLinkManager::FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
2306 : : sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
2307 : : XclExpRefLogEntry* pRefLogEntry )
2308 : : {
2309 : 0 : mxImpl->FindExtSheet( nFileId, rTabName, nXclTabSpan, rnExtSheet, rnFirstSBTab, rnLastSBTab, pRefLogEntry );
2310 : 0 : }
2311 : :
2312 : 0 : void XclExpLinkManager::StoreCell( const ScSingleRefData& rRef )
2313 : : {
2314 : 0 : mxImpl->StoreCellRange( rRef, rRef );
2315 : 0 : }
2316 : :
2317 : 0 : void XclExpLinkManager::StoreCellRange( const ScComplexRefData& rRef )
2318 : : {
2319 : 0 : mxImpl->StoreCellRange( rRef.Ref1, rRef.Ref2 );
2320 : 0 : }
2321 : :
2322 : 0 : void XclExpLinkManager::StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
2323 : : {
2324 : 0 : mxImpl->StoreCell( nFileId, rTabName, rRef );
2325 : 0 : }
2326 : :
2327 : 0 : void XclExpLinkManager::StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef )
2328 : : {
2329 : 0 : mxImpl->StoreCellRange( nFileId, rTabName, rRef.Ref1, rRef.Ref2 );
2330 : 0 : }
2331 : :
2332 : 0 : bool XclExpLinkManager::InsertAddIn(
2333 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
2334 : : {
2335 : 0 : return mxImpl->InsertAddIn( rnExtSheet, rnExtName, rName );
2336 : : }
2337 : :
2338 : 0 : bool XclExpLinkManager::InsertEuroTool(
2339 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
2340 : : {
2341 : 0 : return mxImpl->InsertEuroTool( rnExtSheet, rnExtName, rName );
2342 : : }
2343 : :
2344 : 0 : bool XclExpLinkManager::InsertDde(
2345 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
2346 : : const String& rApplic, const String& rTopic, const String& rItem )
2347 : : {
2348 : 0 : return mxImpl->InsertDde( rnExtSheet, rnExtName, rApplic, rTopic, rItem );
2349 : : }
2350 : :
2351 : 0 : bool XclExpLinkManager::InsertExtName(
2352 : : sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName, const String& rUrl,
2353 : : const ScExternalRefCache::TokenArrayRef pArray )
2354 : : {
2355 [ # # ]: 0 : return mxImpl->InsertExtName( rnExtSheet, rnExtName, rUrl, rName, pArray );
2356 : : }
2357 : :
2358 : 0 : void XclExpLinkManager::Save( XclExpStream& rStrm )
2359 : : {
2360 : 0 : mxImpl->Save( rStrm );
2361 [ + - ][ + - ]: 24 : }
2362 : :
2363 : : // ============================================================================
2364 : :
2365 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|