LCOV - code coverage report
Current view: top level - sc/source/filter/oox - externallinkbuffer.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 70 369 19.0 %
Date: 2014-04-11 Functions: 16 65 24.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "externallinkbuffer.hxx"
      21             : 
      22             : #include <com/sun/star/sheet/ComplexReference.hpp>
      23             : #include <com/sun/star/sheet/DDELinkInfo.hpp>
      24             : #include <com/sun/star/sheet/ExternalLinkType.hpp>
      25             : #include <com/sun/star/sheet/ExternalReference.hpp>
      26             : #include <com/sun/star/sheet/ReferenceFlags.hpp>
      27             : #include <com/sun/star/sheet/SingleReference.hpp>
      28             : #include <com/sun/star/sheet/XDDELinks.hpp>
      29             : #include <com/sun/star/sheet/XDDELink.hpp>
      30             : #include <com/sun/star/sheet/XDDELinkResults.hpp>
      31             : #include <com/sun/star/sheet/XExternalDocLink.hpp>
      32             : #include <com/sun/star/sheet/XExternalDocLinks.hpp>
      33             : #include <rtl/strbuf.hxx>
      34             : #include "oox/core/filterbase.hxx"
      35             : #include "oox/helper/attributelist.hxx"
      36             : #include "oox/token/properties.hxx"
      37             : #include "addressconverter.hxx"
      38             : #include "biffinputstream.hxx"
      39             : #include "excelhandlers.hxx"
      40             : #include "formulaparser.hxx"
      41             : #include "worksheetbuffer.hxx"
      42             : 
      43             : namespace oox {
      44             : namespace xls {
      45             : 
      46             : using namespace ::com::sun::star::sheet;
      47             : using namespace ::com::sun::star::table;
      48             : using namespace ::com::sun::star::uno;
      49             : 
      50             : using ::oox::core::Relation;
      51             : using ::oox::core::Relations;
      52             : 
      53             : namespace {
      54             : 
      55             : const sal_uInt16 BIFF12_EXTERNALBOOK_BOOK   = 0;
      56             : const sal_uInt16 BIFF12_EXTERNALBOOK_DDE    = 1;
      57             : const sal_uInt16 BIFF12_EXTERNALBOOK_OLE    = 2;
      58             : 
      59             : const sal_uInt16 BIFF12_EXTNAME_AUTOMATIC   = 0x0002;
      60             : const sal_uInt16 BIFF12_EXTNAME_PREFERPIC   = 0x0004;
      61             : const sal_uInt16 BIFF12_EXTNAME_STDDOCNAME  = 0x0008;
      62             : const sal_uInt16 BIFF12_EXTNAME_OLEOBJECT   = 0x0010;
      63             : const sal_uInt16 BIFF12_EXTNAME_ICONIFIED   = 0x0020;
      64             : 
      65             : } // namespace
      66             : 
      67           0 : ExternalNameModel::ExternalNameModel() :
      68             :     mbBuiltIn( false ),
      69             :     mbNotify( false ),
      70             :     mbPreferPic( false ),
      71             :     mbStdDocName( false ),
      72             :     mbOleObj( false ),
      73           0 :     mbIconified( false )
      74             : {
      75           0 : }
      76             : 
      77           0 : ExternalName::ExternalName( const ExternalLink& rParentLink ) :
      78             :     DefinedNameBase( rParentLink ),
      79             :     mrParentLink( rParentLink ),
      80           0 :     mbDdeLinkCreated( false )
      81             : {
      82           0 : }
      83             : 
      84           0 : void ExternalName::importDefinedName( const AttributeList& rAttribs )
      85             : {
      86           0 :     maModel.maName = rAttribs.getXString( XML_name, OUString() );
      87             :     OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importDefinedName - empty name" );
      88             :     // zero-based index into sheet list of externalBook
      89           0 :     maModel.mnSheet = rAttribs.getInteger( XML_sheetId, -1 );
      90           0 : }
      91             : 
      92           0 : void ExternalName::importDdeItem( const AttributeList& rAttribs )
      93             : {
      94           0 :     maModel.maName = rAttribs.getXString( XML_name, OUString() );
      95             :     OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importDdeItem - empty name" );
      96           0 :     maExtNameModel.mbOleObj     = false;
      97           0 :     maExtNameModel.mbStdDocName = rAttribs.getBool( XML_ole, false );
      98           0 :     maExtNameModel.mbNotify     = rAttribs.getBool( XML_advise, false );
      99           0 :     maExtNameModel.mbPreferPic  = rAttribs.getBool( XML_preferPic, false );
     100           0 : }
     101             : 
     102           0 : void ExternalName::importValues( const AttributeList& rAttribs )
     103             : {
     104           0 :     setResultSize( rAttribs.getInteger( XML_cols, 1 ), rAttribs.getInteger( XML_rows, 1 ) );
     105           0 : }
     106             : 
     107           0 : void ExternalName::importOleItem( const AttributeList& rAttribs )
     108             : {
     109           0 :     maModel.maName = rAttribs.getXString( XML_name, OUString() );
     110             :     OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importOleItem - empty name" );
     111           0 :     maExtNameModel.mbOleObj    = true;
     112           0 :     maExtNameModel.mbNotify    = rAttribs.getBool( XML_advise, false );
     113           0 :     maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
     114           0 :     maExtNameModel.mbIconified = rAttribs.getBool( XML_icon, false );
     115           0 : }
     116             : 
     117           0 : void ExternalName::importExternalName( SequenceInputStream& rStrm )
     118             : {
     119           0 :     rStrm >> maModel.maName;
     120             :     OSL_ENSURE( !maModel.maName.isEmpty(), "ExternalName::importExternalName - empty name" );
     121           0 : }
     122             : 
     123           0 : void ExternalName::importExternalNameFlags( SequenceInputStream& rStrm )
     124             : {
     125             :     sal_uInt16 nFlags;
     126             :     sal_Int32 nSheetId;
     127           0 :     rStrm >> nFlags >> nSheetId;
     128             :     // index into sheet list of EXTSHEETNAMES (one-based in BIFF12)
     129           0 :     maModel.mnSheet = nSheetId - 1;
     130             :     // no flag for built-in names, as in OOXML...
     131           0 :     maExtNameModel.mbNotify     = getFlag( nFlags, BIFF12_EXTNAME_AUTOMATIC );
     132           0 :     maExtNameModel.mbPreferPic  = getFlag( nFlags, BIFF12_EXTNAME_PREFERPIC );
     133           0 :     maExtNameModel.mbStdDocName = getFlag( nFlags, BIFF12_EXTNAME_STDDOCNAME );
     134           0 :     maExtNameModel.mbOleObj     = getFlag( nFlags, BIFF12_EXTNAME_OLEOBJECT );
     135           0 :     maExtNameModel.mbIconified  = getFlag( nFlags, BIFF12_EXTNAME_ICONIFIED );
     136             :     OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_OLE) == maExtNameModel.mbOleObj,
     137             :         "ExternalName::importExternalNameFlags - wrong OLE flag in external name" );
     138           0 : }
     139             : 
     140           0 : void ExternalName::importDdeItemValues( SequenceInputStream& rStrm )
     141             : {
     142             :     sal_Int32 nRows, nCols;
     143           0 :     rStrm >> nRows >> nCols;
     144           0 :     setResultSize( nCols, nRows );
     145           0 : }
     146             : 
     147           0 : void ExternalName::importDdeItemBool( SequenceInputStream& rStrm )
     148             : {
     149           0 :     appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
     150           0 : }
     151             : 
     152           0 : void ExternalName::importDdeItemDouble( SequenceInputStream& rStrm )
     153             : {
     154           0 :     appendResultValue( rStrm.readDouble() );
     155           0 : }
     156             : 
     157           0 : void ExternalName::importDdeItemError( SequenceInputStream& rStrm )
     158             : {
     159           0 :     appendResultValue( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) );
     160           0 : }
     161             : 
     162           0 : void ExternalName::importDdeItemString( SequenceInputStream& rStrm )
     163             : {
     164           0 :     appendResultValue( BiffHelper::readString( rStrm ) );
     165           0 : }
     166             : 
     167             : #if 0
     168             : sal_Int32 ExternalName::getSheetCacheIndex() const
     169             : {
     170             :     OSL_ENSURE( mrParentLink.getLinkType() == LINKTYPE_DDE, "ExternalName::getSheetCacheIndex - unexpected link type" );
     171             :     sal_Int32 nCacheIdx = -1;
     172             :     switch( getFilterType() )
     173             :     {
     174             :         case FILTER_OOXML:
     175             :             // OOXML/BIFF12: zero-based index into sheet list, -1 means global name
     176             :             if( maModel.mnSheet >= 0 )
     177             :                 nCacheIdx = mrParentLink.getSheetIndex( maModel.mnSheet );
     178             :         break;
     179             :         case FILTER_BIFF:
     180             :             switch( getBiff() )
     181             :             {
     182             :                 case BIFF2:
     183             :                 case BIFF3:
     184             :                 case BIFF4:
     185             :                 break;
     186             :                 case BIFF5:
     187             :                     if( maModel.mnSheet > 0 )
     188             :                         if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( maModel.mnSheet ).get() )
     189             :                             if( pExtLink->getLinkType() == LINKTYPE_EXTERNAL )
     190             :                                 nCacheIdx = pExtLink->getSheetIndex();
     191             :                 break;
     192             :                 case BIFF8:
     193             :                     if( maModel.mnSheet > 0 )
     194             :                         nCacheIdx = mrParentLink.getSheetIndex( maModel.mnSheet - 1 );
     195             :                 break;
     196             :                 case BIFF_UNKNOWN:
     197             :                 break;
     198             :             }
     199             :         break;
     200             :         case FILTER_UNKNOWN:
     201             :         break;
     202             :     }
     203             :     return nCacheIdx;
     204             : }
     205             : #endif
     206             : 
     207           0 : bool ExternalName::getDdeItemInfo( DDEItemInfo& orItemInfo ) const
     208             : {
     209           0 :     if( (mrParentLink.getLinkType() == LINKTYPE_DDE) && !maModel.maName.isEmpty() )
     210             :     {
     211           0 :         orItemInfo.Item = maModel.maName;
     212           0 :         orItemInfo.Results = ContainerHelper::matrixToSequenceSequence( maResults );
     213           0 :         return true;
     214             :     }
     215           0 :     return false;
     216             : }
     217             : 
     218           0 : bool ExternalName::getDdeLinkData( OUString& orDdeServer, OUString& orDdeTopic, OUString& orDdeItem )
     219             : {
     220           0 :     if( (mrParentLink.getLinkType() == LINKTYPE_DDE) && !maModel.maName.isEmpty() )
     221             :     {
     222             :         // try to create a DDE link and to set the imported link results
     223           0 :         if( !mbDdeLinkCreated ) try
     224             :         {
     225           0 :             PropertySet aDocProps( getDocument() );
     226           0 :             Reference< XDDELinks > xDdeLinks( aDocProps.getAnyProperty( PROP_DDELinks ), UNO_QUERY_THROW );
     227           0 :             mxDdeLink = xDdeLinks->addDDELink( mrParentLink.getClassName(), mrParentLink.getTargetUrl(), maModel.maName, ::com::sun::star::sheet::DDELinkMode_DEFAULT );
     228           0 :             mbDdeLinkCreated = true;    // ignore if setting results fails
     229           0 :             if( !maResults.empty() )
     230             :             {
     231           0 :                 Reference< XDDELinkResults > xResults( mxDdeLink, UNO_QUERY_THROW );
     232           0 :                 xResults->setResults( ContainerHelper::matrixToSequenceSequence( maResults ) );
     233           0 :             }
     234             :         }
     235           0 :         catch( Exception& )
     236             :         {
     237             :             OSL_FAIL( "ExternalName::getDdeLinkData - cannot create DDE link" );
     238             :         }
     239             :         // get link data from created DDE link
     240           0 :         if( mxDdeLink.is() )
     241             :         {
     242           0 :             orDdeServer = mxDdeLink->getApplication();
     243           0 :             orDdeTopic = mxDdeLink->getTopic();
     244           0 :             orDdeItem = mxDdeLink->getItem();
     245           0 :             return true;
     246             :         }
     247             :     }
     248           0 :     return false;
     249             : }
     250             : 
     251             : // private --------------------------------------------------------------------
     252             : 
     253           0 : void ExternalName::setResultSize( sal_Int32 nColumns, sal_Int32 nRows )
     254             : {
     255             :     OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_DDE) || (mrParentLink.getLinkType() == LINKTYPE_OLE) ||
     256             :         (mrParentLink.getLinkType() == LINKTYPE_MAYBE_DDE_OLE), "ExternalName::setResultSize - wrong link type" );
     257             :     OSL_ENSURE( (nRows > 0) && (nColumns > 0), "ExternalName::setResultSize - invalid matrix size" );
     258           0 :     const CellAddress& rMaxPos = getAddressConverter().getMaxApiAddress();
     259           0 :     if( (0 < nRows) && (nRows <= rMaxPos.Row + 1) && (0 < nColumns) && (nColumns <= rMaxPos.Column + 1) )
     260           0 :         maResults.resize( static_cast< size_t >( nColumns ), static_cast< size_t >( nRows ), Any( BiffHelper::calcDoubleFromError( BIFF_ERR_NA ) ) );
     261             :     else
     262           0 :         maResults.clear();
     263           0 :     maCurrIt = maResults.begin();
     264           0 : }
     265             : 
     266           0 : void LinkSheetRange::setDeleted()
     267             : {
     268           0 :     meType = LINKSHEETRANGE_INTERNAL;
     269           0 :     mnDocLink = mnFirst = mnLast = -1;
     270           0 : }
     271             : 
     272           0 : void LinkSheetRange::setSameSheet()
     273             : {
     274           0 :     meType = LINKSHEETRANGE_SAMESHEET;
     275           0 :     mnDocLink = -1;
     276           0 :     mnFirst = mnLast = 0;
     277           0 : }
     278             : 
     279           0 : void LinkSheetRange::setRange( sal_Int32 nFirst, sal_Int32 nLast )
     280             : {
     281           0 :     meType = LINKSHEETRANGE_INTERNAL;
     282           0 :     mnDocLink = -1;
     283           0 :     mnFirst = ::std::min( nFirst, nLast );
     284           0 :     mnLast = ::std::max( nFirst, nLast );
     285           0 : }
     286             : 
     287           0 : void LinkSheetRange::setExternalRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast )
     288             : {
     289           0 :     if( nDocLink < 0 )
     290             :     {
     291           0 :         setDeleted();
     292             :     }
     293             :     else
     294             :     {
     295           0 :         meType = LINKSHEETRANGE_EXTERNAL;
     296           0 :         mnDocLink = nDocLink;
     297           0 :         mnFirst = ::std::min( nFirst, nLast );
     298           0 :         mnLast = ::std::max( nFirst, nLast );
     299             :     }
     300           0 : }
     301             : 
     302          45 : ExternalLink::ExternalLink( const WorkbookHelper& rHelper ) :
     303             :     WorkbookHelper( rHelper ),
     304             :     meLinkType( LINKTYPE_UNKNOWN ),
     305          45 :     meFuncLibType( FUNCLIB_UNKNOWN )
     306             : {
     307          45 : }
     308             : 
     309           1 : void ExternalLink::importExternalReference( const AttributeList& rAttribs )
     310             : {
     311           1 :     maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
     312           1 : }
     313             : 
     314           1 : void ExternalLink::importExternalBook( const Relations& rRelations, const AttributeList& rAttribs )
     315             : {
     316           1 :     parseExternalReference( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
     317           1 : }
     318             : 
     319           3 : void ExternalLink::importSheetName( const AttributeList& rAttribs )
     320             : {
     321           3 :     insertExternalSheet( rAttribs.getXString( XML_val, OUString() ) );
     322           3 : }
     323             : 
     324           0 : void ExternalLink::importDefinedName( const AttributeList& rAttribs )
     325             : {
     326           0 :     createExternalName()->importDefinedName( rAttribs );
     327           0 : }
     328             : 
     329           0 : void ExternalLink::importDdeLink( const AttributeList& rAttribs )
     330             : {
     331           0 :     OUString aDdeService = rAttribs.getXString( XML_ddeService, OUString() );
     332           0 :     OUString aDdeTopic = rAttribs.getXString( XML_ddeTopic, OUString() );
     333           0 :     setDdeOleTargetUrl( aDdeService, aDdeTopic, LINKTYPE_DDE );
     334           0 : }
     335             : 
     336           0 : ExternalNameRef ExternalLink::importDdeItem( const AttributeList& rAttribs )
     337             : {
     338           0 :     ExternalNameRef xExtName = createExternalName();
     339           0 :     xExtName->importDdeItem( rAttribs );
     340           0 :     return xExtName;
     341             : }
     342             : 
     343           0 : void ExternalLink::importOleLink( const Relations& rRelations, const AttributeList& rAttribs )
     344             : {
     345           0 :     OUString aProgId = rAttribs.getXString( XML_progId, OUString() );
     346           0 :     OUString aTargetUrl = rRelations.getExternalTargetFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
     347           0 :     setDdeOleTargetUrl( aProgId, aTargetUrl, LINKTYPE_OLE );
     348           0 : }
     349             : 
     350           0 : ExternalNameRef ExternalLink::importOleItem( const AttributeList& rAttribs )
     351             : {
     352           0 :     ExternalNameRef xExtName = createExternalName();
     353           0 :     xExtName->importOleItem( rAttribs );
     354           0 :     return xExtName;
     355             : }
     356             : 
     357           0 : void ExternalLink::importExternalRef( SequenceInputStream& rStrm )
     358             : {
     359           0 :     rStrm >> maRelId;
     360           0 : }
     361             : 
     362           0 : void ExternalLink::importExternalSelf( SequenceInputStream& )
     363             : {
     364           0 :     meLinkType = LINKTYPE_SELF;
     365           0 : }
     366             : 
     367           0 : void ExternalLink::importExternalSame( SequenceInputStream& )
     368             : {
     369           0 :     meLinkType = LINKTYPE_SAME;
     370           0 : }
     371             : 
     372           0 : void ExternalLink::importExternalAddin( SequenceInputStream& )
     373             : {
     374           0 :     meLinkType = LINKTYPE_UNKNOWN;
     375           0 : }
     376             : 
     377           0 : void ExternalLink::importExternalBook( const Relations& rRelations, SequenceInputStream& rStrm )
     378             : {
     379           0 :     switch( rStrm.readuInt16() )
     380             :     {
     381             :         case BIFF12_EXTERNALBOOK_BOOK:
     382           0 :             parseExternalReference( rRelations, BiffHelper::readString( rStrm ) );
     383           0 :         break;
     384             :         case BIFF12_EXTERNALBOOK_DDE:
     385             :         {
     386           0 :             OUString aDdeService, aDdeTopic;
     387           0 :             rStrm >> aDdeService >> aDdeTopic;
     388           0 :             setDdeOleTargetUrl( aDdeService, aDdeTopic, LINKTYPE_DDE );
     389             :         }
     390           0 :         break;
     391             :         case BIFF12_EXTERNALBOOK_OLE:
     392             :         {
     393           0 :             OUString aTargetUrl = rRelations.getExternalTargetFromRelId( BiffHelper::readString( rStrm ) );
     394           0 :             OUString aProgId = BiffHelper::readString( rStrm );
     395           0 :             setDdeOleTargetUrl( aProgId, aTargetUrl, LINKTYPE_OLE );
     396             :         }
     397           0 :         break;
     398             :         default:
     399             :             OSL_FAIL( "ExternalLink::importExternalBook - unknown link type" );
     400             :     }
     401           0 : }
     402             : 
     403           0 : void ExternalLink::importExtSheetNames( SequenceInputStream& rStrm )
     404             : {
     405             :     // load external sheet names and create the sheet caches in the Calc document
     406             :     OSL_ENSURE( (meLinkType == LINKTYPE_EXTERNAL) || (meLinkType == LINKTYPE_LIBRARY),
     407             :         "ExternalLink::importExtSheetNames - invalid link type" );
     408           0 :     if( meLinkType == LINKTYPE_EXTERNAL )   // ignore sheets of external libraries
     409           0 :         for( sal_Int32 nSheet = 0, nCount = rStrm.readInt32(); !rStrm.isEof() && (nSheet < nCount); ++nSheet )
     410           0 :             insertExternalSheet( BiffHelper::readString( rStrm ) );
     411           0 : }
     412             : 
     413           0 : ExternalNameRef ExternalLink::importExternalName( SequenceInputStream& rStrm )
     414             : {
     415           0 :     ExternalNameRef xExtName = createExternalName();
     416           0 :     xExtName->importExternalName( rStrm );
     417           0 :     return xExtName;
     418             : }
     419             : 
     420          99 : ExternalLinkInfo ExternalLink::getLinkInfo() const
     421             : {
     422          99 :     ExternalLinkInfo aLinkInfo;
     423          99 :     switch( meLinkType )
     424             :     {
     425             :         case LINKTYPE_SELF:
     426             :         case LINKTYPE_SAME:
     427             :         case LINKTYPE_INTERNAL:
     428          96 :             aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::SELF;
     429          96 :         break;
     430             :         case LINKTYPE_EXTERNAL:
     431           3 :             aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::DOCUMENT;
     432           3 :             aLinkInfo.Data <<= maTargetUrl;
     433           3 :         break;
     434             :         case LINKTYPE_LIBRARY:
     435             :             // parser will return library function names in OPCODE_BAD string tokens
     436           0 :             aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::SPECIAL;
     437           0 :         break;
     438             :         case LINKTYPE_DDE:
     439             :         {
     440           0 :             aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::DDE;
     441           0 :             DDELinkInfo aDdeLinkInfo;
     442           0 :             aDdeLinkInfo.Service = maClassName;
     443           0 :             aDdeLinkInfo.Topic = maTargetUrl;
     444           0 :             ::std::vector< DDEItemInfo > aItemInfos;
     445           0 :             DDEItemInfo aItemInfo;
     446           0 :             for( ExternalNameVector::const_iterator aIt = maExtNames.begin(), aEnd = maExtNames.end(); aIt != aEnd; ++aIt )
     447           0 :                 if( (*aIt)->getDdeItemInfo( aItemInfo ) )
     448           0 :                     aItemInfos.push_back( aItemInfo );
     449           0 :             aDdeLinkInfo.Items = ContainerHelper::vectorToSequence( aItemInfos );
     450           0 :             aLinkInfo.Data <<= aDdeLinkInfo;
     451             :         }
     452           0 :         break;
     453             :         default:
     454           0 :             aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::UNKNOWN;
     455             :     }
     456          99 :     return aLinkInfo;
     457             : }
     458             : 
     459           0 : FunctionLibraryType ExternalLink::getFuncLibraryType() const
     460             : {
     461           0 :     return (meLinkType == LINKTYPE_LIBRARY) ? meFuncLibType : FUNCLIB_UNKNOWN;
     462             : }
     463             : 
     464           0 : sal_Int32 ExternalLink::getDocumentLinkIndex() const
     465             : {
     466             :     OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getDocumentLinkIndex - invalid link type" );
     467           0 :     return mxDocLink.is() ? mxDocLink->getTokenIndex() : -1;
     468             : }
     469             : 
     470           3 : sal_Int32 ExternalLink::getSheetCacheIndex( sal_Int32 nTabId ) const
     471             : {
     472             :     OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getSheetCacheIndex - invalid link type" );
     473             :     OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOXML) || (getBiff() == BIFF8),
     474             :         "ExternalLink::getSheetCacheIndex - invalid sheet index" );
     475           3 :     return ContainerHelper::getVectorElement( maSheetCaches, nTabId, -1 );
     476             : }
     477             : 
     478           3 : Reference< XExternalSheetCache > ExternalLink::getSheetCache( sal_Int32 nTabId ) const
     479             : {
     480           3 :     sal_Int32 nCacheIdx = getSheetCacheIndex( nTabId );
     481           3 :     if( mxDocLink.is() && (nCacheIdx >= 0) ) try
     482             :     {
     483             :         // existing mxDocLink implies that this is an external link
     484           3 :         Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( nCacheIdx ), UNO_QUERY_THROW );
     485           3 :         return xSheetCache;
     486             :     }
     487           0 :     catch( Exception& )
     488             :     {
     489             :     }
     490           0 :     return 0;
     491             : }
     492             : 
     493           0 : void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const
     494             : {
     495           0 :     switch( meLinkType )
     496             :     {
     497             :         case LINKTYPE_SAME:
     498           0 :             orSheetRange.setSameSheet();
     499           0 :         break;
     500             : 
     501             :         case LINKTYPE_SELF:
     502             :         case LINKTYPE_INTERNAL:
     503           0 :             orSheetRange.setRange( nTabId1, nTabId2 );
     504           0 :         break;
     505             : 
     506             :         case LINKTYPE_EXTERNAL:
     507             :         {
     508           0 :             sal_Int32 nDocLinkIdx = getDocumentLinkIndex();
     509           0 :             switch( getFilterType() )
     510             :             {
     511             :                 case FILTER_OOXML:
     512             :                     // BIFF12: passed indexes point into sheet list of EXTSHEETLIST
     513           0 :                     orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
     514           0 :                 break;
     515             :                 case FILTER_BIFF:
     516           0 :                     switch( getBiff() )
     517             :                     {
     518             :                         case BIFF2:
     519             :                         case BIFF3:
     520             :                         case BIFF4:
     521           0 :                             orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
     522           0 :                         break;
     523             :                         case BIFF5:
     524             :                             // BIFF5: first sheet from this external link, last sheet is passed in nTabId2
     525           0 :                             if( const ExternalLink* pExtLink2 = getExternalLinks().getExternalLink( nTabId2 ).get() )
     526           0 :                                 if( (pExtLink2->getLinkType() == LINKTYPE_EXTERNAL) && (maTargetUrl == pExtLink2->getTargetUrl()) )
     527           0 :                                     orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex(), pExtLink2->getSheetCacheIndex() );
     528           0 :                         break;
     529             :                         case BIFF8:
     530             :                             // BIFF8: passed indexes point into sheet list of EXTERNALBOOK
     531           0 :                             orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
     532           0 :                         break;
     533           0 :                         case BIFF_UNKNOWN: break;
     534             :                     }
     535           0 :                 break;
     536           0 :                 case FILTER_UNKNOWN: break;
     537             :             }
     538             :         }
     539           0 :         break;
     540             : 
     541             :         default:
     542             :             // unsupported/unexpected link type: #REF! error
     543           0 :             orSheetRange.setDeleted();
     544             :     }
     545           0 : }
     546             : 
     547           0 : ExternalNameRef ExternalLink::getNameByIndex( sal_Int32 nIndex ) const
     548             : {
     549           0 :     return maExtNames.get( nIndex );
     550             : }
     551             : 
     552             : // private --------------------------------------------------------------------
     553             : 
     554           1 : void ExternalLink::setExternalTargetUrl( const OUString& rTargetUrl, const OUString& rTargetType )
     555             : {
     556           1 :     meLinkType = LINKTYPE_UNKNOWN;
     557           1 :     if( rTargetType == CREATE_OFFICEDOC_RELATION_TYPE( "externalLinkPath" ) ||
     558           0 :             rTargetType == CREATE_OFFICEDOC_RELATION_TYPE_STRICT( "externalLinkPath" ) )
     559             :     {
     560           1 :         maTargetUrl = getBaseFilter().getAbsoluteUrl( rTargetUrl );
     561           1 :         if( !maTargetUrl.isEmpty() )
     562           1 :             meLinkType = LINKTYPE_EXTERNAL;
     563             :     }
     564           0 :     else if( rTargetType == CREATE_MSOFFICE_RELATION_TYPE( "xlExternalLinkPath/xlLibrary" ) )
     565             :     {
     566           0 :         meLinkType = LINKTYPE_LIBRARY;
     567           0 :         meFuncLibType = getFormulaParser().getFuncLibTypeFromLibraryName( rTargetUrl );
     568             :     }
     569             :     OSL_ENSURE( meLinkType != LINKTYPE_UNKNOWN, "ExternalLink::setExternalTargetUrl - empty target URL or unknown target type" );
     570             : 
     571             :     // create the external document link API object that will contain the sheet caches
     572           1 :     if( meLinkType == LINKTYPE_EXTERNAL ) try
     573             :     {
     574           1 :         PropertySet aDocProps( getDocument() );
     575           2 :         Reference< XExternalDocLinks > xDocLinks( aDocProps.getAnyProperty( PROP_ExternalDocLinks ), UNO_QUERY_THROW );
     576           2 :         mxDocLink = xDocLinks->addDocLink( maTargetUrl );
     577             :     }
     578           0 :     catch( Exception& )
     579             :     {
     580             :     }
     581           1 : }
     582             : 
     583           0 : void ExternalLink::setDdeOleTargetUrl( const OUString& rClassName, const OUString& rTargetUrl, ExternalLinkType eLinkType )
     584             : {
     585           0 :     maClassName = rClassName;
     586           0 :     maTargetUrl = rTargetUrl;
     587           0 :     meLinkType = (maClassName.isEmpty() || maTargetUrl.isEmpty()) ?  LINKTYPE_UNKNOWN : eLinkType;
     588             :     OSL_ENSURE( meLinkType == eLinkType, "ExternalLink::setDdeOleTargetUrl - missing classname or target" );
     589           0 : }
     590             : 
     591           1 : void ExternalLink::parseExternalReference( const Relations& rRelations, const OUString& rRelId )
     592             : {
     593           1 :     if( const Relation* pRelation = rRelations.getRelationFromRelId( rRelId ) )
     594           1 :         setExternalTargetUrl( pRelation->maTarget, pRelation->maType );
     595           1 : }
     596             : 
     597           3 : void ExternalLink::insertExternalSheet( const OUString& rSheetName )
     598             : {
     599             :     OSL_ENSURE( !rSheetName.isEmpty(), "ExternalLink::insertExternalSheet - empty sheet name" );
     600           3 :     if( mxDocLink.is() )
     601             :     {
     602           3 :         Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName, false );
     603           3 :         sal_Int32 nCacheIdx = xSheetCache.is() ? xSheetCache->getTokenIndex() : -1;
     604           3 :         maSheetCaches.push_back( nCacheIdx );
     605             :     }
     606           3 : }
     607             : 
     608           0 : ExternalNameRef ExternalLink::createExternalName()
     609             : {
     610           0 :     ExternalNameRef xExtName( new ExternalName( *this ) );
     611           0 :     maExtNames.push_back( xExtName );
     612           0 :     return xExtName;
     613             : }
     614             : 
     615           0 : RefSheetsModel::RefSheetsModel() :
     616             :     mnExtRefId( -1 ),
     617             :     mnTabId1( -1 ),
     618           0 :     mnTabId2( -1 )
     619             : {
     620           0 : }
     621             : 
     622           0 : void RefSheetsModel::readBiff12Data( SequenceInputStream& rStrm )
     623             : {
     624           0 :     rStrm >> mnExtRefId >> mnTabId1 >> mnTabId2;
     625           0 : }
     626             : 
     627          44 : ExternalLinkBuffer::ExternalLinkBuffer( const WorkbookHelper& rHelper ) :
     628             :     WorkbookHelper( rHelper ),
     629          44 :     mxSelfRef( new ExternalLink( rHelper ) ),
     630          88 :     mbUseRefSheets( false )
     631             : {
     632          44 :     mxSelfRef->setSelfLinkType();
     633          44 : }
     634             : 
     635           1 : ExternalLinkRef ExternalLinkBuffer::importExternalReference( const AttributeList& rAttribs )
     636             : {
     637           1 :     ExternalLinkRef xExtLink = createExternalLink();
     638           1 :     xExtLink->importExternalReference( rAttribs );
     639           1 :     maExtLinks.push_back( xExtLink );
     640           1 :     return xExtLink;
     641             : }
     642             : 
     643           0 : ExternalLinkRef ExternalLinkBuffer::importExternalRef( SequenceInputStream& rStrm )
     644             : {
     645           0 :     mbUseRefSheets = true;
     646           0 :     ExternalLinkRef xExtLink = createExternalLink();
     647           0 :     xExtLink->importExternalRef( rStrm );
     648           0 :     maExtLinks.push_back( xExtLink );
     649           0 :     return xExtLink;
     650             : }
     651             : 
     652           0 : void ExternalLinkBuffer::importExternalSelf( SequenceInputStream& rStrm )
     653             : {
     654           0 :     mbUseRefSheets = true;
     655           0 :     createExternalLink()->importExternalSelf( rStrm );
     656           0 : }
     657             : 
     658           0 : void ExternalLinkBuffer::importExternalSame( SequenceInputStream& rStrm )
     659             : {
     660           0 :     mbUseRefSheets = true;
     661           0 :     createExternalLink()->importExternalSame( rStrm );
     662           0 : }
     663             : 
     664           0 : void ExternalLinkBuffer::importExternalAddin( SequenceInputStream& rStrm )
     665             : {
     666           0 :     mbUseRefSheets = true;
     667           0 :     createExternalLink()->importExternalAddin( rStrm );
     668           0 : }
     669             : 
     670           0 : void ExternalLinkBuffer::importExternalSheets( SequenceInputStream& rStrm )
     671             : {
     672             :     OSL_ENSURE( mbUseRefSheets, "ExternalLinkBuffer::importExternalSheets - missing EXTERNALREFS records" );
     673           0 :     mbUseRefSheets = true;
     674             :     OSL_ENSURE( maRefSheets.empty(), "ExternalLinkBuffer::importExternalSheets - multiple EXTERNALSHEETS records" );
     675           0 :     maRefSheets.clear();
     676             :     sal_Int32 nRefCount;
     677           0 :     rStrm >> nRefCount;
     678           0 :     size_t nMaxCount = getLimitedValue< size_t, sal_Int64 >( nRefCount, 0, rStrm.getRemaining() / 12 );
     679           0 :     maRefSheets.reserve( nMaxCount );
     680           0 :     for( size_t nRefId = 0; !rStrm.isEof() && (nRefId < nMaxCount); ++nRefId )
     681             :     {
     682           0 :         RefSheetsModel aRefSheets;
     683           0 :         aRefSheets.readBiff12Data( rStrm );
     684           0 :         maRefSheets.push_back( aRefSheets );
     685             :     }
     686           0 : }
     687             : 
     688          96 : Sequence< ExternalLinkInfo > ExternalLinkBuffer::getLinkInfos() const
     689             : {
     690          96 :     ::std::vector< ExternalLinkInfo > aLinkInfos;
     691             :     // XML formula parser also used in BIFF12 documents, e.g. replacement formulas in unsupported conditional formattings
     692             :     OSL_ENSURE( getFilterType() == FILTER_OOXML, "ExternalLinkBuffer::getLinkInfos - unexpected file format" );
     693             :     // add entry for implicit index 0 (self reference to this document)
     694          96 :     aLinkInfos.push_back( mxSelfRef->getLinkInfo() );
     695          99 :     for( ExternalLinkVec::const_iterator aIt = maExtLinks.begin(), aEnd = maExtLinks.end(); aIt != aEnd; ++aIt )
     696           3 :         aLinkInfos.push_back( (*aIt)->getLinkInfo() );
     697          96 :     return ContainerHelper::vectorToSequence( aLinkInfos );
     698             : }
     699             : 
     700           0 : ExternalLinkRef ExternalLinkBuffer::getExternalLink( sal_Int32 nRefId, bool bUseRefSheets ) const
     701             : {
     702           0 :     ExternalLinkRef xExtLink;
     703           0 :     switch( getFilterType() )
     704             :     {
     705             :         case FILTER_OOXML:
     706             :             // OOXML: 0 = this document, otherwise one-based index into link list
     707           0 :             if( !bUseRefSheets || !mbUseRefSheets )
     708           0 :                 xExtLink = (nRefId == 0) ? mxSelfRef : maLinks.get( nRefId - 1 );
     709             :             // BIFF12: zero-based index into ref-sheets list
     710           0 :             else if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
     711           0 :                 xExtLink = maLinks.get( pRefSheets->mnExtRefId );
     712           0 :         break;
     713             :         case FILTER_BIFF:
     714           0 :             switch( getBiff() )
     715             :             {
     716             :                 case BIFF2:
     717             :                 case BIFF3:
     718             :                 case BIFF4:
     719             :                     // one-based index to EXTERNSHEET records
     720           0 :                     xExtLink = maLinks.get( nRefId - 1 );
     721           0 :                 break;
     722             :                 case BIFF5:
     723           0 :                     if( nRefId < 0 )
     724             :                     {
     725             :                         // internal links in formula tokens have negative index
     726           0 :                         xExtLink = maLinks.get( -nRefId - 1 );
     727           0 :                         if( xExtLink.get() && !xExtLink->isInternalLink() )
     728           0 :                             xExtLink.reset();
     729             :                     }
     730             :                     else
     731             :                     {
     732             :                         // one-based index to EXTERNSHEET records
     733           0 :                         xExtLink = maLinks.get( nRefId - 1 );
     734             :                     }
     735           0 :                 break;
     736             :                 case BIFF8:
     737             :                     // zero-based index into REF list in EXTERNSHEET record
     738           0 :                     if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
     739           0 :                         xExtLink = maLinks.get( pRefSheets->mnExtRefId );
     740           0 :                 break;
     741           0 :                 case BIFF_UNKNOWN: break;
     742             :             }
     743           0 :         break;
     744           0 :         case FILTER_UNKNOWN: break;
     745             :     }
     746           0 :     return xExtLink;
     747             : }
     748             : 
     749           0 : LinkSheetRange ExternalLinkBuffer::getSheetRange( sal_Int32 nRefId, sal_Int16 nTabId1, sal_Int16 nTabId2 ) const
     750             : {
     751             :     OSL_ENSURE( getBiff() <= BIFF5, "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
     752           0 :     LinkSheetRange aSheetRange;
     753           0 :     if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
     754           0 :         pExtLink->getSheetRange( aSheetRange, nTabId1, nTabId2 );
     755           0 :     return aSheetRange;
     756             : }
     757             : 
     758           0 : LinkSheetRange ExternalLinkBuffer::getSheetRange( sal_Int32 nRefId ) const
     759             : {
     760             :     OSL_ENSURE( ((getFilterType() == FILTER_OOXML) && mbUseRefSheets) || (getBiff() == BIFF8), "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
     761           0 :     LinkSheetRange aSheetRange;
     762           0 :     if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
     763           0 :         if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
     764           0 :             pExtLink->getSheetRange( aSheetRange, pRefSheets->mnTabId1, pRefSheets->mnTabId2 );
     765           0 :     return aSheetRange;
     766             : }
     767             : 
     768             : // private --------------------------------------------------------------------
     769             : 
     770           1 : ExternalLinkRef ExternalLinkBuffer::createExternalLink()
     771             : {
     772           1 :     ExternalLinkRef xExtLink( new ExternalLink( *this ) );
     773           1 :     maLinks.push_back( xExtLink );
     774           1 :     return xExtLink;
     775             : }
     776             : 
     777           0 : const RefSheetsModel* ExternalLinkBuffer::getRefSheets( sal_Int32 nRefId ) const
     778             : {
     779           0 :     return ((0 <= nRefId) && (static_cast< size_t >( nRefId ) < maRefSheets.size())) ?
     780           0 :         &maRefSheets[ static_cast< size_t >( nRefId ) ] : 0;
     781             : }
     782             : 
     783             : } // namespace xls
     784          18 : } // namespace oox
     785             : 
     786             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10