LCOV - code coverage report
Current view: top level - sc/source/ui/unoobj - chart2uno.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1049 1713 61.2 %
Date: 2012-08-25 Functions: 112 160 70.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1056 3011 35.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include "chart2uno.hxx"
      31                 :            : #include "miscuno.hxx"
      32                 :            : #include "document.hxx"
      33                 :            : #include "cell.hxx"
      34                 :            : #include "chartpos.hxx"
      35                 :            : #include "unonames.hxx"
      36                 :            : #include "globstr.hrc"
      37                 :            : #include "convuno.hxx"
      38                 :            : #include "rangeutl.hxx"
      39                 :            : #include "hints.hxx"
      40                 :            : #include "unoreflist.hxx"
      41                 :            : #include "compiler.hxx"
      42                 :            : #include "reftokenhelper.hxx"
      43                 :            : #include "chartlis.hxx"
      44                 :            : #include "stlalgorithm.hxx"
      45                 :            : #include "tokenuno.hxx"
      46                 :            : 
      47                 :            : #include "formula/opcode.hxx"
      48                 :            : 
      49                 :            : #include <sfx2/objsh.hxx>
      50                 :            : #include <vcl/svapp.hxx>
      51                 :            : 
      52                 :            : #include <com/sun/star/beans/UnknownPropertyException.hpp>
      53                 :            : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
      54                 :            : #include <com/sun/star/table/XCellRange.hpp>
      55                 :            : #include <com/sun/star/table/CellAddress.hpp>
      56                 :            : #include <com/sun/star/text/XText.hpp>
      57                 :            : #include <comphelper/extract.hxx>
      58                 :            : #include <comphelper/processfactory.hxx>
      59                 :            : 
      60                 :            : #include <rtl/math.hxx>
      61                 :            : 
      62         [ #  # ]:          1 : SC_SIMPLE_SERVICE_INFO( ScChart2DataProvider, "ScChart2DataProvider",
      63                 :            :         "com.sun.star.chart2.data.DataProvider")
      64         [ #  # ]:          0 : SC_SIMPLE_SERVICE_INFO( ScChart2DataSource, "ScChart2DataSource",
      65                 :            :         "com.sun.star.chart2.data.DataSource")
      66         [ #  # ]:          0 : SC_SIMPLE_SERVICE_INFO( ScChart2DataSequence, "ScChart2DataSequence",
      67                 :            :         "com.sun.star.chart2.data.DataSequence")
      68                 :            : 
      69                 :            : using namespace ::com::sun::star;
      70                 :            : using namespace ::formula;
      71                 :            : using ::rtl::OUString;
      72                 :            : using ::rtl::OUStringBuffer;
      73                 :            : using ::com::sun::star::uno::Sequence;
      74                 :            : using ::com::sun::star::uno::Reference;
      75                 :            : using ::std::auto_ptr;
      76                 :            : using ::std::vector;
      77                 :            : using ::std::list;
      78                 :            : using ::std::distance;
      79                 :            : using ::std::unary_function;
      80                 :            : using ::boost::shared_ptr;
      81                 :            : 
      82                 :            : namespace
      83                 :            : {
      84                 :         14 : const SfxItemPropertyMapEntry* lcl_GetDataProviderPropertyMap()
      85                 :            : {
      86                 :            :     static SfxItemPropertyMapEntry aDataProviderPropertyMap_Impl[] =
      87                 :            :     {
      88         [ +  - ]:          8 :         {MAP_CHAR_LEN(SC_UNONAME_INCLUDEHIDDENCELLS), 0,        &getBooleanCppuType(),                  0, 0 },
      89                 :            :         {0,0,0,0,0,0}
      90 [ +  + ][ +  - ]:         22 :     };
                 [ #  # ]
      91                 :         14 :     return aDataProviderPropertyMap_Impl;
      92                 :            : }
      93                 :            : 
      94                 :       4770 : const SfxItemPropertyMapEntry* lcl_GetDataSequencePropertyMap()
      95                 :            : {
      96                 :            :     static SfxItemPropertyMapEntry aDataSequencePropertyMap_Impl[] =
      97                 :            :     {
      98         [ +  - ]:          8 :         {MAP_CHAR_LEN(SC_UNONAME_HIDDENVALUES), 0, &getCppuType((uno::Sequence<sal_Int32>*)0 ),                 0, 0 },
      99         [ +  - ]:          8 :         {MAP_CHAR_LEN(SC_UNONAME_ROLE), 0, &getCppuType((::com::sun::star::chart2::data::DataSequenceRole*)0),                  0, 0 },
     100         [ +  - ]:          8 :         {MAP_CHAR_LEN(SC_UNONAME_INCLUDEHIDDENCELLS), 0,        &getBooleanCppuType(),                  0, 0 },
     101                 :            :         {0,0,0,0,0,0}
     102 [ +  + ][ +  - ]:       4778 :     };
                 [ #  # ]
     103                 :       4770 :     return aDataSequencePropertyMap_Impl;
     104                 :            : }
     105                 :            : 
     106                 :            : template< typename T >
     107                 :        110 : ::com::sun::star::uno::Sequence< T > lcl_VectorToSequence(
     108                 :            :     const ::std::vector< T > & rCont )
     109                 :            : {
     110                 :        110 :     ::com::sun::star::uno::Sequence< T > aResult( rCont.size());
     111   [ #  #  +  - ]:        110 :     ::std::copy( rCont.begin(), rCont.end(), aResult.getArray());
         [ +  - ][ #  # ]
     112                 :        110 :     return aResult;
     113                 :            : }
     114                 :            : 
     115                 :            : struct lcl_appendTableNumber : public ::std::unary_function< SCTAB, void >
     116                 :            : {
     117                 :         55 :     lcl_appendTableNumber( ::rtl::OUStringBuffer & rBuffer ) :
     118                 :         55 :             m_rBuffer( rBuffer )
     119                 :         55 :     {}
     120                 :         55 :     void operator() ( SCTAB nTab )
     121                 :            :     {
     122                 :            :         // there is no append with SCTAB or sal_Int16
     123                 :         55 :         m_rBuffer.append( static_cast< sal_Int32 >( nTab ));
     124                 :         55 :         m_rBuffer.append( sal_Unicode( ' ' ));
     125                 :         55 :     }
     126                 :            : private:
     127                 :            :     ::rtl::OUStringBuffer & m_rBuffer;
     128                 :            : };
     129                 :            : 
     130                 :         55 : ::rtl::OUString lcl_createTableNumberList( const ::std::list< SCTAB > & rTableList )
     131                 :            : {
     132                 :         55 :     ::rtl::OUStringBuffer aBuffer;
     133         [ +  - ]:         55 :     ::std::for_each( rTableList.begin(), rTableList.end(), lcl_appendTableNumber( aBuffer ));
     134                 :            :     // remove last trailing ' '
     135         [ +  - ]:         55 :     if( aBuffer.getLength() > 0 )
     136         [ +  - ]:         55 :         aBuffer.setLength( aBuffer.getLength() - 1 );
     137         [ +  - ]:         55 :     return aBuffer.makeStringAndClear();
     138                 :            : }
     139                 :            : 
     140                 :          0 : uno::Reference< frame::XModel > lcl_GetXModel( ScDocument * pDoc )
     141                 :            : {
     142                 :          0 :     uno::Reference< frame::XModel > xModel;
     143         [ #  # ]:          0 :     SfxObjectShell * pObjSh( pDoc ? pDoc->GetDocumentShell() : 0 );
     144         [ #  # ]:          0 :     if( pObjSh )
     145 [ #  # ][ #  # ]:          0 :         xModel.set( pObjSh->GetModel());
     146                 :          0 :     return xModel;
     147                 :            : }
     148                 :            : 
     149         [ +  - ]:       4952 : struct TokenTable : boost::noncopyable
     150                 :            : {
     151                 :            :     SCROW mnRowCount;
     152                 :            :     SCCOL mnColCount;
     153                 :            :     vector<FormulaToken*> maTokens;
     154                 :            : 
     155                 :       2476 :     void init( SCCOL nColCount, SCROW nRowCount )
     156                 :            :     {
     157                 :       2476 :         mnColCount = nColCount;
     158                 :       2476 :         mnRowCount = nRowCount;
     159                 :       2476 :         maTokens.reserve(mnColCount*mnRowCount);
     160                 :       2476 :     }
     161                 :       2476 :     void clear()
     162                 :            :     {
     163         [ +  - ]:       2476 :         ::std::for_each(maTokens.begin(), maTokens.end(), ScDeleteObjectByPtr<FormulaToken>());
     164                 :       2476 :     }
     165                 :            : 
     166                 :       9620 :     void push_back( FormulaToken* pToken )
     167                 :            :     {
     168                 :       9620 :         maTokens.push_back( pToken );
     169                 :            :         OSL_ENSURE( maTokens.size()<= static_cast<sal_uInt32>( mnColCount*mnRowCount ), "too much tokens" );
     170                 :       9620 :     }
     171                 :            : 
     172                 :       9246 :     sal_uInt32 getIndex(SCCOL nCol, SCROW nRow) const
     173                 :            :     {
     174                 :            :         OSL_ENSURE( nCol<mnColCount, "wrong column index" );
     175                 :            :         OSL_ENSURE( nRow<mnRowCount, "wrong row index" );
     176                 :       9246 :         sal_uInt32 nRet = static_cast<sal_uInt32>(nCol*mnRowCount + nRow);
     177                 :            :         OSL_ENSURE( maTokens.size()>= static_cast<sal_uInt32>( mnColCount*mnRowCount ), "too few tokens" );
     178                 :       9246 :         return nRet;
     179                 :            :     }
     180                 :            : 
     181                 :            :     vector<ScTokenRef>* getColRanges(SCCOL nCol) const;
     182                 :            :     vector<ScTokenRef>* getRowRanges(SCROW nRow) const;
     183                 :            :     vector<ScTokenRef>* getAllRanges() const;
     184                 :            : };
     185                 :            : 
     186                 :       6108 : vector<ScTokenRef>* TokenTable::getColRanges(SCCOL nCol) const
     187                 :            : {
     188         [ -  + ]:       6108 :     if (nCol >= mnColCount)
     189                 :          0 :         return NULL;
     190         [ +  + ]:       6108 :     if( mnRowCount<=0 )
     191                 :       2243 :         return NULL;
     192                 :            : 
     193                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     194 [ +  - ][ +  - ]:       3865 :     auto_ptr< vector<ScTokenRef> > pTokens(new vector<ScTokenRef>);
     195                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
     196                 :       3865 :     sal_uInt32 nLast = getIndex(nCol, mnRowCount-1);
     197         [ +  + ]:      10130 :     for (sal_uInt32 i = getIndex(nCol, 0); i <= nLast; ++i)
     198                 :            :     {
     199         [ +  - ]:       6265 :         FormulaToken* p = maTokens[i];
     200         [ -  + ]:       6265 :         if (!p)
     201                 :          0 :             continue;
     202                 :            : 
     203         [ +  - ]:       6265 :         ScTokenRef pCopy(static_cast<ScToken*>(p->Clone()));
     204         [ +  - ]:       6265 :         ScRefTokenHelper::join(*pTokens, pCopy);
     205         [ +  - ]:       6265 :     }
     206                 :       6108 :     return pTokens.release();
     207                 :            : }
     208                 :            : 
     209                 :       1492 : vector<ScTokenRef>* TokenTable::getRowRanges(SCROW nRow) const
     210                 :            : {
     211         [ -  + ]:       1492 :     if (nRow >= mnRowCount)
     212                 :          0 :         return NULL;
     213         [ +  + ]:       1492 :     if( mnColCount<=0 )
     214                 :        734 :         return NULL;
     215                 :            : 
     216                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     217 [ +  - ][ +  - ]:        758 :     auto_ptr< vector<ScTokenRef> > pTokens(new vector<ScTokenRef>);
     218                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
     219                 :        758 :     sal_uInt32 nLast = getIndex(mnColCount-1, nRow);
     220         [ +  + ]:       3817 :     for (sal_uInt32 i = getIndex(0, nRow); i <= nLast; i += mnRowCount)
     221                 :            :     {
     222         [ +  - ]:       3059 :         FormulaToken* p = maTokens[i];
     223         [ -  + ]:       3059 :         if (!p)
     224                 :          0 :             continue;
     225                 :            : 
     226         [ +  - ]:       3059 :         ScTokenRef p2(static_cast<ScToken*>(p->Clone()));
     227         [ +  - ]:       3059 :         ScRefTokenHelper::join(*pTokens, p2);
     228         [ +  - ]:       3059 :     }
     229                 :       1492 :     return pTokens.release();
     230                 :            : }
     231                 :            : 
     232                 :        136 : vector<ScTokenRef>* TokenTable::getAllRanges() const
     233                 :            : {
     234                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     235 [ +  - ][ +  - ]:        136 :     auto_ptr< vector<ScTokenRef> > pTokens(new vector<ScTokenRef>);
     236                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
     237                 :        136 :     sal_uInt32 nStop = mnColCount*mnRowCount;
     238         [ +  + ]:        432 :     for (sal_uInt32 i = 0; i < nStop; i++)
     239                 :            :     {
     240         [ +  - ]:        296 :         FormulaToken* p = maTokens[i];
     241         [ -  + ]:        296 :         if (!p)
     242                 :          0 :             continue;
     243                 :            : 
     244         [ +  - ]:        296 :         ScTokenRef p2(static_cast<ScToken*>(p->Clone()));
     245         [ +  - ]:        296 :         ScRefTokenHelper::join(*pTokens, p2);
     246         [ +  - ]:        296 :     }
     247                 :        136 :     return pTokens.release();
     248                 :            : }
     249                 :            : 
     250                 :            : // ============================================================================
     251                 :            : 
     252                 :            : typedef std::map<sal_uInt32, FormulaToken*> FormulaTokenMap;
     253                 :            : typedef std::map<sal_uInt32, FormulaTokenMap*> FormulaTokenMapMap;
     254                 :            : 
     255                 :            : class Chart2PositionMap
     256                 :            : {
     257                 :            : public:
     258                 :            :     Chart2PositionMap(SCCOL nColCount, SCROW nRowCount,
     259                 :            :                       bool bFillRowHeader, bool bFillColumnHeader, FormulaTokenMapMap& rCols,
     260                 :            :                       ScDocument* pDoc );
     261                 :            :     ~Chart2PositionMap();
     262                 :            : 
     263                 :        342 :     SCCOL getDataColCount() const { return mnDataColCount; }
     264                 :        277 :     SCROW getDataRowCount() const { return mnDataRowCount; }
     265                 :            : 
     266                 :            :     vector<ScTokenRef>* getLeftUpperCornerRanges() const;
     267                 :            :     vector<ScTokenRef>* getAllColHeaderRanges() const;
     268                 :            :     vector<ScTokenRef>* getAllRowHeaderRanges() const;
     269                 :            : 
     270                 :            :     vector<ScTokenRef>* getColHeaderRanges(SCCOL nChartCol) const;
     271                 :            :     vector<ScTokenRef>* getRowHeaderRanges(SCROW nChartRow) const;
     272                 :            : 
     273                 :            :     vector<ScTokenRef>* getDataColRanges(SCCOL nCol) const;
     274                 :            :     vector<ScTokenRef>* getDataRowRanges(SCROW nRow) const;
     275                 :            : 
     276                 :            : private:
     277                 :            :     SCCOL mnDataColCount;
     278                 :            :     SCROW mnDataRowCount;
     279                 :            : 
     280                 :            :     TokenTable maLeftUpperCorner; //nHeaderColCount*nHeaderRowCount
     281                 :            :     TokenTable maColHeaders; //mnDataColCount*nHeaderRowCount
     282                 :            :     TokenTable maRowHeaders; //nHeaderColCount*mnDataRowCount
     283                 :            :     TokenTable maData;//mnDataColCount*mnDataRowCount
     284                 :            : };
     285                 :            : 
     286                 :        619 : Chart2PositionMap::Chart2PositionMap(SCCOL nAllColCount,  SCROW nAllRowCount,
     287 [ +  - ][ +  - ]:        619 :                                      bool bFillRowHeader, bool bFillColumnHeader, FormulaTokenMapMap& rCols, ScDocument* pDoc)
                 [ +  - ]
     288                 :            : {
     289                 :            :     // if bFillRowHeader is true, at least the first column serves as a row header.
     290                 :            :     //  If more than one column is pure text all the first pure text columns are used as header.
     291                 :            :     // Likewise, if bFillColumnHeader is true, at least the first row serves as a column header.
     292                 :            :     //  If more than one row is pure text all the first pure text rows are used as header.
     293                 :            : 
     294 [ +  + ][ +  - ]:        619 :     SCROW nHeaderRowCount = (bFillColumnHeader && nAllColCount && nAllRowCount) ? 1 : 0;
                 [ +  - ]
     295 [ +  + ][ +  - ]:        619 :     SCCOL nHeaderColCount = (bFillRowHeader && nAllColCount && nAllRowCount) ? 1 : 0;
                 [ +  - ]
     296                 :            : 
     297 [ +  + ][ +  + ]:        619 :     if( nHeaderColCount || nHeaderRowCount )
     298                 :            :     {
     299                 :         73 :         const SCCOL nInitialHeaderColCount = nHeaderColCount;
     300                 :            :         //check whether there is more than one text column or row that should be added to the headers
     301                 :         73 :         SCROW nSmallestValueRowIndex = nAllRowCount;
     302                 :         73 :         bool bFoundValues = false;
     303                 :         73 :         bool bFoundAnything = false;
     304                 :         73 :         FormulaTokenMapMap::const_iterator it1 = rCols.begin();
     305 [ +  + ][ +  + ]:        217 :         for (SCCOL nCol = 0; !bFoundValues && nCol < nAllColCount; ++nCol)
                 [ +  + ]
     306                 :            :         {
     307 [ +  - ][ +  + ]:        144 :             if (it1 != rCols.end() && nCol>=nHeaderColCount)
         [ +  - ][ +  - ]
                 [ +  + ]
     308                 :            :             {
     309                 :         76 :                 FormulaTokenMap* pCol = it1->second;
     310         [ +  - ]:         76 :                 FormulaTokenMap::const_iterator it2 = pCol->begin();
     311 [ +  + ][ +  + ]:        238 :                 for (SCROW nRow = 0; !bFoundValues && nRow < nSmallestValueRowIndex && it2 != pCol->end(); ++nRow)
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
         [ +  + ][ +  +  
             #  #  #  # ]
     312                 :            :                 {
     313         [ +  - ]:        162 :                     FormulaToken* pToken = it2->second;
     314 [ +  - ][ +  + ]:        162 :                     if (pToken && nRow>=nHeaderRowCount)
     315                 :            :                     {
     316                 :         91 :                         ScRange aRange;
     317                 :         91 :                         bool bExternal = false;
     318                 :         91 :                         StackVar eType = pToken->GetType();
     319 [ +  - ][ +  - ]:         91 :                         if( eType==svExternal || eType==svExternalSingleRef || eType==svExternalDoubleRef || eType==svExternalName )
         [ -  + ][ +  - ]
     320                 :          0 :                             bExternal = true;//lllll todo correct?
     321         [ +  - ]:         91 :                         ScTokenRef pSharedToken(static_cast<ScToken*>(pToken->Clone()));
     322         [ +  - ]:         91 :                         ScRefTokenHelper::getRangeFromToken(aRange, pSharedToken, bExternal );
     323                 :         91 :                         SCCOL nCol1=0, nCol2=0;
     324                 :         91 :                         SCROW nRow1=0, nRow2=0;
     325                 :         91 :                         SCTAB nTab1=0, nTab2=0;
     326                 :         91 :                         aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
     327 [ +  - ][ +  + ]:         91 :                         if (pDoc && pDoc->HasValueData( nCol1, nRow1, nTab1 ))
         [ +  + ][ +  - ]
     328                 :            :                         {
     329                 :         71 :                             bFoundValues = bFoundAnything = true;
     330         [ +  - ]:         71 :                             nSmallestValueRowIndex = std::min( nSmallestValueRowIndex, nRow );
     331                 :            :                         }
     332         [ +  + ]:         91 :                         if( !bFoundAnything )
     333                 :            :                         {
     334 [ +  - ][ +  - ]:         10 :                             if (pDoc && pDoc->HasData( nCol1, nRow1, nTab1 ) )
         [ +  - ][ +  - ]
     335                 :         10 :                                 bFoundAnything = true;
     336         [ +  - ]:         91 :                         }
     337                 :            :                     }
     338         [ +  - ]:        162 :                     ++it2;
     339                 :            :                 }
     340 [ +  + ][ -  + ]:         76 :                 if(!bFoundValues && nHeaderColCount>0)
     341                 :         76 :                     nHeaderColCount++;
     342                 :            :             }
     343                 :        144 :             ++it1;
     344                 :            :         }
     345         [ +  + ]:         73 :         if( bFoundAnything )
     346                 :            :         {
     347         [ +  + ]:         71 :             if(nHeaderRowCount>0)
     348                 :            :             {
     349         [ +  - ]:         66 :                 if( bFoundValues )
     350                 :         66 :                     nHeaderRowCount = nSmallestValueRowIndex;
     351         [ #  # ]:          0 :                 else if( nAllRowCount>1 )
     352                 :          0 :                     nHeaderRowCount = nAllRowCount-1;
     353                 :            :             }
     354                 :            :         }
     355                 :            :         else //if the cells are completely empty, just use single header rows and columns
     356                 :         73 :             nHeaderColCount = nInitialHeaderColCount;
     357                 :            :     }
     358                 :            : 
     359                 :        619 :     mnDataColCount = nAllColCount - nHeaderColCount;
     360                 :        619 :     mnDataRowCount = nAllRowCount - nHeaderRowCount;
     361                 :            : 
     362         [ +  - ]:        619 :     maLeftUpperCorner.init(nHeaderColCount,nHeaderRowCount);
     363         [ +  - ]:        619 :     maColHeaders.init(mnDataColCount,nHeaderRowCount);
     364         [ +  - ]:        619 :     maRowHeaders.init(nHeaderColCount,mnDataRowCount);
     365         [ +  - ]:        619 :     maData.init(mnDataColCount,mnDataRowCount);
     366                 :            : 
     367                 :        619 :     FormulaTokenMapMap::const_iterator it1 = rCols.begin();
     368         [ +  + ]:       5971 :     for (SCCOL nCol = 0; nCol < nAllColCount; ++nCol)
     369                 :            :     {
     370         [ +  - ]:       5352 :         if (it1 != rCols.end())
     371                 :            :         {
     372                 :       5352 :             FormulaTokenMap* pCol = it1->second;
     373         [ +  - ]:       5352 :             FormulaTokenMap::const_iterator it2 = pCol->begin();
     374         [ +  + ]:      14972 :             for (SCROW nRow = 0; nRow < nAllRowCount; ++nRow)
     375                 :            :             {
     376                 :       9620 :                 FormulaToken* pToken = NULL;
     377 [ +  - ][ +  - ]:       9620 :                 if (it2 != pCol->end())
                 [ +  - ]
     378                 :            :                 {
     379         [ +  - ]:       9620 :                     pToken = it2->second;
     380         [ +  - ]:       9620 :                     ++it2;
     381                 :            :                 }
     382                 :            : 
     383         [ +  + ]:       9620 :                 if( nCol < nHeaderColCount )
     384                 :            :                 {
     385         [ +  + ]:        256 :                     if( nRow < nHeaderRowCount )
     386         [ +  - ]:         63 :                         maLeftUpperCorner.push_back(pToken);
     387                 :            :                     else
     388         [ +  - ]:        193 :                         maRowHeaders.push_back(pToken);
     389                 :            :                 }
     390         [ +  + ]:       9364 :                 else if( nRow < nHeaderRowCount )
     391         [ +  - ]:        863 :                     maColHeaders.push_back(pToken);
     392                 :            :                 else
     393         [ +  - ]:       8501 :                     maData.push_back(pToken);
     394                 :            :             }
     395                 :       5352 :             ++it1;
     396                 :            :         }
     397                 :            :     }
     398                 :        619 : }
     399                 :            : 
     400                 :        619 : Chart2PositionMap::~Chart2PositionMap()
     401                 :            : {
     402         [ +  - ]:        619 :     maLeftUpperCorner.clear();
     403         [ +  - ]:        619 :     maColHeaders.clear();
     404         [ +  - ]:        619 :     maRowHeaders.clear();
     405         [ +  - ]:        619 :     maData.clear();
     406                 :        619 : }
     407                 :            : 
     408                 :         68 : vector<ScTokenRef>* Chart2PositionMap::getLeftUpperCornerRanges() const
     409                 :            : {
     410                 :         68 :     return maLeftUpperCorner.getAllRanges();
     411                 :            : }
     412                 :          4 : vector<ScTokenRef>* Chart2PositionMap::getAllColHeaderRanges() const
     413                 :            : {
     414                 :          4 :     return maColHeaders.getAllRanges();
     415                 :            : }
     416                 :         64 : vector<ScTokenRef>* Chart2PositionMap::getAllRowHeaderRanges() const
     417                 :            : {
     418                 :         64 :     return maRowHeaders.getAllRanges();
     419                 :            : }
     420                 :       3054 : vector<ScTokenRef>* Chart2PositionMap::getColHeaderRanges(SCCOL nCol) const
     421                 :            : {
     422                 :       3054 :     return maColHeaders.getColRanges( nCol);
     423                 :            : }
     424                 :        746 : vector<ScTokenRef>* Chart2PositionMap::getRowHeaderRanges(SCROW nRow) const
     425                 :            : {
     426                 :        746 :     return maRowHeaders.getRowRanges( nRow);
     427                 :            : }
     428                 :            : 
     429                 :       3054 : vector<ScTokenRef>* Chart2PositionMap::getDataColRanges(SCCOL nCol) const
     430                 :            : {
     431                 :       3054 :     return maData.getColRanges( nCol);
     432                 :            : }
     433                 :            : 
     434                 :        746 : vector<ScTokenRef>* Chart2PositionMap::getDataRowRanges(SCROW nRow) const
     435                 :            : {
     436                 :        746 :     return maData.getRowRanges( nRow);
     437                 :            : }
     438                 :            : 
     439                 :            : // ----------------------------------------------------------------------------
     440                 :            : 
     441                 :            : /**
     442                 :            :  * Designed to be a drop-in replacement for ScChartPositioner, in order to
     443                 :            :  * handle external references.
     444                 :            :  */
     445                 :            : class Chart2Positioner : boost::noncopyable
     446                 :            : {
     447                 :            :     enum GlueType
     448                 :            :     {
     449                 :            :         GLUETYPE_NA,
     450                 :            :         GLUETYPE_NONE,
     451                 :            :         GLUETYPE_COLS,
     452                 :            :         GLUETYPE_ROWS,
     453                 :            :         GLUETYPE_BOTH
     454                 :            :     };
     455                 :            : 
     456                 :            : public:
     457                 :        619 :     Chart2Positioner(ScDocument* pDoc, const vector<ScTokenRef>& rRefTokens) :
     458                 :            :         mrRefTokens(rRefTokens),
     459                 :            :         mpPositionMap(NULL),
     460                 :            :         meGlue(GLUETYPE_NA),
     461                 :            :         mpDoc(pDoc),
     462                 :            :         mbColHeaders(false),
     463                 :            :         mbRowHeaders(false),
     464                 :        619 :         mbDummyUpperLeft(false)
     465                 :            :     {
     466                 :        619 :     }
     467                 :            : 
     468                 :        619 :     ~Chart2Positioner()
     469         [ +  - ]:        619 :     {
     470                 :        619 :     }
     471                 :            : 
     472                 :        619 :     void setHeaders(bool bColHeaders, bool bRowHeaders)
     473                 :            :     {
     474                 :        619 :         mbColHeaders = bColHeaders;
     475                 :        619 :         mbRowHeaders = bRowHeaders;
     476                 :        619 :     }
     477                 :            : 
     478                 :            :     bool hasColHeaders() const { return mbColHeaders; }
     479                 :            :     bool hasRowHeaders() const { return mbRowHeaders; }
     480                 :            : 
     481                 :        619 :     Chart2PositionMap* getPositionMap()
     482                 :            :     {
     483                 :        619 :         createPositionMap();
     484                 :        619 :         return mpPositionMap.get();
     485                 :            :     }
     486                 :            : 
     487                 :            : private:
     488                 :            :     Chart2Positioner(); // disabled
     489                 :            : 
     490                 :            :     void invalidateGlue();
     491                 :            :     void glueState();
     492                 :            :     void calcGlueState(SCCOL nCols, SCROW nRows);
     493                 :            :     void createPositionMap();
     494                 :            : 
     495                 :            : private:
     496                 :            :     const vector<ScTokenRef>& mrRefTokens;
     497                 :            :     boost::scoped_ptr<Chart2PositionMap> mpPositionMap;
     498                 :            :     GlueType    meGlue;
     499                 :            :     SCCOL       mnStartCol;
     500                 :            :     SCROW       mnStartRow;
     501                 :            :     ScDocument* mpDoc;
     502                 :            :     bool mbColHeaders:1;
     503                 :            :     bool mbRowHeaders:1;
     504                 :            :     bool mbDummyUpperLeft:1;
     505                 :            : };
     506                 :            : 
     507                 :          0 : void Chart2Positioner::invalidateGlue()
     508                 :            : {
     509                 :          0 :     meGlue = GLUETYPE_NA;
     510                 :          0 :     mpPositionMap.reset(NULL);
     511                 :          0 : }
     512                 :            : 
     513                 :        619 : void Chart2Positioner::glueState()
     514                 :            : {
     515         [ +  - ]:        619 :     if (meGlue != GLUETYPE_NA)
     516                 :            :         return;
     517                 :            : 
     518                 :        619 :     mbDummyUpperLeft = false;
     519         [ +  - ]:        619 :     if (mrRefTokens.size() <= 1)
     520                 :            :     {
     521                 :            :         // Source data consists of only one data range.
     522         [ +  - ]:        619 :         const ScTokenRef& p = mrRefTokens.front();
     523                 :            :         ScComplexRefData aData;
     524 [ +  - ][ +  - ]:        619 :         if (ScRefTokenHelper::getDoubleRefDataFromToken(aData, p))
     525                 :            :         {
     526         [ +  - ]:        619 :             if (aData.Ref1.nTab == aData.Ref2.nTab)
     527                 :        619 :                 meGlue = GLUETYPE_NONE;
     528                 :            :             else
     529                 :          0 :                 meGlue = GLUETYPE_COLS;
     530                 :        619 :             mnStartCol = aData.Ref1.nCol;
     531                 :        619 :             mnStartRow = aData.Ref1.nRow;
     532                 :            :         }
     533                 :            :         else
     534                 :            :         {
     535         [ #  # ]:          0 :             invalidateGlue();
     536                 :          0 :             mnStartCol = 0;
     537                 :        619 :             mnStartRow = 0;
     538                 :            :         }
     539                 :            :         return;
     540                 :            :     }
     541                 :            : 
     542                 :            :     ScComplexRefData aData;
     543 [ #  # ][ #  # ]:          0 :     ScRefTokenHelper::getDoubleRefDataFromToken(aData, mrRefTokens.front());
     544                 :          0 :     mnStartCol = aData.Ref1.nCol;
     545                 :          0 :     mnStartRow = aData.Ref1.nRow;
     546                 :            : 
     547                 :          0 :     SCCOL nEndCol = 0;
     548                 :          0 :     SCROW nEndRow = 0;
     549 [ #  # ][ #  # ]:          0 :     for (vector<ScTokenRef>::const_iterator itr = mrRefTokens.begin(), itrEnd = mrRefTokens.end()
     550                 :            :          ; itr != itrEnd; ++itr)
     551                 :            :     {
     552         [ #  # ]:          0 :         ScRefTokenHelper::getDoubleRefDataFromToken(aData, *itr);
     553                 :          0 :         SCCOLROW n1 = aData.Ref1.nCol;
     554                 :          0 :         SCCOLROW n2 = aData.Ref2.nCol;
     555         [ #  # ]:          0 :         if (n1 > MAXCOL)
     556                 :          0 :             n1 = MAXCOL;
     557         [ #  # ]:          0 :         if (n2 > MAXCOL)
     558                 :          0 :             n2 = MAXCOL;
     559         [ #  # ]:          0 :         if (n1 < mnStartCol)
     560                 :          0 :             mnStartCol = static_cast<SCCOL>(n1);
     561         [ #  # ]:          0 :         if (n2 > nEndCol)
     562                 :          0 :             nEndCol = static_cast<SCCOL>(n2);
     563                 :            : 
     564                 :          0 :         n1 = aData.Ref1.nRow;
     565                 :          0 :         n2 = aData.Ref2.nRow;
     566         [ #  # ]:          0 :         if (n1 > MAXROW)
     567                 :          0 :             n1 = MAXROW;
     568         [ #  # ]:          0 :         if (n2 > MAXROW)
     569                 :          0 :             n2 = MAXROW;
     570                 :            : 
     571         [ #  # ]:          0 :         if (n1 < mnStartRow)
     572                 :          0 :             mnStartRow = static_cast<SCROW>(n1);
     573         [ #  # ]:          0 :         if (n2 > nEndRow)
     574                 :          0 :             nEndRow = static_cast<SCROW>(n2);
     575                 :            :     }
     576                 :            : 
     577         [ #  # ]:          0 :     if (mnStartCol == nEndCol)
     578                 :            :     {
     579                 :            :         // All source data is in a single column.
     580                 :          0 :         meGlue = GLUETYPE_ROWS;
     581                 :            :         return;
     582                 :            :     }
     583                 :            : 
     584         [ #  # ]:          0 :     if (mnStartRow == nEndRow)
     585                 :            :     {
     586                 :            :         // All source data is in a single row.
     587                 :          0 :         meGlue = GLUETYPE_COLS;
     588                 :            :         return;
     589                 :            :     }
     590                 :            : 
     591                 :            :     // total column size
     592                 :          0 :     SCCOL nC = nEndCol - mnStartCol + 1;
     593                 :            : 
     594                 :            :     // total row size
     595                 :          0 :     SCROW nR = nEndRow - mnStartRow + 1;
     596                 :            : 
     597                 :            :     // #i103540# prevent invalid vector size
     598 [ #  # ][ #  # ]:          0 :     if ((nC <= 0) || (nR <= 0))
     599                 :            :     {
     600         [ #  # ]:          0 :         invalidateGlue();
     601                 :          0 :         mnStartCol = 0;
     602                 :          0 :         mnStartRow = 0;
     603                 :            :         return;
     604                 :            :     }
     605                 :            : 
     606         [ #  # ]:        619 :     calcGlueState(nC, nR);
     607                 :            : }
     608                 :            : 
     609                 :            : enum State { Hole = 0, Occupied = 1, Free = 2, Glue = 3 };
     610                 :            : 
     611                 :          0 : void Chart2Positioner::calcGlueState(SCCOL nColSize, SCROW nRowSize)
     612                 :            : {
     613                 :            :     // TODO: This code can use some space optimization.  Using an array to
     614                 :            :     // store individual cell's states is terribly inefficient esp for large
     615                 :            :     // data ranges; let's use flat_segment_tree to reduce memory usage here.
     616                 :            : 
     617                 :          0 :     sal_uInt32 nCR = static_cast<sal_uInt32>(nColSize*nRowSize);
     618                 :            : 
     619         [ #  # ]:          0 :     vector<State> aCellStates(nCR, Hole);
     620                 :            : 
     621                 :            :     // Mark all referenced cells "occupied".
     622 [ #  # ][ #  # ]:          0 :     for (vector<ScTokenRef>::const_iterator itr = mrRefTokens.begin(), itrEnd = mrRefTokens.end();
     623                 :            :           itr != itrEnd; ++itr)
     624                 :            :     {
     625                 :            :         ScComplexRefData aData;
     626         [ #  # ]:          0 :         ScRefTokenHelper::getDoubleRefDataFromToken(aData, *itr);
     627                 :          0 :         SCCOL nCol1 = static_cast<SCCOL>(aData.Ref1.nCol) - mnStartCol;
     628                 :          0 :         SCCOL nCol2 = static_cast<SCCOL>(aData.Ref2.nCol) - mnStartCol;
     629                 :          0 :         SCROW nRow1 = static_cast<SCROW>(aData.Ref1.nRow) - mnStartRow;
     630                 :          0 :         SCROW nRow2 = static_cast<SCROW>(aData.Ref2.nRow) - mnStartRow;
     631         [ #  # ]:          0 :         for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
     632         [ #  # ]:          0 :             for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
     633                 :            :             {
     634                 :          0 :                 size_t i = nCol*nRowSize + nRow;
     635         [ #  # ]:          0 :                 aCellStates[i] = Occupied;
     636                 :            :             }
     637                 :            :     }
     638                 :            : 
     639                 :            :     // If at least one cell in either the first column or first row is empty,
     640                 :            :     // we don't glue at all unless the whole column or row is empty; we expect
     641                 :            :     // all cells in the first column / row to be fully populated.  If we have
     642                 :            :     // empty column or row, then we do glue by the column or row,
     643                 :            :     // respectively.
     644                 :            : 
     645                 :          0 :     bool bGlue = true;
     646                 :          0 :     bool bGlueCols = false;
     647 [ #  # ][ #  # ]:          0 :     for (SCCOL nCol = 0; bGlue && nCol < nColSize; ++nCol)
                 [ #  # ]
     648                 :            :     {
     649 [ #  # ][ #  # ]:          0 :         for (SCROW nRow = 0; bGlue && nRow < nRowSize; ++nRow)
                 [ #  # ]
     650                 :            :         {
     651                 :          0 :             size_t i = nCol*nRowSize + nRow;
     652 [ #  # ][ #  # ]:          0 :             if (aCellStates[i] == Occupied)
     653                 :            :             {
     654 [ #  # ][ #  # ]:          0 :                 if (nCol == 0 || nRow == 0)
     655                 :          0 :                     break;
     656                 :            : 
     657                 :          0 :                 bGlue = false;
     658                 :            :             }
     659                 :            :             else
     660         [ #  # ]:          0 :                 aCellStates[i] = Free;
     661                 :            :         }
     662                 :          0 :         size_t nLast = (nCol+1)*nRowSize - 1; // index for the last cell in the column.
     663 [ #  # ][ #  # ]:          0 :         if (bGlue && aCellStates[nLast] == Free)
         [ #  # ][ #  # ]
     664                 :            :         {
     665                 :            :             // Whole column is empty.
     666         [ #  # ]:          0 :             aCellStates[nLast] = Glue;
     667                 :          0 :             bGlueCols = true;
     668                 :            :         }
     669                 :            :     }
     670                 :            : 
     671                 :          0 :     bool bGlueRows = false;
     672 [ #  # ][ #  # ]:          0 :     for (SCROW nRow = 0; bGlue && nRow < nRowSize; ++nRow)
                 [ #  # ]
     673                 :            :     {
     674                 :          0 :         size_t i = nRow;
     675 [ #  # ][ #  # ]:          0 :         for (SCCOL nCol = 0; bGlue && nCol < nColSize; ++nCol, i += nRowSize)
                 [ #  # ]
     676                 :            :         {
     677 [ #  # ][ #  # ]:          0 :             if (aCellStates[i] == Occupied)
     678                 :            :             {
     679 [ #  # ][ #  # ]:          0 :                 if (nCol == 0 || nRow == 0)
     680                 :          0 :                     break;
     681                 :            : 
     682                 :          0 :                 bGlue = false;
     683                 :            :             }
     684                 :            :             else
     685         [ #  # ]:          0 :                 aCellStates[i] = Free;
     686                 :            :         }
     687                 :          0 :         i = (nColSize-1)*nRowSize + nRow; // index for the row position in the last column.
     688 [ #  # ][ #  # ]:          0 :         if (bGlue && aCellStates[i] == Free)
         [ #  # ][ #  # ]
     689                 :            :         {
     690                 :            :             // Whole row is empty.
     691         [ #  # ]:          0 :             aCellStates[i] = Glue;
     692                 :          0 :             bGlueRows = true;
     693                 :            :         }
     694                 :            :     }
     695                 :            : 
     696                 :          0 :     size_t i = 1;
     697 [ #  # ][ #  # ]:          0 :     for (sal_uInt32 n = 1; bGlue && n < nCR; ++n, ++i)
                 [ #  # ]
     698 [ #  # ][ #  # ]:          0 :         if (aCellStates[i] == Hole)
     699                 :          0 :             bGlue = false;
     700                 :            : 
     701         [ #  # ]:          0 :     if (bGlue)
     702                 :            :     {
     703 [ #  # ][ #  # ]:          0 :         if (bGlueCols && bGlueRows)
     704                 :          0 :             meGlue = GLUETYPE_BOTH;
     705         [ #  # ]:          0 :         else if (bGlueRows)
     706                 :          0 :             meGlue = GLUETYPE_ROWS;
     707                 :            :         else
     708                 :          0 :             meGlue = GLUETYPE_COLS;
     709 [ #  # ][ #  # ]:          0 :         if (aCellStates.front() != Occupied)
     710                 :          0 :             mbDummyUpperLeft = true;
     711                 :            :     }
     712                 :            :     else
     713                 :          0 :         meGlue = GLUETYPE_NONE;
     714                 :          0 : }
     715                 :            : 
     716                 :        619 : void Chart2Positioner::createPositionMap()
     717                 :            : {
     718 [ +  - ][ -  + ]:        619 :     if (meGlue == GLUETYPE_NA && mpPositionMap.get())
                 [ -  + ]
     719         [ #  # ]:          0 :         mpPositionMap.reset(NULL);
     720                 :            : 
     721         [ +  - ]:        619 :     if (mpPositionMap.get())
     722                 :        619 :         return;
     723                 :            : 
     724         [ +  - ]:        619 :     glueState();
     725                 :            : 
     726                 :        619 :     bool bNoGlue = (meGlue == GLUETYPE_NONE);
     727                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     728 [ +  - ][ +  - ]:        619 :     auto_ptr<FormulaTokenMapMap> pCols(new FormulaTokenMapMap);
     729                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
     730                 :        619 :     FormulaTokenMap* pCol = NULL;
     731                 :        619 :     SCROW nNoGlueRow = 0;
     732 [ +  - ][ +  + ]:       1238 :     for (vector<ScTokenRef>::const_iterator itr = mrRefTokens.begin(), itrEnd = mrRefTokens.end();
     733                 :            :           itr != itrEnd; ++itr)
     734                 :            :     {
     735                 :        619 :         const ScTokenRef& pToken = *itr;
     736                 :            : 
     737         [ +  - ]:        619 :         bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
     738 [ -  + ][ #  # ]:        619 :         sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
     739 [ -  + ][ #  # ]:        619 :         String aTabName = bExternal ? pToken->GetString() : String();
         [ #  # ][ +  - ]
     740                 :            : 
     741                 :            :         ScComplexRefData aData;
     742 [ +  - ][ -  + ]:        619 :         if( !ScRefTokenHelper::getDoubleRefDataFromToken(aData, *itr) )
     743                 :            :             break;
     744                 :        619 :         const ScSingleRefData& s = aData.Ref1;
     745                 :        619 :         const ScSingleRefData& e = aData.Ref2;
     746                 :        619 :         SCCOL nCol1 = s.nCol, nCol2 = e.nCol;
     747                 :        619 :         SCROW nRow1 = s.nRow, nRow2 = e.nRow;
     748                 :        619 :         SCTAB nTab1 = s.nTab, nTab2 = e.nTab;
     749                 :            : 
     750         [ +  + ]:       1238 :         for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
     751                 :            :         {
     752                 :            :             // columns on secondary sheets are appended; we treat them as if
     753                 :            :             // all columns are on the same sheet.  TODO: We can't assume that
     754                 :            :             // the column range is 16-bit; remove that restriction.
     755                 :            :             sal_uInt32 nInsCol = (static_cast<sal_uInt32>(nTab) << 16) |
     756         [ +  - ]:        619 :                 (bNoGlue ? 0 : static_cast<sal_uInt32>(nCol1));
     757                 :            : 
     758         [ +  + ]:       5971 :             for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nInsCol)
     759                 :            :             {
     760         [ +  - ]:       5352 :                 FormulaTokenMapMap::const_iterator it = pCols->find(nInsCol);
     761         [ +  - ]:       5352 :                 if (it == pCols->end())
     762                 :            :                 {
     763 [ +  - ][ +  - ]:       5352 :                     pCol = new FormulaTokenMap;
     764         [ +  - ]:       5352 :                     (*pCols)[ nInsCol ] = pCol;
     765                 :            :                 }
     766                 :            :                 else
     767                 :          0 :                     pCol = it->second;
     768                 :            : 
     769         [ +  - ]:       5352 :                 sal_uInt32 nInsRow = static_cast<sal_uInt32>(bNoGlue ? nNoGlueRow : nRow1);
     770         [ +  + ]:      14972 :                 for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow, ++nInsRow)
     771                 :            :                 {
     772                 :            :                     ScSingleRefData aCellData;
     773                 :       9620 :                     aCellData.InitFlags();
     774                 :       9620 :                     aCellData.SetFlag3D(true);
     775                 :       9620 :                     aCellData.SetColRel(false);
     776                 :       9620 :                     aCellData.SetRowRel(false);
     777                 :       9620 :                     aCellData.SetTabRel(false);
     778                 :       9620 :                     aCellData.nCol = nCol;
     779                 :       9620 :                     aCellData.nRow = nRow;
     780                 :       9620 :                     aCellData.nTab = nTab;
     781                 :            : 
     782 [ +  - ][ +  - ]:       9620 :                     if (pCol->find(nInsRow) == pCol->end())
                 [ +  - ]
     783                 :            :                     {
     784         [ -  + ]:       9620 :                         if (bExternal)
     785 [ #  # ][ #  # ]:          0 :                             (*pCol)[ nInsRow ] = new ScExternalSingleRefToken(nFileId, aTabName, aCellData);
                 [ #  # ]
     786                 :            :                         else
     787 [ +  - ][ +  - ]:       9620 :                             (*pCol)[ nInsRow ] = new ScSingleRefToken(aCellData);
                 [ +  - ]
     788                 :            :                     }
     789                 :            :                 }
     790                 :            :             }
     791                 :            :         }
     792         [ +  - ]:       1238 :         nNoGlueRow += nRow2 - nRow1 + 1;
     793         [ +  - ]:        619 :     }
     794                 :            : 
     795                 :        619 :     bool bFillRowHeader = mbRowHeaders;
     796                 :        619 :     bool bFillColumnHeader = mbColHeaders;
     797                 :            : 
     798                 :        619 :     SCSIZE nAllColCount = static_cast<SCSIZE>(pCols->size());
     799                 :        619 :     SCSIZE nAllRowCount = 0;
     800         [ +  - ]:        619 :     if (!pCols->empty())
     801                 :            :     {
     802                 :        619 :         pCol = pCols->begin()->second;
     803         [ -  + ]:        619 :         if (mbDummyUpperLeft)
     804 [ #  # ][ #  # ]:          0 :             if (pCol->find(0) == pCol->end())
                 [ #  # ]
     805         [ #  # ]:          0 :                 (*pCol)[ 0 ] = NULL;        // Dummy fuer Beschriftung
     806                 :        619 :         nAllRowCount = static_cast<SCSIZE>(pCol->size());
     807                 :            :     }
     808                 :            : 
     809 [ +  - ][ +  - ]:        619 :     if( nAllColCount!=0 && nAllRowCount!=0 )
     810                 :            :     {
     811         [ +  - ]:        619 :         if (bNoGlue)
     812                 :            :         {
     813                 :        619 :             FormulaTokenMap* pFirstCol = pCols->begin()->second;
     814 [ +  - ][ +  - ]:       2363 :             for (FormulaTokenMap::const_iterator it1 = pFirstCol->begin(); it1 != pFirstCol->end(); ++it1)
         [ +  - ][ +  + ]
                 [ +  - ]
     815                 :            :             {
     816         [ +  - ]:       1744 :                 sal_uInt32 nKey = it1->first;
     817         [ +  + ]:      11364 :                 for (FormulaTokenMapMap::const_iterator it2 = pCols->begin(); it2 != pCols->end(); ++it2)
     818                 :            :                 {
     819                 :       9620 :                     pCol = it2->second;
     820 [ +  - ][ -  + ]:       9620 :                     if (pCol->find(nKey) == pCol->end())
                 [ +  - ]
     821         [ #  # ]:          0 :                         (*pCol)[ nKey ] = NULL;
     822                 :            :                 }
     823                 :            :             }
     824                 :            :         }
     825                 :            :     }
     826                 :            :     mpPositionMap.reset(
     827                 :            :         new Chart2PositionMap(
     828                 :            :             static_cast<SCCOL>(nAllColCount), static_cast<SCROW>(nAllRowCount),
     829 [ +  - ][ +  - ]:        619 :             bFillRowHeader, bFillColumnHeader, *pCols, mpDoc));
                 [ +  - ]
     830                 :            : 
     831                 :            :     // Destroy all column instances.
     832         [ +  + ]:       5971 :     for (FormulaTokenMapMap::const_iterator it = pCols->begin(); it != pCols->end(); ++it)
     833                 :            :     {
     834                 :       5352 :         pCol = it->second;
     835         [ +  - ]:       5352 :         delete pCol;
     836                 :        619 :     }
     837                 :            : }
     838                 :            : 
     839                 :            : // ============================================================================
     840                 :            : 
     841                 :            : /**
     842                 :            :  * Function object to create a range string from a token list.
     843                 :            :  */
     844                 :      98988 : class Tokens2RangeString : public unary_function<ScTokenRef, void>
     845                 :            : {
     846                 :            : public:
     847                 :      24747 :     Tokens2RangeString(ScDocument* pDoc, FormulaGrammar::Grammar eGram, sal_Unicode cRangeSep) :
     848                 :      24747 :         mpRangeStr(new OUStringBuffer),
     849                 :            :         mpDoc(pDoc),
     850                 :            :         meGrammar(eGram),
     851                 :            :         mcRangeSep(cRangeSep),
     852                 :      49494 :         mbFirst(true)
     853                 :            :     {
     854                 :      24747 :     }
     855                 :            : 
     856                 :      49494 :     Tokens2RangeString(const Tokens2RangeString& r) :
     857                 :            :         mpRangeStr(r.mpRangeStr),
     858                 :            :         mpDoc(r.mpDoc),
     859                 :            :         meGrammar(r.meGrammar),
     860                 :            :         mcRangeSep(r.mcRangeSep),
     861                 :      49494 :         mbFirst(r.mbFirst)
     862                 :            :     {
     863                 :      49494 :     }
     864                 :            : 
     865                 :      24747 :     void operator() (const ScTokenRef& rToken)
     866                 :            :     {
     867         [ +  - ]:      24747 :         ScCompiler aCompiler(mpDoc, ScAddress(0,0,0));
     868         [ +  - ]:      24747 :         aCompiler.SetGrammar(meGrammar);
     869         [ +  - ]:      24747 :         String aStr;
     870         [ +  - ]:      24747 :         aCompiler.CreateStringFromToken(aStr, rToken.get());
     871         [ +  - ]:      24747 :         if (mbFirst)
     872                 :      24747 :             mbFirst = false;
     873                 :            :         else
     874         [ #  # ]:          0 :             mpRangeStr->append(mcRangeSep);
     875 [ +  - ][ +  - ]:      24747 :         mpRangeStr->append(aStr);
         [ +  - ][ +  - ]
     876                 :      24747 :     }
     877                 :            : 
     878                 :      24747 :     void getString(OUString& rStr)
     879                 :            :     {
     880                 :      24747 :         rStr = mpRangeStr->makeStringAndClear();
     881                 :      24747 :     }
     882                 :            : 
     883                 :            : private:
     884                 :            :     Tokens2RangeString(); // disabled
     885                 :            : 
     886                 :            : private:
     887                 :            :     shared_ptr<OUStringBuffer>  mpRangeStr;
     888                 :            :     ScDocument*         mpDoc;
     889                 :            :     FormulaGrammar::Grammar  meGrammar;
     890                 :            :     sal_Unicode         mcRangeSep;
     891                 :            :     bool                mbFirst;
     892                 :            : };
     893                 :            : 
     894                 :            : /**
     895                 :            :  * Function object to convert a list of tokens into a string form suitable
     896                 :            :  * for ODF export.  In ODF, a range is expressed as
     897                 :            :  *
     898                 :            :  *   (start cell address):(end cell address)
     899                 :            :  *
     900                 :            :  * and each address doesn't include any '$' symbols.
     901                 :            :  */
     902                 :        228 : class Tokens2RangeStringXML : public unary_function<ScTokenRef, void>
     903                 :            : {
     904                 :            : public:
     905                 :         57 :     Tokens2RangeStringXML(ScDocument* pDoc) :
     906                 :         57 :         mpRangeStr(new OUStringBuffer),
     907                 :            :         mpDoc(pDoc),
     908                 :            :         mcRangeSep(' '),
     909                 :            :         mcAddrSep(':'),
     910                 :        114 :         mbFirst(true)
     911                 :            :     {
     912                 :         57 :     }
     913                 :            : 
     914                 :        114 :     Tokens2RangeStringXML(const Tokens2RangeStringXML& r) :
     915                 :            :         mpRangeStr(r.mpRangeStr),
     916                 :            :         mpDoc(r.mpDoc),
     917                 :            :         mcRangeSep(r.mcRangeSep),
     918                 :            :         mcAddrSep(r.mcAddrSep),
     919                 :        114 :         mbFirst(r.mbFirst)
     920                 :            :     {
     921                 :        114 :     }
     922                 :            : 
     923                 :         57 :     void operator() (const ScTokenRef& rToken)
     924                 :            :     {
     925         [ +  - ]:         57 :         if (mbFirst)
     926                 :         57 :             mbFirst = false;
     927                 :            :         else
     928         [ #  # ]:          0 :             mpRangeStr->append(mcRangeSep);
     929                 :            : 
     930                 :         57 :         ScTokenRef aStart, aEnd;
     931         [ +  - ]:         57 :         bool bValidToken = splitRangeToken(rToken, aStart, aEnd);
     932                 :            :         OSL_ENSURE(bValidToken, "invalid token");
     933         [ -  + ]:         57 :         if (!bValidToken)
     934                 :         57 :             return;
     935         [ +  - ]:         57 :         ScCompiler aCompiler(mpDoc, ScAddress(0,0,0));
     936         [ +  - ]:         57 :         aCompiler.SetGrammar(FormulaGrammar::GRAM_ENGLISH);
     937                 :            :         {
     938         [ +  - ]:         57 :             String aStr;
     939         [ +  - ]:         57 :             aCompiler.CreateStringFromToken(aStr, aStart.get());
     940 [ +  - ][ +  - ]:         57 :             mpRangeStr->append(aStr);
                 [ +  - ]
     941                 :            :         }
     942         [ +  - ]:         57 :         mpRangeStr->append(mcAddrSep);
     943                 :            :         {
     944         [ +  - ]:         57 :             String aStr;
     945         [ +  - ]:         57 :             aCompiler.CreateStringFromToken(aStr, aEnd.get());
     946 [ +  - ][ +  - ]:         57 :             mpRangeStr->append(aStr);
                 [ +  - ]
     947 [ +  - ][ +  - ]:         57 :         }
         [ -  + ][ +  - ]
                 [ +  - ]
     948                 :            :     }
     949                 :            : 
     950                 :         57 :     void getString(OUString& rStr)
     951                 :            :     {
     952                 :         57 :         rStr = mpRangeStr->makeStringAndClear();
     953                 :         57 :     }
     954                 :            : 
     955                 :            : private:
     956                 :            :     Tokens2RangeStringXML(); // disabled
     957                 :            : 
     958                 :         57 :     bool splitRangeToken(const ScTokenRef& pToken, ScTokenRef& rStart, ScTokenRef& rEnd) const
     959                 :            :     {
     960                 :            :         ScComplexRefData aData;
     961         [ +  - ]:         57 :         bool bIsRefToken = ScRefTokenHelper::getDoubleRefDataFromToken(aData, pToken);
     962                 :            :         OSL_ENSURE(bIsRefToken, "invalid token");
     963         [ -  + ]:         57 :         if (!bIsRefToken)
     964                 :          0 :             return false;
     965         [ +  - ]:         57 :         bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
     966 [ -  + ][ #  # ]:         57 :         sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
     967 [ -  + ][ #  # ]:         57 :         String aTabName = bExternal ? pToken->GetString() : String();
         [ #  # ][ +  - ]
     968                 :            : 
     969                 :            :         // In saving to XML, we don't prepend address with '$'.
     970                 :         57 :         setRelative(aData.Ref1);
     971                 :         57 :         setRelative(aData.Ref2);
     972                 :            : 
     973                 :            :         // In XML, the end range must explicitly specify sheet name.
     974                 :         57 :         aData.Ref2.SetFlag3D(true);
     975                 :            : 
     976         [ -  + ]:         57 :         if (bExternal)
     977 [ #  # ][ #  # ]:          0 :             rStart.reset(new ScExternalSingleRefToken(nFileId, aTabName, aData.Ref1));
                 [ #  # ]
     978                 :            :         else
     979 [ +  - ][ +  - ]:         57 :             rStart.reset(new ScSingleRefToken(aData.Ref1));
                 [ +  - ]
     980                 :            : 
     981         [ -  + ]:         57 :         if (bExternal)
     982 [ #  # ][ #  # ]:          0 :             rEnd.reset(new ScExternalSingleRefToken(nFileId, aTabName, aData.Ref2));
                 [ #  # ]
     983                 :            :         else
     984 [ +  - ][ +  - ]:         57 :             rEnd.reset(new ScSingleRefToken(aData.Ref2));
                 [ +  - ]
     985         [ +  - ]:         57 :         return true;
     986                 :            :     }
     987                 :            : 
     988                 :        114 :     void setRelative(ScSingleRefData& rData) const
     989                 :            :     {
     990                 :        114 :         rData.SetColRel(true);
     991                 :        114 :         rData.SetRowRel(true);
     992                 :        114 :         rData.SetTabRel(true);
     993                 :        114 :     }
     994                 :            : 
     995                 :            : private:
     996                 :            :     shared_ptr<OUStringBuffer>  mpRangeStr;
     997                 :            :     ScDocument*         mpDoc;
     998                 :            :     sal_Unicode         mcRangeSep;
     999                 :            :     sal_Unicode         mcAddrSep;
    1000                 :            :     bool                mbFirst;
    1001                 :            : };
    1002                 :            : 
    1003                 :      24747 : void lcl_convertTokensToString(OUString& rStr, const vector<ScTokenRef>& rTokens, ScDocument* pDoc)
    1004                 :            : {
    1005         [ +  - ]:      24747 :     const sal_Unicode cRangeSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    1006         [ +  - ]:      24747 :     FormulaGrammar::Grammar eGrammar = pDoc->GetGrammar();
    1007         [ +  - ]:      24747 :     Tokens2RangeString func(pDoc, eGrammar, cRangeSep);
    1008 [ +  - ][ +  - ]:      24747 :     func = ::std::for_each(rTokens.begin(), rTokens.end(), func);
         [ +  - ][ +  - ]
                 [ +  - ]
    1009 [ +  - ][ +  - ]:      24747 :     func.getString(rStr);
    1010                 :      24747 : }
    1011                 :            : 
    1012                 :            : } // anonymous namespace
    1013                 :            : 
    1014                 :            : // DataProvider ==============================================================
    1015                 :            : 
    1016                 :         14 : ScChart2DataProvider::ScChart2DataProvider( ScDocument* pDoc )
    1017                 :            :     : m_pDocument( pDoc)
    1018                 :            :     , m_aPropSet(lcl_GetDataProviderPropertyMap())
    1019 [ +  - ][ +  - ]:         14 :     , m_bIncludeHiddenCells( sal_True)
                 [ +  - ]
    1020                 :            : {
    1021         [ +  - ]:         14 :     if ( m_pDocument )
    1022         [ +  - ]:         14 :         m_pDocument->AddUnoObject( *this);
    1023                 :         14 : }
    1024                 :            : 
    1025 [ +  - ][ +  - ]:         14 : ScChart2DataProvider::~ScChart2DataProvider()
    1026                 :            : {
    1027         [ +  + ]:         14 :     if ( m_pDocument )
    1028         [ +  - ]:          1 :         m_pDocument->RemoveUnoObject( *this);
    1029         [ -  + ]:         28 : }
    1030                 :            : 
    1031                 :            : 
    1032                 :         77 : void ScChart2DataProvider::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
    1033                 :            : {
    1034   [ +  -  +  + ]:        154 :     if ( rHint.ISA( SfxSimpleHint ) &&
                 [ +  + ]
    1035                 :         77 :             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    1036                 :            :     {
    1037                 :         13 :         m_pDocument = NULL;
    1038                 :            :     }
    1039                 :         77 : }
    1040                 :            : 
    1041                 :          0 : ::sal_Bool SAL_CALL ScChart2DataProvider::createDataSourcePossible( const uno::Sequence< beans::PropertyValue >& aArguments )
    1042                 :            :     throw (uno::RuntimeException)
    1043                 :            : {
    1044         [ #  # ]:          0 :     SolarMutexGuard aGuard;
    1045         [ #  # ]:          0 :     if( ! m_pDocument )
    1046                 :          0 :         return false;
    1047                 :            : 
    1048                 :          0 :     rtl::OUString aRangeRepresentation;
    1049         [ #  # ]:          0 :     for(sal_Int32 i = 0; i < aArguments.getLength(); ++i)
    1050                 :            :     {
    1051                 :          0 :         rtl::OUString sName(aArguments[i].Name);
    1052         [ #  # ]:          0 :         if ( aArguments[i].Name == "CellRangeRepresentation" )
    1053                 :            :         {
    1054                 :          0 :             aArguments[i].Value >>= aRangeRepresentation;
    1055                 :            :         }
    1056                 :          0 :     }
    1057                 :            : 
    1058         [ #  # ]:          0 :     vector<ScTokenRef> aTokens;
    1059         [ #  # ]:          0 :     const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    1060                 :            :     ScRefTokenHelper::compileRangeRepresentation(
    1061 [ #  # ][ #  # ]:          0 :         aTokens, aRangeRepresentation, m_pDocument, cSep, m_pDocument->GetGrammar());
    1062         [ #  # ]:          0 :     return !aTokens.empty();
    1063                 :            : }
    1064                 :            : 
    1065                 :            : namespace
    1066                 :            : {
    1067                 :            : 
    1068                 :            : SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1069                 :       3868 : Reference< chart2::data::XLabeledDataSequence > lcl_createLabeledDataSequenceFromTokens(
    1070                 :            :     auto_ptr< vector< ScTokenRef > > pValueTokens, auto_ptr< vector< ScTokenRef > > pLabelTokens,
    1071                 :            :     ScDocument* pDoc, const Reference< chart2::data::XDataProvider >& xDP, bool bIncludeHiddenCells )
    1072                 :            : {
    1073                 :       3868 :     Reference< chart2::data::XLabeledDataSequence >  xResult;
    1074 [ +  + ][ +  - ]:       3868 :     bool bHasValues = pValueTokens.get() && !pValueTokens->empty();
    1075 [ +  + ][ +  + ]:       3868 :     bool bHasLabel = pLabelTokens.get() && !pLabelTokens->empty();
    1076 [ +  + ][ +  - ]:       3868 :     if( bHasValues || bHasLabel )
    1077                 :            :     {
    1078                 :            :         try
    1079                 :            :         {
    1080         [ +  - ]:       3868 :             Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
    1081         [ +  - ]:       3868 :             if ( xContext.is() )
    1082                 :            :             {
    1083 [ +  - ][ +  - ]:       7736 :                 xResult.set( xContext->getServiceManager()->createInstanceWithContext(
                 [ +  - ]
    1084                 :            :                     ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart2.data.LabeledDataSequence")),
    1085 [ +  - ][ +  - ]:       3868 :                         xContext ), uno::UNO_QUERY_THROW );
                 [ +  - ]
    1086                 :            :             }
    1087         [ +  + ]:       3868 :             if ( bHasValues )
    1088                 :            :             {
    1089 [ +  - ][ +  - ]:       3866 :                 Reference< chart2::data::XDataSequence > xSeq( new ScChart2DataSequence( pDoc, xDP, pValueTokens.release(), bIncludeHiddenCells ) );
                 [ +  - ]
    1090 [ +  - ][ +  - ]:       3866 :                 xResult->setValues( xSeq );
    1091                 :            :             }
    1092         [ +  + ]:       3868 :             if ( bHasLabel )
    1093                 :            :             {
    1094 [ +  - ][ +  - ]:        886 :                 Reference< chart2::data::XDataSequence > xLabelSeq( new ScChart2DataSequence( pDoc, xDP, pLabelTokens.release(), bIncludeHiddenCells ) );
                 [ +  - ]
    1095 [ +  - ][ +  - ]:        886 :                 xResult->setLabel( xLabelSeq );
    1096         [ #  # ]:       3868 :             }
    1097                 :            :         }
    1098         [ #  # ]:          0 :         catch( const uno::Exception& )
    1099                 :            :         {
    1100                 :            :         }
    1101                 :            :     }
    1102                 :       3868 :     return xResult;
    1103                 :            : }
    1104                 :            : SAL_WNODEPRECATED_DECLARATIONS_POP
    1105                 :            : 
    1106                 :            : //----------------------------------------------------
    1107                 :            : /**
    1108                 :            :  * Check the current list of reference tokens, and add the upper left
    1109                 :            :  * corner of the minimum range that encloses all ranges if certain
    1110                 :            :  * conditions are met.
    1111                 :            :  *
    1112                 :            :  * @param rRefTokens list of reference tokens
    1113                 :            :  *
    1114                 :            :  * @return true if the corner was added, false otherwise.
    1115                 :            :  */
    1116                 :         68 : bool lcl_addUpperLeftCornerIfMissing(vector<ScTokenRef>& rRefTokens,
    1117                 :            :             SCROW nCornerRowCount=1, SCCOL nCornerColumnCount=1)
    1118                 :            : {
    1119                 :            :     using ::std::max;
    1120                 :            :     using ::std::min;
    1121                 :            : 
    1122         [ -  + ]:         68 :     if (rRefTokens.empty())
    1123                 :          0 :         return false;
    1124                 :            : 
    1125                 :         68 :     SCCOL nMinCol = MAXCOLCOUNT;
    1126                 :         68 :     SCROW nMinRow = MAXROWCOUNT;
    1127                 :         68 :     SCCOL nMaxCol = 0;
    1128                 :         68 :     SCROW nMaxRow = 0;
    1129                 :         68 :     SCTAB nTab    = 0;
    1130                 :            : 
    1131                 :         68 :     sal_uInt16 nFileId = 0;
    1132         [ +  - ]:         68 :     String aExtTabName;
    1133                 :         68 :     bool bExternal = false;
    1134                 :            : 
    1135 [ +  - ][ +  - ]:         68 :     vector<ScTokenRef>::const_iterator itr = rRefTokens.begin(), itrEnd = rRefTokens.end();
    1136                 :            : 
    1137                 :            :     // Get the first ref token.
    1138                 :         68 :     ScTokenRef pToken = *itr;
    1139   [ +  +  -  -  :         68 :     switch (pToken->GetType())
                      - ]
    1140                 :            :     {
    1141                 :            :         case svSingleRef:
    1142                 :            :         {
    1143         [ +  - ]:          2 :             const ScSingleRefData& rData = pToken->GetSingleRef();
    1144                 :          2 :             nMinCol = rData.nCol;
    1145                 :          2 :             nMinRow = rData.nRow;
    1146                 :          2 :             nMaxCol = rData.nCol;
    1147                 :          2 :             nMaxRow = rData.nRow;
    1148                 :          2 :             nTab = rData.nTab;
    1149                 :            :         }
    1150                 :          2 :         break;
    1151                 :            :         case svDoubleRef:
    1152                 :            :         {
    1153         [ +  - ]:         66 :             const ScComplexRefData& rData = pToken->GetDoubleRef();
    1154         [ +  - ]:         66 :             nMinCol = min(rData.Ref1.nCol, rData.Ref2.nCol);
    1155         [ +  - ]:         66 :             nMinRow = min(rData.Ref1.nRow, rData.Ref2.nRow);
    1156         [ +  - ]:         66 :             nMaxCol = max(rData.Ref1.nCol, rData.Ref2.nCol);
    1157         [ +  - ]:         66 :             nMaxRow = max(rData.Ref1.nRow, rData.Ref2.nRow);
    1158                 :         66 :             nTab = rData.Ref1.nTab;
    1159                 :            :         }
    1160                 :         66 :         break;
    1161                 :            :         case svExternalSingleRef:
    1162                 :            :         {
    1163         [ #  # ]:          0 :             const ScSingleRefData& rData = pToken->GetSingleRef();
    1164                 :          0 :             nMinCol = rData.nCol;
    1165                 :          0 :             nMinRow = rData.nRow;
    1166                 :          0 :             nMaxCol = rData.nCol;
    1167                 :          0 :             nMaxRow = rData.nRow;
    1168                 :          0 :             nTab = rData.nTab;
    1169         [ #  # ]:          0 :             nFileId = pToken->GetIndex();
    1170 [ #  # ][ #  # ]:          0 :             aExtTabName = pToken->GetString();
    1171                 :          0 :             bExternal = true;
    1172                 :            :         }
    1173                 :          0 :         break;
    1174                 :            :         case svExternalDoubleRef:
    1175                 :            :         {
    1176         [ #  # ]:          0 :             const ScComplexRefData& rData = pToken->GetDoubleRef();
    1177         [ #  # ]:          0 :             nMinCol = min(rData.Ref1.nCol, rData.Ref2.nCol);
    1178         [ #  # ]:          0 :             nMinRow = min(rData.Ref1.nRow, rData.Ref2.nRow);
    1179         [ #  # ]:          0 :             nMaxCol = max(rData.Ref1.nCol, rData.Ref2.nCol);
    1180         [ #  # ]:          0 :             nMaxRow = max(rData.Ref1.nRow, rData.Ref2.nRow);
    1181                 :          0 :             nTab = rData.Ref1.nTab;
    1182         [ #  # ]:          0 :             nFileId = pToken->GetIndex();
    1183 [ #  # ][ #  # ]:          0 :             aExtTabName = pToken->GetString();
    1184                 :          0 :             bExternal = true;
    1185                 :            :         }
    1186                 :          0 :         break;
    1187                 :            :         default:
    1188                 :            :             ;
    1189                 :            :     }
    1190                 :            : 
    1191                 :            :     // Determine the minimum range enclosing all data ranges.  Also make sure
    1192                 :            :     // that they are all on the same table.
    1193                 :            : 
    1194 [ +  - ][ -  + ]:         68 :     for (++itr; itr != itrEnd; ++itr)
    1195                 :            :     {
    1196         [ #  # ]:          0 :         pToken = *itr;
    1197   [ #  #  #  #  :          0 :         switch (pToken->GetType())
                      # ]
    1198                 :            :         {
    1199                 :            :             case svSingleRef:
    1200                 :            :             {
    1201         [ #  # ]:          0 :                 const ScSingleRefData& rData = pToken->GetSingleRef();
    1202                 :            : 
    1203         [ #  # ]:          0 :                 nMinCol = min(nMinCol, rData.nCol);
    1204         [ #  # ]:          0 :                 nMinRow = min(nMinRow, rData.nRow);
    1205         [ #  # ]:          0 :                 nMaxCol = max(nMaxCol, rData.nCol);
    1206         [ #  # ]:          0 :                 nMaxRow = max(nMaxRow, rData.nRow);
    1207 [ #  # ][ #  # ]:          0 :                 if (nTab != rData.nTab || bExternal)
    1208                 :          0 :                     return false;
    1209                 :            :             }
    1210                 :          0 :             break;
    1211                 :            :             case svDoubleRef:
    1212                 :            :             {
    1213         [ #  # ]:          0 :                 const ScComplexRefData& rData = pToken->GetDoubleRef();
    1214                 :            : 
    1215         [ #  # ]:          0 :                 nMinCol = min(nMinCol, rData.Ref1.nCol);
    1216         [ #  # ]:          0 :                 nMinCol = min(nMinCol, rData.Ref2.nCol);
    1217         [ #  # ]:          0 :                 nMinRow = min(nMinRow, rData.Ref1.nRow);
    1218         [ #  # ]:          0 :                 nMinRow = min(nMinRow, rData.Ref2.nRow);
    1219                 :            : 
    1220         [ #  # ]:          0 :                 nMaxCol = max(nMaxCol, rData.Ref1.nCol);
    1221         [ #  # ]:          0 :                 nMaxCol = max(nMaxCol, rData.Ref2.nCol);
    1222         [ #  # ]:          0 :                 nMaxRow = max(nMaxRow, rData.Ref1.nRow);
    1223         [ #  # ]:          0 :                 nMaxRow = max(nMaxRow, rData.Ref2.nRow);
    1224                 :            : 
    1225 [ #  # ][ #  # ]:          0 :                 if (nTab != rData.Ref1.nTab || bExternal)
    1226                 :          0 :                     return false;
    1227                 :            :             }
    1228                 :          0 :             break;
    1229                 :            :             case svExternalSingleRef:
    1230                 :            :             {
    1231         [ #  # ]:          0 :                 if (!bExternal)
    1232                 :          0 :                     return false;
    1233                 :            : 
    1234 [ #  # ][ #  # ]:          0 :                 if (nFileId != pToken->GetIndex() || aExtTabName != pToken->GetString())
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1235                 :          0 :                     return false;
    1236                 :            : 
    1237         [ #  # ]:          0 :                 const ScSingleRefData& rData = pToken->GetSingleRef();
    1238                 :            : 
    1239         [ #  # ]:          0 :                 nMinCol = min(nMinCol, rData.nCol);
    1240         [ #  # ]:          0 :                 nMinRow = min(nMinRow, rData.nRow);
    1241         [ #  # ]:          0 :                 nMaxCol = max(nMaxCol, rData.nCol);
    1242         [ #  # ]:          0 :                 nMaxRow = max(nMaxRow, rData.nRow);
    1243                 :            :             }
    1244                 :          0 :             break;
    1245                 :            :             case svExternalDoubleRef:
    1246                 :            :             {
    1247         [ #  # ]:          0 :                 if (!bExternal)
    1248                 :          0 :                     return false;
    1249                 :            : 
    1250 [ #  # ][ #  # ]:          0 :                 if (nFileId != pToken->GetIndex() || aExtTabName != pToken->GetString())
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1251                 :          0 :                     return false;
    1252                 :            : 
    1253         [ #  # ]:          0 :                 const ScComplexRefData& rData = pToken->GetDoubleRef();
    1254                 :            : 
    1255         [ #  # ]:          0 :                 nMinCol = min(nMinCol, rData.Ref1.nCol);
    1256         [ #  # ]:          0 :                 nMinCol = min(nMinCol, rData.Ref2.nCol);
    1257         [ #  # ]:          0 :                 nMinRow = min(nMinRow, rData.Ref1.nRow);
    1258         [ #  # ]:          0 :                 nMinRow = min(nMinRow, rData.Ref2.nRow);
    1259                 :            : 
    1260         [ #  # ]:          0 :                 nMaxCol = max(nMaxCol, rData.Ref1.nCol);
    1261         [ #  # ]:          0 :                 nMaxCol = max(nMaxCol, rData.Ref2.nCol);
    1262         [ #  # ]:          0 :                 nMaxRow = max(nMaxRow, rData.Ref1.nRow);
    1263         [ #  # ]:          0 :                 nMaxRow = max(nMaxRow, rData.Ref2.nRow);
    1264                 :            :             }
    1265                 :          0 :             break;
    1266                 :            :             default:
    1267                 :            :                 ;
    1268                 :            :         }
    1269                 :            :     }
    1270                 :            : 
    1271 [ +  + ][ +  - ]:         68 :     if (nMinRow >= nMaxRow || nMinCol >= nMaxCol ||
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
    1272                 :            :         nMinRow >= MAXROWCOUNT || nMinCol >= MAXCOLCOUNT ||
    1273                 :            :         nMaxRow >= MAXROWCOUNT || nMaxCol >= MAXCOLCOUNT)
    1274                 :            :     {
    1275                 :            :         // Invalid range.  Bail out.
    1276                 :          2 :         return false;
    1277                 :            :     }
    1278                 :            : 
    1279                 :            :     // Check if the following conditions are met:
    1280                 :            :     //
    1281                 :            :     // 1) The upper-left corner cell is not included.
    1282                 :            :     // 2) The three adjacent cells of that corner cell are included.
    1283                 :            : 
    1284                 :         66 :     bool bRight = false, bBottom = false, bDiagonal = false;
    1285 [ +  - ][ +  - ]:         66 :     for (itr = rRefTokens.begin(); itr != itrEnd; ++itr)
                 [ +  - ]
    1286                 :            :     {
    1287         [ +  - ]:         66 :         pToken = *itr;
    1288      [ -  +  - ]:         66 :         switch (pToken->GetType())
    1289                 :            :         {
    1290                 :            :             case svSingleRef:
    1291                 :            :             case svExternalSingleRef:
    1292                 :            :             {
    1293         [ #  # ]:          0 :                 const ScSingleRefData& rData = pToken->GetSingleRef();
    1294 [ #  # ][ #  # ]:          0 :                 if (rData.nCol == nMinCol && rData.nRow == nMinRow)
    1295                 :            :                     // The corner cell is contained.
    1296                 :          0 :                     return false;
    1297                 :            : 
    1298 [ #  # ][ #  # ]:          0 :                 if (rData.nCol == nMinCol+nCornerColumnCount && rData.nRow == nMinRow)
    1299                 :          0 :                     bRight = true;
    1300                 :            : 
    1301 [ #  # ][ #  # ]:          0 :                 if (rData.nCol == nMinCol && rData.nRow == nMinRow+nCornerRowCount)
    1302                 :          0 :                     bBottom = true;
    1303                 :            : 
    1304 [ #  # ][ #  # ]:          0 :                 if (rData.nCol == nMinCol+nCornerColumnCount && rData.nRow == nMinRow+nCornerRowCount)
    1305                 :          0 :                     bDiagonal = true;
    1306                 :            :             }
    1307                 :          0 :             break;
    1308                 :            :             case svDoubleRef:
    1309                 :            :             case svExternalDoubleRef:
    1310                 :            :             {
    1311         [ +  - ]:         66 :                 const ScComplexRefData& rData = pToken->GetDoubleRef();
    1312                 :         66 :                 const ScSingleRefData& r1 = rData.Ref1;
    1313                 :         66 :                 const ScSingleRefData& r2 = rData.Ref2;
    1314 [ +  - ][ +  - ]:         66 :                 if (r1.nCol <= nMinCol && nMinCol <= r2.nCol &&
         [ +  - ][ +  - ]
    1315                 :            :                     r1.nRow <= nMinRow && nMinRow <= r2.nRow)
    1316                 :            :                     // The corner cell is contained.
    1317                 :         66 :                     return false;
    1318                 :            : 
    1319 [ #  # ][ #  # ]:          0 :                 if (r1.nCol <= nMinCol+nCornerColumnCount && nMinCol+nCornerColumnCount <= r2.nCol &&
         [ #  # ][ #  # ]
    1320                 :            :                     r1.nRow <= nMinRow && nMinRow <= r2.nRow)
    1321                 :          0 :                     bRight = true;
    1322                 :            : 
    1323 [ #  # ][ #  # ]:          0 :                 if (r1.nCol <= nMinCol && nMinCol <= r2.nCol &&
         [ #  # ][ #  # ]
    1324                 :            :                     r1.nRow <= nMinRow+nCornerRowCount && nMinRow+nCornerRowCount <= r2.nRow)
    1325                 :          0 :                     bBottom = true;
    1326                 :            : 
    1327 [ #  # ][ #  # ]:          0 :                 if (r1.nCol <= nMinCol+nCornerColumnCount && nMinCol+nCornerColumnCount <= r2.nCol &&
         [ #  # ][ #  # ]
    1328                 :            :                     r1.nRow <= nMinRow+nCornerRowCount && nMinRow+nCornerRowCount <= r2.nRow)
    1329                 :          0 :                     bDiagonal = true;
    1330                 :            :             }
    1331                 :          0 :             break;
    1332                 :            :             default:
    1333                 :            :                 ;
    1334                 :            :         }
    1335                 :            :     }
    1336                 :            : 
    1337 [ #  # ][ #  # ]:          0 :     if (!bRight || !bBottom || !bDiagonal)
                 [ #  # ]
    1338                 :            :         // Not all the adjacent cells are included.  Bail out.
    1339                 :          0 :         return false;
    1340                 :            : 
    1341                 :            :     ScSingleRefData aData;
    1342                 :          0 :     aData.InitFlags();
    1343                 :          0 :     aData.SetFlag3D(true);
    1344                 :          0 :     aData.SetColRel(false);
    1345                 :          0 :     aData.SetRowRel(false);
    1346                 :          0 :     aData.SetTabRel(false);
    1347                 :          0 :     aData.nCol = nMinCol;
    1348                 :          0 :     aData.nRow = nMinRow;
    1349                 :          0 :     aData.nTab = nTab;
    1350                 :            : 
    1351 [ #  # ][ #  # ]:          0 :     if( nCornerRowCount==1 && nCornerColumnCount==1 )
    1352                 :            :     {
    1353         [ #  # ]:          0 :         if (bExternal)
    1354                 :            :         {
    1355                 :            :             ScTokenRef pCorner(
    1356 [ #  # ][ #  # ]:          0 :                 new ScExternalSingleRefToken(nFileId, aExtTabName, aData));
    1357 [ #  # ][ #  # ]:          0 :             ScRefTokenHelper::join(rRefTokens, pCorner);
    1358                 :            :         }
    1359                 :            :         else
    1360                 :            :         {
    1361 [ #  # ][ #  # ]:          0 :             ScTokenRef pCorner(new ScSingleRefToken(aData));
    1362 [ #  # ][ #  # ]:          0 :             ScRefTokenHelper::join(rRefTokens, pCorner);
    1363                 :          0 :         }
    1364                 :            :     }
    1365                 :            :     else
    1366                 :            :     {
    1367                 :          0 :         ScSingleRefData aDataEnd(aData);
    1368                 :          0 :         aDataEnd.nCol += (nCornerColumnCount-1);
    1369                 :          0 :         aDataEnd.nRow += (nCornerRowCount-1);
    1370                 :            :         ScComplexRefData r;
    1371                 :          0 :         r.Ref1=aData;
    1372                 :          0 :         r.Ref2=aDataEnd;
    1373         [ #  # ]:          0 :         if (bExternal)
    1374                 :            :         {
    1375                 :            :             ScTokenRef pCorner(
    1376 [ #  # ][ #  # ]:          0 :                 new ScExternalDoubleRefToken(nFileId, aExtTabName, r));
    1377 [ #  # ][ #  # ]:          0 :             ScRefTokenHelper::join(rRefTokens, pCorner);
    1378                 :            :         }
    1379                 :            :         else
    1380                 :            :         {
    1381 [ #  # ][ #  # ]:          0 :             ScTokenRef pCorner(new ScDoubleRefToken(r));
    1382 [ #  # ][ #  # ]:          0 :             ScRefTokenHelper::join(rRefTokens, pCorner);
    1383                 :            :         }
    1384                 :            :     }
    1385                 :            : 
    1386 [ +  - ][ +  - ]:         68 :     return true;
    1387                 :            : }
    1388                 :            : 
    1389                 :            : class ShrinkRefTokenToDataRange : std::unary_function<ScTokenRef, void>
    1390                 :            : {
    1391                 :            :     ScDocument* mpDoc;
    1392                 :            : public:
    1393                 :        637 :     ShrinkRefTokenToDataRange(ScDocument* pDoc) : mpDoc(pDoc) {}
    1394                 :        637 :     void operator() (ScTokenRef& rRef)
    1395                 :            :     {
    1396 [ +  - ][ +  - ]:        637 :         if (ScRefTokenHelper::isExternalRef(rRef))
    1397                 :            :             return;
    1398                 :            : 
    1399                 :            :         // Don't assume an ScDoubleRefToken if it isn't. It can be at least an
    1400                 :            :         // ScSingleRefToken, then there isn't anything to shrink.
    1401         [ +  + ]:        637 :         if (rRef->GetType() != svDoubleRef)
    1402                 :            :             return;
    1403                 :            : 
    1404         [ +  - ]:        623 :         ScComplexRefData& rData = rRef->GetDoubleRef();
    1405                 :        623 :         ScSingleRefData& s = rData.Ref1;
    1406                 :        623 :         ScSingleRefData& e = rData.Ref2;
    1407                 :            : 
    1408                 :        623 :         SCCOL nMinCol = MAXCOL, nMaxCol = 0;
    1409                 :        623 :         SCROW nMinRow = MAXROW, nMaxRow = 0;
    1410                 :            : 
    1411                 :            :         // Determine the smallest range that encompasses the data ranges of all sheets.
    1412                 :        623 :         SCTAB nTab1 = s.nTab, nTab2 = e.nTab;
    1413         [ +  + ]:       1246 :         for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
    1414                 :            :         {
    1415                 :        623 :             SCCOL nCol1 = 0, nCol2 = MAXCOL;
    1416                 :        623 :             SCROW nRow1 = 0, nRow2 = MAXROW;
    1417         [ +  - ]:        623 :             mpDoc->ShrinkToDataArea(nTab, nCol1, nRow1, nCol2, nRow2);
    1418         [ +  - ]:        623 :             nMinCol = std::min(nMinCol, nCol1);
    1419         [ +  - ]:        623 :             nMinRow = std::min(nMinRow, nRow1);
    1420         [ +  - ]:        623 :             nMaxCol = std::max(nMaxCol, nCol2);
    1421         [ +  - ]:        623 :             nMaxRow = std::max(nMaxRow, nRow2);
    1422                 :            :         }
    1423                 :            : 
    1424                 :            :         // Shrink range to the data range if applicable.
    1425         [ -  + ]:        623 :         if (s.nCol < nMinCol)
    1426                 :          0 :             s.nCol = nMinCol;
    1427         [ -  + ]:        623 :         if (s.nRow < nMinRow)
    1428                 :          0 :             s.nRow = nMinRow;
    1429         [ -  + ]:        623 :         if (e.nCol > nMaxCol)
    1430                 :          0 :             e.nCol = nMaxCol;
    1431         [ -  + ]:        623 :         if (e.nRow > nMaxRow)
    1432                 :        637 :             e.nRow = nMaxRow;
    1433                 :            :     }
    1434                 :            : };
    1435                 :            : 
    1436                 :        637 : void shrinkToDataRange(ScDocument* pDoc, vector<ScTokenRef>& rRefTokens)
    1437                 :            : {
    1438         [ +  - ]:        637 :     std::for_each(rRefTokens.begin(), rRefTokens.end(), ShrinkRefTokenToDataRange(pDoc));
    1439                 :        637 : }
    1440                 :            : 
    1441                 :            : }
    1442                 :            : 
    1443                 :            : uno::Reference< chart2::data::XDataSource> SAL_CALL
    1444                 :        619 : ScChart2DataProvider::createDataSource(
    1445                 :            :     const uno::Sequence< beans::PropertyValue >& aArguments )
    1446                 :            :     throw( lang::IllegalArgumentException, uno::RuntimeException)
    1447                 :            : {
    1448         [ +  - ]:        619 :     SolarMutexGuard aGuard;
    1449         [ -  + ]:        619 :     if ( ! m_pDocument )
    1450         [ #  # ]:          0 :         throw uno::RuntimeException();
    1451                 :            : 
    1452                 :        619 :     uno::Reference< chart2::data::XDataSource> xResult;
    1453                 :        619 :     bool bLabel = true;
    1454                 :        619 :     bool bCategories = false;
    1455                 :        619 :     bool bOrientCol = true;
    1456                 :        619 :     ::rtl::OUString aRangeRepresentation;
    1457         [ +  - ]:        619 :     uno::Sequence< sal_Int32 > aSequenceMapping;
    1458         [ +  + ]:       3150 :     for(sal_Int32 i = 0; i < aArguments.getLength(); ++i)
    1459                 :            :     {
    1460                 :       2531 :         rtl::OUString sName(aArguments[i].Name);
    1461         [ +  + ]:       2531 :         if ( aArguments[i].Name == "DataRowSource" )
    1462                 :            :         {
    1463                 :        619 :             chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS;
    1464 [ +  - ][ -  + ]:        619 :             if( ! (aArguments[i].Value >>= eSource))
    1465                 :            :             {
    1466                 :          0 :                 sal_Int32 nSource(0);
    1467         [ #  # ]:          0 :                 if( aArguments[i].Value >>= nSource )
    1468                 :          0 :                     eSource = (static_cast< chart::ChartDataRowSource >( nSource ));
    1469                 :            :             }
    1470                 :        619 :             bOrientCol = (eSource == chart::ChartDataRowSource_COLUMNS);
    1471                 :            :         }
    1472         [ +  + ]:       1912 :         else if ( aArguments[i].Name == "FirstCellAsLabel" )
    1473                 :            :         {
    1474         [ +  - ]:        619 :             bLabel = ::cppu::any2bool(aArguments[i].Value);
    1475                 :            :         }
    1476         [ +  + ]:       1293 :         else if ( aArguments[i].Name == "HasCategories" )
    1477                 :            :         {
    1478         [ +  - ]:        619 :             bCategories = ::cppu::any2bool(aArguments[i].Value);
    1479                 :            :         }
    1480         [ +  + ]:        674 :         else if ( aArguments[i].Name == "CellRangeRepresentation" )
    1481                 :            :         {
    1482                 :        619 :             aArguments[i].Value >>= aRangeRepresentation;
    1483                 :            :         }
    1484         [ -  + ]:         55 :         else if ( aArguments[i].Name == "SequenceMapping" )
    1485                 :            :         {
    1486         [ #  # ]:          0 :             aArguments[i].Value >>= aSequenceMapping;
    1487                 :            :         }
    1488                 :       2531 :     }
    1489                 :            : 
    1490         [ +  - ]:        619 :     vector<ScTokenRef> aRefTokens;
    1491         [ +  - ]:        619 :     const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    1492                 :            :     ScRefTokenHelper::compileRangeRepresentation(
    1493 [ +  - ][ +  - ]:        619 :         aRefTokens, aRangeRepresentation, m_pDocument, cSep, m_pDocument->GetGrammar());
    1494         [ -  + ]:        619 :     if (aRefTokens.empty())
    1495                 :            :         // Invalid range representation.  Bail out.
    1496         [ #  # ]:          0 :         throw lang::IllegalArgumentException();
    1497                 :            : 
    1498         [ +  - ]:        619 :     shrinkToDataRange(m_pDocument, aRefTokens);
    1499                 :            : 
    1500         [ +  + ]:        619 :     if (bLabel)
    1501         [ +  - ]:         68 :         lcl_addUpperLeftCornerIfMissing(aRefTokens); //#i90669#
    1502                 :            : 
    1503         [ +  + ]:        619 :     bool bColHeaders = (bOrientCol ? bLabel : bCategories );
    1504         [ +  + ]:        619 :     bool bRowHeaders = (bOrientCol ? bCategories : bLabel );
    1505                 :            : 
    1506         [ +  - ]:        619 :     Chart2Positioner aChPositioner(m_pDocument, aRefTokens);
    1507                 :        619 :     aChPositioner.setHeaders(bColHeaders, bRowHeaders);
    1508                 :            : 
    1509         [ +  - ]:        619 :     const Chart2PositionMap* pChartMap = aChPositioner.getPositionMap();
    1510         [ +  - ]:        619 :     if (!pChartMap)
    1511                 :            :         // No chart position map instance.  Bail out.
    1512                 :            :         return xResult;
    1513                 :            : 
    1514                 :        619 :     ScChart2DataSource* pDS = NULL;
    1515         [ +  - ]:        619 :     ::std::list< Reference< chart2::data::XLabeledDataSequence > > aSeqs;
    1516                 :            : 
    1517                 :            :     // Fill Categories
    1518         [ +  + ]:        619 :     if( bCategories )
    1519                 :            :     {
    1520                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1521                 :         68 :         auto_ptr< vector<ScTokenRef> > pValueTokens(NULL);
    1522                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
    1523         [ +  + ]:         68 :         if (bOrientCol)
    1524         [ +  - ]:         64 :             pValueTokens.reset(pChartMap->getAllRowHeaderRanges());
    1525                 :            :         else
    1526         [ +  - ]:          4 :             pValueTokens.reset(pChartMap->getAllColHeaderRanges());
    1527                 :            : 
    1528                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1529                 :         68 :         auto_ptr< vector<ScTokenRef> > pLabelTokens(NULL);
    1530         [ +  - ]:         68 :             pLabelTokens.reset(pChartMap->getLeftUpperCornerRanges());
    1531                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
    1532                 :            : 
    1533                 :            :         Reference< chart2::data::XLabeledDataSequence > xCategories = lcl_createLabeledDataSequenceFromTokens(
    1534 [ +  - ][ +  - ]:         68 :             pValueTokens, pLabelTokens, m_pDocument, this, m_bIncludeHiddenCells ); //ownership of pointers is transfered!
    1535         [ +  - ]:         68 :         if ( xCategories.is() )
    1536                 :            :         {
    1537         [ +  - ]:         68 :             aSeqs.push_back( xCategories );
    1538                 :         68 :         }
    1539                 :            :     }
    1540                 :            : 
    1541                 :            :     // Fill Serieses (values and label)
    1542         [ +  + ]:        619 :     sal_Int32 nCount = bOrientCol ? pChartMap->getDataColCount() : pChartMap->getDataRowCount();
    1543         [ +  + ]:       4419 :     for (sal_Int32 i = 0; i < nCount; ++i)
    1544                 :            :     {
    1545                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1546                 :       3800 :         auto_ptr< vector<ScTokenRef> > pValueTokens(NULL);
    1547                 :       3800 :         auto_ptr< vector<ScTokenRef> > pLabelTokens(NULL);
    1548                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
    1549         [ +  + ]:       3800 :         if (bOrientCol)
    1550                 :            :         {
    1551         [ +  - ]:       3054 :             pValueTokens.reset(pChartMap->getDataColRanges(static_cast<SCCOL>(i)));
    1552         [ +  - ]:       3054 :             pLabelTokens.reset(pChartMap->getColHeaderRanges(static_cast<SCCOL>(i)));
    1553                 :            :         }
    1554                 :            :         else
    1555                 :            :         {
    1556         [ +  - ]:        746 :             pValueTokens.reset(pChartMap->getDataRowRanges(static_cast<SCROW>(i)));
    1557         [ +  - ]:        746 :             pLabelTokens.reset(pChartMap->getRowHeaderRanges(static_cast<SCROW>(i)));
    1558                 :            :         }
    1559                 :            :         Reference< chart2::data::XLabeledDataSequence > xChartSeries = lcl_createLabeledDataSequenceFromTokens(
    1560 [ +  - ][ +  - ]:       3800 :             pValueTokens, pLabelTokens, m_pDocument, this, m_bIncludeHiddenCells ); //ownership of pointers is transfered!
    1561 [ +  - ][ +  - ]:       3800 :         if ( xChartSeries.is() && xChartSeries->getValues().is() && xChartSeries->getValues()->getData().getLength() )
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
           [ +  +  #  #  
             #  #  #  # ]
                 [ +  - ]
    1562                 :            :         {
    1563         [ +  - ]:       3629 :             aSeqs.push_back( xChartSeries );
    1564                 :            :         }
    1565                 :       3800 :     }
    1566                 :            : 
    1567         [ +  - ]:        619 :     pDS = new ScChart2DataSource(m_pDocument);
    1568                 :        619 :     ::std::list< Reference< chart2::data::XLabeledDataSequence > >::iterator aItr( aSeqs.begin() );
    1569                 :        619 :     ::std::list< Reference< chart2::data::XLabeledDataSequence > >::iterator aEndItr( aSeqs.end() );
    1570                 :            : 
    1571                 :            :     //reorder labeled sequences according to aSequenceMapping
    1572         [ +  - ]:        619 :     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aSeqVector;
    1573         [ +  + ]:       4316 :     while(aItr != aEndItr)
    1574                 :            :     {
    1575         [ +  - ]:       3697 :         aSeqVector.push_back(*aItr);
    1576                 :       3697 :         ++aItr;
    1577                 :            :     }
    1578                 :            : 
    1579         [ +  - ]:        619 :     ::std::map< sal_Int32, Reference< chart2::data::XLabeledDataSequence > > aSequenceMap;
    1580         [ -  + ]:        619 :     for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ )
    1581                 :            :     {
    1582                 :            :         // note: assuming that the values in the sequence mapping are always non-negative
    1583         [ #  # ]:          0 :         ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::size_type nOldIndex( static_cast< sal_uInt32 >( aSequenceMapping[nNewIndex] ) );
    1584         [ #  # ]:          0 :         if( nOldIndex < aSeqVector.size() )
    1585                 :            :         {
    1586         [ #  # ]:          0 :             pDS->AddLabeledSequence( aSeqVector[nOldIndex] );
    1587         [ #  # ]:          0 :             aSeqVector[nOldIndex] = 0;
    1588                 :            :         }
    1589                 :            :     }
    1590                 :            : 
    1591                 :        619 :     ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aVectorItr( aSeqVector.begin() );
    1592                 :        619 :     ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aVectorEndItr( aSeqVector.end() );
    1593 [ +  - ][ +  + ]:       4316 :     while(aVectorItr != aVectorEndItr)
    1594                 :            :     {
    1595                 :       3697 :         Reference< chart2::data::XLabeledDataSequence > xSeq( *aVectorItr );
    1596         [ +  - ]:       3697 :         if ( xSeq.is() )
    1597                 :            :         {
    1598         [ +  - ]:       3697 :             pDS->AddLabeledSequence( xSeq );
    1599                 :            :         }
    1600                 :       3697 :         ++aVectorItr;
    1601                 :       3697 :     }
    1602                 :            : 
    1603 [ +  - ][ +  - ]:        619 :     xResult.set( pDS );
    1604 [ +  - ][ +  - ]:        619 :     return xResult;
                 [ +  - ]
    1605                 :            : }
    1606                 :            : 
    1607                 :            : namespace
    1608                 :            : {
    1609                 :            : 
    1610                 :            : /**
    1611                 :            :  * Function object to create a list of table numbers from a token list.
    1612                 :            :  */
    1613                 :        220 : class InsertTabNumber : public unary_function<ScTokenRef, void>
    1614                 :            : {
    1615                 :            : public:
    1616                 :         55 :     InsertTabNumber() :
    1617         [ +  - ]:         55 :         mpTabNumList(new list<SCTAB>())
    1618                 :            :     {
    1619                 :         55 :     }
    1620                 :            : 
    1621                 :        110 :     InsertTabNumber(const InsertTabNumber& r) :
    1622                 :        110 :         mpTabNumList(r.mpTabNumList)
    1623                 :            :     {
    1624                 :        110 :     }
    1625                 :            : 
    1626                 :         55 :     void operator() (const ScTokenRef& pToken) const
    1627                 :            :     {
    1628         [ -  + ]:         55 :         if (!ScRefTokenHelper::isRef(pToken))
    1629                 :         55 :             return;
    1630                 :            : 
    1631                 :         55 :         const ScSingleRefData& r = pToken->GetSingleRef();
    1632                 :         55 :         mpTabNumList->push_back(r.nTab);
    1633                 :            :     }
    1634                 :            : 
    1635                 :         55 :     void getList(list<SCTAB>& rList)
    1636                 :            :     {
    1637                 :         55 :         mpTabNumList->swap(rList);
    1638                 :         55 :     }
    1639                 :            : private:
    1640                 :            :     shared_ptr< list<SCTAB> > mpTabNumList;
    1641                 :            : };
    1642                 :            : 
    1643                 :            : class RangeAnalyzer
    1644                 :            : {
    1645                 :            : public:
    1646                 :            :     RangeAnalyzer();
    1647                 :            :     void initRangeAnalyzer( const vector<ScTokenRef>& rTokens );
    1648                 :            :     void analyzeRange( sal_Int32& rnDataInRows, sal_Int32& rnDataInCols,
    1649                 :            :             bool& rbRowSourceAmbiguous ) const;
    1650                 :            :     bool inSameSingleRow( RangeAnalyzer& rOther );
    1651                 :            :     bool inSameSingleColumn( RangeAnalyzer& rOther );
    1652                 :          0 :     SCROW getRowCount() { return mnRowCount; }
    1653                 :          0 :     SCCOL getColumnCount() { return mnColumnCount; }
    1654                 :            : 
    1655                 :            : private:
    1656                 :            :     bool mbEmpty;
    1657                 :            :     bool mbAmbiguous;
    1658                 :            :     SCROW mnRowCount;
    1659                 :            :     SCCOL mnColumnCount;
    1660                 :            : 
    1661                 :            :     SCCOL mnStartColumn;
    1662                 :            :     SCROW mnStartRow;
    1663                 :            : };
    1664                 :            : 
    1665                 :       1610 : RangeAnalyzer::RangeAnalyzer()
    1666                 :            :     : mbEmpty(true)
    1667                 :            :     , mbAmbiguous(false)
    1668                 :            :     , mnRowCount(0)
    1669                 :            :     , mnColumnCount(0)
    1670                 :            :     , mnStartColumn(-1)
    1671                 :       1610 :     , mnStartRow(-1)
    1672                 :            : {
    1673                 :       1610 : }
    1674                 :            : 
    1675                 :       1444 : void RangeAnalyzer::initRangeAnalyzer( const vector<ScTokenRef>& rTokens )
    1676                 :            : {
    1677                 :       1444 :     mnRowCount=0;
    1678                 :       1444 :     mnColumnCount=0;
    1679                 :       1444 :     mnStartColumn = -1;
    1680                 :       1444 :     mnStartRow = -1;
    1681                 :       1444 :     mbAmbiguous=false;
    1682         [ -  + ]:       1444 :     if( rTokens.empty() )
    1683                 :            :     {
    1684                 :          0 :         mbEmpty=true;
    1685                 :       1444 :         return;
    1686                 :            :     }
    1687                 :       1444 :     mbEmpty=false;
    1688                 :            : 
    1689                 :       1444 :     vector<ScTokenRef>::const_iterator itr = rTokens.begin(), itrEnd = rTokens.end();
    1690 [ +  - ][ +  + ]:       2888 :     for (; itr != itrEnd ; ++itr)
    1691                 :            :     {
    1692                 :       1444 :         ScTokenRef aRefToken = *itr;
    1693                 :       1444 :         StackVar eVar = aRefToken->GetType();
    1694 [ -  + ][ +  + ]:       1444 :         if (eVar == svDoubleRef || eVar == svExternalDoubleRef)
    1695                 :            :         {
    1696         [ +  - ]:        694 :             const ScComplexRefData& r = aRefToken->GetDoubleRef();
    1697         [ +  - ]:        694 :             if (r.Ref1.nTab == r.Ref2.nTab)
    1698                 :            :             {
    1699         [ +  - ]:        694 :                 mnColumnCount = std::max<SCCOL>( mnColumnCount, static_cast<SCCOL>(abs(r.Ref2.nCol - r.Ref1.nCol)+1) );
    1700         [ +  - ]:        694 :                 mnRowCount = std::max<SCROW>( mnRowCount, static_cast<SCROW>(abs(r.Ref2.nRow - r.Ref1.nRow)+1) );
    1701         [ +  - ]:        694 :                 if( mnStartColumn == -1 )
    1702                 :            :                 {
    1703                 :        694 :                     mnStartColumn = r.Ref1.nCol;
    1704                 :        694 :                     mnStartRow = r.Ref1.nRow;
    1705                 :            :                 }
    1706                 :            :                 else
    1707                 :            :                 {
    1708 [ #  # ][ #  # ]:          0 :                     if( mnStartColumn != r.Ref1.nCol && mnStartRow != r.Ref1.nRow )
    1709                 :          0 :                         mbAmbiguous=true;
    1710                 :            :                 }
    1711                 :            :             }
    1712                 :            :             else
    1713                 :        694 :                 mbAmbiguous=true;
    1714                 :            :         }
    1715 [ -  + ][ #  # ]:        750 :         else if (eVar == svSingleRef || eVar == svExternalSingleRef)
    1716                 :            :         {
    1717         [ +  - ]:        750 :             const ScSingleRefData& r = aRefToken->GetSingleRef();
    1718         [ +  - ]:        750 :             mnColumnCount = std::max<SCCOL>( mnColumnCount, 1);
    1719         [ +  - ]:        750 :             mnRowCount = std::max<SCROW>( mnRowCount, 1);
    1720         [ +  - ]:        750 :             if( mnStartColumn == -1 )
    1721                 :            :             {
    1722                 :        750 :                 mnStartColumn = r.nCol;
    1723                 :        750 :                 mnStartRow = r.nRow;
    1724                 :            :             }
    1725                 :            :             else
    1726                 :            :             {
    1727 [ #  # ][ #  # ]:          0 :                 if( mnStartColumn != r.nCol && mnStartRow != r.nRow )
    1728                 :          0 :                     mbAmbiguous=true;
    1729                 :        750 :             }
    1730                 :            :         }
    1731                 :            :         else
    1732                 :          0 :             mbAmbiguous=true;
    1733         [ +  - ]:       1444 :     }
    1734                 :            : }
    1735                 :            : 
    1736                 :       1398 : void RangeAnalyzer::analyzeRange( sal_Int32& rnDataInRows,
    1737                 :            :                                      sal_Int32& rnDataInCols,
    1738                 :            :                                      bool& rbRowSourceAmbiguous ) const
    1739                 :            : {
    1740 [ +  + ][ +  - ]:       1398 :     if(!mbEmpty && !mbAmbiguous)
    1741                 :            :     {
    1742 [ +  + ][ +  + ]:       2692 :         if( mnRowCount==1 && mnColumnCount>1 )
    1743                 :          6 :             ++rnDataInRows;
    1744 [ +  - ][ +  + ]:       1340 :         else if( mnColumnCount==1 && mnRowCount>1 )
    1745                 :        641 :             ++rnDataInCols;
    1746 [ -  + ][ #  # ]:        699 :         else if( mnRowCount>1 && mnColumnCount>1 )
    1747                 :          0 :             rbRowSourceAmbiguous = true;
    1748                 :            :     }
    1749         [ -  + ]:         52 :     else if( !mbEmpty )
    1750                 :          0 :         rbRowSourceAmbiguous = true;
    1751                 :       1398 : }
    1752                 :            : 
    1753                 :          0 : bool RangeAnalyzer::inSameSingleRow( RangeAnalyzer& rOther )
    1754                 :            : {
    1755 [ #  # ][ #  # ]:          0 :     if( mnStartRow==rOther.mnStartRow &&
                 [ #  # ]
    1756                 :            :         mnRowCount==1 && rOther.mnRowCount==1 )
    1757                 :          0 :         return true;
    1758                 :          0 :     return false;
    1759                 :            : }
    1760                 :            : 
    1761                 :          4 : bool RangeAnalyzer::inSameSingleColumn( RangeAnalyzer& rOther )
    1762                 :            : {
    1763 [ +  - ][ +  - ]:          4 :     if( mnStartColumn==rOther.mnStartColumn &&
                 [ +  - ]
    1764                 :            :         mnColumnCount==1 && rOther.mnColumnCount==1 )
    1765                 :          4 :         return true;
    1766                 :          4 :     return false;
    1767                 :            : }
    1768                 :            : 
    1769                 :            : } //end anonymous namespace
    1770                 :            : 
    1771                 :         55 : uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArguments(
    1772                 :            :     const uno::Reference< chart2::data::XDataSource >& xDataSource )
    1773                 :            :     throw (uno::RuntimeException)
    1774                 :            : {
    1775         [ +  - ]:         55 :     ::std::vector< beans::PropertyValue > aResult;
    1776                 :         55 :     bool bRowSourceDetected = false;
    1777                 :         55 :     bool bFirstCellAsLabel = false;
    1778                 :         55 :     bool bHasCategories = false;
    1779                 :         55 :     ::rtl::OUString sRangeRep;
    1780                 :            : 
    1781                 :         55 :     bool bHasCategoriesLabels = false;
    1782         [ +  - ]:         55 :     vector<ScTokenRef> aAllCategoriesValuesTokens;
    1783         [ +  - ]:         55 :     vector<ScTokenRef> aAllSeriesLabelTokens;
    1784                 :            : 
    1785                 :         55 :     chart::ChartDataRowSource eRowSource = chart::ChartDataRowSource_COLUMNS;
    1786                 :            : 
    1787         [ +  - ]:         55 :     vector<ScTokenRef> aAllTokens;
    1788                 :            : 
    1789                 :            :     // parse given data source and collect infos
    1790                 :            :     {
    1791         [ +  - ]:         55 :         SolarMutexGuard aGuard;
    1792                 :            :         OSL_ENSURE( m_pDocument, "No Document -> no detectArguments" );
    1793 [ +  - ][ -  + ]:         55 :         if(!m_pDocument ||!xDataSource.is())
                 [ -  + ]
    1794         [ #  # ]:          0 :             return lcl_VectorToSequence( aResult );
    1795                 :            : 
    1796                 :         55 :         sal_Int32 nDataInRows = 0;
    1797                 :         55 :         sal_Int32 nDataInCols = 0;
    1798                 :         55 :         bool bRowSourceAmbiguous = false;
    1799                 :            : 
    1800 [ +  - ][ +  - ]:         55 :         Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences());
    1801                 :         55 :         const sal_Int32 nCount( aSequences.getLength());
    1802                 :         55 :         RangeAnalyzer aPrevLabel,aPrevValues;
    1803         [ +  + ]:        805 :         for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx )
    1804                 :            :         {
    1805         [ +  - ]:        750 :             Reference< chart2::data::XLabeledDataSequence > xLS(aSequences[nIdx]);
    1806         [ +  - ]:        750 :             if( xLS.is() )
    1807                 :            :             {
    1808                 :        750 :                 bool bThisIsCategories = false;
    1809         [ +  + ]:        750 :                 if(!bHasCategories)
    1810                 :            :                 {
    1811 [ +  - ][ +  - ]:        107 :                     Reference< beans::XPropertySet > xSeqProp( xLS->getValues(), uno::UNO_QUERY );
                 [ +  - ]
    1812                 :        107 :                     ::rtl::OUString aRole;
    1813 [ +  - ][ +  - ]:        214 :                     if( xSeqProp.is() && (xSeqProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Role"))) >>= aRole) &&
                 [ +  - ]
           [ +  -  +  + ]
         [ +  - ][ +  - ]
           [ +  +  #  #  
           #  # ][ +  - ]
    1814                 :        107 :                         aRole.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("categories")) )
    1815                 :        107 :                         bThisIsCategories = bHasCategories = true;
    1816                 :            :                 }
    1817                 :            : 
    1818                 :        750 :                 RangeAnalyzer aLabel,aValues;
    1819                 :            :                 // label
    1820 [ +  - ][ +  - ]:        750 :                 Reference< chart2::data::XDataSequence > xLabel( xLS->getLabel());
    1821         [ +  + ]:        750 :                 if( xLabel.is())
    1822                 :            :                 {
    1823                 :        694 :                     bFirstCellAsLabel = true;
    1824         [ +  - ]:        694 :                     vector<ScTokenRef> aTokens;
    1825         [ +  - ]:        694 :                     const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    1826                 :            :                     ScRefTokenHelper::compileRangeRepresentation(
    1827 [ +  - ][ +  - ]:        694 :                         aTokens, xLabel->getSourceRangeRepresentation(), m_pDocument, cSep, m_pDocument->GetGrammar());
         [ +  - ][ +  - ]
    1828         [ +  - ]:        694 :                     aLabel.initRangeAnalyzer(aTokens);
    1829 [ +  - ][ +  - ]:        694 :                     vector<ScTokenRef>::const_iterator itr = aTokens.begin(), itrEnd = aTokens.end();
    1830 [ +  - ][ +  + ]:       1388 :                     for (; itr != itrEnd; ++itr)
    1831                 :            :                     {
    1832         [ +  - ]:        694 :                         ScRefTokenHelper::join(aAllTokens, *itr);
    1833         [ +  + ]:        694 :                         if(!bThisIsCategories)
    1834         [ +  - ]:        647 :                             ScRefTokenHelper::join(aAllSeriesLabelTokens, *itr);
    1835                 :            :                     }
    1836         [ +  + ]:        694 :                     if(bThisIsCategories)
    1837                 :        694 :                         bHasCategoriesLabels=true;
    1838                 :            :                 }
    1839                 :            :                 // values
    1840 [ +  - ][ +  - ]:        750 :                 Reference< chart2::data::XDataSequence > xValues( xLS->getValues());
    1841         [ +  - ]:        750 :                 if( xValues.is())
    1842                 :            :                 {
    1843         [ +  - ]:        750 :                     vector<ScTokenRef> aTokens;
    1844         [ +  - ]:        750 :                     const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    1845                 :            :                     ScRefTokenHelper::compileRangeRepresentation(
    1846 [ +  - ][ +  - ]:        750 :                         aTokens, xValues->getSourceRangeRepresentation(), m_pDocument, cSep, m_pDocument->GetGrammar());
         [ +  - ][ +  - ]
    1847         [ +  - ]:        750 :                     aValues.initRangeAnalyzer(aTokens);
    1848 [ +  - ][ +  - ]:        750 :                     vector<ScTokenRef>::const_iterator itr = aTokens.begin(), itrEnd = aTokens.end();
    1849 [ +  - ][ +  + ]:       1500 :                     for (; itr != itrEnd; ++itr)
    1850                 :            :                     {
    1851         [ +  - ]:        750 :                         ScRefTokenHelper::join(aAllTokens, *itr);
    1852         [ +  + ]:        750 :                         if(bThisIsCategories)
    1853         [ +  - ]:         51 :                             ScRefTokenHelper::join(aAllCategoriesValuesTokens, *itr);
    1854                 :        750 :                     }
    1855                 :            :                 }
    1856                 :            :                 //detect row source
    1857 [ +  + ][ -  + ]:        750 :                 if(!bThisIsCategories || nCount==1) //categories might span multiple rows *and* columns, so they should be used for detection only if nothing else is available
    1858                 :            :                 {
    1859         [ +  - ]:        699 :                     if (!bRowSourceAmbiguous)
    1860                 :            :                     {
    1861                 :        699 :                         aValues.analyzeRange(nDataInRows,nDataInCols,bRowSourceAmbiguous);
    1862                 :        699 :                         aLabel.analyzeRange(nDataInRows,nDataInCols,bRowSourceAmbiguous);
    1863 [ -  + ][ +  + ]:        699 :                         if (nDataInRows > 1 && nDataInCols > 1)
    1864                 :          0 :                             bRowSourceAmbiguous = true;
    1865 [ +  - ][ +  + ]:        699 :                         else if( !bRowSourceAmbiguous && !nDataInRows && !nDataInCols )
                 [ +  + ]
    1866                 :            :                         {
    1867         [ +  - ]:          4 :                             if( aValues.inSameSingleColumn( aLabel ) )
    1868                 :          4 :                                 nDataInCols++;
    1869         [ #  # ]:          0 :                             else if( aValues.inSameSingleRow( aLabel ) )
    1870                 :          0 :                                 nDataInRows++;
    1871                 :            :                             else
    1872                 :            :                             {
    1873                 :            :                                 //#i86188# also detect a single column split into rows correctly
    1874         [ #  # ]:          0 :                                 if( aValues.inSameSingleColumn( aPrevValues ) )
    1875                 :          0 :                                     nDataInRows++;
    1876         [ #  # ]:          0 :                                 else if( aValues.inSameSingleRow( aPrevValues ) )
    1877                 :          0 :                                     nDataInCols++;
    1878         [ #  # ]:          0 :                                 else if( aLabel.inSameSingleColumn( aPrevLabel ) )
    1879                 :          0 :                                     nDataInRows++;
    1880         [ #  # ]:          0 :                                 else if( aLabel.inSameSingleRow( aPrevLabel ) )
    1881                 :        699 :                                     nDataInCols++;
    1882                 :            :                             }
    1883                 :            :                         }
    1884                 :            :                     }
    1885                 :            :                 }
    1886                 :        750 :                 aPrevValues=aValues;
    1887                 :        750 :                 aPrevLabel=aLabel;
    1888                 :            :             }
    1889                 :        750 :         }
    1890                 :            : 
    1891         [ +  - ]:         55 :         if (!bRowSourceAmbiguous)
    1892                 :            :         {
    1893                 :         55 :             bRowSourceDetected = true;
    1894                 :            :             eRowSource = ( nDataInRows > 0
    1895                 :            :                            ? chart::ChartDataRowSource_ROWS
    1896                 :         55 :                            : chart::ChartDataRowSource_COLUMNS );
    1897                 :            :         }
    1898                 :            :         else
    1899                 :            :         {
    1900                 :            :             // set DataRowSource to the better of the two ambiguities
    1901                 :            :             eRowSource = ( nDataInRows > nDataInCols
    1902                 :            :                            ? chart::ChartDataRowSource_ROWS
    1903                 :          0 :                            : chart::ChartDataRowSource_COLUMNS );
    1904 [ +  - ][ +  - ]:         55 :         }
                 [ +  - ]
    1905                 :            : 
    1906                 :            :     }
    1907                 :            : 
    1908                 :            :     // TableNumberList
    1909                 :            :     {
    1910         [ +  - ]:         55 :         list<SCTAB> aTableNumList;
    1911         [ +  - ]:         55 :         InsertTabNumber func;
    1912 [ +  - ][ +  - ]:         55 :         func = ::std::for_each(aAllTokens.begin(), aAllTokens.end(), func);
         [ +  - ][ +  - ]
                 [ +  - ]
    1913         [ +  - ]:         55 :         func.getList(aTableNumList);
    1914                 :            :         aResult.push_back(
    1915                 :            :             beans::PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableNumberList")), -1,
    1916                 :            :                                   uno::makeAny( lcl_createTableNumberList( aTableNumList ) ),
    1917 [ +  - ][ +  - ]:         55 :                                   beans::PropertyState_DIRECT_VALUE ));
         [ +  - ][ +  - ]
                 [ +  - ]
    1918                 :            :     }
    1919                 :            : 
    1920                 :            :     // DataRowSource (calculated before)
    1921         [ +  - ]:         55 :     if( bRowSourceDetected )
    1922                 :            :     {
    1923                 :            :         aResult.push_back(
    1924                 :            :             beans::PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataRowSource")), -1,
    1925 [ +  - ][ +  - ]:         55 :                                   uno::makeAny( eRowSource ), beans::PropertyState_DIRECT_VALUE ));
                 [ +  - ]
    1926                 :            :     }
    1927                 :            : 
    1928                 :            :     // HasCategories
    1929         [ +  - ]:         55 :     if( bRowSourceDetected )
    1930                 :            :     {
    1931                 :            :         aResult.push_back(
    1932                 :            :             beans::PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasCategories")), -1,
    1933 [ +  - ][ +  - ]:         55 :                                   uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE ));
                 [ +  - ]
    1934                 :            :     }
    1935                 :            : 
    1936                 :            :     // FirstCellAsLabel
    1937         [ +  - ]:         55 :     if( bRowSourceDetected )
    1938                 :            :     {
    1939                 :            :         aResult.push_back(
    1940                 :            :             beans::PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FirstCellAsLabel")), -1,
    1941 [ +  - ][ +  - ]:         55 :                                   uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE ));
                 [ +  - ]
    1942                 :            :     }
    1943                 :            : 
    1944                 :            :     // Add the left upper corner to the range if it is missing.
    1945 [ +  - ][ +  + ]:         55 :     if (bRowSourceDetected && bFirstCellAsLabel && bHasCategories && !bHasCategoriesLabels )
         [ +  + ][ -  + ]
    1946                 :            :     {
    1947                 :          0 :         RangeAnalyzer aTop,aLeft;
    1948         [ #  # ]:          0 :         if( eRowSource==chart::ChartDataRowSource_COLUMNS )
    1949                 :            :         {
    1950         [ #  # ]:          0 :             aTop.initRangeAnalyzer(aAllSeriesLabelTokens);
    1951         [ #  # ]:          0 :             aLeft.initRangeAnalyzer(aAllCategoriesValuesTokens);
    1952                 :            :         }
    1953                 :            :         else
    1954                 :            :         {
    1955         [ #  # ]:          0 :             aTop.initRangeAnalyzer(aAllCategoriesValuesTokens);
    1956         [ #  # ]:          0 :             aLeft.initRangeAnalyzer(aAllSeriesLabelTokens);
    1957                 :            :         }
    1958         [ #  # ]:          0 :         lcl_addUpperLeftCornerIfMissing(aAllTokens, aTop.getRowCount(), aLeft.getColumnCount());//e.g. #i91212#
    1959                 :            :     }
    1960                 :            : 
    1961                 :            :     // Get range string.
    1962         [ +  - ]:         55 :     lcl_convertTokensToString(sRangeRep, aAllTokens, m_pDocument);
    1963                 :            : 
    1964                 :            :     // add cell range property
    1965                 :            :     aResult.push_back(
    1966                 :            :         beans::PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellRangeRepresentation")), -1,
    1967 [ +  - ][ +  - ]:         55 :                               uno::makeAny( sRangeRep ), beans::PropertyState_DIRECT_VALUE ));
                 [ +  - ]
    1968                 :            : 
    1969                 :            :     //Sequence Mapping
    1970                 :         55 :     bool bSequencesReordered = true;//todo detect this above or detect this sequence mapping cheaper ...
    1971 [ +  - ][ +  - ]:         55 :     if( bSequencesReordered && bRowSourceDetected )
    1972                 :            :     {
    1973                 :         55 :         bool bDifferentIndexes = false;
    1974                 :            : 
    1975         [ +  - ]:         55 :         std::vector< sal_Int32 > aSequenceMappingVector;
    1976                 :            : 
    1977                 :         55 :         uno::Reference< chart2::data::XDataSource > xCompareDataSource;
    1978                 :            :         try
    1979                 :            :         {
    1980 [ +  - ][ +  - ]:         55 :             xCompareDataSource.set( this->createDataSource( lcl_VectorToSequence( aResult ) ) );
         [ +  - ][ #  # ]
                 [ +  - ]
    1981                 :            :         }
    1982         [ #  # ]:          0 :         catch( const lang::IllegalArgumentException & )
    1983                 :            :         {
    1984                 :            :             // creation of data source to compare didn't work, so we cannot
    1985                 :            :             // create a sequence mapping
    1986                 :            :         }
    1987                 :            : 
    1988 [ +  - ][ +  - ]:         55 :         if( xDataSource.is() && xCompareDataSource.is() )
                 [ +  - ]
    1989                 :            :         {
    1990                 :            :             uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> > aOldSequences(
    1991 [ +  - ][ +  - ]:         55 :                 xCompareDataSource->getDataSequences() );
    1992                 :            :             uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aNewSequences(
    1993 [ +  - ][ +  - ]:         55 :                 xDataSource->getDataSequences());
    1994                 :            : 
    1995                 :         55 :             rtl::OUString aOldLabel;
    1996                 :         55 :             rtl::OUString aNewLabel;
    1997                 :         55 :             rtl::OUString aOldValues;
    1998                 :         55 :             rtl::OUString aNewValues;
    1999                 :         55 :             rtl::OUString aEmpty;
    2000                 :            : 
    2001         [ +  + ]:        805 :             for( sal_Int32 nNewIndex = 0; nNewIndex < aNewSequences.getLength(); nNewIndex++ )
    2002                 :            :             {
    2003         [ +  - ]:        750 :                 uno::Reference< chart2::data::XLabeledDataSequence> xNew( aNewSequences[nNewIndex] );
    2004         [ +  - ]:       6335 :                 for( sal_Int32 nOldIndex = 0; nOldIndex < aOldSequences.getLength(); nOldIndex++ )
    2005                 :            :                 {
    2006         [ +  - ]:       5585 :                     uno::Reference< chart2::data::XLabeledDataSequence> xOld( aOldSequences[nOldIndex] );
    2007                 :            : 
    2008 [ +  - ][ +  - ]:       5585 :                     if( xOld.is() && xNew.is() )
                 [ +  - ]
    2009                 :            :                     {
    2010                 :       5585 :                         aOldLabel = aNewLabel = aOldValues = aNewValues = aEmpty;
    2011 [ +  - ][ +  - ]:       5585 :                         if( xOld.is() && xOld->getLabel().is() )
         [ +  + ][ +  - ]
           [ +  +  #  # ]
                 [ +  - ]
    2012 [ +  - ][ +  - ]:       5165 :                             aOldLabel = xOld->getLabel()->getSourceRangeRepresentation();
         [ +  - ][ +  - ]
    2013 [ +  - ][ +  - ]:       5585 :                         if( xNew.is() && xNew->getLabel().is() )
         [ +  - ][ +  + ]
                 [ +  - ]
           [ +  +  #  # ]
    2014 [ +  - ][ +  - ]:       5165 :                             aNewLabel = xNew->getLabel()->getSourceRangeRepresentation();
         [ +  - ][ +  - ]
    2015 [ +  - ][ +  - ]:       5585 :                         if( xOld.is() && xOld->getValues().is() )
         [ +  - ][ +  - ]
                 [ +  - ]
           [ +  -  #  # ]
    2016 [ +  - ][ +  - ]:       5585 :                             aOldValues = xOld->getValues()->getSourceRangeRepresentation();
         [ +  - ][ +  - ]
    2017 [ +  - ][ +  - ]:       5585 :                         if( xNew.is() && xNew->getValues().is() )
         [ +  - ][ +  - ]
                 [ +  - ]
           [ +  -  #  # ]
    2018 [ +  - ][ +  - ]:       5585 :                             aNewValues = xNew->getValues()->getSourceRangeRepresentation();
         [ +  - ][ +  - ]
    2019                 :            : 
    2020   [ +  +  +  + ]:       6699 :                         if( aOldLabel.equals(aNewLabel)
                 [ +  + ]
    2021                 :       1114 :                             && ( aOldValues.equals(aNewValues) ) )
    2022                 :            :                         {
    2023         [ -  + ]:        750 :                             if( nOldIndex!=nNewIndex )
    2024                 :          0 :                                 bDifferentIndexes = true;
    2025         [ +  - ]:       5585 :                             aSequenceMappingVector.push_back(nOldIndex);
    2026                 :            :                             break;
    2027                 :            :                         }
    2028                 :            :                     }
    2029         [ +  + ]:       5585 :                 }
    2030 [ +  - ][ +  - ]:        805 :             }
    2031                 :            :         }
    2032                 :            : 
    2033 [ -  + ][ #  # ]:         55 :         if( bDifferentIndexes && !aSequenceMappingVector.empty() )
                 [ -  + ]
    2034                 :            :         {
    2035                 :            :             aResult.push_back(
    2036                 :            :                 beans::PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SequenceMapping")), -1,
    2037                 :            :                     uno::makeAny( lcl_VectorToSequence(aSequenceMappingVector) )
    2038 [ #  # ][ #  # ]:          0 :                     , beans::PropertyState_DIRECT_VALUE ));
         [ #  # ][ #  # ]
                 [ #  # ]
    2039                 :         55 :         }
    2040                 :            :     }
    2041                 :            : 
    2042         [ +  - ]:         55 :     return lcl_VectorToSequence( aResult );
    2043                 :            : }
    2044                 :            : 
    2045                 :          0 : ::sal_Bool SAL_CALL ScChart2DataProvider::createDataSequenceByRangeRepresentationPossible( const ::rtl::OUString& aRangeRepresentation )
    2046                 :            :     throw (uno::RuntimeException)
    2047                 :            : {
    2048         [ #  # ]:          0 :     SolarMutexGuard aGuard;
    2049         [ #  # ]:          0 :     if( ! m_pDocument )
    2050                 :          0 :         return false;
    2051                 :            : 
    2052         [ #  # ]:          0 :     vector<ScTokenRef> aTokens;
    2053         [ #  # ]:          0 :     const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    2054                 :            :     ScRefTokenHelper::compileRangeRepresentation(
    2055 [ #  # ][ #  # ]:          0 :         aTokens, aRangeRepresentation, m_pDocument, cSep, m_pDocument->GetGrammar());
    2056         [ #  # ]:          0 :     return !aTokens.empty();
    2057                 :            : }
    2058                 :            : 
    2059                 :            : uno::Reference< chart2::data::XDataSequence > SAL_CALL
    2060                 :         18 :     ScChart2DataProvider::createDataSequenceByRangeRepresentation(
    2061                 :            :     const ::rtl::OUString& aRangeRepresentation )
    2062                 :            :     throw (lang::IllegalArgumentException,
    2063                 :            :            uno::RuntimeException)
    2064                 :            : {
    2065         [ +  - ]:         18 :     SolarMutexGuard aGuard;
    2066                 :         18 :     uno::Reference< chart2::data::XDataSequence > xResult;
    2067                 :            : 
    2068                 :            :     OSL_ENSURE( m_pDocument, "No Document -> no createDataSequenceByRangeRepresentation" );
    2069 [ -  + ][ +  - ]:         18 :     if(!m_pDocument || aRangeRepresentation.isEmpty())
                 [ +  - ]
    2070                 :            :         return xResult;
    2071                 :            : 
    2072         [ +  - ]:         18 :     vector<ScTokenRef> aRefTokens;
    2073         [ +  - ]:         18 :     const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    2074                 :            :     ScRefTokenHelper::compileRangeRepresentation(
    2075 [ +  - ][ +  - ]:         18 :         aRefTokens, aRangeRepresentation, m_pDocument, cSep, m_pDocument->GetGrammar());
    2076         [ +  - ]:         18 :     if (aRefTokens.empty())
    2077                 :            :         return xResult;
    2078                 :            : 
    2079         [ +  - ]:         18 :     shrinkToDataRange(m_pDocument, aRefTokens);
    2080                 :            : 
    2081                 :            :     // ScChart2DataSequence manages the life cycle of pRefTokens.
    2082 [ +  - ][ +  - ]:         18 :     vector<ScTokenRef>* pRefTokens = new vector<ScTokenRef>();
    2083                 :         18 :     pRefTokens->swap(aRefTokens);
    2084 [ +  - ][ +  - ]:         18 :     xResult.set(new ScChart2DataSequence(m_pDocument, this, pRefTokens, m_bIncludeHiddenCells));
         [ +  - ][ +  - ]
    2085                 :            : 
    2086         [ +  - ]:         18 :     return xResult;
    2087                 :            : }
    2088                 :            : 
    2089                 :          0 : uno::Reference< sheet::XRangeSelection > SAL_CALL ScChart2DataProvider::getRangeSelection()
    2090                 :            :     throw (uno::RuntimeException)
    2091                 :            : {
    2092                 :          0 :     uno::Reference< sheet::XRangeSelection > xResult;
    2093                 :            : 
    2094         [ #  # ]:          0 :     uno::Reference< frame::XModel > xModel( lcl_GetXModel( m_pDocument ));
    2095         [ #  # ]:          0 :     if( xModel.is())
    2096 [ #  # ][ #  # ]:          0 :         xResult.set( xModel->getCurrentController(), uno::UNO_QUERY );
                 [ #  # ]
    2097                 :            : 
    2098                 :          0 :     return xResult;
    2099                 :            : }
    2100                 :            : 
    2101                 :          0 : sal_Bool SAL_CALL ScChart2DataProvider::createDataSequenceByFormulaTokensPossible(
    2102                 :            :     const Sequence<sheet::FormulaToken>& aTokens )
    2103                 :            :         throw (uno::RuntimeException)
    2104                 :            : {
    2105         [ #  # ]:          0 :     if (aTokens.getLength() <= 0)
    2106                 :          0 :         return false;
    2107                 :            : 
    2108         [ #  # ]:          0 :     ScTokenArray aCode;
    2109 [ #  # ][ #  # ]:          0 :     if (!ScTokenConversion::ConvertToTokenArray(*m_pDocument, aCode, aTokens))
    2110                 :          0 :         return false;
    2111                 :            : 
    2112                 :          0 :     sal_uInt16 n = aCode.GetLen();
    2113         [ #  # ]:          0 :     if (!n)
    2114                 :          0 :         return false;
    2115                 :            : 
    2116         [ #  # ]:          0 :     const formula::FormulaToken* pFirst = aCode.First();
    2117                 :          0 :     const formula::FormulaToken* pLast = aCode.GetArray()[n-1];
    2118 [ #  # ][ #  # ]:          0 :     for (const formula::FormulaToken* p = aCode.First(); p; p = aCode.Next())
                 [ #  # ]
    2119                 :            :     {
    2120      [ #  #  # ]:          0 :         switch (p->GetType())
    2121                 :            :         {
    2122                 :            :             case svSep:
    2123                 :            :             {
    2124   [ #  #  #  # ]:          0 :                 switch (p->GetOpCode())
    2125                 :            :                 {
    2126                 :            :                     case ocSep:
    2127                 :            :                         // separators are allowed.
    2128                 :          0 :                     break;
    2129                 :            :                     case ocOpen:
    2130         [ #  # ]:          0 :                         if (p != pFirst)
    2131                 :            :                             // open paran is allowed only as the first token.
    2132                 :          0 :                             return false;
    2133                 :          0 :                     break;
    2134                 :            :                     case ocClose:
    2135         [ #  # ]:          0 :                         if (p != pLast)
    2136                 :            :                             // close paren is allowed only as the last token.
    2137                 :          0 :                             return false;
    2138                 :          0 :                     break;
    2139                 :            :                     default:
    2140                 :          0 :                         return false;
    2141                 :            :                 }
    2142                 :            :             }
    2143                 :          0 :             break;
    2144                 :            :             case svSingleRef:
    2145                 :            :             case svDoubleRef:
    2146                 :            :             case svExternalSingleRef:
    2147                 :            :             case svExternalDoubleRef:
    2148                 :          0 :             break;
    2149                 :            :             default:
    2150                 :          0 :                 return false;
    2151                 :            :         }
    2152                 :            :     }
    2153                 :            : 
    2154         [ #  # ]:          0 :     return true;
    2155                 :            : }
    2156                 :            : 
    2157                 :            : Reference<chart2::data::XDataSequence> SAL_CALL
    2158                 :          0 : ScChart2DataProvider::createDataSequenceByFormulaTokens(
    2159                 :            :     const Sequence<sheet::FormulaToken>& aTokens )
    2160                 :            :         throw (lang::IllegalArgumentException, uno::RuntimeException)
    2161                 :            : {
    2162                 :          0 :     Reference<chart2::data::XDataSequence> xResult;
    2163         [ #  # ]:          0 :     if (aTokens.getLength() <= 0)
    2164                 :            :         return xResult;
    2165                 :            : 
    2166         [ #  # ]:          0 :     ScTokenArray aCode;
    2167 [ #  # ][ #  # ]:          0 :     if (!ScTokenConversion::ConvertToTokenArray(*m_pDocument, aCode, aTokens))
    2168                 :            :         return xResult;
    2169                 :            : 
    2170                 :          0 :     sal_uInt16 n = aCode.GetLen();
    2171         [ #  # ]:          0 :     if (!n)
    2172                 :            :         return xResult;
    2173                 :            : 
    2174         [ #  # ]:          0 :     vector<ScTokenRef> aRefTokens;
    2175         [ #  # ]:          0 :     const formula::FormulaToken* pFirst = aCode.First();
    2176                 :          0 :     const formula::FormulaToken* pLast = aCode.GetArray()[n-1];
    2177 [ #  # ][ #  # ]:          0 :     for (const formula::FormulaToken* p = aCode.First(); p; p = aCode.Next())
                 [ #  # ]
    2178                 :            :     {
    2179      [ #  #  # ]:          0 :         switch (p->GetType())
    2180                 :            :         {
    2181                 :            :             case svSep:
    2182                 :            :             {
    2183   [ #  #  #  # ]:          0 :                 switch (p->GetOpCode())
    2184                 :            :                 {
    2185                 :            :                     case ocSep:
    2186                 :            :                         // separators are allowed.
    2187                 :          0 :                     break;
    2188                 :            :                     case ocOpen:
    2189         [ #  # ]:          0 :                         if (p != pFirst)
    2190                 :            :                             // open paran is allowed only as the first token.
    2191         [ #  # ]:          0 :                             throw lang::IllegalArgumentException();
    2192                 :          0 :                     break;
    2193                 :            :                     case ocClose:
    2194         [ #  # ]:          0 :                         if (p != pLast)
    2195                 :            :                             // close paren is allowed only as the last token.
    2196         [ #  # ]:          0 :                             throw lang::IllegalArgumentException();
    2197                 :          0 :                     break;
    2198                 :            :                     default:
    2199         [ #  # ]:          0 :                         throw lang::IllegalArgumentException();
    2200                 :            :                 }
    2201                 :            :             }
    2202                 :          0 :             break;
    2203                 :            :             case svSingleRef:
    2204                 :            :             case svDoubleRef:
    2205                 :            :             case svExternalSingleRef:
    2206                 :            :             case svExternalDoubleRef:
    2207                 :            :             {
    2208         [ #  # ]:          0 :                 ScTokenRef pNew(static_cast<ScToken*>(p->Clone()));
    2209 [ #  # ][ #  # ]:          0 :                 aRefTokens.push_back(pNew);
    2210                 :            :             }
    2211                 :          0 :             break;
    2212                 :            :             default:
    2213         [ #  # ]:          0 :                 throw lang::IllegalArgumentException();
    2214                 :            :         }
    2215                 :            :     }
    2216                 :            : 
    2217         [ #  # ]:          0 :     if (aRefTokens.empty())
    2218                 :            :         return xResult;
    2219                 :            : 
    2220         [ #  # ]:          0 :     shrinkToDataRange(m_pDocument, aRefTokens);
    2221                 :            : 
    2222                 :            :     // ScChart2DataSequence manages the life cycle of pRefTokens.
    2223 [ #  # ][ #  # ]:          0 :     vector<ScTokenRef>* pRefTokens = new vector<ScTokenRef>();
    2224                 :          0 :     pRefTokens->swap(aRefTokens);
    2225 [ #  # ][ #  # ]:          0 :     xResult.set(new ScChart2DataSequence(m_pDocument, this, pRefTokens, m_bIncludeHiddenCells));
         [ #  # ][ #  # ]
    2226         [ #  # ]:          0 :     return xResult;
    2227                 :            : }
    2228                 :            : 
    2229                 :            : // XRangeXMLConversion ---------------------------------------------------
    2230                 :            : 
    2231                 :         57 : rtl::OUString SAL_CALL ScChart2DataProvider::convertRangeToXML( const rtl::OUString& sRangeRepresentation )
    2232                 :            :     throw ( uno::RuntimeException, lang::IllegalArgumentException )
    2233                 :            : {
    2234                 :         57 :     OUString aRet;
    2235         [ +  - ]:         57 :     if (!m_pDocument)
    2236                 :            :         return aRet;
    2237                 :            : 
    2238         [ +  - ]:         57 :     if (sRangeRepresentation.isEmpty())
    2239                 :            :         // Empty data range is allowed.
    2240                 :            :         return aRet;
    2241                 :            : 
    2242         [ +  - ]:         57 :     vector<ScTokenRef> aRefTokens;
    2243         [ +  - ]:         57 :     const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    2244                 :            :     ScRefTokenHelper::compileRangeRepresentation(
    2245 [ +  - ][ +  - ]:         57 :         aRefTokens, sRangeRepresentation, m_pDocument, cSep, m_pDocument->GetGrammar());
    2246         [ -  + ]:         57 :     if (aRefTokens.empty())
    2247         [ #  # ]:          0 :         throw lang::IllegalArgumentException();
    2248                 :            : 
    2249         [ +  - ]:         57 :     Tokens2RangeStringXML converter(m_pDocument);
    2250 [ +  - ][ +  - ]:         57 :     converter = ::std::for_each(aRefTokens.begin(), aRefTokens.end(), converter);
         [ +  - ][ +  - ]
                 [ +  - ]
    2251         [ +  - ]:         57 :     converter.getString(aRet);
    2252                 :            : 
    2253         [ +  - ]:         57 :     return aRet;
    2254                 :            : }
    2255                 :            : 
    2256                 :          0 : rtl::OUString SAL_CALL ScChart2DataProvider::convertRangeFromXML( const rtl::OUString& sXMLRange )
    2257                 :            :     throw ( uno::RuntimeException, lang::IllegalArgumentException )
    2258                 :            : {
    2259                 :          0 :     const sal_Unicode cSep = ' ';
    2260                 :          0 :     const sal_Unicode cQuote = '\'';
    2261                 :            : 
    2262         [ #  # ]:          0 :     if (!m_pDocument)
    2263                 :            :     {
    2264                 :            :         // #i74062# When loading flat XML, this is called before the referenced sheets are in the document,
    2265                 :            :         // so the conversion has to take place directly with the strings, without looking up the sheets.
    2266                 :            : 
    2267                 :          0 :         rtl::OUStringBuffer sRet;
    2268                 :          0 :         sal_Int32 nOffset = 0;
    2269         [ #  # ]:          0 :         while( nOffset >= 0 )
    2270                 :            :         {
    2271                 :          0 :             rtl::OUString sToken;
    2272         [ #  # ]:          0 :             ScRangeStringConverter::GetTokenByOffset( sToken, sXMLRange, nOffset, cSep, cQuote );
    2273         [ #  # ]:          0 :             if( nOffset >= 0 )
    2274                 :            :             {
    2275                 :            :                 // convert one address (remove dots)
    2276                 :            : 
    2277         [ #  # ]:          0 :                 String aUIString(sToken);
    2278                 :            : 
    2279         [ #  # ]:          0 :                 sal_Int32 nIndex = ScRangeStringConverter::IndexOf( sToken, ':', 0, cQuote );
    2280         [ #  # ]:          0 :                 if ( nIndex >= 0 && nIndex < aUIString.Len() - 1 &&
           [ #  #  #  # ]
                 [ #  # ]
    2281                 :          0 :                         aUIString.GetChar((xub_StrLen)nIndex + 1) == (sal_Unicode) '.' )
    2282         [ #  # ]:          0 :                     aUIString.Erase( (xub_StrLen)nIndex + 1, 1 );
    2283                 :            : 
    2284         [ #  # ]:          0 :                 if ( aUIString.GetChar(0) == (sal_Unicode) '.' )
    2285         [ #  # ]:          0 :                     aUIString.Erase( 0, 1 );
    2286                 :            : 
    2287         [ #  # ]:          0 :                 if( sRet.getLength() )
    2288         [ #  # ]:          0 :                     sRet.append( (sal_Unicode) ';' );
    2289 [ #  # ][ #  # ]:          0 :                 sRet.append( aUIString );
                 [ #  # ]
    2290                 :            :             }
    2291                 :          0 :         }
    2292                 :            : 
    2293         [ #  # ]:          0 :         return sRet.makeStringAndClear();
    2294                 :            :     }
    2295                 :            : 
    2296                 :          0 :     OUString aRet;
    2297         [ #  # ]:          0 :     ScRangeStringConverter::GetStringFromXMLRangeString(aRet, sXMLRange, m_pDocument);
    2298                 :          0 :     return aRet;
    2299                 :            : }
    2300                 :            : 
    2301                 :            : // DataProvider XPropertySet -------------------------------------------------
    2302                 :            : 
    2303                 :            : uno::Reference< beans::XPropertySetInfo> SAL_CALL
    2304                 :          0 : ScChart2DataProvider::getPropertySetInfo() throw( uno::RuntimeException)
    2305                 :            : {
    2306         [ #  # ]:          0 :     SolarMutexGuard aGuard;
    2307                 :            :     static uno::Reference<beans::XPropertySetInfo> aRef =
    2308 [ #  # ][ #  # ]:          0 :         new SfxItemPropertySetInfo( m_aPropSet.getPropertyMap() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2309         [ #  # ]:          0 :     return aRef;
    2310                 :            : }
    2311                 :            : 
    2312                 :            : 
    2313                 :         22 : void SAL_CALL ScChart2DataProvider::setPropertyValue(
    2314                 :            :         const ::rtl::OUString& rPropertyName, const uno::Any& rValue)
    2315                 :            :             throw( beans::UnknownPropertyException,
    2316                 :            :                     beans::PropertyVetoException,
    2317                 :            :                     lang::IllegalArgumentException,
    2318                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    2319                 :            : {
    2320         [ +  - ]:         22 :     if ( rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS )
    2321                 :            :     {
    2322         [ -  + ]:         22 :         if ( !(rValue >>= m_bIncludeHiddenCells))
    2323         [ #  # ]:          0 :             throw lang::IllegalArgumentException();
    2324                 :            :     }
    2325                 :            :     else
    2326         [ #  # ]:          0 :         throw beans::UnknownPropertyException();
    2327                 :         22 : }
    2328                 :            : 
    2329                 :            : 
    2330                 :          0 : uno::Any SAL_CALL ScChart2DataProvider::getPropertyValue(
    2331                 :            :         const ::rtl::OUString& rPropertyName)
    2332                 :            :             throw( beans::UnknownPropertyException,
    2333                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    2334                 :            : {
    2335                 :          0 :     uno::Any aRet;
    2336         [ #  # ]:          0 :     if ( rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS )
    2337         [ #  # ]:          0 :         aRet <<= m_bIncludeHiddenCells;
    2338                 :            :     else
    2339         [ #  # ]:          0 :         throw beans::UnknownPropertyException();
    2340                 :          0 :     return aRet;
    2341                 :            : }
    2342                 :            : 
    2343                 :            : 
    2344                 :          0 : void SAL_CALL ScChart2DataProvider::addPropertyChangeListener(
    2345                 :            :         const ::rtl::OUString& /*rPropertyName*/,
    2346                 :            :         const uno::Reference< beans::XPropertyChangeListener>& /*xListener*/)
    2347                 :            :             throw( beans::UnknownPropertyException,
    2348                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    2349                 :            : {
    2350                 :            :     OSL_FAIL( "Not yet implemented" );
    2351                 :          0 : }
    2352                 :            : 
    2353                 :            : 
    2354                 :          0 : void SAL_CALL ScChart2DataProvider::removePropertyChangeListener(
    2355                 :            :         const ::rtl::OUString& /*rPropertyName*/,
    2356                 :            :         const uno::Reference< beans::XPropertyChangeListener>& /*rListener*/)
    2357                 :            :             throw( beans::UnknownPropertyException,
    2358                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    2359                 :            : {
    2360                 :            :     OSL_FAIL( "Not yet implemented" );
    2361                 :          0 : }
    2362                 :            : 
    2363                 :            : 
    2364                 :          0 : void SAL_CALL ScChart2DataProvider::addVetoableChangeListener(
    2365                 :            :         const ::rtl::OUString& /*rPropertyName*/,
    2366                 :            :         const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
    2367                 :            :             throw( beans::UnknownPropertyException,
    2368                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    2369                 :            : {
    2370                 :            :     OSL_FAIL( "Not yet implemented" );
    2371                 :          0 : }
    2372                 :            : 
    2373                 :            : 
    2374                 :          0 : void SAL_CALL ScChart2DataProvider::removeVetoableChangeListener(
    2375                 :            :         const ::rtl::OUString& /*rPropertyName*/,
    2376                 :            :         const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/ )
    2377                 :            :             throw( beans::UnknownPropertyException,
    2378                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    2379                 :            : {
    2380                 :            :     OSL_FAIL( "Not yet implemented" );
    2381                 :          0 : }
    2382                 :            : 
    2383                 :            : // DataSource ================================================================
    2384                 :            : 
    2385                 :        619 : ScChart2DataSource::ScChart2DataSource( ScDocument* pDoc)
    2386 [ +  - ][ +  - ]:        619 :     : m_pDocument( pDoc)
    2387                 :            : {
    2388         [ +  - ]:        619 :     if ( m_pDocument )
    2389         [ +  - ]:        619 :         m_pDocument->AddUnoObject( *this);
    2390                 :        619 : }
    2391                 :            : 
    2392                 :            : 
    2393         [ +  - ]:        619 : ScChart2DataSource::~ScChart2DataSource()
    2394                 :            : {
    2395         [ +  - ]:        619 :     if ( m_pDocument )
    2396         [ +  - ]:        619 :         m_pDocument->RemoveUnoObject( *this);
    2397         [ -  + ]:       1238 : }
    2398                 :            : 
    2399                 :            : 
    2400                 :          0 : void ScChart2DataSource::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
    2401                 :            : {
    2402   [ #  #  #  # ]:          0 :     if ( rHint.ISA( SfxSimpleHint ) &&
                 [ #  # ]
    2403                 :          0 :             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    2404                 :            :     {
    2405                 :          0 :         m_pDocument = NULL;
    2406                 :            :     }
    2407                 :          0 : }
    2408                 :            : 
    2409                 :            : 
    2410                 :            : uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> > SAL_CALL
    2411                 :        619 : ScChart2DataSource::getDataSequences() throw ( uno::RuntimeException)
    2412                 :            : {
    2413         [ +  - ]:        619 :     SolarMutexGuard aGuard;
    2414                 :            : 
    2415                 :        619 :     LabeledList::const_iterator aItr(m_aLabeledSequences.begin());
    2416                 :        619 :     LabeledList::const_iterator aEndItr(m_aLabeledSequences.end());
    2417                 :            : 
    2418         [ +  - ]:        619 :     uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aRet(m_aLabeledSequences.size());
    2419                 :            : 
    2420                 :        619 :     sal_Int32 i = 0;
    2421         [ +  + ]:       4316 :     while (aItr != aEndItr)
    2422                 :            :     {
    2423 [ +  - ][ +  - ]:       3697 :         aRet[i] = *aItr;
    2424                 :       3697 :         ++i;
    2425                 :       3697 :         ++aItr;
    2426                 :            :     }
    2427                 :            : 
    2428         [ +  - ]:        619 :     return aRet;
    2429                 :            : }
    2430                 :            : 
    2431                 :       3697 : void ScChart2DataSource::AddLabeledSequence(const uno::Reference < chart2::data::XLabeledDataSequence >& xNew)
    2432                 :            : {
    2433                 :       3697 :     m_aLabeledSequences.push_back(xNew);
    2434                 :       3697 : }
    2435                 :            : 
    2436                 :            : 
    2437                 :            : // DataSequence ==============================================================
    2438                 :            : 
    2439                 :       7964 : ScChart2DataSequence::Item::Item() :
    2440                 :       7964 :     mfValue(0.0), mbIsValue(false)
    2441                 :            : {
    2442                 :       7964 :     ::rtl::math::setNan(&mfValue);
    2443                 :       7964 : }
    2444                 :            : 
    2445                 :       4770 : ScChart2DataSequence::HiddenRangeListener::HiddenRangeListener(ScChart2DataSequence& rParent) :
    2446                 :       4770 :     mrParent(rParent)
    2447                 :            : {
    2448                 :       4770 : }
    2449                 :            : 
    2450                 :       4770 : ScChart2DataSequence::HiddenRangeListener::~HiddenRangeListener()
    2451                 :            : {
    2452         [ -  + ]:       9540 : }
    2453                 :            : 
    2454                 :          0 : void ScChart2DataSequence::HiddenRangeListener::notify()
    2455                 :            : {
    2456                 :          0 :     mrParent.setDataChangedHint(true);
    2457                 :          0 : }
    2458                 :            : 
    2459                 :       4770 : ScChart2DataSequence::ScChart2DataSequence( ScDocument* pDoc,
    2460                 :            :         const uno::Reference < chart2::data::XDataProvider >& xDP,
    2461                 :            :         vector<ScTokenRef>* pTokens,
    2462                 :            :         bool bIncludeHiddenCells )
    2463                 :            :     : m_bIncludeHiddenCells( bIncludeHiddenCells)
    2464                 :            :     , m_nObjectId( 0 )
    2465                 :            :     , m_pDocument( pDoc)
    2466                 :            :     , m_pTokens(pTokens)
    2467                 :            :     , m_pRangeIndices(NULL)
    2468                 :            :     , m_pExtRefListener(NULL)
    2469                 :            :     , m_xDataProvider( xDP)
    2470                 :            :     , m_aPropSet(lcl_GetDataSequencePropertyMap())
    2471                 :            :     , m_pHiddenListener(NULL)
    2472                 :            :     , m_pValueListener( NULL )
    2473                 :            :     , m_bGotDataChangedHint(false)
    2474 [ +  - ][ +  - ]:       4770 :     , m_bExtDataRebuildQueued(false)
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    2475                 :            : {
    2476                 :            :     OSL_ENSURE(pTokens, "reference token list is null");
    2477                 :            : 
    2478         [ +  - ]:       4770 :     if ( m_pDocument )
    2479                 :            :     {
    2480         [ +  - ]:       4770 :         m_pDocument->AddUnoObject( *this);
    2481         [ +  - ]:       4770 :         m_nObjectId = m_pDocument->GetNewUnoId();
    2482                 :            :     }
    2483                 :            :     // FIXME: real implementation of identifier and it's mapping to ranges.
    2484                 :            :     // Reuse ScChartListener?
    2485                 :            : 
    2486                 :            :     // BM: don't use names of named ranges but the UI range strings
    2487                 :            : //  String  aStr;
    2488                 :            : //  rRangeList->Format( aStr, SCR_ABS_3D, m_pDocument );
    2489                 :            : //    m_aIdentifier = ::rtl::OUString( aStr );
    2490                 :            : 
    2491                 :            : //      m_aIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ID_"));
    2492                 :            : //      static sal_Int32 nID = 0;
    2493                 :            : //      m_aIdentifier += ::rtl::OUString::valueOf( ++nID);
    2494                 :       4770 : }
    2495                 :            : 
    2496 [ +  - ][ +  - ]:       4770 : ScChart2DataSequence::~ScChart2DataSequence()
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    2497                 :            : {
    2498         [ +  + ]:       4770 :     if ( m_pDocument )
    2499                 :            :     {
    2500         [ +  - ]:       4594 :         m_pDocument->RemoveUnoObject( *this);
    2501         [ +  - ]:       4594 :         if (m_pHiddenListener.get())
    2502                 :            :         {
    2503         [ +  - ]:       4594 :             ScChartListenerCollection* pCLC = m_pDocument->GetChartListenerCollection();
    2504         [ +  - ]:       4594 :             if (pCLC)
    2505         [ +  - ]:       4594 :                 pCLC->EndListeningHiddenRange(m_pHiddenListener.get());
    2506                 :            :         }
    2507         [ +  - ]:       4594 :         StopListeningToAllExternalRefs();
    2508                 :            :     }
    2509                 :            : 
    2510 [ +  - ][ +  - ]:       4770 :     delete m_pValueListener;
    2511         [ -  + ]:       9540 : }
    2512                 :            : 
    2513                 :          0 : void ScChart2DataSequence::RefChanged()
    2514                 :            : {
    2515 [ #  # ][ #  # ]:          0 :     if( m_pValueListener && !m_aValueListeners.empty() )
                 [ #  # ]
    2516                 :            :     {
    2517                 :          0 :         m_pValueListener->EndListeningAll();
    2518                 :            : 
    2519         [ #  # ]:          0 :         if( m_pDocument )
    2520                 :            :         {
    2521                 :          0 :             ScChartListenerCollection* pCLC = NULL;
    2522         [ #  # ]:          0 :             if (m_pHiddenListener.get())
    2523                 :            :             {
    2524         [ #  # ]:          0 :                 pCLC = m_pDocument->GetChartListenerCollection();
    2525         [ #  # ]:          0 :                 if (pCLC)
    2526         [ #  # ]:          0 :                     pCLC->EndListeningHiddenRange(m_pHiddenListener.get());
    2527                 :            :             }
    2528                 :            : 
    2529 [ #  # ][ #  # ]:          0 :             vector<ScTokenRef>::const_iterator itr = m_pTokens->begin(), itrEnd = m_pTokens->end();
    2530 [ #  # ][ #  # ]:          0 :             for (; itr != itrEnd; ++itr)
    2531                 :            :             {
    2532                 :          0 :                 ScRange aRange;
    2533 [ #  # ][ #  # ]:          0 :                 if (!ScRefTokenHelper::getRangeFromToken(aRange, *itr))
    2534                 :          0 :                     continue;
    2535                 :            : 
    2536         [ #  # ]:          0 :                 m_pDocument->StartListeningArea(aRange, m_pValueListener);
    2537         [ #  # ]:          0 :                 if (pCLC)
    2538         [ #  # ]:          0 :                     pCLC->StartListeningHiddenRange(aRange, m_pHiddenListener.get());
    2539                 :            :             }
    2540                 :            :         }
    2541                 :            :     }
    2542                 :          0 : }
    2543                 :            : 
    2544                 :       6245 : void ScChart2DataSequence::BuildDataCache()
    2545                 :            : {
    2546                 :       6245 :     m_bExtDataRebuildQueued = false;
    2547                 :            : 
    2548         [ +  + ]:       6245 :     if (!m_aDataArray.empty())
    2549                 :            :         return;
    2550                 :            : 
    2551         [ +  - ]:       4000 :     if (!m_pTokens.get())
    2552                 :            :     {
    2553                 :            :         OSL_FAIL("m_pTokens == NULL!  Something is wrong.");
    2554                 :            :         return;
    2555                 :            :     }
    2556                 :            : 
    2557         [ +  - ]:       4000 :     StopListeningToAllExternalRefs();
    2558                 :            : 
    2559         [ +  - ]:       4000 :     ::std::list<sal_Int32> aHiddenValues;
    2560                 :       4000 :     sal_Int32 nDataCount = 0;
    2561                 :       4000 :     sal_Int32 nHiddenValueCount = 0;
    2562                 :            : 
    2563 [ +  - ][ +  - ]:       8000 :     for (vector<ScTokenRef>::const_iterator itr = m_pTokens->begin(), itrEnd = m_pTokens->end();
         [ +  - ][ +  + ]
    2564                 :            :           itr != itrEnd; ++itr)
    2565                 :            :     {
    2566 [ +  - ][ -  + ]:       4000 :         if (ScRefTokenHelper::isExternalRef(*itr))
    2567                 :            :         {
    2568         [ #  # ]:          0 :             nDataCount += FillCacheFromExternalRef(*itr);
    2569                 :            :         }
    2570                 :            :         else
    2571                 :            :         {
    2572                 :       4000 :             ScRange aRange;
    2573 [ -  + ][ +  - ]:       4000 :             if (!ScRefTokenHelper::getRangeFromToken(aRange, *itr))
    2574                 :          0 :                 continue;
    2575                 :            : 
    2576                 :       4000 :             SCCOL nLastCol = -1;
    2577                 :       4000 :             SCROW nLastRow = -1;
    2578         [ +  + ]:       8000 :             for (SCTAB nTab = aRange.aStart.Tab(); nTab <= aRange.aEnd.Tab(); ++nTab)
    2579                 :            :             {
    2580         [ +  + ]:      10328 :                 for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol)
    2581                 :            :                 {
    2582         [ +  + ]:      15333 :                     for (SCROW nRow = aRange.aStart.Row(); nRow <= aRange.aEnd.Row(); ++nRow)
    2583                 :            :                     {
    2584         [ +  - ]:       9005 :                         bool bColHidden = m_pDocument->ColHidden(nCol, nTab, NULL, &nLastCol);
    2585         [ +  - ]:       9005 :                         bool bRowHidden = m_pDocument->RowHidden(nRow, nTab, NULL, &nLastRow);
    2586                 :            : 
    2587 [ +  + ][ +  + ]:       9005 :                         if (bColHidden || bRowHidden)
    2588                 :            :                         {
    2589                 :            :                             // hidden cell
    2590                 :       1041 :                             ++nHiddenValueCount;
    2591         [ +  - ]:       1041 :                             aHiddenValues.push_back(nDataCount-1);
    2592                 :            : 
    2593         [ +  - ]:       1041 :                             if( !m_bIncludeHiddenCells )
    2594                 :       1041 :                                 continue;
    2595                 :            :                         }
    2596                 :            : 
    2597         [ +  - ]:       7964 :                         m_aDataArray.push_back(Item());
    2598         [ +  - ]:       7964 :                         Item& rItem = m_aDataArray.back();
    2599                 :       7964 :                         ++nDataCount;
    2600                 :            : 
    2601                 :       7964 :                         ScAddress aAdr(nCol, nRow, nTab);
    2602         [ +  - ]:       7964 :                         ScBaseCell* pCell = m_pDocument->GetCell(aAdr);
    2603         [ +  + ]:       7964 :                         if (!pCell)
    2604                 :          8 :                             continue;
    2605                 :            : 
    2606 [ +  - ][ +  + ]:       7956 :                         if (pCell->HasStringData())
    2607         [ +  - ]:       5284 :                             rItem.maString = pCell->GetStringData();
    2608                 :            :                         else
    2609                 :            :                         {
    2610         [ +  - ]:       2672 :                             String aStr;
    2611         [ +  - ]:       2672 :                             m_pDocument->GetString(nCol, nRow, nTab, aStr);
    2612 [ +  - ][ +  - ]:       2672 :                             rItem.maString = aStr;
    2613                 :            :                         }
    2614                 :            : 
    2615      [ +  +  + ]:       7956 :                         switch (pCell->GetCellType())
    2616                 :            :                         {
    2617                 :            :                             case CELLTYPE_VALUE:
    2618                 :       2469 :                                 rItem.mfValue = static_cast< ScValueCell*>(pCell)->GetValue();
    2619                 :       2469 :                                 rItem.mbIsValue = true;
    2620                 :       2469 :                             break;
    2621                 :            :                             case CELLTYPE_FORMULA:
    2622                 :            :                             {
    2623         [ +  - ]:        203 :                                 ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
    2624         [ +  - ]:        203 :                                 sal_uInt16 nErr = pFCell->GetErrCode();
    2625         [ -  + ]:        203 :                                 if (nErr)
    2626                 :          0 :                                     break;
    2627                 :            : 
    2628 [ +  - ][ +  - ]:        203 :                                 if (pFCell->HasValueData())
    2629                 :            :                                 {
    2630         [ +  - ]:        203 :                                     rItem.mfValue = pFCell->GetValue();
    2631                 :        203 :                                     rItem.mbIsValue = true;
    2632                 :            :                                 }
    2633                 :            :                             }
    2634                 :       9005 :                             break;
    2635                 :            : #if OSL_DEBUG_LEVEL > 0
    2636                 :            :                             case CELLTYPE_DESTROYED:
    2637                 :            : #endif
    2638                 :            :                             case CELLTYPE_EDIT:
    2639                 :            :                             case CELLTYPE_NONE:
    2640                 :            :                             case CELLTYPE_NOTE:
    2641                 :            :                             case CELLTYPE_STRING:
    2642                 :            :                             case CELLTYPE_SYMBOLS:
    2643                 :            :                             default:
    2644                 :            :                                 ; // do nothing
    2645                 :            :                         }
    2646                 :            :                     }
    2647                 :            :                 }
    2648                 :            :             }
    2649                 :            :         }
    2650                 :            :     }
    2651                 :            : 
    2652                 :            :     // convert the hidden cell list to sequence.
    2653         [ +  - ]:       4000 :     m_aHiddenValues.realloc(nHiddenValueCount);
    2654         [ +  - ]:       4000 :     sal_Int32* pArr = m_aHiddenValues.getArray();
    2655 [ +  - ][ +  - ]:       4000 :     ::std::list<sal_Int32>::const_iterator itr = aHiddenValues.begin(), itrEnd = aHiddenValues.end();
    2656 [ +  - ][ +  - ]:       5041 :     for (;itr != itrEnd; ++itr, ++pArr)
                 [ +  + ]
    2657         [ +  - ]:       1041 :         *pArr = *itr;
    2658                 :            : 
    2659                 :            :     // Clear the data series cache when the array is re-built.
    2660         [ +  - ]:       6245 :     m_aMixedDataCache.realloc(0);
    2661                 :            : }
    2662                 :            : 
    2663                 :          0 : void ScChart2DataSequence::RebuildDataCache()
    2664                 :            : {
    2665         [ #  # ]:          0 :     if (!m_bExtDataRebuildQueued)
    2666                 :            :     {
    2667                 :          0 :         m_aDataArray.clear();
    2668 [ #  # ][ #  # ]:          0 :         m_pDocument->BroadcastUno(ScHint(SC_HINT_DATACHANGED, ScAddress(), NULL));
                 [ #  # ]
    2669                 :          0 :         m_bExtDataRebuildQueued = true;
    2670                 :          0 :         m_bGotDataChangedHint = true;
    2671                 :            :     }
    2672                 :          0 : }
    2673                 :            : 
    2674                 :          0 : sal_Int32 ScChart2DataSequence::FillCacheFromExternalRef(const ScTokenRef& pToken)
    2675                 :            : {
    2676         [ #  # ]:          0 :     ScExternalRefManager* pRefMgr = m_pDocument->GetExternalRefManager();
    2677                 :          0 :     ScRange aRange;
    2678 [ #  # ][ #  # ]:          0 :     if (!ScRefTokenHelper::getRangeFromToken(aRange, pToken, true))
    2679                 :          0 :         return 0;
    2680                 :            : 
    2681         [ #  # ]:          0 :     sal_uInt16 nFileId = pToken->GetIndex();
    2682         [ #  # ]:          0 :     const String& rTabName = pToken->GetString();
    2683 [ #  # ][ #  # ]:          0 :     ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, aRange, NULL);
    2684         [ #  # ]:          0 :     if (!pArray)
    2685                 :            :         // no external data exists for this range.
    2686                 :          0 :         return 0;
    2687                 :            : 
    2688                 :            :     // Start listening for this external document.
    2689         [ #  # ]:          0 :     ExternalRefListener* pExtRefListener = GetExtRefListener();
    2690         [ #  # ]:          0 :     pRefMgr->addLinkListener(nFileId, pExtRefListener);
    2691         [ #  # ]:          0 :     pExtRefListener->addFileId(nFileId);
    2692                 :            : 
    2693 [ #  # ][ #  # ]:          0 :     ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, rTabName, false, NULL);
    2694                 :          0 :     sal_Int32 nDataCount = 0;
    2695 [ #  # ][ #  # ]:          0 :     for (FormulaToken* p = pArray->First(); p; p = pArray->Next())
                 [ #  # ]
    2696                 :            :     {
    2697                 :            :         // Cached external range is always represented as a single
    2698                 :            :         // matrix token, although that might change in the future when
    2699                 :            :         // we introduce a new token type to store multi-table range
    2700                 :            :         // data.
    2701                 :            : 
    2702         [ #  # ]:          0 :         if (p->GetType() != svMatrix)
    2703                 :            :         {
    2704                 :            :             OSL_FAIL("Cached array is not a matrix token.");
    2705                 :          0 :             continue;
    2706                 :            :         }
    2707                 :            : 
    2708         [ #  # ]:          0 :         const ScMatrix* pMat = static_cast<ScToken*>(p)->GetMatrix();
    2709                 :            :         SCSIZE nCSize, nRSize;
    2710         [ #  # ]:          0 :         pMat->GetDimensions(nCSize, nRSize);
    2711         [ #  # ]:          0 :         for (SCSIZE nC = 0; nC < nCSize; ++nC)
    2712                 :            :         {
    2713         [ #  # ]:          0 :             for (SCSIZE nR = 0; nR < nRSize; ++nR)
    2714                 :            :             {
    2715 [ #  # ][ #  # ]:          0 :                 if (pMat->IsValue(nC, nR) || pMat->IsBoolean(nC, nR))
         [ #  # ][ #  # ]
                 [ #  # ]
    2716                 :            :                 {
    2717         [ #  # ]:          0 :                     m_aDataArray.push_back(Item());
    2718         [ #  # ]:          0 :                     Item& rItem = m_aDataArray.back();
    2719                 :          0 :                     ++nDataCount;
    2720                 :            : 
    2721                 :          0 :                     rItem.mbIsValue = true;
    2722         [ #  # ]:          0 :                     rItem.mfValue = pMat->GetDouble(nC, nR);
    2723                 :            : 
    2724         [ #  # ]:          0 :                     SvNumberFormatter* pFormatter = m_pDocument->GetFormatTable();
    2725         [ #  # ]:          0 :                     if (pFormatter)
    2726                 :            :                     {
    2727         [ #  # ]:          0 :                         String aStr;
    2728                 :          0 :                         const double fVal = rItem.mfValue;
    2729                 :          0 :                         Color* pColor = NULL;
    2730                 :          0 :                         sal_uInt32 nFmt = 0;
    2731         [ #  # ]:          0 :                         if (pTable)
    2732                 :            :                         {
    2733                 :            :                             // Get the correct format index from the cache.
    2734                 :          0 :                             SCCOL nCol = aRange.aStart.Col() + static_cast<SCCOL>(nC);
    2735                 :          0 :                             SCROW nRow = aRange.aStart.Row() + static_cast<SCROW>(nR);
    2736 [ #  # ][ #  # ]:          0 :                             pTable->getCell(nCol, nRow, &nFmt);
    2737                 :            :                         }
    2738         [ #  # ]:          0 :                         pFormatter->GetOutputString(fVal, nFmt, aStr, &pColor);
    2739 [ #  # ][ #  # ]:          0 :                         rItem.maString = aStr;
    2740                 :            :                     }
    2741                 :            :                 }
    2742 [ #  # ][ #  # ]:          0 :                 else if (pMat->IsString(nC, nR))
    2743                 :            :                 {
    2744         [ #  # ]:          0 :                     m_aDataArray.push_back(Item());
    2745         [ #  # ]:          0 :                     Item& rItem = m_aDataArray.back();
    2746                 :          0 :                     ++nDataCount;
    2747                 :            : 
    2748                 :          0 :                     rItem.mbIsValue = false;
    2749         [ #  # ]:          0 :                     rItem.maString = pMat->GetString(nC, nR);
    2750                 :            :                 }
    2751                 :            :             }
    2752                 :            :         }
    2753                 :            :     }
    2754 [ #  # ][ #  # ]:          0 :     return nDataCount;
    2755                 :            : }
    2756                 :            : 
    2757                 :          0 : void ScChart2DataSequence::UpdateTokensFromRanges(const ScRangeList& rRanges)
    2758                 :            : {
    2759         [ #  # ]:          0 :     if (!m_pRangeIndices.get())
    2760                 :          0 :         return;
    2761                 :            : 
    2762         [ #  # ]:          0 :     for ( size_t i = 0, nCount = rRanges.size(); i < nCount; ++i )
    2763                 :            :     {
    2764                 :          0 :         ScTokenRef pToken;
    2765         [ #  # ]:          0 :         const ScRange* pRange = rRanges[i];
    2766                 :            :         OSL_ENSURE(pRange, "range object is NULL.");
    2767                 :            : 
    2768         [ #  # ]:          0 :         ScRefTokenHelper::getTokenFromRange(pToken, *pRange);
    2769         [ #  # ]:          0 :         sal_uInt32 nOrigPos = (*m_pRangeIndices)[i];
    2770         [ #  # ]:          0 :         (*m_pTokens)[nOrigPos] = pToken;
    2771         [ #  # ]:          0 :     }
    2772                 :            : 
    2773                 :          0 :     RefChanged();
    2774                 :            : 
    2775                 :            :     // any change of the range address is broadcast to value (modify) listeners
    2776         [ #  # ]:          0 :     if ( !m_aValueListeners.empty() )
    2777                 :          0 :         m_bGotDataChangedHint = true;
    2778                 :            : }
    2779                 :            : 
    2780                 :          0 : ScChart2DataSequence::ExternalRefListener* ScChart2DataSequence::GetExtRefListener()
    2781                 :            : {
    2782         [ #  # ]:          0 :     if (!m_pExtRefListener.get())
    2783         [ #  # ]:          0 :         m_pExtRefListener.reset(new ExternalRefListener(*this, m_pDocument));
    2784                 :            : 
    2785                 :          0 :     return m_pExtRefListener.get();
    2786                 :            : }
    2787                 :            : 
    2788                 :       8594 : void ScChart2DataSequence::StopListeningToAllExternalRefs()
    2789                 :            : {
    2790         [ -  + ]:       8594 :     if (!m_pExtRefListener.get())
    2791                 :       8594 :         return;
    2792                 :            : 
    2793                 :          0 :     const boost::unordered_set<sal_uInt16>& rFileIds = m_pExtRefListener->getAllFileIds();
    2794 [ #  # ][ #  # ]:          0 :     boost::unordered_set<sal_uInt16>::const_iterator itr = rFileIds.begin(), itrEnd = rFileIds.end();
    2795         [ #  # ]:          0 :     ScExternalRefManager* pRefMgr = m_pDocument->GetExternalRefManager();
    2796         [ #  # ]:          0 :     for (; itr != itrEnd; ++itr)
    2797 [ #  # ][ #  # ]:          0 :         pRefMgr->removeLinkListener(*itr, m_pExtRefListener.get());
    2798                 :            : 
    2799         [ #  # ]:       8594 :     m_pExtRefListener.reset(NULL);
    2800                 :            : }
    2801                 :            : 
    2802                 :          0 : void ScChart2DataSequence::CopyData(const ScChart2DataSequence& r)
    2803                 :            : {
    2804         [ #  # ]:          0 :     if (!m_pDocument)
    2805                 :            :     {
    2806                 :            :         OSL_FAIL("document instance is NULL!?");
    2807                 :          0 :         return;
    2808                 :            :     }
    2809                 :            : 
    2810         [ #  # ]:          0 :     list<Item> aDataArray(r.m_aDataArray);
    2811         [ #  # ]:          0 :     m_aDataArray.swap(aDataArray);
    2812                 :            : 
    2813         [ #  # ]:          0 :     m_aHiddenValues = r.m_aHiddenValues;
    2814                 :          0 :     m_aRole = r.m_aRole;
    2815                 :            : 
    2816         [ #  # ]:          0 :     if (r.m_pRangeIndices.get())
    2817 [ #  # ][ #  # ]:          0 :         m_pRangeIndices.reset(new vector<sal_uInt32>(*r.m_pRangeIndices));
                 [ #  # ]
    2818                 :            : 
    2819         [ #  # ]:          0 :     if (r.m_pExtRefListener.get())
    2820                 :            :     {
    2821                 :            :         // Re-register all external files that the old instance was
    2822                 :            :         // listening to.
    2823                 :            : 
    2824         [ #  # ]:          0 :         ScExternalRefManager* pRefMgr = m_pDocument->GetExternalRefManager();
    2825 [ #  # ][ #  # ]:          0 :         m_pExtRefListener.reset(new ExternalRefListener(*this, m_pDocument));
                 [ #  # ]
    2826                 :          0 :         const boost::unordered_set<sal_uInt16>& rFileIds = r.m_pExtRefListener->getAllFileIds();
    2827 [ #  # ][ #  # ]:          0 :         boost::unordered_set<sal_uInt16>::const_iterator itr = rFileIds.begin(), itrEnd = rFileIds.end();
    2828         [ #  # ]:          0 :         for (; itr != itrEnd; ++itr)
    2829                 :            :         {
    2830 [ #  # ][ #  # ]:          0 :             pRefMgr->addLinkListener(*itr, m_pExtRefListener.get());
    2831 [ #  # ][ #  # ]:          0 :             m_pExtRefListener->addFileId(*itr);
    2832                 :            :         }
    2833                 :          0 :     }
    2834                 :            : }
    2835                 :            : 
    2836                 :        176 : void ScChart2DataSequence::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
    2837                 :            : {
    2838         [ +  - ]:        176 :     if ( rHint.ISA( SfxSimpleHint ) )
    2839                 :            :     {
    2840                 :        176 :         sal_uLong nId = static_cast<const SfxSimpleHint&>(rHint).GetId();
    2841         [ +  - ]:        176 :         if ( nId ==SFX_HINT_DYING )
    2842                 :            :         {
    2843                 :        176 :             m_pDocument = NULL;
    2844                 :            :         }
    2845         [ #  # ]:          0 :         else if ( nId == SFX_HINT_DATACHANGED )
    2846                 :            :         {
    2847                 :            :             // delayed broadcast as in ScCellRangesBase
    2848                 :            : 
    2849 [ #  # ][ #  # ]:          0 :             if ( m_bGotDataChangedHint && m_pDocument )
    2850                 :            :             {
    2851                 :          0 :                 m_aDataArray.clear();
    2852         [ #  # ]:          0 :                 lang::EventObject aEvent;
    2853         [ #  # ]:          0 :                 aEvent.Source.set((cppu::OWeakObject*)this);
    2854                 :            : 
    2855         [ #  # ]:          0 :                 if( m_pDocument )
    2856                 :            :                 {
    2857         [ #  # ]:          0 :                     for ( sal_uInt16 n=0; n<m_aValueListeners.size(); n++ )
    2858 [ #  # ][ #  # ]:          0 :                         m_pDocument->AddUnoListenerCall( m_aValueListeners[n], aEvent );
    2859                 :            :                 }
    2860                 :            : 
    2861         [ #  # ]:          0 :                 m_bGotDataChangedHint = false;
    2862                 :            :             }
    2863                 :            :         }
    2864         [ #  # ]:          0 :         else if ( nId == SC_HINT_CALCALL )
    2865                 :            :         {
    2866                 :            :             // broadcast from DoHardRecalc - set m_bGotDataChangedHint
    2867                 :            :             // (SFX_HINT_DATACHANGED follows separately)
    2868                 :            : 
    2869         [ #  # ]:          0 :             if ( !m_aValueListeners.empty() )
    2870                 :          0 :                 m_bGotDataChangedHint = true;
    2871                 :            :         }
    2872                 :            :     }
    2873         [ #  # ]:          0 :     else if ( rHint.ISA( ScUpdateRefHint ) )
    2874                 :            :     {
    2875                 :            :         // Create a range list from the token list, have the range list
    2876                 :            :         // updated, and bring the change back to the token list.
    2877                 :            : 
    2878         [ #  # ]:          0 :         ScRangeList aRanges;
    2879 [ #  # ][ #  # ]:          0 :         m_pRangeIndices.reset(new vector<sal_uInt32>());
                 [ #  # ]
    2880 [ #  # ][ #  # ]:          0 :         vector<ScTokenRef>::const_iterator itrBeg = m_pTokens->begin(), itrEnd = m_pTokens->end();
    2881 [ #  # ][ #  # ]:          0 :         for (vector<ScTokenRef>::const_iterator itr = itrBeg ;itr != itrEnd; ++itr)
    2882                 :            :         {
    2883 [ #  # ][ #  # ]:          0 :             if (!ScRefTokenHelper::isExternalRef(*itr))
    2884                 :            :             {
    2885                 :          0 :                 ScRange aRange;
    2886         [ #  # ]:          0 :                 ScRefTokenHelper::getRangeFromToken(aRange, *itr);
    2887         [ #  # ]:          0 :                 aRanges.Append(aRange);
    2888         [ #  # ]:          0 :                 sal_uInt32 nPos = distance(itrBeg, itr);
    2889         [ #  # ]:          0 :                 m_pRangeIndices->push_back(nPos);
    2890                 :            :             }
    2891                 :            :         }
    2892                 :            : 
    2893                 :            :         OSL_ENSURE(m_pRangeIndices->size() == static_cast<size_t>(aRanges.size()),
    2894                 :            :                    "range list and range index list have different sizes.");
    2895                 :            : 
    2896                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2897                 :          0 :         auto_ptr<ScRangeList> pUndoRanges;
    2898                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
    2899         [ #  # ]:          0 :         if ( m_pDocument->HasUnoRefUndo() )
    2900 [ #  # ][ #  # ]:          0 :             pUndoRanges.reset(new ScRangeList(aRanges));
    2901                 :            : 
    2902                 :          0 :         const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
    2903                 :            :         bool bChanged = aRanges.UpdateReference(
    2904         [ #  # ]:          0 :             rRef.GetMode(), m_pDocument, rRef.GetRange(), rRef.GetDx(), rRef.GetDy(), rRef.GetDz());
    2905                 :            : 
    2906         [ #  # ]:          0 :         if (bChanged)
    2907                 :            :         {
    2908                 :            :             OSL_ENSURE(m_pRangeIndices->size() == aRanges.size(),
    2909                 :            :                        "range list and range index list have different sizes after the reference update.");
    2910                 :            : 
    2911                 :            :             // Bring the change back from the range list to the token list.
    2912         [ #  # ]:          0 :             UpdateTokensFromRanges(aRanges);
    2913                 :            : 
    2914         [ #  # ]:          0 :             if (pUndoRanges.get())
    2915         [ #  # ]:          0 :                 m_pDocument->AddUnoRefChange(m_nObjectId, *pUndoRanges);
    2916 [ #  # ][ #  # ]:          0 :         }
    2917                 :            :     }
    2918         [ #  # ]:          0 :     else if ( rHint.ISA( ScUnoRefUndoHint ) )
    2919                 :            :     {
    2920                 :          0 :         const ScUnoRefUndoHint& rUndoHint = static_cast<const ScUnoRefUndoHint&>(rHint);
    2921                 :            : 
    2922                 :            :         do
    2923                 :            :         {
    2924         [ #  # ]:          0 :             if (rUndoHint.GetObjectId() != m_nObjectId)
    2925                 :          0 :                 break;
    2926                 :            : 
    2927                 :            :             // The hint object provides the old ranges.  Restore the old state
    2928                 :            :             // from these ranges.
    2929                 :            : 
    2930 [ #  # ][ #  # ]:          0 :             if (!m_pRangeIndices.get() || m_pRangeIndices->empty())
                 [ #  # ]
    2931                 :            :             {
    2932                 :            :                 OSL_FAIL(" faulty range indices");
    2933                 :          0 :                 break;
    2934                 :            :             }
    2935                 :            : 
    2936                 :          0 :             const ScRangeList& rRanges = rUndoHint.GetRanges();
    2937                 :            : 
    2938                 :          0 :             size_t nCount = rRanges.size();
    2939         [ #  # ]:          0 :             if (nCount != m_pRangeIndices->size())
    2940                 :            :             {
    2941                 :            :                 OSL_FAIL("range count and range index count differ.");
    2942                 :          0 :                 break;
    2943                 :            :             }
    2944                 :            : 
    2945                 :          0 :             UpdateTokensFromRanges(rRanges);
    2946                 :            :         }
    2947                 :            :         while (false);
    2948                 :            :     }
    2949                 :        176 : }
    2950                 :            : 
    2951                 :            : 
    2952                 :        178 : IMPL_LINK( ScChart2DataSequence, ValueListenerHdl, SfxHint*, pHint )
    2953                 :            : {
    2954 [ +  - ][ +  - ]:        356 :     if ( m_pDocument && pHint && pHint->ISA( SfxSimpleHint ) &&
           [ +  -  +  - ]
                 [ +  - ]
    2955                 :        178 :             ((const SfxSimpleHint*)pHint)->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING) )
    2956                 :            :     {
    2957                 :            :         //  This may be called several times for a single change, if several formulas
    2958                 :            :         //  in the range are notified. So only a flag is set that is checked when
    2959                 :            :         //  SFX_HINT_DATACHANGED is received.
    2960                 :            : 
    2961                 :        178 :         setDataChangedHint(true);
    2962                 :            :     }
    2963                 :        178 :     return 0;
    2964                 :            : }
    2965                 :            : 
    2966                 :            : // ----------------------------------------------------------------------------
    2967                 :            : 
    2968                 :          0 : ScChart2DataSequence::ExternalRefListener::ExternalRefListener(
    2969                 :            :     ScChart2DataSequence& rParent, ScDocument* pDoc) :
    2970                 :            :     ScExternalRefManager::LinkListener(),
    2971                 :            :     mrParent(rParent),
    2972         [ #  # ]:          0 :     mpDoc(pDoc)
    2973                 :            : {
    2974                 :          0 : }
    2975                 :            : 
    2976         [ #  # ]:          0 : ScChart2DataSequence::ExternalRefListener::~ExternalRefListener()
    2977                 :            : {
    2978 [ #  # ][ #  # ]:          0 :     if (!mpDoc || mpDoc->IsInDtorClear())
                 [ #  # ]
    2979                 :            :         // The document is being destroyed.  Do nothing.
    2980                 :            :         return;
    2981                 :            : 
    2982                 :            :     // Make sure to remove all pointers to this object.
    2983 [ #  # ][ #  # ]:          0 :     mpDoc->GetExternalRefManager()->removeLinkListener(this);
                 [ #  # ]
    2984         [ #  # ]:          0 : }
    2985                 :            : 
    2986                 :          0 : void ScChart2DataSequence::ExternalRefListener::notify(sal_uInt16 nFileId, ScExternalRefManager::LinkUpdateType eType)
    2987                 :            : {
    2988      [ #  #  # ]:          0 :     switch (eType)
    2989                 :            :     {
    2990                 :            :         case ScExternalRefManager::LINK_MODIFIED:
    2991                 :            :         {
    2992         [ #  # ]:          0 :             if (maFileIds.count(nFileId))
    2993                 :            :                 // We are listening to this external document.
    2994                 :          0 :                 mrParent.RebuildDataCache();
    2995                 :            :         }
    2996                 :          0 :         break;
    2997                 :            :         case ScExternalRefManager::LINK_BROKEN:
    2998                 :          0 :             removeFileId(nFileId);
    2999                 :          0 :         break;
    3000                 :            :     }
    3001                 :          0 : }
    3002                 :            : 
    3003                 :          0 : void ScChart2DataSequence::ExternalRefListener::addFileId(sal_uInt16 nFileId)
    3004                 :            : {
    3005                 :          0 :     maFileIds.insert(nFileId);
    3006                 :          0 : }
    3007                 :            : 
    3008                 :          0 : void ScChart2DataSequence::ExternalRefListener::removeFileId(sal_uInt16 nFileId)
    3009                 :            : {
    3010                 :          0 :     maFileIds.erase(nFileId);
    3011                 :          0 : }
    3012                 :            : 
    3013                 :          0 : const boost::unordered_set<sal_uInt16>& ScChart2DataSequence::ExternalRefListener::getAllFileIds()
    3014                 :            : {
    3015                 :          0 :     return maFileIds;
    3016                 :            : }
    3017                 :            : 
    3018                 :            : // ----------------------------------------------------------------------------
    3019                 :            : 
    3020                 :       4200 : uno::Sequence< uno::Any> SAL_CALL ScChart2DataSequence::getData()
    3021                 :            :             throw ( uno::RuntimeException)
    3022                 :            : {
    3023         [ +  - ]:       4200 :     SolarMutexGuard aGuard;
    3024         [ -  + ]:       4200 :     if ( !m_pDocument)
    3025         [ #  # ]:          0 :         throw uno::RuntimeException();
    3026                 :            : 
    3027         [ +  - ]:       4200 :     BuildDataCache();
    3028                 :            : 
    3029         [ +  + ]:       4200 :     if (!m_aMixedDataCache.getLength())
    3030                 :            :     {
    3031                 :            :         // Build a cache for the 1st time...
    3032                 :            : 
    3033                 :       3821 :         sal_Int32 nCount = m_aDataArray.size();
    3034         [ +  - ]:       3821 :         m_aMixedDataCache.realloc(nCount);
    3035         [ +  - ]:       3821 :         uno::Any* pArr = m_aMixedDataCache.getArray();
    3036                 :       3821 :         ::std::list<Item>::const_iterator itr = m_aDataArray.begin(), itrEnd = m_aDataArray.end();
    3037         [ +  + ]:      11606 :         for (; itr != itrEnd; ++itr, ++pArr)
    3038                 :            :         {
    3039         [ +  + ]:       7785 :             if (itr->mbIsValue)
    3040         [ +  - ]:       2672 :                 *pArr <<= itr->mfValue;
    3041                 :            :             else
    3042         [ +  - ]:       5113 :                 *pArr <<= itr->maString;
    3043                 :            :         }
    3044                 :            :     }
    3045 [ +  - ][ +  - ]:       4200 :     return m_aMixedDataCache;
    3046                 :            : }
    3047                 :            : 
    3048                 :            : // XNumericalDataSequence --------------------------------------------------
    3049                 :            : 
    3050                 :        764 : uno::Sequence< double > SAL_CALL ScChart2DataSequence::getNumericalData()
    3051                 :            :             throw ( uno::RuntimeException)
    3052                 :            : {
    3053         [ +  - ]:        764 :     SolarMutexGuard aGuard;
    3054         [ -  + ]:        764 :     if ( !m_pDocument)
    3055         [ #  # ]:          0 :         throw uno::RuntimeException();
    3056                 :            : 
    3057         [ +  - ]:        764 :     BuildDataCache();
    3058                 :            : 
    3059                 :            :     double fNAN;
    3060                 :        764 :     ::rtl::math::setNan(&fNAN);
    3061                 :            : 
    3062                 :        764 :     sal_Int32 nCount = m_aDataArray.size();
    3063         [ +  - ]:        764 :     uno::Sequence<double> aSeq(nCount);
    3064         [ +  - ]:        764 :     double* pArr = aSeq.getArray();
    3065                 :        764 :     ::std::list<Item>::const_iterator itr = m_aDataArray.begin(), itrEnd = m_aDataArray.end();
    3066         [ +  + ]:       4687 :     for (; itr != itrEnd; ++itr, ++pArr)
    3067         [ +  + ]:       3923 :         *pArr = itr->mbIsValue ? itr->mfValue : fNAN;
    3068                 :            : 
    3069         [ +  - ]:        764 :     return aSeq;
    3070                 :            : }
    3071                 :            : 
    3072                 :            : // XTextualDataSequence --------------------------------------------------
    3073                 :            : 
    3074                 :        744 : uno::Sequence< rtl::OUString > SAL_CALL ScChart2DataSequence::getTextualData(  ) throw (uno::RuntimeException)
    3075                 :            : {
    3076         [ +  - ]:        744 :     SolarMutexGuard aGuard;
    3077         [ +  - ]:        744 :     uno::Sequence<rtl::OUString> aSeq;
    3078         [ -  + ]:        744 :     if ( !m_pDocument )
    3079         [ #  # ]:          0 :         throw uno::RuntimeException();
    3080                 :            : 
    3081         [ +  - ]:        744 :     BuildDataCache();
    3082                 :            : 
    3083                 :        744 :     sal_Int32 nCount = m_aDataArray.size();
    3084         [ +  - ]:        744 :     if ( nCount > 0 )
    3085                 :            :     {
    3086 [ +  - ][ +  - ]:        744 :         aSeq =  uno::Sequence<rtl::OUString>(nCount);
                 [ +  - ]
    3087         [ +  - ]:        744 :         rtl::OUString* pArr = aSeq.getArray();
    3088                 :        744 :         ::std::list<Item>::const_iterator itr = m_aDataArray.begin(), itrEnd = m_aDataArray.end();
    3089         [ +  + ]:       1488 :         for(; itr != itrEnd; ++itr, ++pArr)
    3090                 :        744 :             *pArr = itr->maString;
    3091                 :            :     }
    3092 [ #  # ][ #  # ]:          0 :     else if ( m_pTokens.get() && m_pTokens->front() )
         [ #  # ][ #  # ]
    3093                 :            :     {
    3094 [ #  # ][ #  # ]:          0 :         if( m_pTokens->front()->GetType() == svString )
    3095                 :            :         {
    3096 [ #  # ][ #  # ]:          0 :             aSeq = uno::Sequence<rtl::OUString>(1);
                 [ #  # ]
    3097 [ #  # ][ #  # ]:          0 :             aSeq[0] = m_pTokens->front()->GetString();
         [ #  # ][ #  # ]
    3098                 :            :         }
    3099                 :            :     }
    3100                 :            : 
    3101         [ +  - ]:        744 :     return aSeq;
    3102                 :            : }
    3103                 :            : 
    3104                 :      24692 : ::rtl::OUString SAL_CALL ScChart2DataSequence::getSourceRangeRepresentation()
    3105                 :            :             throw ( uno::RuntimeException)
    3106                 :            : {
    3107         [ +  - ]:      24692 :     SolarMutexGuard aGuard;
    3108                 :      24692 :     OUString aStr;
    3109                 :            :     OSL_ENSURE( m_pDocument, "No Document -> no SourceRangeRepresentation" );
    3110 [ +  - ][ +  - ]:      24692 :     if (m_pDocument && m_pTokens.get())
                 [ +  - ]
    3111         [ +  - ]:      24692 :         lcl_convertTokensToString(aStr, *m_pTokens, m_pDocument);
    3112                 :            : 
    3113         [ +  - ]:      24692 :     return aStr;
    3114                 :            : }
    3115                 :            : 
    3116                 :            : namespace {
    3117                 :            : 
    3118                 :            : /**
    3119                 :            :  * This function object is used to accumulatively count the numbers of
    3120                 :            :  * columns and rows in all reference tokens.
    3121                 :            :  */
    3122                 :            : class AccumulateRangeSize : public unary_function<ScTokenRef, void>
    3123                 :            : {
    3124                 :            : public:
    3125                 :         15 :     AccumulateRangeSize() :
    3126                 :         15 :         mnCols(0), mnRows(0) {}
    3127                 :            : 
    3128                 :         30 :     AccumulateRangeSize(const AccumulateRangeSize& r) :
    3129                 :         30 :         mnCols(r.mnCols), mnRows(r.mnRows) {}
    3130                 :            : 
    3131                 :         15 :     void operator() (const ScTokenRef& pToken)
    3132                 :            :     {
    3133                 :         15 :         ScRange r;
    3134         [ +  - ]:         15 :         bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
    3135         [ +  - ]:         15 :         ScRefTokenHelper::getRangeFromToken(r, pToken, bExternal);
    3136         [ +  - ]:         15 :         r.Justify();
    3137                 :         15 :         mnCols += r.aEnd.Col() - r.aStart.Col() + 1;
    3138                 :         15 :         mnRows += r.aEnd.Row() - r.aStart.Row() + 1;
    3139                 :         15 :     }
    3140                 :            : 
    3141                 :         15 :     SCCOL getCols() const { return mnCols; }
    3142                 :         15 :     SCROW getRows() const { return mnRows; }
    3143                 :            : private:
    3144                 :            :     SCCOL mnCols;
    3145                 :            :     SCROW mnRows;
    3146                 :            : };
    3147                 :            : 
    3148                 :            : /**
    3149                 :            :  * This function object is used to generate label strings from a list of
    3150                 :            :  * reference tokens.
    3151                 :            :  */
    3152                 :         60 : class GenerateLabelStrings : public unary_function<ScTokenRef, void>
    3153                 :            : {
    3154                 :            : public:
    3155                 :         15 :     GenerateLabelStrings(sal_Int32 nSize, chart2::data::LabelOrigin eOrigin, bool bColumn) :
    3156         [ +  - ]:         15 :         mpLabels(new Sequence<OUString>(nSize)),
    3157                 :            :         meOrigin(eOrigin),
    3158                 :            :         mnCount(0),
    3159                 :         30 :         mbColumn(bColumn) {}
    3160                 :            : 
    3161                 :         30 :     GenerateLabelStrings(const GenerateLabelStrings& r) :
    3162                 :            :         mpLabels(r.mpLabels),
    3163                 :            :         meOrigin(r.meOrigin),
    3164                 :            :         mnCount(r.mnCount),
    3165                 :         30 :         mbColumn(r.mbColumn) {}
    3166                 :            : 
    3167                 :         15 :     void operator() (const ScTokenRef& pToken)
    3168                 :            :     {
    3169         [ +  - ]:         15 :         bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
    3170                 :         15 :         ScRange aRange;
    3171         [ +  - ]:         15 :         ScRefTokenHelper::getRangeFromToken(aRange, pToken, bExternal);
    3172         [ +  - ]:         15 :         OUString* pArr = mpLabels->getArray();
    3173         [ +  + ]:         15 :         if (mbColumn)
    3174                 :            :         {
    3175         [ +  + ]:         28 :             for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol)
    3176                 :            :             {
    3177         [ +  - ]:         14 :                 if ( meOrigin != chart2::data::LabelOrigin_LONG_SIDE)
    3178                 :            :                 {
    3179 [ +  - ][ +  - ]:         14 :                     String aString = ScGlobal::GetRscString(STR_COLUMN);
    3180         [ +  - ]:         14 :                     aString += ' ';
    3181                 :         14 :                     ScAddress aPos( nCol, 0, 0 );
    3182         [ +  - ]:         14 :                     String aColStr;
    3183         [ +  - ]:         14 :                     aPos.Format( aColStr, SCA_VALID_COL, NULL );
    3184         [ +  - ]:         14 :                     aString += aColStr;
    3185 [ +  - ][ +  - ]:         14 :                     pArr[mnCount] = aString;
                 [ +  - ]
    3186                 :            :                 }
    3187                 :            :                 else //only indices for categories
    3188 [ #  # ][ #  # ]:          0 :                     pArr[mnCount] = String::CreateFromInt32( mnCount+1 );
                 [ #  # ]
    3189                 :         14 :                 ++mnCount;
    3190                 :            :             }
    3191                 :            :         }
    3192                 :            :         else
    3193                 :            :         {
    3194         [ +  + ]:          4 :             for (sal_Int32 nRow = aRange.aStart.Row(); nRow <= aRange.aEnd.Row(); ++nRow)
    3195                 :            :             {
    3196         [ -  + ]:          3 :                 if (meOrigin != chart2::data::LabelOrigin_LONG_SIDE)
    3197                 :            :                 {
    3198 [ #  # ][ #  # ]:          0 :                     String aString = ScGlobal::GetRscString(STR_ROW);
    3199         [ #  # ]:          0 :                     aString += ' ';
    3200 [ #  # ][ #  # ]:          0 :                     aString += String::CreateFromInt32( nRow+1 );
                 [ #  # ]
    3201 [ #  # ][ #  # ]:          0 :                     pArr[mnCount] = aString;
    3202                 :            :                 }
    3203                 :            :                 else //only indices for categories
    3204 [ +  - ][ +  - ]:          3 :                     pArr[mnCount] = String::CreateFromInt32( mnCount+1 );
                 [ +  - ]
    3205                 :          3 :                 ++mnCount;
    3206                 :            :             }
    3207                 :            :         }
    3208                 :         15 :     }
    3209                 :            : 
    3210                 :         15 :     Sequence<OUString> getLabels() const { return *mpLabels; }
    3211                 :            : 
    3212                 :            : private:
    3213                 :            :     GenerateLabelStrings(); // disabled
    3214                 :            : 
    3215                 :            :     shared_ptr< Sequence<OUString> >    mpLabels;
    3216                 :            :     chart2::data::LabelOrigin           meOrigin;
    3217                 :            :     sal_Int32                           mnCount;
    3218                 :            :     bool                                mbColumn;
    3219                 :            : };
    3220                 :            : 
    3221                 :            : }
    3222                 :            : 
    3223                 :         15 : uno::Sequence< ::rtl::OUString > SAL_CALL ScChart2DataSequence::generateLabel(chart2::data::LabelOrigin eOrigin)
    3224                 :            :         throw (uno::RuntimeException)
    3225                 :            : {
    3226         [ +  - ]:         15 :     SolarMutexGuard aGuard;
    3227         [ -  + ]:         15 :     if ( !m_pDocument)
    3228         [ #  # ]:          0 :         throw uno::RuntimeException();
    3229                 :            : 
    3230         [ -  + ]:         15 :     if (!m_pTokens.get())
    3231         [ #  # ]:          0 :         return Sequence<OUString>();
    3232                 :            : 
    3233                 :            :     // Determine the total size of all ranges.
    3234                 :         15 :     AccumulateRangeSize func;
    3235         [ +  - ]:         15 :     func = ::std::for_each(m_pTokens->begin(), m_pTokens->end(), func);
    3236                 :         15 :     SCCOL nCols = func.getCols();
    3237                 :         15 :     SCROW nRows = func.getRows();
    3238                 :            : 
    3239                 :            :     // Detemine whether this is column-major or row-major.
    3240                 :         15 :     bool bColumn = true;
    3241 [ +  - ][ +  + ]:         15 :     if ((eOrigin == chart2::data::LabelOrigin_SHORT_SIDE) ||
    3242                 :            :         (eOrigin == chart2::data::LabelOrigin_LONG_SIDE))
    3243                 :            :     {
    3244         [ +  - ]:         15 :         if (nRows > nCols)
    3245                 :            :         {
    3246         [ +  + ]:         15 :             if (eOrigin == chart2::data::LabelOrigin_SHORT_SIDE)
    3247                 :         14 :                 bColumn = true;
    3248                 :            :             else
    3249                 :          1 :                 bColumn = false;
    3250                 :            :         }
    3251         [ #  # ]:          0 :         else if (nCols > nRows)
    3252                 :            :         {
    3253         [ #  # ]:          0 :             if (eOrigin == chart2::data::LabelOrigin_SHORT_SIDE)
    3254                 :          0 :                 bColumn = false;
    3255                 :            :             else
    3256                 :          0 :                 bColumn = true;
    3257                 :            :         }
    3258                 :            :         else
    3259         [ #  # ]:          0 :             return Sequence<OUString>();
    3260                 :            :     }
    3261                 :            : 
    3262                 :            :     // Generate label strings based on the info so far.
    3263         [ +  + ]:         15 :     sal_Int32 nCount = bColumn ? nCols : nRows;
    3264         [ +  - ]:         15 :     GenerateLabelStrings genLabels(nCount, eOrigin, bColumn);
    3265 [ +  - ][ +  - ]:         15 :     genLabels = ::std::for_each(m_pTokens->begin(), m_pTokens->end(), genLabels);
         [ +  - ][ +  - ]
                 [ +  - ]
    3266         [ +  - ]:         15 :     Sequence<OUString> aSeq = genLabels.getLabels();
    3267                 :            : 
    3268 [ +  - ][ +  - ]:         15 :     return aSeq;
         [ +  - ][ +  - ]
    3269                 :            : }
    3270                 :            : 
    3271                 :            : namespace {
    3272                 :            : 
    3273                 :       6159 : sal_uLong getDisplayNumberFormat(ScDocument* pDoc, const ScAddress& rPos)
    3274                 :            : {
    3275                 :       6159 :     sal_uLong nFormat = pDoc->GetNumberFormat(rPos); // original format from cell.
    3276                 :       6159 :     SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
    3277         [ -  + ]:       6159 :     if (!pFormatter)
    3278                 :          0 :         return nFormat;
    3279                 :            : 
    3280                 :       6159 :     ScBaseCell* pCell = pDoc->GetCell(rPos);
    3281 [ +  + ][ -  + ]:       6159 :     if (!pCell || pCell->GetCellType() != CELLTYPE_FORMULA || nFormat)
         [ +  + ][ +  + ]
    3282                 :       5970 :         return nFormat;
    3283                 :            : 
    3284                 :            :     // With formula cell, the format may be inferred from the formula result.
    3285         [ +  - ]:       6159 :     return static_cast<ScFormulaCell*>(pCell)->GetStandardFormat(*pFormatter, nFormat);
    3286                 :            : }
    3287                 :            : 
    3288                 :            : }
    3289                 :            : 
    3290                 :       6159 : ::sal_Int32 SAL_CALL ScChart2DataSequence::getNumberFormatKeyByIndex( ::sal_Int32 nIndex )
    3291                 :            :     throw (lang::IndexOutOfBoundsException,
    3292                 :            :            uno::RuntimeException)
    3293                 :            : {
    3294                 :            :     // index -1 means a heuristic value for the entire sequence
    3295                 :       6159 :     bool bGetSeriesFormat = (nIndex == -1);
    3296                 :            : 
    3297         [ +  - ]:       6159 :     SolarMutexGuard aGuard;
    3298 [ +  - ][ -  + ]:       6159 :     if ( !m_pDocument || !m_pTokens.get())
                 [ -  + ]
    3299                 :          0 :         return 0;
    3300                 :            : 
    3301                 :            :     // TODO: Handle external references too.
    3302                 :            : 
    3303                 :       6159 :     sal_Int32 nCount = 0;
    3304                 :            : 
    3305         [ +  - ]:       6159 :     ScRangeList aRanges;
    3306         [ +  - ]:       6159 :     ScRefTokenHelper::getRangeListFromTokens(aRanges, *m_pTokens);
    3307 [ +  - ][ +  - ]:       6159 :     for (size_t i = 0, n = aRanges.size(); i < n; ++i)
    3308                 :            :     {
    3309         [ +  - ]:       6159 :         ScRange* p = aRanges[i];
    3310         [ +  - ]:       6159 :         for (SCTAB nTab = p->aStart.Tab(); nTab <= p->aEnd.Tab(); ++nTab)
    3311                 :            :         {
    3312         [ +  - ]:      30651 :             for (SCCOL nCol = p->aStart.Col(); nCol <= p->aEnd.Col(); ++nCol)
    3313                 :            :             {
    3314         [ +  - ]:      30651 :                 if (!m_bIncludeHiddenCells)
    3315                 :            :                 {
    3316                 :            :                     // Skip hidden columns.
    3317                 :      30651 :                     SCCOL nLastCol = -1;
    3318         [ +  - ]:      30651 :                     bool bColHidden = m_pDocument->ColHidden(nCol, nTab, NULL, &nLastCol);
    3319         [ -  + ]:      30651 :                     if (bColHidden)
    3320                 :            :                     {
    3321                 :          0 :                         nCol = nLastCol;
    3322                 :      30651 :                         continue;
    3323                 :            :                     }
    3324                 :            :                 }
    3325                 :            : 
    3326         [ +  + ]:      56330 :                 for (SCROW nRow = p->aStart.Row(); nRow <= p->aEnd.Row(); ++nRow)
    3327                 :            :                 {
    3328         [ +  - ]:      31838 :                     if (!m_bIncludeHiddenCells)
    3329                 :            :                     {
    3330                 :            :                         // Skip hidden rows.
    3331                 :      31838 :                         SCROW nLastRow = -1;
    3332         [ +  - ]:      31838 :                         bool bRowHidden = m_pDocument->RowHidden(nRow, nTab, NULL, &nLastRow);
    3333         [ +  + ]:      31838 :                         if (bRowHidden)
    3334                 :            :                         {
    3335                 :        396 :                             nRow = nLastRow;
    3336                 :      31838 :                             continue;
    3337                 :            :                         }
    3338                 :            :                     }
    3339                 :            : 
    3340                 :      31442 :                     ScAddress aPos(nCol, nRow, nTab);
    3341                 :            : 
    3342         [ +  + ]:      31442 :                     if( bGetSeriesFormat )
    3343                 :            :                     {
    3344                 :            :                         // TODO: use nicer heuristic
    3345                 :            :                         // return format of first non-empty cell
    3346         [ +  - ]:       1737 :                         ScBaseCell* pCell = m_pDocument->GetCell(aPos);
    3347         [ +  + ]:       1737 :                         if (pCell)
    3348         [ +  - ]:       1711 :                             return static_cast<sal_Int32>(getDisplayNumberFormat(m_pDocument, aPos));
    3349                 :            :                     }
    3350         [ +  + ]:      29705 :                     else if( nCount == nIndex )
    3351                 :            :                     {
    3352         [ +  - ]:       4448 :                         return static_cast<sal_Int32>(getDisplayNumberFormat(m_pDocument, aPos));
    3353                 :            :                     }
    3354                 :      31442 :                     ++nCount;
    3355                 :            :                 }
    3356                 :            :             }
    3357                 :            :         }
    3358                 :            :     }
    3359 [ +  - ][ +  - ]:       6159 :     return 0;
    3360                 :            : }
    3361                 :            : 
    3362                 :            : // XCloneable ================================================================
    3363                 :            : 
    3364                 :          0 : uno::Reference< util::XCloneable > SAL_CALL ScChart2DataSequence::createClone()
    3365                 :            :     throw (uno::RuntimeException)
    3366                 :            : {
    3367         [ #  # ]:          0 :     SolarMutexGuard aGuard;
    3368                 :            : 
    3369                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    3370                 :          0 :     auto_ptr< vector<ScTokenRef> > pTokensNew;
    3371                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
    3372         [ #  # ]:          0 :     if (m_pTokens.get())
    3373                 :            :     {
    3374                 :            :         // Clone tokens.
    3375 [ #  # ][ #  # ]:          0 :         pTokensNew.reset(new vector<ScTokenRef>);
    3376         [ #  # ]:          0 :         pTokensNew->reserve(m_pTokens->size());
    3377 [ #  # ][ #  # ]:          0 :         vector<ScTokenRef>::const_iterator itr = m_pTokens->begin(), itrEnd = m_pTokens->end();
    3378 [ #  # ][ #  # ]:          0 :         for (; itr != itrEnd; ++itr)
    3379                 :            :         {
    3380         [ #  # ]:          0 :             ScTokenRef p(static_cast<ScToken*>((*itr)->Clone()));
    3381         [ #  # ]:          0 :             pTokensNew->push_back(p);
    3382         [ #  # ]:          0 :         }
    3383                 :            :     }
    3384                 :            : 
    3385                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    3386         [ #  # ]:          0 :     auto_ptr<ScChart2DataSequence> p(new ScChart2DataSequence(m_pDocument, m_xDataProvider, pTokensNew.release(), m_bIncludeHiddenCells));
    3387                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
    3388         [ #  # ]:          0 :     p->CopyData(*this);
    3389 [ #  # ][ #  # ]:          0 :     Reference< util::XCloneable > xClone(p.release());
    3390                 :            : 
    3391 [ #  # ][ #  # ]:          0 :     return xClone;
    3392                 :            : }
    3393                 :            : 
    3394                 :            : // XModifyBroadcaster ========================================================
    3395                 :            : 
    3396                 :       4770 : void SAL_CALL ScChart2DataSequence::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
    3397                 :            :     throw (uno::RuntimeException)
    3398                 :            : {
    3399                 :            :     // like ScCellRangesBase::addModifyListener
    3400         [ +  - ]:       4770 :     SolarMutexGuard aGuard;
    3401 [ +  - ][ -  + ]:       4770 :     if (!m_pTokens.get() || m_pTokens->empty())
                 [ -  + ]
    3402                 :       4770 :         return;
    3403                 :            : 
    3404         [ +  - ]:       4770 :     ScRangeList aRanges;
    3405         [ +  - ]:       4770 :     ScRefTokenHelper::getRangeListFromTokens(aRanges, *m_pTokens);
    3406                 :            :     uno::Reference<util::XModifyListener> *pObj =
    3407                 :       4770 :             new uno::Reference<util::XModifyListener>( aListener );
    3408         [ +  - ]:       4770 :     m_aValueListeners.push_back( pObj );
    3409                 :            : 
    3410         [ +  - ]:       4770 :     if ( m_aValueListeners.size() == 1 )
    3411                 :            :     {
    3412         [ +  - ]:       4770 :         if (!m_pValueListener)
    3413 [ +  - ][ +  - ]:       4770 :             m_pValueListener = new ScLinkListener( LINK( this, ScChart2DataSequence, ValueListenerHdl ) );
                 [ +  - ]
    3414                 :            : 
    3415         [ +  - ]:       4770 :         if (!m_pHiddenListener.get())
    3416 [ +  - ][ +  - ]:       4770 :             m_pHiddenListener.reset(new HiddenRangeListener(*this));
                 [ +  - ]
    3417                 :            : 
    3418         [ +  - ]:       4770 :         if( m_pDocument )
    3419                 :            :         {
    3420         [ +  - ]:       4770 :             ScChartListenerCollection* pCLC = m_pDocument->GetChartListenerCollection();
    3421 [ +  - ][ +  - ]:       4770 :             vector<ScTokenRef>::const_iterator itr = m_pTokens->begin(), itrEnd = m_pTokens->end();
    3422 [ +  - ][ +  + ]:       9540 :             for (; itr != itrEnd; ++itr)
    3423                 :            :             {
    3424                 :       4770 :                 ScRange aRange;
    3425 [ -  + ][ +  - ]:       4770 :                 if (!ScRefTokenHelper::getRangeFromToken(aRange, *itr))
    3426                 :          0 :                     continue;
    3427                 :            : 
    3428         [ +  - ]:       4770 :                 m_pDocument->StartListeningArea( aRange, m_pValueListener );
    3429         [ +  - ]:       4770 :                 if (pCLC)
    3430         [ +  - ]:       4770 :                     pCLC->StartListeningHiddenRange(aRange, m_pHiddenListener.get());
    3431                 :            :             }
    3432                 :            :         }
    3433                 :            : 
    3434                 :       4770 :         acquire();  // don't lose this object (one ref for all listeners)
    3435 [ +  - ][ +  - ]:       4770 :     }
                 [ +  - ]
    3436                 :            : }
    3437                 :            : 
    3438                 :       4770 : void SAL_CALL ScChart2DataSequence::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener )
    3439                 :            :     throw (uno::RuntimeException)
    3440                 :            : {
    3441                 :            :     // like ScCellRangesBase::removeModifyListener
    3442                 :            : 
    3443         [ +  - ]:       4770 :     SolarMutexGuard aGuard;
    3444 [ +  - ][ -  + ]:       4770 :     if (!m_pTokens.get() || m_pTokens->empty())
                 [ -  + ]
    3445                 :       4770 :         return;
    3446                 :            : 
    3447                 :       4770 :     acquire();      // in case the listeners have the last ref - released below
    3448                 :            : 
    3449                 :       4770 :     sal_uInt16 nCount = m_aValueListeners.size();
    3450         [ +  - ]:       4770 :     for ( sal_uInt16 n=nCount; n--; )
    3451                 :            :     {
    3452         [ +  - ]:       4770 :         uno::Reference<util::XModifyListener>& rObj = m_aValueListeners[n];
    3453 [ +  - ][ +  - ]:       4770 :         if ( rObj == aListener )
    3454                 :            :         {
    3455 [ +  - ][ +  - ]:       4770 :             m_aValueListeners.erase( m_aValueListeners.begin() + n );
                 [ +  - ]
    3456                 :            : 
    3457         [ +  - ]:       4770 :             if ( m_aValueListeners.empty() )
    3458                 :            :             {
    3459         [ +  - ]:       4770 :                 if (m_pValueListener)
    3460         [ +  - ]:       4770 :                     m_pValueListener->EndListeningAll();
    3461                 :            : 
    3462 [ +  - ][ +  + ]:       4770 :                 if (m_pHiddenListener.get() && m_pDocument)
                 [ +  + ]
    3463                 :            :                 {
    3464         [ +  - ]:       4594 :                     ScChartListenerCollection* pCLC = m_pDocument->GetChartListenerCollection();
    3465         [ +  - ]:       4594 :                     if (pCLC)
    3466         [ +  - ]:       4594 :                         pCLC->EndListeningHiddenRange(m_pHiddenListener.get());
    3467                 :            :                 }
    3468                 :            : 
    3469                 :       4770 :                 release();      // release the ref for the listeners
    3470                 :            :             }
    3471                 :            : 
    3472                 :       4770 :             break;
    3473                 :            :         }
    3474                 :            :     }
    3475                 :            : 
    3476 [ +  - ][ +  - ]:       4770 :     release();      // might delete this object
    3477                 :            : }
    3478                 :            : 
    3479                 :            : // DataSequence XPropertySet -------------------------------------------------
    3480                 :            : 
    3481                 :            : uno::Reference< beans::XPropertySetInfo> SAL_CALL
    3482                 :          0 : ScChart2DataSequence::getPropertySetInfo() throw( uno::RuntimeException)
    3483                 :            : {
    3484         [ #  # ]:          0 :     SolarMutexGuard aGuard;
    3485                 :            :     static uno::Reference<beans::XPropertySetInfo> aRef =
    3486 [ #  # ][ #  # ]:          0 :         new SfxItemPropertySetInfo( m_aPropSet.getPropertyMap() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3487         [ #  # ]:          0 :     return aRef;
    3488                 :            : }
    3489                 :            : 
    3490                 :            : 
    3491                 :        513 : void SAL_CALL ScChart2DataSequence::setPropertyValue(
    3492                 :            :         const ::rtl::OUString& rPropertyName, const uno::Any& rValue)
    3493                 :            :             throw( beans::UnknownPropertyException,
    3494                 :            :                     beans::PropertyVetoException,
    3495                 :            :                     lang::IllegalArgumentException,
    3496                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    3497                 :            : {
    3498         [ +  + ]:        513 :     if ( rPropertyName == SC_UNONAME_ROLE )
    3499                 :            :     {
    3500         [ -  + ]:        495 :         if ( !(rValue >>= m_aRole))
    3501         [ #  # ]:          0 :             throw lang::IllegalArgumentException();
    3502                 :            :     }
    3503         [ +  - ]:         18 :     else if ( rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS )
    3504                 :            :     {
    3505                 :         18 :         sal_Bool bOldValue = m_bIncludeHiddenCells;
    3506         [ -  + ]:         18 :         if ( !(rValue >>= m_bIncludeHiddenCells))
    3507         [ #  # ]:          0 :             throw lang::IllegalArgumentException();
    3508         [ -  + ]:         18 :         if( bOldValue != m_bIncludeHiddenCells )
    3509                 :          0 :             m_aDataArray.clear();//data array is dirty now
    3510                 :            :     }
    3511                 :            :     else
    3512         [ #  # ]:          0 :         throw beans::UnknownPropertyException();
    3513                 :            :     // TODO: support optional properties
    3514                 :        513 : }
    3515                 :            : 
    3516                 :            : 
    3517                 :       5114 : uno::Any SAL_CALL ScChart2DataSequence::getPropertyValue(
    3518                 :            :         const ::rtl::OUString& rPropertyName)
    3519                 :            :             throw( beans::UnknownPropertyException,
    3520                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    3521                 :            : {
    3522                 :       5114 :     uno::Any aRet;
    3523         [ +  + ]:       5114 :     if ( rPropertyName == SC_UNONAME_ROLE )
    3524         [ +  - ]:       4577 :         aRet <<= m_aRole;
    3525         [ -  + ]:        537 :     else if ( rPropertyName == SC_UNONAME_INCLUDEHIDDENCELLS )
    3526         [ #  # ]:          0 :         aRet <<= m_bIncludeHiddenCells;
    3527         [ +  - ]:        537 :     else if ( rPropertyName == SC_UNONAME_HIDDENVALUES )
    3528                 :            :     {
    3529                 :            :         // This property is read-only thus cannot be set externally via
    3530                 :            :         // setPropertyValue(...).
    3531         [ +  - ]:        537 :         BuildDataCache();
    3532         [ +  - ]:        537 :         aRet <<= m_aHiddenValues;
    3533                 :            :     }
    3534                 :            :     else
    3535         [ #  # ]:          0 :         throw beans::UnknownPropertyException();
    3536                 :            :     // TODO: support optional properties
    3537                 :       5114 :     return aRet;
    3538                 :            : }
    3539                 :            : 
    3540                 :            : 
    3541                 :          0 : void SAL_CALL ScChart2DataSequence::addPropertyChangeListener(
    3542                 :            :         const ::rtl::OUString& /*rPropertyName*/,
    3543                 :            :         const uno::Reference< beans::XPropertyChangeListener>& /*xListener*/)
    3544                 :            :             throw( beans::UnknownPropertyException,
    3545                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    3546                 :            : {
    3547                 :            :     // FIXME: real implementation
    3548                 :            :     OSL_FAIL( "Not yet implemented" );
    3549                 :          0 : }
    3550                 :            : 
    3551                 :            : 
    3552                 :          0 : void SAL_CALL ScChart2DataSequence::removePropertyChangeListener(
    3553                 :            :         const ::rtl::OUString& /*rPropertyName*/,
    3554                 :            :         const uno::Reference< beans::XPropertyChangeListener>& /*rListener*/)
    3555                 :            :             throw( beans::UnknownPropertyException,
    3556                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    3557                 :            : {
    3558                 :            :     // FIXME: real implementation
    3559                 :            :     OSL_FAIL( "Not yet implemented" );
    3560                 :          0 : }
    3561                 :            : 
    3562                 :            : 
    3563                 :          0 : void SAL_CALL ScChart2DataSequence::addVetoableChangeListener(
    3564                 :            :         const ::rtl::OUString& /*rPropertyName*/,
    3565                 :            :         const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
    3566                 :            :             throw( beans::UnknownPropertyException,
    3567                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    3568                 :            : {
    3569                 :            :     // FIXME: real implementation
    3570                 :            :     OSL_FAIL( "Not yet implemented" );
    3571                 :          0 : }
    3572                 :            : 
    3573                 :            : 
    3574                 :          0 : void SAL_CALL ScChart2DataSequence::removeVetoableChangeListener(
    3575                 :            :         const ::rtl::OUString& /*rPropertyName*/,
    3576                 :            :         const uno::Reference< beans::XVetoableChangeListener>& /*rListener*/)
    3577                 :            :             throw( beans::UnknownPropertyException,
    3578                 :            :                     lang::WrappedTargetException, uno::RuntimeException)
    3579                 :            : {
    3580                 :            :     // FIXME: real implementation
    3581                 :            :     OSL_FAIL( "Not yet implemented" );
    3582                 :          0 : }
    3583                 :            : 
    3584                 :        178 : void ScChart2DataSequence::setDataChangedHint(bool b)
    3585                 :            : {
    3586                 :        178 :     m_bGotDataChangedHint = b;
    3587                 :        178 : }
    3588                 :            : 
    3589                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10