1*ca5ec200SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*ca5ec200SAndrew Rist * distributed with this work for additional information
6*ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance
9*ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at
10*ca5ec200SAndrew Rist *
11*ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*ca5ec200SAndrew Rist *
13*ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*ca5ec200SAndrew Rist * software distributed under the License is distributed on an
15*ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the
17*ca5ec200SAndrew Rist * specific language governing permissions and limitations
18*ca5ec200SAndrew Rist * under the License.
19*ca5ec200SAndrew Rist *
20*ca5ec200SAndrew Rist *************************************************************/
21*ca5ec200SAndrew Rist
22*ca5ec200SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "oox/xls/externallinkbuffer.hxx"
25cdf0e10cSrcweir
26cdf0e10cSrcweir #include <com/sun/star/sheet/ComplexReference.hpp>
27cdf0e10cSrcweir #include <com/sun/star/sheet/DDELinkInfo.hpp>
28cdf0e10cSrcweir #include <com/sun/star/sheet/ExternalLinkType.hpp>
29cdf0e10cSrcweir #include <com/sun/star/sheet/ExternalReference.hpp>
30cdf0e10cSrcweir #include <com/sun/star/sheet/ReferenceFlags.hpp>
31cdf0e10cSrcweir #include <com/sun/star/sheet/SingleReference.hpp>
32cdf0e10cSrcweir #include <com/sun/star/sheet/XDDELinks.hpp>
33cdf0e10cSrcweir #include <com/sun/star/sheet/XDDELink.hpp>
34cdf0e10cSrcweir #include <com/sun/star/sheet/XDDELinkResults.hpp>
35cdf0e10cSrcweir #include <com/sun/star/sheet/XExternalDocLink.hpp>
36cdf0e10cSrcweir #include <com/sun/star/sheet/XExternalDocLinks.hpp>
37cdf0e10cSrcweir #include <rtl/strbuf.hxx>
38cdf0e10cSrcweir #include "oox/core/filterbase.hxx"
39cdf0e10cSrcweir #include "oox/helper/attributelist.hxx"
40cdf0e10cSrcweir #include "oox/xls/addressconverter.hxx"
41cdf0e10cSrcweir #include "oox/xls/biffinputstream.hxx"
42cdf0e10cSrcweir #include "oox/xls/excelhandlers.hxx"
43cdf0e10cSrcweir #include "oox/xls/formulaparser.hxx"
44cdf0e10cSrcweir #include "oox/xls/worksheetbuffer.hxx"
45cdf0e10cSrcweir
46cdf0e10cSrcweir namespace oox {
47cdf0e10cSrcweir namespace xls {
48cdf0e10cSrcweir
49cdf0e10cSrcweir // ============================================================================
50cdf0e10cSrcweir
51cdf0e10cSrcweir using namespace ::com::sun::star::sheet;
52cdf0e10cSrcweir using namespace ::com::sun::star::table;
53cdf0e10cSrcweir using namespace ::com::sun::star::uno;
54cdf0e10cSrcweir
55cdf0e10cSrcweir using ::oox::core::Relation;
56cdf0e10cSrcweir using ::oox::core::Relations;
57cdf0e10cSrcweir using ::rtl::OString;
58cdf0e10cSrcweir using ::rtl::OStringBuffer;
59cdf0e10cSrcweir using ::rtl::OStringToOUString;
60cdf0e10cSrcweir using ::rtl::OUString;
61cdf0e10cSrcweir
62cdf0e10cSrcweir // ============================================================================
63cdf0e10cSrcweir
64cdf0e10cSrcweir namespace {
65cdf0e10cSrcweir
66cdf0e10cSrcweir const sal_uInt16 BIFF12_EXTERNALBOOK_BOOK = 0;
67cdf0e10cSrcweir const sal_uInt16 BIFF12_EXTERNALBOOK_DDE = 1;
68cdf0e10cSrcweir const sal_uInt16 BIFF12_EXTERNALBOOK_OLE = 2;
69cdf0e10cSrcweir
70cdf0e10cSrcweir const sal_uInt16 BIFF12_EXTNAME_AUTOMATIC = 0x0002;
71cdf0e10cSrcweir const sal_uInt16 BIFF12_EXTNAME_PREFERPIC = 0x0004;
72cdf0e10cSrcweir const sal_uInt16 BIFF12_EXTNAME_STDDOCNAME = 0x0008;
73cdf0e10cSrcweir const sal_uInt16 BIFF12_EXTNAME_OLEOBJECT = 0x0010;
74cdf0e10cSrcweir const sal_uInt16 BIFF12_EXTNAME_ICONIFIED = 0x0020;
75cdf0e10cSrcweir
76cdf0e10cSrcweir const sal_uInt16 BIFF_EXTNAME_BUILTIN = 0x0001;
77cdf0e10cSrcweir const sal_uInt16 BIFF_EXTNAME_AUTOMATIC = 0x0002;
78cdf0e10cSrcweir const sal_uInt16 BIFF_EXTNAME_PREFERPIC = 0x0004;
79cdf0e10cSrcweir const sal_uInt16 BIFF_EXTNAME_STDDOCNAME = 0x0008;
80cdf0e10cSrcweir const sal_uInt16 BIFF_EXTNAME_OLEOBJECT = 0x0010;
81cdf0e10cSrcweir const sal_uInt16 BIFF_EXTNAME_ICONIFIED = 0x8000;
82cdf0e10cSrcweir
83cdf0e10cSrcweir } // namespace
84cdf0e10cSrcweir
85cdf0e10cSrcweir // ============================================================================
86cdf0e10cSrcweir
ExternalNameModel()87cdf0e10cSrcweir ExternalNameModel::ExternalNameModel() :
88cdf0e10cSrcweir mbBuiltIn( false ),
89cdf0e10cSrcweir mbNotify( false ),
90cdf0e10cSrcweir mbPreferPic( false ),
91cdf0e10cSrcweir mbStdDocName( false ),
92cdf0e10cSrcweir mbOleObj( false ),
93cdf0e10cSrcweir mbIconified( false )
94cdf0e10cSrcweir {
95cdf0e10cSrcweir }
96cdf0e10cSrcweir
97cdf0e10cSrcweir // ============================================================================
98cdf0e10cSrcweir
ExternalName(const ExternalLink & rParentLink)99cdf0e10cSrcweir ExternalName::ExternalName( const ExternalLink& rParentLink ) :
100cdf0e10cSrcweir DefinedNameBase( rParentLink ),
101cdf0e10cSrcweir mrParentLink( rParentLink ),
102cdf0e10cSrcweir mnStorageId( 0 ),
103cdf0e10cSrcweir mbDdeLinkCreated( false )
104cdf0e10cSrcweir {
105cdf0e10cSrcweir }
106cdf0e10cSrcweir
importDefinedName(const AttributeList & rAttribs)107cdf0e10cSrcweir void ExternalName::importDefinedName( const AttributeList& rAttribs )
108cdf0e10cSrcweir {
109cdf0e10cSrcweir maModel.maName = rAttribs.getXString( XML_name, OUString() );
110cdf0e10cSrcweir OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importDefinedName - empty name" );
111cdf0e10cSrcweir // zero-based index into sheet list of externalBook
112cdf0e10cSrcweir maModel.mnSheet = rAttribs.getInteger( XML_sheetId, -1 );
113cdf0e10cSrcweir }
114cdf0e10cSrcweir
importDdeItem(const AttributeList & rAttribs)115cdf0e10cSrcweir void ExternalName::importDdeItem( const AttributeList& rAttribs )
116cdf0e10cSrcweir {
117cdf0e10cSrcweir maModel.maName = rAttribs.getXString( XML_name, OUString() );
118cdf0e10cSrcweir OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importDdeItem - empty name" );
119cdf0e10cSrcweir maExtNameModel.mbOleObj = false;
120cdf0e10cSrcweir maExtNameModel.mbStdDocName = rAttribs.getBool( XML_ole, false );
121cdf0e10cSrcweir maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
122cdf0e10cSrcweir maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
123cdf0e10cSrcweir }
124cdf0e10cSrcweir
importValues(const AttributeList & rAttribs)125cdf0e10cSrcweir void ExternalName::importValues( const AttributeList& rAttribs )
126cdf0e10cSrcweir {
127cdf0e10cSrcweir setResultSize( rAttribs.getInteger( XML_cols, 1 ), rAttribs.getInteger( XML_rows, 1 ) );
128cdf0e10cSrcweir }
129cdf0e10cSrcweir
importOleItem(const AttributeList & rAttribs)130cdf0e10cSrcweir void ExternalName::importOleItem( const AttributeList& rAttribs )
131cdf0e10cSrcweir {
132cdf0e10cSrcweir maModel.maName = rAttribs.getXString( XML_name, OUString() );
133cdf0e10cSrcweir OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importOleItem - empty name" );
134cdf0e10cSrcweir maExtNameModel.mbOleObj = true;
135cdf0e10cSrcweir maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
136cdf0e10cSrcweir maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
137cdf0e10cSrcweir maExtNameModel.mbIconified = rAttribs.getBool( XML_icon, false );
138cdf0e10cSrcweir }
139cdf0e10cSrcweir
importExternalName(SequenceInputStream & rStrm)140cdf0e10cSrcweir void ExternalName::importExternalName( SequenceInputStream& rStrm )
141cdf0e10cSrcweir {
142cdf0e10cSrcweir rStrm >> maModel.maName;
143cdf0e10cSrcweir OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importExternalName - empty name" );
144cdf0e10cSrcweir }
145cdf0e10cSrcweir
importExternalNameFlags(SequenceInputStream & rStrm)146cdf0e10cSrcweir void ExternalName::importExternalNameFlags( SequenceInputStream& rStrm )
147cdf0e10cSrcweir {
148cdf0e10cSrcweir sal_uInt16 nFlags;
149cdf0e10cSrcweir sal_Int32 nSheetId;
150cdf0e10cSrcweir rStrm >> nFlags >> nSheetId;
151cdf0e10cSrcweir // index into sheet list of EXTSHEETNAMES (one-based in BIFF12)
152cdf0e10cSrcweir maModel.mnSheet = nSheetId - 1;
153cdf0e10cSrcweir // no flag for built-in names, as in OOXML...
154cdf0e10cSrcweir maExtNameModel.mbNotify = getFlag( nFlags, BIFF12_EXTNAME_AUTOMATIC );
155cdf0e10cSrcweir maExtNameModel.mbPreferPic = getFlag( nFlags, BIFF12_EXTNAME_PREFERPIC );
156cdf0e10cSrcweir maExtNameModel.mbStdDocName = getFlag( nFlags, BIFF12_EXTNAME_STDDOCNAME );
157cdf0e10cSrcweir maExtNameModel.mbOleObj = getFlag( nFlags, BIFF12_EXTNAME_OLEOBJECT );
158cdf0e10cSrcweir maExtNameModel.mbIconified = getFlag( nFlags, BIFF12_EXTNAME_ICONIFIED );
159cdf0e10cSrcweir OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_OLE) == maExtNameModel.mbOleObj,
160cdf0e10cSrcweir "ExternalName::importExternalNameFlags - wrong OLE flag in external name" );
161cdf0e10cSrcweir }
162cdf0e10cSrcweir
importDdeItemValues(SequenceInputStream & rStrm)163cdf0e10cSrcweir void ExternalName::importDdeItemValues( SequenceInputStream& rStrm )
164cdf0e10cSrcweir {
165cdf0e10cSrcweir sal_Int32 nRows, nCols;
166cdf0e10cSrcweir rStrm >> nRows >> nCols;
167cdf0e10cSrcweir setResultSize( nCols, nRows );
168cdf0e10cSrcweir }
169cdf0e10cSrcweir
importDdeItemBool(SequenceInputStream & rStrm)170cdf0e10cSrcweir void ExternalName::importDdeItemBool( SequenceInputStream& rStrm )
171cdf0e10cSrcweir {
172cdf0e10cSrcweir appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
173cdf0e10cSrcweir }
174cdf0e10cSrcweir
importDdeItemDouble(SequenceInputStream & rStrm)175cdf0e10cSrcweir void ExternalName::importDdeItemDouble( SequenceInputStream& rStrm )
176cdf0e10cSrcweir {
177cdf0e10cSrcweir appendResultValue( rStrm.readDouble() );
178cdf0e10cSrcweir }
179cdf0e10cSrcweir
importDdeItemError(SequenceInputStream & rStrm)180cdf0e10cSrcweir void ExternalName::importDdeItemError( SequenceInputStream& rStrm )
181cdf0e10cSrcweir {
182cdf0e10cSrcweir appendResultValue( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) );
183cdf0e10cSrcweir }
184cdf0e10cSrcweir
importDdeItemString(SequenceInputStream & rStrm)185cdf0e10cSrcweir void ExternalName::importDdeItemString( SequenceInputStream& rStrm )
186cdf0e10cSrcweir {
187cdf0e10cSrcweir appendResultValue( BiffHelper::readString( rStrm ) );
188cdf0e10cSrcweir }
189cdf0e10cSrcweir
importExternalName(BiffInputStream & rStrm)190cdf0e10cSrcweir void ExternalName::importExternalName( BiffInputStream& rStrm )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir sal_uInt16 nFlags = 0;
193cdf0e10cSrcweir if( getBiff() >= BIFF3 )
194cdf0e10cSrcweir {
195cdf0e10cSrcweir rStrm >> nFlags;
196cdf0e10cSrcweir maExtNameModel.mbBuiltIn = getFlag( nFlags, BIFF_EXTNAME_BUILTIN );
197cdf0e10cSrcweir maExtNameModel.mbNotify = getFlag( nFlags, BIFF_EXTNAME_AUTOMATIC );
198cdf0e10cSrcweir maExtNameModel.mbPreferPic = getFlag( nFlags, BIFF_EXTNAME_PREFERPIC );
199cdf0e10cSrcweir
200cdf0e10cSrcweir // BIFF5-BIFF8: sheet index for sheet-local names, OLE settings
201cdf0e10cSrcweir if( getBiff() >= BIFF5 )
202cdf0e10cSrcweir {
203cdf0e10cSrcweir maExtNameModel.mbStdDocName = getFlag( nFlags, BIFF_EXTNAME_STDDOCNAME );
204cdf0e10cSrcweir maExtNameModel.mbOleObj = getFlag( nFlags, BIFF_EXTNAME_OLEOBJECT );
205cdf0e10cSrcweir maExtNameModel.mbIconified = getFlag( nFlags, BIFF_EXTNAME_ICONIFIED );
206cdf0e10cSrcweir
207cdf0e10cSrcweir if( maExtNameModel.mbOleObj )
208cdf0e10cSrcweir {
209cdf0e10cSrcweir rStrm >> mnStorageId;
210cdf0e10cSrcweir }
211cdf0e10cSrcweir else
212cdf0e10cSrcweir {
213cdf0e10cSrcweir /* Import the reference ID for names that are sheet-local in
214cdf0e10cSrcweir the external document. This index will be resolved later to
215cdf0e10cSrcweir the index of the external sheet cache which is able to
216cdf0e10cSrcweir provide the name of the sheet related to this defined name.
217cdf0e10cSrcweir - BIFF5: one-based index to EXTERNSHEET record containing
218cdf0e10cSrcweir the document and sheet name
219cdf0e10cSrcweir - BIFF8: one-based index into EXTERNALBOOK sheet name list
220cdf0e10cSrcweir The value zero means this external name is a global name.
221cdf0e10cSrcweir */
222cdf0e10cSrcweir rStrm.skip( 2 );
223cdf0e10cSrcweir maModel.mnSheet = rStrm.readuInt16();
224cdf0e10cSrcweir }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir }
227cdf0e10cSrcweir
228cdf0e10cSrcweir maModel.maName = (getBiff() == BIFF8) ?
229cdf0e10cSrcweir rStrm.readUniStringBody( rStrm.readuInt8() ) :
230cdf0e10cSrcweir rStrm.readByteStringUC( false, getTextEncoding() );
231cdf0e10cSrcweir OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importExternalName - empty name" );
232cdf0e10cSrcweir
233cdf0e10cSrcweir // load cell references that are stored in hidden external names (seen in BIFF3-BIFF4)
234cdf0e10cSrcweir bool bHiddenRef = (getBiff() <= BIFF4) && (maModel.maName.getLength() > 1) && (maModel.maName[ 0 ] == '\x01') && (rStrm.getRemaining() > 2);
235cdf0e10cSrcweir switch( mrParentLink.getLinkType() )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir case LINKTYPE_INTERNAL:
238cdf0e10cSrcweir // cell references to other internal sheets are stored in hidden external names
239cdf0e10cSrcweir if( bHiddenRef && (getBiff() == BIFF4) && isWorkbookFile() )
240cdf0e10cSrcweir {
241cdf0e10cSrcweir ApiTokenSequence aTokens = importBiffFormula( mrParentLink.getCalcSheetIndex(), rStrm );
242cdf0e10cSrcweir extractReference( aTokens );
243cdf0e10cSrcweir }
244cdf0e10cSrcweir break;
245cdf0e10cSrcweir
246cdf0e10cSrcweir case LINKTYPE_EXTERNAL:
247cdf0e10cSrcweir // cell references to other documents are stored in hidden external names
248cdf0e10cSrcweir if( bHiddenRef )
249cdf0e10cSrcweir {
250cdf0e10cSrcweir ApiTokenSequence aTokens = importBiffFormula( 0, rStrm );
251cdf0e10cSrcweir extractExternalReference( aTokens );
252cdf0e10cSrcweir }
253cdf0e10cSrcweir break;
254cdf0e10cSrcweir
255cdf0e10cSrcweir case LINKTYPE_DDE:
256cdf0e10cSrcweir case LINKTYPE_OLE:
257cdf0e10cSrcweir case LINKTYPE_MAYBE_DDE_OLE:
258cdf0e10cSrcweir // DDE/OLE link results
259cdf0e10cSrcweir if( rStrm.getRemaining() > 3 )
260cdf0e10cSrcweir {
261cdf0e10cSrcweir bool bBiff8 = getBiff() == BIFF8;
262cdf0e10cSrcweir sal_Int32 nCols = rStrm.readuInt8();
263cdf0e10cSrcweir sal_Int32 nRows = rStrm.readuInt16();
264cdf0e10cSrcweir if( bBiff8 ) { ++nCols; ++nRows; } else if( nCols == 0 ) nCols = 256;
265cdf0e10cSrcweir setResultSize( nCols, nRows );
266cdf0e10cSrcweir
267cdf0e10cSrcweir bool bLoop = true;
268cdf0e10cSrcweir while( bLoop && !rStrm.isEof() && (maCurrIt != maResults.end()) )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir switch( rStrm.readuInt8() )
271cdf0e10cSrcweir {
272cdf0e10cSrcweir case BIFF_DATATYPE_EMPTY:
273cdf0e10cSrcweir appendResultValue( OUString() );
274cdf0e10cSrcweir rStrm.skip( 8 );
275cdf0e10cSrcweir break;
276cdf0e10cSrcweir case BIFF_DATATYPE_DOUBLE:
277cdf0e10cSrcweir appendResultValue( rStrm.readDouble() );
278cdf0e10cSrcweir break;
279cdf0e10cSrcweir case BIFF_DATATYPE_STRING:
280cdf0e10cSrcweir appendResultValue( bBiff8 ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() ) );
281cdf0e10cSrcweir break;
282cdf0e10cSrcweir case BIFF_DATATYPE_BOOL:
283cdf0e10cSrcweir appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
284cdf0e10cSrcweir rStrm.skip( 7 );
285cdf0e10cSrcweir break;
286cdf0e10cSrcweir case BIFF_DATATYPE_ERROR:
287cdf0e10cSrcweir appendResultValue( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) );
288cdf0e10cSrcweir rStrm.skip( 7 );
289cdf0e10cSrcweir break;
290cdf0e10cSrcweir default:
291cdf0e10cSrcweir bLoop = false;
292cdf0e10cSrcweir }
293cdf0e10cSrcweir }
294cdf0e10cSrcweir OSL_ENSURE( bLoop && !rStrm.isEof() && (maCurrIt == maResults.end()),
295cdf0e10cSrcweir "ExternalName::importExternalName - stream error in result set" );
296cdf0e10cSrcweir }
297cdf0e10cSrcweir break;
298cdf0e10cSrcweir
299cdf0e10cSrcweir default:;
300cdf0e10cSrcweir }
301cdf0e10cSrcweir }
302cdf0e10cSrcweir
303cdf0e10cSrcweir #if 0
304cdf0e10cSrcweir sal_Int32 ExternalName::getSheetCacheIndex() const
305cdf0e10cSrcweir {
306cdf0e10cSrcweir OSL_ENSURE( mrParentLink.getLinkType() == LINKTYPE_DDE, "ExternalName::getSheetCacheIndex - unexpected link type" );
307cdf0e10cSrcweir sal_Int32 nCacheIdx = -1;
308cdf0e10cSrcweir switch( getFilterType() )
309cdf0e10cSrcweir {
310cdf0e10cSrcweir case FILTER_OOXML:
311cdf0e10cSrcweir // OOXML/BIFF12: zero-based index into sheet list, -1 means global name
312cdf0e10cSrcweir if( maModel.mnSheet >= 0 )
313cdf0e10cSrcweir nCacheIdx = mrParentLink.getSheetIndex( maModel.mnSheet );
314cdf0e10cSrcweir break;
315cdf0e10cSrcweir case FILTER_BIFF:
316cdf0e10cSrcweir switch( getBiff() )
317cdf0e10cSrcweir {
318cdf0e10cSrcweir case BIFF2:
319cdf0e10cSrcweir case BIFF3:
320cdf0e10cSrcweir case BIFF4:
321cdf0e10cSrcweir break;
322cdf0e10cSrcweir case BIFF5:
323cdf0e10cSrcweir if( maModel.mnSheet > 0 )
324cdf0e10cSrcweir if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( maModel.mnSheet ).get() )
325cdf0e10cSrcweir if( pExtLink->getLinkType() == LINKTYPE_EXTERNAL )
326cdf0e10cSrcweir nCacheIdx = pExtLink->getSheetIndex();
327cdf0e10cSrcweir break;
328cdf0e10cSrcweir case BIFF8:
329cdf0e10cSrcweir if( maModel.mnSheet > 0 )
330cdf0e10cSrcweir nCacheIdx = mrParentLink.getSheetIndex( maModel.mnSheet - 1 );
331cdf0e10cSrcweir break;
332cdf0e10cSrcweir case BIFF_UNKNOWN:
333cdf0e10cSrcweir break;
334cdf0e10cSrcweir }
335cdf0e10cSrcweir break;
336cdf0e10cSrcweir case FILTER_UNKNOWN:
337cdf0e10cSrcweir break;
338cdf0e10cSrcweir }
339cdf0e10cSrcweir return nCacheIdx;
340cdf0e10cSrcweir }
341cdf0e10cSrcweir #endif
342cdf0e10cSrcweir
getDdeItemInfo(DDEItemInfo & orItemInfo) const343cdf0e10cSrcweir bool ExternalName::getDdeItemInfo( DDEItemInfo& orItemInfo ) const
344cdf0e10cSrcweir {
345cdf0e10cSrcweir if( (mrParentLink.getLinkType() == LINKTYPE_DDE) && (maModel.maName.getLength() > 0) )
346cdf0e10cSrcweir {
347cdf0e10cSrcweir orItemInfo.Item = maModel.maName;
348cdf0e10cSrcweir orItemInfo.Results = ContainerHelper::matrixToSequenceSequence( maResults );
349cdf0e10cSrcweir return true;
350cdf0e10cSrcweir }
351cdf0e10cSrcweir return false;
352cdf0e10cSrcweir }
353cdf0e10cSrcweir
getDdeLinkData(OUString & orDdeServer,OUString & orDdeTopic,OUString & orDdeItem)354cdf0e10cSrcweir bool ExternalName::getDdeLinkData( OUString& orDdeServer, OUString& orDdeTopic, OUString& orDdeItem )
355cdf0e10cSrcweir {
356cdf0e10cSrcweir if( (mrParentLink.getLinkType() == LINKTYPE_DDE) && (maModel.maName.getLength() > 0) )
357cdf0e10cSrcweir {
358cdf0e10cSrcweir // try to create a DDE link and to set the imported link results
359cdf0e10cSrcweir if( !mbDdeLinkCreated ) try
360cdf0e10cSrcweir {
361cdf0e10cSrcweir PropertySet aDocProps( getDocument() );
362cdf0e10cSrcweir Reference< XDDELinks > xDdeLinks( aDocProps.getAnyProperty( PROP_DDELinks ), UNO_QUERY_THROW );
363cdf0e10cSrcweir mxDdeLink = xDdeLinks->addDDELink( mrParentLink.getClassName(), mrParentLink.getTargetUrl(), maModel.maName, ::com::sun::star::sheet::DDELinkMode_DEFAULT );
364cdf0e10cSrcweir mbDdeLinkCreated = true; // ignore if setting results fails
365cdf0e10cSrcweir if( !maResults.empty() )
366cdf0e10cSrcweir {
367cdf0e10cSrcweir Reference< XDDELinkResults > xResults( mxDdeLink, UNO_QUERY_THROW );
368cdf0e10cSrcweir xResults->setResults( ContainerHelper::matrixToSequenceSequence( maResults ) );
369cdf0e10cSrcweir }
370cdf0e10cSrcweir }
371cdf0e10cSrcweir catch( Exception& )
372cdf0e10cSrcweir {
373cdf0e10cSrcweir OSL_ENSURE( false, "ExternalName::getDdeLinkData - cannot create DDE link" );
374cdf0e10cSrcweir }
375cdf0e10cSrcweir // get link data from created DDE link
376cdf0e10cSrcweir if( mxDdeLink.is() )
377cdf0e10cSrcweir {
378cdf0e10cSrcweir orDdeServer = mxDdeLink->getApplication();
379cdf0e10cSrcweir orDdeTopic = mxDdeLink->getTopic();
380cdf0e10cSrcweir orDdeItem = mxDdeLink->getItem();
381cdf0e10cSrcweir return true;
382cdf0e10cSrcweir }
383cdf0e10cSrcweir }
384cdf0e10cSrcweir return false;
385cdf0e10cSrcweir }
386cdf0e10cSrcweir
387cdf0e10cSrcweir // private --------------------------------------------------------------------
388cdf0e10cSrcweir
389cdf0e10cSrcweir namespace {
390cdf0e10cSrcweir
lclSetSheetCacheIndex(SingleReference & orApiRef,sal_Int32 nCacheIdx)391cdf0e10cSrcweir void lclSetSheetCacheIndex( SingleReference& orApiRef, sal_Int32 nCacheIdx )
392cdf0e10cSrcweir {
393cdf0e10cSrcweir using namespace ::com::sun::star::sheet::ReferenceFlags;
394cdf0e10cSrcweir setFlag( orApiRef.Flags, SHEET_RELATIVE, false );
395cdf0e10cSrcweir setFlag( orApiRef.Flags, SHEET_3D, true );
396cdf0e10cSrcweir orApiRef.Sheet = nCacheIdx;
397cdf0e10cSrcweir }
398cdf0e10cSrcweir
399cdf0e10cSrcweir } // namespace
400cdf0e10cSrcweir
extractExternalReference(const ApiTokenSequence & rTokens)401cdf0e10cSrcweir void ExternalName::extractExternalReference( const ApiTokenSequence& rTokens )
402cdf0e10cSrcweir {
403cdf0e10cSrcweir OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4), "ExternalName::setExternalReference - unexpected call" );
404cdf0e10cSrcweir sal_Int32 nDocLinkIdx = mrParentLink.getDocumentLinkIndex();
405cdf0e10cSrcweir sal_Int32 nCacheIdx = mrParentLink.getSheetCacheIndex();
406cdf0e10cSrcweir if( (nDocLinkIdx >= 0) && (nCacheIdx >= 0) )
407cdf0e10cSrcweir {
408cdf0e10cSrcweir ExternalReference aExtApiRef;
409cdf0e10cSrcweir aExtApiRef.Index = nDocLinkIdx;
410cdf0e10cSrcweir
411cdf0e10cSrcweir Any aRefAny = getFormulaParser().extractReference( rTokens );
412cdf0e10cSrcweir if( aRefAny.has< SingleReference >() )
413cdf0e10cSrcweir {
414cdf0e10cSrcweir SingleReference aApiRef;
415cdf0e10cSrcweir aRefAny >>= aApiRef;
416cdf0e10cSrcweir lclSetSheetCacheIndex( aApiRef, nCacheIdx );
417cdf0e10cSrcweir aExtApiRef.Reference <<= aApiRef;
418cdf0e10cSrcweir maRefAny <<= aExtApiRef;
419cdf0e10cSrcweir }
420cdf0e10cSrcweir else if( aRefAny.has< ComplexReference >() )
421cdf0e10cSrcweir {
422cdf0e10cSrcweir ComplexReference aApiRef;
423cdf0e10cSrcweir aRefAny >>= aApiRef;
424cdf0e10cSrcweir lclSetSheetCacheIndex( aApiRef.Reference1, nCacheIdx );
425cdf0e10cSrcweir lclSetSheetCacheIndex( aApiRef.Reference2, nCacheIdx );
426cdf0e10cSrcweir aExtApiRef.Reference <<= aApiRef;
427cdf0e10cSrcweir maRefAny <<= aExtApiRef;
428cdf0e10cSrcweir }
429cdf0e10cSrcweir }
430cdf0e10cSrcweir }
431cdf0e10cSrcweir
setResultSize(sal_Int32 nColumns,sal_Int32 nRows)432cdf0e10cSrcweir void ExternalName::setResultSize( sal_Int32 nColumns, sal_Int32 nRows )
433cdf0e10cSrcweir {
434cdf0e10cSrcweir OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_DDE) || (mrParentLink.getLinkType() == LINKTYPE_OLE) ||
435cdf0e10cSrcweir (mrParentLink.getLinkType() == LINKTYPE_MAYBE_DDE_OLE), "ExternalName::setResultSize - wrong link type" );
436cdf0e10cSrcweir OSL_ENSURE( (nRows > 0) && (nColumns > 0), "ExternalName::setResultSize - invalid matrix size" );
437cdf0e10cSrcweir const CellAddress& rMaxPos = getAddressConverter().getMaxApiAddress();
438cdf0e10cSrcweir if( (0 < nRows) && (nRows <= rMaxPos.Row + 1) && (0 < nColumns) && (nColumns <= rMaxPos.Column + 1) )
439cdf0e10cSrcweir maResults.resize( static_cast< size_t >( nColumns ), static_cast< size_t >( nRows ), Any( BiffHelper::calcDoubleFromError( BIFF_ERR_NA ) ) );
440cdf0e10cSrcweir else
441cdf0e10cSrcweir maResults.clear();
442cdf0e10cSrcweir maCurrIt = maResults.begin();
443cdf0e10cSrcweir }
444cdf0e10cSrcweir
445cdf0e10cSrcweir // ============================================================================
446cdf0e10cSrcweir
setDeleted()447cdf0e10cSrcweir void LinkSheetRange::setDeleted()
448cdf0e10cSrcweir {
449cdf0e10cSrcweir meType = LINKSHEETRANGE_INTERNAL;
450cdf0e10cSrcweir mnDocLink = mnFirst = mnLast = -1;
451cdf0e10cSrcweir }
452cdf0e10cSrcweir
setSameSheet()453cdf0e10cSrcweir void LinkSheetRange::setSameSheet()
454cdf0e10cSrcweir {
455cdf0e10cSrcweir meType = LINKSHEETRANGE_SAMESHEET;
456cdf0e10cSrcweir mnDocLink = -1;
457cdf0e10cSrcweir mnFirst = mnLast = 0;
458cdf0e10cSrcweir }
459cdf0e10cSrcweir
setRange(sal_Int32 nFirst,sal_Int32 nLast)460cdf0e10cSrcweir void LinkSheetRange::setRange( sal_Int32 nFirst, sal_Int32 nLast )
461cdf0e10cSrcweir {
462cdf0e10cSrcweir meType = LINKSHEETRANGE_INTERNAL;
463cdf0e10cSrcweir mnDocLink = -1;
464cdf0e10cSrcweir mnFirst = ::std::min( nFirst, nLast );
465cdf0e10cSrcweir mnLast = ::std::max( nFirst, nLast );
466cdf0e10cSrcweir }
467cdf0e10cSrcweir
setExternalRange(sal_Int32 nDocLink,sal_Int32 nFirst,sal_Int32 nLast)468cdf0e10cSrcweir void LinkSheetRange::setExternalRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast )
469cdf0e10cSrcweir {
470cdf0e10cSrcweir if( nDocLink < 0 )
471cdf0e10cSrcweir {
472cdf0e10cSrcweir setDeleted();
473cdf0e10cSrcweir }
474cdf0e10cSrcweir else
475cdf0e10cSrcweir {
476cdf0e10cSrcweir meType = LINKSHEETRANGE_EXTERNAL;
477cdf0e10cSrcweir mnDocLink = nDocLink;
478cdf0e10cSrcweir mnFirst = ::std::min( nFirst, nLast );
479cdf0e10cSrcweir mnLast = ::std::max( nFirst, nLast );
480cdf0e10cSrcweir }
481cdf0e10cSrcweir }
482cdf0e10cSrcweir
483cdf0e10cSrcweir // ============================================================================
484cdf0e10cSrcweir
ExternalLink(const WorkbookHelper & rHelper)485cdf0e10cSrcweir ExternalLink::ExternalLink( const WorkbookHelper& rHelper ) :
486cdf0e10cSrcweir WorkbookHelper( rHelper ),
487cdf0e10cSrcweir meLinkType( LINKTYPE_UNKNOWN ),
488cdf0e10cSrcweir meFuncLibType( FUNCLIB_UNKNOWN )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir }
491cdf0e10cSrcweir
importExternalReference(const AttributeList & rAttribs)492cdf0e10cSrcweir void ExternalLink::importExternalReference( const AttributeList& rAttribs )
493cdf0e10cSrcweir {
494cdf0e10cSrcweir maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
495cdf0e10cSrcweir }
496cdf0e10cSrcweir
importExternalBook(const Relations & rRelations,const AttributeList & rAttribs)497cdf0e10cSrcweir void ExternalLink::importExternalBook( const Relations& rRelations, const AttributeList& rAttribs )
498cdf0e10cSrcweir {
499cdf0e10cSrcweir parseExternalReference( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
500cdf0e10cSrcweir }
501cdf0e10cSrcweir
importSheetName(const AttributeList & rAttribs)502cdf0e10cSrcweir void ExternalLink::importSheetName( const AttributeList& rAttribs )
503cdf0e10cSrcweir {
504cdf0e10cSrcweir insertExternalSheet( rAttribs.getXString( XML_val, OUString() ) );
505cdf0e10cSrcweir }
506cdf0e10cSrcweir
importDefinedName(const AttributeList & rAttribs)507cdf0e10cSrcweir void ExternalLink::importDefinedName( const AttributeList& rAttribs )
508cdf0e10cSrcweir {
509cdf0e10cSrcweir createExternalName()->importDefinedName( rAttribs );
510cdf0e10cSrcweir }
511cdf0e10cSrcweir
importDdeLink(const AttributeList & rAttribs)512cdf0e10cSrcweir void ExternalLink::importDdeLink( const AttributeList& rAttribs )
513cdf0e10cSrcweir {
514cdf0e10cSrcweir OUString aDdeService = rAttribs.getXString( XML_ddeService, OUString() );
515cdf0e10cSrcweir OUString aDdeTopic = rAttribs.getXString( XML_ddeTopic, OUString() );
516cdf0e10cSrcweir setDdeOleTargetUrl( aDdeService, aDdeTopic, LINKTYPE_DDE );
517cdf0e10cSrcweir }
518cdf0e10cSrcweir
importDdeItem(const AttributeList & rAttribs)519cdf0e10cSrcweir ExternalNameRef ExternalLink::importDdeItem( const AttributeList& rAttribs )
520cdf0e10cSrcweir {
521cdf0e10cSrcweir ExternalNameRef xExtName = createExternalName();
522cdf0e10cSrcweir xExtName->importDdeItem( rAttribs );
523cdf0e10cSrcweir return xExtName;
524cdf0e10cSrcweir }
525cdf0e10cSrcweir
importOleLink(const Relations & rRelations,const AttributeList & rAttribs)526cdf0e10cSrcweir void ExternalLink::importOleLink( const Relations& rRelations, const AttributeList& rAttribs )
527cdf0e10cSrcweir {
528cdf0e10cSrcweir OUString aProgId = rAttribs.getXString( XML_progId, OUString() );
529cdf0e10cSrcweir OUString aTargetUrl = rRelations.getExternalTargetFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
530cdf0e10cSrcweir setDdeOleTargetUrl( aProgId, aTargetUrl, LINKTYPE_OLE );
531cdf0e10cSrcweir }
532cdf0e10cSrcweir
importOleItem(const AttributeList & rAttribs)533cdf0e10cSrcweir ExternalNameRef ExternalLink::importOleItem( const AttributeList& rAttribs )
534cdf0e10cSrcweir {
535cdf0e10cSrcweir ExternalNameRef xExtName = createExternalName();
536cdf0e10cSrcweir xExtName->importOleItem( rAttribs );
537cdf0e10cSrcweir return xExtName;
538cdf0e10cSrcweir }
539cdf0e10cSrcweir
importExternalRef(SequenceInputStream & rStrm)540cdf0e10cSrcweir void ExternalLink::importExternalRef( SequenceInputStream& rStrm )
541cdf0e10cSrcweir {
542cdf0e10cSrcweir rStrm >> maRelId;
543cdf0e10cSrcweir }
544cdf0e10cSrcweir
importExternalSelf(SequenceInputStream &)545cdf0e10cSrcweir void ExternalLink::importExternalSelf( SequenceInputStream& )
546cdf0e10cSrcweir {
547cdf0e10cSrcweir meLinkType = LINKTYPE_SELF;
548cdf0e10cSrcweir }
549cdf0e10cSrcweir
importExternalSame(SequenceInputStream &)550cdf0e10cSrcweir void ExternalLink::importExternalSame( SequenceInputStream& )
551cdf0e10cSrcweir {
552cdf0e10cSrcweir meLinkType = LINKTYPE_SAME;
553cdf0e10cSrcweir }
554cdf0e10cSrcweir
importExternalAddin(SequenceInputStream &)555cdf0e10cSrcweir void ExternalLink::importExternalAddin( SequenceInputStream& )
556cdf0e10cSrcweir {
557cdf0e10cSrcweir meLinkType = LINKTYPE_UNKNOWN;
558cdf0e10cSrcweir }
559cdf0e10cSrcweir
importExternalBook(const Relations & rRelations,SequenceInputStream & rStrm)560cdf0e10cSrcweir void ExternalLink::importExternalBook( const Relations& rRelations, SequenceInputStream& rStrm )
561cdf0e10cSrcweir {
562cdf0e10cSrcweir switch( rStrm.readuInt16() )
563cdf0e10cSrcweir {
564cdf0e10cSrcweir case BIFF12_EXTERNALBOOK_BOOK:
565cdf0e10cSrcweir parseExternalReference( rRelations, BiffHelper::readString( rStrm ) );
566cdf0e10cSrcweir break;
567cdf0e10cSrcweir case BIFF12_EXTERNALBOOK_DDE:
568cdf0e10cSrcweir {
569cdf0e10cSrcweir OUString aDdeService, aDdeTopic;
570cdf0e10cSrcweir rStrm >> aDdeService >> aDdeTopic;
571cdf0e10cSrcweir setDdeOleTargetUrl( aDdeService, aDdeTopic, LINKTYPE_DDE );
572cdf0e10cSrcweir }
573cdf0e10cSrcweir break;
574cdf0e10cSrcweir case BIFF12_EXTERNALBOOK_OLE:
575cdf0e10cSrcweir {
576cdf0e10cSrcweir OUString aTargetUrl = rRelations.getExternalTargetFromRelId( BiffHelper::readString( rStrm ) );
577cdf0e10cSrcweir OUString aProgId = BiffHelper::readString( rStrm );
578cdf0e10cSrcweir setDdeOleTargetUrl( aProgId, aTargetUrl, LINKTYPE_OLE );
579cdf0e10cSrcweir }
580cdf0e10cSrcweir break;
581cdf0e10cSrcweir default:
582cdf0e10cSrcweir OSL_ENSURE( false, "ExternalLink::importExternalBook - unknown link type" );
583cdf0e10cSrcweir }
584cdf0e10cSrcweir }
585cdf0e10cSrcweir
importExtSheetNames(SequenceInputStream & rStrm)586cdf0e10cSrcweir void ExternalLink::importExtSheetNames( SequenceInputStream& rStrm )
587cdf0e10cSrcweir {
588cdf0e10cSrcweir // load external sheet names and create the sheet caches in the Calc document
589cdf0e10cSrcweir OSL_ENSURE( (meLinkType == LINKTYPE_EXTERNAL) || (meLinkType == LINKTYPE_LIBRARY),
590cdf0e10cSrcweir "ExternalLink::importExtSheetNames - invalid link type" );
591cdf0e10cSrcweir if( meLinkType == LINKTYPE_EXTERNAL ) // ignore sheets of external libraries
592cdf0e10cSrcweir for( sal_Int32 nSheet = 0, nCount = rStrm.readInt32(); !rStrm.isEof() && (nSheet < nCount); ++nSheet )
593cdf0e10cSrcweir insertExternalSheet( BiffHelper::readString( rStrm ) );
594cdf0e10cSrcweir }
595cdf0e10cSrcweir
importExternalName(SequenceInputStream & rStrm)596cdf0e10cSrcweir ExternalNameRef ExternalLink::importExternalName( SequenceInputStream& rStrm )
597cdf0e10cSrcweir {
598cdf0e10cSrcweir ExternalNameRef xExtName = createExternalName();
599cdf0e10cSrcweir xExtName->importExternalName( rStrm );
600cdf0e10cSrcweir return xExtName;
601cdf0e10cSrcweir }
602cdf0e10cSrcweir
importExternSheet(BiffInputStream & rStrm)603cdf0e10cSrcweir void ExternalLink::importExternSheet( BiffInputStream& rStrm )
604cdf0e10cSrcweir {
605cdf0e10cSrcweir OStringBuffer aTargetBuffer( rStrm.readByteString( false, true ) );
606cdf0e10cSrcweir // references to own sheets have wrong string length field (off by 1)
607cdf0e10cSrcweir if( (aTargetBuffer.getLength() > 0) && (aTargetBuffer[ 0 ] == 3) )
608cdf0e10cSrcweir aTargetBuffer.append( static_cast< sal_Char >( rStrm.readuInt8() ) );
609cdf0e10cSrcweir // parse the encoded URL
610cdf0e10cSrcweir OUString aBiffTarget = OStringToOUString( aTargetBuffer.makeStringAndClear(), getTextEncoding() );
611cdf0e10cSrcweir OUString aSheetName = parseBiffTargetUrl( aBiffTarget );
612cdf0e10cSrcweir switch( meLinkType )
613cdf0e10cSrcweir {
614cdf0e10cSrcweir case LINKTYPE_INTERNAL:
615cdf0e10cSrcweir maCalcSheets.push_back( getWorksheets().getCalcSheetIndex( aSheetName ) );
616cdf0e10cSrcweir break;
617cdf0e10cSrcweir case LINKTYPE_EXTERNAL:
618cdf0e10cSrcweir insertExternalSheet( (aSheetName.getLength() > 0) ? aSheetName : WorksheetBuffer::getBaseFileName( maTargetUrl ) );
619cdf0e10cSrcweir break;
620cdf0e10cSrcweir default:;
621cdf0e10cSrcweir }
622cdf0e10cSrcweir }
623cdf0e10cSrcweir
importExternalBook(BiffInputStream & rStrm)624cdf0e10cSrcweir void ExternalLink::importExternalBook( BiffInputStream& rStrm )
625cdf0e10cSrcweir {
626cdf0e10cSrcweir OUString aTarget;
627cdf0e10cSrcweir sal_uInt16 nSheetCount;
628cdf0e10cSrcweir rStrm >> nSheetCount;
629cdf0e10cSrcweir if( rStrm.getRemaining() == 2 )
630cdf0e10cSrcweir {
631cdf0e10cSrcweir if( rStrm.readuInt8() == 1 )
632cdf0e10cSrcweir {
633cdf0e10cSrcweir sal_Char cChar = static_cast< sal_Char >( rStrm.readuInt8() );
634cdf0e10cSrcweir if( cChar != 0 )
635cdf0e10cSrcweir aTarget = OStringToOUString( OString( cChar ), getTextEncoding() );
636cdf0e10cSrcweir }
637cdf0e10cSrcweir }
638cdf0e10cSrcweir else if( rStrm.getRemaining() >= 3 )
639cdf0e10cSrcweir {
640cdf0e10cSrcweir // NUL characters may occur
641cdf0e10cSrcweir aTarget = rStrm.readUniString( true );
642cdf0e10cSrcweir }
643cdf0e10cSrcweir
644cdf0e10cSrcweir // parse the encoded URL
645cdf0e10cSrcweir OUString aDummySheetName = parseBiffTargetUrl( aTarget );
646cdf0e10cSrcweir OSL_ENSURE( aDummySheetName.getLength() == 0, "ExternalLink::importExternalBook - sheet name in encoded URL" );
647cdf0e10cSrcweir (void)aDummySheetName; // prevent compiler warning
648cdf0e10cSrcweir
649cdf0e10cSrcweir // load external sheet names and create the sheet caches in the Calc document
650cdf0e10cSrcweir if( meLinkType == LINKTYPE_EXTERNAL )
651cdf0e10cSrcweir for( sal_uInt16 nSheet = 0; !rStrm.isEof() && (nSheet < nSheetCount); ++nSheet )
652cdf0e10cSrcweir insertExternalSheet( rStrm.readUniString() );
653cdf0e10cSrcweir }
654cdf0e10cSrcweir
importExternalName(BiffInputStream & rStrm)655cdf0e10cSrcweir void ExternalLink::importExternalName( BiffInputStream& rStrm )
656cdf0e10cSrcweir {
657cdf0e10cSrcweir ExternalNameRef xExtName = createExternalName();
658cdf0e10cSrcweir xExtName->importExternalName( rStrm );
659cdf0e10cSrcweir switch( meLinkType )
660cdf0e10cSrcweir {
661cdf0e10cSrcweir case LINKTYPE_DDE:
662cdf0e10cSrcweir OSL_ENSURE( !xExtName->isOleObject(), "ExternalLink::importExternalName - OLE object in DDE link" );
663cdf0e10cSrcweir break;
664cdf0e10cSrcweir case LINKTYPE_OLE:
665cdf0e10cSrcweir OSL_ENSURE( xExtName->isOleObject(), "ExternalLink::importExternalName - anything but OLE object in OLE link" );
666cdf0e10cSrcweir break;
667cdf0e10cSrcweir case LINKTYPE_MAYBE_DDE_OLE:
668cdf0e10cSrcweir meLinkType = xExtName->isOleObject() ? LINKTYPE_OLE : LINKTYPE_DDE;
669cdf0e10cSrcweir break;
670cdf0e10cSrcweir default:
671cdf0e10cSrcweir OSL_ENSURE( !xExtName->isOleObject(), "ExternalLink::importExternalName - OLE object in external name" );
672cdf0e10cSrcweir }
673cdf0e10cSrcweir }
674cdf0e10cSrcweir
getLinkInfo() const675cdf0e10cSrcweir ExternalLinkInfo ExternalLink::getLinkInfo() const
676cdf0e10cSrcweir {
677cdf0e10cSrcweir ExternalLinkInfo aLinkInfo;
678cdf0e10cSrcweir switch( meLinkType )
679cdf0e10cSrcweir {
680cdf0e10cSrcweir case LINKTYPE_SELF:
681cdf0e10cSrcweir case LINKTYPE_SAME:
682cdf0e10cSrcweir case LINKTYPE_INTERNAL:
683cdf0e10cSrcweir aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::SELF;
684cdf0e10cSrcweir break;
685cdf0e10cSrcweir case LINKTYPE_EXTERNAL:
686cdf0e10cSrcweir aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::DOCUMENT;
687cdf0e10cSrcweir aLinkInfo.Data <<= maTargetUrl;
688cdf0e10cSrcweir break;
689cdf0e10cSrcweir case LINKTYPE_LIBRARY:
690cdf0e10cSrcweir // parser will return library function names in OPCODE_BAD string tokens
691cdf0e10cSrcweir aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::SPECIAL;
692cdf0e10cSrcweir break;
693cdf0e10cSrcweir case LINKTYPE_DDE:
694cdf0e10cSrcweir {
695cdf0e10cSrcweir aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::DDE;
696cdf0e10cSrcweir DDELinkInfo aDdeLinkInfo;
697cdf0e10cSrcweir aDdeLinkInfo.Service = maClassName;
698cdf0e10cSrcweir aDdeLinkInfo.Topic = maTargetUrl;
699cdf0e10cSrcweir ::std::vector< DDEItemInfo > aItemInfos;
700cdf0e10cSrcweir DDEItemInfo aItemInfo;
701cdf0e10cSrcweir for( ExternalNameVector::const_iterator aIt = maExtNames.begin(), aEnd = maExtNames.end(); aIt != aEnd; ++aIt )
702cdf0e10cSrcweir if( (*aIt)->getDdeItemInfo( aItemInfo ) )
703cdf0e10cSrcweir aItemInfos.push_back( aItemInfo );
704cdf0e10cSrcweir aDdeLinkInfo.Items = ContainerHelper::vectorToSequence( aItemInfos );
705cdf0e10cSrcweir aLinkInfo.Data <<= aDdeLinkInfo;
706cdf0e10cSrcweir }
707cdf0e10cSrcweir break;
708cdf0e10cSrcweir default:
709cdf0e10cSrcweir aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::UNKNOWN;
710cdf0e10cSrcweir }
711cdf0e10cSrcweir return aLinkInfo;
712cdf0e10cSrcweir }
713cdf0e10cSrcweir
getFuncLibraryType() const714cdf0e10cSrcweir FunctionLibraryType ExternalLink::getFuncLibraryType() const
715cdf0e10cSrcweir {
716cdf0e10cSrcweir return (meLinkType == LINKTYPE_LIBRARY) ? meFuncLibType : FUNCLIB_UNKNOWN;
717cdf0e10cSrcweir }
718cdf0e10cSrcweir
getCalcSheetIndex(sal_Int32 nTabId) const719cdf0e10cSrcweir sal_Int16 ExternalLink::getCalcSheetIndex( sal_Int32 nTabId ) const
720cdf0e10cSrcweir {
721cdf0e10cSrcweir OSL_ENSURE( meLinkType == LINKTYPE_INTERNAL, "ExternalLink::getCalcSheetIndex - invalid link type" );
722cdf0e10cSrcweir OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOXML) || (getBiff() == BIFF8),
723cdf0e10cSrcweir "ExternalLink::getCalcSheetIndex - invalid sheet index" );
724cdf0e10cSrcweir return ContainerHelper::getVectorElement( maCalcSheets, nTabId, -1 );
725cdf0e10cSrcweir }
726cdf0e10cSrcweir
getDocumentLinkIndex() const727cdf0e10cSrcweir sal_Int32 ExternalLink::getDocumentLinkIndex() const
728cdf0e10cSrcweir {
729cdf0e10cSrcweir OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getDocumentLinkIndex - invalid link type" );
730cdf0e10cSrcweir return mxDocLink.is() ? mxDocLink->getTokenIndex() : -1;
731cdf0e10cSrcweir }
732cdf0e10cSrcweir
getSheetCacheIndex(sal_Int32 nTabId) const733cdf0e10cSrcweir sal_Int32 ExternalLink::getSheetCacheIndex( sal_Int32 nTabId ) const
734cdf0e10cSrcweir {
735cdf0e10cSrcweir OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getSheetCacheIndex - invalid link type" );
736cdf0e10cSrcweir OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOXML) || (getBiff() == BIFF8),
737cdf0e10cSrcweir "ExternalLink::getSheetCacheIndex - invalid sheet index" );
738cdf0e10cSrcweir return ContainerHelper::getVectorElement( maSheetCaches, nTabId, -1 );
739cdf0e10cSrcweir }
740cdf0e10cSrcweir
getSheetCache(sal_Int32 nTabId) const741cdf0e10cSrcweir Reference< XExternalSheetCache > ExternalLink::getSheetCache( sal_Int32 nTabId ) const
742cdf0e10cSrcweir {
743cdf0e10cSrcweir sal_Int32 nCacheIdx = getSheetCacheIndex( nTabId );
744cdf0e10cSrcweir if( mxDocLink.is() && (nCacheIdx >= 0) ) try
745cdf0e10cSrcweir {
746cdf0e10cSrcweir // existing mxDocLink implies that this is an external link
747cdf0e10cSrcweir Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( nCacheIdx ), UNO_QUERY_THROW );
748cdf0e10cSrcweir return xSheetCache;
749cdf0e10cSrcweir }
750cdf0e10cSrcweir catch( Exception& )
751cdf0e10cSrcweir {
752cdf0e10cSrcweir }
753cdf0e10cSrcweir return 0;
754cdf0e10cSrcweir }
755cdf0e10cSrcweir
getSheetRange(LinkSheetRange & orSheetRange,sal_Int32 nTabId1,sal_Int32 nTabId2) const756cdf0e10cSrcweir void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const
757cdf0e10cSrcweir {
758cdf0e10cSrcweir switch( meLinkType )
759cdf0e10cSrcweir {
760cdf0e10cSrcweir case LINKTYPE_SAME:
761cdf0e10cSrcweir orSheetRange.setSameSheet();
762cdf0e10cSrcweir break;
763cdf0e10cSrcweir
764cdf0e10cSrcweir case LINKTYPE_SELF:
765cdf0e10cSrcweir case LINKTYPE_INTERNAL:
766cdf0e10cSrcweir orSheetRange.setRange( nTabId1, nTabId2 );
767cdf0e10cSrcweir break;
768cdf0e10cSrcweir
769cdf0e10cSrcweir case LINKTYPE_EXTERNAL:
770cdf0e10cSrcweir {
771cdf0e10cSrcweir sal_Int32 nDocLinkIdx = getDocumentLinkIndex();
772cdf0e10cSrcweir switch( getFilterType() )
773cdf0e10cSrcweir {
774cdf0e10cSrcweir case FILTER_OOXML:
775cdf0e10cSrcweir // BIFF12: passed indexes point into sheet list of EXTSHEETLIST
776cdf0e10cSrcweir orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
777cdf0e10cSrcweir break;
778cdf0e10cSrcweir case FILTER_BIFF:
779cdf0e10cSrcweir switch( getBiff() )
780cdf0e10cSrcweir {
781cdf0e10cSrcweir case BIFF2:
782cdf0e10cSrcweir case BIFF3:
783cdf0e10cSrcweir case BIFF4:
784cdf0e10cSrcweir orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
785cdf0e10cSrcweir break;
786cdf0e10cSrcweir case BIFF5:
787cdf0e10cSrcweir // BIFF5: first sheet from this external link, last sheet is passed in nTabId2
788cdf0e10cSrcweir if( const ExternalLink* pExtLink2 = getExternalLinks().getExternalLink( nTabId2 ).get() )
789cdf0e10cSrcweir if( (pExtLink2->getLinkType() == LINKTYPE_EXTERNAL) && (maTargetUrl == pExtLink2->getTargetUrl()) )
790cdf0e10cSrcweir orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex(), pExtLink2->getSheetCacheIndex() );
791cdf0e10cSrcweir break;
792cdf0e10cSrcweir case BIFF8:
793cdf0e10cSrcweir // BIFF8: passed indexes point into sheet list of EXTERNALBOOK
794cdf0e10cSrcweir orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
795cdf0e10cSrcweir break;
796cdf0e10cSrcweir case BIFF_UNKNOWN: break;
797cdf0e10cSrcweir }
798cdf0e10cSrcweir break;
799cdf0e10cSrcweir case FILTER_UNKNOWN: break;
800cdf0e10cSrcweir }
801cdf0e10cSrcweir }
802cdf0e10cSrcweir break;
803cdf0e10cSrcweir
804cdf0e10cSrcweir default:
805cdf0e10cSrcweir // unsupported/unexpected link type: #REF! error
806cdf0e10cSrcweir orSheetRange.setDeleted();
807cdf0e10cSrcweir }
808cdf0e10cSrcweir }
809cdf0e10cSrcweir
getNameByIndex(sal_Int32 nIndex) const810cdf0e10cSrcweir ExternalNameRef ExternalLink::getNameByIndex( sal_Int32 nIndex ) const
811cdf0e10cSrcweir {
812cdf0e10cSrcweir return maExtNames.get( nIndex );
813cdf0e10cSrcweir }
814cdf0e10cSrcweir
815cdf0e10cSrcweir // private --------------------------------------------------------------------
816cdf0e10cSrcweir
817cdf0e10cSrcweir #define OOX_TARGETTYPE_EXTLINK CREATE_OFFICEDOC_RELATION_TYPE( "externalLinkPath" )
818cdf0e10cSrcweir #define OOX_TARGETTYPE_LIBRARY CREATE_MSOFFICE_RELATION_TYPE( "xlExternalLinkPath/xlLibrary" )
819cdf0e10cSrcweir
setExternalTargetUrl(const OUString & rTargetUrl,const OUString & rTargetType)820cdf0e10cSrcweir void ExternalLink::setExternalTargetUrl( const OUString& rTargetUrl, const OUString& rTargetType )
821cdf0e10cSrcweir {
822cdf0e10cSrcweir meLinkType = LINKTYPE_UNKNOWN;
823cdf0e10cSrcweir if( rTargetType == OOX_TARGETTYPE_EXTLINK )
824cdf0e10cSrcweir {
825cdf0e10cSrcweir maTargetUrl = getBaseFilter().getAbsoluteUrl( rTargetUrl );
826cdf0e10cSrcweir if( maTargetUrl.getLength() > 0 )
827cdf0e10cSrcweir meLinkType = LINKTYPE_EXTERNAL;
828cdf0e10cSrcweir }
829cdf0e10cSrcweir else if( rTargetType == OOX_TARGETTYPE_LIBRARY )
830cdf0e10cSrcweir {
831cdf0e10cSrcweir meLinkType = LINKTYPE_LIBRARY;
832cdf0e10cSrcweir meFuncLibType = getFormulaParser().getFuncLibTypeFromLibraryName( rTargetUrl );
833cdf0e10cSrcweir }
834cdf0e10cSrcweir OSL_ENSURE( meLinkType != LINKTYPE_UNKNOWN, "ExternalLink::setExternalTargetUrl - empty target URL or unknown target type" );
835cdf0e10cSrcweir
836cdf0e10cSrcweir // create the external document link API object that will contain the sheet caches
837cdf0e10cSrcweir if( meLinkType == LINKTYPE_EXTERNAL ) try
838cdf0e10cSrcweir {
839cdf0e10cSrcweir PropertySet aDocProps( getDocument() );
840cdf0e10cSrcweir Reference< XExternalDocLinks > xDocLinks( aDocProps.getAnyProperty( PROP_ExternalDocLinks ), UNO_QUERY_THROW );
841cdf0e10cSrcweir mxDocLink = xDocLinks->addDocLink( maTargetUrl );
842cdf0e10cSrcweir }
843cdf0e10cSrcweir catch( Exception& )
844cdf0e10cSrcweir {
845cdf0e10cSrcweir }
846cdf0e10cSrcweir }
847cdf0e10cSrcweir
setDdeOleTargetUrl(const OUString & rClassName,const OUString & rTargetUrl,ExternalLinkType eLinkType)848cdf0e10cSrcweir void ExternalLink::setDdeOleTargetUrl( const OUString& rClassName, const OUString& rTargetUrl, ExternalLinkType eLinkType )
849cdf0e10cSrcweir {
850cdf0e10cSrcweir maClassName = rClassName;
851cdf0e10cSrcweir maTargetUrl = rTargetUrl;
852cdf0e10cSrcweir meLinkType = ((maClassName.getLength() > 0) && (maTargetUrl.getLength() > 0)) ? eLinkType : LINKTYPE_UNKNOWN;
853cdf0e10cSrcweir OSL_ENSURE( meLinkType == eLinkType, "ExternalLink::setDdeOleTargetUrl - missing classname or target" );
854cdf0e10cSrcweir }
855cdf0e10cSrcweir
parseExternalReference(const Relations & rRelations,const OUString & rRelId)856cdf0e10cSrcweir void ExternalLink::parseExternalReference( const Relations& rRelations, const OUString& rRelId )
857cdf0e10cSrcweir {
858cdf0e10cSrcweir if( const Relation* pRelation = rRelations.getRelationFromRelId( rRelId ) )
859cdf0e10cSrcweir setExternalTargetUrl( pRelation->maTarget, pRelation->maType );
860cdf0e10cSrcweir }
861cdf0e10cSrcweir
parseBiffTargetUrl(const OUString & rBiffTargetUrl)862cdf0e10cSrcweir OUString ExternalLink::parseBiffTargetUrl( const OUString& rBiffTargetUrl )
863cdf0e10cSrcweir {
864cdf0e10cSrcweir meLinkType = LINKTYPE_UNKNOWN;
865cdf0e10cSrcweir
866cdf0e10cSrcweir OUString aClassName, aTargetUrl, aSheetName;
867cdf0e10cSrcweir switch( getAddressConverter().parseBiffTargetUrl( aClassName, aTargetUrl, aSheetName, rBiffTargetUrl ) )
868cdf0e10cSrcweir {
869cdf0e10cSrcweir case BIFF_TARGETTYPE_URL:
870cdf0e10cSrcweir if( aTargetUrl.getLength() == 0 )
871cdf0e10cSrcweir {
872cdf0e10cSrcweir meLinkType = (aSheetName.getLength() > 0) ? LINKTYPE_INTERNAL : LINKTYPE_SELF;
873cdf0e10cSrcweir }
874cdf0e10cSrcweir else if( (aTargetUrl.getLength() == 1) && (aTargetUrl[ 0 ] == ':') )
875cdf0e10cSrcweir {
876cdf0e10cSrcweir if( getBiff() >= BIFF4 )
877cdf0e10cSrcweir meLinkType = LINKTYPE_ANALYSIS;
878cdf0e10cSrcweir }
879cdf0e10cSrcweir else if( (aTargetUrl.getLength() > 1) || (aTargetUrl[ 0 ] != ' ') )
880cdf0e10cSrcweir {
881cdf0e10cSrcweir setExternalTargetUrl( aTargetUrl, OOX_TARGETTYPE_EXTLINK );
882cdf0e10cSrcweir }
883cdf0e10cSrcweir break;
884cdf0e10cSrcweir
885cdf0e10cSrcweir case BIFF_TARGETTYPE_SAMESHEET:
886cdf0e10cSrcweir OSL_ENSURE( (aTargetUrl.getLength() == 0) && (aSheetName.getLength() == 0), "ExternalLink::parseBiffTargetUrl - unexpected target or sheet name" );
887cdf0e10cSrcweir meLinkType = LINKTYPE_SAME;
888cdf0e10cSrcweir break;
889cdf0e10cSrcweir
890cdf0e10cSrcweir case BIFF_TARGETTYPE_LIBRARY:
891cdf0e10cSrcweir OSL_ENSURE( aSheetName.getLength() == 0, "ExternalLink::parseBiffTargetUrl - unexpected sheet name" );
892cdf0e10cSrcweir setExternalTargetUrl( aTargetUrl, OOX_TARGETTYPE_LIBRARY );
893cdf0e10cSrcweir break;
894cdf0e10cSrcweir
895cdf0e10cSrcweir case BIFF_TARGETTYPE_DDE_OLE:
896cdf0e10cSrcweir setDdeOleTargetUrl( aClassName, aTargetUrl, LINKTYPE_MAYBE_DDE_OLE );
897cdf0e10cSrcweir break;
898cdf0e10cSrcweir
899cdf0e10cSrcweir case BIFF_TARGETTYPE_UNKNOWN:
900cdf0e10cSrcweir break;
901cdf0e10cSrcweir }
902cdf0e10cSrcweir return aSheetName;
903cdf0e10cSrcweir }
904cdf0e10cSrcweir
insertExternalSheet(const OUString & rSheetName)905cdf0e10cSrcweir void ExternalLink::insertExternalSheet( const OUString& rSheetName )
906cdf0e10cSrcweir {
907cdf0e10cSrcweir OSL_ENSURE( rSheetName.getLength() > 0, "ExternalLink::insertExternalSheet - empty sheet name" );
908cdf0e10cSrcweir if( mxDocLink.is() )
909cdf0e10cSrcweir {
910cdf0e10cSrcweir Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName, false );
911cdf0e10cSrcweir sal_Int32 nCacheIdx = xSheetCache.is() ? xSheetCache->getTokenIndex() : -1;
912cdf0e10cSrcweir maSheetCaches.push_back( nCacheIdx );
913cdf0e10cSrcweir }
914cdf0e10cSrcweir }
915cdf0e10cSrcweir
createExternalName()916cdf0e10cSrcweir ExternalNameRef ExternalLink::createExternalName()
917cdf0e10cSrcweir {
918cdf0e10cSrcweir ExternalNameRef xExtName( new ExternalName( *this ) );
919cdf0e10cSrcweir maExtNames.push_back( xExtName );
920cdf0e10cSrcweir return xExtName;
921cdf0e10cSrcweir }
922cdf0e10cSrcweir
923cdf0e10cSrcweir // ============================================================================
924cdf0e10cSrcweir
RefSheetsModel()925cdf0e10cSrcweir RefSheetsModel::RefSheetsModel() :
926cdf0e10cSrcweir mnExtRefId( -1 ),
927cdf0e10cSrcweir mnTabId1( -1 ),
928cdf0e10cSrcweir mnTabId2( -1 )
929cdf0e10cSrcweir {
930cdf0e10cSrcweir }
931cdf0e10cSrcweir
readBiff12Data(SequenceInputStream & rStrm)932cdf0e10cSrcweir void RefSheetsModel::readBiff12Data( SequenceInputStream& rStrm )
933cdf0e10cSrcweir {
934cdf0e10cSrcweir rStrm >> mnExtRefId >> mnTabId1 >> mnTabId2;
935cdf0e10cSrcweir }
936cdf0e10cSrcweir
readBiff8Data(BiffInputStream & rStrm)937cdf0e10cSrcweir void RefSheetsModel::readBiff8Data( BiffInputStream& rStrm )
938cdf0e10cSrcweir {
939cdf0e10cSrcweir mnExtRefId = rStrm.readuInt16();
940cdf0e10cSrcweir mnTabId1 = rStrm.readInt16();
941cdf0e10cSrcweir mnTabId2 = rStrm.readInt16();
942cdf0e10cSrcweir }
943cdf0e10cSrcweir
944cdf0e10cSrcweir // ----------------------------------------------------------------------------
945cdf0e10cSrcweir
ExternalLinkBuffer(const WorkbookHelper & rHelper)946cdf0e10cSrcweir ExternalLinkBuffer::ExternalLinkBuffer( const WorkbookHelper& rHelper ) :
947cdf0e10cSrcweir WorkbookHelper( rHelper ),
948cdf0e10cSrcweir mxSelfRef( new ExternalLink( rHelper ) ),
949cdf0e10cSrcweir mbUseRefSheets( false )
950cdf0e10cSrcweir {
951cdf0e10cSrcweir mxSelfRef->setSelfLinkType();
952cdf0e10cSrcweir }
953cdf0e10cSrcweir
importExternalReference(const AttributeList & rAttribs)954cdf0e10cSrcweir ExternalLinkRef ExternalLinkBuffer::importExternalReference( const AttributeList& rAttribs )
955cdf0e10cSrcweir {
956cdf0e10cSrcweir ExternalLinkRef xExtLink = createExternalLink();
957cdf0e10cSrcweir xExtLink->importExternalReference( rAttribs );
958cdf0e10cSrcweir maExtLinks.push_back( xExtLink );
959cdf0e10cSrcweir return xExtLink;
960cdf0e10cSrcweir }
961cdf0e10cSrcweir
importExternalRef(SequenceInputStream & rStrm)962cdf0e10cSrcweir ExternalLinkRef ExternalLinkBuffer::importExternalRef( SequenceInputStream& rStrm )
963cdf0e10cSrcweir {
964cdf0e10cSrcweir mbUseRefSheets = true;
965cdf0e10cSrcweir ExternalLinkRef xExtLink = createExternalLink();
966cdf0e10cSrcweir xExtLink->importExternalRef( rStrm );
967cdf0e10cSrcweir maExtLinks.push_back( xExtLink );
968cdf0e10cSrcweir return xExtLink;
969cdf0e10cSrcweir }
970cdf0e10cSrcweir
importExternalSelf(SequenceInputStream & rStrm)971cdf0e10cSrcweir void ExternalLinkBuffer::importExternalSelf( SequenceInputStream& rStrm )
972cdf0e10cSrcweir {
973cdf0e10cSrcweir mbUseRefSheets = true;
974cdf0e10cSrcweir createExternalLink()->importExternalSelf( rStrm );
975cdf0e10cSrcweir }
976cdf0e10cSrcweir
importExternalSame(SequenceInputStream & rStrm)977cdf0e10cSrcweir void ExternalLinkBuffer::importExternalSame( SequenceInputStream& rStrm )
978cdf0e10cSrcweir {
979cdf0e10cSrcweir mbUseRefSheets = true;
980cdf0e10cSrcweir createExternalLink()->importExternalSame( rStrm );
981cdf0e10cSrcweir }
982cdf0e10cSrcweir
importExternalAddin(SequenceInputStream & rStrm)983cdf0e10cSrcweir void ExternalLinkBuffer::importExternalAddin( SequenceInputStream& rStrm )
984cdf0e10cSrcweir {
985cdf0e10cSrcweir mbUseRefSheets = true;
986cdf0e10cSrcweir createExternalLink()->importExternalAddin( rStrm );
987cdf0e10cSrcweir }
988cdf0e10cSrcweir
importExternalSheets(SequenceInputStream & rStrm)989cdf0e10cSrcweir void ExternalLinkBuffer::importExternalSheets( SequenceInputStream& rStrm )
990cdf0e10cSrcweir {
991cdf0e10cSrcweir OSL_ENSURE( mbUseRefSheets, "ExternalLinkBuffer::importExternalSheets - missing EXTERNALREFS records" );
992cdf0e10cSrcweir mbUseRefSheets = true;
993cdf0e10cSrcweir OSL_ENSURE( maRefSheets.empty(), "ExternalLinkBuffer::importExternalSheets - multiple EXTERNALSHEETS records" );
994cdf0e10cSrcweir maRefSheets.clear();
995cdf0e10cSrcweir sal_Int32 nRefCount;
996cdf0e10cSrcweir rStrm >> nRefCount;
997cdf0e10cSrcweir size_t nMaxCount = getLimitedValue< size_t, sal_Int64 >( nRefCount, 0, rStrm.getRemaining() / 12 );
998cdf0e10cSrcweir maRefSheets.reserve( nMaxCount );
999cdf0e10cSrcweir for( size_t nRefId = 0; !rStrm.isEof() && (nRefId < nMaxCount); ++nRefId )
1000cdf0e10cSrcweir {
1001cdf0e10cSrcweir RefSheetsModel aRefSheets;
1002cdf0e10cSrcweir aRefSheets.readBiff12Data( rStrm );
1003cdf0e10cSrcweir maRefSheets.push_back( aRefSheets );
1004cdf0e10cSrcweir }
1005cdf0e10cSrcweir }
1006cdf0e10cSrcweir
importExternSheet(BiffInputStream & rStrm)1007cdf0e10cSrcweir ExternalLinkRef ExternalLinkBuffer::importExternSheet( BiffInputStream& rStrm )
1008cdf0e10cSrcweir {
1009cdf0e10cSrcweir OSL_ENSURE( getBiff() <= BIFF5, "ExternalLinkBuffer::importExternSheet - wrong BIFF version" );
1010cdf0e10cSrcweir ExternalLinkRef xExtLink = createExternalLink();
1011cdf0e10cSrcweir xExtLink->importExternSheet( rStrm );
1012cdf0e10cSrcweir return xExtLink;
1013cdf0e10cSrcweir }
1014cdf0e10cSrcweir
importExternalBook(BiffInputStream & rStrm)1015cdf0e10cSrcweir ExternalLinkRef ExternalLinkBuffer::importExternalBook( BiffInputStream& rStrm )
1016cdf0e10cSrcweir {
1017cdf0e10cSrcweir ExternalLinkRef xExtLink = createExternalLink();
1018cdf0e10cSrcweir xExtLink->importExternalBook( rStrm );
1019cdf0e10cSrcweir return xExtLink;
1020cdf0e10cSrcweir }
1021cdf0e10cSrcweir
importExternalName(BiffInputStream & rStrm)1022cdf0e10cSrcweir void ExternalLinkBuffer::importExternalName( BiffInputStream& rStrm )
1023cdf0e10cSrcweir {
1024cdf0e10cSrcweir if( !maLinks.empty() )
1025cdf0e10cSrcweir maLinks.back()->importExternalName( rStrm );
1026cdf0e10cSrcweir }
1027cdf0e10cSrcweir
importExternSheet8(BiffInputStream & rStrm)1028cdf0e10cSrcweir void ExternalLinkBuffer::importExternSheet8( BiffInputStream& rStrm )
1029cdf0e10cSrcweir {
1030cdf0e10cSrcweir OSL_ENSURE( getBiff() == BIFF8, "ExternalLinkBuffer::importExternSheet8 - wrong BIFF version" );
1031cdf0e10cSrcweir
1032cdf0e10cSrcweir sal_uInt16 nRefCount;
1033cdf0e10cSrcweir rStrm >> nRefCount;
1034cdf0e10cSrcweir OSL_ENSURE( static_cast< sal_Int64 >( nRefCount * 6 ) == rStrm.getRemaining(), "ExternalLinkBuffer::importExternSheet8 - invalid count" );
1035cdf0e10cSrcweir nRefCount = static_cast< sal_uInt16 >( ::std::min< sal_Int64 >( nRefCount, rStrm.getRemaining() / 6 ) );
1036cdf0e10cSrcweir
1037cdf0e10cSrcweir /* #i104057# A weird external XLS generator writes multiple EXTERNSHEET
1038cdf0e10cSrcweir records instead of only one as expected. Surprisingly, Excel seems to
1039cdf0e10cSrcweir insert the entries of the second record before the entries of the first
1040cdf0e10cSrcweir record. */
1041cdf0e10cSrcweir maRefSheets.insert( maRefSheets.begin(), nRefCount, RefSheetsModel() );
1042cdf0e10cSrcweir for( RefSheetsModelVec::iterator aIt = maRefSheets.begin(), aEnd = aIt + nRefCount; !rStrm.isEof() && (aIt != aEnd); ++aIt )
1043cdf0e10cSrcweir aIt->readBiff8Data( rStrm );
1044cdf0e10cSrcweir }
1045cdf0e10cSrcweir
getLinkInfos() const1046cdf0e10cSrcweir Sequence< ExternalLinkInfo > ExternalLinkBuffer::getLinkInfos() const
1047cdf0e10cSrcweir {
1048cdf0e10cSrcweir ::std::vector< ExternalLinkInfo > aLinkInfos;
1049cdf0e10cSrcweir // XML formula parser also used in BIFF12 documents, e.g. replacement formulas in unsupported conditional formattings
1050cdf0e10cSrcweir OSL_ENSURE( getFilterType() == FILTER_OOXML, "ExternalLinkBuffer::getLinkInfos - unexpected file format" );
1051cdf0e10cSrcweir // add entry for implicit index 0 (self reference to this document)
1052cdf0e10cSrcweir aLinkInfos.push_back( mxSelfRef->getLinkInfo() );
1053cdf0e10cSrcweir for( ExternalLinkVec::const_iterator aIt = maExtLinks.begin(), aEnd = maExtLinks.end(); aIt != aEnd; ++aIt )
1054cdf0e10cSrcweir aLinkInfos.push_back( (*aIt)->getLinkInfo() );
1055cdf0e10cSrcweir return ContainerHelper::vectorToSequence( aLinkInfos );
1056cdf0e10cSrcweir }
1057cdf0e10cSrcweir
getExternalLink(sal_Int32 nRefId,bool bUseRefSheets) const1058cdf0e10cSrcweir ExternalLinkRef ExternalLinkBuffer::getExternalLink( sal_Int32 nRefId, bool bUseRefSheets ) const
1059cdf0e10cSrcweir {
1060cdf0e10cSrcweir ExternalLinkRef xExtLink;
1061cdf0e10cSrcweir switch( getFilterType() )
1062cdf0e10cSrcweir {
1063cdf0e10cSrcweir case FILTER_OOXML:
1064cdf0e10cSrcweir // OOXML: 0 = this document, otherwise one-based index into link list
1065cdf0e10cSrcweir if( !bUseRefSheets || !mbUseRefSheets )
1066cdf0e10cSrcweir xExtLink = (nRefId == 0) ? mxSelfRef : maLinks.get( nRefId - 1 );
1067cdf0e10cSrcweir // BIFF12: zero-based index into ref-sheets list
1068cdf0e10cSrcweir else if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
1069cdf0e10cSrcweir xExtLink = maLinks.get( pRefSheets->mnExtRefId );
1070cdf0e10cSrcweir break;
1071cdf0e10cSrcweir case FILTER_BIFF:
1072cdf0e10cSrcweir switch( getBiff() )
1073cdf0e10cSrcweir {
1074cdf0e10cSrcweir case BIFF2:
1075cdf0e10cSrcweir case BIFF3:
1076cdf0e10cSrcweir case BIFF4:
1077cdf0e10cSrcweir // one-based index to EXTERNSHEET records
1078cdf0e10cSrcweir xExtLink = maLinks.get( nRefId - 1 );
1079cdf0e10cSrcweir break;
1080cdf0e10cSrcweir case BIFF5:
1081cdf0e10cSrcweir if( nRefId < 0 )
1082cdf0e10cSrcweir {
1083cdf0e10cSrcweir // internal links in formula tokens have negative index
1084cdf0e10cSrcweir xExtLink = maLinks.get( -nRefId - 1 );
1085cdf0e10cSrcweir if( xExtLink.get() && !xExtLink->isInternalLink() )
1086cdf0e10cSrcweir xExtLink.reset();
1087cdf0e10cSrcweir }
1088cdf0e10cSrcweir else
1089cdf0e10cSrcweir {
1090cdf0e10cSrcweir // one-based index to EXTERNSHEET records
1091cdf0e10cSrcweir xExtLink = maLinks.get( nRefId - 1 );
1092cdf0e10cSrcweir }
1093cdf0e10cSrcweir break;
1094cdf0e10cSrcweir case BIFF8:
1095cdf0e10cSrcweir // zero-based index into REF list in EXTERNSHEET record
1096cdf0e10cSrcweir if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
1097cdf0e10cSrcweir xExtLink = maLinks.get( pRefSheets->mnExtRefId );
1098cdf0e10cSrcweir break;
1099cdf0e10cSrcweir case BIFF_UNKNOWN: break;
1100cdf0e10cSrcweir }
1101cdf0e10cSrcweir break;
1102cdf0e10cSrcweir case FILTER_UNKNOWN: break;
1103cdf0e10cSrcweir }
1104cdf0e10cSrcweir return xExtLink;
1105cdf0e10cSrcweir }
1106cdf0e10cSrcweir
getSheetRange(sal_Int32 nRefId,sal_Int16 nTabId1,sal_Int16 nTabId2) const1107cdf0e10cSrcweir LinkSheetRange ExternalLinkBuffer::getSheetRange( sal_Int32 nRefId, sal_Int16 nTabId1, sal_Int16 nTabId2 ) const
1108cdf0e10cSrcweir {
1109cdf0e10cSrcweir OSL_ENSURE( getBiff() <= BIFF5, "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
1110cdf0e10cSrcweir LinkSheetRange aSheetRange;
1111cdf0e10cSrcweir if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
1112cdf0e10cSrcweir pExtLink->getSheetRange( aSheetRange, nTabId1, nTabId2 );
1113cdf0e10cSrcweir return aSheetRange;
1114cdf0e10cSrcweir }
1115cdf0e10cSrcweir
getSheetRange(sal_Int32 nRefId) const1116cdf0e10cSrcweir LinkSheetRange ExternalLinkBuffer::getSheetRange( sal_Int32 nRefId ) const
1117cdf0e10cSrcweir {
1118cdf0e10cSrcweir OSL_ENSURE( ((getFilterType() == FILTER_OOXML) && mbUseRefSheets) || (getBiff() == BIFF8), "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
1119cdf0e10cSrcweir LinkSheetRange aSheetRange;
1120cdf0e10cSrcweir if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
1121cdf0e10cSrcweir if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
1122cdf0e10cSrcweir pExtLink->getSheetRange( aSheetRange, pRefSheets->mnTabId1, pRefSheets->mnTabId2 );
1123cdf0e10cSrcweir return aSheetRange;
1124cdf0e10cSrcweir }
1125cdf0e10cSrcweir
1126cdf0e10cSrcweir // private --------------------------------------------------------------------
1127cdf0e10cSrcweir
createExternalLink()1128cdf0e10cSrcweir ExternalLinkRef ExternalLinkBuffer::createExternalLink()
1129cdf0e10cSrcweir {
1130cdf0e10cSrcweir ExternalLinkRef xExtLink( new ExternalLink( *this ) );
1131cdf0e10cSrcweir maLinks.push_back( xExtLink );
1132cdf0e10cSrcweir return xExtLink;
1133cdf0e10cSrcweir }
1134cdf0e10cSrcweir
getRefSheets(sal_Int32 nRefId) const1135cdf0e10cSrcweir const RefSheetsModel* ExternalLinkBuffer::getRefSheets( sal_Int32 nRefId ) const
1136cdf0e10cSrcweir {
1137cdf0e10cSrcweir return ((0 <= nRefId) && (static_cast< size_t >( nRefId ) < maRefSheets.size())) ?
1138cdf0e10cSrcweir &maRefSheets[ static_cast< size_t >( nRefId ) ] : 0;
1139cdf0e10cSrcweir }
1140cdf0e10cSrcweir
1141cdf0e10cSrcweir // ============================================================================
1142cdf0e10cSrcweir
1143cdf0e10cSrcweir } // namespace xls
1144cdf0e10cSrcweir } // namespace oox
1145