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 10cdf0e10cSrcweir * 11*ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 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 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 99cdf0e10cSrcweir ExternalName::ExternalName( const ExternalLink& rParentLink ) : 100cdf0e10cSrcweir DefinedNameBase( rParentLink ), 101cdf0e10cSrcweir mrParentLink( rParentLink ), 102cdf0e10cSrcweir mnStorageId( 0 ), 103cdf0e10cSrcweir mbDdeLinkCreated( false ) 104cdf0e10cSrcweir { 105cdf0e10cSrcweir } 106cdf0e10cSrcweir 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 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 125cdf0e10cSrcweir void ExternalName::importValues( const AttributeList& rAttribs ) 126cdf0e10cSrcweir { 127cdf0e10cSrcweir setResultSize( rAttribs.getInteger( XML_cols, 1 ), rAttribs.getInteger( XML_rows, 1 ) ); 128cdf0e10cSrcweir } 129cdf0e10cSrcweir 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 140cdf0e10cSrcweir void ExternalName::importExternalName( SequenceInputStream& rStrm ) 141cdf0e10cSrcweir { 142cdf0e10cSrcweir rStrm >> maModel.maName; 143cdf0e10cSrcweir OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importExternalName - empty name" ); 144cdf0e10cSrcweir } 145cdf0e10cSrcweir 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 163cdf0e10cSrcweir void ExternalName::importDdeItemValues( SequenceInputStream& rStrm ) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir sal_Int32 nRows, nCols; 166cdf0e10cSrcweir rStrm >> nRows >> nCols; 167cdf0e10cSrcweir setResultSize( nCols, nRows ); 168cdf0e10cSrcweir } 169cdf0e10cSrcweir 170cdf0e10cSrcweir void ExternalName::importDdeItemBool( SequenceInputStream& rStrm ) 171cdf0e10cSrcweir { 172cdf0e10cSrcweir appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 ); 173cdf0e10cSrcweir } 174cdf0e10cSrcweir 175cdf0e10cSrcweir void ExternalName::importDdeItemDouble( SequenceInputStream& rStrm ) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir appendResultValue( rStrm.readDouble() ); 178cdf0e10cSrcweir } 179cdf0e10cSrcweir 180cdf0e10cSrcweir void ExternalName::importDdeItemError( SequenceInputStream& rStrm ) 181cdf0e10cSrcweir { 182cdf0e10cSrcweir appendResultValue( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) ); 183cdf0e10cSrcweir } 184cdf0e10cSrcweir 185cdf0e10cSrcweir void ExternalName::importDdeItemString( SequenceInputStream& rStrm ) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir appendResultValue( BiffHelper::readString( rStrm ) ); 188cdf0e10cSrcweir } 189cdf0e10cSrcweir 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 343cdf0e10cSrcweir 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 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 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 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 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 447cdf0e10cSrcweir void LinkSheetRange::setDeleted() 448cdf0e10cSrcweir { 449cdf0e10cSrcweir meType = LINKSHEETRANGE_INTERNAL; 450cdf0e10cSrcweir mnDocLink = mnFirst = mnLast = -1; 451cdf0e10cSrcweir } 452cdf0e10cSrcweir 453cdf0e10cSrcweir void LinkSheetRange::setSameSheet() 454cdf0e10cSrcweir { 455cdf0e10cSrcweir meType = LINKSHEETRANGE_SAMESHEET; 456cdf0e10cSrcweir mnDocLink = -1; 457cdf0e10cSrcweir mnFirst = mnLast = 0; 458cdf0e10cSrcweir } 459cdf0e10cSrcweir 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 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 485cdf0e10cSrcweir ExternalLink::ExternalLink( const WorkbookHelper& rHelper ) : 486cdf0e10cSrcweir WorkbookHelper( rHelper ), 487cdf0e10cSrcweir meLinkType( LINKTYPE_UNKNOWN ), 488cdf0e10cSrcweir meFuncLibType( FUNCLIB_UNKNOWN ) 489cdf0e10cSrcweir { 490cdf0e10cSrcweir } 491cdf0e10cSrcweir 492cdf0e10cSrcweir void ExternalLink::importExternalReference( const AttributeList& rAttribs ) 493cdf0e10cSrcweir { 494cdf0e10cSrcweir maRelId = rAttribs.getString( R_TOKEN( id ), OUString() ); 495cdf0e10cSrcweir } 496cdf0e10cSrcweir 497cdf0e10cSrcweir void ExternalLink::importExternalBook( const Relations& rRelations, const AttributeList& rAttribs ) 498cdf0e10cSrcweir { 499cdf0e10cSrcweir parseExternalReference( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) ); 500cdf0e10cSrcweir } 501cdf0e10cSrcweir 502cdf0e10cSrcweir void ExternalLink::importSheetName( const AttributeList& rAttribs ) 503cdf0e10cSrcweir { 504cdf0e10cSrcweir insertExternalSheet( rAttribs.getXString( XML_val, OUString() ) ); 505cdf0e10cSrcweir } 506cdf0e10cSrcweir 507cdf0e10cSrcweir void ExternalLink::importDefinedName( const AttributeList& rAttribs ) 508cdf0e10cSrcweir { 509cdf0e10cSrcweir createExternalName()->importDefinedName( rAttribs ); 510cdf0e10cSrcweir } 511cdf0e10cSrcweir 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 519cdf0e10cSrcweir ExternalNameRef ExternalLink::importDdeItem( const AttributeList& rAttribs ) 520cdf0e10cSrcweir { 521cdf0e10cSrcweir ExternalNameRef xExtName = createExternalName(); 522cdf0e10cSrcweir xExtName->importDdeItem( rAttribs ); 523cdf0e10cSrcweir return xExtName; 524cdf0e10cSrcweir } 525cdf0e10cSrcweir 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 533cdf0e10cSrcweir ExternalNameRef ExternalLink::importOleItem( const AttributeList& rAttribs ) 534cdf0e10cSrcweir { 535cdf0e10cSrcweir ExternalNameRef xExtName = createExternalName(); 536cdf0e10cSrcweir xExtName->importOleItem( rAttribs ); 537cdf0e10cSrcweir return xExtName; 538cdf0e10cSrcweir } 539cdf0e10cSrcweir 540cdf0e10cSrcweir void ExternalLink::importExternalRef( SequenceInputStream& rStrm ) 541cdf0e10cSrcweir { 542cdf0e10cSrcweir rStrm >> maRelId; 543cdf0e10cSrcweir } 544cdf0e10cSrcweir 545cdf0e10cSrcweir void ExternalLink::importExternalSelf( SequenceInputStream& ) 546cdf0e10cSrcweir { 547cdf0e10cSrcweir meLinkType = LINKTYPE_SELF; 548cdf0e10cSrcweir } 549cdf0e10cSrcweir 550cdf0e10cSrcweir void ExternalLink::importExternalSame( SequenceInputStream& ) 551cdf0e10cSrcweir { 552cdf0e10cSrcweir meLinkType = LINKTYPE_SAME; 553cdf0e10cSrcweir } 554cdf0e10cSrcweir 555cdf0e10cSrcweir void ExternalLink::importExternalAddin( SequenceInputStream& ) 556cdf0e10cSrcweir { 557cdf0e10cSrcweir meLinkType = LINKTYPE_UNKNOWN; 558cdf0e10cSrcweir } 559cdf0e10cSrcweir 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 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 596cdf0e10cSrcweir ExternalNameRef ExternalLink::importExternalName( SequenceInputStream& rStrm ) 597cdf0e10cSrcweir { 598cdf0e10cSrcweir ExternalNameRef xExtName = createExternalName(); 599cdf0e10cSrcweir xExtName->importExternalName( rStrm ); 600cdf0e10cSrcweir return xExtName; 601cdf0e10cSrcweir } 602cdf0e10cSrcweir 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 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 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 675cdf0e10cSrcweir 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 714cdf0e10cSrcweir FunctionLibraryType ExternalLink::getFuncLibraryType() const 715cdf0e10cSrcweir { 716cdf0e10cSrcweir return (meLinkType == LINKTYPE_LIBRARY) ? meFuncLibType : FUNCLIB_UNKNOWN; 717cdf0e10cSrcweir } 718cdf0e10cSrcweir 719cdf0e10cSrcweir 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 727cdf0e10cSrcweir 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 733cdf0e10cSrcweir 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 741cdf0e10cSrcweir 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 756cdf0e10cSrcweir 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 810cdf0e10cSrcweir 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 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 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 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 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 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 916cdf0e10cSrcweir ExternalNameRef ExternalLink::createExternalName() 917cdf0e10cSrcweir { 918cdf0e10cSrcweir ExternalNameRef xExtName( new ExternalName( *this ) ); 919cdf0e10cSrcweir maExtNames.push_back( xExtName ); 920cdf0e10cSrcweir return xExtName; 921cdf0e10cSrcweir } 922cdf0e10cSrcweir 923cdf0e10cSrcweir // ============================================================================ 924cdf0e10cSrcweir 925cdf0e10cSrcweir RefSheetsModel::RefSheetsModel() : 926cdf0e10cSrcweir mnExtRefId( -1 ), 927cdf0e10cSrcweir mnTabId1( -1 ), 928cdf0e10cSrcweir mnTabId2( -1 ) 929cdf0e10cSrcweir { 930cdf0e10cSrcweir } 931cdf0e10cSrcweir 932cdf0e10cSrcweir void RefSheetsModel::readBiff12Data( SequenceInputStream& rStrm ) 933cdf0e10cSrcweir { 934cdf0e10cSrcweir rStrm >> mnExtRefId >> mnTabId1 >> mnTabId2; 935cdf0e10cSrcweir } 936cdf0e10cSrcweir 937cdf0e10cSrcweir void RefSheetsModel::readBiff8Data( BiffInputStream& rStrm ) 938cdf0e10cSrcweir { 939cdf0e10cSrcweir mnExtRefId = rStrm.readuInt16(); 940cdf0e10cSrcweir mnTabId1 = rStrm.readInt16(); 941cdf0e10cSrcweir mnTabId2 = rStrm.readInt16(); 942cdf0e10cSrcweir } 943cdf0e10cSrcweir 944cdf0e10cSrcweir // ---------------------------------------------------------------------------- 945cdf0e10cSrcweir 946cdf0e10cSrcweir ExternalLinkBuffer::ExternalLinkBuffer( const WorkbookHelper& rHelper ) : 947cdf0e10cSrcweir WorkbookHelper( rHelper ), 948cdf0e10cSrcweir mxSelfRef( new ExternalLink( rHelper ) ), 949cdf0e10cSrcweir mbUseRefSheets( false ) 950cdf0e10cSrcweir { 951cdf0e10cSrcweir mxSelfRef->setSelfLinkType(); 952cdf0e10cSrcweir } 953cdf0e10cSrcweir 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 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 971cdf0e10cSrcweir void ExternalLinkBuffer::importExternalSelf( SequenceInputStream& rStrm ) 972cdf0e10cSrcweir { 973cdf0e10cSrcweir mbUseRefSheets = true; 974cdf0e10cSrcweir createExternalLink()->importExternalSelf( rStrm ); 975cdf0e10cSrcweir } 976cdf0e10cSrcweir 977cdf0e10cSrcweir void ExternalLinkBuffer::importExternalSame( SequenceInputStream& rStrm ) 978cdf0e10cSrcweir { 979cdf0e10cSrcweir mbUseRefSheets = true; 980cdf0e10cSrcweir createExternalLink()->importExternalSame( rStrm ); 981cdf0e10cSrcweir } 982cdf0e10cSrcweir 983cdf0e10cSrcweir void ExternalLinkBuffer::importExternalAddin( SequenceInputStream& rStrm ) 984cdf0e10cSrcweir { 985cdf0e10cSrcweir mbUseRefSheets = true; 986cdf0e10cSrcweir createExternalLink()->importExternalAddin( rStrm ); 987cdf0e10cSrcweir } 988cdf0e10cSrcweir 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 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 1015cdf0e10cSrcweir ExternalLinkRef ExternalLinkBuffer::importExternalBook( BiffInputStream& rStrm ) 1016cdf0e10cSrcweir { 1017cdf0e10cSrcweir ExternalLinkRef xExtLink = createExternalLink(); 1018cdf0e10cSrcweir xExtLink->importExternalBook( rStrm ); 1019cdf0e10cSrcweir return xExtLink; 1020cdf0e10cSrcweir } 1021cdf0e10cSrcweir 1022cdf0e10cSrcweir void ExternalLinkBuffer::importExternalName( BiffInputStream& rStrm ) 1023cdf0e10cSrcweir { 1024cdf0e10cSrcweir if( !maLinks.empty() ) 1025cdf0e10cSrcweir maLinks.back()->importExternalName( rStrm ); 1026cdf0e10cSrcweir } 1027cdf0e10cSrcweir 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 1046cdf0e10cSrcweir 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 1058cdf0e10cSrcweir 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 1107cdf0e10cSrcweir 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 1116cdf0e10cSrcweir 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 1128cdf0e10cSrcweir ExternalLinkRef ExternalLinkBuffer::createExternalLink() 1129cdf0e10cSrcweir { 1130cdf0e10cSrcweir ExternalLinkRef xExtLink( new ExternalLink( *this ) ); 1131cdf0e10cSrcweir maLinks.push_back( xExtLink ); 1132cdf0e10cSrcweir return xExtLink; 1133cdf0e10cSrcweir } 1134cdf0e10cSrcweir 1135cdf0e10cSrcweir 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