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