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