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