1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: chart2uno.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "chart2uno.hxx"
35 #include "miscuno.hxx"
36 #include "document.hxx"
37 #include "unoguard.hxx"
39 #include "chartpos.hxx"
40 #include "unonames.hxx"
41 #include "globstr.hrc"
42 #include "convuno.hxx"
43 #include "rangeutl.hxx"
45 #include "unoreflist.hxx"
46 #include "compiler.hxx"
47 #include "reftokenhelper.hxx"
48 #include "chartlis.hxx"
50 #include <sfx2/objsh.hxx>
51 #include <tools/table.hxx>
53 #include <com/sun/star/beans/UnknownPropertyException.hpp>
54 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
55 #include <com/sun/star/table/XCellRange.hpp>
56 #include <com/sun/star/table/CellAddress.hpp>
57 #include <com/sun/star/text/XText.hpp>
58 #include <comphelper/extract.hxx>
62 #include <rtl/math.hxx>
64 SC_SIMPLE_SERVICE_INFO( ScChart2DataProvider
, "ScChart2DataProvider",
65 "com.sun.star.chart2.data.DataProvider")
66 SC_SIMPLE_SERVICE_INFO( ScChart2DataSource
, "ScChart2DataSource",
67 "com.sun.star.chart2.data.DataSource")
68 SC_SIMPLE_SERVICE_INFO( ScChart2LabeledDataSequence
, "ScChart2LabeledDataSequence",
69 "com.sun.star.chart2.data.LabeledDataSequence")
70 SC_SIMPLE_SERVICE_INFO( ScChart2DataSequence
, "ScChart2DataSequence",
71 "com.sun.star.chart2.data.DataSequence")
72 #if USE_CHART2_EMPTYDATASEQUENCE
73 SC_SIMPLE_SERVICE_INFO( ScChart2EmptyDataSequence
, "ScChart2EmptyDataSequence",
74 "com.sun.star.chart2.data.DataSequence")
77 using namespace ::com::sun::star
;
78 using namespace ::formula
;
79 using ::rtl::OUString
;
80 using ::rtl::OUStringBuffer
;
81 using ::com::sun::star::uno::Sequence
;
82 using ::com::sun::star::uno::Reference
;
83 using ::std::auto_ptr
;
86 using ::std::distance
;
87 using ::std::unary_function
;
88 using ::std::hash_set
;
89 using ::boost::shared_ptr
;
93 const SfxItemPropertyMapEntry
* lcl_GetDataProviderPropertyMap()
95 static SfxItemPropertyMapEntry aDataProviderPropertyMap_Impl
[] =
97 {MAP_CHAR_LEN(SC_UNONAME_INCLUDEHIDDENCELLS
), 0, &getBooleanCppuType(), 0, 0 },
100 return aDataProviderPropertyMap_Impl
;
103 const SfxItemPropertyMapEntry
* lcl_GetDataSequencePropertyMap()
105 static SfxItemPropertyMapEntry aDataSequencePropertyMap_Impl
[] =
107 {MAP_CHAR_LEN(SC_UNONAME_HIDDENVALUES
), 0, &getCppuType((uno::Sequence
<sal_Int32
>*)0 ), 0, 0 },
108 {MAP_CHAR_LEN(SC_UNONAME_ROLE
), 0, &getCppuType((::com::sun::star::chart2::data::DataSequenceRole
*)0), 0, 0 },
109 {MAP_CHAR_LEN(SC_UNONAME_INCLUDEHIDDENCELLS
), 0, &getBooleanCppuType(), 0, 0 },
112 return aDataSequencePropertyMap_Impl
;
115 template< typename T
>
116 ::com::sun::star::uno::Sequence
< T
> lcl_VectorToSequence(
117 const ::std::vector
< T
> & rCont
)
119 ::com::sun::star::uno::Sequence
< T
> aResult( rCont
.size());
120 ::std::copy( rCont
.begin(), rCont
.end(), aResult
.getArray());
124 ::std::vector
< ::rtl::OUString
> lcl_getRangeRepresentationsFromDataSource(
125 const uno::Reference
< chart2::data::XDataSource
> & xDataSource
)
127 ::std::vector
< ::rtl::OUString
> aResult
;
128 if( xDataSource
.is())
130 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aSequences(
131 xDataSource
->getDataSequences());
132 const sal_Int32
nCount( aSequences
.getLength());
133 for( sal_Int32 nIdx
=0; nIdx
<nCount
; ++nIdx
)
135 if( aSequences
[nIdx
].is() )
138 uno::Reference
< chart2::data::XDataSequence
> xSeq( aSequences
[nIdx
]->getLabel());
140 aResult
.push_back( xSeq
->getSourceRangeRepresentation());
142 xSeq
.set( aSequences
[nIdx
]->getValues());
144 aResult
.push_back( xSeq
->getSourceRangeRepresentation());
151 uno::Reference
< chart2::data::XLabeledDataSequence
> lcl_getCategoriesFromDataSource(
152 const uno::Reference
< chart2::data::XDataSource
> & xDataSource
)
154 uno::Reference
< chart2::data::XLabeledDataSequence
> xResult
;
155 if( xDataSource
.is())
157 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aSequences(
158 xDataSource
->getDataSequences());
159 const sal_Int32
nCount( aSequences
.getLength());
160 for( sal_Int32 nIdx
=0; nIdx
<nCount
; ++nIdx
)
162 if( aSequences
[nIdx
].is() )
164 uno::Reference
< beans::XPropertySet
> xSeqProp( aSequences
[nIdx
]->getValues(), uno::UNO_QUERY
);
165 ::rtl::OUString aRole
;
167 (xSeqProp
->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Role"))) >>= aRole
) &&
168 aRole
.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("categories")) )
170 xResult
.set( aSequences
[nIdx
] );
179 struct lcl_appendTableNumber
: public ::std::unary_function
< SCTAB
, void >
181 lcl_appendTableNumber( ::rtl::OUStringBuffer
& rBuffer
) :
184 void operator() ( SCTAB nTab
)
186 // there is no append with SCTAB or sal_Int16
187 m_rBuffer
.append( static_cast< sal_Int32
>( nTab
));
188 m_rBuffer
.append( sal_Unicode( ' ' ));
191 ::rtl::OUStringBuffer
& m_rBuffer
;
194 ::rtl::OUString
lcl_createTableNumberList( const ::std::list
< SCTAB
> & rTableList
)
196 ::rtl::OUStringBuffer aBuffer
;
197 ::std::for_each( rTableList
.begin(), rTableList
.end(), lcl_appendTableNumber( aBuffer
));
198 // remove last trailing ' '
199 if( aBuffer
.getLength() > 0 )
200 aBuffer
.setLength( aBuffer
.getLength() - 1 );
201 return aBuffer
.makeStringAndClear();
204 uno::Reference
< frame::XModel
> lcl_GetXModel( ScDocument
* pDoc
)
206 uno::Reference
< frame::XModel
> xModel
;
207 SfxObjectShell
* pObjSh( pDoc
? pDoc
->GetDocumentShell() : 0 );
209 xModel
.set( pObjSh
->GetModel());
213 uno::Reference
< sheet::XSpreadsheetDocument
> lcl_GetSpreadSheetDocument( ScDocument
* pDoc
)
215 return uno::Reference
< sheet::XSpreadsheetDocument
>( lcl_GetXModel( pDoc
), uno::UNO_QUERY
);
218 // ============================================================================
220 class Chart2PositionMap
223 Chart2PositionMap(SCCOL nColCount
, SCROW nRowCount
,
224 bool bColAdd
, bool bRowAdd
, Table
& rCols
);
225 ~Chart2PositionMap();
227 SCCOL
getColCount() const { return static_cast<SCCOL
>(maColHeaders
.size()); }
228 SCROW
getRowCount() const { return static_cast<SCROW
>(maRowHeaders
.size()); }
230 const FormulaToken
* getColHeaderPosition(SCCOL nChartCol
) const;
231 const FormulaToken
* getRowHeaderPosition(SCROW nChartRow
) const;
233 vector
<ScSharedTokenRef
>* getColRanges(SCCOL nCol
) const;
234 vector
<ScSharedTokenRef
>* getRowRanges(SCROW nRow
) const;
238 sal_uInt32
getIndex(SCCOL nCol
, SCROW nRow
) const
240 return static_cast<sal_uInt32
>(nCol
*getRowCount() + nRow
);
244 vector
<FormulaToken
*> maRowHeaders
;
245 vector
<FormulaToken
*> maColHeaders
;
246 vector
<FormulaToken
*> maData
;
249 Chart2PositionMap::Chart2PositionMap(SCCOL nColCount
, SCROW nRowCount
,
250 bool bColAdd
, bool bRowAdd
, Table
& rCols
)
252 // bColAdd is true when the first column serves as a row header. Likewise,
253 // when bRowAdd is true the first row serves as a column header.
255 maColHeaders
.reserve(nColCount
);
256 maRowHeaders
.reserve(nRowCount
);
257 maData
.reserve(nColCount
*nRowCount
);
259 Table
* pCol
= static_cast<Table
*>(rCols
.First());
260 FormulaToken
* pPos
= static_cast<FormulaToken
*>(pCol
->First());
263 pPos
= static_cast<FormulaToken
*>(pCol
->Next());
267 // 1st column as a row header.
268 for (SCROW nRow
= 0; nRow
< nRowCount
; ++nRow
)
270 maRowHeaders
.push_back(pPos
);
271 pPos
= static_cast<FormulaToken
*>(pCol
->Next());
273 pCol
= static_cast<Table
*>(rCols
.Next()); // move to the next column.
277 for (SCROW nRow
= 0; nRow
< nRowCount
; ++nRow
)
280 maRowHeaders
.push_back(pPos
? pPos
->Clone() : NULL
);
281 pPos
= static_cast<FormulaToken
*>(pCol
->Next());
285 // Data in columns and in column headers.
286 for (SCCOL nCol
= 0; nCol
< nColCount
; ++nCol
)
290 pPos
= static_cast<FormulaToken
*>(pCol
->First());
293 // 1st row as a column header.
294 maColHeaders
.push_back(pPos
);
295 pPos
= static_cast<FormulaToken
*>(pCol
->Next());
298 // Duplicate the 1st cell as a column header.
299 maColHeaders
.push_back(pPos
? pPos
->Clone() : NULL
);
301 for (SCROW nRow
= 0; nRow
< nRowCount
; ++nRow
)
303 maData
.push_back(pPos
);
304 pPos
= static_cast<FormulaToken
*>(pCol
->Next());
309 // the entire column is empty.
310 maColHeaders
.push_back(NULL
);
311 for (SCROW nRow
= 0; nRow
< nRowCount
; ++nRow
)
312 maData
.push_back(NULL
);
314 pCol
= static_cast<Table
*>(rCols
.Next());
320 struct DeleteInstance
: public unary_function
<FormulaToken
*, void>
322 void operator() (FormulaToken
* p
) const
330 Chart2PositionMap::~Chart2PositionMap()
332 for_each(maColHeaders
.begin(), maColHeaders
.end(), DeleteInstance());
333 for_each(maRowHeaders
.begin(), maRowHeaders
.end(), DeleteInstance());
334 for_each(maData
.begin(), maData
.end(), DeleteInstance());
337 const FormulaToken
* Chart2PositionMap::getColHeaderPosition(SCCOL nCol
) const
339 if (nCol
< getColCount())
340 return maColHeaders
[nCol
];
343 const FormulaToken
* Chart2PositionMap::getRowHeaderPosition(SCROW nRow
) const
345 if (nRow
< getRowCount())
346 return maRowHeaders
[nRow
];
350 vector
<ScSharedTokenRef
>* Chart2PositionMap::getColRanges(SCCOL nCol
) const
352 if (nCol
>= getColCount())
355 auto_ptr
< vector
<ScSharedTokenRef
> > pTokens(new vector
<ScSharedTokenRef
>);
356 sal_uInt32 nStop
= getIndex(nCol
, getRowCount());
357 for (sal_uInt32 i
= getIndex(nCol
, 0); i
< nStop
; ++i
)
359 FormulaToken
* p
= maData
[i
];
363 ScSharedTokenRef
pCopy(static_cast<ScToken
*>(p
->Clone()));
364 ScRefTokenHelper::join(*pTokens
, pCopy
);
366 return pTokens
.release();
369 vector
<ScSharedTokenRef
>* Chart2PositionMap::getRowRanges(SCROW nRow
) const
371 SCROW nRowCount
= getRowCount();
372 if (nRow
>= nRowCount
)
375 auto_ptr
< vector
<ScSharedTokenRef
> > pTokens(new vector
<ScSharedTokenRef
>);
376 sal_uInt32 nStop
= getIndex(getColCount(), nRow
);
377 for (sal_uInt32 i
= getIndex(0, nRow
); i
< nStop
; i
+= nRowCount
)
379 FormulaToken
* p
= maData
[i
];
383 ScSharedTokenRef
p2(static_cast<ScToken
*>(p
->Clone()));
384 ScRefTokenHelper::join(*pTokens
, p2
);
386 return pTokens
.release();
389 // ----------------------------------------------------------------------------
392 * Designed to be a drop-in replacement for ScChartPositioner, in order to
393 * handle external references.
395 class Chart2Positioner
407 Chart2Positioner(ScDocument
* pDoc
, const vector
<ScSharedTokenRef
>& rRefTokens
) :
408 mpRefTokens(new vector
<ScSharedTokenRef
>(rRefTokens
)),
414 mbDummyUpperLeft(false)
422 void setHeaders(bool bColHeaders
, bool bRowHeaders
)
424 mbColHeaders
= bColHeaders
;
425 mbRowHeaders
= bRowHeaders
;
428 bool hasColHeaders() const { return mbColHeaders
; }
429 bool hasRowHeaders() const { return mbRowHeaders
; }
431 Chart2PositionMap
* getPositionMap()
434 return mpPositionMap
.get();
438 Chart2Positioner(); // disabled
440 void invalidateGlue();
442 void createPositionMap();
445 shared_ptr
< vector
<ScSharedTokenRef
> > mpRefTokens
;
446 auto_ptr
<Chart2PositionMap
> mpPositionMap
;
453 bool mbDummyUpperLeft
:1;
456 void Chart2Positioner::invalidateGlue()
458 meGlue
= GLUETYPE_NA
;
459 mpPositionMap
.reset(NULL
);
462 void Chart2Positioner::glueState()
464 if (meGlue
!= GLUETYPE_NA
)
467 mbDummyUpperLeft
= false;
468 if (mpRefTokens
->size() <= 1)
470 const ScSharedTokenRef
& p
= mpRefTokens
->front();
471 ScComplexRefData aData
;
472 if (ScRefTokenHelper::getDoubleRefDataFromToken(aData
, p
))
474 if (aData
.Ref1
.nTab
== aData
.Ref2
.nTab
)
475 meGlue
= GLUETYPE_NONE
;
477 meGlue
= GLUETYPE_COLS
;
478 mnStartCol
= aData
.Ref1
.nCol
;
479 mnStartRow
= aData
.Ref1
.nRow
;
490 ScComplexRefData aData
;
491 ScRefTokenHelper::getDoubleRefDataFromToken(aData
, mpRefTokens
->front());
492 mnStartCol
= aData
.Ref1
.nCol
;
493 mnStartRow
= aData
.Ref1
.nRow
;
495 SCCOL nMaxCols
= 0, nEndCol
= 0;
496 SCROW nMaxRows
= 0, nEndRow
= 0;
497 for (vector
<ScSharedTokenRef
>::const_iterator itr
= mpRefTokens
->begin(), itrEnd
= mpRefTokens
->end()
498 ; itr
!= itrEnd
; ++itr
)
500 ScRefTokenHelper::getDoubleRefDataFromToken(aData
, *itr
);
501 SCCOLROW n1
= aData
.Ref1
.nCol
;
502 SCCOLROW n2
= aData
.Ref2
.nCol
;
507 SCCOLROW nTmp
= n2
- n1
+ 1;
509 mnStartCol
= static_cast<SCCOL
>(n1
);
511 nEndCol
= static_cast<SCCOL
>(n2
);
513 nMaxCols
= static_cast<SCCOL
>(nTmp
);
515 n1
= aData
.Ref1
.nRow
;
516 n2
= aData
.Ref2
.nRow
;
524 mnStartRow
= static_cast<SCROW
>(n1
);
526 nEndRow
= static_cast<SCROW
>(n2
);
528 nMaxRows
= static_cast<SCROW
>(nTmp
);
531 // total column size ?
532 SCCOL nC
= nEndCol
- mnStartCol
+ 1;
535 meGlue
= GLUETYPE_ROWS
;
539 SCROW nR
= nEndRow
- mnStartRow
+ 1;
542 meGlue
= GLUETYPE_COLS
;
545 // #i103540# prevent invalid vector size
546 if ((nC
<= 0) || (nR
<= 0))
553 sal_uInt32 nCR
= static_cast<sal_uInt32
>(nC
*nR
);
555 const sal_uInt8 nHole
= 0;
556 const sal_uInt8 nOccu
= 1;
557 const sal_uInt8 nFree
= 2;
558 const sal_uInt8 nGlue
= 3;
560 vector
<sal_uInt8
> aCellStates(nCR
);
561 for (vector
<ScSharedTokenRef
>::const_iterator itr
= mpRefTokens
->begin(), itrEnd
= mpRefTokens
->end();
562 itr
!= itrEnd
; ++itr
)
564 ScRefTokenHelper::getDoubleRefDataFromToken(aData
, *itr
);
565 SCCOL nCol1
= static_cast<SCCOL
>(aData
.Ref1
.nCol
) - mnStartCol
;
566 SCCOL nCol2
= static_cast<SCCOL
>(aData
.Ref2
.nCol
) - mnStartCol
;
567 SCROW nRow1
= static_cast<SCROW
>(aData
.Ref1
.nRow
) - mnStartRow
;
568 SCROW nRow2
= static_cast<SCROW
>(aData
.Ref2
.nRow
) - mnStartRow
;
569 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
570 for (SCROW nRow
= nRow1
; nRow
<= nRow2
; ++nRow
)
572 size_t i
= nCol
*nR
+ nRow
;
573 aCellStates
[i
] = nOccu
;
579 bool bGlueCols
= false;
580 for (SCCOL nCol
= 0; bGlue
&& nCol
< nC
; ++nCol
)
582 for (SCROW nRow
= 0; bGlue
&& nRow
< nR
; ++nRow
)
585 if (aCellStates
[i
] == nOccu
)
587 if (nRow
> 0 && nRow
> 0)
593 aCellStates
[i
] = nFree
;
595 i
= (nCol
+1)*nR
- 1; // index for the last cell in the column.
596 if (bGlue
&& (aCellStates
[i
] == nFree
))
598 aCellStates
[i
] = nGlue
;
603 bool bGlueRows
= false;
604 for (SCROW nRow
= 0; bGlue
&& nRow
< nR
; ++nRow
)
607 for (SCCOL nCol
= 0; bGlue
&& nCol
< nC
; ++nCol
, i
+= nR
)
609 if (aCellStates
[i
] == nOccu
)
611 if (nCol
> 0 && nRow
> 0)
617 aCellStates
[i
] = nFree
;
619 i
= (nC
-1)*nR
+ nRow
; // index for the row position in the last column.
620 if (bGlue
&& aCellStates
[i
] == nFree
)
622 aCellStates
[i
] = nGlue
;
628 for (sal_uInt32 n
= 1; bGlue
&& n
< nCR
; ++n
, ++i
)
629 if (aCellStates
[i
] == nHole
)
634 if (bGlueCols
&& bGlueRows
)
635 meGlue
= GLUETYPE_BOTH
;
637 meGlue
= GLUETYPE_ROWS
;
639 meGlue
= GLUETYPE_COLS
;
640 if (aCellStates
.front() != nOccu
)
641 mbDummyUpperLeft
= true;
644 meGlue
= GLUETYPE_NONE
;
647 void Chart2Positioner::createPositionMap()
649 if (meGlue
== GLUETYPE_NA
&& mpPositionMap
.get())
650 mpPositionMap
.reset(NULL
);
652 if (mpPositionMap
.get())
657 bool bNoGlue
= (meGlue
== GLUETYPE_NONE
);
658 auto_ptr
<Table
> pCols(new Table
);
659 auto_ptr
<FormulaToken
> pNewAddress
;
660 auto_ptr
<Table
> pNewRowTable(new Table
);
662 SCROW nNoGlueRow
= 0;
663 for (vector
<ScSharedTokenRef
>::const_iterator itr
= mpRefTokens
->begin(), itrEnd
= mpRefTokens
->end();
664 itr
!= itrEnd
; ++itr
)
666 const ScSharedTokenRef
& pToken
= *itr
;
668 bool bExternal
= ScRefTokenHelper::isExternalRef(pToken
);
669 sal_uInt16 nFileId
= bExternal
? pToken
->GetIndex() : 0;
670 String aTabName
= bExternal
? pToken
->GetString() : String();
672 ScComplexRefData aData
;
673 ScRefTokenHelper::getDoubleRefDataFromToken(aData
, *itr
);
674 const ScSingleRefData
& s
= aData
.Ref1
;
675 const ScSingleRefData
& e
= aData
.Ref2
;
676 SCCOL nCol1
= s
.nCol
, nCol2
= e
.nCol
;
677 SCROW nRow1
= s
.nRow
, nRow2
= e
.nRow
;
678 SCTAB nTab1
= s
.nTab
, nTab2
= e
.nTab
;
680 for (SCTAB nTab
= nTab1
; nTab
<= nTab2
; ++nTab
)
682 // What's this for ???
683 sal_uInt32 nInsCol
= (static_cast<sal_uInt32
>(nTab
) << 16) |
684 (bNoGlue
? 0 : static_cast<sal_uInt32
>(nCol1
));
685 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
, ++nInsCol
)
687 if (bNoGlue
|| meGlue
== GLUETYPE_ROWS
)
689 pCol
= static_cast<Table
*>(pCols
->Get(nInsCol
));
692 pCol
= pNewRowTable
.get();
693 pCols
->Insert(nInsCol
, pNewRowTable
.release());
694 pNewRowTable
.reset(new Table
);
699 if (pCols
->Insert(nInsCol
, pNewRowTable
.get()))
701 pCol
= pNewRowTable
.release();
702 pNewRowTable
.reset(new Table
);
705 pCol
= static_cast<Table
*>(pCols
->Get(nInsCol
));
708 sal_uInt32 nInsRow
= static_cast<sal_uInt32
>(bNoGlue
? nNoGlueRow
: nRow1
);
709 for (SCROW nRow
= nRow1
; nRow
<= nRow2
; ++nRow
, ++nInsRow
)
711 ScSingleRefData aCellData
;
712 aCellData
.InitFlags();
713 aCellData
.SetFlag3D(true);
714 aCellData
.SetColRel(false);
715 aCellData
.SetRowRel(false);
716 aCellData
.SetTabRel(false);
717 aCellData
.nCol
= nCol
;
718 aCellData
.nRow
= nRow
;
719 aCellData
.nTab
= nTab
;
722 pNewAddress
.reset(new ScExternalSingleRefToken(nFileId
, aTabName
, aCellData
));
724 pNewAddress
.reset(new ScSingleRefToken(aCellData
));
726 if (pCol
->Insert(nInsRow
, pNewAddress
.get()))
727 pNewAddress
.release(); // To prevent the instance from being destroyed.
731 nNoGlueRow
+= nRow2
- nRow1
+ 1;
733 pNewAddress
.reset(NULL
);
734 pNewRowTable
.reset(NULL
);
736 bool bColAdd
= mbRowHeaders
;
737 bool bRowAdd
= mbColHeaders
;
739 SCSIZE nColCount
= static_cast<SCSIZE
>(pCols
->Count());
740 SCSIZE nRowCount
= 0;
741 pCol
= static_cast<Table
*>(pCols
->First());
744 if (mbDummyUpperLeft
)
745 pCol
->Insert(0, NULL
); // Dummy fuer Beschriftung
746 nRowCount
= static_cast<SCSIZE
>(pCol
->Count());
751 if (nColCount
> 0 && bColAdd
)
753 if (nRowCount
> 0 && bRowAdd
)
756 if (nColCount
== 0 || nRowCount
== 0)
758 ScComplexRefData aData
;
759 ScRefTokenHelper::getDoubleRefDataFromToken(aData
, mpRefTokens
->front());
760 if (pCols
->Count() > 0)
761 pCol
= static_cast<Table
*>(pCols
->First());
765 pCols
->Insert(0, pCol
);
768 if (pCol
->Count() > 0)
770 FormulaToken
* pPos
= static_cast<FormulaToken
*>(pCol
->First());
774 pCol
->Replace(pCol
->GetCurKey(), NULL
);
778 pCol
->Insert(0, NULL
);
788 Table
* pFirstCol
= static_cast<Table
*>(pCols
->First());
789 sal_uInt32 nCount
= pFirstCol
->Count();
791 for (sal_uInt32 n
= 0; n
< nCount
; ++n
, pFirstCol
->Next())
793 sal_uInt32 nKey
= pFirstCol
->GetCurKey();
795 for (pCol
= static_cast<Table
*>(pCols
->Next()); pCol
; pCol
= static_cast<Table
*>(pCols
->Next()))
796 pCol
->Insert(nKey
, NULL
);
801 new Chart2PositionMap(
802 static_cast<SCCOL
>(nColCount
), static_cast<SCROW
>(nRowCount
),
803 bColAdd
, bRowAdd
, *pCols
));
805 // Destroy all column instances.
806 for (pCol
= static_cast<Table
*>(pCols
->First()); pCol
; pCol
= static_cast<Table
*>(pCols
->Next()))
810 // ============================================================================
813 * Function object to create a range string from a token list.
815 class Tokens2RangeString
: public unary_function
<ScSharedTokenRef
, void>
818 Tokens2RangeString(ScDocument
* pDoc
, FormulaGrammar::Grammar eGram
, sal_Unicode cRangeSep
) :
819 mpRangeStr(new OUStringBuffer
),
822 mcRangeSep(cRangeSep
),
827 Tokens2RangeString(const Tokens2RangeString
& r
) :
828 mpRangeStr(r
.mpRangeStr
),
830 meGrammar(r
.meGrammar
),
831 mcRangeSep(r
.mcRangeSep
),
836 void operator() (const ScSharedTokenRef
& rToken
)
838 ScCompiler
aCompiler(mpDoc
, ScAddress(0,0,0));
839 aCompiler
.SetGrammar(meGrammar
);
841 aCompiler
.CreateStringFromToken(aStr
, rToken
.get());
845 mpRangeStr
->append(mcRangeSep
);
846 mpRangeStr
->append(aStr
);
849 void getString(OUString
& rStr
)
851 rStr
= mpRangeStr
->makeStringAndClear();
855 Tokens2RangeString(); // disabled
858 shared_ptr
<OUStringBuffer
> mpRangeStr
;
860 FormulaGrammar::Grammar meGrammar
;
861 sal_Unicode mcRangeSep
;
866 * Function object to convert a list of tokens into a string form suitable
867 * for ODF export. In ODF, a range is expressed as
869 * (start cell address):(end cell address)
871 * and each address doesn't include any '$' symbols.
873 class Tokens2RangeStringXML
: public unary_function
<ScSharedTokenRef
, void>
876 Tokens2RangeStringXML(ScDocument
* pDoc
) :
877 mpRangeStr(new OUStringBuffer
),
885 Tokens2RangeStringXML(const Tokens2RangeStringXML
& r
) :
886 mpRangeStr(r
.mpRangeStr
),
888 mcRangeSep(r
.mcRangeSep
),
889 mcAddrSep(r
.mcAddrSep
),
894 void operator() (const ScSharedTokenRef
& rToken
)
899 mpRangeStr
->append(mcRangeSep
);
901 ScSharedTokenRef aStart
, aEnd
;
902 splitRangeToken(rToken
, aStart
, aEnd
);
903 ScCompiler
aCompiler(mpDoc
, ScAddress(0,0,0));
904 aCompiler
.SetGrammar(FormulaGrammar::GRAM_ENGLISH
);
907 aCompiler
.CreateStringFromToken(aStr
, aStart
.get());
908 mpRangeStr
->append(aStr
);
910 mpRangeStr
->append(mcAddrSep
);
913 aCompiler
.CreateStringFromToken(aStr
, aEnd
.get());
914 mpRangeStr
->append(aStr
);
918 void getString(OUString
& rStr
)
920 rStr
= mpRangeStr
->makeStringAndClear();
924 Tokens2RangeStringXML(); // disabled
926 void splitRangeToken(const ScSharedTokenRef
& pToken
, ScSharedTokenRef
& rStart
, ScSharedTokenRef
& rEnd
) const
928 ScComplexRefData aData
;
929 ScRefTokenHelper::getDoubleRefDataFromToken(aData
, pToken
);
930 bool bExternal
= ScRefTokenHelper::isExternalRef(pToken
);
931 sal_uInt16 nFileId
= bExternal
? pToken
->GetIndex() : 0;
932 String aTabName
= bExternal
? pToken
->GetString() : String();
934 // In saving to XML, we don't prepend address with '$'.
935 setRelative(aData
.Ref1
);
936 setRelative(aData
.Ref2
);
938 // In XML, the end range must explicitly specify sheet name.
939 aData
.Ref2
.SetFlag3D(true);
942 rStart
.reset(new ScExternalSingleRefToken(nFileId
, aTabName
, aData
.Ref1
));
944 rStart
.reset(new ScSingleRefToken(aData
.Ref1
));
947 rEnd
.reset(new ScExternalSingleRefToken(nFileId
, aTabName
, aData
.Ref2
));
949 rEnd
.reset(new ScSingleRefToken(aData
.Ref2
));
952 void setRelative(ScSingleRefData
& rData
) const
954 rData
.SetColRel(true);
955 rData
.SetRowRel(true);
956 rData
.SetTabRel(true);
960 shared_ptr
<OUStringBuffer
> mpRangeStr
;
962 sal_Unicode mcRangeSep
;
963 sal_Unicode mcAddrSep
;
967 void lcl_convertTokensToString(OUString
& rStr
, const vector
<ScSharedTokenRef
>& rTokens
, ScDocument
* pDoc
)
969 const sal_Unicode cRangeSep
= ScCompiler::GetNativeSymbol(ocSep
).GetChar(0);
970 FormulaGrammar::Grammar eGrammar
= pDoc
->GetGrammar();
971 Tokens2RangeString
func(pDoc
, eGrammar
, cRangeSep
);
972 func
= for_each(rTokens
.begin(), rTokens
.end(), func
);
973 func
.getString(rStr
);
976 } // anonymous namespace
978 // DataProvider ==============================================================
980 ScChart2DataProvider::ScChart2DataProvider( ScDocument
* pDoc
)
982 , m_aPropSet(lcl_GetDataProviderPropertyMap())
983 , m_bIncludeHiddenCells( sal_True
)
986 m_pDocument
->AddUnoObject( *this);
989 ScChart2DataProvider::~ScChart2DataProvider()
992 m_pDocument
->RemoveUnoObject( *this);
996 void ScChart2DataProvider::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
998 if ( rHint
.ISA( SfxSimpleHint
) &&
999 ((const SfxSimpleHint
&)rHint
).GetId() == SFX_HINT_DYING
)
1005 ::sal_Bool SAL_CALL
ScChart2DataProvider::createDataSourcePossible( const uno::Sequence
< beans::PropertyValue
>& aArguments
)
1006 throw (uno::RuntimeException
)
1012 rtl::OUString aRangeRepresentation
;
1013 for(sal_Int32 i
= 0; i
< aArguments
.getLength(); ++i
)
1015 rtl::OUString
sName(aArguments
[i
].Name
);
1016 if (aArguments
[i
].Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CellRangeRepresentation")))
1018 aArguments
[i
].Value
>>= aRangeRepresentation
;
1022 vector
<ScSharedTokenRef
> aTokens
;
1023 ScRefTokenHelper::compileRangeRepresentation(aTokens
, aRangeRepresentation
, m_pDocument
, m_pDocument
->GetGrammar());
1024 return !aTokens
.empty();
1029 class RemoveHeaderFromRanges
: public unary_function
<ScSharedTokenRef
, void>
1032 RemoveHeaderFromRanges(const ScSharedTokenRef
& rHeaderCell
, bool bOrientCol
) :
1033 mpTokens(new vector
<ScSharedTokenRef
>),
1034 mpHeaderCell(rHeaderCell
),
1035 mbOrientCol(bOrientCol
)
1039 RemoveHeaderFromRanges(const RemoveHeaderFromRanges
& r
) :
1040 mpTokens(r
.mpTokens
),
1041 mpHeaderCell(r
.mpHeaderCell
),
1042 mbOrientCol(r
.mbOrientCol
)
1046 void operator() (const ScSharedTokenRef
& pRange
)
1048 if (!isContained(pRange
))
1050 // header cell is not part of this range. Just add it to the
1051 // range list and move on.
1052 ScRefTokenHelper::join(*mpTokens
, pRange
);
1056 // This range contains the header cell.
1058 ScComplexRefData aRange
;
1059 ScRefTokenHelper::getDoubleRefDataFromToken(aRange
, pRange
);
1060 const ScSingleRefData
& s
= aRange
.Ref1
;
1061 const ScSingleRefData
& e
= aRange
.Ref2
;
1062 const ScSingleRefData
& h
= mpHeaderCell
->GetSingleRef();
1065 // This range *only* contains the header cell. Skip it.
1068 if (s
.nTab
!= e
.nTab
)
1069 // 3D range has no business being here....
1076 if (s
.nCol
== e
.nCol
)
1078 // single column range.
1079 splitSingleColRange(pRange
, s
, e
);
1083 if (s
.nCol
== h
.nCol
)
1085 // header cell is in the first column.
1088 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1089 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1090 r
.Ref2
.InitAddress(s
.nCol
, e
.nRow
, s
.nTab
);
1091 splitSingleColRange(pNew
, r
.Ref1
, r
.Ref2
);
1095 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1096 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1097 r
.Ref1
.InitAddress(s
.nCol
+ 1, s
.nRow
, s
.nTab
);
1098 ScRefTokenHelper::join(*mpTokens
, pNew
);
1101 else if (e
.nCol
== h
.nCol
)
1103 // header cell is in the last column.
1106 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1107 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1108 r
.Ref1
.InitAddress(e
.nCol
, s
.nRow
, s
.nTab
);
1109 splitSingleColRange(pNew
, r
.Ref1
, r
.Ref2
);
1113 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1114 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1115 r
.Ref2
.InitAddress(e
.nCol
- 1, e
.nRow
, e
.nTab
);
1116 ScRefTokenHelper::join(*mpTokens
, pNew
);
1121 // header cell is somewhere between the first and last columns.
1124 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1125 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1126 r
.Ref2
.InitAddress(h
.nCol
- 1, e
.nRow
, h
.nTab
);
1127 ScRefTokenHelper::join(*mpTokens
, pNew
);
1131 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1132 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1133 r
.Ref1
.InitAddress(h
.nCol
, s
.nRow
, s
.nTab
);
1134 r
.Ref2
.InitAddress(h
.nCol
, e
.nRow
, e
.nTab
);
1135 splitSingleColRange(pNew
, r
.Ref1
, r
.Ref2
);
1139 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1140 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1141 r
.Ref1
.InitAddress(h
.nCol
+ 1, s
.nRow
, h
.nTab
);
1142 ScRefTokenHelper::join(*mpTokens
, pNew
);
1151 if (s
.nRow
== e
.nRow
)
1153 // Single row range.
1154 splitSingleRowRange(pRange
, s
, e
);
1158 if (s
.nRow
== h
.nRow
)
1160 // header cell is in the first row.
1163 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1164 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1165 r
.Ref2
.InitAddress(e
.nCol
, s
.nRow
, s
.nTab
);
1166 splitSingleRowRange(pNew
, r
.Ref1
, r
.Ref2
);
1170 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1171 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1172 r
.Ref1
.InitAddress(s
.nCol
, s
.nRow
+ 1, s
.nTab
);
1173 ScRefTokenHelper::join(*mpTokens
, pNew
);
1176 else if (e
.nRow
== h
.nRow
)
1178 // header cell is in the last row.
1181 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1182 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1183 r
.Ref1
.InitAddress(s
.nCol
, e
.nRow
, s
.nTab
);
1184 splitSingleRowRange(pNew
, r
.Ref1
, r
.Ref2
);
1188 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1189 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1190 r
.Ref2
.InitAddress(e
.nCol
, e
.nRow
- 1, e
.nTab
);
1191 ScRefTokenHelper::join(*mpTokens
, pNew
);
1196 // header cell is somewhere between the 1st and last rows.
1199 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1200 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1201 r
.Ref2
.InitAddress(e
.nCol
, h
.nRow
- 1, h
.nTab
);
1202 ScRefTokenHelper::join(*mpTokens
, pNew
);
1206 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1207 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1208 r
.Ref1
.InitAddress(s
.nCol
, h
.nRow
, s
.nTab
);
1209 r
.Ref2
.InitAddress(e
.nCol
, h
.nRow
, e
.nTab
);
1210 splitSingleRowRange(pNew
, r
.Ref1
, r
.Ref2
);
1214 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1215 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1216 r
.Ref1
.InitAddress(s
.nCol
, h
.nRow
+ 1, h
.nTab
);
1217 ScRefTokenHelper::join(*mpTokens
, pNew
);
1224 void getNewTokens(vector
<ScSharedTokenRef
>& rTokens
)
1226 mpTokens
->swap(rTokens
);
1231 void splitSingleColRange(const ScSharedTokenRef
& pRange
, const ScSingleRefData
& s
, const ScSingleRefData
& e
)
1233 const ScSingleRefData
& h
= mpHeaderCell
->GetSingleRef();
1237 // header is at the top.
1239 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1240 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1242 ScRefTokenHelper::join(*mpTokens
, pNew
);
1244 else if (equals(e
, h
))
1246 // header is at the bottom.
1248 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1249 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1251 ScRefTokenHelper::join(*mpTokens
, pNew
);
1255 // header is somewhere in the middle.
1258 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1259 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1260 r
.Ref2
.InitAddress(h
.nCol
, h
.nRow
- 1, h
.nTab
);
1261 ScRefTokenHelper::join(*mpTokens
, pNew
);
1265 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1266 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1267 r
.Ref1
.InitAddress(h
.nCol
, h
.nRow
+ 1, h
.nTab
);
1268 ScRefTokenHelper::join(*mpTokens
, pNew
);
1273 void splitSingleRowRange(const ScSharedTokenRef
& pRange
, const ScSingleRefData
& s
, const ScSingleRefData
& e
)
1275 const ScSingleRefData
& h
= mpHeaderCell
->GetSingleRef();
1279 // header is at the top.
1281 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1282 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1284 ScRefTokenHelper::join(*mpTokens
, pNew
);
1286 else if (equals(e
, h
))
1288 // header is at the bottom.
1290 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1291 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1293 ScRefTokenHelper::join(*mpTokens
, pNew
);
1297 // header is somewhere in the middle.
1300 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1301 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1302 r
.Ref2
.InitAddress(h
.nCol
- 1, h
.nRow
, h
.nTab
);
1303 ScRefTokenHelper::join(*mpTokens
, pNew
);
1307 ScSharedTokenRef
pNew(static_cast<ScToken
*>(pRange
->Clone()));
1308 ScComplexRefData
& r
= pNew
->GetDoubleRef();
1309 r
.Ref1
.InitAddress(h
.nCol
+ 1, h
.nRow
, h
.nTab
);
1310 ScRefTokenHelper::join(*mpTokens
, pNew
);
1316 * Compare two single ref data for equality, but only compare their
1317 * absolute cell addresses while ignoring flags and relative addresses.
1319 bool equals(const ScSingleRefData
& r1
, const ScSingleRefData
& r2
) const
1321 return (r1
.nCol
== r2
.nCol
) && (r1
.nRow
== r2
.nRow
) && (r1
.nTab
== r2
.nTab
);
1324 bool isContained(const ScSharedTokenRef
& pRange
)
1326 bool bExternal
= ScRefTokenHelper::isExternalRef(mpHeaderCell
);
1327 if (bExternal
!= ScRefTokenHelper::isExternalRef(pRange
))
1328 // internal vs external.
1333 if (pRange
->GetIndex() != mpHeaderCell
->GetIndex())
1334 // different external files.
1337 if (pRange
->GetString() != mpHeaderCell
->GetString())
1342 ScComplexRefData aRange
;
1343 ScRefTokenHelper::getDoubleRefDataFromToken(aRange
, pRange
);
1344 const ScSingleRefData
& rCell
= mpHeaderCell
->GetSingleRef();
1346 bool bRowContained
= (aRange
.Ref1
.nRow
<= rCell
.nRow
) && (rCell
.nRow
<= aRange
.Ref2
.nRow
);
1347 bool bColContained
= (aRange
.Ref1
.nCol
<= rCell
.nCol
) && (rCell
.nCol
<= aRange
.Ref2
.nCol
);
1348 bool bTabContained
= (aRange
.Ref1
.nTab
<= rCell
.nTab
) && (rCell
.nTab
<= aRange
.Ref2
.nTab
);
1350 return (bRowContained
&& bColContained
&& bTabContained
);
1354 shared_ptr
< vector
<ScSharedTokenRef
> > mpTokens
;
1357 * Stores header cell position. Must be a single ref token i.e. either
1358 * ScSingleRefToken or ScExternalSingleRefToken.
1360 ScSharedTokenRef mpHeaderCell
;
1367 static void lcl_removeHeaderFromRanges(vector
<ScSharedTokenRef
>& rTokens
, const ScSharedTokenRef
& rHeaderCell
, bool bOrientCol
)
1369 RemoveHeaderFromRanges
func(rHeaderCell
, bOrientCol
);
1370 func
= for_each(rTokens
.begin(), rTokens
.end(), func
);
1371 func
.getNewTokens(rTokens
);
1374 uno::Reference
< chart2::data::XDataSource
> SAL_CALL
1375 ScChart2DataProvider::createDataSource(
1376 const uno::Sequence
< beans::PropertyValue
>& aArguments
)
1377 throw( lang::IllegalArgumentException
, uno::RuntimeException
)
1380 if ( ! m_pDocument
)
1381 throw uno::RuntimeException();
1383 uno::Reference
< chart2::data::XDataSource
> xResult
;
1385 bool bOrientCol
= true;
1386 ::rtl::OUString aRangeRepresentation
;
1387 uno::Sequence
< sal_Int32
> aSequenceMapping
;
1388 for(sal_Int32 i
= 0; i
< aArguments
.getLength(); ++i
)
1390 rtl::OUString
sName(aArguments
[i
].Name
);
1391 if (aArguments
[i
].Name
== rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataRowSource")))
1393 chart::ChartDataRowSource eSource
= chart::ChartDataRowSource_COLUMNS
;
1394 if( ! (aArguments
[i
].Value
>>= eSource
))
1396 sal_Int32
nSource(0);
1397 if( aArguments
[i
].Value
>>= nSource
)
1398 eSource
= (static_cast< chart::ChartDataRowSource
>( nSource
));
1400 bOrientCol
= (eSource
== chart::ChartDataRowSource_COLUMNS
);
1402 else if (aArguments
[i
].Name
== rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FirstCellAsLabel")))
1404 bLabel
= ::cppu::any2bool(aArguments
[i
].Value
);
1406 else if (aArguments
[i
].Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CellRangeRepresentation")))
1408 aArguments
[i
].Value
>>= aRangeRepresentation
;
1410 else if (aArguments
[i
].Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("SequenceMapping")))
1412 aArguments
[i
].Value
>>= aSequenceMapping
;
1416 vector
<ScSharedTokenRef
> aRefTokens
;
1417 ScRefTokenHelper::compileRangeRepresentation(aRefTokens
, aRangeRepresentation
, m_pDocument
, m_pDocument
->GetGrammar());
1418 if (aRefTokens
.empty())
1419 // Invalid range representation. Bail out.
1420 throw lang::IllegalArgumentException();
1423 addUpperLeftCornerIfMissing(aRefTokens
);
1425 bool bColHeaders
= (bOrientCol
? bLabel
: false );
1426 bool bRowHeaders
= (bOrientCol
? false : bLabel
);
1428 Chart2Positioner
aChPositioner(m_pDocument
, aRefTokens
);
1429 aChPositioner
.setHeaders(bColHeaders
, bRowHeaders
);
1431 const Chart2PositionMap
* pChartMap
= aChPositioner
.getPositionMap();
1433 // No chart position map instance. Bail out.
1436 ScChart2DataSource
* pDS
= NULL
;
1437 std::list
< ScChart2LabeledDataSequence
* > aSeqs
;
1441 ScChart2LabeledDataSequence
* pHeader
= NULL
;
1442 if (bOrientCol
? aChPositioner
.hasRowHeaders() : aChPositioner
.hasColHeaders())
1444 pHeader
= new ScChart2LabeledDataSequence(m_pDocument
);
1445 sal_Int32 nCount
= static_cast< sal_Int32
>( bOrientCol
? pChartMap
->getRowCount() : pChartMap
->getColCount() );
1446 vector
<ScSharedTokenRef
> aRefTokens2
;
1447 ScSharedTokenRef pLabelToken
;
1448 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
1450 const FormulaToken
* pPos
= bOrientCol
?
1451 pChartMap
->getRowHeaderPosition(static_cast<SCROW
>(i
)) :
1452 pChartMap
->getColHeaderPosition(static_cast<SCCOL
>(i
));
1455 ScSharedTokenRef
p(static_cast<ScToken
*>(pPos
->Clone()));
1456 ScRefTokenHelper::join(aRefTokens2
, p
);
1460 StackVar eType
= pLabelToken
->GetType();
1461 if (eType
== svSingleRef
|| eType
== svExternalSingleRef
)
1463 ScSingleRefData
& r
= pLabelToken
->GetSingleRef();
1476 auto_ptr
< vector
<ScSharedTokenRef
> > pTokens(new vector
<ScSharedTokenRef
>);
1477 pTokens
->push_back(pLabelToken
);
1478 Reference
< chart2::data::XDataSequence
> xLabelSeq(new ScChart2DataSequence(m_pDocument
, this, pTokens
.release(), m_bIncludeHiddenCells
));
1479 Reference
< beans::XPropertySet
> xLabelProps(xLabelSeq
, uno::UNO_QUERY
);
1480 if (xLabelProps
.is())
1481 xLabelProps
->setPropertyValue(
1482 OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ROLE
)),
1483 uno::makeAny(OUString(RTL_CONSTASCII_USTRINGPARAM("label"))));
1484 pHeader
->setLabel(xLabelSeq
);
1487 ScRefTokenHelper::join(aRefTokens2
, pLabelToken
);
1489 auto_ptr
< vector
<ScSharedTokenRef
> > pTokens(new vector
<ScSharedTokenRef
>);
1490 pTokens
->swap(aRefTokens2
);
1491 uno::Reference
< chart2::data::XDataSequence
> xSeq( new ScChart2DataSequence( m_pDocument
, this, pTokens
.release(), m_bIncludeHiddenCells
) );
1492 pHeader
->setValues(xSeq
);
1495 aSeqs
.push_back(pHeader
);
1497 // Fill Serieses with Labels
1499 sal_Int32 nCount
= bOrientCol
? pChartMap
->getColCount() : pChartMap
->getRowCount();
1500 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
1502 ScChart2LabeledDataSequence
* pLabeled
= new ScChart2LabeledDataSequence(m_pDocument
);
1503 uno::Reference
< chart2::data::XDataSequence
> xLabelSeq
;
1504 auto_ptr
< vector
<ScSharedTokenRef
> > pRanges(NULL
);
1506 pRanges
.reset(pChartMap
->getColRanges(static_cast<SCCOL
>(i
)));
1508 pRanges
.reset(pChartMap
->getRowRanges(static_cast<SCROW
>(i
)));
1510 ScSharedTokenRef pHeaderCell
;
1513 const FormulaToken
* p
= pChartMap
->getColHeaderPosition(static_cast<SCCOL
>(i
));
1515 pHeaderCell
.reset(static_cast<ScToken
*>(p
->Clone()));
1519 const FormulaToken
* p
= pChartMap
->getRowHeaderPosition(static_cast<SCROW
>(i
));
1521 pHeaderCell
.reset(static_cast<ScToken
*>(p
->Clone()));
1526 if (!pHeaderCell
&& pRanges
.get() && !pRanges
->empty())
1528 const ScSharedTokenRef
& p
= pRanges
->front();
1529 if (p
&& ScRefTokenHelper::isRef(p
))
1531 // Take the first cell in the range as the header position.
1532 ScSingleRefData aData
= p
->GetSingleRef();
1533 bool bExternal
= ScRefTokenHelper::isExternalRef(p
);
1536 sal_uInt16 nFileId
= p
->GetIndex();
1537 const String
& rTabName
= p
->GetString();
1538 pHeaderCell
.reset(new ScExternalSingleRefToken(nFileId
, rTabName
, aData
));
1541 pHeaderCell
.reset(new ScSingleRefToken(aData
));
1546 auto_ptr
< vector
<ScSharedTokenRef
> > pTokens(new vector
<ScSharedTokenRef
>);
1547 pTokens
->reserve(1);
1548 pTokens
->push_back(pHeaderCell
);
1549 xLabelSeq
.set(new ScChart2DataSequence(m_pDocument
, this, pTokens
.release(), m_bIncludeHiddenCells
));
1550 uno::Reference
< beans::XPropertySet
> xLabelProps(xLabelSeq
, uno::UNO_QUERY
);
1551 if (xLabelProps
.is())
1552 xLabelProps
->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ROLE
)), uno::makeAny(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("label"))));
1554 // remove Header from Ranges
1555 lcl_removeHeaderFromRanges(*pRanges
, pHeaderCell
, bOrientCol
);
1561 ScRefTokenHelper::join(*pRanges
, pHeaderCell
);
1564 // FIXME: if there are no labels the column or row name should be taken
1566 uno::Reference
< chart2::data::XDataSequence
> xSeq(new ScChart2DataSequence(m_pDocument
, this, pRanges
.release(), m_bIncludeHiddenCells
));
1568 pLabeled
->setValues(xSeq
);
1569 pLabeled
->setLabel(xLabelSeq
);
1571 aSeqs
.push_back(pLabeled
);
1574 pDS
= new ScChart2DataSource(m_pDocument
);
1575 std::list
< ScChart2LabeledDataSequence
* >::iterator
aItr(aSeqs
.begin());
1576 std::list
< ScChart2LabeledDataSequence
* >::iterator
aEndItr(aSeqs
.end());
1578 //reorder labeled sequences according to aSequenceMapping
1579 std::vector
< ScChart2LabeledDataSequence
* > aSeqVector
;
1580 while(aItr
!= aEndItr
)
1582 aSeqVector
.push_back(*aItr
);
1586 std::map
< sal_Int32
, ScChart2LabeledDataSequence
* > aSequenceMap
;
1587 for( sal_Int32 nNewIndex
= 0; nNewIndex
< aSequenceMapping
.getLength(); nNewIndex
++ )
1589 // note: assuming that the values in the sequence mapping are always non-negative
1590 std::vector
< ScChart2LabeledDataSequence
* >::size_type
nOldIndex( static_cast< sal_uInt32
>( aSequenceMapping
[nNewIndex
] ));
1591 if( nOldIndex
< aSeqVector
.size() )
1593 pDS
->AddLabeledSequence( aSeqVector
[nOldIndex
] );
1594 aSeqVector
[nOldIndex
] = 0;
1599 std::vector
< ScChart2LabeledDataSequence
* >::iterator
aVectorItr(aSeqVector
.begin());
1600 std::vector
< ScChart2LabeledDataSequence
* >::iterator
aVectorEndItr(aSeqVector
.end());
1601 while(aVectorItr
!= aVectorEndItr
)
1604 pDS
->AddLabeledSequence(*aVectorItr
);
1615 bool lcl_HasCategories(
1616 const uno::Reference
< chart2::data::XDataSource
>& xDataSource
,
1617 bool & rOutHasCategories
)
1619 bool bResult
= false;
1620 uno::Reference
< chart2::data::XLabeledDataSequence
> xCategories(
1621 lcl_getCategoriesFromDataSource( xDataSource
));
1622 if( xCategories
.is())
1624 uno::Reference
< lang::XServiceInfo
> xValues( xCategories
->getValues(), uno::UNO_QUERY
);
1627 rOutHasCategories
= xValues
->getImplementationName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ScChart2DataSequence"));
1634 bool lcl_HasFirstCellAsLabel(
1635 const uno::Reference
< chart2::data::XDataSource
>& xDataSource
,
1636 bool & rOutHasFirstCellAsLabel
)
1638 bool bResult
= false;
1639 if( xDataSource
.is())
1641 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aSequences(
1642 xDataSource
->getDataSequences());
1643 const sal_Int32
nCount( aSequences
.getLength());
1644 if (nCount
> 0 && aSequences
[nCount
- 1].is() )
1646 uno::Reference
< lang::XServiceInfo
> xLabel( aSequences
[nCount
- 1]->getLabel(), uno::UNO_QUERY
); // take the last sequence, because the first has no label if it is also created
1649 rOutHasFirstCellAsLabel
= xLabel
->getImplementationName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ScChart2DataSequence"));
1657 } // anonymous namespace
1659 bool ScChart2DataProvider::addUpperLeftCornerIfMissing(vector
<ScSharedTokenRef
>& rRefTokens
)
1664 if (rRefTokens
.empty())
1667 SCCOL nMinCol
= MAXCOLCOUNT
;
1668 SCROW nMinRow
= MAXROWCOUNT
;
1675 bool bExternal
= false;
1677 vector
<ScSharedTokenRef
>::const_iterator itr
= rRefTokens
.begin(), itrEnd
= rRefTokens
.end();
1679 // Get the first ref token.
1680 ScSharedTokenRef pToken
= *itr
;
1681 switch (pToken
->GetType())
1685 const ScSingleRefData
& rData
= pToken
->GetSingleRef();
1686 nMinCol
= rData
.nCol
;
1687 nMinRow
= rData
.nRow
;
1688 nMaxCol
= rData
.nCol
;
1689 nMaxRow
= rData
.nRow
;
1695 const ScComplexRefData
& rData
= pToken
->GetDoubleRef();
1696 nMinCol
= min(rData
.Ref1
.nCol
, rData
.Ref2
.nCol
);
1697 nMinRow
= min(rData
.Ref1
.nRow
, rData
.Ref2
.nRow
);
1698 nMaxCol
= max(rData
.Ref1
.nCol
, rData
.Ref2
.nCol
);
1699 nMaxRow
= max(rData
.Ref1
.nRow
, rData
.Ref2
.nRow
);
1700 nTab
= rData
.Ref1
.nTab
;
1703 case svExternalSingleRef
:
1705 const ScSingleRefData
& rData
= pToken
->GetSingleRef();
1706 nMinCol
= rData
.nCol
;
1707 nMinRow
= rData
.nRow
;
1708 nMaxCol
= rData
.nCol
;
1709 nMaxRow
= rData
.nRow
;
1711 nFileId
= pToken
->GetIndex();
1712 aExtTabName
= pToken
->GetString();
1716 case svExternalDoubleRef
:
1718 const ScComplexRefData
& rData
= pToken
->GetDoubleRef();
1719 nMinCol
= min(rData
.Ref1
.nCol
, rData
.Ref2
.nCol
);
1720 nMinRow
= min(rData
.Ref1
.nRow
, rData
.Ref2
.nRow
);
1721 nMaxCol
= max(rData
.Ref1
.nCol
, rData
.Ref2
.nCol
);
1722 nMaxRow
= max(rData
.Ref1
.nRow
, rData
.Ref2
.nRow
);
1723 nTab
= rData
.Ref1
.nTab
;
1724 nFileId
= pToken
->GetIndex();
1725 aExtTabName
= pToken
->GetString();
1733 // Determine the minimum range enclosing all data ranges. Also make sure
1734 // that they are all on the same table.
1736 for (++itr
; itr
!= itrEnd
; ++itr
)
1739 switch (pToken
->GetType())
1743 const ScSingleRefData
& rData
= pToken
->GetSingleRef();
1745 nMinCol
= min(nMinCol
, rData
.nCol
);
1746 nMinRow
= min(nMinRow
, rData
.nRow
);
1747 nMaxCol
= max(nMaxCol
, rData
.nCol
);
1748 nMaxRow
= max(nMaxRow
, rData
.nRow
);
1749 if (nTab
!= rData
.nTab
|| bExternal
)
1755 const ScComplexRefData
& rData
= pToken
->GetDoubleRef();
1757 nMinCol
= min(nMinCol
, rData
.Ref1
.nCol
);
1758 nMinCol
= min(nMinCol
, rData
.Ref2
.nCol
);
1759 nMinRow
= min(nMinRow
, rData
.Ref1
.nRow
);
1760 nMinRow
= min(nMinRow
, rData
.Ref2
.nRow
);
1762 nMaxCol
= max(nMaxCol
, rData
.Ref1
.nCol
);
1763 nMaxCol
= max(nMaxCol
, rData
.Ref2
.nCol
);
1764 nMaxRow
= max(nMaxRow
, rData
.Ref1
.nRow
);
1765 nMaxRow
= max(nMaxRow
, rData
.Ref2
.nRow
);
1767 if (nTab
!= rData
.Ref1
.nTab
|| bExternal
)
1771 case svExternalSingleRef
:
1776 if (nFileId
!= pToken
->GetIndex() || aExtTabName
!= pToken
->GetString())
1779 const ScSingleRefData
& rData
= pToken
->GetSingleRef();
1781 nMinCol
= min(nMinCol
, rData
.nCol
);
1782 nMinRow
= min(nMinRow
, rData
.nRow
);
1783 nMaxCol
= max(nMaxCol
, rData
.nCol
);
1784 nMaxRow
= max(nMaxRow
, rData
.nRow
);
1787 case svExternalDoubleRef
:
1792 if (nFileId
!= pToken
->GetIndex() || aExtTabName
!= pToken
->GetString())
1795 const ScComplexRefData
& rData
= pToken
->GetDoubleRef();
1797 nMinCol
= min(nMinCol
, rData
.Ref1
.nCol
);
1798 nMinCol
= min(nMinCol
, rData
.Ref2
.nCol
);
1799 nMinRow
= min(nMinRow
, rData
.Ref1
.nRow
);
1800 nMinRow
= min(nMinRow
, rData
.Ref2
.nRow
);
1802 nMaxCol
= max(nMaxCol
, rData
.Ref1
.nCol
);
1803 nMaxCol
= max(nMaxCol
, rData
.Ref2
.nCol
);
1804 nMaxRow
= max(nMaxRow
, rData
.Ref1
.nRow
);
1805 nMaxRow
= max(nMaxRow
, rData
.Ref2
.nRow
);
1813 if (nMinRow
>= nMaxRow
|| nMinCol
>= nMaxCol
||
1814 nMinRow
>= MAXROWCOUNT
|| nMinCol
>= MAXCOLCOUNT
||
1815 nMaxRow
>= MAXROWCOUNT
|| nMaxCol
>= MAXCOLCOUNT
)
1817 // Invalid range. Bail out.
1821 // Check if the following conditions are met:
1823 // 1) The upper-left corner cell is not included.
1824 // 2) The three adjacent cells of that corner cell are included.
1826 bool bRight
= false, bBottom
= false, bDiagonal
= false;
1827 for (itr
= rRefTokens
.begin(); itr
!= itrEnd
; ++itr
)
1830 switch (pToken
->GetType())
1833 case svExternalSingleRef
:
1835 const ScSingleRefData
& rData
= pToken
->GetSingleRef();
1836 if (rData
.nCol
== nMinCol
&& rData
.nRow
== nMinRow
)
1837 // The corner cell is contained.
1840 if (rData
.nCol
== nMinCol
+1 && rData
.nRow
== nMinRow
)
1843 if (rData
.nCol
== nMinCol
&& rData
.nRow
== nMinRow
+1)
1846 if (rData
.nCol
== nMinCol
+1 && rData
.nRow
== nMinRow
+1)
1851 case svExternalDoubleRef
:
1853 const ScComplexRefData
& rData
= pToken
->GetDoubleRef();
1854 const ScSingleRefData
& r1
= rData
.Ref1
;
1855 const ScSingleRefData
& r2
= rData
.Ref2
;
1856 if (r1
.nCol
<= nMinCol
&& nMinCol
<= r2
.nCol
&&
1857 r1
.nRow
<= nMinRow
&& nMinRow
<= r2
.nRow
)
1858 // The corner cell is contained.
1861 if (r1
.nCol
<= nMinCol
+1 && nMinCol
+1 <= r2
.nCol
&&
1862 r1
.nRow
<= nMinRow
&& nMinRow
<= r2
.nRow
)
1865 if (r1
.nCol
<= nMinCol
&& nMinCol
<= r2
.nCol
&&
1866 r1
.nRow
<= nMinRow
+1 && nMinRow
+1 <= r2
.nRow
)
1869 if (r1
.nCol
<= nMinCol
+1 && nMinCol
+1 <= r2
.nCol
&&
1870 r1
.nRow
<= nMinRow
+1 && nMinRow
+1 <= r2
.nRow
)
1879 if (!bRight
|| !bBottom
|| !bDiagonal
)
1880 // Not all the adjacent cells are included. Bail out.
1883 #if 0 // Do we really need to do this ???
1884 if (rRefTokens
.size() == 2)
1886 // Make a simple rectangular range if possible.
1887 ScRange
aRightPart(ScAddress(nMinCol
+1, nMinRow
, nTab
), ScAddress(nMaxCol
, nMaxRow
, nTab
));
1888 ScRange
aBottomPart(ScAddress(nMinCol
, nMinRow
+1, nTab
), ScAddress(nMaxCol
, nMaxRow
, nTab
));
1889 vector
<ScRange
> aRanges
;
1891 aRanges
.push_back(aRightPart
);
1892 aRanges
.push_back(aBottomPart
);
1893 if (lcl_isRangeContained(rRefTokens
, aRanges
))
1895 // Consolidate them into a single rectangle.
1896 ScComplexRefData aData
;
1898 aData
.Ref1
.SetFlag3D(true);
1899 aData
.Ref1
.SetColRel(false);
1900 aData
.Ref1
.SetRowRel(false);
1901 aData
.Ref1
.SetTabRel(false);
1902 aData
.Ref2
.SetColRel(false);
1903 aData
.Ref2
.SetRowRel(false);
1904 aData
.Ref2
.SetTabRel(false);
1905 aData
.Ref1
.nCol
= nMinCol
;
1906 aData
.Ref1
.nRow
= nMinRow
;
1907 aData
.Ref1
.nTab
= nTab
;
1908 aData
.Ref2
.nCol
= nMaxCol
;
1909 aData
.Ref2
.nRow
= nMaxRow
;
1910 aData
.Ref2
.nTab
= nTab
;
1911 vector
<ScSharedTokenRef
> aNewTokens
;
1912 aNewTokens
.reserve(1);
1916 new ScExternalDoubleRefToken(nFileId
, aExtTabName
, aData
));
1917 aNewTokens
.push_back(p
);
1921 ScSharedTokenRef
p(new ScDoubleRefToken(aData
));
1922 aNewTokens
.push_back(p
);
1924 rRefTokens
.swap(aNewTokens
);
1930 ScSingleRefData aData
;
1932 aData
.SetFlag3D(true);
1933 aData
.SetColRel(false);
1934 aData
.SetRowRel(false);
1935 aData
.SetTabRel(false);
1936 aData
.nCol
= nMinCol
;
1937 aData
.nRow
= nMinRow
;
1942 ScSharedTokenRef
pCorner(
1943 new ScExternalSingleRefToken(nFileId
, aExtTabName
, aData
));
1944 ScRefTokenHelper::join(rRefTokens
, pCorner
);
1948 ScSharedTokenRef
pCorner(new ScSingleRefToken(aData
));
1949 ScRefTokenHelper::join(rRefTokens
, pCorner
);
1958 * Function object to create a list of table numbers from a token list.
1960 class InsertTabNumber
: public unary_function
<ScSharedTokenRef
, void>
1964 mpTabNumList(new list
<SCTAB
>())
1968 InsertTabNumber(const InsertTabNumber
& r
) :
1969 mpTabNumList(r
.mpTabNumList
)
1973 void operator() (const ScSharedTokenRef
& pToken
) const
1975 if (!ScRefTokenHelper::isRef(pToken
))
1978 const ScSingleRefData
& r
= pToken
->GetSingleRef();
1979 mpTabNumList
->push_back(r
.nTab
);
1982 void getList(list
<SCTAB
>& rList
)
1984 mpTabNumList
->swap(rList
);
1987 shared_ptr
< list
<SCTAB
> > mpTabNumList
;
1992 uno::Sequence
< beans::PropertyValue
> SAL_CALL
ScChart2DataProvider::detectArguments(
1993 const uno::Reference
< chart2::data::XDataSource
>& xDataSource
)
1994 throw (uno::RuntimeException
)
1996 ::std::vector
< beans::PropertyValue
> aResult
;
1997 bool bRowSourceDetected
= false;
1998 bool bFirstCellAsLabel
= false;
1999 bool bHasCategories
= true;
2000 ::rtl::OUString sRangeRep
;
2002 chart::ChartDataRowSource eRowSource
= chart::ChartDataRowSource_COLUMNS
;
2004 vector
<ScSharedTokenRef
> aTokens
;
2006 // CellRangeRepresentation
2009 DBG_ASSERT( m_pDocument
, "No Document -> no detectArguments" );
2011 return lcl_VectorToSequence( aResult
);
2013 detectRangesFromDataSource(aTokens
, eRowSource
, bRowSourceDetected
, xDataSource
);
2018 list
<SCTAB
> aTableNumList
;
2019 InsertTabNumber func
;
2020 func
= for_each(aTokens
.begin(), aTokens
.end(), func
);
2021 func
.getList(aTableNumList
);
2023 beans::PropertyValue( ::rtl::OUString::createFromAscii("TableNumberList"), -1,
2024 uno::makeAny( lcl_createTableNumberList( aTableNumList
) ),
2025 beans::PropertyState_DIRECT_VALUE
));
2028 // DataRowSource (calculated before)
2029 if( bRowSourceDetected
)
2032 beans::PropertyValue( ::rtl::OUString::createFromAscii("DataRowSource"), -1,
2033 uno::makeAny( eRowSource
), beans::PropertyState_DIRECT_VALUE
));
2037 if( bRowSourceDetected
)
2039 if( lcl_HasCategories( xDataSource
, bHasCategories
))
2042 beans::PropertyValue( ::rtl::OUString::createFromAscii("HasCategories"), -1,
2043 uno::makeAny( bHasCategories
), beans::PropertyState_DIRECT_VALUE
));
2048 if( bRowSourceDetected
)
2050 lcl_HasFirstCellAsLabel( xDataSource
, bFirstCellAsLabel
);
2052 beans::PropertyValue( ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1,
2053 uno::makeAny( bFirstCellAsLabel
), beans::PropertyState_DIRECT_VALUE
));
2056 // Add the left upper corner to the range if it is missing.
2057 if (bRowSourceDetected
&& bFirstCellAsLabel
&& bHasCategories
)
2058 addUpperLeftCornerIfMissing(aTokens
);
2060 // Get range string.
2061 lcl_convertTokensToString(sRangeRep
, aTokens
, m_pDocument
);
2063 // add cell range property
2065 beans::PropertyValue( ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1,
2066 uno::makeAny( sRangeRep
), beans::PropertyState_DIRECT_VALUE
));
2069 bool bSequencesReordered
= true;//todo detect this above or detect this sequence mapping cheaper ...
2070 if( bSequencesReordered
&& bRowSourceDetected
)
2072 bool bDifferentIndexes
= false;
2074 std::vector
< sal_Int32
> aSequenceMappingVector
;
2076 uno::Reference
< chart2::data::XDataSource
> xCompareDataSource
;
2079 xCompareDataSource
.set( this->createDataSource( lcl_VectorToSequence( aResult
) ) );
2081 catch( const lang::IllegalArgumentException
& )
2083 // creation of data source to compare didn't work, so we cannot
2084 // create a sequence mapping
2087 if( xDataSource
.is() && xCompareDataSource
.is() )
2089 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aOldSequences(
2090 xCompareDataSource
->getDataSequences() );
2091 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aNewSequences(
2092 xDataSource
->getDataSequences());
2094 rtl::OUString aOldLabel
;
2095 rtl::OUString aNewLabel
;
2096 rtl::OUString aOldValues
;
2097 rtl::OUString aNewValues
;
2098 rtl::OUString aEmpty
;
2100 for( sal_Int32 nNewIndex
= 0; nNewIndex
< aNewSequences
.getLength(); nNewIndex
++ )
2102 uno::Reference
< chart2::data::XLabeledDataSequence
> xNew( aNewSequences
[nNewIndex
] );
2103 for( sal_Int32 nOldIndex
= 0; nOldIndex
< aOldSequences
.getLength(); nOldIndex
++ )
2105 uno::Reference
< chart2::data::XLabeledDataSequence
> xOld( aOldSequences
[nOldIndex
] );
2107 if( xOld
.is() && xNew
.is() )
2109 aOldLabel
= aNewLabel
= aOldValues
= aNewValues
= aEmpty
;
2110 if( xOld
.is() && xOld
->getLabel().is() )
2111 aOldLabel
= xOld
->getLabel()->getSourceRangeRepresentation();
2112 if( xNew
.is() && xNew
->getLabel().is() )
2113 aNewLabel
= xNew
->getLabel()->getSourceRangeRepresentation();
2114 if( xOld
.is() && xOld
->getValues().is() )
2115 aOldValues
= xOld
->getValues()->getSourceRangeRepresentation();
2116 if( xNew
.is() && xNew
->getValues().is() )
2117 aNewValues
= xNew
->getValues()->getSourceRangeRepresentation();
2119 if( aOldLabel
.equals(aNewLabel
)
2120 && ( aOldValues
.equals(aNewValues
) ) )
2122 if( nOldIndex
!=nNewIndex
)
2123 bDifferentIndexes
= true;
2124 aSequenceMappingVector
.push_back(nOldIndex
);
2132 if( bDifferentIndexes
&& aSequenceMappingVector
.size() )
2135 beans::PropertyValue( ::rtl::OUString::createFromAscii("SequenceMapping"), -1,
2136 uno::makeAny( lcl_VectorToSequence(aSequenceMappingVector
) )
2137 , beans::PropertyState_DIRECT_VALUE
));
2141 return lcl_VectorToSequence( aResult
);
2144 ::sal_Bool SAL_CALL
ScChart2DataProvider::createDataSequenceByRangeRepresentationPossible( const ::rtl::OUString
& aRangeRepresentation
)
2145 throw (uno::RuntimeException
)
2151 vector
<ScSharedTokenRef
> aTokens
;
2152 ScRefTokenHelper::compileRangeRepresentation(aTokens
, aRangeRepresentation
, m_pDocument
, m_pDocument
->GetGrammar());
2153 return !aTokens
.empty();
2156 uno::Reference
< chart2::data::XDataSequence
> SAL_CALL
2157 ScChart2DataProvider::createDataSequenceByRangeRepresentation(
2158 const ::rtl::OUString
& aRangeRepresentation
)
2159 throw (lang::IllegalArgumentException
,
2160 uno::RuntimeException
)
2163 uno::Reference
< chart2::data::XDataSequence
> xResult
;
2165 DBG_ASSERT( m_pDocument
, "No Document -> no createDataSequenceByRangeRepresentation" );
2166 if(!m_pDocument
|| (aRangeRepresentation
.getLength() == 0))
2169 // Note: the range representation must be in Calc A1 format. The import
2170 // filters use this method to pass data ranges, and they have no idea what
2171 // the current formula syntax is. In the future we should add another
2172 // method to allow the client code to directly pass tokens representing
2175 vector
<ScSharedTokenRef
> aRefTokens
;
2176 ScRefTokenHelper::compileRangeRepresentation(aRefTokens
, aRangeRepresentation
, m_pDocument
);
2177 if (aRefTokens
.empty())
2180 // ScChart2DataSequence manages the life cycle of pRefTokens.
2181 vector
<ScSharedTokenRef
>* pRefTokens
= new vector
<ScSharedTokenRef
>();
2182 pRefTokens
->swap(aRefTokens
);
2183 xResult
.set(new ScChart2DataSequence(m_pDocument
, this, pRefTokens
, m_bIncludeHiddenCells
));
2188 uno::Reference
< sheet::XRangeSelection
> SAL_CALL
ScChart2DataProvider::getRangeSelection()
2189 throw (uno::RuntimeException
)
2191 uno::Reference
< sheet::XRangeSelection
> xResult
;
2193 uno::Reference
< frame::XModel
> xModel( lcl_GetXModel( m_pDocument
));
2195 xResult
.set( xModel
->getCurrentController(), uno::UNO_QUERY
);
2200 /*uno::Reference< util::XNumberFormatsSupplier > SAL_CALL ScChart2DataProvider::getNumberFormatsSupplier()
2201 throw (uno::RuntimeException)
2203 return uno::Reference< util::XNumberFormatsSupplier >( lcl_GetXModel( m_pDocument ), uno::UNO_QUERY );
2206 // XRangeXMLConversion ---------------------------------------------------
2208 rtl::OUString SAL_CALL
ScChart2DataProvider::convertRangeToXML( const rtl::OUString
& sRangeRepresentation
)
2209 throw ( uno::RuntimeException
, lang::IllegalArgumentException
)
2215 if (!sRangeRepresentation
.getLength())
2216 // Empty data range is allowed.
2219 vector
<ScSharedTokenRef
> aRefTokens
;
2220 ScRefTokenHelper::compileRangeRepresentation(aRefTokens
, sRangeRepresentation
, m_pDocument
, m_pDocument
->GetGrammar());
2221 if (aRefTokens
.empty())
2222 throw lang::IllegalArgumentException();
2224 Tokens2RangeStringXML
converter(m_pDocument
);
2225 converter
= for_each(aRefTokens
.begin(), aRefTokens
.end(), converter
);
2226 converter
.getString(aRet
);
2231 rtl::OUString SAL_CALL
ScChart2DataProvider::convertRangeFromXML( const rtl::OUString
& sXMLRange
)
2232 throw ( uno::RuntimeException
, lang::IllegalArgumentException
)
2234 const sal_Unicode cSep
= ' ';
2235 const sal_Unicode cQuote
= '\'';
2239 // #i74062# When loading flat XML, this is called before the referenced sheets are in the document,
2240 // so the conversion has to take place directly with the strings, without looking up the sheets.
2242 rtl::OUStringBuffer sRet
;
2243 sal_Int32 nOffset
= 0;
2244 while( nOffset
>= 0 )
2246 rtl::OUString sToken
;
2247 ScRangeStringConverter::GetTokenByOffset( sToken
, sXMLRange
, nOffset
, cSep
, cQuote
);
2250 // convert one address (remove dots)
2252 String
aUIString(sToken
);
2254 sal_Int32 nIndex
= ScRangeStringConverter::IndexOf( sToken
, ':', 0, cQuote
);
2255 if ( nIndex
>= 0 && nIndex
< aUIString
.Len() - 1 &&
2256 aUIString
.GetChar((xub_StrLen
)nIndex
+ 1) == (sal_Unicode
) '.' )
2257 aUIString
.Erase( (xub_StrLen
)nIndex
+ 1, 1 );
2259 if ( aUIString
.GetChar(0) == (sal_Unicode
) '.' )
2260 aUIString
.Erase( 0, 1 );
2262 if( sRet
.getLength() )
2263 sRet
.append( (sal_Unicode
) ';' );
2264 sRet
.append( aUIString
);
2268 return sRet
.makeStringAndClear();
2272 ScRangeStringConverter::GetStringFromXMLRangeString(aRet
, sXMLRange
, m_pDocument
);
2278 class CollectRefTokens
: public ::std::unary_function
<ScSharedTokenRef
, void>
2281 CollectRefTokens() :
2282 mpRefTokens(new vector
<ScSharedTokenRef
>()),
2285 mbRowSourceAmbiguous(false)
2289 CollectRefTokens(const CollectRefTokens
& r
) :
2290 mpRefTokens(r
.mpRefTokens
),
2291 mnDataInRows(r
.mnDataInRows
),
2292 mnDataInCols(r
.mnDataInCols
),
2293 mbRowSourceAmbiguous(r
.mbRowSourceAmbiguous
)
2297 void operator() (const ScSharedTokenRef
& rRefToken
)
2299 if (!mbRowSourceAmbiguous
)
2301 StackVar eVar
= rRefToken
->GetType();
2302 if (eVar
== svDoubleRef
|| eVar
== svExternalDoubleRef
)
2304 const ScComplexRefData
& r
= rRefToken
->GetDoubleRef();
2305 mbRowSourceAmbiguous
= r
.Ref1
.nTab
!= r
.Ref2
.nTab
;
2306 if (!mbRowSourceAmbiguous
)
2308 bool bColDiff
= (r
.Ref2
.nCol
- r
.Ref1
.nCol
) != 0;
2309 bool bRowDiff
= (r
.Ref2
.nRow
- r
.Ref1
.nRow
) != 0;
2311 if (bColDiff
&& !bRowDiff
)
2313 else if (bRowDiff
&& !bColDiff
)
2315 else if (bRowDiff
&& bColDiff
)
2316 mbRowSourceAmbiguous
= true;
2318 if (mnDataInRows
> 0 && mnDataInCols
> 0)
2319 mbRowSourceAmbiguous
= true;
2324 mpRefTokens
->push_back(rRefToken
);
2327 void appendTokens(vector
<ScSharedTokenRef
>& rTokens
)
2329 vector
<ScSharedTokenRef
> aNewTokens
= rTokens
;
2330 vector
<ScSharedTokenRef
>::const_iterator itr
= mpRefTokens
->begin(), itrEnd
= mpRefTokens
->end();
2331 for (; itr
!= itrEnd
; ++itr
)
2332 ScRefTokenHelper::join(aNewTokens
, *itr
);
2334 rTokens
.swap(aNewTokens
);
2337 bool isRowSourceAmbiguous() const
2339 return mbRowSourceAmbiguous
;
2342 sal_uInt32
getDataInRows() const
2344 return mnDataInRows
;
2347 sal_uInt32
getDataInCols() const
2349 return mnDataInCols
;
2353 shared_ptr
< vector
<ScSharedTokenRef
> > mpRefTokens
;
2354 sal_uInt32 mnDataInRows
;
2355 sal_uInt32 mnDataInCols
;
2356 bool mbRowSourceAmbiguous
;
2361 // DataProvider XPropertySet -------------------------------------------------
2363 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
2364 ScChart2DataProvider::getPropertySetInfo() throw( uno::RuntimeException
)
2367 static uno::Reference
<beans::XPropertySetInfo
> aRef
=
2368 new SfxItemPropertySetInfo( m_aPropSet
.getPropertyMap() );
2373 void SAL_CALL
ScChart2DataProvider::setPropertyValue(
2374 const ::rtl::OUString
& rPropertyName
, const uno::Any
& rValue
)
2375 throw( beans::UnknownPropertyException
,
2376 beans::PropertyVetoException
,
2377 lang::IllegalArgumentException
,
2378 lang::WrappedTargetException
, uno::RuntimeException
)
2380 if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS
)))
2382 if ( !(rValue
>>= m_bIncludeHiddenCells
))
2383 throw lang::IllegalArgumentException();
2386 throw beans::UnknownPropertyException();
2390 uno::Any SAL_CALL
ScChart2DataProvider::getPropertyValue(
2391 const ::rtl::OUString
& rPropertyName
)
2392 throw( beans::UnknownPropertyException
,
2393 lang::WrappedTargetException
, uno::RuntimeException
)
2396 if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS
)))
2397 aRet
<<= m_bIncludeHiddenCells
;
2399 throw beans::UnknownPropertyException();
2404 void SAL_CALL
ScChart2DataProvider::addPropertyChangeListener(
2405 const ::rtl::OUString
& /*rPropertyName*/,
2406 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/)
2407 throw( beans::UnknownPropertyException
,
2408 lang::WrappedTargetException
, uno::RuntimeException
)
2410 OSL_ENSURE( false, "Not yet implemented" );
2414 void SAL_CALL
ScChart2DataProvider::removePropertyChangeListener(
2415 const ::rtl::OUString
& /*rPropertyName*/,
2416 const uno::Reference
< beans::XPropertyChangeListener
>& /*rListener*/)
2417 throw( beans::UnknownPropertyException
,
2418 lang::WrappedTargetException
, uno::RuntimeException
)
2420 OSL_ENSURE( false, "Not yet implemented" );
2424 void SAL_CALL
ScChart2DataProvider::addVetoableChangeListener(
2425 const ::rtl::OUString
& /*rPropertyName*/,
2426 const uno::Reference
< beans::XVetoableChangeListener
>& /*rListener*/)
2427 throw( beans::UnknownPropertyException
,
2428 lang::WrappedTargetException
, uno::RuntimeException
)
2430 OSL_ENSURE( false, "Not yet implemented" );
2434 void SAL_CALL
ScChart2DataProvider::removeVetoableChangeListener(
2435 const ::rtl::OUString
& /*rPropertyName*/,
2436 const uno::Reference
< beans::XVetoableChangeListener
>& /*rListener*/ )
2437 throw( beans::UnknownPropertyException
,
2438 lang::WrappedTargetException
, uno::RuntimeException
)
2440 OSL_ENSURE( false, "Not yet implemented" );
2443 void ScChart2DataProvider::detectRangesFromDataSource(vector
<ScSharedTokenRef
>& rRefTokens
,
2444 chart::ChartDataRowSource
& rRowSource
,
2445 bool& rRowSourceDetected
,
2446 const Reference
<chart2::data::XDataSource
>& xDataSource
)
2451 sal_Int32 nDataInRows
= 0;
2452 sal_Int32 nDataInCols
= 0;
2453 bool bRowSourceAmbiguous
= false;
2455 vector
<OUString
> aRangeReps
= lcl_getRangeRepresentationsFromDataSource(xDataSource
);
2456 for (vector
<OUString
>::const_iterator itr
= aRangeReps
.begin(), itrEnd
= aRangeReps
.end();
2457 itr
!= itrEnd
; ++itr
)
2459 const OUString
& rRangeRep
= *itr
;
2460 vector
<ScSharedTokenRef
> aTokens
;
2461 ScRefTokenHelper::compileRangeRepresentation(aTokens
, rRangeRep
, m_pDocument
, m_pDocument
->GetGrammar());
2463 CollectRefTokens func
;
2464 func
= for_each(aTokens
.begin(), aTokens
.end(), func
);
2465 func
.appendTokens(rRefTokens
);
2466 bRowSourceAmbiguous
= bRowSourceAmbiguous
|| func
.isRowSourceAmbiguous();
2467 if (!bRowSourceAmbiguous
)
2469 nDataInRows
+= func
.getDataInRows();
2470 nDataInCols
+= func
.getDataInCols();
2474 if (!bRowSourceAmbiguous
)
2476 rRowSourceDetected
= true;
2477 rRowSource
= ( nDataInRows
> 0
2478 ? chart::ChartDataRowSource_ROWS
2479 : chart::ChartDataRowSource_COLUMNS
);
2483 // set DataRowSource to the better of the two ambiguities
2484 rRowSource
= ( nDataInRows
> nDataInCols
2485 ? chart::ChartDataRowSource_ROWS
2486 : chart::ChartDataRowSource_COLUMNS
);
2490 // DataSource ================================================================
2492 ScChart2DataSource::ScChart2DataSource( ScDocument
* pDoc
)
2493 : m_pDocument( pDoc
)
2496 m_pDocument
->AddUnoObject( *this);
2500 ScChart2DataSource::~ScChart2DataSource()
2503 m_pDocument
->RemoveUnoObject( *this);
2507 void ScChart2DataSource::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
2509 if ( rHint
.ISA( SfxSimpleHint
) &&
2510 ((const SfxSimpleHint
&)rHint
).GetId() == SFX_HINT_DYING
)
2517 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > SAL_CALL
2518 ScChart2DataSource::getDataSequences() throw ( uno::RuntimeException
)
2522 LabeledList::const_iterator
aItr(m_aLabeledSequences
.begin());
2523 LabeledList::const_iterator
aEndItr(m_aLabeledSequences
.end());
2525 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aRet(m_aLabeledSequences
.size());
2528 while (aItr
!= aEndItr
)
2537 /* typedef ::std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > tVec;
2539 bool bSeries = false;
2540 // split into columns - FIXME: different if GlueState() is used
2541 for ( ScRangePtr p = m_xRanges->First(); p; p = m_xRanges->Next())
2543 for ( SCCOL nCol = p->aStart.Col(); nCol <= p->aEnd.Col(); ++nCol)
2545 uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
2546 new ScChart2LabeledDataSequence( m_pDocument));
2547 if( xLabeledSeq.is())
2549 aVec.push_back( xLabeledSeq );
2552 ScRangeListRef aColRanges = new ScRangeList;
2553 // one single sheet selected assumed for now
2554 aColRanges->Append( ScRange( nCol, p->aStart.Row(),
2555 p->aStart.Tab(), nCol, p->aStart.Row(),
2557 // TEST: add range two times, once as label, once as data
2558 // TODO: create pure Numerical and Text sequences if possible
2559 uno::Reference< chart2::data::XDataSequence > xLabel(
2560 new ScChart2DataSequence( m_pDocument, aColRanges));
2563 uno::Reference< beans::XPropertySet > xProp( xLabel, uno::UNO_QUERY );
2565 xProp->setPropertyValue(
2566 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )),
2567 ::uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "label" ))));
2569 xLabeledSeq->setLabel( xLabel );
2572 ScRangeListRef aColRanges = new ScRangeList;
2574 // one single sheet selected assumed for now
2575 aColRanges->Append( ScRange( nCol, p->aStart.Row() + 1,
2576 p->aStart.Tab(), nCol, p->aEnd.Row(),
2578 uno::Reference< chart2::data::XDataSequence > xData(
2579 new ScChart2DataSequence( m_pDocument, aColRanges));
2582 uno::Reference< beans::XPropertySet > xProp( xData, uno::UNO_QUERY );
2584 xProp->setPropertyValue(
2585 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )),
2586 ::uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "values" ))));
2588 xLabeledSeq->setValues( xData );
2594 uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> > aSequences(
2596 uno::Reference< chart2::data::XLabeledDataSequence> * pArr = aSequences.getArray();
2598 for ( tVec::const_iterator iSeq = aVec.begin(); iSeq != aVec.end();
2603 return aSequences;*/
2606 void ScChart2DataSource::AddLabeledSequence(const uno::Reference
< chart2::data::XLabeledDataSequence
>& xNew
)
2608 m_aLabeledSequences
.push_back(xNew
);
2611 // LabeledDataSequence =======================================================
2613 ScChart2LabeledDataSequence::ScChart2LabeledDataSequence(
2614 ScDocument
* pDoc
) :
2618 m_pDocument
->AddUnoObject( *this);
2621 ScChart2LabeledDataSequence::~ScChart2LabeledDataSequence()
2624 m_pDocument
->RemoveUnoObject( *this);
2627 // SfxListener -----------------------------------------------------------
2629 void ScChart2LabeledDataSequence::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
2631 if ( rHint
.ISA( SfxSimpleHint
) &&
2632 ((const SfxSimpleHint
&)rHint
).GetId() == SFX_HINT_DYING
)
2639 // XLabeledDataSequence --------------------------------------------------
2641 uno::Reference
< chart2::data::XDataSequence
> SAL_CALL
ScChart2LabeledDataSequence::getValues()
2642 throw (uno::RuntimeException
)
2648 void SAL_CALL
ScChart2LabeledDataSequence::setValues(
2649 const uno::Reference
< chart2::data::XDataSequence
>& xSequence
)
2650 throw (uno::RuntimeException
)
2653 m_aData
= xSequence
;
2656 uno::Reference
< chart2::data::XDataSequence
> SAL_CALL
ScChart2LabeledDataSequence::getLabel()
2657 throw (uno::RuntimeException
)
2663 void SAL_CALL
ScChart2LabeledDataSequence::setLabel(
2664 const uno::Reference
< chart2::data::XDataSequence
>& xSequence
)
2665 throw (uno::RuntimeException
)
2668 m_aLabel
= xSequence
;
2671 // XCloneable ================================================================
2673 uno::Reference
< util::XCloneable
> SAL_CALL
ScChart2LabeledDataSequence::createClone()
2674 throw (uno::RuntimeException
)
2677 uno::Reference
< util::XCloneable
> xToClone(m_aData
, uno::UNO_QUERY
);
2680 ScChart2LabeledDataSequence
* pRet
= new ScChart2LabeledDataSequence(m_pDocument
);
2681 uno::Reference
< chart2::data::XDataSequence
> xSequence(xToClone
->createClone(), uno::UNO_QUERY
);
2682 pRet
->setValues(xSequence
);
2683 xToClone
.set(m_aLabel
, uno::UNO_QUERY
);
2686 xSequence
.set(xToClone
->createClone(), uno::UNO_QUERY
);
2687 pRet
->setLabel(xSequence
);
2694 // XModifyBroadcaster ========================================================
2696 void SAL_CALL
ScChart2LabeledDataSequence::addModifyListener( const uno::Reference
< util::XModifyListener
>& aListener
)
2697 throw (uno::RuntimeException
)
2699 // quick'n dirty: just add the listener to each DataSequence
2701 uno::Reference
<util::XModifyBroadcaster
> xDataBroadcaster( m_aData
, uno::UNO_QUERY
);
2702 if ( xDataBroadcaster
.is() )
2703 xDataBroadcaster
->addModifyListener( aListener
);
2704 uno::Reference
<util::XModifyBroadcaster
> xLabelBroadcaster( m_aLabel
, uno::UNO_QUERY
);
2705 if ( xLabelBroadcaster
.is() )
2706 xLabelBroadcaster
->addModifyListener( aListener
);
2709 void SAL_CALL
ScChart2LabeledDataSequence::removeModifyListener( const uno::Reference
< util::XModifyListener
>& aListener
)
2710 throw (uno::RuntimeException
)
2712 uno::Reference
<util::XModifyBroadcaster
> xDataBroadcaster( m_aData
, uno::UNO_QUERY
);
2713 if ( xDataBroadcaster
.is() )
2714 xDataBroadcaster
->removeModifyListener( aListener
);
2715 uno::Reference
<util::XModifyBroadcaster
> xLabelBroadcaster( m_aLabel
, uno::UNO_QUERY
);
2716 if ( xLabelBroadcaster
.is() )
2717 xLabelBroadcaster
->removeModifyListener( aListener
);
2720 // DataSequence ==============================================================
2722 ScChart2DataSequence::Item::Item() :
2723 mfValue(0.0), mbIsValue(false)
2725 ::rtl::math::setNan(&mfValue
);
2728 ScChart2DataSequence::HiddenRangeListener::HiddenRangeListener(ScChart2DataSequence
& rParent
) :
2733 ScChart2DataSequence::HiddenRangeListener::~HiddenRangeListener()
2737 void ScChart2DataSequence::HiddenRangeListener::notify()
2739 mrParent
.setDataChangedHint(true);
2742 ScChart2DataSequence::ScChart2DataSequence( ScDocument
* pDoc
,
2743 const uno::Reference
< chart2::data::XDataProvider
>& xDP
,
2744 vector
<ScSharedTokenRef
>* pTokens
,
2745 bool bIncludeHiddenCells
)
2746 : m_bIncludeHiddenCells( bIncludeHiddenCells
)
2748 , m_pDocument( pDoc
)
2749 , m_pTokens(pTokens
)
2750 , m_pRangeIndices(NULL
)
2751 , m_pExtRefListener(NULL
)
2752 , m_xDataProvider( xDP
)
2753 , m_aPropSet(lcl_GetDataSequencePropertyMap())
2754 , m_pHiddenListener(NULL
)
2755 , m_pValueListener( NULL
)
2756 , m_bGotDataChangedHint(false)
2757 , m_bExtDataRebuildQueued(false)
2759 DBG_ASSERT(pTokens
, "reference token list is null");
2763 m_pDocument
->AddUnoObject( *this);
2764 m_nObjectId
= m_pDocument
->GetNewUnoId();
2766 // FIXME: real implementation of identifier and it's mapping to ranges.
2767 // Reuse ScChartListener?
2769 // BM: don't use names of named ranges but the UI range strings
2771 // rRangeList->Format( aStr, SCR_ABS_3D, m_pDocument );
2772 // m_aIdentifier = ::rtl::OUString( aStr );
2774 // m_aIdentifier = ::rtl::OUString::createFromAscii( "ID_");
2775 // static sal_Int32 nID = 0;
2776 // m_aIdentifier += ::rtl::OUString::valueOf( ++nID);
2779 ScChart2DataSequence::~ScChart2DataSequence()
2783 m_pDocument
->RemoveUnoObject( *this);
2784 if (m_pHiddenListener
.get())
2786 ScChartListenerCollection
* pCLC
= m_pDocument
->GetChartListenerCollection();
2788 pCLC
->EndListeningHiddenRange(m_pHiddenListener
.get());
2790 StopListeningToAllExternalRefs();
2793 delete m_pValueListener
;
2796 void ScChart2DataSequence::RefChanged()
2798 if( m_pValueListener
&& m_aValueListeners
.Count() != 0 )
2800 m_pValueListener
->EndListeningAll();
2804 ScChartListenerCollection
* pCLC
= NULL
;
2805 if (m_pHiddenListener
.get())
2807 pCLC
= m_pDocument
->GetChartListenerCollection();
2809 pCLC
->EndListeningHiddenRange(m_pHiddenListener
.get());
2812 vector
<ScSharedTokenRef
>::const_iterator itr
= m_pTokens
->begin(), itrEnd
= m_pTokens
->end();
2813 for (; itr
!= itrEnd
; ++itr
)
2816 if (!ScRefTokenHelper::getRangeFromToken(aRange
, *itr
))
2819 m_pDocument
->StartListeningArea(aRange
, m_pValueListener
);
2821 pCLC
->StartListeningHiddenRange(aRange
, m_pHiddenListener
.get());
2827 void ScChart2DataSequence::BuildDataCache()
2829 m_bExtDataRebuildQueued
= false;
2831 if (!m_aDataArray
.empty())
2834 if (!m_pTokens
.get())
2836 DBG_ERROR("m_pTokens == NULL! Something is wrong.");
2840 StopListeningToAllExternalRefs();
2842 ::std::list
<sal_Int32
> aHiddenValues
;
2843 sal_Int32 nDataCount
= 0;
2844 sal_Int32 nHiddenValueCount
= 0;
2846 for (vector
<ScSharedTokenRef
>::const_iterator itr
= m_pTokens
->begin(), itrEnd
= m_pTokens
->end();
2847 itr
!= itrEnd
; ++itr
)
2849 if (ScRefTokenHelper::isExternalRef(*itr
))
2851 nDataCount
+= FillCacheFromExternalRef(*itr
);
2856 if (!ScRefTokenHelper::getRangeFromToken(aRange
, *itr
))
2859 SCCOL nLastCol
= -1;
2860 SCROW nLastRow
= -1;
2861 for (SCTAB nTab
= aRange
.aStart
.Tab(); nTab
<= aRange
.aEnd
.Tab(); ++nTab
)
2863 for (SCCOL nCol
= aRange
.aStart
.Col(); nCol
<= aRange
.aEnd
.Col(); ++nCol
)
2865 for (SCROW nRow
= aRange
.aStart
.Row(); nRow
<= aRange
.aEnd
.Row(); ++nRow
)
2867 bool bColHidden
= m_pDocument
->ColHidden(nCol
, nTab
, nLastCol
);
2868 bool bRowHidden
= m_pDocument
->RowHidden(nRow
, nTab
, nLastRow
);
2870 if (bColHidden
|| bRowHidden
)
2873 ++nHiddenValueCount
;
2874 aHiddenValues
.push_back(nDataCount
-1);
2876 if( !m_bIncludeHiddenCells
)
2880 m_aDataArray
.push_back(Item());
2881 Item
& rItem
= m_aDataArray
.back();
2884 ScAddress
aAdr(nCol
, nRow
, nTab
);
2885 ScBaseCell
* pCell
= m_pDocument
->GetCell(aAdr
);
2889 if (pCell
->HasStringData())
2890 rItem
.maString
= pCell
->GetStringData();
2894 m_pDocument
->GetString(nCol
, nRow
, nTab
, aStr
);
2895 rItem
.maString
= aStr
;
2898 switch (pCell
->GetCellType())
2900 case CELLTYPE_VALUE
:
2901 rItem
.mfValue
= static_cast< ScValueCell
*>(pCell
)->GetValue();
2902 rItem
.mbIsValue
= true;
2904 case CELLTYPE_FORMULA
:
2906 ScFormulaCell
* pFCell
= static_cast<ScFormulaCell
*>(pCell
);
2907 USHORT nErr
= pFCell
->GetErrCode();
2911 if (pFCell
->HasValueData())
2913 rItem
.mfValue
= pFCell
->GetValue();
2914 rItem
.mbIsValue
= true;
2919 case CELLTYPE_DESTROYED
:
2924 case CELLTYPE_STRING
:
2925 case CELLTYPE_SYMBOLS
:
2935 // convert the hidden cell list to sequence.
2936 m_aHiddenValues
.realloc(nHiddenValueCount
);
2937 sal_Int32
* pArr
= m_aHiddenValues
.getArray();
2938 ::std::list
<sal_Int32
>::const_iterator itr
= aHiddenValues
.begin(), itrEnd
= aHiddenValues
.end();
2939 for (;itr
!= itrEnd
; ++itr
, ++pArr
)
2942 // Clear the data series cache when the array is re-built.
2943 m_aMixedDataCache
.realloc(0);
2946 void ScChart2DataSequence::RebuildDataCache()
2948 if (!m_bExtDataRebuildQueued
)
2950 m_aDataArray
.clear();
2951 m_pDocument
->BroadcastUno(ScHint(SC_HINT_DATACHANGED
, ScAddress(), NULL
));
2952 m_bExtDataRebuildQueued
= true;
2953 m_bGotDataChangedHint
= true;
2957 sal_Int32
ScChart2DataSequence::FillCacheFromExternalRef(const ScSharedTokenRef
& pToken
)
2959 ScExternalRefManager
* pRefMgr
= m_pDocument
->GetExternalRefManager();
2961 if (!ScRefTokenHelper::getRangeFromToken(aRange
, pToken
, true))
2964 sal_uInt16 nFileId
= pToken
->GetIndex();
2965 const String
& rTabName
= pToken
->GetString();
2966 ScExternalRefCache::TokenArrayRef pArray
= pRefMgr
->getDoubleRefTokens(nFileId
, rTabName
, aRange
, NULL
);
2968 // no external data exists for this range.
2971 // Start listening for this external document.
2972 ExternalRefListener
* pExtRefListener
= GetExtRefListener();
2973 pRefMgr
->addLinkListener(nFileId
, pExtRefListener
);
2974 pExtRefListener
->addFileId(nFileId
);
2976 ScExternalRefCache::TableTypeRef pTable
= pRefMgr
->getCacheTable(nFileId
, rTabName
, false, NULL
);
2977 sal_Int32 nDataCount
= 0;
2978 for (FormulaToken
* p
= pArray
->First(); p
; p
= pArray
->Next())
2980 // Cached external range is always represented as a single
2981 // matrix token, although that might change in the future when
2982 // we introduce a new token type to store multi-table range
2985 if (p
->GetType() != svMatrix
)
2987 DBG_ERROR("Cached array is not a matrix token.");
2991 const ScMatrix
* pMat
= static_cast<ScToken
*>(p
)->GetMatrix();
2992 SCSIZE nCSize
, nRSize
;
2993 pMat
->GetDimensions(nCSize
, nRSize
);
2994 for (SCSIZE nC
= 0; nC
< nCSize
; ++nC
)
2996 for (SCSIZE nR
= 0; nR
< nRSize
; ++nR
)
2998 if (pMat
->IsValue(nC
, nR
) || pMat
->IsBoolean(nC
, nR
))
3000 m_aDataArray
.push_back(Item());
3001 Item
& rItem
= m_aDataArray
.back();
3004 rItem
.mbIsValue
= true;
3005 rItem
.mfValue
= pMat
->GetDouble(nC
, nR
);
3007 SvNumberFormatter
* pFormatter
= m_pDocument
->GetFormatTable();
3011 const double fVal
= rItem
.mfValue
;
3012 Color
* pColor
= NULL
;
3013 sal_uInt32 nFmt
= 0;
3016 // Get the correct format index from the cache.
3017 SCCOL nCol
= aRange
.aStart
.Col() + static_cast<SCCOL
>(nC
);
3018 SCROW nRow
= aRange
.aStart
.Row() + static_cast<SCROW
>(nR
);
3019 pTable
->getCell(nCol
, nRow
, &nFmt
);
3021 pFormatter
->GetOutputString(fVal
, nFmt
, aStr
, &pColor
);
3022 rItem
.maString
= aStr
;
3025 else if (pMat
->IsString(nC
, nR
))
3027 m_aDataArray
.push_back(Item());
3028 Item
& rItem
= m_aDataArray
.back();
3031 rItem
.mbIsValue
= false;
3032 rItem
.maString
= pMat
->GetString(nC
, nR
);
3040 void ScChart2DataSequence::UpdateTokensFromRanges(const ScRangeList
& rRanges
)
3042 if (!m_pRangeIndices
.get())
3045 sal_uInt32 nCount
= rRanges
.Count();
3046 for (sal_uInt32 i
= 0; i
< nCount
; ++i
)
3048 ScSharedTokenRef pToken
;
3049 ScRange
* pRange
= static_cast<ScRange
*>(rRanges
.GetObject(i
));
3050 DBG_ASSERT(pRange
, "range object is NULL.");
3052 ScRefTokenHelper::getTokenFromRange(pToken
, *pRange
);
3053 sal_uInt32 nOrigPos
= (*m_pRangeIndices
)[i
];
3054 (*m_pTokens
)[nOrigPos
] = pToken
;
3059 // any change of the range address is broadcast to value (modify) listeners
3060 if ( m_aValueListeners
.Count() )
3061 m_bGotDataChangedHint
= true;
3064 ScChart2DataSequence::ExternalRefListener
* ScChart2DataSequence::GetExtRefListener()
3066 if (!m_pExtRefListener
.get())
3067 m_pExtRefListener
.reset(new ExternalRefListener(*this, m_pDocument
));
3069 return m_pExtRefListener
.get();
3072 void ScChart2DataSequence::StopListeningToAllExternalRefs()
3074 if (!m_pExtRefListener
.get())
3077 const hash_set
<sal_uInt16
>& rFileIds
= m_pExtRefListener
->getAllFileIds();
3078 hash_set
<sal_uInt16
>::const_iterator itr
= rFileIds
.begin(), itrEnd
= rFileIds
.end();
3079 ScExternalRefManager
* pRefMgr
= m_pDocument
->GetExternalRefManager();
3080 for (; itr
!= itrEnd
; ++itr
)
3081 pRefMgr
->removeLinkListener(*itr
, m_pExtRefListener
.get());
3083 m_pExtRefListener
.reset(NULL
);
3086 void ScChart2DataSequence::CopyData(const ScChart2DataSequence
& r
)
3090 DBG_ERROR("document instance is NULL!?");
3094 list
<Item
> aDataArray(r
.m_aDataArray
);
3095 m_aDataArray
.swap(aDataArray
);
3097 m_aHiddenValues
= r
.m_aHiddenValues
;
3098 m_aRole
= r
.m_aRole
;
3100 if (r
.m_pRangeIndices
.get())
3101 m_pRangeIndices
.reset(new vector
<sal_uInt32
>(*r
.m_pRangeIndices
));
3103 if (r
.m_pExtRefListener
.get())
3105 // Re-register all external files that the old instance was
3108 ScExternalRefManager
* pRefMgr
= m_pDocument
->GetExternalRefManager();
3109 m_pExtRefListener
.reset(new ExternalRefListener(*this, m_pDocument
));
3110 const hash_set
<sal_uInt16
>& rFileIds
= r
.m_pExtRefListener
->getAllFileIds();
3111 hash_set
<sal_uInt16
>::const_iterator itr
= rFileIds
.begin(), itrEnd
= rFileIds
.end();
3112 for (; itr
!= itrEnd
; ++itr
)
3114 pRefMgr
->addLinkListener(*itr
, m_pExtRefListener
.get());
3115 m_pExtRefListener
->addFileId(*itr
);
3120 void ScChart2DataSequence::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
3122 if ( rHint
.ISA( SfxSimpleHint
) )
3124 ULONG nId
= static_cast<const SfxSimpleHint
&>(rHint
).GetId();
3125 if ( nId
==SFX_HINT_DYING
)
3129 else if ( nId
== SFX_HINT_DATACHANGED
)
3131 // delayed broadcast as in ScCellRangesBase
3133 if ( m_bGotDataChangedHint
&& m_pDocument
)
3135 m_aDataArray
.clear();
3136 lang::EventObject aEvent
;
3137 aEvent
.Source
.set((cppu::OWeakObject
*)this);
3141 for ( USHORT n
=0; n
<m_aValueListeners
.Count(); n
++ )
3142 m_pDocument
->AddUnoListenerCall( *m_aValueListeners
[n
], aEvent
);
3145 m_bGotDataChangedHint
= false;
3148 else if ( nId
== SC_HINT_CALCALL
)
3150 // broadcast from DoHardRecalc - set m_bGotDataChangedHint
3151 // (SFX_HINT_DATACHANGED follows separately)
3153 if ( m_aValueListeners
.Count() )
3154 m_bGotDataChangedHint
= true;
3157 else if ( rHint
.ISA( ScUpdateRefHint
) )
3159 // Create a range list from the token list, have the range list
3160 // updated, and bring the change back to the token list.
3162 ScRangeList aRanges
;
3163 m_pRangeIndices
.reset(new vector
<sal_uInt32
>());
3164 vector
<ScSharedTokenRef
>::const_iterator itrBeg
= m_pTokens
->begin(), itrEnd
= m_pTokens
->end();
3165 for (vector
<ScSharedTokenRef
>::const_iterator itr
= itrBeg
;itr
!= itrEnd
; ++itr
)
3167 if (!ScRefTokenHelper::isExternalRef(*itr
))
3170 ScRefTokenHelper::getRangeFromToken(aRange
, *itr
);
3171 aRanges
.Append(aRange
);
3172 sal_uInt32 nPos
= distance(itrBeg
, itr
);
3173 m_pRangeIndices
->push_back(nPos
);
3177 DBG_ASSERT(m_pRangeIndices
->size() == static_cast<size_t>(aRanges
.Count()),
3178 "range list and range index list have different sizes.");
3180 auto_ptr
<ScRangeList
> pUndoRanges
;
3181 if ( m_pDocument
->HasUnoRefUndo() )
3182 pUndoRanges
.reset(new ScRangeList(aRanges
));
3184 const ScUpdateRefHint
& rRef
= (const ScUpdateRefHint
&)rHint
;
3185 bool bChanged
= aRanges
.UpdateReference(
3186 rRef
.GetMode(), m_pDocument
, rRef
.GetRange(), rRef
.GetDx(), rRef
.GetDy(), rRef
.GetDz());
3190 DBG_ASSERT(m_pRangeIndices
->size() == static_cast<size_t>(aRanges
.Count()),
3191 "range list and range index list have different sizes after the reference update.");
3193 // Bring the change back from the range list to the token list.
3194 UpdateTokensFromRanges(aRanges
);
3196 if (pUndoRanges
.get())
3197 m_pDocument
->AddUnoRefChange(m_nObjectId
, *pUndoRanges
);
3200 else if ( rHint
.ISA( ScUnoRefUndoHint
) )
3202 const ScUnoRefUndoHint
& rUndoHint
= static_cast<const ScUnoRefUndoHint
&>(rHint
);
3206 if (rUndoHint
.GetObjectId() != m_nObjectId
)
3209 // The hint object provides the old ranges. Restore the old state
3210 // from these ranges.
3212 if (!m_pRangeIndices
.get() || m_pRangeIndices
->empty())
3214 DBG_ERROR(" faulty range indices");
3218 const ScRangeList
& rRanges
= rUndoHint
.GetRanges();
3220 sal_uInt32 nCount
= rRanges
.Count();
3221 if (nCount
!= m_pRangeIndices
->size())
3223 DBG_ERROR("range count and range index count differ.");
3227 UpdateTokensFromRanges(rRanges
);
3234 IMPL_LINK( ScChart2DataSequence
, ValueListenerHdl
, SfxHint
*, pHint
)
3236 if ( m_pDocument
&& pHint
&& pHint
->ISA( SfxSimpleHint
) &&
3237 ((const SfxSimpleHint
*)pHint
)->GetId() & (SC_HINT_DATACHANGED
| SC_HINT_DYING
) )
3239 // This may be called several times for a single change, if several formulas
3240 // in the range are notified. So only a flag is set that is checked when
3241 // SFX_HINT_DATACHANGED is received.
3243 setDataChangedHint(true);
3248 // ----------------------------------------------------------------------------
3250 ScChart2DataSequence::ExternalRefListener::ExternalRefListener(
3251 ScChart2DataSequence
& rParent
, ScDocument
* pDoc
) :
3252 ScExternalRefManager::LinkListener(),
3258 ScChart2DataSequence::ExternalRefListener::~ExternalRefListener()
3260 if (!mpDoc
|| mpDoc
->IsInDtorClear())
3261 // The document is being destroyed. Do nothing.
3264 // Make sure to remove all pointers to this object.
3265 mpDoc
->GetExternalRefManager()->removeLinkListener(this);
3268 void ScChart2DataSequence::ExternalRefListener::notify(sal_uInt16 nFileId
, ScExternalRefManager::LinkUpdateType eType
)
3272 case ScExternalRefManager::LINK_MODIFIED
:
3274 if (maFileIds
.count(nFileId
))
3275 // We are listening to this external document.
3276 mrParent
.RebuildDataCache();
3279 case ScExternalRefManager::LINK_BROKEN
:
3280 removeFileId(nFileId
);
3285 void ScChart2DataSequence::ExternalRefListener::addFileId(sal_uInt16 nFileId
)
3287 maFileIds
.insert(nFileId
);
3290 void ScChart2DataSequence::ExternalRefListener::removeFileId(sal_uInt16 nFileId
)
3292 maFileIds
.erase(nFileId
);
3295 const hash_set
<sal_uInt16
>& ScChart2DataSequence::ExternalRefListener::getAllFileIds()
3300 // ----------------------------------------------------------------------------
3302 uno::Sequence
< uno::Any
> SAL_CALL
ScChart2DataSequence::getData()
3303 throw ( uno::RuntimeException
)
3307 throw uno::RuntimeException();
3311 if (!m_aMixedDataCache
.getLength())
3313 // Build a cache for the 1st time...
3315 sal_Int32 nCount
= m_aDataArray
.size();
3316 m_aMixedDataCache
.realloc(nCount
);
3317 uno::Any
* pArr
= m_aMixedDataCache
.getArray();
3318 ::std::list
<Item
>::const_iterator itr
= m_aDataArray
.begin(), itrEnd
= m_aDataArray
.end();
3319 for (; itr
!= itrEnd
; ++itr
, ++pArr
)
3322 *pArr
<<= itr
->mfValue
;
3324 *pArr
<<= itr
->maString
;
3327 return m_aMixedDataCache
;
3330 // XNumericalDataSequence --------------------------------------------------
3332 uno::Sequence
< double > SAL_CALL
ScChart2DataSequence::getNumericalData()
3333 throw ( uno::RuntimeException
)
3337 throw uno::RuntimeException();
3342 ::rtl::math::setNan(&fNAN
);
3344 sal_Int32 nCount
= m_aDataArray
.size();
3345 uno::Sequence
<double> aSeq(nCount
);
3346 double* pArr
= aSeq
.getArray();
3347 ::std::list
<Item
>::const_iterator itr
= m_aDataArray
.begin(), itrEnd
= m_aDataArray
.end();
3348 for (; itr
!= itrEnd
; ++itr
, ++pArr
)
3349 *pArr
= itr
->mbIsValue
? itr
->mfValue
: fNAN
;
3354 // XTextualDataSequence --------------------------------------------------
3356 uno::Sequence
< rtl::OUString
> SAL_CALL
ScChart2DataSequence::getTextualData( ) throw (uno::RuntimeException
)
3360 throw uno::RuntimeException();
3364 sal_Int32 nCount
= m_aDataArray
.size();
3365 uno::Sequence
<rtl::OUString
> aSeq(nCount
);
3366 rtl::OUString
* pArr
= aSeq
.getArray();
3367 ::std::list
<Item
>::const_iterator itr
= m_aDataArray
.begin(), itrEnd
= m_aDataArray
.end();
3368 for (; itr
!= itrEnd
; ++itr
, ++pArr
)
3369 *pArr
= itr
->maString
;
3374 ::rtl::OUString SAL_CALL
ScChart2DataSequence::getSourceRangeRepresentation()
3375 throw ( uno::RuntimeException
)
3379 DBG_ASSERT( m_pDocument
, "No Document -> no SourceRangeRepresentation" );
3380 if (m_pDocument
&& m_pTokens
.get())
3381 lcl_convertTokensToString(aStr
, *m_pTokens
, m_pDocument
);
3389 * This function object is used to accumulatively count the numbers of
3390 * columns and rows in all reference tokens.
3392 class AccumulateRangeSize
: public unary_function
<ScSharedTokenRef
, void>
3395 AccumulateRangeSize() :
3396 mnCols(0), mnRows(0) {}
3398 AccumulateRangeSize(const AccumulateRangeSize
& r
) :
3399 mnCols(r
.mnCols
), mnRows(r
.mnRows
) {}
3401 void operator() (const ScSharedTokenRef
& pToken
)
3404 bool bExternal
= ScRefTokenHelper::isExternalRef(pToken
);
3405 ScRefTokenHelper::getRangeFromToken(r
, pToken
, bExternal
);
3407 mnCols
+= r
.aEnd
.Col() - r
.aStart
.Col() + 1;
3408 mnRows
+= r
.aEnd
.Row() - r
.aStart
.Row() + 1;
3411 SCCOL
getCols() const { return mnCols
; }
3412 SCROW
getRows() const { return mnRows
; }
3419 * This function object is used to generate label strings from a list of
3422 class GenerateLabelStrings
: public unary_function
<ScSharedTokenRef
, void>
3425 GenerateLabelStrings(sal_Int32 nSize
, chart2::data::LabelOrigin eOrigin
, bool bColumn
) :
3426 mpLabels(new Sequence
<OUString
>(nSize
)),
3429 mbColumn(bColumn
) {}
3431 GenerateLabelStrings(const GenerateLabelStrings
& r
) :
3432 mpLabels(r
.mpLabels
),
3433 meOrigin(r
.meOrigin
),
3435 mbColumn(r
.mbColumn
) {}
3437 void operator() (const ScSharedTokenRef
& pToken
)
3439 bool bExternal
= ScRefTokenHelper::isExternalRef(pToken
);
3441 ScRefTokenHelper::getRangeFromToken(aRange
, pToken
, bExternal
);
3442 OUString
* pArr
= mpLabels
->getArray();
3445 for (SCCOL nCol
= aRange
.aStart
.Col(); nCol
<= aRange
.aEnd
.Col(); ++nCol
)
3447 if ( meOrigin
!= chart2::data::LabelOrigin_LONG_SIDE
)
3449 String aString
= ScGlobal::GetRscString(STR_COLUMN
);
3451 ScAddress
aPos( nCol
, 0, 0 );
3453 aPos
.Format( aColStr
, SCA_VALID_COL
, NULL
);
3455 pArr
[mnCount
] = aString
;
3457 else //only indices for categories
3458 pArr
[mnCount
] = String::CreateFromInt32( mnCount
+1 );
3464 for (sal_Int32 nRow
= aRange
.aStart
.Row(); nRow
<= aRange
.aEnd
.Row(); ++nRow
)
3466 if (meOrigin
!= chart2::data::LabelOrigin_LONG_SIDE
)
3468 String aString
= ScGlobal::GetRscString(STR_ROW
);
3470 aString
+= String::CreateFromInt32( nRow
+1 );
3471 pArr
[mnCount
] = aString
;
3473 else //only indices for categories
3474 pArr
[mnCount
] = String::CreateFromInt32( mnCount
+1 );
3480 Sequence
<OUString
> getLabels() const { return *mpLabels
; }
3483 GenerateLabelStrings(); // disabled
3485 shared_ptr
< Sequence
<OUString
> > mpLabels
;
3486 chart2::data::LabelOrigin meOrigin
;
3493 uno::Sequence
< ::rtl::OUString
> SAL_CALL
ScChart2DataSequence::generateLabel(chart2::data::LabelOrigin eOrigin
)
3494 throw (uno::RuntimeException
)
3498 throw uno::RuntimeException();
3500 if (!m_pTokens
.get())
3501 return Sequence
<OUString
>();
3503 // Determine the total size of all ranges.
3504 AccumulateRangeSize func
;
3505 func
= for_each(m_pTokens
->begin(), m_pTokens
->end(), func
);
3506 SCCOL nCols
= func
.getCols();
3507 SCROW nRows
= func
.getRows();
3509 // Detemine whether this is column-major or row-major.
3510 bool bColumn
= true;
3511 if ((eOrigin
== chart2::data::LabelOrigin_SHORT_SIDE
) ||
3512 (eOrigin
== chart2::data::LabelOrigin_LONG_SIDE
))
3516 if (eOrigin
== chart2::data::LabelOrigin_SHORT_SIDE
)
3521 else if (nCols
> nRows
)
3523 if (eOrigin
== chart2::data::LabelOrigin_SHORT_SIDE
)
3529 return Sequence
<OUString
>();
3532 // Generate label strings based on the info so far.
3533 sal_Int32 nCount
= bColumn
? nCols
: nRows
;
3534 GenerateLabelStrings
genLabels(nCount
, eOrigin
, bColumn
);
3535 genLabels
= for_each(m_pTokens
->begin(), m_pTokens
->end(), genLabels
);
3536 Sequence
<OUString
> aSeq
= genLabels
.getLabels();
3541 ::sal_Int32 SAL_CALL
ScChart2DataSequence::getNumberFormatKeyByIndex( ::sal_Int32 nIndex
)
3542 throw (lang::IndexOutOfBoundsException
,
3543 uno::RuntimeException
)
3545 // index -1 means a heuristic value for the entire sequence
3546 bool bGetSeriesFormat
= (nIndex
== -1);
3547 sal_Int32 nResult
= 0;
3550 if ( !m_pDocument
|| !m_pTokens
.get())
3553 sal_Int32 nCount
= 0;
3554 bool bFound
= false;
3557 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( lcl_GetSpreadSheetDocument( m_pDocument
));
3558 if (!xSpreadDoc
.is())
3561 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
3565 ScRangeList aRanges
;
3566 ScRefTokenHelper::getRangeListFromTokens(aRanges
, *m_pTokens
);
3567 uno::Reference
< table::XCellRange
> xSheet
;
3568 for ( p
= aRanges
.First(); p
&& !bFound
; p
= aRanges
.Next())
3570 // TODO: use DocIter?
3571 table::CellAddress aStart
, aEnd
;
3572 ScUnoConversion::FillApiAddress( aStart
, p
->aStart
);
3573 ScUnoConversion::FillApiAddress( aEnd
, p
->aEnd
);
3574 for ( sal_Int16 nSheet
= aStart
.Sheet
; nSheet
<= aEnd
.Sheet
&& !bFound
; ++nSheet
)
3576 xSheet
.set(xIndex
->getByIndex(nSheet
), uno::UNO_QUERY
);
3577 for ( sal_Int32 nCol
= aStart
.Column
; nCol
<= aEnd
.Column
&& !bFound
; ++nCol
)
3579 for ( sal_Int32 nRow
= aStart
.Row
; nRow
<= aEnd
.Row
&& !bFound
; ++nRow
)
3581 if( bGetSeriesFormat
)
3583 // TODO: use nicer heuristic
3584 // return format of first non-empty cell
3585 uno::Reference
< text::XText
> xText(
3586 xSheet
->getCellByPosition(nCol
, nRow
), uno::UNO_QUERY
);
3587 if (xText
.is() && xText
->getString().getLength())
3589 uno::Reference
< beans::XPropertySet
> xProp(xText
, uno::UNO_QUERY
);
3591 xProp
->getPropertyValue(
3592 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberFormat"))) >>= nResult
;
3597 else if( nCount
== nIndex
)
3599 uno::Reference
< beans::XPropertySet
> xProp(
3600 xSheet
->getCellByPosition(nCol
, nRow
), uno::UNO_QUERY
);
3602 xProp
->getPropertyValue(
3603 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberFormat"))) >>= nResult
;
3616 // XCloneable ================================================================
3618 uno::Reference
< util::XCloneable
> SAL_CALL
ScChart2DataSequence::createClone()
3619 throw (uno::RuntimeException
)
3623 auto_ptr
< vector
<ScSharedTokenRef
> > pTokensNew
;
3624 if (m_pTokens
.get())
3627 pTokensNew
.reset(new vector
<ScSharedTokenRef
>);
3628 pTokensNew
->reserve(m_pTokens
->size());
3629 vector
<ScSharedTokenRef
>::const_iterator itr
= m_pTokens
->begin(), itrEnd
= m_pTokens
->end();
3630 for (; itr
!= itrEnd
; ++itr
)
3632 ScSharedTokenRef
p(static_cast<ScToken
*>((*itr
)->Clone()));
3633 pTokensNew
->push_back(p
);
3637 auto_ptr
<ScChart2DataSequence
> p(new ScChart2DataSequence(m_pDocument
, m_xDataProvider
, pTokensNew
.release(), m_bIncludeHiddenCells
));
3639 Reference
< util::XCloneable
> xClone(p
.release());
3644 // XModifyBroadcaster ========================================================
3646 void SAL_CALL
ScChart2DataSequence::addModifyListener( const uno::Reference
< util::XModifyListener
>& aListener
)
3647 throw (uno::RuntimeException
)
3649 // like ScCellRangesBase::addModifyListener
3651 if (!m_pTokens
.get() || m_pTokens
->empty())
3654 ScRangeList aRanges
;
3655 ScRefTokenHelper::getRangeListFromTokens(aRanges
, *m_pTokens
);
3656 uno::Reference
<util::XModifyListener
> *pObj
=
3657 new uno::Reference
<util::XModifyListener
>( aListener
);
3658 m_aValueListeners
.Insert( pObj
, m_aValueListeners
.Count() );
3660 if ( m_aValueListeners
.Count() == 1 )
3662 if (!m_pValueListener
)
3663 m_pValueListener
= new ScLinkListener( LINK( this, ScChart2DataSequence
, ValueListenerHdl
) );
3665 if (!m_pHiddenListener
.get())
3666 m_pHiddenListener
.reset(new HiddenRangeListener(*this));
3670 ScChartListenerCollection
* pCLC
= m_pDocument
->GetChartListenerCollection();
3671 vector
<ScSharedTokenRef
>::const_iterator itr
= m_pTokens
->begin(), itrEnd
= m_pTokens
->end();
3672 for (; itr
!= itrEnd
; ++itr
)
3675 if (!ScRefTokenHelper::getRangeFromToken(aRange
, *itr
))
3678 m_pDocument
->StartListeningArea( aRange
, m_pValueListener
);
3680 pCLC
->StartListeningHiddenRange(aRange
, m_pHiddenListener
.get());
3684 acquire(); // don't lose this object (one ref for all listeners)
3688 void SAL_CALL
ScChart2DataSequence::removeModifyListener( const uno::Reference
< util::XModifyListener
>& aListener
)
3689 throw (uno::RuntimeException
)
3691 // like ScCellRangesBase::removeModifyListener
3694 if (!m_pTokens
.get() || m_pTokens
->empty())
3697 acquire(); // in case the listeners have the last ref - released below
3699 USHORT nCount
= m_aValueListeners
.Count();
3700 for ( USHORT n
=nCount
; n
--; )
3702 uno::Reference
<util::XModifyListener
> *pObj
= m_aValueListeners
[n
];
3703 if ( *pObj
== aListener
)
3705 m_aValueListeners
.DeleteAndDestroy( n
);
3707 if ( m_aValueListeners
.Count() == 0 )
3709 if (m_pValueListener
)
3710 m_pValueListener
->EndListeningAll();
3712 if (m_pHiddenListener
.get() && m_pDocument
)
3714 ScChartListenerCollection
* pCLC
= m_pDocument
->GetChartListenerCollection();
3716 pCLC
->EndListeningHiddenRange(m_pHiddenListener
.get());
3719 release(); // release the ref for the listeners
3726 release(); // might delete this object
3729 // DataSequence XPropertySet -------------------------------------------------
3731 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
3732 ScChart2DataSequence::getPropertySetInfo() throw( uno::RuntimeException
)
3735 static uno::Reference
<beans::XPropertySetInfo
> aRef
=
3736 new SfxItemPropertySetInfo( m_aPropSet
.getPropertyMap() );
3741 void SAL_CALL
ScChart2DataSequence::setPropertyValue(
3742 const ::rtl::OUString
& rPropertyName
, const uno::Any
& rValue
)
3743 throw( beans::UnknownPropertyException
,
3744 beans::PropertyVetoException
,
3745 lang::IllegalArgumentException
,
3746 lang::WrappedTargetException
, uno::RuntimeException
)
3748 if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_ROLE
)))
3750 if ( !(rValue
>>= m_aRole
))
3751 throw lang::IllegalArgumentException();
3753 else if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS
)))
3755 sal_Bool bOldValue
= m_bIncludeHiddenCells
;
3756 if ( !(rValue
>>= m_bIncludeHiddenCells
))
3757 throw lang::IllegalArgumentException();
3758 if( bOldValue
!= m_bIncludeHiddenCells
)
3759 m_aDataArray
.clear();//data array is dirty now
3762 throw beans::UnknownPropertyException();
3763 // TODO: support optional properties
3767 uno::Any SAL_CALL
ScChart2DataSequence::getPropertyValue(
3768 const ::rtl::OUString
& rPropertyName
)
3769 throw( beans::UnknownPropertyException
,
3770 lang::WrappedTargetException
, uno::RuntimeException
)
3773 if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_ROLE
)))
3775 else if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS
)))
3776 aRet
<<= m_bIncludeHiddenCells
;
3777 else if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SC_UNONAME_HIDDENVALUES
)))
3779 // This property is read-only thus cannot be set externally via
3780 // setPropertyValue(...).
3782 aRet
<<= m_aHiddenValues
;
3785 throw beans::UnknownPropertyException();
3786 // TODO: support optional properties
3791 void SAL_CALL
ScChart2DataSequence::addPropertyChangeListener(
3792 const ::rtl::OUString
& /*rPropertyName*/,
3793 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/)
3794 throw( beans::UnknownPropertyException
,
3795 lang::WrappedTargetException
, uno::RuntimeException
)
3797 // FIXME: real implementation
3798 // throw uno::RuntimeException();
3799 OSL_ENSURE( false, "Not yet implemented" );
3803 void SAL_CALL
ScChart2DataSequence::removePropertyChangeListener(
3804 const ::rtl::OUString
& /*rPropertyName*/,
3805 const uno::Reference
< beans::XPropertyChangeListener
>& /*rListener*/)
3806 throw( beans::UnknownPropertyException
,
3807 lang::WrappedTargetException
, uno::RuntimeException
)
3809 // FIXME: real implementation
3810 // throw uno::RuntimeException();
3811 OSL_ENSURE( false, "Not yet implemented" );
3815 void SAL_CALL
ScChart2DataSequence::addVetoableChangeListener(
3816 const ::rtl::OUString
& /*rPropertyName*/,
3817 const uno::Reference
< beans::XVetoableChangeListener
>& /*rListener*/)
3818 throw( beans::UnknownPropertyException
,
3819 lang::WrappedTargetException
, uno::RuntimeException
)
3821 // FIXME: real implementation
3822 // throw uno::RuntimeException();
3823 OSL_ENSURE( false, "Not yet implemented" );
3827 void SAL_CALL
ScChart2DataSequence::removeVetoableChangeListener(
3828 const ::rtl::OUString
& /*rPropertyName*/,
3829 const uno::Reference
< beans::XVetoableChangeListener
>& /*rListener*/)
3830 throw( beans::UnknownPropertyException
,
3831 lang::WrappedTargetException
, uno::RuntimeException
)
3833 // FIXME: real implementation
3834 // throw uno::RuntimeException();
3835 OSL_ENSURE( false, "Not yet implemented" );
3838 void ScChart2DataSequence::setDataChangedHint(bool b
)
3840 m_bGotDataChangedHint
= b
;
3845 // sal_Int64 SAL_CALL ScChart2DataSequence::getSomething(
3846 // const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
3848 // if ( rId.getLength() == 16 &&
3849 // 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
3850 // rId.getConstArray(), 16 ) )
3852 // return (sal_Int64)this;
3858 // const uno::Sequence<sal_Int8>& ScChart2DataSequence::getUnoTunnelId()
3860 // static uno::Sequence<sal_Int8> * pSeq = 0;
3863 // osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
3866 // static uno::Sequence< sal_Int8 > aSeq( 16 );
3867 // rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
3875 // ScChart2DataSequence* ScChart2DataSequence::getImplementation( const uno::Reference<uno::XInterface> xObj )
3877 // ScChart2DataSequence* pRet = NULL;
3878 // uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
3880 // pRet = (ScChart2DataSequence*) xUT->getSomething( getUnoTunnelId() );
3884 #if USE_CHART2_EMPTYDATASEQUENCE
3885 // DataSequence ==============================================================
3887 ScChart2EmptyDataSequence::ScChart2EmptyDataSequence( ScDocument
* pDoc
,
3888 const uno::Reference
< chart2::data::XDataProvider
>& xDP
,
3889 const ScRangeListRef
& rRangeList
,
3891 : m_bIncludeHiddenCells( sal_True
)
3892 , m_xRanges( rRangeList
)
3893 , m_pDocument( pDoc
)
3894 , m_xDataProvider( xDP
)
3895 , m_aPropSet(lcl_GetDataSequencePropertyMap())
3896 , m_bColumn(bColumn
)
3899 m_pDocument
->AddUnoObject( *this);
3900 // FIXME: real implementation of identifier and it's mapping to ranges.
3901 // Reuse ScChartListener?
3903 // BM: don't use names of named ranges but the UI range strings
3905 // rRangeList->Format( aStr, SCR_ABS_3D, m_pDocument );
3906 // m_aIdentifier = ::rtl::OUString( aStr );
3908 // m_aIdentifier = ::rtl::OUString::createFromAscii( "ID_");
3909 // static sal_Int32 nID = 0;
3910 // m_aIdentifier += ::rtl::OUString::valueOf( ++nID);
3914 ScChart2EmptyDataSequence::~ScChart2EmptyDataSequence()
3917 m_pDocument
->RemoveUnoObject( *this);
3921 void ScChart2EmptyDataSequence::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
3923 if ( rHint
.ISA( SfxSimpleHint
) &&
3924 ((const SfxSimpleHint
&)rHint
).GetId() == SFX_HINT_DYING
)
3931 uno::Sequence
< uno::Any
> SAL_CALL
ScChart2EmptyDataSequence::getData()
3932 throw ( uno::RuntimeException
)
3936 throw uno::RuntimeException();
3937 return uno::Sequence
< uno::Any
>();
3940 // XTextualDataSequence --------------------------------------------------
3942 uno::Sequence
< rtl::OUString
> SAL_CALL
ScChart2EmptyDataSequence::getTextualData( ) throw (uno::RuntimeException
)
3946 throw uno::RuntimeException();
3948 sal_Int32 nCount
= 0;
3951 DBG_ASSERT(m_xRanges
->Count() == 1, "not handled count of ranges");
3953 for ( p
= m_xRanges
->First(); p
; p
= m_xRanges
->Next())
3956 // TODO: handle overlaping ranges?
3957 nCount
+= m_bColumn
? p
->aEnd
.Col() - p
->aStart
.Col() + 1 : p
->aEnd
.Row() - p
->aStart
.Row() + 1;
3959 uno::Sequence
< rtl::OUString
> aSeq( nCount
);
3960 rtl::OUString
* pArr
= aSeq
.getArray();
3962 for ( p
= m_xRanges
->First(); p
; p
= m_xRanges
->Next())
3966 for (SCCOL nCol
= p
->aStart
.Col(); nCol
<= p
->aEnd
.Col(); ++nCol
)
3968 String aString
= ScGlobal::GetRscString(STR_COLUMN
);
3970 ScAddress
aPos( nCol
, 0, 0 );
3972 aPos
.Format( aColStr
, SCA_VALID_COL
, NULL
);
3974 pArr
[nCount
] = aString
;
3980 sal_Int32 n
= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
3981 for (sal_Int32 i
= 0; i
< n
; ++i
)
3982 pArr
[nCount
++] = String::CreateFromInt32( i
+1 );
3988 ::rtl::OUString SAL_CALL
ScChart2EmptyDataSequence::getSourceRangeRepresentation()
3989 throw ( uno::RuntimeException
)
3993 DBG_ASSERT( m_pDocument
, "No Document -> no SourceRangeRepresentation" );
3995 m_xRanges
->Format( aStr
, SCR_ABS_3D
, m_pDocument
, m_pDocument
->GetAddressConvention() );
3999 uno::Sequence
< ::rtl::OUString
> SAL_CALL
ScChart2EmptyDataSequence::generateLabel(chart2::data::LabelOrigin
/*nOrigin*/)
4000 throw (uno::RuntimeException
)
4003 uno::Sequence
< ::rtl::OUString
> aRet
;
4007 ::sal_Int32 SAL_CALL
ScChart2EmptyDataSequence::getNumberFormatKeyByIndex( ::sal_Int32
/*nIndex*/ )
4008 throw (lang::IndexOutOfBoundsException
,
4009 uno::RuntimeException
)
4011 sal_Int32 nResult
= 0;
4020 // XCloneable ================================================================
4022 uno::Reference
< util::XCloneable
> SAL_CALL
ScChart2EmptyDataSequence::createClone()
4023 throw (uno::RuntimeException
)
4026 if (m_xDataProvider
.is())
4029 uno::Reference
< util::XCloneable
> xClone(new ScChart2EmptyDataSequence(m_pDocument
, m_xDataProvider
, new ScRangeList(*m_xRanges
), m_bColumn
));
4030 uno::Reference
< beans::XPropertySet
> xProp( xClone
, uno::UNO_QUERY
);
4033 xProp
->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_ROLE
)),
4034 uno::makeAny( m_aRole
));
4035 xProp
->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS
)),
4036 uno::makeAny( m_bIncludeHiddenCells
));
4040 return uno::Reference
< util::XCloneable
>();
4043 // XModifyBroadcaster ========================================================
4045 void SAL_CALL
ScChart2EmptyDataSequence::addModifyListener( const uno::Reference
< util::XModifyListener
>& /*aListener*/ )
4046 throw (uno::RuntimeException
)
4051 void SAL_CALL
ScChart2EmptyDataSequence::removeModifyListener( const uno::Reference
< util::XModifyListener
>& /*aListener*/ )
4052 throw (uno::RuntimeException
)
4057 // DataSequence XPropertySet -------------------------------------------------
4059 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
4060 ScChart2EmptyDataSequence::getPropertySetInfo() throw( uno::RuntimeException
)
4063 static uno::Reference
<beans::XPropertySetInfo
> aRef
=
4064 new SfxItemPropertySetInfo( m_aPropSet
.getPropertyMap() );
4069 void SAL_CALL
ScChart2EmptyDataSequence::setPropertyValue(
4070 const ::rtl::OUString
& rPropertyName
, const uno::Any
& rValue
)
4071 throw( beans::UnknownPropertyException
,
4072 beans::PropertyVetoException
,
4073 lang::IllegalArgumentException
,
4074 lang::WrappedTargetException
, uno::RuntimeException
)
4076 if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_ROLE
)))
4078 if ( !(rValue
>>= m_aRole
))
4079 throw lang::IllegalArgumentException();
4081 else if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS
)))
4083 if ( !(rValue
>>= m_bIncludeHiddenCells
))
4084 throw lang::IllegalArgumentException();
4087 throw beans::UnknownPropertyException();
4088 // TODO: support optional properties
4092 uno::Any SAL_CALL
ScChart2EmptyDataSequence::getPropertyValue(
4093 const ::rtl::OUString
& rPropertyName
)
4094 throw( beans::UnknownPropertyException
,
4095 lang::WrappedTargetException
, uno::RuntimeException
)
4098 if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_ROLE
)))
4100 else if ( rPropertyName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SC_UNONAME_INCLUDEHIDDENCELLS
)))
4101 aRet
<<= m_bIncludeHiddenCells
;
4103 throw beans::UnknownPropertyException();
4104 // TODO: support optional properties
4109 void SAL_CALL
ScChart2EmptyDataSequence::addPropertyChangeListener(
4110 const ::rtl::OUString
& /*rPropertyName*/,
4111 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/)
4112 throw( beans::UnknownPropertyException
,
4113 lang::WrappedTargetException
, uno::RuntimeException
)
4115 // FIXME: real implementation
4116 // throw uno::RuntimeException();
4117 OSL_ENSURE( false, "Not yet implemented" );
4121 void SAL_CALL
ScChart2EmptyDataSequence::removePropertyChangeListener(
4122 const ::rtl::OUString
& /*rPropertyName*/,
4123 const uno::Reference
< beans::XPropertyChangeListener
>& /*rListener*/)
4124 throw( beans::UnknownPropertyException
,
4125 lang::WrappedTargetException
, uno::RuntimeException
)
4127 // FIXME: real implementation
4128 // throw uno::RuntimeException();
4129 OSL_ENSURE( false, "Not yet implemented" );
4133 void SAL_CALL
ScChart2EmptyDataSequence::addVetoableChangeListener(
4134 const ::rtl::OUString
& /*rPropertyName*/,
4135 const uno::Reference
< beans::XVetoableChangeListener
>& /*rListener*/)
4136 throw( beans::UnknownPropertyException
,
4137 lang::WrappedTargetException
, uno::RuntimeException
)
4139 // FIXME: real implementation
4140 // throw uno::RuntimeException();
4141 OSL_ENSURE( false, "Not yet implemented" );
4145 void SAL_CALL
ScChart2EmptyDataSequence::removeVetoableChangeListener(
4146 const ::rtl::OUString
& /*rPropertyName*/,
4147 const uno::Reference
< beans::XVetoableChangeListener
>& /*rListener*/ )
4148 throw( beans::UnknownPropertyException
,
4149 lang::WrappedTargetException
, uno::RuntimeException
)
4151 // FIXME: real implementation
4152 // throw uno::RuntimeException();
4153 OSL_ENSURE( false, "Not yet implemented" );
4158 // sal_Int64 SAL_CALL ScChart2EmptyDataSequence::getSomething(
4159 // const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
4161 // if ( rId.getLength() == 16 &&
4162 // 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
4163 // rId.getConstArray(), 16 ) )
4165 // return (sal_Int64)this;
4171 // const uno::Sequence<sal_Int8>& ScChart2EmptyDataSequence::getUnoTunnelId()
4173 // static uno::Sequence<sal_Int8> * pSeq = 0;
4176 // osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
4179 // static uno::Sequence< sal_Int8 > aSeq( 16 );
4180 // rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
4188 // ScChart2DataSequence* ScChart2EmptyDataSequence::getImplementation( const uno::Reference<uno::XInterface> xObj )
4190 // ScChart2DataSequence* pRet = NULL;
4191 // uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
4193 // pRet = (ScChart2EmptyDataSequence*) xUT->getSomething( getUnoTunnelId() );