1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xelink.cxx,v $
10 * $Revision: 1.21.134.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 #include <unotools/collatorwrapper.hxx>
37 #include <svtools/zforlist.hxx>
38 #include "document.hxx"
40 #include "scextopt.hxx"
41 #include "externalrefmgr.hxx"
46 using ::std::auto_ptr
;
49 using namespace formula
;
51 // ============================================================================
52 // *** Helper classes ***
53 // ============================================================================
55 // External names =============================================================
57 /** This is a base class for any external name (i.e. add-in names or DDE links).
58 @descr Derived classes implement creation and export of the external names. */
59 class XclExpExtNameBase
: public XclExpRecord
, protected XclExpRoot
62 /** @param nFlags The flags to export. */
63 explicit XclExpExtNameBase( const XclExpRoot
& rRoot
,
64 const String
& rName
, sal_uInt16 nFlags
= 0 );
65 virtual ~XclExpExtNameBase();
67 /** Returns the name string of the external name. */
68 inline const String
& GetName() const { return maName
; }
71 /** Writes the start of the record that is equal in all EXTERNNAME records and calls WriteAddData(). */
72 virtual void WriteBody( XclExpStream
& rStrm
);
73 /** Called to write additional data following the common record contents.
74 @descr Derived classes should overwrite this function to write their data. */
75 virtual void WriteAddData( XclExpStream
& rStrm
);
78 String maName
; /// Calc name (title) of the external name.
79 XclExpStringRef mxName
; /// Excel name (title) of the external name.
80 sal_uInt16 mnFlags
; /// Flags for record export.
83 // ----------------------------------------------------------------------------
85 /** Represents an EXTERNNAME record for an add-in function name. */
86 class XclExpExtNameAddIn
: public XclExpExtNameBase
89 explicit XclExpExtNameAddIn( const XclExpRoot
& rRoot
, const String
& rName
);
92 /** Writes additional record contents. */
93 virtual void WriteAddData( XclExpStream
& rStrm
);
96 // ----------------------------------------------------------------------------
98 /** Represents an EXTERNNAME record for a DDE link. */
99 class XclExpExtNameDde
: public XclExpExtNameBase
102 explicit XclExpExtNameDde( const XclExpRoot
& rRoot
, const String
& rName
,
103 sal_uInt16 nFlags
, const ScMatrix
* pResults
= 0 );
106 /** Writes additional record contents. */
107 virtual void WriteAddData( XclExpStream
& rStrm
);
110 typedef ScfRef
< XclExpCachedMatrix
> XclExpCachedMatRef
;
111 XclExpCachedMatRef mxMatrix
; /// Cached results of the DDE link.
114 // ----------------------------------------------------------------------------
118 class XclExpExtName
: public XclExpExtNameBase
121 explicit XclExpExtName( const XclExpRoot
& rRoot
, const XclExpSupbook
& rSupbook
, const String
& rName
,
122 const ScExternalRefCache::TokenArrayRef pArray
);
125 /** Writes additional record contents. */
126 virtual void WriteAddData( XclExpStream
& rStrm
);
129 const XclExpSupbook
& mrSupbook
;
130 auto_ptr
<ScTokenArray
> mpArray
;
133 // List of external names =====================================================
135 /** List of all external names of a sheet. */
136 class XclExpExtNameBuffer
: public XclExpRecordBase
, protected XclExpRoot
139 explicit XclExpExtNameBuffer( const XclExpRoot
& rRoot
);
141 /** Inserts an add-in function name
142 @return The 1-based (Excel-like) list index of the name. */
143 sal_uInt16
InsertAddIn( const String
& rName
);
144 /** InsertEuroTool */
145 sal_uInt16
InsertEuroTool( const String
& rName
);
146 /** Inserts a DDE link.
147 @return The 1-based (Excel-like) list index of the DDE link. */
148 sal_uInt16
InsertDde( const String
& rApplic
, const String
& rTopic
, const String
& rItem
);
150 sal_uInt16
InsertExtName( const XclExpSupbook
& rSupbook
, const String
& rName
, const ScExternalRefCache::TokenArrayRef pArray
);
152 /** Writes the EXTERNNAME record list. */
153 virtual void Save( XclExpStream
& rStrm
);
156 typedef XclExpRecordList
< XclExpExtNameBase
> XclExpExtNameList
;
157 typedef XclExpExtNameList::RecordRefType XclExpExtNameRef
;
160 /** Returns the 1-based (Excel-like) list index of the external name or 0, if not found. */
161 sal_uInt16
GetIndex( const String
& rName
) const;
162 /** Appends the passed newly crested external name.
163 @return The 1-based (Excel-like) list index of the appended name. */
164 sal_uInt16
AppendNew( XclExpExtNameBase
* pExtName
);
167 XclExpExtNameList maNameList
; /// The list with all EXTERNNAME records.
170 // Cached external cells ======================================================
172 /** Base class to store the contents of one external cell (record CRN). */
173 class XclExpCrn
: public XclExpRecord
176 /** @param nAddSize The size of additional data derived classes will write. */
177 explicit XclExpCrn( SCCOL nScCol
, SCROW nScRow
, sal_uInt8 nId
, sal_uInt32 nAddLen
= 0 );
180 /** Writes the start of the record that is equal in all CRN records and calls WriteAddData(). */
181 virtual void WriteBody( XclExpStream
& rStrm
);
183 /** Called to write additional data following the common record contents.
184 @descr Derived classes should overwrite this function to write their data. */
185 virtual void WriteAddData( XclExpStream
& rStrm
) = 0;
188 sal_uInt16 mnXclCol
; /// Column index of the external cell.
189 sal_uInt16 mnXclRow
; /// Row index of the external cell.
190 sal_uInt8 mnId
; /// Identifier for data type (EXC_CACHEDVAL_***).
193 // ----------------------------------------------------------------------------
195 /** Cached data of an external value cell. */
196 class XclExpCrnDouble
: public XclExpCrn
199 explicit XclExpCrnDouble( SCCOL nScCol
, SCROW nScRow
, double fVal
);
202 /** Writes the double value following the common record contents. */
203 virtual void WriteAddData( XclExpStream
& rStrm
);
206 double mfVal
; /// Value of the cached cell.
209 // ----------------------------------------------------------------------------
211 /** Cached data of an external text cell. */
212 class XclExpCrnString
: public XclExpCrn
215 explicit XclExpCrnString( SCCOL nScCol
, SCROW nScRow
, const String
& rText
);
218 /** Writes the string following the common record contents. */
219 virtual void WriteAddData( XclExpStream
& rStrm
);
222 XclExpString maText
; /// Text of the cached cell.
225 // ----------------------------------------------------------------------------
227 /// Cached data of an external Boolean cell. */
228 class XclExpCrnBool
: public XclExpCrn
231 explicit XclExpCrnBool( SCCOL nScCol
, SCROW nScRow
, bool bBoolVal
);
234 /** Writes the Boolean value following the common record contents. */
235 virtual void WriteAddData( XclExpStream
& rStrm
);
238 sal_uInt16 mnBool
; /// Boolean value of the cached cell.
241 // Cached cells of a sheet ====================================================
243 /// Represents the record XCT which is the header record of a CRN record list. */
244 class XclExpXct
: public XclExpRecord
247 explicit XclExpXct( const String
& rTabName
, sal_uInt16 nSBTab
);
249 /** Returns the external sheet name. */
250 inline const XclExpString
& GetTabName() const { return maTabName
; }
252 /** Stores all cells in the given range in the CRN list. */
253 void StoreCellRange( const XclExpRoot
& rRoot
, const ScRange
& rRange
);
255 void StoreCell( const XclExpRoot
& rRoot
, const ScAddress
& rCell
, const formula::FormulaToken
& rToken
);
256 void StoreCellRange( const XclExpRoot
& rRoot
, const ScRange
& rRange
, const formula::FormulaToken
& rToken
);
258 /** Writes the XCT and all CRN records. */
259 virtual void Save( XclExpStream
& rStrm
);
262 /** Writes the XCT record contents. */
263 virtual void WriteBody( XclExpStream
& rStrm
);
266 typedef XclExpRecordList
< XclExpCrn
> XclExpCrnList
;
267 typedef XclExpCrnList::RecordRefType XclExpCrnRef
;
269 XclExpCrnList maCrnList
; /// CRN records that follow this record.
270 ScMarkData maUsedCells
; /// Contains addresses of all stored cells.
271 XclExpString maTabName
; /// Sheet name of the external sheet.
272 sal_uInt16 mnSBTab
; /// Referred sheet index in SUPBOOK record.
275 // External documents (EXTERNSHEET/SUPBOOK), base class =======================
277 /** Base class for records representing external sheets/documents.
279 In BIFF5/BIFF7, this record is the EXTERNSHEET record containing one sheet
280 of the own or an external document. In BIFF8, this record is the SUPBOOK
281 record representing the entire own or external document with all referenced
284 class XclExpExternSheetBase
: public XclExpRecord
, protected XclExpRoot
287 explicit XclExpExternSheetBase( const XclExpRoot
& rRoot
,
288 sal_uInt16 nRecId
, sal_uInt32 nRecSize
= 0 );
291 /** Creates and returns the list of EXTERNNAME records. */
292 XclExpExtNameBuffer
& GetExtNameBuffer();
293 /** Creates and returns the list of EXTERNNAME records. */
294 void WriteExtNameBuffer( XclExpStream
& rStrm
);
297 typedef ScfRef
< XclExpExtNameBuffer
> XclExpExtNameBfrRef
;
298 XclExpExtNameBfrRef mxExtNameBfr
; /// List of EXTERNNAME records.
301 // External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
303 /** Represents an EXTERNSHEET record containing the URL and sheet name of a sheet.
304 @descr This class is used up to BIFF7 only, writing a BIFF8 EXTERNSHEET
305 record is implemented directly in the link manager. */
306 class XclExpExternSheet
: public XclExpExternSheetBase
309 /** Creates an EXTERNSHEET record containing a special code (i.e. own document or sheet). */
310 explicit XclExpExternSheet( const XclExpRoot
& rRoot
, sal_Unicode cCode
);
311 /** Creates an EXTERNSHEET record referring to an internal sheet. */
312 explicit XclExpExternSheet( const XclExpRoot
& rRoot
, const String
& rTabName
);
314 /** Finds or inserts an EXTERNNAME record for add-ins.
315 @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
316 sal_uInt16
InsertAddIn( const String
& rName
);
318 /** Writes the EXTERNSHEET and all EXTERNNAME, XCT and CRN records. */
319 virtual void Save( XclExpStream
& rStrm
);
322 /** Initializes the record data with the passed encoded URL. */
323 void Init( const String
& rEncUrl
);
324 /** Writes the contents of the EXTERNSHEET record. */
325 virtual void WriteBody( XclExpStream
& rStrm
);
328 XclExpString maTabName
; /// The name of the sheet.
331 // External documents (SUPBOOK, BIFF8) ========================================
333 /** The SUPBOOK record contains data for an external document (URL, sheet names, external values). */
334 class XclExpSupbook
: public XclExpExternSheetBase
337 /** Creates a SUPBOOK record for internal references. */
338 explicit XclExpSupbook( const XclExpRoot
& rRoot
, sal_uInt16 nXclTabCount
);
339 /** Creates a SUPBOOK record for add-in functions. */
340 explicit XclExpSupbook( const XclExpRoot
& rRoot
);
341 /** EUROTOOL SUPBOOK */
342 explicit XclExpSupbook( const XclExpRoot
& rRoot
, const String
& rUrl
, XclSupbookType
);
343 /** Creates a SUPBOOK record for an external document. */
344 explicit XclExpSupbook( const XclExpRoot
& rRoot
, const String
& rUrl
);
345 /** Creates a SUPBOOK record for a DDE link. */
346 explicit XclExpSupbook( const XclExpRoot
& rRoot
, const String
& rApplic
, const String
& rTopic
);
348 /** Returns true, if this SUPBOOK contains the passed URL of an external document. */
349 bool IsUrlLink( const String
& rUrl
) const;
350 /** Returns true, if this SUPBOOK contains the passed DDE link. */
351 bool IsDdeLink( const String
& rApplic
, const String
& rTopic
) const;
352 /** Fills the passed reference log entry with the URL and sheet names. */
353 void FillRefLogEntry( XclExpRefLogEntry
& rRefLogEntry
,
354 sal_uInt16 nFirstSBTab
, sal_uInt16 nLastSBTab
) const;
356 /** Stores all cells in the given range in the CRN list of the specified SUPBOOK sheet. */
357 void StoreCellRange( const ScRange
& rRange
, sal_uInt16 nSBTab
);
359 void StoreCell( sal_uInt16 nSBTab
, const ScAddress
& rCell
, const formula::FormulaToken
& rToken
);
360 void StoreCellRange( sal_uInt16 nSBTab
, const ScRange
& rRange
, const formula::FormulaToken
& rToken
);
362 sal_uInt16
GetTabIndex( const String
& rTabName
) const;
363 sal_uInt16
GetTabCount() const;
365 /** Inserts a new sheet name into the SUPBOOK and returns the SUPBOOK internal sheet index. */
366 sal_uInt16
InsertTabName( const String
& rTabName
);
367 /** Finds or inserts an EXTERNNAME record for add-ins.
368 @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
369 sal_uInt16
InsertAddIn( const String
& rName
);
370 /** InsertEuroTool */
371 sal_uInt16
InsertEuroTool( const String
& rName
);
372 /** Finds or inserts an EXTERNNAME record for DDE links.
373 @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
374 sal_uInt16
InsertDde( const String
& rItem
);
376 sal_uInt16
InsertExtName( const String
& rName
, const ScExternalRefCache::TokenArrayRef pArray
);
378 /** Writes the SUPBOOK and all EXTERNNAME, XCT and CRN records. */
379 virtual void Save( XclExpStream
& rStrm
);
382 /** Returns the sheet name inside of this SUPBOOK. */
383 const XclExpString
* GetTabName( sal_uInt16 nSBTab
) const;
385 /** Writes the SUPBOOK record contents. */
386 virtual void WriteBody( XclExpStream
& rStrm
);
389 typedef XclExpRecordList
< XclExpXct
> XclExpXctList
;
390 typedef XclExpXctList::RecordRefType XclExpXctRef
;
392 XclExpXctList maXctList
; /// List of XCT records (which contain CRN records).
393 String maUrl
; /// URL of the external document or application name for DDE.
394 String maDdeTopic
; /// Topic of an DDE link.
395 XclExpString maUrlEncoded
; /// Document name encoded for Excel.
396 XclSupbookType meType
; /// Type of this SUPBOOK record.
397 sal_uInt16 mnXclTabCount
; /// Number of internal sheets.
400 // All SUPBOOKS in a document =================================================
402 /** This struct contains a sheet index range for 3D references.
403 @descr This reference consists of an index to a SUPBOOK record and indexes
404 to SUPBOOK sheet names. */
407 sal_uInt16 mnSupbook
; /// Index to SUPBOOK record.
408 sal_uInt16 mnFirstSBTab
; /// Index to the first sheet of the range in the SUPBOOK.
409 sal_uInt16 mnLastSBTab
; /// Index to the last sheet of the range in the SUPBOOK.
411 inline explicit XclExpXti() : mnSupbook( 0 ), mnFirstSBTab( 0 ), mnLastSBTab( 0 ) {}
412 inline explicit XclExpXti( sal_uInt16 nSupbook
, sal_uInt16 nFirstSBTab
, sal_uInt16 nLastSBTab
) :
413 mnSupbook( nSupbook
), mnFirstSBTab( nFirstSBTab
), mnLastSBTab( nLastSBTab
) {}
415 /** Writes this XTI structure (inside of the EXTERNSHEET record). */
416 inline void Save( XclExpStream
& rStrm
) const
417 { rStrm
<< mnSupbook
<< mnFirstSBTab
<< mnLastSBTab
; }
420 inline bool operator==( const XclExpXti
& rLeft
, const XclExpXti
& rRight
)
423 (rLeft
.mnSupbook
== rRight
.mnSupbook
) &&
424 (rLeft
.mnFirstSBTab
== rRight
.mnFirstSBTab
) &&
425 (rLeft
.mnLastSBTab
== rRight
.mnLastSBTab
);
428 // ----------------------------------------------------------------------------
430 /** Contains a list of all SUPBOOK records and index arrays of external sheets. */
431 class XclExpSupbookBuffer
: public XclExpRecordBase
, protected XclExpRoot
434 explicit XclExpSupbookBuffer( const XclExpRoot
& rRoot
);
436 /** Finds SUPBOOK index and SUPBOOK sheet range from given Excel sheet range.
437 @return An XTI structure containing SUPBOOK and sheet indexes. */
438 XclExpXti
GetXti( sal_uInt16 nFirstXclTab
, sal_uInt16 nLastXclTab
,
439 XclExpRefLogEntry
* pRefLogEntry
= 0 ) const;
441 /** Stores all cells in the given range in a CRN record list. */
442 void StoreCellRange( const ScRange
& rRange
);
444 void StoreCell( sal_uInt16 nFileId
, const String
& rTabName
, const ScAddress
& rCell
);
445 void StoreCellRange( sal_uInt16 nFileId
, const String
& rTabName
, const ScRange
& rRange
);
447 /** Finds or inserts an EXTERNNAME record for an add-in function name.
448 @param rnSupbook Returns the index of the SUPBOOK record which contains the add-in function name.
449 @param rnExtName Returns the 1-based EXTERNNAME record index. */
451 sal_uInt16
& rnSupbook
, sal_uInt16
& rnExtName
,
452 const String
& rName
);
453 /** InsertEuroTool */
455 sal_uInt16
& rnSupbook
, sal_uInt16
& rnExtName
,
456 const String
& rName
);
457 /** Finds or inserts an EXTERNNAME record for DDE links.
458 @param rnSupbook Returns the index of the SUPBOOK record which contains the DDE link.
459 @param rnExtName Returns the 1-based EXTERNNAME record index. */
461 sal_uInt16
& rnSupbook
, sal_uInt16
& rnExtName
,
462 const String
& rApplic
, const String
& rTopic
, const String
& rItem
);
465 sal_uInt16
& rnSupbook
, sal_uInt16
& rnExtName
, const String
& rUrl
,
466 const String
& rName
, const ScExternalRefCache::TokenArrayRef pArray
);
468 XclExpXti
GetXti( sal_uInt16 nFileId
, const String
& rTabName
, sal_uInt16 nXclTabSpan
,
469 XclExpRefLogEntry
* pRefLogEntry
= NULL
);
471 /** Writes all SUPBOOK records with their sub records. */
472 virtual void Save( XclExpStream
& rStrm
);
476 sal_uInt16 mnSupbook
; /// SUPBOOK index for an Excel sheet.
477 sal_uInt16 mnSBTab
; /// Sheet name index in SUPBOOK for an Excel sheet.
478 inline void Set( sal_uInt16 nSupbook
, sal_uInt16 nSBTab
)
479 { mnSupbook
= nSupbook
; mnSBTab
= nSBTab
; }
481 typedef ::std::vector
< XclExpSBIndex
> XclExpSBIndexVec
;
484 typedef XclExpRecordList
< XclExpSupbook
> XclExpSupbookList
;
485 typedef XclExpSupbookList::RecordRefType XclExpSupbookRef
;
488 /** Searches for the SUPBOOK record containing the passed document URL.
489 @param rxSupbook (out-param) Returns a reference to the SUPBOOK record, or 0.
490 @param rnIndex (out-param) Returns the list index, if the SUPBOOK exists.
491 @return True, if the SUPBOOK record exists (out-parameters are valid). */
492 bool GetSupbookUrl( XclExpSupbookRef
& rxSupbook
, sal_uInt16
& rnIndex
,
493 const String
& rUrl
) const;
494 /** Searches for the SUPBOOK record containing the passed DDE link.
495 @param rxSupbook (out-param) Returns a reference to the SUPBOOK record, or 0.
496 @param rnIndex (out-param) Returns the list index, if the SUPBOOK exists.
497 @return True, if the SUPBOOK record exists (out-parameters are valid). */
498 bool GetSupbookDde( XclExpSupbookRef
& rxSupbook
, sal_uInt16
& rnIndex
,
499 const String
& rApplic
, const String
& rTopic
) const;
501 /** Appends a new SUPBOOK to the list.
502 @return The list index of the SUPBOOK record. */
503 sal_uInt16
Append( XclExpSupbookRef xSupbook
);
506 XclExpSupbookList maSupbookList
; /// List of all SUPBOOK records.
507 XclExpSBIndexVec maSBIndexVec
; /// SUPBOOK and sheet name index for each Excel sheet.
508 sal_uInt16 mnOwnDocSB
; /// Index to SUPBOOK for own document.
509 sal_uInt16 mnAddInSB
; /// Index to add-in SUPBOOK.
512 // Export link manager ========================================================
514 /** Abstract base class for implementation classes of the link manager. */
515 class XclExpLinkManagerImpl
: protected XclExpRoot
518 /** Derived classes search for an EXTSHEET structure for the given Calc sheet range. */
519 virtual void FindExtSheet( sal_uInt16
& rnExtSheet
,
520 sal_uInt16
& rnFirstXclTab
, sal_uInt16
& rnLastXclTab
,
521 SCTAB nFirstScTab
, SCTAB nLastScTab
,
522 XclExpRefLogEntry
* pRefLogEntry
) = 0;
523 /** Derived classes search for a special EXTERNSHEET index for the own document. */
524 virtual sal_uInt16
FindExtSheet( sal_Unicode cCode
) = 0;
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
) = 0;
530 /** Derived classes store all cells in the given range in a CRN record list. */
531 virtual void StoreCellRange( const ScSingleRefData
& rRef1
, const ScSingleRefData
& rRef2
) = 0;
533 virtual void StoreCell( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef
) = 0;
534 virtual void StoreCellRange( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef1
, const ScSingleRefData
& rRef2
) = 0;
536 /** Derived classes find or insert an EXTERNNAME record for an add-in function name. */
537 virtual bool InsertAddIn(
538 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
539 const String
& rName
) = 0;
540 /** InsertEuroTool */
541 virtual bool InsertEuroTool(
542 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
543 const String
& rName
) = 0;
545 /** Derived classes find or insert an EXTERNNAME record for DDE links. */
546 virtual bool InsertDde(
547 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
548 const String
& rApplic
, const String
& rTopic
, const String
& rItem
) = 0;
550 virtual bool InsertExtName(
551 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
, const String
& rUrl
,
552 const String
& rName
, const ScExternalRefCache::TokenArrayRef pArray
) = 0;
554 /** Derived classes write the entire link table to the passed stream. */
555 virtual void Save( XclExpStream
& rStrm
) = 0;
558 explicit XclExpLinkManagerImpl( const XclExpRoot
& rRoot
);
561 // ----------------------------------------------------------------------------
563 /** Implementation of the link manager for BIFF5/BIFF7. */
564 class XclExpLinkManagerImpl5
: public XclExpLinkManagerImpl
567 explicit XclExpLinkManagerImpl5( const XclExpRoot
& rRoot
);
569 virtual void FindExtSheet( sal_uInt16
& rnExtSheet
,
570 sal_uInt16
& rnFirstXclTab
, sal_uInt16
& rnLastXclTab
,
571 SCTAB nFirstScTab
, SCTAB nLastScTab
,
572 XclExpRefLogEntry
* pRefLogEntry
);
573 virtual sal_uInt16
FindExtSheet( sal_Unicode cCode
);
575 virtual void FindExtSheet( sal_uInt16 nFileId
, const String
& rTabName
, sal_uInt16 nXclTabSpan
,
576 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnFirstSBTab
, sal_uInt16
& rnLastSBTab
,
577 XclExpRefLogEntry
* pRefLogEntry
);
579 virtual void StoreCellRange( const ScSingleRefData
& rRef1
, const ScSingleRefData
& rRef2
);
581 virtual void StoreCell( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef
);
582 virtual void StoreCellRange( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef1
, const ScSingleRefData
& rRef2
);
584 virtual bool InsertAddIn(
585 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
586 const String
& rName
);
588 /** InsertEuroTool */
589 virtual bool InsertEuroTool(
590 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
591 const String
& rName
);
593 virtual bool InsertDde(
594 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
595 const String
& rApplic
, const String
& rTopic
, const String
& rItem
);
597 virtual bool InsertExtName(
598 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
, const String
& rUrl
,
599 const String
& rName
, const ScExternalRefCache::TokenArrayRef pArray
);
601 virtual void Save( XclExpStream
& rStrm
);
604 typedef XclExpRecordList
< XclExpExternSheet
> XclExpExtSheetList
;
605 typedef XclExpExtSheetList::RecordRefType XclExpExtSheetRef
;
606 typedef ::std::map
< SCTAB
, sal_uInt16
> XclExpIntTabMap
;
607 typedef ::std::map
< sal_Unicode
, sal_uInt16
> XclExpCodeMap
;
610 /** Returns the number of EXTERNSHEET records. */
611 sal_uInt16
GetExtSheetCount() const;
613 /** Appends an internal EXTERNSHEET record and returns the one-based index. */
614 sal_uInt16
AppendInternal( XclExpExtSheetRef xExtSheet
);
615 /** Creates all EXTERNSHEET records for internal sheets on first call. */
616 void CreateInternal();
618 /** Returns the specified internal EXTERNSHEET record. */
619 XclExpExtSheetRef
GetInternal( sal_uInt16 nExtSheet
);
620 /** Returns the EXTERNSHEET index of an internal Calc sheet, or a deleted reference. */
621 XclExpExtSheetRef
FindInternal( sal_uInt16
& rnExtSheet
, sal_uInt16
& rnXclTab
, SCTAB nScTab
);
622 /** Finds or creates the EXTERNSHEET index of an internal special EXTERNSHEET. */
623 XclExpExtSheetRef
FindInternal( sal_uInt16
& rnExtSheet
, sal_Unicode cCode
);
626 XclExpExtSheetList maExtSheetList
; /// List with EXTERNSHEET records.
627 XclExpIntTabMap maIntTabMap
; /// Maps internal Calc sheets to EXTERNSHEET records.
628 XclExpCodeMap maCodeMap
; /// Maps special external codes to EXTERNSHEET records.
631 // ----------------------------------------------------------------------------
633 /** Implementation of the link manager for BIFF8. */
634 class XclExpLinkManagerImpl8
: public XclExpLinkManagerImpl
637 explicit XclExpLinkManagerImpl8( const XclExpRoot
& rRoot
);
639 virtual void FindExtSheet( sal_uInt16
& rnExtSheet
,
640 sal_uInt16
& rnFirstXclTab
, sal_uInt16
& rnLastXclTab
,
641 SCTAB nFirstScTab
, SCTAB nLastScTab
,
642 XclExpRefLogEntry
* pRefLogEntry
);
643 virtual sal_uInt16
FindExtSheet( sal_Unicode cCode
);
645 virtual void FindExtSheet( sal_uInt16 nFileId
, const String
& rTabName
, sal_uInt16 nXclTabSpan
,
646 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnFirstSBTab
, sal_uInt16
& rnLastSBTab
,
647 XclExpRefLogEntry
* pRefLogEntry
);
649 virtual void StoreCellRange( const ScSingleRefData
& rRef1
, const ScSingleRefData
& rRef2
);
651 virtual void StoreCell( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef
);
652 virtual void StoreCellRange( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef1
, const ScSingleRefData
& rRef2
);
654 virtual bool InsertAddIn(
655 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
656 const String
& rName
);
657 /** InsertEuroTool */
658 virtual bool InsertEuroTool(
659 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
660 const String
& rName
);
662 virtual bool InsertDde(
663 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
664 const String
& rApplic
, const String
& rTopic
, const String
& rItem
);
666 virtual bool InsertExtName(
667 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
, const String
& rUrl
,
668 const String
& rName
, const ScExternalRefCache::TokenArrayRef pArray
);
670 virtual void Save( XclExpStream
& rStrm
);
673 /** Searches for or inserts a new XTI structure.
674 @return The 0-based list index of the XTI structure. */
675 sal_uInt16
InsertXti( const XclExpXti
& rXti
);
678 typedef ::std::vector
< XclExpXti
> XclExpXtiVec
;
680 XclExpSupbookBuffer maSBBuffer
; /// List of all SUPBOOK records.
681 XclExpXtiVec maXtiVec
; /// List of XTI structures for the EXTERNSHEET record.
684 // ============================================================================
685 // *** Implementation ***
686 // ============================================================================
688 // Excel sheet indexes ========================================================
690 const sal_uInt8 EXC_TABBUF_IGNORE
= 0x01; /// Sheet will be ignored completely.
691 const sal_uInt8 EXC_TABBUF_EXTERN
= 0x02; /// Sheet is linked externally.
692 const sal_uInt8 EXC_TABBUF_SKIPMASK
= 0x0F; /// Sheet will be skipped, if any flag is set.
693 const sal_uInt8 EXC_TABBUF_VISIBLE
= 0x10; /// Sheet is visible.
694 const sal_uInt8 EXC_TABBUF_SELECTED
= 0x20; /// Sheet is selected.
695 const sal_uInt8 EXC_TABBUF_MIRRORED
= 0x40; /// Sheet is mirrored (right-to-left).
697 // ----------------------------------------------------------------------------
699 XclExpTabInfo::XclExpTabInfo( const XclExpRoot
& rRoot
) :
706 mnFirstVisXclTab( 0 )
708 ScDocument
& rDoc
= GetDoc();
709 ScExtDocOptions
& rDocOpt
= GetExtDocOptions();
711 mnScCnt
= rDoc
.GetTableCount();
714 SCTAB nFirstVisScTab
= SCTAB_INVALID
; // first visible sheet
715 SCTAB nFirstExpScTab
= SCTAB_INVALID
; // first exported sheet
717 // --- initialize the flags in the index buffer ---
719 maTabInfoVec
.resize( mnScCnt
);
720 for( nScTab
= 0; nScTab
< mnScCnt
; ++nScTab
)
722 // ignored sheets (skipped by export, with invalid Excel sheet index)
723 if( rDoc
.IsScenario( nScTab
) )
725 SetFlag( nScTab
, EXC_TABBUF_IGNORE
);
728 // external sheets (skipped, but with valid Excel sheet index for ref's)
729 else if( rDoc
.GetLinkMode( nScTab
) == SC_LINK_VALUE
)
731 SetFlag( nScTab
, EXC_TABBUF_EXTERN
);
738 rDoc
.GetName( nScTab
, maTabInfoVec
[ nScTab
].maScName
);
740 // remember first exported sheet
741 if( nFirstExpScTab
== SCTAB_INVALID
)
742 nFirstExpScTab
= nScTab
;
743 // remember first visible exported sheet
744 if( (nFirstVisScTab
== SCTAB_INVALID
) && rDoc
.IsVisible( nScTab
) )
745 nFirstVisScTab
= nScTab
;
747 // sheet visible (only exported sheets)
748 SetFlag( nScTab
, EXC_TABBUF_VISIBLE
, rDoc
.IsVisible( nScTab
) );
750 // sheet selected (only exported sheets)
751 if( const ScExtTabSettings
* pTabSett
= rDocOpt
.GetTabSettings( nScTab
) )
752 SetFlag( nScTab
, EXC_TABBUF_SELECTED
, pTabSett
->mbSelected
);
754 // sheet mirrored (only exported sheets)
755 SetFlag( nScTab
, EXC_TABBUF_MIRRORED
, rDoc
.IsLayoutRTL( nScTab
) );
759 // --- visible/selected sheets ---
761 SCTAB nDisplScTab
= rDocOpt
.GetDocSettings().mnDisplTab
;
763 // #112908# find first visible exported sheet
764 if( (nFirstVisScTab
== SCTAB_INVALID
) || !IsExportTab( nFirstVisScTab
) )
766 // no exportable visible sheet -> use first exportable sheet
767 nFirstVisScTab
= nFirstExpScTab
;
768 if( (nFirstVisScTab
== SCTAB_INVALID
) || !IsExportTab( nFirstVisScTab
) )
770 // no exportable sheet at all -> use active sheet and export it
771 nFirstVisScTab
= nDisplScTab
;
772 SetFlag( nFirstVisScTab
, EXC_TABBUF_SKIPMASK
, false ); // clear skip flags
774 SetFlag( nFirstVisScTab
, EXC_TABBUF_VISIBLE
); // must be visible, even if originally hidden
777 // find currently displayed sheet
778 if( !IsExportTab( nDisplScTab
) ) // selected sheet not exported (i.e. scenario) -> use first visible
779 nDisplScTab
= nFirstVisScTab
;
780 SetFlag( nDisplScTab
, EXC_TABBUF_VISIBLE
| EXC_TABBUF_SELECTED
);
782 // number of selected sheets
783 for( nScTab
= 0; nScTab
< mnScCnt
; ++nScTab
)
784 if( IsSelectedTab( nScTab
) )
787 // --- calculate resulting Excel sheet indexes ---
790 mnFirstVisXclTab
= GetXclTab( nFirstVisScTab
);
791 mnDisplXclTab
= GetXclTab( nDisplScTab
);
793 // --- sorted vectors for index lookup ---
798 bool XclExpTabInfo::IsExportTab( SCTAB nScTab
) const
800 /* Check sheet index before to avoid assertion in GetFlag(). */
801 return (nScTab
< mnScCnt
) && !GetFlag( nScTab
, EXC_TABBUF_SKIPMASK
);
804 bool XclExpTabInfo::IsExternalTab( SCTAB nScTab
) const
806 /* Check sheet index before to avoid assertion (called from formula
807 compiler also for deleted references). */
808 return (nScTab
< mnScCnt
) && GetFlag( nScTab
, EXC_TABBUF_EXTERN
);
811 bool XclExpTabInfo::IsVisibleTab( SCTAB nScTab
) const
813 return GetFlag( nScTab
, EXC_TABBUF_VISIBLE
);
816 bool XclExpTabInfo::IsSelectedTab( SCTAB nScTab
) const
818 return GetFlag( nScTab
, EXC_TABBUF_SELECTED
);
821 bool XclExpTabInfo::IsDisplayedTab( SCTAB nScTab
) const
823 DBG_ASSERT( nScTab
< mnScCnt
, "XclExpTabInfo::IsActiveTab - sheet out of range" );
824 return GetXclTab( nScTab
) == mnDisplXclTab
;
827 bool XclExpTabInfo::IsMirroredTab( SCTAB nScTab
) const
829 return GetFlag( nScTab
, EXC_TABBUF_MIRRORED
);
832 const String
& XclExpTabInfo::GetScTabName( SCTAB nScTab
) const
834 DBG_ASSERT( nScTab
< mnScCnt
, "XclExpTabInfo::IsActiveTab - sheet out of range" );
835 return (nScTab
< mnScCnt
) ? maTabInfoVec
[ nScTab
].maScName
: EMPTY_STRING
;
838 sal_uInt16
XclExpTabInfo::GetXclTab( SCTAB nScTab
) const
840 return (nScTab
< mnScCnt
) ? maTabInfoVec
[ nScTab
].mnXclTab
: EXC_TAB_DELETED
;
843 SCTAB
XclExpTabInfo::GetRealScTab( SCTAB nSortedScTab
) const
845 DBG_ASSERT( nSortedScTab
< mnScCnt
, "XclExpTabInfo::GetRealScTab - sheet out of range" );
846 return (nSortedScTab
< mnScCnt
) ? maFromSortedVec
[ nSortedScTab
] : SCTAB_INVALID
;
849 //UNUSED2009-05 SCTAB XclExpTabInfo::GetSortedScTab( SCTAB nScTab ) const
851 //UNUSED2009-05 DBG_ASSERT( nScTab < mnScCnt, "XclExpTabInfo::GetSortedScTab - sheet out of range" );
852 //UNUSED2009-05 return (nScTab < mnScCnt) ? maToSortedVec[ nScTab ] : SCTAB_INVALID;
855 bool XclExpTabInfo::GetFlag( SCTAB nScTab
, sal_uInt8 nFlags
) const
857 DBG_ASSERT( nScTab
< mnScCnt
, "XclExpTabInfo::GetFlag - sheet out of range" );
858 return (nScTab
< mnScCnt
) && ::get_flag( maTabInfoVec
[ nScTab
].mnFlags
, nFlags
);
861 void XclExpTabInfo::SetFlag( SCTAB nScTab
, sal_uInt8 nFlags
, bool bSet
)
863 DBG_ASSERT( nScTab
< mnScCnt
, "XclExpTabInfo::SetFlag - sheet out of range" );
864 if( nScTab
< mnScCnt
)
865 ::set_flag( maTabInfoVec
[ nScTab
].mnFlags
, nFlags
, bSet
);
868 void XclExpTabInfo::CalcXclIndexes()
870 sal_uInt16 nXclTab
= 0;
873 // --- pass 1: process regular sheets ---
874 for( nScTab
= 0; nScTab
< mnScCnt
; ++nScTab
)
876 if( IsExportTab( nScTab
) )
878 maTabInfoVec
[ nScTab
].mnXclTab
= nXclTab
;
882 maTabInfoVec
[ nScTab
].mnXclTab
= EXC_TAB_DELETED
;
886 // --- pass 2: process external sheets (nXclTab continues) ---
887 for( nScTab
= 0; nScTab
< mnScCnt
; ++nScTab
)
889 if( IsExternalTab( nScTab
) )
891 maTabInfoVec
[ nScTab
].mnXclTab
= nXclTab
;
897 // result: first occur all exported sheets, followed by all external sheets
900 typedef ::std::pair
< String
, SCTAB
> XclExpTabName
;
901 typedef ::std::vector
< XclExpTabName
> XclExpTabNameVec
;
903 inline bool operator<( const XclExpTabName
& rArg1
, const XclExpTabName
& rArg2
)
905 // compare the sheet names only
906 return ScGlobal::GetCollator()->compareString( rArg1
.first
, rArg2
.first
) == COMPARE_LESS
;
909 void XclExpTabInfo::CalcSortedIndexes()
911 ScDocument
& rDoc
= GetDoc();
912 XclExpTabNameVec
aVec( mnScCnt
);
915 // fill with sheet names
916 for( nScTab
= 0; nScTab
< mnScCnt
; ++nScTab
)
918 rDoc
.GetName( nScTab
, aVec
[ nScTab
].first
);
919 aVec
[ nScTab
].second
= nScTab
;
921 ::std::sort( aVec
.begin(), aVec
.end() );
923 // fill index vectors from sorted sheet name vector
924 maFromSortedVec
.resize( mnScCnt
);
925 maToSortedVec
.resize( mnScCnt
);
926 for( nScTab
= 0; nScTab
< mnScCnt
; ++nScTab
)
928 maFromSortedVec
[ nScTab
] = aVec
[ nScTab
].second
;
929 maToSortedVec
[ aVec
[ nScTab
].second
] = nScTab
;
933 // External names =============================================================
935 XclExpExtNameBase::XclExpExtNameBase(
936 const XclExpRoot
& rRoot
, const String
& rName
, sal_uInt16 nFlags
) :
937 XclExpRecord( EXC_ID_EXTERNNAME
),
940 mxName( XclExpStringHelper::CreateString( rRoot
, rName
, EXC_STR_8BITLENGTH
) ),
943 DBG_ASSERT( maName
.Len() <= 255, "XclExpExtNameBase::XclExpExtNameBase - string too long" );
944 SetRecSize( 6 + mxName
->GetSize() );
947 XclExpExtNameBase::~XclExpExtNameBase()
951 void XclExpExtNameBase::WriteBody( XclExpStream
& rStrm
)
956 WriteAddData( rStrm
);
959 void XclExpExtNameBase::WriteAddData( XclExpStream
& /*rStrm*/ )
963 // ----------------------------------------------------------------------------
965 XclExpExtNameAddIn::XclExpExtNameAddIn( const XclExpRoot
& rRoot
, const String
& rName
) :
966 XclExpExtNameBase( rRoot
, rName
)
971 void XclExpExtNameAddIn::WriteAddData( XclExpStream
& rStrm
)
973 // write a #REF! error formula
974 rStrm
<< sal_uInt16( 2 ) << EXC_TOKID_ERR
<< EXC_ERR_REF
;
977 // ----------------------------------------------------------------------------
979 XclExpExtNameDde::XclExpExtNameDde( const XclExpRoot
& rRoot
,
980 const String
& rName
, sal_uInt16 nFlags
, const ScMatrix
* pResults
) :
981 XclExpExtNameBase( rRoot
, rName
, nFlags
)
985 mxMatrix
.reset( new XclExpCachedMatrix( *pResults
) );
986 AddRecSize( mxMatrix
->GetSize() );
990 void XclExpExtNameDde::WriteAddData( XclExpStream
& rStrm
)
993 mxMatrix
->Save( rStrm
);
996 // ----------------------------------------------------------------------------
998 XclExpExtName::XclExpExtName( const XclExpRoot
& rRoot
, const XclExpSupbook
& rSupbook
,
999 const String
& rName
, const ScExternalRefCache::TokenArrayRef pArray
) :
1000 XclExpExtNameBase( rRoot
, rName
),
1001 mrSupbook(rSupbook
),
1002 mpArray(pArray
->Clone())
1006 void XclExpExtName::WriteAddData( XclExpStream
& rStrm
)
1008 // Write only if it only has a single token that is either a cell or cell
1009 // range address. Excel just writes '02 00 1C 17' for all the other types
1010 // of external names.
1014 if (mpArray
->GetLen() != 1)
1017 const ScToken
* p
= static_cast<const ScToken
*>(mpArray
->First());
1018 if (p
->GetOpCode() != ocExternalRef
)
1021 switch (p
->GetType())
1023 case svExternalSingleRef
:
1025 const ScSingleRefData
& rRef
= p
->GetSingleRef();
1026 if (rRef
.IsTabRel())
1029 bool bColRel
= rRef
.IsColRel();
1030 bool bRowRel
= rRef
.IsRowRel();
1031 sal_uInt16 nCol
= static_cast< sal_uInt16
>( bColRel
? rRef
.nRelCol
: rRef
.nCol
);
1032 sal_uInt16 nRow
= static_cast< sal_uInt16
>( bRowRel
? rRef
.nRelRow
: rRef
.nRow
);
1033 if (bColRel
) nCol
|= 0x4000;
1034 if (bRowRel
) nCol
|= 0x8000;
1036 const String
& rTabName
= p
->GetString();
1037 sal_uInt16 nSBTab
= mrSupbook
.GetTabIndex(rTabName
);
1040 rStrm
<< static_cast<sal_uInt16
>(9);
1041 // operator token (3A for cell reference)
1042 rStrm
<< static_cast<sal_uInt8
>(0x3A);
1043 // cell address (Excel's address has 2 sheet IDs.)
1044 rStrm
<< nSBTab
<< nSBTab
<< nRow
<< nCol
;
1047 case svExternalDoubleRef
:
1049 const ScComplexRefData
& rRef
= p
->GetDoubleRef();
1050 const ScSingleRefData
& r1
= rRef
.Ref1
;
1051 const ScSingleRefData
& r2
= rRef
.Ref2
;
1052 if (r1
.IsTabRel() || r2
.IsTabRel())
1055 sal_uInt16 nTab1
= r1
.nTab
;
1056 sal_uInt16 nTab2
= r2
.nTab
;
1057 bool bCol1Rel
= r1
.IsColRel();
1058 bool bRow1Rel
= r1
.IsRowRel();
1059 bool bCol2Rel
= r2
.IsColRel();
1060 bool bRow2Rel
= r2
.IsRowRel();
1062 sal_uInt16 nCol1
= static_cast< sal_uInt16
>( bCol1Rel
? r1
.nRelCol
: r1
.nCol
);
1063 sal_uInt16 nCol2
= static_cast< sal_uInt16
>( bCol2Rel
? r2
.nRelCol
: r2
.nCol
);
1064 sal_uInt16 nRow1
= static_cast< sal_uInt16
>( bRow1Rel
? r1
.nRelRow
: r1
.nRow
);
1065 sal_uInt16 nRow2
= static_cast< sal_uInt16
>( bRow2Rel
? r2
.nRelRow
: r2
.nRow
);
1066 if (bCol1Rel
) nCol1
|= 0x4000;
1067 if (bRow1Rel
) nCol1
|= 0x8000;
1068 if (bCol2Rel
) nCol2
|= 0x4000;
1069 if (bRow2Rel
) nCol2
|= 0x8000;
1071 const String
& rTabName
= p
->GetString();
1072 sal_uInt16 nSBTab
= mrSupbook
.GetTabIndex(rTabName
);
1074 // size is always 13 (0x0D)
1075 rStrm
<< static_cast<sal_uInt16
>(13);
1076 // operator token (3B for area reference)
1077 rStrm
<< static_cast<sal_uInt8
>(0x3B);
1078 // range (area) address
1079 sal_uInt16 nSBTab2
= nSBTab
+ nTab2
- nTab1
;
1080 rStrm
<< nSBTab
<< nSBTab2
<< nRow1
<< nRow2
<< nCol1
<< nCol2
;
1089 // special value for #REF! (02 00 1C 17)
1090 rStrm
<< static_cast<sal_uInt16
>(2) << EXC_TOKID_ERR
<< EXC_ERR_REF
;
1093 // List of external names =====================================================
1095 XclExpExtNameBuffer::XclExpExtNameBuffer( const XclExpRoot
& rRoot
) :
1100 sal_uInt16
XclExpExtNameBuffer::InsertAddIn( const String
& rName
)
1102 sal_uInt16 nIndex
= GetIndex( rName
);
1103 return nIndex
? nIndex
: AppendNew( new XclExpExtNameAddIn( GetRoot(), rName
) );
1106 sal_uInt16
XclExpExtNameBuffer::InsertEuroTool( const String
& rName
)
1108 sal_uInt16 nIndex
= GetIndex( rName
);
1109 return nIndex
? nIndex
: AppendNew( new XclExpExtNameBase( GetRoot(), rName
) );
1112 sal_uInt16
XclExpExtNameBuffer::InsertDde(
1113 const String
& rApplic
, const String
& rTopic
, const String
& rItem
)
1115 sal_uInt16 nIndex
= GetIndex( rItem
);
1119 if( GetDoc().FindDdeLink( rApplic
, rTopic
, rItem
, SC_DDE_IGNOREMODE
, nPos
) )
1121 // create the leading 'StdDocumentName' EXTERNNAME record
1122 if( maNameList
.IsEmpty() )
1123 AppendNew( new XclExpExtNameDde(
1124 GetRoot(), CREATE_STRING( "StdDocumentName" ), EXC_EXTN_EXPDDE_STDDOC
) );
1126 // try to find DDE result array, but create EXTERNNAME record without them too
1127 const ScMatrix
* pScMatrix
= GetDoc().GetDdeLinkResultMatrix( nPos
);
1128 nIndex
= AppendNew( new XclExpExtNameDde( GetRoot(), rItem
, EXC_EXTN_EXPDDE
, pScMatrix
) );
1134 sal_uInt16
XclExpExtNameBuffer::InsertExtName( const XclExpSupbook
& rSupbook
,
1135 const String
& rName
, const ScExternalRefCache::TokenArrayRef pArray
)
1137 sal_uInt16 nIndex
= GetIndex( rName
);
1138 return nIndex
? nIndex
: AppendNew( new XclExpExtName( GetRoot(), rSupbook
, rName
, pArray
) );
1141 void XclExpExtNameBuffer::Save( XclExpStream
& rStrm
)
1143 maNameList
.Save( rStrm
);
1146 sal_uInt16
XclExpExtNameBuffer::GetIndex( const String
& rName
) const
1148 for( size_t nPos
= 0, nSize
= maNameList
.GetSize(); nPos
< nSize
; ++nPos
)
1149 if( maNameList
.GetRecord( nPos
)->GetName() == rName
)
1150 return static_cast< sal_uInt16
>( nPos
+ 1 );
1154 sal_uInt16
XclExpExtNameBuffer::AppendNew( XclExpExtNameBase
* pExtName
)
1156 XclExpExtNameRef
xExtName( pExtName
);
1157 size_t nSize
= maNameList
.GetSize();
1158 if( nSize
< 0x7FFF )
1160 maNameList
.AppendRecord( xExtName
);
1161 return static_cast< sal_uInt16
>( nSize
+ 1 );
1166 // Cached external cells ======================================================
1168 XclExpCrn::XclExpCrn( SCCOL nScCol
, SCROW nScRow
, sal_uInt8 nId
, sal_uInt32 nAddLen
) :
1169 XclExpRecord( EXC_ID_CRN
, 5 + nAddLen
),
1170 mnXclCol( static_cast< sal_uInt16
>( nScCol
) ),
1171 mnXclRow( static_cast< sal_uInt16
>( nScRow
) ),
1176 void XclExpCrn::WriteBody( XclExpStream
& rStrm
)
1178 rStrm
<< static_cast< sal_uInt8
>( mnXclCol
)
1179 << static_cast< sal_uInt8
>( mnXclCol
)
1182 WriteAddData( rStrm
);
1185 // ----------------------------------------------------------------------------
1187 XclExpCrnDouble::XclExpCrnDouble( SCCOL nScCol
, SCROW nScRow
, double fVal
) :
1188 XclExpCrn( nScCol
, nScRow
, EXC_CACHEDVAL_DOUBLE
, 8 ),
1193 void XclExpCrnDouble::WriteAddData( XclExpStream
& rStrm
)
1198 // ----------------------------------------------------------------------------
1200 XclExpCrnString::XclExpCrnString( SCCOL nScCol
, SCROW nScRow
, const String
& rText
) :
1201 XclExpCrn( nScCol
, nScRow
, EXC_CACHEDVAL_STRING
),
1204 // set correct size after maText is initialized
1205 AddRecSize( maText
.GetSize() );
1208 void XclExpCrnString::WriteAddData( XclExpStream
& rStrm
)
1213 // ----------------------------------------------------------------------------
1215 XclExpCrnBool::XclExpCrnBool( SCCOL nScCol
, SCROW nScRow
, bool bBoolVal
) :
1216 XclExpCrn( nScCol
, nScRow
, EXC_CACHEDVAL_BOOL
, 8 ),
1217 mnBool( bBoolVal
? 1 : 0 )
1221 void XclExpCrnBool::WriteAddData( XclExpStream
& rStrm
)
1224 rStrm
.WriteZeroBytes( 6 );
1227 // Cached cells of a sheet ====================================================
1229 XclExpXct::XclExpXct( const String
& rTabName
, sal_uInt16 nSBTab
) :
1230 XclExpRecord( EXC_ID_XCT
, 4 ),
1231 maTabName( rTabName
),
1236 void XclExpXct::StoreCellRange( const XclExpRoot
& rRoot
, const ScRange
& rRange
)
1238 // #i70418# restrict size of external range to prevent memory overflow
1239 if( (rRange
.aEnd
.Col() - rRange
.aStart
.Col()) * (rRange
.aEnd
.Row() - rRange
.aStart
.Row()) > 1024 )
1242 ScDocument
& rDoc
= rRoot
.GetDoc();
1243 SvNumberFormatter
& rFormatter
= rRoot
.GetFormatter();
1244 SCTAB nScTab
= rRange
.aStart
.Tab();
1245 SCCOL nScLastCol
= rRange
.aEnd
.Col();
1246 SCROW nScLastRow
= rRange
.aEnd
.Row();
1248 for( SCROW nScRow
= rRange
.aStart
.Row(); nScRow
<= nScLastRow
; ++nScRow
)
1250 for( SCCOL nScCol
= rRange
.aStart
.Col(); nScCol
<= nScLastCol
; ++nScCol
)
1252 if( !maUsedCells
.IsCellMarked( nScCol
, nScRow
, TRUE
) )
1255 if( rDoc
.HasValueData( nScCol
, nScRow
, nScTab
) )
1257 ScAddress
aAddr( nScCol
, nScRow
, nScTab
);
1258 double fVal
= rDoc
.GetValue( aAddr
);
1259 ULONG nFormat
= rDoc
.GetNumberFormat( aAddr
);
1260 short nType
= rFormatter
.GetType( nFormat
);
1261 bool bIsBool
= (nType
== NUMBERFORMAT_LOGICAL
);
1263 if( !bIsBool
&& ((nFormat
% SV_COUNTRY_LANGUAGE_OFFSET
) == 0) &&
1264 (rDoc
.GetCellType( aAddr
) == CELLTYPE_FORMULA
) )
1265 if( ScFormulaCell
* pCell
= static_cast< ScFormulaCell
* >( rDoc
.GetCell( aAddr
) ) )
1266 bIsBool
= (pCell
->GetFormatType() == NUMBERFORMAT_LOGICAL
);
1268 if( bIsBool
&& ((fVal
== 0.0) || (fVal
== 1.0)) )
1269 xCrn
.reset( new XclExpCrnBool( nScCol
, nScRow
, (fVal
== 1.0) ) );
1271 xCrn
.reset( new XclExpCrnDouble( nScCol
, nScRow
, fVal
) );
1276 rDoc
.GetString( nScCol
, nScRow
, nScTab
, aText
);
1277 xCrn
.reset( new XclExpCrnString( nScCol
, nScRow
, aText
) );
1279 maCrnList
.AppendRecord( xCrn
);
1284 maUsedCells
.SetMultiMarkArea( rRange
);
1287 void XclExpXct::StoreCell( const XclExpRoot
& /*rRoot*/, const ScAddress
& rCell
, const formula::FormulaToken
& rToken
)
1289 switch (rToken
.GetType())
1294 new XclExpCrnString(rCell
.Col(), rCell
.Row(), rToken
.GetString()));
1295 maCrnList
.AppendRecord(xCrn
);
1301 new XclExpCrnDouble(rCell
.Col(), rCell
.Row(), rToken
.GetDouble()));
1302 maCrnList
.AppendRecord(xCrn
);
1308 new XclExpCrnDouble(rCell
.Col(), rCell
.Row(), 0.0));
1309 maCrnList
.AppendRecord(xCrn
);
1317 void XclExpXct::StoreCellRange( const XclExpRoot
& /*rRoot*/, const ScRange
& rRange
, const formula::FormulaToken
& rToken
)
1319 if (rToken
.GetType() != svMatrix
)
1322 if (rRange
.aStart
.Tab() != rRange
.aEnd
.Tab())
1323 // multi-table range is not supported here.
1326 const ScMatrix
* pMtx
= static_cast<const ScToken
*>(&rToken
)->GetMatrix();
1330 SCSIZE nCols
, nRows
;
1331 pMtx
->GetDimensions(nCols
, nRows
);
1332 const ScAddress
& s
= rRange
.aStart
;
1333 const ScAddress
& e
= rRange
.aEnd
;
1334 if (static_cast<SCCOL
>(nCols
) != e
.Col() - s
.Col() + 1 ||
1335 static_cast<SCROW
>(nRows
) != e
.Row() - s
.Row() + 1)
1341 for (SCCOL nCol
= 0; nCol
< static_cast< SCCOL
>( nCols
); ++nCol
)
1343 for (SCROW nRow
= 0; nRow
< static_cast< SCROW
>( nRows
); ++nRow
)
1345 if (pMtx
->IsString(nCol
, nRow
))
1347 XclExpCrnRef
xCrn(new XclExpCrnString(
1348 s
.Col() + nCol
, s
.Row() + nRow
, pMtx
->GetString(nCol
, nRow
)));
1349 maCrnList
.AppendRecord(xCrn
);
1351 else if (pMtx
->IsValueOrEmpty(nCol
, nRow
))
1353 XclExpCrnRef
xCrn(new XclExpCrnDouble(
1354 s
.Col() + nCol
, s
.Row() + nRow
, pMtx
->GetDouble(nCol
, nRow
)));
1355 maCrnList
.AppendRecord(xCrn
);
1361 void XclExpXct::Save( XclExpStream
& rStrm
)
1363 XclExpRecord::Save( rStrm
);
1364 maCrnList
.Save( rStrm
);
1367 void XclExpXct::WriteBody( XclExpStream
& rStrm
)
1369 sal_uInt16 nCount
= ulimit_cast
< sal_uInt16
>( maCrnList
.GetSize() );
1370 rStrm
<< nCount
<< mnSBTab
;
1373 // External documents (EXTERNSHEET/SUPBOOK), base class =======================
1375 XclExpExternSheetBase::XclExpExternSheetBase( const XclExpRoot
& rRoot
, sal_uInt16 nRecId
, sal_uInt32 nRecSize
) :
1376 XclExpRecord( nRecId
, nRecSize
),
1381 XclExpExtNameBuffer
& XclExpExternSheetBase::GetExtNameBuffer()
1384 mxExtNameBfr
.reset( new XclExpExtNameBuffer( GetRoot() ) );
1385 return *mxExtNameBfr
;
1388 void XclExpExternSheetBase::WriteExtNameBuffer( XclExpStream
& rStrm
)
1390 if( mxExtNameBfr
.is() )
1391 mxExtNameBfr
->Save( rStrm
);
1394 // External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
1396 XclExpExternSheet::XclExpExternSheet( const XclExpRoot
& rRoot
, sal_Unicode cCode
) :
1397 XclExpExternSheetBase( rRoot
, EXC_ID_EXTERNSHEET
)
1399 Init( String( cCode
) );
1402 XclExpExternSheet::XclExpExternSheet( const XclExpRoot
& rRoot
, const String
& rTabName
) :
1403 XclExpExternSheetBase( rRoot
, EXC_ID_EXTERNSHEET
)
1405 // reference to own sheet: \03<sheetname>
1406 Init( String( EXC_EXTSH_TABNAME
).Append( rTabName
) );
1409 void XclExpExternSheet::Save( XclExpStream
& rStrm
)
1411 // EXTERNSHEET record
1412 XclExpRecord::Save( rStrm
);
1413 // EXTERNNAME records
1414 WriteExtNameBuffer( rStrm
);
1417 void XclExpExternSheet::Init( const String
& rEncUrl
)
1419 DBG_ASSERT_BIFF( GetBiff() <= EXC_BIFF5
);
1420 maTabName
.AssignByte( rEncUrl
, GetTextEncoding(), EXC_STR_8BITLENGTH
);
1421 SetRecSize( maTabName
.GetSize() );
1424 sal_uInt16
XclExpExternSheet::InsertAddIn( const String
& rName
)
1426 return GetExtNameBuffer().InsertAddIn( rName
);
1429 void XclExpExternSheet::WriteBody( XclExpStream
& rStrm
)
1431 sal_uInt8 nNameSize
= static_cast< sal_uInt8
>( maTabName
.Len() );
1432 // special case: reference to own sheet (starting with '\03') needs wrong string length
1433 if( maTabName
.GetChar( 0 ) == EXC_EXTSH_TABNAME
)
1436 maTabName
.WriteBuffer( rStrm
);
1439 // External document (SUPBOOK, BIFF8) =========================================
1441 XclExpSupbook::XclExpSupbook( const XclExpRoot
& rRoot
, sal_uInt16 nXclTabCount
) :
1442 XclExpExternSheetBase( rRoot
, EXC_ID_SUPBOOK
, 4 ),
1443 meType( EXC_SBTYPE_SELF
),
1444 mnXclTabCount( nXclTabCount
)
1448 XclExpSupbook::XclExpSupbook( const XclExpRoot
& rRoot
) :
1449 XclExpExternSheetBase( rRoot
, EXC_ID_SUPBOOK
, 4 ),
1450 meType( EXC_SBTYPE_ADDIN
),
1455 XclExpSupbook::XclExpSupbook( const XclExpRoot
& rRoot
, const String
& rUrl
, XclSupbookType
) :
1456 XclExpExternSheetBase( rRoot
, EXC_ID_SUPBOOK
),
1458 maUrlEncoded( rUrl
),
1459 meType( EXC_SBTYPE_EUROTOOL
),
1462 SetRecSize( 2 + maUrlEncoded
.GetSize() );
1466 XclExpSupbook::XclExpSupbook( const XclExpRoot
& rRoot
, const String
& rUrl
) :
1467 XclExpExternSheetBase( rRoot
, EXC_ID_SUPBOOK
),
1469 maUrlEncoded( XclExpUrlHelper::EncodeUrl( rRoot
, rUrl
) ),
1470 meType( EXC_SBTYPE_EXTERN
),
1473 SetRecSize( 2 + maUrlEncoded
.GetSize() );
1475 // We need to create all tables up front to ensure the correct table order.
1476 ScExternalRefManager
* pRefMgr
= rRoot
.GetDoc().GetExternalRefManager();
1477 sal_uInt16 nFileId
= pRefMgr
->getExternalFileId(rUrl
);
1478 vector
<String
> aTabNames
;
1479 pRefMgr
->getAllCachedTableNames(nFileId
, aTabNames
);
1480 if (aTabNames
.empty())
1483 vector
<String
>::const_iterator itr
= aTabNames
.begin(), itrEnd
= aTabNames
.end();
1484 for (; itr
!= itrEnd
; ++itr
)
1485 InsertTabName(*itr
);
1488 XclExpSupbook::XclExpSupbook( const XclExpRoot
& rRoot
, const String
& rApplic
, const String
& rTopic
) :
1489 XclExpExternSheetBase( rRoot
, EXC_ID_SUPBOOK
, 4 ),
1491 maDdeTopic( rTopic
),
1492 maUrlEncoded( XclExpUrlHelper::EncodeDde( rApplic
, rTopic
) ),
1493 meType( EXC_SBTYPE_SPECIAL
),
1496 SetRecSize( 2 + maUrlEncoded
.GetSize() );
1499 bool XclExpSupbook::IsUrlLink( const String
& rUrl
) const
1501 return (meType
== EXC_SBTYPE_EXTERN
|| meType
== EXC_SBTYPE_EUROTOOL
) && (maUrl
== rUrl
);
1504 bool XclExpSupbook::IsDdeLink( const String
& rApplic
, const String
& rTopic
) const
1506 return (meType
== EXC_SBTYPE_SPECIAL
) && (maUrl
== rApplic
) && (maDdeTopic
== rTopic
);
1509 void XclExpSupbook::FillRefLogEntry( XclExpRefLogEntry
& rRefLogEntry
,
1510 sal_uInt16 nFirstSBTab
, sal_uInt16 nLastSBTab
) const
1512 rRefLogEntry
.mpUrl
= maUrlEncoded
.IsEmpty() ? 0 : &maUrlEncoded
;
1513 rRefLogEntry
.mpFirstTab
= GetTabName( nFirstSBTab
);
1514 rRefLogEntry
.mpLastTab
= GetTabName( nLastSBTab
);
1517 void XclExpSupbook::StoreCellRange( const ScRange
& rRange
, sal_uInt16 nSBTab
)
1519 XclExpXctRef xXct
= maXctList
.GetRecord( nSBTab
);
1521 xXct
->StoreCellRange( GetRoot(), rRange
);
1524 void XclExpSupbook::StoreCell( sal_uInt16 nSBTab
, const ScAddress
& rCell
, const formula::FormulaToken
& rToken
)
1526 XclExpXctRef xXct
= maXctList
.GetRecord(nSBTab
);
1530 xXct
->StoreCell(GetRoot(), rCell
, rToken
);
1533 void XclExpSupbook::StoreCellRange( sal_uInt16 nSBTab
, const ScRange
& rRange
, const formula::FormulaToken
& rToken
)
1535 if (rRange
.aStart
.Tab() != rRange
.aEnd
.Tab())
1536 // multi-table range is not allowed!
1539 XclExpXctRef xXct
= maXctList
.GetRecord(nSBTab
);
1543 xXct
->StoreCellRange(GetRoot(), rRange
, rToken
);
1546 sal_uInt16
XclExpSupbook::GetTabIndex( const String
& rTabName
) const
1548 XclExpString
aXclName(rTabName
);
1549 size_t nSize
= maXctList
.GetSize();
1550 for (size_t i
= 0; i
< nSize
; ++i
)
1552 XclExpXctRef aRec
= maXctList
.GetRecord(i
);
1553 if (aXclName
== aRec
->GetTabName())
1554 return ulimit_cast
<sal_uInt16
>(i
);
1559 sal_uInt16
XclExpSupbook::GetTabCount() const
1561 return ulimit_cast
<sal_uInt16
>(maXctList
.GetSize());
1564 sal_uInt16
XclExpSupbook::InsertTabName( const String
& rTabName
)
1566 DBG_ASSERT( meType
== EXC_SBTYPE_EXTERN
, "XclExpSupbook::InsertTabName - don't insert sheet names here" );
1567 sal_uInt16 nSBTab
= ulimit_cast
< sal_uInt16
>( maXctList
.GetSize() );
1568 XclExpXctRef
xXct( new XclExpXct( rTabName
, nSBTab
) );
1569 AddRecSize( xXct
->GetTabName().GetSize() );
1570 maXctList
.AppendRecord( xXct
);
1574 sal_uInt16
XclExpSupbook::InsertAddIn( const String
& rName
)
1576 return GetExtNameBuffer().InsertAddIn( rName
);
1579 sal_uInt16
XclExpSupbook::InsertEuroTool( const String
& rName
)
1581 return GetExtNameBuffer().InsertEuroTool( rName
);
1584 sal_uInt16
XclExpSupbook::InsertDde( const String
& rItem
)
1586 return GetExtNameBuffer().InsertDde( maUrl
, maDdeTopic
, rItem
);
1589 sal_uInt16
XclExpSupbook::InsertExtName( const String
& rName
, const ScExternalRefCache::TokenArrayRef pArray
)
1591 return GetExtNameBuffer().InsertExtName(*this, rName
, pArray
);
1594 void XclExpSupbook::Save( XclExpStream
& rStrm
)
1597 XclExpRecord::Save( rStrm
);
1598 // XCT record, CRN records
1599 maXctList
.Save( rStrm
);
1600 // EXTERNNAME records
1601 WriteExtNameBuffer( rStrm
);
1604 const XclExpString
* XclExpSupbook::GetTabName( sal_uInt16 nSBTab
) const
1606 XclExpXctRef xXct
= maXctList
.GetRecord( nSBTab
);
1607 return xXct
.is() ? &xXct
->GetTabName() : 0;
1610 void XclExpSupbook::WriteBody( XclExpStream
& rStrm
)
1614 case EXC_SBTYPE_SELF
:
1615 rStrm
<< mnXclTabCount
<< EXC_SUPB_SELF
;
1617 case EXC_SBTYPE_EXTERN
:
1618 case EXC_SBTYPE_SPECIAL
:
1619 case EXC_SBTYPE_EUROTOOL
:
1621 sal_uInt16 nCount
= ulimit_cast
< sal_uInt16
>( maXctList
.GetSize() );
1622 rStrm
<< nCount
<< maUrlEncoded
;
1624 for( size_t nPos
= 0, nSize
= maXctList
.GetSize(); nPos
< nSize
; ++nPos
)
1625 rStrm
<< maXctList
.GetRecord( nPos
)->GetTabName();
1628 case EXC_SBTYPE_ADDIN
:
1629 rStrm
<< mnXclTabCount
<< EXC_SUPB_ADDIN
;
1632 DBG_ERRORFILE( "XclExpSupbook::WriteBody - unknown SUPBOOK type" );
1636 // All SUPBOOKS in a document =================================================
1638 XclExpSupbookBuffer::XclExpSupbookBuffer( const XclExpRoot
& rRoot
) :
1639 XclExpRoot( rRoot
),
1640 mnOwnDocSB( SAL_MAX_UINT16
),
1641 mnAddInSB( SAL_MAX_UINT16
)
1643 XclExpTabInfo
& rTabInfo
= GetTabInfo();
1644 sal_uInt16 nXclCnt
= rTabInfo
.GetXclTabCount();
1645 sal_uInt16 nCodeCnt
= static_cast< sal_uInt16
>( GetExtDocOptions().GetCodeNameCount() );
1646 size_t nCount
= nXclCnt
+ rTabInfo
.GetXclExtTabCount();
1648 DBG_ASSERT( nCount
> 0, "XclExpSupbookBuffer::XclExpSupbookBuffer - no sheets to export" );
1651 maSBIndexVec
.resize( nCount
);
1653 // self-ref SUPBOOK first of list
1654 XclExpSupbookRef
xSupbook( new XclExpSupbook( GetRoot(), ::std::max( nXclCnt
, nCodeCnt
) ) );
1655 mnOwnDocSB
= Append( xSupbook
);
1656 for( sal_uInt16 nXclTab
= 0; nXclTab
< nXclCnt
; ++nXclTab
)
1657 maSBIndexVec
[ nXclTab
].Set( mnOwnDocSB
, nXclTab
);
1661 XclExpXti
XclExpSupbookBuffer::GetXti( sal_uInt16 nFirstXclTab
, sal_uInt16 nLastXclTab
,
1662 XclExpRefLogEntry
* pRefLogEntry
) const
1665 size_t nSize
= maSBIndexVec
.size();
1666 if( (nFirstXclTab
< nSize
) && (nLastXclTab
< nSize
) )
1668 // index of the SUPBOOK record
1669 aXti
.mnSupbook
= maSBIndexVec
[ nFirstXclTab
].mnSupbook
;
1671 // all sheets in the same supbook?
1672 bool bSameSB
= true;
1673 for( sal_uInt16 nXclTab
= nFirstXclTab
+ 1; bSameSB
&& (nXclTab
<= nLastXclTab
); ++nXclTab
)
1675 bSameSB
= maSBIndexVec
[ nXclTab
].mnSupbook
== aXti
.mnSupbook
;
1677 nLastXclTab
= nXclTab
- 1;
1679 aXti
.mnFirstSBTab
= maSBIndexVec
[ nFirstXclTab
].mnSBTab
;
1680 aXti
.mnLastSBTab
= maSBIndexVec
[ nLastXclTab
].mnSBTab
;
1682 // fill external reference log entry (for change tracking)
1685 pRefLogEntry
->mnFirstXclTab
= nFirstXclTab
;
1686 pRefLogEntry
->mnLastXclTab
= nLastXclTab
;
1687 XclExpSupbookRef xSupbook
= maSupbookList
.GetRecord( aXti
.mnSupbook
);
1689 xSupbook
->FillRefLogEntry( *pRefLogEntry
, aXti
.mnFirstSBTab
, aXti
.mnLastSBTab
);
1694 // special range, i.e. for deleted sheets or add-ins
1695 aXti
.mnSupbook
= mnOwnDocSB
;
1696 aXti
.mnFirstSBTab
= nFirstXclTab
;
1697 aXti
.mnLastSBTab
= nLastXclTab
;
1703 void XclExpSupbookBuffer::StoreCellRange( const ScRange
& rRange
)
1705 sal_uInt16 nXclTab
= GetTabInfo().GetXclTab( rRange
.aStart
.Tab() );
1706 if( nXclTab
< maSBIndexVec
.size() )
1708 const XclExpSBIndex
& rSBIndex
= maSBIndexVec
[ nXclTab
];
1709 XclExpSupbookRef xSupbook
= maSupbookList
.GetRecord( rSBIndex
.mnSupbook
);
1710 DBG_ASSERT( xSupbook
.is(), "XclExpSupbookBuffer::StoreCellRange - missing SUPBOOK record" );
1712 xSupbook
->StoreCellRange( rRange
, rSBIndex
.mnSBTab
);
1718 class FindSBIndexEntry
1721 explicit FindSBIndexEntry(sal_uInt16 nSupbookId
, sal_uInt16 nTabId
) :
1722 mnSupbookId(nSupbookId
), mnTabId(nTabId
) {}
1724 bool operator()(const XclExpSupbookBuffer::XclExpSBIndex
& r
) const
1726 return mnSupbookId
== r
.mnSupbook
&& mnTabId
== r
.mnSBTab
;
1730 sal_uInt16 mnSupbookId
;
1736 void XclExpSupbookBuffer::StoreCell( sal_uInt16 nFileId
, const String
& rTabName
, const ScAddress
& rCell
)
1738 ScExternalRefManager
* pRefMgr
= GetDoc().GetExternalRefManager();
1739 const String
* pUrl
= pRefMgr
->getExternalFileName(nFileId
);
1743 XclExpSupbookRef xSupbook
;
1744 sal_uInt16 nSupbookId
;
1745 if (!GetSupbookUrl(xSupbook
, nSupbookId
, *pUrl
))
1747 xSupbook
.reset(new XclExpSupbook(GetRoot(), *pUrl
));
1748 nSupbookId
= Append(xSupbook
);
1751 ScExternalRefCache::TokenRef pToken
= pRefMgr
->getSingleRefToken(nFileId
, rTabName
, rCell
, NULL
, NULL
);
1755 sal_uInt16 nSheetId
= xSupbook
->GetTabIndex(rTabName
);
1756 if (nSheetId
== EXC_NOTAB
)
1757 // specified table name not found in this SUPBOOK.
1760 FindSBIndexEntry
f(nSupbookId
, nSheetId
);
1761 XclExpSBIndexVec::iterator itrEnd
= maSBIndexVec
.end();
1762 XclExpSBIndexVec::const_iterator itr
= find_if(maSBIndexVec
.begin(), itrEnd
, f
);
1765 maSBIndexVec
.push_back(XclExpSBIndex());
1766 XclExpSBIndex
& r
= maSBIndexVec
.back();
1767 r
.mnSupbook
= nSupbookId
;
1768 r
.mnSBTab
= nSheetId
;
1771 xSupbook
->StoreCell(nSheetId
, rCell
, *pToken
);
1774 void XclExpSupbookBuffer::StoreCellRange( sal_uInt16 nFileId
, const String
& rTabName
, const ScRange
& rRange
)
1776 ScExternalRefManager
* pRefMgr
= GetDoc().GetExternalRefManager();
1777 const String
* pUrl
= pRefMgr
->getExternalFileName(nFileId
);
1781 XclExpSupbookRef xSupbook
;
1782 sal_uInt16 nSupbookId
;
1783 if (!GetSupbookUrl(xSupbook
, nSupbookId
, *pUrl
))
1785 xSupbook
.reset(new XclExpSupbook(GetRoot(), *pUrl
));
1786 nSupbookId
= Append(xSupbook
);
1789 SCTAB nTabCount
= rRange
.aEnd
.Tab() - rRange
.aStart
.Tab() + 1;
1791 // If this is a multi-table range, get token for each table.
1792 vector
<FormulaToken
*> aMatrixList
;
1793 aMatrixList
.reserve(nTabCount
);
1795 // This is a new'ed instance, so we must manage its life cycle here.
1796 ScExternalRefCache::TokenArrayRef pArray
= pRefMgr
->getDoubleRefTokens(nFileId
, rTabName
, rRange
, NULL
);
1800 for (FormulaToken
* p
= pArray
->First(); p
; p
= pArray
->Next())
1802 if (p
->GetType() == svMatrix
)
1803 aMatrixList
.push_back(p
);
1804 else if (p
->GetOpCode() != ocSep
)
1806 // This is supposed to be ocSep!!!
1811 if (aMatrixList
.size() != static_cast<size_t>(nTabCount
))
1813 // matrix size mis-match !
1817 sal_uInt16 nFirstSheetId
= xSupbook
->GetTabIndex(rTabName
);
1819 ScRange
aRange(rRange
);
1820 aRange
.aStart
.SetTab(0);
1821 aRange
.aEnd
.SetTab(0);
1822 for (SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
1824 sal_uInt16 nSheetId
= nFirstSheetId
+ static_cast<sal_uInt16
>(nTab
);
1825 FindSBIndexEntry
f(nSupbookId
, nSheetId
);
1826 XclExpSBIndexVec::iterator itrEnd
= maSBIndexVec
.end();
1827 XclExpSBIndexVec::const_iterator itr
= find_if(maSBIndexVec
.begin(), itrEnd
, f
);
1830 maSBIndexVec
.push_back(XclExpSBIndex());
1831 XclExpSBIndex
& r
= maSBIndexVec
.back();
1832 r
.mnSupbook
= nSupbookId
;
1833 r
.mnSBTab
= nSheetId
;
1836 xSupbook
->StoreCellRange(nSheetId
, aRange
, *aMatrixList
[nTab
]);
1840 bool XclExpSupbookBuffer::InsertAddIn(
1841 sal_uInt16
& rnSupbook
, sal_uInt16
& rnExtName
, const String
& rName
)
1843 XclExpSupbookRef xSupbook
;
1844 if( mnAddInSB
== SAL_MAX_UINT16
)
1846 xSupbook
.reset( new XclExpSupbook( GetRoot() ) );
1847 mnAddInSB
= Append( xSupbook
);
1850 xSupbook
= maSupbookList
.GetRecord( mnAddInSB
);
1851 DBG_ASSERT( xSupbook
.is(), "XclExpSupbookBuffer::InsertAddin - missing add-in supbook" );
1852 rnSupbook
= mnAddInSB
;
1853 rnExtName
= xSupbook
->InsertAddIn( rName
);
1854 return rnExtName
> 0;
1857 bool XclExpSupbookBuffer::InsertEuroTool(
1858 sal_uInt16
& rnSupbook
, sal_uInt16
& rnExtName
, const String
& rName
)
1860 XclExpSupbookRef xSupbook
;
1861 String
aUrl( RTL_CONSTASCII_USTRINGPARAM("\001\010EUROTOOL.XLA"));
1862 if( !GetSupbookUrl( xSupbook
, rnSupbook
, aUrl
) )
1864 xSupbook
.reset( new XclExpSupbook( GetRoot(), aUrl
, EXC_SBTYPE_EUROTOOL
) );
1865 rnSupbook
= Append( xSupbook
);
1867 rnExtName
= xSupbook
->InsertEuroTool( rName
);
1868 return rnExtName
> 0;
1871 bool XclExpSupbookBuffer::InsertDde(
1872 sal_uInt16
& rnSupbook
, sal_uInt16
& rnExtName
,
1873 const String
& rApplic
, const String
& rTopic
, const String
& rItem
)
1875 XclExpSupbookRef xSupbook
;
1876 if( !GetSupbookDde( xSupbook
, rnSupbook
, rApplic
, rTopic
) )
1878 xSupbook
.reset( new XclExpSupbook( GetRoot(), rApplic
, rTopic
) );
1879 rnSupbook
= Append( xSupbook
);
1881 rnExtName
= xSupbook
->InsertDde( rItem
);
1882 return rnExtName
> 0;
1885 bool XclExpSupbookBuffer::InsertExtName(
1886 sal_uInt16
& rnSupbook
, sal_uInt16
& rnExtName
, const String
& rUrl
,
1887 const String
& rName
, const ScExternalRefCache::TokenArrayRef pArray
)
1889 XclExpSupbookRef xSupbook
;
1890 if (!GetSupbookUrl(xSupbook
, rnSupbook
, rUrl
))
1892 xSupbook
.reset( new XclExpSupbook(GetRoot(), rUrl
) );
1893 rnSupbook
= Append(xSupbook
);
1895 rnExtName
= xSupbook
->InsertExtName(rName
, pArray
);
1896 return rnExtName
> 0;
1899 XclExpXti
XclExpSupbookBuffer::GetXti( sal_uInt16 nFileId
, const String
& rTabName
, sal_uInt16 nXclTabSpan
,
1900 XclExpRefLogEntry
* pRefLogEntry
)
1902 XclExpXti
aXti(0, EXC_NOTAB
, EXC_NOTAB
);
1903 ScExternalRefManager
* pRefMgr
= GetDoc().GetExternalRefManager();
1904 const String
* pUrl
= pRefMgr
->getExternalFileName(nFileId
);
1908 XclExpSupbookRef xSupbook
;
1909 sal_uInt16 nSupbookId
;
1910 if (!GetSupbookUrl(xSupbook
, nSupbookId
, *pUrl
))
1912 xSupbook
.reset(new XclExpSupbook(GetRoot(), *pUrl
));
1913 nSupbookId
= Append(xSupbook
);
1915 aXti
.mnSupbook
= nSupbookId
;
1917 sal_uInt16 nFirstSheetId
= xSupbook
->GetTabIndex(rTabName
);
1918 if (nFirstSheetId
== EXC_NOTAB
)
1920 // first sheet not found in SUPBOOK.
1923 sal_uInt16 nSheetCount
= xSupbook
->GetTabCount();
1924 for (sal_uInt16 i
= 0; i
< nXclTabSpan
; ++i
)
1926 sal_uInt16 nSheetId
= nFirstSheetId
+ i
;
1927 if (nSheetId
>= nSheetCount
)
1930 FindSBIndexEntry
f(nSupbookId
, nSheetId
);
1931 XclExpSBIndexVec::iterator itrEnd
= maSBIndexVec
.end();
1932 XclExpSBIndexVec::const_iterator itr
= find_if(maSBIndexVec
.begin(), itrEnd
, f
);
1935 maSBIndexVec
.push_back(XclExpSBIndex());
1936 XclExpSBIndex
& r
= maSBIndexVec
.back();
1937 r
.mnSupbook
= nSupbookId
;
1938 r
.mnSBTab
= nSheetId
;
1941 aXti
.mnFirstSBTab
= nSheetId
;
1942 if (i
== nXclTabSpan
- 1)
1943 aXti
.mnLastSBTab
= nSheetId
;
1948 pRefLogEntry
->mnFirstXclTab
= 0;
1949 pRefLogEntry
->mnLastXclTab
= 0;
1951 xSupbook
->FillRefLogEntry(*pRefLogEntry
, aXti
.mnFirstSBTab
, aXti
.mnLastSBTab
);
1957 void XclExpSupbookBuffer::Save( XclExpStream
& rStrm
)
1959 maSupbookList
.Save( rStrm
);
1962 bool XclExpSupbookBuffer::GetSupbookUrl(
1963 XclExpSupbookRef
& rxSupbook
, sal_uInt16
& rnIndex
, const String
& rUrl
) const
1965 for( size_t nPos
= 0, nSize
= maSupbookList
.GetSize(); nPos
< nSize
; ++nPos
)
1967 rxSupbook
= maSupbookList
.GetRecord( nPos
);
1968 if( rxSupbook
->IsUrlLink( rUrl
) )
1970 rnIndex
= ulimit_cast
< sal_uInt16
>( nPos
);
1977 bool XclExpSupbookBuffer::GetSupbookDde( XclExpSupbookRef
& rxSupbook
,
1978 sal_uInt16
& rnIndex
, const String
& rApplic
, const String
& rTopic
) const
1980 for( size_t nPos
= 0, nSize
= maSupbookList
.GetSize(); nPos
< nSize
; ++nPos
)
1982 rxSupbook
= maSupbookList
.GetRecord( nPos
);
1983 if( rxSupbook
->IsDdeLink( rApplic
, rTopic
) )
1985 rnIndex
= ulimit_cast
< sal_uInt16
>( nPos
);
1992 sal_uInt16
XclExpSupbookBuffer::Append( XclExpSupbookRef xSupbook
)
1994 maSupbookList
.AppendRecord( xSupbook
);
1995 return ulimit_cast
< sal_uInt16
>( maSupbookList
.GetSize() - 1 );
1998 // Export link manager ========================================================
2000 XclExpLinkManagerImpl::XclExpLinkManagerImpl( const XclExpRoot
& rRoot
) :
2005 // ----------------------------------------------------------------------------
2007 XclExpLinkManagerImpl5::XclExpLinkManagerImpl5( const XclExpRoot
& rRoot
) :
2008 XclExpLinkManagerImpl( rRoot
)
2012 void XclExpLinkManagerImpl5::FindExtSheet(
2013 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnFirstXclTab
, sal_uInt16
& rnLastXclTab
,
2014 SCTAB nFirstScTab
, SCTAB nLastScTab
, XclExpRefLogEntry
* pRefLogEntry
)
2016 FindInternal( rnExtSheet
, rnFirstXclTab
, nFirstScTab
);
2017 if( (rnFirstXclTab
== EXC_TAB_DELETED
) || (nFirstScTab
== nLastScTab
) )
2019 rnLastXclTab
= rnFirstXclTab
;
2023 sal_uInt16 nDummyExtSheet
;
2024 FindInternal( nDummyExtSheet
, rnLastXclTab
, nLastScTab
);
2027 (void)pRefLogEntry
; // avoid compiler warning
2028 DBG_ASSERT( !pRefLogEntry
, "XclExpLinkManagerImpl5::FindExtSheet - fill reflog entry not implemented" );
2031 sal_uInt16
XclExpLinkManagerImpl5::FindExtSheet( sal_Unicode cCode
)
2033 sal_uInt16 nExtSheet
;
2034 FindInternal( nExtSheet
, cCode
);
2038 void XclExpLinkManagerImpl5::FindExtSheet(
2039 sal_uInt16
/*nFileId*/, const String
& /*rTabName*/, sal_uInt16
/*nXclTabSpan*/,
2040 sal_uInt16
& /*rnExtSheet*/, sal_uInt16
& /*rnFirstSBTab*/, sal_uInt16
& /*rnLastSBTab*/,
2041 XclExpRefLogEntry
* /*pRefLogEntry*/ )
2046 void XclExpLinkManagerImpl5::StoreCellRange( const ScSingleRefData
& /*rRef1*/, const ScSingleRefData
& /*rRef2*/ )
2051 void XclExpLinkManagerImpl5::StoreCell( sal_uInt16
/*nFileId*/, const String
& /*rTabName*/, const ScSingleRefData
& /*rRef*/ )
2056 void XclExpLinkManagerImpl5::StoreCellRange( sal_uInt16
/*nFileId*/, const String
& /*rTabName*/, const ScSingleRefData
& /*rRef1*/, const ScSingleRefData
& /*rRef2*/ )
2061 bool XclExpLinkManagerImpl5::InsertAddIn(
2062 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
, const String
& rName
)
2064 XclExpExtSheetRef xExtSheet
= FindInternal( rnExtSheet
, EXC_EXTSH_ADDIN
);
2065 if( xExtSheet
.is() )
2067 rnExtName
= xExtSheet
->InsertAddIn( rName
);
2068 return rnExtName
> 0;
2073 bool XclExpLinkManagerImpl5::InsertEuroTool(
2074 sal_uInt16
& /*rnExtSheet*/, sal_uInt16
& /*rnExtName*/, const String
& /*rName*/ )
2080 bool XclExpLinkManagerImpl5::InsertDde(
2081 sal_uInt16
& /*rnExtSheet*/, sal_uInt16
& /*rnExtName*/,
2082 const String
& /*rApplic*/, const String
& /*rTopic*/, const String
& /*rItem*/ )
2088 bool XclExpLinkManagerImpl5::InsertExtName(
2089 sal_uInt16
& /*rnExtSheet*/, sal_uInt16
& /*rnExtName*/, const String
& /*rUrl*/,
2090 const String
& /*rName*/, const ScExternalRefCache::TokenArrayRef
/*pArray*/ )
2096 void XclExpLinkManagerImpl5::Save( XclExpStream
& rStrm
)
2098 if( sal_uInt16 nExtSheetCount
= GetExtSheetCount() )
2100 // EXTERNCOUNT record
2101 XclExpUInt16Record( EXC_ID_EXTERNCOUNT
, nExtSheetCount
).Save( rStrm
);
2102 // list of EXTERNSHEET records with EXTERNNAME, XCT, CRN records
2103 maExtSheetList
.Save( rStrm
);
2107 sal_uInt16
XclExpLinkManagerImpl5::GetExtSheetCount() const
2109 return static_cast< sal_uInt16
>( maExtSheetList
.GetSize() );
2112 sal_uInt16
XclExpLinkManagerImpl5::AppendInternal( XclExpExtSheetRef xExtSheet
)
2114 if( GetExtSheetCount() < 0x7FFF )
2116 maExtSheetList
.AppendRecord( xExtSheet
);
2117 // return negated one-based EXTERNSHEET index (i.e. 0xFFFD for 3rd record)
2118 return static_cast< sal_uInt16
>( -GetExtSheetCount() );
2123 void XclExpLinkManagerImpl5::CreateInternal()
2125 if( maIntTabMap
.empty() )
2127 // create EXTERNSHEET records for all internal exported sheets
2128 XclExpTabInfo
& rTabInfo
= GetTabInfo();
2129 for( SCTAB nScTab
= 0, nScCnt
= rTabInfo
.GetScTabCount(); nScTab
< nScCnt
; ++nScTab
)
2131 if( rTabInfo
.IsExportTab( nScTab
) )
2133 XclExpExtSheetRef xRec
;
2134 if( nScTab
== GetCurrScTab() )
2135 xRec
.reset( new XclExpExternSheet( GetRoot(), EXC_EXTSH_OWNTAB
) );
2137 xRec
.reset( new XclExpExternSheet( GetRoot(), rTabInfo
.GetScTabName( nScTab
) ) );
2138 maIntTabMap
[ nScTab
] = AppendInternal( xRec
);
2144 XclExpLinkManagerImpl5::XclExpExtSheetRef
XclExpLinkManagerImpl5::GetInternal( sal_uInt16 nExtSheet
)
2146 return maExtSheetList
.GetRecord( static_cast< sal_uInt16
>( -nExtSheet
- 1 ) );
2149 XclExpLinkManagerImpl5::XclExpExtSheetRef
XclExpLinkManagerImpl5::FindInternal(
2150 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnXclTab
, SCTAB nScTab
)
2152 // create internal EXTERNSHEET records on demand
2155 // try to find an EXTERNSHEET record - if not, return a "deleted sheet" reference
2156 XclExpExtSheetRef xExtSheet
;
2157 XclExpIntTabMap::const_iterator aIt
= maIntTabMap
.find( nScTab
);
2158 if( aIt
== maIntTabMap
.end() )
2160 xExtSheet
= FindInternal( rnExtSheet
, EXC_EXTSH_OWNDOC
);
2161 rnXclTab
= EXC_TAB_DELETED
;
2165 rnExtSheet
= aIt
->second
;
2166 xExtSheet
= GetInternal( rnExtSheet
);
2167 rnXclTab
= GetTabInfo().GetXclTab( nScTab
);
2172 XclExpLinkManagerImpl5::XclExpExtSheetRef
XclExpLinkManagerImpl5::FindInternal(
2173 sal_uInt16
& rnExtSheet
, sal_Unicode cCode
)
2175 XclExpExtSheetRef xExtSheet
;
2176 XclExpCodeMap::const_iterator aIt
= maCodeMap
.find( cCode
);
2177 if( aIt
== maCodeMap
.end() )
2179 xExtSheet
.reset( new XclExpExternSheet( GetRoot(), cCode
) );
2180 rnExtSheet
= maCodeMap
[ cCode
] = AppendInternal( xExtSheet
);
2184 rnExtSheet
= aIt
->second
;
2185 xExtSheet
= GetInternal( rnExtSheet
);
2190 // ----------------------------------------------------------------------------
2192 XclExpLinkManagerImpl8::XclExpLinkManagerImpl8( const XclExpRoot
& rRoot
) :
2193 XclExpLinkManagerImpl( rRoot
),
2198 void XclExpLinkManagerImpl8::FindExtSheet(
2199 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnFirstXclTab
, sal_uInt16
& rnLastXclTab
,
2200 SCTAB nFirstScTab
, SCTAB nLastScTab
, XclExpRefLogEntry
* pRefLogEntry
)
2202 XclExpTabInfo
& rTabInfo
= GetTabInfo();
2203 rnFirstXclTab
= rTabInfo
.GetXclTab( nFirstScTab
);
2204 rnLastXclTab
= rTabInfo
.GetXclTab( nLastScTab
);
2205 rnExtSheet
= InsertXti( maSBBuffer
.GetXti( rnFirstXclTab
, rnLastXclTab
, pRefLogEntry
) );
2208 sal_uInt16
XclExpLinkManagerImpl8::FindExtSheet( sal_Unicode cCode
)
2210 (void)cCode
; // avoid compiler warning
2211 DBG_ASSERT( (cCode
== EXC_EXTSH_OWNDOC
) || (cCode
== EXC_EXTSH_ADDIN
),
2212 "XclExpLinkManagerImpl8::FindExtSheet - unknown externsheet code" );
2213 return InsertXti( maSBBuffer
.GetXti( EXC_TAB_EXTERNAL
, EXC_TAB_EXTERNAL
) );
2216 void XclExpLinkManagerImpl8::FindExtSheet(
2217 sal_uInt16 nFileId
, const String
& rTabName
, sal_uInt16 nXclTabSpan
,
2218 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnFirstSBTab
, sal_uInt16
& rnLastSBTab
,
2219 XclExpRefLogEntry
* pRefLogEntry
)
2221 XclExpXti aXti
= maSBBuffer
.GetXti(nFileId
, rTabName
, nXclTabSpan
, pRefLogEntry
);
2222 rnExtSheet
= InsertXti(aXti
);
2223 rnFirstSBTab
= aXti
.mnFirstSBTab
;
2224 rnLastSBTab
= aXti
.mnLastSBTab
;
2227 void XclExpLinkManagerImpl8::StoreCellRange( const ScSingleRefData
& rRef1
, const ScSingleRefData
& rRef2
)
2229 if( !rRef1
.IsDeleted() && !rRef2
.IsDeleted() && (rRef1
.nTab
>= 0) && (rRef2
.nTab
>= 0) )
2231 const XclExpTabInfo
& rTabInfo
= GetTabInfo();
2232 SCTAB nFirstScTab
= static_cast< SCTAB
>( rRef1
.nTab
);
2233 SCTAB nLastScTab
= static_cast< SCTAB
>( rRef2
.nTab
);
2235 static_cast< SCCOL
>( rRef1
.nCol
), static_cast< SCROW
>( rRef1
.nRow
), 0,
2236 static_cast< SCCOL
>( rRef2
.nCol
), static_cast< SCROW
>( rRef2
.nRow
), 0 );
2237 for( SCTAB nScTab
= nFirstScTab
; nScTab
<= nLastScTab
; ++nScTab
)
2239 if( rTabInfo
.IsExternalTab( nScTab
) )
2241 aRange
.aStart
.SetTab( nScTab
);
2242 aRange
.aEnd
.SetTab( nScTab
);
2243 maSBBuffer
.StoreCellRange( aRange
);
2249 void XclExpLinkManagerImpl8::StoreCell( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef
)
2251 ScAddress
aAddr(rRef
.nCol
, rRef
.nRow
, rRef
.nTab
);
2252 maSBBuffer
.StoreCell(nFileId
, rTabName
, aAddr
);
2255 void XclExpLinkManagerImpl8::StoreCellRange( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef1
, const ScSingleRefData
& rRef2
)
2257 ScRange
aRange(static_cast<SCCOL
>(rRef1
.nCol
), static_cast<SCROW
>(rRef1
.nRow
), static_cast<SCTAB
>(rRef1
.nTab
),
2258 static_cast<SCCOL
>(rRef2
.nCol
), static_cast<SCROW
>(rRef2
.nRow
), static_cast<SCTAB
>(rRef2
.nTab
));
2259 maSBBuffer
.StoreCellRange(nFileId
, rTabName
, aRange
);
2262 bool XclExpLinkManagerImpl8::InsertAddIn(
2263 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
, const String
& rName
)
2265 sal_uInt16 nSupbook
;
2266 if( maSBBuffer
.InsertAddIn( nSupbook
, rnExtName
, rName
) )
2268 rnExtSheet
= InsertXti( XclExpXti( nSupbook
, EXC_TAB_EXTERNAL
, EXC_TAB_EXTERNAL
) );
2274 bool XclExpLinkManagerImpl8::InsertEuroTool(
2275 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
, const String
& rName
)
2277 sal_uInt16 nSupbook
;
2278 if( maSBBuffer
.InsertEuroTool( nSupbook
, rnExtName
, rName
) )
2280 rnExtSheet
= InsertXti( XclExpXti( nSupbook
, EXC_TAB_EXTERNAL
, EXC_TAB_EXTERNAL
) );
2287 bool XclExpLinkManagerImpl8::InsertDde(
2288 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
2289 const String
& rApplic
, const String
& rTopic
, const String
& rItem
)
2291 sal_uInt16 nSupbook
;
2292 if( maSBBuffer
.InsertDde( nSupbook
, rnExtName
, rApplic
, rTopic
, rItem
) )
2294 rnExtSheet
= InsertXti( XclExpXti( nSupbook
, EXC_TAB_EXTERNAL
, EXC_TAB_EXTERNAL
) );
2300 bool XclExpLinkManagerImpl8::InsertExtName( sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
2301 const String
& rName
, const String
& rUrl
, const ScExternalRefCache::TokenArrayRef pArray
)
2303 sal_uInt16 nSupbook
;
2304 if( maSBBuffer
.InsertExtName( nSupbook
, rnExtName
, rUrl
, rName
, pArray
) )
2306 rnExtSheet
= InsertXti( XclExpXti( nSupbook
, EXC_TAB_EXTERNAL
, EXC_TAB_EXTERNAL
) );
2312 void XclExpLinkManagerImpl8::Save( XclExpStream
& rStrm
)
2314 if( !maXtiVec
.empty() )
2316 // SUPBOOKs, XCTs, CRNs, EXTERNNAMEs
2317 maSBBuffer
.Save( rStrm
);
2320 sal_uInt16 nCount
= ulimit_cast
< sal_uInt16
>( maXtiVec
.size() );
2321 rStrm
.StartRecord( EXC_ID_EXTERNSHEET
, 2 + 6 * nCount
);
2323 rStrm
.SetSliceSize( 6 );
2324 for( XclExpXtiVec::const_iterator aIt
= maXtiVec
.begin(), aEnd
= maXtiVec
.end(); aIt
!= aEnd
; ++aIt
)
2330 sal_uInt16
XclExpLinkManagerImpl8::InsertXti( const XclExpXti
& rXti
)
2332 for( XclExpXtiVec::const_iterator aIt
= maXtiVec
.begin(), aEnd
= maXtiVec
.end(); aIt
!= aEnd
; ++aIt
)
2334 return ulimit_cast
< sal_uInt16
>( aIt
- maXtiVec
.begin() );
2335 maXtiVec
.push_back( rXti
);
2336 return ulimit_cast
< sal_uInt16
>( maXtiVec
.size() - 1 );
2339 // ============================================================================
2341 XclExpLinkManager::XclExpLinkManager( const XclExpRoot
& rRoot
) :
2347 mxImpl
.reset( new XclExpLinkManagerImpl5( rRoot
) );
2350 mxImpl
.reset( new XclExpLinkManagerImpl8( rRoot
) );
2357 XclExpLinkManager::~XclExpLinkManager()
2361 void XclExpLinkManager::FindExtSheet(
2362 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnXclTab
,
2363 SCTAB nScTab
, XclExpRefLogEntry
* pRefLogEntry
)
2365 mxImpl
->FindExtSheet( rnExtSheet
, rnXclTab
, rnXclTab
, nScTab
, nScTab
, pRefLogEntry
);
2368 void XclExpLinkManager::FindExtSheet(
2369 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnFirstXclTab
, sal_uInt16
& rnLastXclTab
,
2370 SCTAB nFirstScTab
, SCTAB nLastScTab
, XclExpRefLogEntry
* pRefLogEntry
)
2372 mxImpl
->FindExtSheet( rnExtSheet
, rnFirstXclTab
, rnLastXclTab
, nFirstScTab
, nLastScTab
, pRefLogEntry
);
2375 sal_uInt16
XclExpLinkManager::FindExtSheet( sal_Unicode cCode
)
2377 return mxImpl
->FindExtSheet( cCode
);
2380 void XclExpLinkManager::FindExtSheet( sal_uInt16 nFileId
, const String
& rTabName
, sal_uInt16 nXclTabSpan
,
2381 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnFirstSBTab
, sal_uInt16
& rnLastSBTab
,
2382 XclExpRefLogEntry
* pRefLogEntry
)
2384 mxImpl
->FindExtSheet( nFileId
, rTabName
, nXclTabSpan
, rnExtSheet
, rnFirstSBTab
, rnLastSBTab
, pRefLogEntry
);
2387 void XclExpLinkManager::StoreCell( const ScSingleRefData
& rRef
)
2389 mxImpl
->StoreCellRange( rRef
, rRef
);
2392 void XclExpLinkManager::StoreCellRange( const ScComplexRefData
& rRef
)
2394 mxImpl
->StoreCellRange( rRef
.Ref1
, rRef
.Ref2
);
2397 void XclExpLinkManager::StoreCell( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef
)
2399 mxImpl
->StoreCell( nFileId
, rTabName
, rRef
);
2402 void XclExpLinkManager::StoreCellRange( sal_uInt16 nFileId
, const String
& rTabName
, const ScComplexRefData
& rRef
)
2404 mxImpl
->StoreCellRange( nFileId
, rTabName
, rRef
.Ref1
, rRef
.Ref2
);
2407 bool XclExpLinkManager::InsertAddIn(
2408 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
, const String
& rName
)
2410 return mxImpl
->InsertAddIn( rnExtSheet
, rnExtName
, rName
);
2413 bool XclExpLinkManager::InsertEuroTool(
2414 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
, const String
& rName
)
2416 return mxImpl
->InsertEuroTool( rnExtSheet
, rnExtName
, rName
);
2419 bool XclExpLinkManager::InsertDde(
2420 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
,
2421 const String
& rApplic
, const String
& rTopic
, const String
& rItem
)
2423 return mxImpl
->InsertDde( rnExtSheet
, rnExtName
, rApplic
, rTopic
, rItem
);
2426 bool XclExpLinkManager::InsertExtName(
2427 sal_uInt16
& rnExtSheet
, sal_uInt16
& rnExtName
, const String
& rName
, const String
& rUrl
,
2428 const ScExternalRefCache::TokenArrayRef pArray
)
2430 return mxImpl
->InsertExtName( rnExtSheet
, rnExtName
, rUrl
, rName
, pArray
);
2433 void XclExpLinkManager::Save( XclExpStream
& rStrm
)
2435 mxImpl
->Save( rStrm
);
2438 // ============================================================================