29#include <document.hxx>
31#include <unonames.hxx>
37#include <compiler.hxx>
42#include <tokenarray.hxx>
55#include <com/sun/star/beans/UnknownPropertyException.hpp>
56#include <com/sun/star/chart/ChartDataRowSource.hpp>
57#include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
58#include <com/sun/star/frame/XModel.hpp>
66 "com.sun.star.chart2.data.DataProvider")
68 "
com.sun.star.chart2.data.DataSource")
70 "
com.sun.star.chart2.data.DataSequence")
72using namespace ::
com::sun::star;
74using ::
com::sun::star::
uno::Sequence;
75using ::
std::unique_ptr;
78using ::
std::shared_ptr;
89 return aDataProviderPropertyMap_Impl;
100 return aDataSequencePropertyMap_Impl;
103struct lcl_appendTableNumber
105 explicit lcl_appendTableNumber( OUStringBuffer & rBuffer ) :
108 void operator() (
SCTAB nTab )
111 m_rBuffer.append(
static_cast< sal_Int32
>( nTab ));
112 m_rBuffer.append(
' ' );
115 OUStringBuffer & m_rBuffer;
118OUString lcl_createTableNumberList( const ::std::vector< SCTAB > & rTableVector )
121 ::std::for_each( rTableVector.begin(), rTableVector.end(), lcl_appendTableNumber(
aBuffer ));
125 return aBuffer.makeStringAndClear();
128uno::Reference< frame::XModel > lcl_GetXModel(
const ScDocument * pDoc )
130 uno::Reference< frame::XModel >
xModel;
141 vector<std::unique_ptr<FormulaToken>> maTokens;
144 TokenTable(
const TokenTable&) =
delete;
145 const TokenTable& operator=(
const TokenTable&) =
delete;
155 mnColCount = nColCount;
156 mnRowCount = nRowCount;
157 maTokens.reserve(mnColCount*mnRowCount);
161 for (
auto & rToken : maTokens)
165 void push_back( std::unique_ptr<FormulaToken> pToken )
167 maTokens.push_back( std::move(pToken) );
168 OSL_ENSURE( maTokens.size()<=
o3tl::make_unsigned( mnColCount*mnRowCount ),
"too many tokens" );
171 sal_uInt32 getIndex(
SCCOL nCol,
SCROW nRow)
const
173 OSL_ENSURE( nCol<mnColCount,
"wrong column index" );
174 OSL_ENSURE( nRow<mnRowCount,
"wrong row index" );
175 sal_uInt32 nRet =
static_cast<sal_uInt32
>(nCol*mnRowCount + nRow);
176 OSL_ENSURE( maTokens.size()>=
o3tl::make_unsigned( mnColCount*mnRowCount ),
"too few tokens" );
180 vector<ScTokenRef> getColRanges(
const ScDocument* pDoc,
SCCOL nCol)
const;
181 vector<ScTokenRef> getRowRanges(
const ScDocument* pDoc,
SCROW nRow)
const;
182 vector<ScTokenRef> getAllRanges(
const ScDocument* pDoc)
const;
185vector<ScTokenRef> TokenTable::getColRanges(
const ScDocument* pDoc,
SCCOL nCol)
const
187 if (nCol >= mnColCount)
188 return vector<ScTokenRef>();
190 return vector<ScTokenRef>();
192 vector<ScTokenRef> aTokens;
193 sal_uInt32 nLast = getIndex(nCol, mnRowCount-1);
194 for (sal_uInt32
i = getIndex(nCol, 0);
i <= nLast; ++
i)
196 FormulaToken*
p = maTokens[
i].get();
206vector<ScTokenRef> TokenTable::getRowRanges(
const ScDocument* pDoc,
SCROW nRow)
const
208 if (nRow >= mnRowCount)
209 return vector<ScTokenRef>();
211 return vector<ScTokenRef>();
213 vector<ScTokenRef> aTokens;
214 sal_uInt32 nLast = getIndex(mnColCount-1, nRow);
215 for (sal_uInt32
i = getIndex(0, nRow);
i <= nLast;
i += mnRowCount)
217 FormulaToken*
p = maTokens[
i].get();
227vector<ScTokenRef> TokenTable::getAllRanges(
const ScDocument* pDoc)
const
229 vector<ScTokenRef> aTokens;
230 sal_uInt32 nStop = mnColCount*mnRowCount;
231 for (sal_uInt32
i = 0;
i < nStop;
i++)
233 FormulaToken*
p = maTokens[
i].get();
243typedef std::map<SCROW, std::unique_ptr<FormulaToken>> FormulaTokenMap;
244typedef std::map<sal_uInt32, FormulaTokenMap> FormulaTokenMapMap;
246class Chart2PositionMap
249 Chart2PositionMap(
SCCOL nColCount,
SCROW nRowCount,
250 bool bFillRowHeader,
bool bFillColumnHeader, FormulaTokenMapMap& rCols,
252 ~Chart2PositionMap();
254 SCCOL getDataColCount()
const {
return mnDataColCount; }
255 SCROW getDataRowCount()
const {
return mnDataRowCount; }
257 vector<ScTokenRef> getLeftUpperCornerRanges()
const;
258 vector<ScTokenRef> getAllColHeaderRanges()
const;
259 vector<ScTokenRef> getAllRowHeaderRanges()
const;
261 vector<ScTokenRef> getColHeaderRanges(
SCCOL nChartCol)
const;
262 vector<ScTokenRef> getRowHeaderRanges(
SCROW nChartRow)
const;
264 vector<ScTokenRef> getDataColRanges(
SCCOL nCol)
const;
265 vector<ScTokenRef> getDataRowRanges(
SCROW nRow)
const;
269 SCCOL mnDataColCount;
270 SCROW mnDataRowCount;
272 TokenTable maLeftUpperCorner;
273 TokenTable maColHeaders;
274 TokenTable maRowHeaders;
278Chart2PositionMap::Chart2PositionMap(
SCCOL nAllColCount,
SCROW nAllRowCount,
279 bool bFillRowHeader,
bool bFillColumnHeader, FormulaTokenMapMap& rCols,
ScDocument* pDoc)
287 SCROW nHeaderRowCount = (bFillColumnHeader && nAllColCount && nAllRowCount) ? 1 : 0;
288 SCCOL nHeaderColCount = (bFillRowHeader && nAllColCount && nAllRowCount) ? 1 : 0;
290 if( pDoc && (nHeaderColCount || nHeaderRowCount ) )
293 SCROW nMaxHeaderRow = nAllRowCount;
295 for (
auto it = rCols.begin(); it != rCols.end(); ++it, ++nCol)
298 if (nCol < nHeaderColCount)
301 const auto& rCol = *it;
303 bool bFoundValuesInCol =
false;
304 bool bFoundAnythingInCol =
false;
306 for (
auto it2 = rCol.second.begin(); it2 != rCol.second.end(); ++it2, ++nRow)
308 const auto& rCell = *it2;
311 if (nRow < nHeaderRowCount || !rCell.second)
315 bool bExternal =
false;
319 ScTokenRef pSharedToken(rCell.second->Clone());
321 SCCOL nCol1=0, nCol2=0;
322 SCROW nRow1=0, nRow2=0;
323 SCTAB nTab1=0, nTab2=0;
324 aRange.
GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
328 bFoundValuesInCol =
true;
329 nMaxHeaderRow = std::min(nMaxHeaderRow, nRow);
332 if ( pDoc->
HasData( nCol1, nRow1, nTab1 ) )
335 bFoundAnythingInCol =
true;
340 nMaxHeaderRow = std::min(nMaxHeaderRow, nRow);
344 if (nHeaderColCount && !bFoundValuesInCol && bFoundAnythingInCol && nCol == nHeaderColCount)
354 nHeaderRowCount = nMaxHeaderRow;
358 mnDataColCount = nAllColCount - nHeaderColCount;
359 mnDataRowCount = nAllRowCount - nHeaderRowCount;
361 maLeftUpperCorner.init(nHeaderColCount,nHeaderRowCount);
362 maColHeaders.init(mnDataColCount,nHeaderRowCount);
363 maRowHeaders.init(nHeaderColCount,mnDataRowCount);
364 maData.init(mnDataColCount,mnDataRowCount);
366 FormulaTokenMapMap::iterator it1 = rCols.begin();
367 for (
SCCOL nCol = 0; nCol < nAllColCount; ++nCol)
369 if (it1 != rCols.end())
371 FormulaTokenMap& rCol = it1->second;
372 FormulaTokenMap::iterator it2 = rCol.begin();
373 for (
SCROW nRow = 0; nRow < nAllRowCount; ++nRow)
375 std::unique_ptr<FormulaToken> pToken;
376 if (it2 != rCol.end())
378 pToken = std::move(it2->second);
382 if( nCol < nHeaderColCount )
384 if( nRow < nHeaderRowCount )
385 maLeftUpperCorner.push_back(std::move(pToken));
387 maRowHeaders.push_back(std::move(pToken));
389 else if( nRow < nHeaderRowCount )
390 maColHeaders.push_back(std::move(pToken));
392 maData.push_back(std::move(pToken));
399Chart2PositionMap::~Chart2PositionMap()
401 maLeftUpperCorner.clear();
402 maColHeaders.clear();
403 maRowHeaders.clear();
407vector<ScTokenRef> Chart2PositionMap::getLeftUpperCornerRanges()
const
409 return maLeftUpperCorner.getAllRanges(mpDoc);
411vector<ScTokenRef> Chart2PositionMap::getAllColHeaderRanges()
const
413 return maColHeaders.getAllRanges(mpDoc);
415vector<ScTokenRef> Chart2PositionMap::getAllRowHeaderRanges()
const
417 return maRowHeaders.getAllRanges(mpDoc);
419vector<ScTokenRef> Chart2PositionMap::getColHeaderRanges(
SCCOL nCol)
const
421 return maColHeaders.getColRanges(mpDoc, nCol);
423vector<ScTokenRef> Chart2PositionMap::getRowHeaderRanges(
SCROW nRow)
const
425 return maRowHeaders.getRowRanges(mpDoc, nRow);
428vector<ScTokenRef> Chart2PositionMap::getDataColRanges(
SCCOL nCol)
const
430 return maData.getColRanges(mpDoc, nCol);
433vector<ScTokenRef> Chart2PositionMap::getDataRowRanges(
SCROW nRow)
const
435 return maData.getRowRanges(mpDoc, nRow);
442class Chart2Positioner
454 Chart2Positioner(
const Chart2Positioner&) =
delete;
455 const Chart2Positioner& operator=(
const Chart2Positioner&) =
delete;
457 Chart2Positioner(
ScDocument* pDoc,
const vector<ScTokenRef>& rRefTokens) :
458 mrRefTokens(rRefTokens),
465 mbDummyUpperLeft(
false)
469 void setHeaders(
bool bColHeaders,
bool bRowHeaders)
471 mbColHeaders = bColHeaders;
472 mbRowHeaders = bRowHeaders;
475 Chart2PositionMap* getPositionMap()
478 return mpPositionMap.get();
482 void invalidateGlue();
485 void createPositionMap();
488 const vector<ScTokenRef>& mrRefTokens;
489 std::unique_ptr<Chart2PositionMap> mpPositionMap;
496 bool mbDummyUpperLeft:1;
499void Chart2Positioner::invalidateGlue()
501 meGlue = GLUETYPE_NA;
502 mpPositionMap.reset();
505void Chart2Positioner::glueState()
507 if (meGlue != GLUETYPE_NA)
510 mbDummyUpperLeft =
false;
511 if (mrRefTokens.size() <= 1)
519 meGlue = GLUETYPE_NONE;
521 meGlue = GLUETYPE_COLS;
522 mnStartCol =
aData.Ref1.Col();
523 mnStartRow =
aData.Ref1.Row();
537 SAL_WARN(
"sc",
"Chart2Positioner::glueState getDoubleRefDataFromToken failed");
543 mnStartCol =
aData.Ref1.Col();
544 mnStartRow =
aData.Ref1.Row();
548 for (
const auto& rxToken : mrRefTokens)
553 if (
n1 > mpDoc->MaxCol())
554 n1 = mpDoc->MaxCol();
555 if (
n2 > mpDoc->MaxCol())
556 n2 = mpDoc->MaxCol();
558 mnStartCol =
static_cast<SCCOL>(
n1);
560 nEndCol =
static_cast<SCCOL>(
n2);
564 if (
n1 > mpDoc->MaxRow())
565 n1 = mpDoc->MaxRow();
566 if (
n2 > mpDoc->MaxRow())
567 n2 = mpDoc->MaxRow();
570 mnStartRow =
static_cast<SCROW>(
n1);
572 nEndRow =
static_cast<SCROW>(
n2);
575 if (mnStartCol == nEndCol)
578 meGlue = GLUETYPE_ROWS;
582 if (mnStartRow == nEndRow)
585 meGlue = GLUETYPE_COLS;
590 SCCOL nC = nEndCol - mnStartCol + 1;
593 SCROW nR = nEndRow - mnStartRow + 1;
596 if ((nC <= 0) || (nR <= 0))
604 calcGlueState(nC, nR);
609void Chart2Positioner::calcGlueState(
SCCOL nColSize,
SCROW nRowSize)
615 sal_uInt32 nCR =
static_cast<sal_uInt32
>(nColSize*nRowSize);
617 vector<State> aCellStates(nCR,
Hole);
620 for (
const auto& rxToken : mrRefTokens)
628 for (
SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
629 for (
SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
631 size_t i = nCol*nRowSize + nRow;
632 aCellStates[
i] = Occupied;
643 bool bGlueCols =
false;
644 for (
SCCOL nCol = 0; bGlue && nCol < nColSize; ++nCol)
646 for (
SCROW nRow = 0; bGlue && nRow < nRowSize; ++nRow)
648 size_t i = nCol*nRowSize + nRow;
649 if (aCellStates[
i] == Occupied)
651 if (nCol == 0 || nRow == 0)
657 aCellStates[
i] =
Free;
659 size_t nLast = (nCol+1)*nRowSize - 1;
660 if (bGlue && aCellStates[nLast] ==
Free)
663 aCellStates[nLast] =
Glue;
668 bool bGlueRows =
false;
669 for (
SCROW nRow = 0; bGlue && nRow < nRowSize; ++nRow)
672 for (
SCCOL nCol = 0; bGlue && nCol < nColSize; ++nCol,
i += nRowSize)
674 if (aCellStates[
i] == Occupied)
676 if (nCol == 0 || nRow == 0)
682 aCellStates[
i] =
Free;
684 i = (nColSize-1)*nRowSize + nRow;
685 if (bGlue && aCellStates[
i] ==
Free)
688 aCellStates[
i] =
Glue;
694 for (sal_uInt32
n = 1; bGlue &&
n < nCR; ++
n, ++
i)
695 if (aCellStates[
i] ==
Hole)
700 if (bGlueCols && bGlueRows)
701 meGlue = GLUETYPE_BOTH;
703 meGlue = GLUETYPE_ROWS;
705 meGlue = GLUETYPE_COLS;
706 if (aCellStates.front() != Occupied)
707 mbDummyUpperLeft =
true;
710 meGlue = GLUETYPE_NONE;
713void Chart2Positioner::createPositionMap()
715 if (meGlue == GLUETYPE_NA && mpPositionMap)
716 mpPositionMap.reset();
723 bool bNoGlue = (meGlue == GLUETYPE_NONE);
724 FormulaTokenMapMap aCols;
725 SCROW nNoGlueRow = 0;
729 sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
732 aTabName = pToken->GetString();
743 for (
SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
748 sal_uInt32 nInsCol = (
static_cast<sal_uInt32
>(nTab) << 16) |
749 (bNoGlue ? 0 :
static_cast<sal_uInt32
>(nCol1));
751 for (
SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nInsCol)
753 FormulaTokenMap& rCol = aCols[nInsCol];
755 auto nInsRow = bNoGlue ? nNoGlueRow : nRow1;
756 for (
SCROW nRow = nRow1; nRow <= nRow2; ++nRow, ++nInsRow)
768 auto& rCell = rCol[nInsRow];
779 nNoGlueRow += nRow2 - nRow1 + 1;
782 bool bFillRowHeader = mbRowHeaders;
783 bool bFillColumnHeader = mbColHeaders;
785 SCSIZE nAllColCount =
static_cast<SCSIZE>(aCols.size());
789 FormulaTokenMap& rCol = aCols.begin()->second;
790 if (mbDummyUpperLeft)
791 rCol.try_emplace( 0,
nullptr );
792 nAllRowCount =
static_cast<SCSIZE>(rCol.size());
795 if( nAllColCount!=0 && nAllRowCount!=0 )
799 FormulaTokenMap& rFirstCol = aCols.begin()->second;
800 for (
const auto& rFirstColEntry : rFirstCol)
802 SCROW nKey = rFirstColEntry.first;
803 for (
auto& rEntry : aCols)
805 FormulaTokenMap& rCol = rEntry.second;
806 rCol.try_emplace( nKey,
nullptr );
812 new Chart2PositionMap(
813 static_cast<SCCOL>(nAllColCount),
static_cast<SCROW>(nAllRowCount),
814 bFillRowHeader, bFillColumnHeader, aCols, mpDoc));
820class Tokens2RangeString
824 mpRangeStr(std::make_shared<OUStringBuffer>()),
827 mcRangeSep(cRangeSep),
840 mpRangeStr->append(mcRangeSep);
841 mpRangeStr->append(
aStr);
846 rStr = mpRangeStr->makeStringAndClear();
850 shared_ptr<OUStringBuffer> mpRangeStr;
852 FormulaGrammar::Grammar meGrammar;
865class Tokens2RangeStringXML
868 explicit Tokens2RangeStringXML(
ScDocument& rDoc) :
869 mpRangeStr(std::make_shared<OUStringBuffer>()),
880 mpRangeStr->append(mcRangeSep);
883 bool bValidToken = splitRangeToken(*mpDoc, rToken, aStart, aEnd);
885 if (!bValidToken && rToken->GetType() ==
svIndex && rToken->GetOpCode() ==
ocName)
887 ScRangeData* pNameRange = mpDoc->FindRangeNameBySheetAndIndex(rToken->GetSheet(), rToken->GetIndex());
891 bValidToken = splitRangeToken(*mpDoc, aTempToken, aStart, aEnd);
895 OSL_ENSURE(bValidToken,
"invalid token");
903 mpRangeStr->append(
aStr);
905 mpRangeStr->append(mcAddrSep);
909 mpRangeStr->append(
aStr);
915 rStr = mpRangeStr->makeStringAndClear();
923 OSL_ENSURE(bIsRefToken,
"invalid token");
927 sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
930 aTabName = pToken->GetString();
933 setRelative(
aData.Ref1);
934 setRelative(
aData.Ref2);
937 aData.Ref1.SetFlag3D(
true);
938 aData.Ref2.SetFlag3D(
true);
960 shared_ptr<OUStringBuffer> mpRangeStr;
967void lcl_convertTokensToString(OUString& rStr,
const vector<ScTokenRef>& rTokens,
ScDocument& rDoc)
970 FormulaGrammar::Grammar eGrammar = rDoc.
GetGrammar();
971 Tokens2RangeString func(rDoc, eGrammar, cRangeSep);
972 func = ::std::for_each(rTokens.begin(), rTokens.end(), func);
973 func.getString(rStr);
982 , m_aPropSet(lcl_GetDataProviderPropertyMap())
983 , m_bIncludeHiddenCells( true)
999 if ( rHint.
GetId() == SfxHintId::Dying )
1011 OUString aRangeRepresentation;
1014 if ( rArgument.Name ==
"CellRangeRepresentation" )
1016 rArgument.Value >>= aRangeRepresentation;
1020 vector<ScTokenRef> aTokens;
1024 return !aTokens.empty();
1030uno::Reference< chart2::data::XLabeledDataSequence > lcl_createLabeledDataSequenceFromTokens(
1031 vector< ScTokenRef > && aValueTokens, vector< ScTokenRef > && aLabelTokens,
1034 uno::Reference< chart2::data::XLabeledDataSequence > xResult;
1035 bool bHasValues = !aValueTokens.empty();
1036 bool bHasLabel = !aLabelTokens.empty();
1037 if( bHasValues || bHasLabel )
1041 uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1042 if ( xContext.is() )
1044 xResult.set( chart2::data::LabeledDataSequence::create(xContext), uno::UNO_QUERY_THROW );
1048 uno::Reference< chart2::data::XDataSequence > xSeq(
new ScChart2DataSequence( pDoc, std::move(aValueTokens), bIncludeHiddenCells ) );
1049 xResult->setValues( xSeq );
1054 uno::Reference< chart2::data::XDataSequence > xLabelSeq(
new ScChart2DataSequence( pDoc, std::move(aLabelTokens),
true ) );
1055 xResult->setLabel( xLabelSeq );
1058 catch(
const uno::Exception& )
1074bool lcl_addUpperLeftCornerIfMissing(
const ScDocument* pDoc, vector<ScTokenRef>& rRefTokens,
1075 SCROW nCornerRowCount,
SCCOL nCornerColumnCount)
1080 if (rRefTokens.empty())
1089 sal_uInt16 nFileId = 0;
1091 bool bExternal =
false;
1093 vector<ScTokenRef>::const_iterator itr = rRefTokens.begin(), itrEnd = rRefTokens.end();
1097 switch (pToken->GetType())
1102 nMinCol = rData.
Col();
1103 nMinRow = rData.
Row();
1104 nMaxCol = rData.
Col();
1105 nMaxRow = rData.
Row();
1122 nMinCol = rData.
Col();
1123 nMinRow = rData.
Row();
1124 nMaxCol = rData.
Col();
1125 nMaxRow = rData.
Row();
1127 nFileId = pToken->GetIndex();
1128 aExtTabName = pToken->GetString();
1140 nFileId = pToken->GetIndex();
1141 aExtTabName = pToken->GetString();
1152 for (++itr; itr != itrEnd; ++itr)
1155 switch (pToken->GetType())
1161 nMinCol =
min(nMinCol, rData.
Col());
1162 nMinRow =
min(nMinRow, rData.
Row());
1163 nMaxCol =
max(nMaxCol, rData.
Col());
1164 nMaxRow =
max(nMaxRow, rData.
Row());
1165 if (nTab != rData.
Tab() || bExternal)
1183 if (nTab != rData.
Ref1.
Tab() || bExternal)
1192 if (nFileId != pToken->GetIndex() || aExtTabName != pToken->GetString())
1197 nMinCol =
min(nMinCol, rData.
Col());
1198 nMinRow =
min(nMinRow, rData.
Row());
1199 nMaxCol =
max(nMaxCol, rData.
Col());
1200 nMaxRow =
max(nMaxRow, rData.
Row());
1208 if (nFileId != pToken->GetIndex() || aExtTabName != pToken->GetString())
1230 if (nMinRow >= nMaxRow || nMinCol >= nMaxCol ||
1231 nMinRow >= rSheetLimits.GetMaxRowCount() || nMinCol >= rSheetLimits.GetMaxColCount() ||
1232 nMaxRow >= rSheetLimits.GetMaxRowCount() || nMaxCol >= rSheetLimits.GetMaxColCount())
1243 bool bRight =
false, bBottom =
false, bDiagonal =
false;
1244 for (
const auto& rxToken : rRefTokens)
1246 switch (rxToken->GetType())
1252 if (rData.
Col() == nMinCol && rData.
Row() == nMinRow)
1256 if (rData.
Col() == nMinCol+nCornerColumnCount && rData.
Row() == nMinRow)
1259 if (rData.
Col() == nMinCol && rData.
Row() == nMinRow+nCornerRowCount)
1262 if (rData.
Col() == nMinCol+nCornerColumnCount && rData.
Row() == nMinRow+nCornerRowCount)
1272 if (r1.
Col() <= nMinCol && nMinCol <= r2.
Col() &&
1273 r1.
Row() <= nMinRow && nMinRow <= r2.
Row())
1277 if (r1.
Col() <= nMinCol+nCornerColumnCount && nMinCol+nCornerColumnCount <= r2.
Col() &&
1278 r1.
Row() <= nMinRow && nMinRow <= r2.
Row())
1281 if (r1.
Col() <= nMinCol && nMinCol <= r2.
Col() &&
1282 r1.
Row() <= nMinRow+nCornerRowCount && nMinRow+nCornerRowCount <= r2.
Row())
1285 if (r1.
Col() <= nMinCol+nCornerColumnCount && nMinCol+nCornerColumnCount <= r2.
Col() &&
1286 r1.
Row() <= nMinRow+nCornerRowCount && nMinRow+nCornerRowCount <= r2.
Row())
1295 if (!bRight || !bBottom || !bDiagonal)
1301 aData.SetFlag3D(
true);
1302 aData.SetAbsCol(nMinCol);
1303 aData.SetAbsRow(nMinRow);
1304 aData.SetAbsTab(nTab);
1306 if( nCornerRowCount==1 && nCornerColumnCount==1 )
1323 aDataEnd.IncCol(nCornerColumnCount-1);
1324 aDataEnd.IncRow(nCornerRowCount-1);
1344#define SHRINK_RANGE_THRESHOLD 10000
1346class ShrinkRefTokenToDataRange
1350 explicit ShrinkRefTokenToDataRange(
ScDocument* pDoc) : mpDoc(pDoc) {}
1373 for (
SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
1378 nMinCol = std::min(nMinCol, nCol1);
1379 nMinRow = std::min(nMinRow, nRow1);
1380 nMaxCol = std::max(nMaxCol, nCol2);
1381 nMaxRow = std::max(nMaxRow, nRow2);
1385 if (s.
Col() < nMinCol)
1387 if (s.
Row() < nMinRow)
1389 if (e.
Col() > nMaxCol)
1391 if (e.
Row() > nMaxRow)
1396void shrinkToDataRange(
ScDocument* pDoc, vector<ScTokenRef>& rRefTokens)
1398 std::for_each(rRefTokens.begin(), rRefTokens.end(), ShrinkRefTokenToDataRange(pDoc));
1403uno::Reference< chart2::data::XDataSource> SAL_CALL
1405 const uno::Sequence< beans::PropertyValue >& aArguments )
1409 throw uno::RuntimeException();
1411 uno::Reference< chart2::data::XDataSource> xResult;
1413 bool bCategories =
false;
1414 bool bOrientCol =
true;
1415 OUString aRangeRepresentation;
1416 uno::Sequence< sal_Int32 > aSequenceMapping;
1417 bool bTimeBased =
false;
1420 if ( rArgument.Name ==
"DataRowSource" )
1422 chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS;
1423 if( ! (rArgument.Value >>= eSource))
1425 sal_Int32 nSource(0);
1426 if( rArgument.Value >>= nSource )
1427 eSource =
static_cast< chart::ChartDataRowSource
>( nSource );
1429 bOrientCol = (eSource == chart::ChartDataRowSource_COLUMNS);
1431 else if ( rArgument.Name ==
"FirstCellAsLabel" )
1433 bLabel = ::cppu::any2bool(rArgument.Value);
1435 else if ( rArgument.Name ==
"HasCategories" )
1437 bCategories = ::cppu::any2bool(rArgument.Value);
1439 else if ( rArgument.Name ==
"CellRangeRepresentation" )
1441 rArgument.Value >>= aRangeRepresentation;
1443 else if ( rArgument.Name ==
"SequenceMapping" )
1445 rArgument.Value >>= aSequenceMapping;
1447 else if ( rArgument.Name ==
"TimeBased" )
1449 rArgument.Value >>= bTimeBased;
1453 vector<ScTokenRef> aRefTokens;
1457 if (aRefTokens.empty())
1459 throw lang::IllegalArgumentException();
1462 SCTAB nTimeBasedEnd = 0;
1466 for(
const auto& rxToken : aRefTokens)
1475 nTimeBasedStart = std::min(nTimeBasedStart, s.
Tab());
1476 nTimeBasedEnd = std::min(nTimeBasedEnd, e.
Tab());
1487 lcl_addUpperLeftCornerIfMissing(
m_pDocument, aRefTokens, 1, 1);
1489 bool bColHeaders = (bOrientCol ? bLabel : bCategories );
1490 bool bRowHeaders = (bOrientCol ? bCategories : bLabel );
1492 Chart2Positioner aChPositioner(
m_pDocument, aRefTokens);
1493 aChPositioner.setHeaders(bColHeaders, bRowHeaders);
1495 const Chart2PositionMap* pChartMap = aChPositioner.getPositionMap();
1501 ::std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aSeqs;
1506 vector<ScTokenRef> aValueTokens;
1508 aValueTokens = pChartMap->getAllRowHeaderRanges();
1510 aValueTokens = pChartMap->getAllColHeaderRanges();
1512 vector<ScTokenRef> aLabelTokens(
1513 pChartMap->getLeftUpperCornerRanges());
1515 uno::Reference< chart2::data::XLabeledDataSequence > xCategories = lcl_createLabeledDataSequenceFromTokens(
1517 if ( xCategories.is() )
1519 aSeqs.push_back( xCategories );
1524 sal_Int32
nCount = bOrientCol ? pChartMap->getDataColCount() : pChartMap->getDataRowCount();
1527 vector<ScTokenRef> aValueTokens;
1528 vector<ScTokenRef> aLabelTokens;
1531 aValueTokens = pChartMap->getDataColRanges(
static_cast<SCCOL>(
i));
1532 aLabelTokens = pChartMap->getColHeaderRanges(
static_cast<SCCOL>(
i));
1536 aValueTokens = pChartMap->getDataRowRanges(
static_cast<SCROW>(
i));
1537 aLabelTokens = pChartMap->getRowHeaderRanges(
static_cast<SCROW>(
i));
1539 uno::Reference< chart2::data::XLabeledDataSequence > xChartSeries = lcl_createLabeledDataSequenceFromTokens(
1541 if ( xChartSeries.is() && xChartSeries->getValues().is() && xChartSeries->getValues()->getData().hasElements() )
1543 aSeqs.push_back( xChartSeries );
1550 ::std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aSeqVector;
1551 aSeqVector.reserve(aSeqs.size());
1552 for (
auto const&
aSeq : aSeqs)
1554 aSeqVector.push_back(
aSeq);
1557 for(
const sal_Int32 nNewIndex : std::as_const(aSequenceMapping) )
1560 ::std::vector< uno::Reference< chart2::data::XLabeledDataSequence > >::size_type nOldIndex(
static_cast< sal_uInt32
>( nNewIndex ) );
1561 if( nOldIndex < aSeqVector.size() )
1563 pDS->AddLabeledSequence( aSeqVector[nOldIndex] );
1564 aSeqVector[nOldIndex] =
nullptr;
1568 for(
const uno::Reference< chart2::data::XLabeledDataSequence >& xSeq : aSeqVector)
1572 pDS->AddLabeledSequence( xSeq );
1586class InsertTabNumber
1594 void operator() (
const ScTokenRef& pToken)
const
1600 mpTabNumVector->push_back(r.
Tab());
1603 void getVector(vector<SCTAB>& rVector)
1605 mpTabNumVector->swap(rVector);
1608 shared_ptr< vector<SCTAB> > mpTabNumVector;
1615 void initRangeAnalyzer(
const ScDocument* pDoc,
const vector<ScTokenRef>& rTokens );
1616 void analyzeRange( sal_Int32& rnDataInRows, sal_Int32& rnDataInCols,
1617 bool& rbRowSourceAmbiguous )
const;
1618 bool inSameSingleRow(
const RangeAnalyzer& rOther );
1619 bool inSameSingleColumn(
const RangeAnalyzer& rOther );
1620 SCROW getRowCount()
const {
return mnRowCount; }
1621 SCCOL getColumnCount()
const {
return mnColumnCount; }
1627 SCCOL mnColumnCount;
1629 SCCOL mnStartColumn;
1633RangeAnalyzer::RangeAnalyzer()
1635 , mbAmbiguous(false)
1643void RangeAnalyzer::initRangeAnalyzer(
const ScDocument* pDoc,
const vector<ScTokenRef>& rTokens )
1650 if( rTokens.empty() )
1659 StackVar eVar = aRefToken->GetType();
1660 if (eVar == svDoubleRef || eVar == svExternalDoubleRef)
1667 if( mnStartColumn == -1 )
1681 else if (eVar == svSingleRef || eVar == svExternalSingleRef)
1684 mnColumnCount = std::max<SCCOL>( mnColumnCount, 1);
1685 mnRowCount = std::max<SCROW>( mnRowCount, 1);
1686 if( mnStartColumn == -1 )
1688 mnStartColumn = r.
Col();
1689 mnStartRow = r.
Row();
1693 if (mnStartColumn != r.
Col() && mnStartRow != r.
Row())
1697 else if (eVar == svIndex && aRefToken->GetOpCode() == ocName)
1703 mnColumnCount = std::max<SCCOL>(mnColumnCount,
static_cast<SCCOL>(
abs(aRange.
aEnd.
Col() - aRange.
aStart.
Col()) + 1));
1705 if (mnStartColumn == -1)
1724void RangeAnalyzer::analyzeRange( sal_Int32& rnDataInRows,
1725 sal_Int32& rnDataInCols,
1726 bool& rbRowSourceAmbiguous )
const
1728 if(!mbEmpty && !mbAmbiguous)
1730 if( mnRowCount==1 && mnColumnCount>1 )
1732 else if( mnColumnCount==1 && mnRowCount>1 )
1734 else if( mnRowCount>1 && mnColumnCount>1 )
1735 rbRowSourceAmbiguous =
true;
1738 rbRowSourceAmbiguous =
true;
1741bool RangeAnalyzer::inSameSingleRow(
const RangeAnalyzer& rOther )
1743 return mnStartRow==rOther.mnStartRow &&
1744 mnRowCount==1 && rOther.mnRowCount==1;
1747bool RangeAnalyzer::inSameSingleColumn(
const RangeAnalyzer& rOther )
1749 return mnStartColumn==rOther.mnStartColumn &&
1750 mnColumnCount==1 && rOther.mnColumnCount==1;
1753std::pair<OUString, OUString> constructKey(
const uno::Reference< chart2::data::XLabeledDataSequence>& xNew)
1755 std::pair<OUString, OUString> aKey;
1756 if( xNew->getLabel().is() )
1757 aKey.first = xNew->getLabel()->getSourceRangeRepresentation();
1758 if( xNew->getValues().is() )
1759 aKey.second = xNew->getValues()->getSourceRangeRepresentation();
1767 const uno::Reference< chart2::data::XDataSource >& xDataSource )
1769 ::std::vector< beans::PropertyValue > aResult;
1770 bool bRowSourceDetected =
false;
1771 bool bFirstCellAsLabel =
false;
1772 bool bHasCategories =
false;
1775 bool bHasCategoriesLabels =
false;
1776 vector<ScTokenRef> aAllCategoriesValuesTokens;
1777 vector<ScTokenRef> aAllSeriesLabelTokens;
1779 chart::ChartDataRowSource eRowSource = chart::ChartDataRowSource_COLUMNS;
1781 vector<ScTokenRef> aAllTokens;
1786 OSL_ENSURE(
m_pDocument,
"No Document -> no detectArguments" );
1790 sal_Int32 nDataInRows = 0;
1791 sal_Int32 nDataInCols = 0;
1792 bool bRowSourceAmbiguous =
false;
1794 const Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences());
1795 const sal_Int32
nCount( aSequences.getLength());
1796 RangeAnalyzer aPrevLabel,aPrevValues;
1797 for(
const uno::Reference< chart2::data::XLabeledDataSequence >& xLS : aSequences )
1801 bool bThisIsCategories =
false;
1804 uno::Reference< beans::XPropertySet > xSeqProp( xLS->getValues(), uno::UNO_QUERY );
1806 if( xSeqProp.is() && (xSeqProp->getPropertyValue(
"Role") >>= aRole) &&
1807 aRole ==
"categories" )
1808 bThisIsCategories = bHasCategories =
true;
1811 RangeAnalyzer
aLabel,aValues;
1813 uno::Reference< chart2::data::XDataSequence > xLabel( xLS->getLabel());
1816 bFirstCellAsLabel =
true;
1817 vector<ScTokenRef> aTokens;
1822 for (
const auto& rxToken : aTokens)
1824 if (rxToken->GetType() ==
svIndex && rxToken->GetOpCode() ==
ocName)
1837 if(!bThisIsCategories)
1840 if(bThisIsCategories)
1841 bHasCategoriesLabels=
true;
1844 uno::Reference< chart2::data::XDataSequence > xValues( xLS->getValues());
1847 vector<ScTokenRef> aTokens;
1852 for (
const auto& rxToken : aTokens)
1854 if (rxToken->GetType() ==
svIndex && rxToken->GetOpCode() ==
ocName)
1867 if(bThisIsCategories)
1872 if(!bThisIsCategories ||
nCount==1)
1874 if (!bRowSourceAmbiguous)
1876 aValues.analyzeRange(nDataInRows,nDataInCols,bRowSourceAmbiguous);
1877 aLabel.analyzeRange(nDataInRows,nDataInCols,bRowSourceAmbiguous);
1878 if (nDataInRows > 1 && nDataInCols > 1)
1879 bRowSourceAmbiguous =
true;
1880 else if( !bRowSourceAmbiguous && !nDataInRows && !nDataInCols )
1882 if( aValues.inSameSingleColumn(
aLabel ) )
1884 else if( aValues.inSameSingleRow(
aLabel ) )
1889 if( aValues.inSameSingleColumn( aPrevValues ) )
1891 else if( aValues.inSameSingleRow( aPrevValues ) )
1893 else if(
aLabel.inSameSingleColumn( aPrevLabel ) )
1895 else if(
aLabel.inSameSingleRow( aPrevLabel ) )
1901 aPrevValues=aValues;
1906 if (!bRowSourceAmbiguous)
1908 bRowSourceDetected =
true;
1909 eRowSource = ( nDataInCols > 0
1910 ? chart::ChartDataRowSource_COLUMNS
1911 : chart::ChartDataRowSource_ROWS );
1916 eRowSource = ( nDataInRows > nDataInCols
1917 ? chart::ChartDataRowSource_ROWS
1918 : chart::ChartDataRowSource_COLUMNS );
1925 vector<SCTAB> aTableNumVector;
1926 InsertTabNumber func;
1927 func = ::std::for_each(aAllTokens.begin(), aAllTokens.end(), func);
1928 func.getVector(aTableNumVector);
1929 aResult.emplace_back(
"TableNumberList", -1,
1930 uno::Any( lcl_createTableNumberList( aTableNumVector ) ),
1931 beans::PropertyState_DIRECT_VALUE );
1934 if( bRowSourceDetected )
1937 aResult.emplace_back(
"DataRowSource", -1,
1938 uno::Any( eRowSource ), beans::PropertyState_DIRECT_VALUE );
1940 aResult.emplace_back(
"HasCategories", -1,
1941 uno::Any( bHasCategories ), beans::PropertyState_DIRECT_VALUE );
1943 aResult.emplace_back(
"FirstCellAsLabel", -1,
1944 uno::Any( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE );
1948 if (bRowSourceDetected && bFirstCellAsLabel && bHasCategories && !bHasCategoriesLabels )
1950 RangeAnalyzer aTop,aLeft;
1951 if( eRowSource==chart::ChartDataRowSource_COLUMNS )
1953 aTop.initRangeAnalyzer(
m_pDocument, aAllSeriesLabelTokens);
1954 aLeft.initRangeAnalyzer(
m_pDocument, aAllCategoriesValuesTokens);
1958 aTop.initRangeAnalyzer(
m_pDocument, aAllCategoriesValuesTokens);
1959 aLeft.initRangeAnalyzer(
m_pDocument, aAllSeriesLabelTokens);
1961 lcl_addUpperLeftCornerIfMissing(
m_pDocument, aAllTokens, aTop.getRowCount(), aLeft.getColumnCount());
1965 lcl_convertTokensToString(sRangeRep, aAllTokens, *
m_pDocument);
1968 aResult.emplace_back(
"CellRangeRepresentation", -1,
1969 uno::Any( sRangeRep ), beans::PropertyState_DIRECT_VALUE );
1972 bool const bSequencesReordered =
true;
1973 if( bSequencesReordered && bRowSourceDetected )
1975 bool bDifferentIndexes =
false;
1977 std::vector< sal_Int32 > aSequenceMappingVector;
1979 uno::Reference< chart2::data::XDataSource > xCompareDataSource;
1984 catch(
const lang::IllegalArgumentException & )
1990 if( xDataSource.is() && xCompareDataSource.is() )
1992 const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> >& aOldSequences =
1993 xCompareDataSource->getDataSequences();
1994 const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> >& aNewSequences =
1995 xDataSource->getDataSequences();
1997 std::map<std::pair<OUString, OUString>,sal_Int32> aOldEntryToIndex;
2000 const uno::Reference< chart2::data::XLabeledDataSequence>& xOld( aOldSequences[
nIndex] );
2003 std::pair<OUString, OUString> aKey = constructKey(xOld);
2004 aOldEntryToIndex[aKey] =
nIndex;
2008 for( sal_Int32 nNewIndex = 0,
n = aNewSequences.getLength(); nNewIndex <
n; nNewIndex++ )
2010 const uno::Reference< chart2::data::XLabeledDataSequence>& xNew( aNewSequences[nNewIndex] );
2014 std::pair<OUString, OUString> aKey = constructKey(xNew);
2015 if (aOldEntryToIndex.find(aKey) == aOldEntryToIndex.end())
2018 sal_Int32 nOldIndex = aOldEntryToIndex[aKey];
2019 if( nOldIndex != nNewIndex )
2020 bDifferentIndexes =
true;
2022 aSequenceMappingVector.push_back(nOldIndex);
2026 if( bDifferentIndexes && !aSequenceMappingVector.empty() )
2028 aResult.emplace_back(
"SequenceMapping", -1,
2030 , beans::PropertyState_DIRECT_VALUE );
2043 vector<ScTokenRef> aTokens;
2047 return !aTokens.empty();
2050uno::Reference< chart2::data::XDataSequence > SAL_CALL
2052 const OUString& aRangeRepresentation )
2055 uno::Reference< chart2::data::XDataSequence > xResult;
2057 OSL_ENSURE(
m_pDocument,
"No Document -> no createDataSequenceByRangeRepresentation" );
2058 if(!
m_pDocument || aRangeRepresentation.isEmpty())
2061 vector<ScTokenRef> aRefTokens;
2065 if (aRefTokens.empty())
2075uno::Reference<chart2::data::XDataSequence> SAL_CALL
2077 const OUString& ,
const OUString& ,
2080 return uno::Reference<chart2::data::XDataSequence>();
2085 uno::Reference< sheet::XRangeSelection > xResult;
2089 xResult.set(
xModel->getCurrentController(), uno::UNO_QUERY );
2095 const Sequence<sheet::FormulaToken>& aTokens )
2097 if (!aTokens.hasElements())
2104 sal_uInt16
n = aCode.
GetLen();
2113 switch (
p->GetType())
2117 switch (
p->GetOpCode())
2150uno::Reference<chart2::data::XDataSequence> SAL_CALL
2152 const Sequence<sheet::FormulaToken>& aTokens )
2154 uno::Reference<chart2::data::XDataSequence> xResult;
2155 if (!aTokens.hasElements())
2162 sal_uInt16
n = aCode.
GetLen();
2166 vector<ScTokenRef> aRefTokens;
2172 switch (
p->GetType())
2176 switch (
p->GetOpCode())
2184 throw lang::IllegalArgumentException();
2189 throw lang::IllegalArgumentException();
2192 throw lang::IllegalArgumentException();
2204 aRefTokens.push_back(pNew);
2208 throw lang::IllegalArgumentException();
2212 if (aRefTokens.empty())
2229 if (sRangeRepresentation.isEmpty())
2233 vector<ScTokenRef> aRefTokens;
2237 if (aRefTokens.empty())
2239 SAL_WARN(
"sc",
"convertRangeToXML throw IllegalArgumentException from input of: " << sRangeRepresentation);
2240 throw lang::IllegalArgumentException();
2244 converter = ::std::for_each(aRefTokens.begin(), aRefTokens.end(), converter);
2245 converter.getString(aRet);
2257 OUStringBuffer sRet;
2258 sal_Int32 nOffset = 0;
2259 while( nOffset >= 0 )
2267 OUString aUIString(sToken);
2270 if (
nIndex >= 0 &&
nIndex < aUIString.getLength() - 1 &&
2271 aUIString[
nIndex + 1] ==
'.' )
2272 aUIString = aUIString.replaceAt(
nIndex + 1, 1,
u"" );
2274 if ( aUIString[0] ==
'.' )
2275 aUIString = aUIString.copy( 1 );
2277 if( !sRet.isEmpty() )
2279 sRet.append( aUIString );
2283 return sRet.makeStringAndClear();
2293uno::Reference< beans::XPropertySetInfo> SAL_CALL
2297 static uno::Reference<beans::XPropertySetInfo> aRef =
2303 const OUString& rPropertyName,
const uno::Any& rValue)
2306 throw beans::UnknownPropertyException(rPropertyName);
2309 throw lang::IllegalArgumentException();
2314 const OUString& rPropertyName)
2325 throw beans::UnknownPropertyException(rPropertyName);
2331 const uno::Reference< beans::XPropertyChangeListener>& )
2333 OSL_FAIL(
"Not yet implemented" );
2338 const uno::Reference< beans::XPropertyChangeListener>& )
2340 OSL_FAIL(
"Not yet implemented" );
2345 const uno::Reference< beans::XVetoableChangeListener>& )
2347 OSL_FAIL(
"Not yet implemented" );
2352 const uno::Reference< beans::XVetoableChangeListener>& )
2354 OSL_FAIL(
"Not yet implemented" );
2360 : m_pDocument( pDoc)
2376 if ( rHint.
GetId() == SfxHintId::Dying )
2382uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> > SAL_CALL
2397 : mfValue(
std::numeric_limits<double>::quiet_NaN())
2417 vector<ScTokenRef>&& rTokens,
2418 bool bIncludeHiddenCells )
2490 const std::unordered_set<sal_uInt16>& rFileIds = r.
m_pExtRefListener->getAllFileIds();
2491 for (
const auto& rFileId : rFileIds)
2556 ::std::vector<sal_Int32> aHiddenValues;
2557 sal_Int32 nDataCount = 0;
2571 SCCOL nLastCol = -1;
2572 SCROW nLastRow = -1;
2581 if (nRow == aRange.
aEnd.
Row())
2593 pData->GetArea(aTempRange);
2594 if (aTempRange.
aEnd.
Row() == nRow)
2604 if (bColHidden || bRowHidden)
2607 aHiddenValues.push_back(nDataCount-1);
2629 if (nErr != FormulaError::NONE)
2659 aHiddenValues.begin(), aHiddenValues.end(),
m_aHiddenValues.getArray());
2683 sal_uInt16 nFileId = pToken->GetIndex();
2684 OUString aTabName = pToken->GetString().getString();
2697 sal_Int32 nDataCount = 0;
2698 FormulaTokenArrayPlainIterator aIter(*pArray);
2699 for (FormulaToken*
p = aIter.First();
p;
p = aIter.Next())
2708 OSL_FAIL(
"Cached array is not a matrix token.");
2715 for (
SCSIZE nC = 0; nC < nCSize; ++nC)
2717 for (
SCSIZE nR = 0; nR < nRSize; ++nR)
2729 const double fVal = aItem.
mfValue;
2730 const Color* pColor =
nullptr;
2731 sal_uInt32 nFmt = 0;
2737 pTable->getCell(nCol, nRow, &nFmt);
2769 const ScRange & rRange = rRanges[
i];
2772 sal_uInt32 nOrigPos = (*m_oRangeIndices)[
i];
2796 const std::unordered_set<sal_uInt16>& rFileIds =
m_pExtRefListener->getAllFileIds();
2798 for (
const auto& rFileId : rFileIds)
2814 vector<ScTokenRef>::const_iterator itrBeg =
m_aTokens.begin(), itrEnd =
m_aTokens.end();
2815 for (vector<ScTokenRef>::const_iterator itr = itrBeg ;itr != itrEnd; ++itr)
2828 "range list and range index list have different sizes.");
2830 unique_ptr<ScRangeList> pUndoRanges;
2842 "sc.ui",
"range list and range index list have different sizes after the reference update.");
2863 assert(
false &&
" faulty range indices");
2867 const ScRangeList& rRanges = pUndoHint->GetRanges();
2872 assert(
false &&
"range count and range index count differ.");
2883 if (
nId ==SfxHintId::Dying )
2887 else if (
nId == SfxHintId::DataChanged )
2894 lang::EventObject
aEvent;
2895 aEvent.Source = getXWeak();
2899 for (
const uno::Reference<util::XModifyListener> & xListener:
m_aValueListeners)
2906 else if (
nId == SfxHintId::ScCalcAll )
2914 else if (
nId == SfxHintId::ScClearCache)
2924 if ( m_pDocument && (rHint.GetId() == SfxHintId::ScDataChanged) )
2930 setDataChangedHint(
true);
2943 if (!mpDoc || mpDoc->IsInDtorClear())
2948 mpDoc->GetExternalRefManager()->removeLinkListener(
this);
2957 if (maFileIds.count(nFileId))
2963 maFileIds.erase(nFileId);
2973 maFileIds.insert(nFileId);
2980 throw uno::RuntimeException();
2993 if (rItem.mbIsValue)
2994 *pArr <<= rItem.mfValue;
2995 else if (rItem.maString.isEmpty())
3001 *pArr <<= rItem.maString;
3004 *pArr <<= rItem.maString;
3017 throw uno::RuntimeException();
3023 double* pArr =
aSeq.getArray();
3026 *pArr = rItem.mbIsValue ? rItem.mfValue : std::numeric_limits<double>::quiet_NaN();
3038 uno::Sequence<OUString>
aSeq;
3040 throw uno::RuntimeException();
3048 OUString* pArr =
aSeq.getArray();
3051 *pArr = rItem.maString;
3059 aSeq = uno::Sequence<OUString> {
m_aTokens.front()->GetString().getString() };
3070 OSL_ENSURE(
m_pDocument,
"No Document -> no SourceRangeRepresentation" );
3083class AccumulateRangeSize
3086 AccumulateRangeSize(
const ScDocument* pDoc) :
3087 mpDoc(pDoc), mnCols(0), mnRows(0) {}
3099 SCCOL getCols()
const {
return mnCols; }
3100 SCROW getRows()
const {
return mnRows; }
3111class GenerateLabelStrings
3114 GenerateLabelStrings(
const ScDocument* pDoc, sal_Int32 nSize, chart2::data::LabelOrigin eOrigin,
bool bColumn) :
3119 mbColumn(bColumn) {}
3126 OUString* pArr = mpLabels->getArray();
3131 if ( meOrigin != chart2::data::LabelOrigin_LONG_SIDE)
3133 OUString aString =
ScResId(STR_COLUMN) +
" ";
3140 pArr[
mnCount] = OUString::number( mnCount+1 );
3146 for (sal_Int32 nRow = aRange.
aStart.
Row(); nRow <= aRange.
aEnd.
Row(); ++nRow)
3148 if (meOrigin != chart2::data::LabelOrigin_LONG_SIDE)
3150 OUString aString =
ScResId(STR_ROW) +
3151 " " + OUString::number( nRow+1 );
3155 pArr[
mnCount] = OUString::number( mnCount+1 );
3161 const Sequence<OUString>& getLabels()
const {
return *mpLabels; }
3165 shared_ptr< Sequence<OUString> > mpLabels;
3166 chart2::data::LabelOrigin meOrigin;
3177 throw uno::RuntimeException();
3182 SCCOL nCols = func.getCols();
3183 SCROW nRows = func.getRows();
3186 bool bColumn =
true;
3187 if ((eOrigin == chart2::data::LabelOrigin_SHORT_SIDE) ||
3188 (eOrigin == chart2::data::LabelOrigin_LONG_SIDE))
3192 bColumn = eOrigin == chart2::data::LabelOrigin_SHORT_SIDE;
3194 else if (nCols > nRows)
3196 bColumn = eOrigin != chart2::data::LabelOrigin_SHORT_SIDE;
3199 return Sequence<OUString>();
3203 sal_Int32
nCount = bColumn ? nCols : nRows;
3206 Sequence<OUString>
aSeq = genLabels.getLabels();
3235 return static_cast<sal_Int32
>(getDisplayNumberFormat(
m_pDocument, rItem.mAddress));
3245 SAL_WARN(
"sc.ui",
"Passed invalid index to getNumberFormatKeyByIndex(). Will return default value '0'.");
3316 if ( rObj == aListener )
3342uno::Reference< beans::XPropertySetInfo> SAL_CALL
3346 static uno::Reference<beans::XPropertySetInfo> aRef =
3352 const OUString& rPropertyName,
const uno::Any& rValue)
3357 throw lang::IllegalArgumentException();
3363 throw lang::IllegalArgumentException();
3367 else if( rPropertyName ==
"TimeBased" )
3370 rValue>>= bTimeBased;
3374 throw beans::UnknownPropertyException(rPropertyName);
3400 bool bHasStringLabel =
false;
3406 aRet <<= bHasStringLabel;
3409 throw beans::UnknownPropertyException(rPropertyName);
3416 const uno::Reference< beans::XPropertyChangeListener>& )
3419 OSL_FAIL(
"Not yet implemented" );
3424 const uno::Reference< beans::XPropertyChangeListener>& )
3427 OSL_FAIL(
"Not yet implemented" );
3432 const uno::Reference< beans::XVetoableChangeListener>& )
3435 OSL_FAIL(
"Not yet implemented" );
3440 const uno::Reference< beans::XVetoableChangeListener>& )
3443 OSL_FAIL(
"Not yet implemented" );
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
BaseContainerNodeSharedPtr & mrParent
FILE * init(int, char **)
SC_SIMPLE_SERVICE_INFO(ScChart2DataProvider, "ScChart2DataProvider", "com.sun.star.chart2.data.DataProvider") SC_SIMPLE_SERVICE_INFO(ScChart2DataSource
#define SHRINK_RANGE_THRESHOLD
IMPL_LINK(ScChart2DataSequence, ValueListenerHdl, const SfxHint &, rHint, void)
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceByRangeRepresentation(const OUString &aRangeRepresentation) override
virtual void SAL_CALL addVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &rListener) override
virtual css::uno::Reference< css::sheet::XRangeSelection > SAL_CALL getRangeSelection() override
virtual void SAL_CALL removePropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &rListener) override
virtual OUString SAL_CALL convertRangeFromXML(const OUString &sXMLRange) override
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL detectArguments(const css::uno::Reference< css::chart2::data::XDataSource > &xDataSource) override
virtual ~ScChart2DataProvider() override
virtual OUString SAL_CALL convertRangeToXML(const OUString &sRangeRepresentation) override
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceByValueArray(const OUString &aRole, const OUString &aRangeRepresentation, const OUString &aRoleQualifier) override
virtual void SAL_CALL removeVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &rListener) override
virtual sal_Bool SAL_CALL createDataSequenceByRangeRepresentationPossible(const OUString &aRangeRepresentation) override
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
virtual sal_Bool SAL_CALL createDataSourcePossible(const css::uno::Sequence< css::beans::PropertyValue > &aArguments) override
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceByFormulaTokens(const css::uno::Sequence< css::sheet::FormulaToken > &aTokens) override
ScChart2DataProvider(ScDocument *pDoc)
SfxItemPropertySet m_aPropSet
virtual sal_Bool SAL_CALL createDataSequenceByFormulaTokensPossible(const css::uno::Sequence< css::sheet::FormulaToken > &aTokens) override
virtual void SAL_CALL addPropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
bool m_bIncludeHiddenCells
virtual css::uno::Reference< css::chart2::data::XDataSource > SAL_CALL createDataSource(const css::uno::Sequence< css::beans::PropertyValue > &aArguments) override
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
ExternalRefListener(ScChart2DataSequence &rParent, ScDocument *pDoc)
virtual void notify(sal_uInt16 nFileId, ScExternalRefManager::LinkUpdateType eType) override
virtual ~ExternalRefListener() override
void addFileId(sal_uInt16 nFileId)
HiddenRangeListener(ScChart2DataSequence &rParent)
virtual ~HiddenRangeListener() override
virtual void notify() override
css::chart2::data::DataSequenceRole m_aRole
void StopListeningToAllExternalRefs()
std::unique_ptr< HiddenRangeListener > m_pHiddenListener
XModifyListenerArr_Impl m_aValueListeners
virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override
virtual OUString SAL_CALL getSourceRangeRepresentation() override
std::vector< ScTokenRef > m_aTokens
ScChart2DataSequence(ScDocument *pDoc, ::std::vector< ScTokenRef > &&rTokens, bool bIncludeHiddenCells)
virtual css::uno::Sequence< OUString > SAL_CALL generateLabel(css::chart2::data::LabelOrigin nOrigin) override
virtual void SAL_CALL addPropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
void setDataChangedHint(bool b)
ExternalRefListener * GetExtRefListener()
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
std::unique_ptr< ExternalRefListener > m_pExtRefListener
css::uno::Sequence< css::uno::Any > m_aMixedDataCache
Cached data for getData.
std::shared_ptr< std::vector< Item > > m_xDataArray
This vector contains the cached data which was calculated with BuildDataCache().
virtual void SAL_CALL addVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &rListener) override
virtual void SAL_CALL removePropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &rListener) override
virtual void SAL_CALL addModifyListener(const css::uno::Reference< css::util::XModifyListener > &aListener) override
virtual sal_Bool SAL_CALL switchToNext(sal_Bool bWrap) override
virtual css::uno::Sequence< OUString > SAL_CALL getTextualData() override
void UpdateTokensFromRanges(const ScRangeList &rRanges)
std::optional< std::vector< sal_uInt32 > > m_oRangeIndices
bool m_bExtDataRebuildQueued
virtual css::uno::Sequence< css::uno::Any > SAL_CALL getData() override
virtual void SAL_CALL setRange(sal_Int32 nStart, sal_Int32 nEnd) override
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
virtual void SAL_CALL removeVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &rListener) override
virtual sal_Bool SAL_CALL setToPointInTime(sal_Int32 nPoint) override
std::unique_ptr< ScLinkListener > m_pValueListener
SfxItemPropertySet m_aPropSet
bool m_bGotDataChangedHint
sal_Int32 FillCacheFromExternalRef(const ScTokenRef &pToken)
virtual void SAL_CALL removeModifyListener(const css::uno::Reference< css::util::XModifyListener > &aListener) override
bool m_bIncludeHiddenCells
void BuildDataCache()
Build an internal data array to cache the data ranges, and other information such as hidden values.
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual ::sal_Int32 SAL_CALL getNumberFormatKeyByIndex(::sal_Int32 nIndex) override
Get the number format key for the n-th data entry If nIndex == -1, then you will get the number forma...
css::uno::Sequence< sal_Int32 > m_aHiddenValues
virtual ~ScChart2DataSequence() override
virtual css::uno::Sequence< double > SAL_CALL getNumericalData() override
std::vector< css::uno::Reference< css::chart2::data::XLabeledDataSequence > > m_aLabeledSequences
ScChart2DataSource(ScDocument *pDoc)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
void AddLabeledSequence(const css::uno::Reference< css::chart2::data::XLabeledDataSequence > &xNew)
virtual css::uno::Sequence< css::uno::Reference< css::chart2::data::XLabeledDataSequence > > SAL_CALL getDataSequences() override
virtual ~ScChart2DataSource() override
void EndListeningHiddenRange(ScChartHiddenRangeListener *pListener)
Remove all ranges associated with passed listener instance from the list of hidden range listeners.
void StartListeningHiddenRange(const ScRange &rRange, ScChartHiddenRangeListener *pListener)
Start listening on hide/show change within specified cell range.
ScSheetLimits & GetSheetLimits() const
SC_DLLPUBLIC sal_uInt32 GetNumberFormat(SCCOL nCol, SCROW nRow, SCTAB nTab) const
bool ShrinkToDataArea(SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow) const
Shrink a range to only include data area.
SC_DLLPUBLIC SCCOL MaxCol() const
const ScDBData * GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const
ScRangeData * FindRangeNameBySheetAndIndex(SCTAB nTab, sal_uInt16 nIndex) const
Find a named expression / range name in either global or a local scope.
SC_DLLPUBLIC SCROW MaxRow() const
void AddUnoRefChange(sal_Int64 nId, const ScRangeList &rOldRanges)
SC_DLLPUBLIC ScChartListenerCollection * GetChartListenerCollection() const
SC_DLLPUBLIC bool InitColumnBlockPosition(sc::ColumnBlockPosition &rBlockPos, SCTAB nTab, SCCOL nCol)
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
void AddUnoObject(SfxListener &rObject)
SC_DLLPUBLIC bool HasData(SCCOL nCol, SCROW nRow, SCTAB nTab)
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const
void StartListeningArea(const ScRange &rRange, bool bGroupListening, SvtListener *pListener)
bool HasUnoRefUndo() const
bool PastingDrawFromOtherDoc() const
SfxObjectShell * GetDocumentShell() const
SC_DLLPUBLIC bool HasValueData(SCCOL nCol, SCROW nRow, SCTAB nTab) const
void AddUnoListenerCall(const css::uno::Reference< css::util::XModifyListener > &rListener, const css::lang::EventObject &rEvent)
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
void RemoveUnoObject(SfxListener &rObject)
void BroadcastUno(const SfxHint &rHint)
std::shared_ptr< Table > TableTypeRef
std::shared_ptr< ScTokenArray > TokenArrayRef
void addLinkListener(sal_uInt16 nFileId, LinkListener *pListener)
Register a new link listener to a specified external document.
ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
Get a cache table instance for specified table and table index.
void removeLinkListener(sal_uInt16 nFileId, LinkListener *pListener)
Remove an existing link listener.
ScExternalRefCache::TokenArrayRef getDoubleRefTokens(sal_uInt16 nFileId, const OUString &rTabName, const ScRange &rRange, const ScAddress *pCurPos)
Get an array of tokens that consist of the specified external cell range.
@ OH_NO_WE_ARE_GOING_TO_DIE
Matrix data type that can store values of mixed types.
svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const
bool IsStringOrEmpty(SCSIZE nIndex) const
bool IsBoolean(SCSIZE nC, SCSIZE nR) const
double GetDouble(SCSIZE nC, SCSIZE nR) const
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
bool IsValue(SCSIZE nIndex) const
SC_DLLPUBLIC bool IsReference(ScRange &rRef) const
bool HasReferences() const
void push_back(const ScRange &rRange)
bool UpdateReference(UpdateRefMode, const ScDocument *, const ScRange &rWhere, SCCOL nDx, SCROW nDy, SCTAB nDz)
static void GetStringFromXMLRangeString(OUString &rString, std::u16string_view rXMLRange, const ScDocument &rDoc)
XML Range to Calc Range.
static sal_Int32 IndexOf(std::u16string_view rString, sal_Unicode cSearchChar, sal_Int32 nOffset, sal_Unicode cQuote='\'')
static void GetTokenByOffset(OUString &rToken, std::u16string_view rString, sal_Int32 &nOffset, sal_Unicode cSeparator=' ', sal_Unicode cQuote='\'')
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
static SC_DLLPUBLIC bool ConvertToTokenArray(ScDocument &rDoc, ScTokenArray &rTokenArray, const css::uno::Sequence< css::sheet::FormulaToken > &rSequence)
Hint to restore a UNO object to its old state (used during undo).
const ScRange & GetRange() const
UpdateRefMode GetMode() const
const SfxItemPropertyMap & getPropertyMap() const
css::uno::Reference< css::frame::XModel3 > GetModel() const
css::uno::Type const & get()
const OUString & getString() const
static const SharedString & getEmptyString()
Sequence< PropertyValue > aArguments
#define LINK(Instance, Class, Member)
Sequence< sal_Int8 > aSeq
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
std::vector< sal_Int8, boost::noinit_adaptor< std::allocator< sal_Int8 > > > maData
std::unique_ptr< sal_Int32[]> pData
constexpr OUStringLiteral aData
bool SC_DLLPUBLIC isRef(const ScTokenRef &pToken)
void getRangeListFromTokens(const ScDocument *pDoc, ScRangeList &rRangeList, const ::std::vector< ScTokenRef > &pTokens, const ScAddress &rPos)
void compileRangeRepresentation(::std::vector< ScTokenRef > &rRefTokens, const OUString &rRangeStr, ScDocument &rDoc, const sal_Unicode cSep, ::formula::FormulaGrammar::Grammar eGrammar, bool bOnly3DRef=false)
Compile an array of reference tokens from a data source range string.
bool getRangeFromToken(const ScDocument *pDoc, ScRange &rRange, const ScTokenRef &pToken, const ScAddress &rPos, bool bExternal=false)
void getTokenFromRange(const ScDocument *pDoc, ScTokenRef &pToken, const ScRange &rRange)
Create a double reference token from a range object.
bool SC_DLLPUBLIC isExternalRef(const ScTokenRef &pToken)
void SC_DLLPUBLIC join(const ScDocument *pDoc, ::std::vector< ScTokenRef > &rTokens, const ScTokenRef &pToken, const ScAddress &rPos)
bool getDoubleRefDataFromToken(ScComplexRefData &rData, const ScTokenRef &pToken)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
OUString getString(const Any &_rAny)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::shared_ptr< T > make_shared(Args &&... args)
static o3tl::span< const SfxItemPropertyMapEntry > lcl_GetDataSequencePropertyMap()
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
SwNodeOffset abs(const SwNodeOffset &a)
OUString ScResId(TranslateId aId)
Complex reference (a range) into the sheet.
This is very similar to ScCellValue, except that it references the original value instead of copying ...
ScFormulaCell * getFormula() const
SCROW GetMaxRowCount() const
SCCOL GetMaxColCount() const
Single reference (one address) into the sheet.
void SetAbsCol(SCCOL nVal)
void SetAbsTab(SCTAB nVal)
void SetRowRel(bool bVal)
void SetTabRel(bool bVal)
void SetAbsRow(SCROW nVal)
void SetFlag3D(bool bVal)
void InitFlags()
No default ctor, because used in ScRawToken union, set InitFlags!
void SetColRel(bool bVal)
Store position data for column array storage.
Reference< XModel > xModel
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
::boost::intrusive_ptr< formula::FormulaToken > ScTokenRef
constexpr OUStringLiteral SC_UNONAME_TIME_BASED
constexpr OUStringLiteral SC_UNONAME_HIDDENVALUES
constexpr OUStringLiteral SC_UNONAME_ROLE
constexpr OUStringLiteral SC_UNONAME_USE_INTERNAL_DATA_PROVIDER
constexpr OUStringLiteral SC_UNONAME_INCLUDEHIDDENCELLS
constexpr OUStringLiteral SC_UNONAME_HAS_STRING_LABEL
std::unique_ptr< char[]> aBuffer