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