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

Generated by: LCOV version 1.10