29 #include <document.hxx>
31 #include <unonames.hxx>
32 #include <globstr.hrc>
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")
72 using namespace ::
com::sun::star;
74 using ::
com::sun::star::
uno::Sequence;
75 using ::
std::unique_ptr;
77 using ::
std::distance;
78 using ::
std::shared_ptr;
88 {
u"", 0, css::uno::Type(), 0, 0 }
90 return aDataProviderPropertyMap_Impl;
100 {
u"", 0, css::uno::Type(), 0, 0 }
102 return aDataSequencePropertyMap_Impl;
105 struct lcl_appendTableNumber
107 explicit lcl_appendTableNumber( OUStringBuffer & rBuffer ) :
110 void operator() (
SCTAB nTab )
113 m_rBuffer.append( static_cast< sal_Int32 >( nTab ));
114 m_rBuffer.append(
' ' );
117 OUStringBuffer & m_rBuffer;
120 OUString lcl_createTableNumberList( const ::std::vector< SCTAB > & rTableVector )
123 ::std::for_each( rTableVector.begin(), rTableVector.end(), lcl_appendTableNumber( aBuffer ));
125 if( !aBuffer.isEmpty() )
126 aBuffer.setLength( aBuffer.getLength() - 1 );
127 return aBuffer.makeStringAndClear();
130 uno::Reference< frame::XModel > lcl_GetXModel(
const ScDocument * pDoc )
132 uno::Reference< frame::XModel >
xModel;
135 xModel.set( pObjSh->GetModel());
143 vector<std::unique_ptr<FormulaToken>> maTokens;
146 TokenTable(
const TokenTable&) =
delete;
147 const TokenTable& operator=(
const TokenTable&) =
delete;
157 mnColCount = nColCount;
158 mnRowCount = nRowCount;
159 maTokens.reserve(mnColCount*mnRowCount);
163 for (
auto & rToken : maTokens)
167 void push_back( std::unique_ptr<FormulaToken> pToken )
169 maTokens.push_back( std::move(pToken) );
170 OSL_ENSURE( maTokens.size()<=
o3tl::make_unsigned( mnColCount*mnRowCount ),
"too many tokens" );
173 sal_uInt32 getIndex(
SCCOL nCol,
SCROW nRow)
const
175 OSL_ENSURE( nCol<mnColCount,
"wrong column index" );
176 OSL_ENSURE( nRow<mnRowCount,
"wrong row index" );
177 sal_uInt32 nRet =
static_cast<sal_uInt32
>(nCol*mnRowCount + nRow);
178 OSL_ENSURE( maTokens.size()>=
o3tl::make_unsigned( mnColCount*mnRowCount ),
"too few tokens" );
182 vector<ScTokenRef> getColRanges(
const ScDocument* pDoc,
SCCOL nCol)
const;
183 vector<ScTokenRef> getRowRanges(
const ScDocument* pDoc,
SCROW nRow)
const;
184 vector<ScTokenRef> getAllRanges(
const ScDocument* pDoc)
const;
187 vector<ScTokenRef> TokenTable::getColRanges(
const ScDocument* pDoc,
SCCOL nCol)
const
189 if (nCol >= mnColCount)
190 return vector<ScTokenRef>();
192 return vector<ScTokenRef>();
194 vector<ScTokenRef> aTokens;
195 sal_uInt32 nLast = getIndex(nCol, mnRowCount-1);
196 for (sal_uInt32
i = getIndex(nCol, 0);
i <= nLast; ++
i)
198 FormulaToken*
p = maTokens[
i].get();
208 vector<ScTokenRef> TokenTable::getRowRanges(
const ScDocument* pDoc,
SCROW nRow)
const
210 if (nRow >= mnRowCount)
211 return vector<ScTokenRef>();
213 return vector<ScTokenRef>();
215 vector<ScTokenRef> aTokens;
216 sal_uInt32 nLast = getIndex(mnColCount-1, nRow);
217 for (sal_uInt32
i = getIndex(0, nRow);
i <= nLast;
i += mnRowCount)
219 FormulaToken*
p = maTokens[
i].get();
229 vector<ScTokenRef> TokenTable::getAllRanges(
const ScDocument* pDoc)
const
231 vector<ScTokenRef> aTokens;
232 sal_uInt32 nStop = mnColCount*mnRowCount;
233 for (sal_uInt32
i = 0;
i < nStop;
i++)
235 FormulaToken*
p = maTokens[
i].get();
245 typedef std::map<SCROW, std::unique_ptr<FormulaToken>> FormulaTokenMap;
246 typedef std::map<sal_uInt32, FormulaTokenMap> FormulaTokenMapMap;
248 class Chart2PositionMap
251 Chart2PositionMap(
SCCOL nColCount,
SCROW nRowCount,
252 bool bFillRowHeader,
bool bFillColumnHeader, FormulaTokenMapMap& rCols,
254 ~Chart2PositionMap();
256 SCCOL getDataColCount()
const {
return mnDataColCount; }
257 SCROW getDataRowCount()
const {
return mnDataRowCount; }
259 vector<ScTokenRef> getLeftUpperCornerRanges()
const;
260 vector<ScTokenRef> getAllColHeaderRanges()
const;
261 vector<ScTokenRef> getAllRowHeaderRanges()
const;
263 vector<ScTokenRef> getColHeaderRanges(
SCCOL nChartCol)
const;
264 vector<ScTokenRef> getRowHeaderRanges(
SCROW nChartRow)
const;
266 vector<ScTokenRef> getDataColRanges(
SCCOL nCol)
const;
267 vector<ScTokenRef> getDataRowRanges(
SCROW nRow)
const;
271 SCCOL mnDataColCount;
272 SCROW mnDataRowCount;
274 TokenTable maLeftUpperCorner;
275 TokenTable maColHeaders;
276 TokenTable maRowHeaders;
280 Chart2PositionMap::Chart2PositionMap(
SCCOL nAllColCount,
SCROW nAllRowCount,
281 bool bFillRowHeader,
bool bFillColumnHeader, FormulaTokenMapMap& rCols,
ScDocument* pDoc)
289 SCROW nHeaderRowCount = (bFillColumnHeader && nAllColCount && nAllRowCount) ? 1 : 0;
290 SCCOL nHeaderColCount = (bFillRowHeader && nAllColCount && nAllRowCount) ? 1 : 0;
292 if( pDoc && (nHeaderColCount || nHeaderRowCount ) )
295 SCROW nMaxHeaderRow = nAllRowCount;
297 for (
auto it = rCols.begin(); it != rCols.end(); ++it, ++nCol)
300 if (nCol < nHeaderColCount)
303 const auto& rCol = *it;
305 bool bFoundValuesInCol =
false;
306 bool bFoundAnythingInCol =
false;
308 for (
auto it2 = rCol.second.begin(); it2 != rCol.second.end(); ++it2, ++nRow)
310 const auto& rCell = *it2;
313 if (nRow < nHeaderRowCount || !rCell.second)
317 bool bExternal =
false;
321 ScTokenRef pSharedToken(rCell.second->Clone());
323 SCCOL nCol1=0, nCol2=0;
324 SCROW nRow1=0, nRow2=0;
325 SCTAB nTab1=0, nTab2=0;
326 aRange.
GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
330 bFoundValuesInCol =
true;
331 nMaxHeaderRow = std::min(nMaxHeaderRow, nRow);
334 if ( pDoc->
HasData( nCol1, nRow1, nTab1 ) )
337 bFoundAnythingInCol =
true;
342 nMaxHeaderRow = std::min(nMaxHeaderRow, nRow);
346 if (nHeaderColCount && !bFoundValuesInCol && bFoundAnythingInCol && nCol == nHeaderColCount)
356 nHeaderRowCount = nMaxHeaderRow;
360 mnDataColCount = nAllColCount - nHeaderColCount;
361 mnDataRowCount = nAllRowCount - nHeaderRowCount;
363 maLeftUpperCorner.init(nHeaderColCount,nHeaderRowCount);
364 maColHeaders.init(mnDataColCount,nHeaderRowCount);
365 maRowHeaders.init(nHeaderColCount,mnDataRowCount);
366 maData.init(mnDataColCount,mnDataRowCount);
368 FormulaTokenMapMap::iterator it1 = rCols.begin();
369 for (
SCCOL nCol = 0; nCol < nAllColCount; ++nCol)
371 if (it1 != rCols.end())
373 FormulaTokenMap& rCol = it1->second;
374 FormulaTokenMap::iterator it2 = rCol.begin();
375 for (
SCROW nRow = 0; nRow < nAllRowCount; ++nRow)
377 std::unique_ptr<FormulaToken> pToken;
378 if (it2 != rCol.end())
380 pToken = std::move(it2->second);
384 if( nCol < nHeaderColCount )
386 if( nRow < nHeaderRowCount )
387 maLeftUpperCorner.push_back(std::move(pToken));
389 maRowHeaders.push_back(std::move(pToken));
391 else if( nRow < nHeaderRowCount )
392 maColHeaders.push_back(std::move(pToken));
394 maData.push_back(std::move(pToken));
401 Chart2PositionMap::~Chart2PositionMap()
403 maLeftUpperCorner.clear();
404 maColHeaders.clear();
405 maRowHeaders.clear();
409 vector<ScTokenRef> Chart2PositionMap::getLeftUpperCornerRanges()
const
411 return maLeftUpperCorner.getAllRanges(mpDoc);
413 vector<ScTokenRef> Chart2PositionMap::getAllColHeaderRanges()
const
415 return maColHeaders.getAllRanges(mpDoc);
417 vector<ScTokenRef> Chart2PositionMap::getAllRowHeaderRanges()
const
419 return maRowHeaders.getAllRanges(mpDoc);
421 vector<ScTokenRef> Chart2PositionMap::getColHeaderRanges(
SCCOL nCol)
const
423 return maColHeaders.getColRanges(mpDoc, nCol);
425 vector<ScTokenRef> Chart2PositionMap::getRowHeaderRanges(
SCROW nRow)
const
427 return maRowHeaders.getRowRanges(mpDoc, nRow);
430 vector<ScTokenRef> Chart2PositionMap::getDataColRanges(
SCCOL nCol)
const
432 return maData.getColRanges(mpDoc, nCol);
435 vector<ScTokenRef> Chart2PositionMap::getDataRowRanges(
SCROW nRow)
const
437 return maData.getRowRanges(mpDoc, nRow);
444 class Chart2Positioner
456 Chart2Positioner(
const Chart2Positioner&) =
delete;
457 const Chart2Positioner& operator=(
const Chart2Positioner&) =
delete;
459 Chart2Positioner(
ScDocument* pDoc,
const vector<ScTokenRef>& rRefTokens) :
460 mrRefTokens(rRefTokens),
467 mbDummyUpperLeft(
false)
471 void setHeaders(
bool bColHeaders,
bool bRowHeaders)
473 mbColHeaders = bColHeaders;
474 mbRowHeaders = bRowHeaders;
477 Chart2PositionMap* getPositionMap()
480 return mpPositionMap.get();
484 void invalidateGlue();
487 void createPositionMap();
490 const vector<ScTokenRef>& mrRefTokens;
491 std::unique_ptr<Chart2PositionMap> mpPositionMap;
498 bool mbDummyUpperLeft:1;
501 void Chart2Positioner::invalidateGlue()
503 meGlue = GLUETYPE_NA;
504 mpPositionMap.reset();
507 void Chart2Positioner::glueState()
509 if (meGlue != GLUETYPE_NA)
512 mbDummyUpperLeft =
false;
513 if (mrRefTokens.size() <= 1)
521 meGlue = GLUETYPE_NONE;
523 meGlue = GLUETYPE_COLS;
543 for (
const auto& rxToken : mrRefTokens)
548 if (n1 > mpDoc->MaxCol())
549 n1 = mpDoc->MaxCol();
550 if (n2 > mpDoc->MaxCol())
551 n2 = mpDoc->MaxCol();
553 mnStartCol =
static_cast<SCCOL>(n1);
555 nEndCol =
static_cast<SCCOL>(n2);
559 if (n1 > mpDoc->MaxRow())
560 n1 = mpDoc->MaxRow();
561 if (n2 > mpDoc->MaxRow())
562 n2 = mpDoc->MaxRow();
565 mnStartRow =
static_cast<SCROW>(n1);
567 nEndRow =
static_cast<SCROW>(n2);
570 if (mnStartCol == nEndCol)
573 meGlue = GLUETYPE_ROWS;
577 if (mnStartRow == nEndRow)
580 meGlue = GLUETYPE_COLS;
585 SCCOL nC = nEndCol - mnStartCol + 1;
588 SCROW nR = nEndRow - mnStartRow + 1;
591 if ((nC <= 0) || (nR <= 0))
599 calcGlueState(nC, nR);
604 void Chart2Positioner::calcGlueState(
SCCOL nColSize,
SCROW nRowSize)
610 sal_uInt32 nCR =
static_cast<sal_uInt32
>(nColSize*nRowSize);
612 vector<State> aCellStates(nCR, Hole);
615 for (
const auto& rxToken : mrRefTokens)
623 for (
SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
624 for (
SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
626 size_t i = nCol*nRowSize + nRow;
627 aCellStates[i] = Occupied;
638 bool bGlueCols =
false;
639 for (
SCCOL nCol = 0; bGlue && nCol < nColSize; ++nCol)
641 for (
SCROW nRow = 0; bGlue && nRow < nRowSize; ++nRow)
643 size_t i = nCol*nRowSize + nRow;
644 if (aCellStates[i] == Occupied)
646 if (nCol == 0 || nRow == 0)
652 aCellStates[i] =
Free;
654 size_t nLast = (nCol+1)*nRowSize - 1;
655 if (bGlue && aCellStates[nLast] == Free)
658 aCellStates[nLast] =
Glue;
663 bool bGlueRows =
false;
664 for (
SCROW nRow = 0; bGlue && nRow < nRowSize; ++nRow)
667 for (
SCCOL nCol = 0; bGlue && nCol < nColSize; ++nCol, i += nRowSize)
669 if (aCellStates[i] == Occupied)
671 if (nCol == 0 || nRow == 0)
677 aCellStates[i] =
Free;
679 i = (nColSize-1)*nRowSize + nRow;
680 if (bGlue && aCellStates[i] == Free)
683 aCellStates[i] =
Glue;
689 for (sal_uInt32 n = 1; bGlue &&
n < nCR; ++
n, ++i)
690 if (aCellStates[i] == Hole)
695 if (bGlueCols && bGlueRows)
696 meGlue = GLUETYPE_BOTH;
698 meGlue = GLUETYPE_ROWS;
700 meGlue = GLUETYPE_COLS;
701 if (aCellStates.front() != Occupied)
702 mbDummyUpperLeft =
true;
705 meGlue = GLUETYPE_NONE;
708 void Chart2Positioner::createPositionMap()
710 if (meGlue == GLUETYPE_NA && mpPositionMap)
711 mpPositionMap.reset();
718 bool bNoGlue = (meGlue == GLUETYPE_NONE);
719 FormulaTokenMapMap aCols;
720 SCROW nNoGlueRow = 0;
724 sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
727 aTabName = pToken->GetString();
738 for (
SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
743 sal_uInt32 nInsCol = (
static_cast<sal_uInt32
>(nTab) << 16) |
744 (bNoGlue ? 0 :
static_cast<sal_uInt32
>(nCol1));
746 for (
SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nInsCol)
748 FormulaTokenMap& rCol = aCols[nInsCol];
750 auto nInsRow = bNoGlue ? nNoGlueRow : nRow1;
751 for (
SCROW nRow = nRow1; nRow <= nRow2; ++nRow, ++nInsRow)
763 auto& rCell = rCol[nInsRow];
774 nNoGlueRow += nRow2 - nRow1 + 1;
777 bool bFillRowHeader = mbRowHeaders;
778 bool bFillColumnHeader = mbColHeaders;
780 SCSIZE nAllColCount =
static_cast<SCSIZE>(aCols.size());
784 FormulaTokenMap& rCol = aCols.begin()->second;
785 if (mbDummyUpperLeft)
786 rCol.try_emplace( 0,
nullptr );
787 nAllRowCount =
static_cast<SCSIZE>(rCol.size());
790 if( nAllColCount!=0 && nAllRowCount!=0 )
794 FormulaTokenMap& rFirstCol = aCols.begin()->second;
795 for (
const auto& rFirstColEntry : rFirstCol)
797 SCROW nKey = rFirstColEntry.first;
798 for (
auto& rEntry : aCols)
800 FormulaTokenMap& rCol = rEntry.second;
801 rCol.try_emplace( nKey,
nullptr );
807 new Chart2PositionMap(
808 static_cast<SCCOL>(nAllColCount), static_cast<SCROW>(nAllRowCount),
809 bFillRowHeader, bFillColumnHeader, aCols, mpDoc));
815 class Tokens2RangeString
822 mcRangeSep(cRangeSep),
831 aCompiler.CreateStringFromToken(aStr, rToken.get());
835 mpRangeStr->append(mcRangeSep);
836 mpRangeStr->append(aStr);
841 rStr = mpRangeStr->makeStringAndClear();
845 shared_ptr<OUStringBuffer> mpRangeStr;
847 FormulaGrammar::Grammar meGrammar;
860 class Tokens2RangeStringXML
863 explicit Tokens2RangeStringXML(
ScDocument& rDoc) :
875 mpRangeStr->append(mcRangeSep);
878 bool bValidToken = splitRangeToken(*mpDoc, rToken, aStart, aEnd);
880 if (!bValidToken && rToken->GetType() ==
svIndex && rToken->GetOpCode() ==
ocName)
882 ScRangeData* pNameRange = mpDoc->FindRangeNameBySheetAndIndex(rToken->GetSheet(), rToken->GetIndex());
886 bValidToken = splitRangeToken(*mpDoc, aTempToken, aStart, aEnd);
890 OSL_ENSURE(bValidToken,
"invalid token");
897 aCompiler.CreateStringFromToken(aStr, aStart.get());
898 mpRangeStr->append(aStr);
900 mpRangeStr->append(mcAddrSep);
903 aCompiler.CreateStringFromToken(aStr, aEnd.get());
904 mpRangeStr->append(aStr);
910 rStr = mpRangeStr->makeStringAndClear();
918 OSL_ENSURE(bIsRefToken,
"invalid token");
922 sal_uInt16 nFileId = bExternal ? pToken->GetIndex() : 0;
925 aTabName = pToken->GetString();
928 setRelative(aData.
Ref1);
929 setRelative(aData.
Ref2);
955 shared_ptr<OUStringBuffer> mpRangeStr;
962 void lcl_convertTokensToString(OUString& rStr,
const vector<ScTokenRef>& rTokens,
ScDocument& rDoc)
965 FormulaGrammar::Grammar eGrammar = rDoc.
GetGrammar();
966 Tokens2RangeString func(rDoc, eGrammar, cRangeSep);
967 func = ::std::for_each(rTokens.begin(), rTokens.end(), func);
968 func.getString(rStr);
977 , m_aPropSet(lcl_GetDataProviderPropertyMap())
978 , m_bIncludeHiddenCells( true)
994 if ( rHint.
GetId() == SfxHintId::Dying )
1006 OUString aRangeRepresentation;
1007 for(
const auto& rArgument : aArguments)
1009 if ( rArgument.Name ==
"CellRangeRepresentation" )
1011 rArgument.Value >>= aRangeRepresentation;
1015 vector<ScTokenRef> aTokens;
1019 return !aTokens.empty();
1025 uno::Reference< chart2::data::XLabeledDataSequence > lcl_createLabeledDataSequenceFromTokens(
1026 vector< ScTokenRef > && aValueTokens, vector< ScTokenRef > && aLabelTokens,
1029 uno::Reference< chart2::data::XLabeledDataSequence > xResult;
1030 bool bHasValues = !aValueTokens.empty();
1031 bool bHasLabel = !aLabelTokens.empty();
1032 if( bHasValues || bHasLabel )
1037 if ( xContext.is() )
1039 xResult.set( chart2::data::LabeledDataSequence::create(xContext), uno::UNO_QUERY_THROW );
1043 uno::Reference< chart2::data::XDataSequence > xSeq(
new ScChart2DataSequence( pDoc, std::move(aValueTokens), bIncludeHiddenCells ) );
1044 xResult->setValues( xSeq );
1049 uno::Reference< chart2::data::XDataSequence > xLabelSeq(
new ScChart2DataSequence( pDoc, std::move(aLabelTokens),
true ) );
1050 xResult->setLabel( xLabelSeq );
1053 catch(
const uno::Exception& )
1069 bool lcl_addUpperLeftCornerIfMissing(
const ScDocument* pDoc, vector<ScTokenRef>& rRefTokens,
1070 SCROW nCornerRowCount,
SCCOL nCornerColumnCount)
1075 if (rRefTokens.empty())
1084 sal_uInt16 nFileId = 0;
1086 bool bExternal =
false;
1088 vector<ScTokenRef>::const_iterator itr = rRefTokens.begin(), itrEnd = rRefTokens.end();
1092 switch (pToken->GetType())
1097 nMinCol = rData.
Col();
1098 nMinRow = rData.
Row();
1099 nMaxCol = rData.
Col();
1100 nMaxRow = rData.
Row();
1117 nMinCol = rData.
Col();
1118 nMinRow = rData.
Row();
1119 nMaxCol = rData.
Col();
1120 nMaxRow = rData.
Row();
1122 nFileId = pToken->GetIndex();
1123 aExtTabName = pToken->GetString();
1135 nFileId = pToken->GetIndex();
1136 aExtTabName = pToken->GetString();
1147 for (++itr; itr != itrEnd; ++itr)
1150 switch (pToken->GetType())
1156 nMinCol =
min(nMinCol, rData.
Col());
1157 nMinRow =
min(nMinRow, rData.
Row());
1158 nMaxCol =
max(nMaxCol, rData.
Col());
1159 nMaxRow =
max(nMaxRow, rData.
Row());
1160 if (nTab != rData.
Tab() || bExternal)
1178 if (nTab != rData.
Ref1.
Tab() || bExternal)
1187 if (nFileId != pToken->GetIndex() || aExtTabName != pToken->GetString())
1192 nMinCol =
min(nMinCol, rData.
Col());
1193 nMinRow =
min(nMinRow, rData.
Row());
1194 nMaxCol =
max(nMaxCol, rData.
Col());
1195 nMaxRow =
max(nMaxRow, rData.
Row());
1203 if (nFileId != pToken->GetIndex() || aExtTabName != pToken->GetString())
1225 if (nMinRow >= nMaxRow || nMinCol >= nMaxCol ||
1226 nMinRow >= rSheetLimits.GetMaxRowCount() || nMinCol >= rSheetLimits.GetMaxColCount() ||
1227 nMaxRow >= rSheetLimits.GetMaxRowCount() || nMaxCol >= rSheetLimits.GetMaxColCount())
1238 bool bRight =
false, bBottom =
false, bDiagonal =
false;
1239 for (
const auto& rxToken : rRefTokens)
1241 switch (rxToken->GetType())
1247 if (rData.
Col() == nMinCol && rData.
Row() == nMinRow)
1251 if (rData.
Col() == nMinCol+nCornerColumnCount && rData.
Row() == nMinRow)
1254 if (rData.
Col() == nMinCol && rData.
Row() == nMinRow+nCornerRowCount)
1257 if (rData.
Col() == nMinCol+nCornerColumnCount && rData.
Row() == nMinRow+nCornerRowCount)
1267 if (r1.
Col() <= nMinCol && nMinCol <= r2.
Col() &&
1268 r1.
Row() <= nMinRow && nMinRow <= r2.
Row())
1272 if (r1.
Col() <= nMinCol+nCornerColumnCount && nMinCol+nCornerColumnCount <= r2.
Col() &&
1273 r1.
Row() <= nMinRow && nMinRow <= r2.
Row())
1276 if (r1.
Col() <= nMinCol && nMinCol <= r2.
Col() &&
1277 r1.
Row() <= nMinRow+nCornerRowCount && nMinRow+nCornerRowCount <= r2.
Row())
1280 if (r1.
Col() <= nMinCol+nCornerColumnCount && nMinCol+nCornerColumnCount <= r2.
Col() &&
1281 r1.
Row() <= nMinRow+nCornerRowCount && nMinRow+nCornerRowCount <= r2.
Row())
1290 if (!bRight || !bBottom || !bDiagonal)
1301 if( nCornerRowCount==1 && nCornerColumnCount==1 )
1318 aDataEnd.IncCol(nCornerColumnCount-1);
1319 aDataEnd.IncRow(nCornerRowCount-1);
1339 #define SHRINK_RANGE_THRESHOLD 10000
1341 class ShrinkRefTokenToDataRange
1345 explicit ShrinkRefTokenToDataRange(
ScDocument* pDoc) : mpDoc(pDoc) {}
1368 for (
SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
1373 nMinCol = std::min(nMinCol, nCol1);
1374 nMinRow = std::min(nMinRow, nRow1);
1375 nMaxCol = std::max(nMaxCol, nCol2);
1376 nMaxRow = std::max(nMaxRow, nRow2);
1380 if (s.
Col() < nMinCol)
1382 if (s.
Row() < nMinRow)
1384 if (e.
Col() > nMaxCol)
1386 if (e.
Row() > nMaxRow)
1391 void shrinkToDataRange(
ScDocument* pDoc, vector<ScTokenRef>& rRefTokens)
1393 std::for_each(rRefTokens.begin(), rRefTokens.end(), ShrinkRefTokenToDataRange(pDoc));
1398 uno::Reference< chart2::data::XDataSource> SAL_CALL
1400 const uno::Sequence< beans::PropertyValue >& aArguments )
1404 throw uno::RuntimeException();
1412 bool bCategories =
false;
1413 bool bOrientCol =
true;
1414 OUString aRangeRepresentation;
1415 uno::Sequence< sal_Int32 > aSequenceMapping;
1416 bool bTimeBased =
false;
1417 for(
const auto& rArgument : aArguments)
1419 if ( rArgument.Name ==
"DataRowSource" )
1421 chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS;
1422 if( ! (rArgument.Value >>= eSource))
1424 sal_Int32 nSource(0);
1425 if( rArgument.Value >>= nSource )
1426 eSource =
static_cast< chart::ChartDataRowSource
>( nSource );
1428 bOrientCol = (eSource == chart::ChartDataRowSource_COLUMNS);
1430 else if ( rArgument.Name ==
"FirstCellAsLabel" )
1432 bLabel = ::cppu::any2bool(rArgument.Value);
1434 else if ( rArgument.Name ==
"HasCategories" )
1436 bCategories = ::cppu::any2bool(rArgument.Value);
1438 else if ( rArgument.Name ==
"CellRangeRepresentation" )
1440 rArgument.Value >>= aRangeRepresentation;
1442 else if ( rArgument.Name ==
"SequenceMapping" )
1444 rArgument.Value >>= aSequenceMapping;
1446 else if ( rArgument.Name ==
"TimeBased" )
1448 rArgument.Value >>= bTimeBased;
1452 vector<ScTokenRef> aRefTokens;
1456 if (aRefTokens.empty())
1458 throw lang::IllegalArgumentException();
1461 SCTAB nTimeBasedEnd = 0;
1465 for(
const auto& rxToken : aRefTokens)
1474 nTimeBasedStart = std::min(nTimeBasedStart, s.
Tab());
1475 nTimeBasedEnd = std::min(nTimeBasedEnd, e.
Tab());
1486 lcl_addUpperLeftCornerIfMissing(
m_pDocument, aRefTokens, 1, 1);
1488 bool bColHeaders = (bOrientCol ? bLabel : bCategories );
1489 bool bRowHeaders = (bOrientCol ? bCategories : bLabel );
1491 Chart2Positioner aChPositioner(
m_pDocument, aRefTokens);
1492 aChPositioner.setHeaders(bColHeaders, bRowHeaders);
1494 const Chart2PositionMap* pChartMap = aChPositioner.getPositionMap();
1500 ::std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aSeqs;
1505 vector<ScTokenRef> aValueTokens;
1507 aValueTokens = pChartMap->getAllRowHeaderRanges();
1509 aValueTokens = pChartMap->getAllColHeaderRanges();
1511 vector<ScTokenRef> aLabelTokens(
1512 pChartMap->getLeftUpperCornerRanges());
1514 uno::Reference< chart2::data::XLabeledDataSequence > xCategories = lcl_createLabeledDataSequenceFromTokens(
1516 if ( xCategories.is() )
1518 aSeqs.push_back( xCategories );
1523 sal_Int32
nCount = bOrientCol ? pChartMap->getDataColCount() : pChartMap->getDataRowCount();
1524 for (sal_Int32 i = 0; i < nCount; ++i)
1526 vector<ScTokenRef> aValueTokens;
1527 vector<ScTokenRef> aLabelTokens;
1530 aValueTokens = pChartMap->getDataColRanges(static_cast<SCCOL>(i));
1531 aLabelTokens = pChartMap->getColHeaderRanges(static_cast<SCCOL>(i));
1535 aValueTokens = pChartMap->getDataRowRanges(static_cast<SCROW>(i));
1536 aLabelTokens = pChartMap->getRowHeaderRanges(static_cast<SCROW>(i));
1538 uno::Reference< chart2::data::XLabeledDataSequence > xChartSeries = lcl_createLabeledDataSequenceFromTokens(
1540 if ( xChartSeries.is() && xChartSeries->getValues().is() && xChartSeries->getValues()->getData().hasElements() )
1542 aSeqs.push_back( xChartSeries );
1549 ::std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aSeqVector;
1550 aSeqVector.reserve(aSeqs.size());
1551 for (
auto const&
aSeq : aSeqs)
1553 aSeqVector.push_back(
aSeq);
1556 for(
const sal_Int32 nNewIndex : std::as_const(aSequenceMapping) )
1559 ::std::vector< uno::Reference< chart2::data::XLabeledDataSequence > >::size_type nOldIndex( static_cast< sal_uInt32 >( nNewIndex ) );
1560 if( nOldIndex < aSeqVector.size() )
1562 pDS->AddLabeledSequence( aSeqVector[nOldIndex] );
1563 aSeqVector[nOldIndex] =
nullptr;
1567 for(
const uno::Reference< chart2::data::XLabeledDataSequence >& xSeq : aSeqVector)
1571 pDS->AddLabeledSequence( xSeq );
1585 class InsertTabNumber
1593 void operator() (
const ScTokenRef& pToken)
const
1599 mpTabNumVector->push_back(r.
Tab());
1602 void getVector(vector<SCTAB>& rVector)
1604 mpTabNumVector->swap(rVector);
1607 shared_ptr< vector<SCTAB> > mpTabNumVector;
1614 void initRangeAnalyzer(
const ScDocument* pDoc,
const vector<ScTokenRef>& rTokens );
1615 void analyzeRange( sal_Int32& rnDataInRows, sal_Int32& rnDataInCols,
1616 bool& rbRowSourceAmbiguous )
const;
1617 bool inSameSingleRow(
const RangeAnalyzer& rOther );
1618 bool inSameSingleColumn(
const RangeAnalyzer& rOther );
1619 SCROW getRowCount()
const {
return mnRowCount; }
1620 SCCOL getColumnCount()
const {
return mnColumnCount; }
1626 SCCOL mnColumnCount;
1628 SCCOL mnStartColumn;
1632 RangeAnalyzer::RangeAnalyzer()
1634 , mbAmbiguous(
false)
1642 void RangeAnalyzer::initRangeAnalyzer(
const ScDocument* pDoc,
const vector<ScTokenRef>& rTokens )
1649 if( rTokens.empty() )
1658 StackVar eVar = aRefToken->GetType();
1659 if (eVar == svDoubleRef || eVar == svExternalDoubleRef)
1666 if( mnStartColumn == -1 )
1680 else if (eVar == svSingleRef || eVar == svExternalSingleRef)
1683 mnColumnCount = std::max<SCCOL>( mnColumnCount, 1);
1684 mnRowCount = std::max<SCROW>( mnRowCount, 1);
1685 if( mnStartColumn == -1 )
1687 mnStartColumn = r.
Col();
1688 mnStartRow = r.
Row();
1692 if (mnStartColumn != r.
Col() && mnStartRow != r.
Row())
1696 else if (eVar == svIndex && aRefToken->GetOpCode() ==
ocName)
1702 mnColumnCount = std::max<SCCOL>(mnColumnCount,
static_cast<SCCOL>(
abs(aRange.
aEnd.
Col() - aRange.
aStart.
Col()) + 1));
1704 if (mnStartColumn == -1)
1723 void RangeAnalyzer::analyzeRange( sal_Int32& rnDataInRows,
1724 sal_Int32& rnDataInCols,
1725 bool& rbRowSourceAmbiguous )
const
1727 if(!mbEmpty && !mbAmbiguous)
1729 if( mnRowCount==1 && mnColumnCount>1 )
1731 else if( mnColumnCount==1 && mnRowCount>1 )
1733 else if( mnRowCount>1 && mnColumnCount>1 )
1734 rbRowSourceAmbiguous =
true;
1737 rbRowSourceAmbiguous =
true;
1740 bool RangeAnalyzer::inSameSingleRow(
const RangeAnalyzer& rOther )
1742 return mnStartRow==rOther.mnStartRow &&
1743 mnRowCount==1 && rOther.mnRowCount==1;
1746 bool RangeAnalyzer::inSameSingleColumn(
const RangeAnalyzer& rOther )
1748 return mnStartColumn==rOther.mnStartColumn &&
1749 mnColumnCount==1 && rOther.mnColumnCount==1;
1752 std::pair<OUString, OUString> constructKey(
const uno::Reference< chart2::data::XLabeledDataSequence>& xNew)
1754 std::pair<OUString, OUString> aKey;
1755 if( xNew->getLabel().is() )
1756 aKey.first = xNew->getLabel()->getSourceRangeRepresentation();
1757 if( xNew->getValues().is() )
1758 aKey.second = xNew->getValues()->getSourceRangeRepresentation();
1766 const uno::Reference< chart2::data::XDataSource >& xDataSource )
1772 ::std::vector< beans::PropertyValue > aResult;
1773 bool bRowSourceDetected =
false;
1774 bool bFirstCellAsLabel =
false;
1775 bool bHasCategories =
false;
1778 bool bHasCategoriesLabels =
false;
1779 vector<ScTokenRef> aAllCategoriesValuesTokens;
1780 vector<ScTokenRef> aAllSeriesLabelTokens;
1782 chart::ChartDataRowSource eRowSource = chart::ChartDataRowSource_COLUMNS;
1784 vector<ScTokenRef> aAllTokens;
1789 OSL_ENSURE(
m_pDocument,
"No Document -> no detectArguments" );
1793 sal_Int32 nDataInRows = 0;
1794 sal_Int32 nDataInCols = 0;
1795 bool bRowSourceAmbiguous =
false;
1797 const Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences());
1798 const sal_Int32
nCount( aSequences.getLength());
1799 RangeAnalyzer aPrevLabel,aPrevValues;
1800 for(
const uno::Reference< chart2::data::XLabeledDataSequence >& xLS : aSequences )
1804 bool bThisIsCategories =
false;
1807 uno::Reference< beans::XPropertySet > xSeqProp( xLS->getValues(), uno::UNO_QUERY );
1809 if( xSeqProp.is() && (xSeqProp->getPropertyValue(
"Role") >>= aRole) &&
1810 aRole ==
"categories" )
1811 bThisIsCategories = bHasCategories =
true;
1814 RangeAnalyzer
aLabel,aValues;
1816 uno::Reference< chart2::data::XDataSequence > xLabel( xLS->getLabel());
1819 bFirstCellAsLabel =
true;
1820 vector<ScTokenRef> aTokens;
1825 for (
const auto& rxToken : aTokens)
1827 if (rxToken->GetType() ==
svIndex && rxToken->GetOpCode() ==
ocName)
1840 if(!bThisIsCategories)
1843 if(bThisIsCategories)
1844 bHasCategoriesLabels=
true;
1847 uno::Reference< chart2::data::XDataSequence > xValues( xLS->getValues());
1850 vector<ScTokenRef> aTokens;
1855 for (
const auto& rxToken : aTokens)
1857 if (rxToken->GetType() ==
svIndex && rxToken->GetOpCode() ==
ocName)
1870 if(bThisIsCategories)
1875 if(!bThisIsCategories ||
nCount==1)
1877 if (!bRowSourceAmbiguous)
1879 aValues.analyzeRange(nDataInRows,nDataInCols,bRowSourceAmbiguous);
1880 aLabel.analyzeRange(nDataInRows,nDataInCols,bRowSourceAmbiguous);
1881 if (nDataInRows > 1 && nDataInCols > 1)
1882 bRowSourceAmbiguous =
true;
1883 else if( !bRowSourceAmbiguous && !nDataInRows && !nDataInCols )
1885 if( aValues.inSameSingleColumn( aLabel ) )
1887 else if( aValues.inSameSingleRow( aLabel ) )
1892 if( aValues.inSameSingleColumn( aPrevValues ) )
1894 else if( aValues.inSameSingleRow( aPrevValues ) )
1896 else if( aLabel.inSameSingleColumn( aPrevLabel ) )
1898 else if( aLabel.inSameSingleRow( aPrevLabel ) )
1904 aPrevValues=aValues;
1909 if (!bRowSourceAmbiguous)
1911 bRowSourceDetected =
true;
1912 eRowSource = ( nDataInCols > 0
1913 ? chart::ChartDataRowSource_COLUMNS
1914 : chart::ChartDataRowSource_ROWS );
1919 eRowSource = ( nDataInRows > nDataInCols
1920 ? chart::ChartDataRowSource_ROWS
1921 : chart::ChartDataRowSource_COLUMNS );
1928 vector<SCTAB> aTableNumVector;
1929 InsertTabNumber func;
1930 func = ::std::for_each(aAllTokens.begin(), aAllTokens.end(), func);
1931 func.getVector(aTableNumVector);
1932 aResult.emplace_back(
"TableNumberList", -1,
1933 uno::Any( lcl_createTableNumberList( aTableNumVector ) ),
1934 beans::PropertyState_DIRECT_VALUE );
1937 if( bRowSourceDetected )
1940 aResult.emplace_back(
"DataRowSource", -1,
1941 uno::Any( eRowSource ), beans::PropertyState_DIRECT_VALUE );
1943 aResult.emplace_back(
"HasCategories", -1,
1944 uno::Any( bHasCategories ), beans::PropertyState_DIRECT_VALUE );
1946 aResult.emplace_back(
"FirstCellAsLabel", -1,
1947 uno::Any( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE );
1951 if (bRowSourceDetected && bFirstCellAsLabel && bHasCategories && !bHasCategoriesLabels )
1953 RangeAnalyzer aTop,aLeft;
1954 if( eRowSource==chart::ChartDataRowSource_COLUMNS )
1956 aTop.initRangeAnalyzer(
m_pDocument, aAllSeriesLabelTokens);
1957 aLeft.initRangeAnalyzer(
m_pDocument, aAllCategoriesValuesTokens);
1961 aTop.initRangeAnalyzer(
m_pDocument, aAllCategoriesValuesTokens);
1962 aLeft.initRangeAnalyzer(
m_pDocument, aAllSeriesLabelTokens);
1964 lcl_addUpperLeftCornerIfMissing(
m_pDocument, aAllTokens, aTop.getRowCount(), aLeft.getColumnCount());
1968 lcl_convertTokensToString(sRangeRep, aAllTokens, *
m_pDocument);
1971 aResult.emplace_back(
"CellRangeRepresentation", -1,
1972 uno::Any( sRangeRep ), beans::PropertyState_DIRECT_VALUE );
1975 bool const bSequencesReordered =
true;
1976 if( bSequencesReordered && bRowSourceDetected )
1978 bool bDifferentIndexes =
false;
1980 std::vector< sal_Int32 > aSequenceMappingVector;
1982 uno::Reference< chart2::data::XDataSource > xCompareDataSource;
1987 catch(
const lang::IllegalArgumentException & )
1993 if( xDataSource.is() && xCompareDataSource.is() )
1995 const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> >& aOldSequences =
1996 xCompareDataSource->getDataSequences();
1997 const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> >& aNewSequences =
1998 xDataSource->getDataSequences();
2000 std::map<std::pair<OUString, OUString>,sal_Int32> aOldEntryToIndex;
2003 const uno::Reference< chart2::data::XLabeledDataSequence>& xOld( aOldSequences[
nIndex] );
2006 std::pair<OUString, OUString> aKey = constructKey(xOld);
2007 aOldEntryToIndex[aKey] = nIndex;
2011 for( sal_Int32 nNewIndex = 0, n = aNewSequences.getLength(); nNewIndex < n; nNewIndex++ )
2013 const uno::Reference< chart2::data::XLabeledDataSequence>& xNew( aNewSequences[nNewIndex] );
2017 std::pair<OUString, OUString> aKey = constructKey(xNew);
2018 if (aOldEntryToIndex.find(aKey) == aOldEntryToIndex.end())
2021 sal_Int32 nOldIndex = aOldEntryToIndex[aKey];
2022 if( nOldIndex != nNewIndex )
2023 bDifferentIndexes =
true;
2025 aSequenceMappingVector.push_back(nOldIndex);
2029 if( bDifferentIndexes && !aSequenceMappingVector.empty() )
2031 aResult.emplace_back(
"SequenceMapping", -1,
2033 , beans::PropertyState_DIRECT_VALUE );
2049 vector<ScTokenRef> aTokens;
2053 return !aTokens.empty();
2056 uno::Reference< chart2::data::XDataSequence > SAL_CALL
2058 const OUString& aRangeRepresentation )
2061 uno::Reference< chart2::data::XDataSequence > xResult;
2063 OSL_ENSURE(
m_pDocument,
"No Document -> no createDataSequenceByRangeRepresentation" );
2064 if(!
m_pDocument || aRangeRepresentation.isEmpty())
2067 vector<ScTokenRef> aRefTokens;
2071 if (aRefTokens.empty())
2081 uno::Reference<chart2::data::XDataSequence> SAL_CALL
2083 const OUString& ,
const OUString& ,
2086 return uno::Reference<chart2::data::XDataSequence>();
2091 uno::Reference< sheet::XRangeSelection > xResult;
2095 xResult.set( xModel->getCurrentController(), uno::UNO_QUERY );
2101 const Sequence<sheet::FormulaToken>& aTokens )
2103 if (!aTokens.hasElements())
2110 sal_uInt16
n = aCode.
GetLen();
2119 switch (
p->GetType())
2123 switch (
p->GetOpCode())
2156 uno::Reference<chart2::data::XDataSequence> SAL_CALL
2158 const Sequence<sheet::FormulaToken>& aTokens )
2160 uno::Reference<chart2::data::XDataSequence> xResult;
2161 if (!aTokens.hasElements())
2168 sal_uInt16
n = aCode.
GetLen();
2172 vector<ScTokenRef> aRefTokens;
2178 switch (
p->GetType())
2182 switch (
p->GetOpCode())
2190 throw lang::IllegalArgumentException();
2195 throw lang::IllegalArgumentException();
2198 throw lang::IllegalArgumentException();
2210 aRefTokens.push_back(pNew);
2214 throw lang::IllegalArgumentException();
2218 if (aRefTokens.empty())
2235 if (sRangeRepresentation.isEmpty())
2239 vector<ScTokenRef> aRefTokens;
2243 if (aRefTokens.empty())
2244 throw lang::IllegalArgumentException();
2247 converter = ::std::for_each(aRefTokens.begin(), aRefTokens.end(), converter);
2248 converter.getString(aRet);
2260 OUStringBuffer sRet;
2261 sal_Int32 nOffset = 0;
2262 while( nOffset >= 0 )
2270 OUString aUIString(sToken);
2273 if ( nIndex >= 0 && nIndex < aUIString.getLength() - 1 &&
2274 aUIString[nIndex + 1] ==
'.' )
2275 aUIString = aUIString.replaceAt( nIndex + 1, 1,
u"" );
2277 if ( aUIString[0] ==
'.' )
2278 aUIString = aUIString.copy( 1 );
2280 if( !sRet.isEmpty() )
2282 sRet.append( aUIString );
2286 return sRet.makeStringAndClear();
2296 uno::Reference< beans::XPropertySetInfo> SAL_CALL
2300 static uno::Reference<beans::XPropertySetInfo> aRef =
2306 const OUString& rPropertyName,
const uno::Any& rValue)
2309 throw beans::UnknownPropertyException(rPropertyName);
2312 throw lang::IllegalArgumentException();
2317 const OUString& rPropertyName)
2328 throw beans::UnknownPropertyException(rPropertyName);
2334 const uno::Reference< beans::XPropertyChangeListener>& )
2336 OSL_FAIL(
"Not yet implemented" );
2341 const uno::Reference< beans::XPropertyChangeListener>& )
2343 OSL_FAIL(
"Not yet implemented" );
2348 const uno::Reference< beans::XVetoableChangeListener>& )
2350 OSL_FAIL(
"Not yet implemented" );
2355 const uno::Reference< beans::XVetoableChangeListener>& )
2357 OSL_FAIL(
"Not yet implemented" );
2363 : m_pDocument( pDoc)
2379 if ( rHint.
GetId() == SfxHintId::Dying )
2385 uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence> > SAL_CALL
2400 : mfValue(
std::numeric_limits<double>::quiet_NaN())
2420 vector<ScTokenRef>&& rTokens,
2421 bool bIncludeHiddenCells )
2510 ::std::vector<sal_Int32> aHiddenValues;
2511 sal_Int32 nDataCount = 0;
2525 SCCOL nLastCol = -1;
2526 SCROW nLastRow = -1;
2538 if (bColHidden || bRowHidden)
2541 aHiddenValues.push_back(nDataCount-1);
2563 if (nErr != FormulaError::NONE)
2593 aHiddenValues.begin(), aHiddenValues.end(),
m_aHiddenValues.getArray());
2617 sal_uInt16 nFileId = pToken->GetIndex();
2618 OUString aTabName = pToken->GetString().
getString();
2630 sal_Int32 nDataCount = 0;
2631 FormulaTokenArrayPlainIterator aIter(*pArray);
2632 for (FormulaToken*
p = aIter.First();
p;
p = aIter.Next())
2641 OSL_FAIL(
"Cached array is not a matrix token.");
2648 for (
SCSIZE nC = 0; nC < nCSize; ++nC)
2650 for (
SCSIZE nR = 0; nR < nRSize; ++nR)
2662 const double fVal = aItem.
mfValue;
2663 const Color* pColor =
nullptr;
2664 sal_uInt32 nFmt = 0;
2670 pTable->getCell(nCol, nRow, &nFmt);
2702 const ScRange & rRange = rRanges[i];
2705 sal_uInt32 nOrigPos = (*m_oRangeIndices)[i];
2729 const std::unordered_set<sal_uInt16>& rFileIds =
m_pExtRefListener->getAllFileIds();
2731 for (
const auto& rFileId : rFileIds)
2741 OSL_FAIL(
"document instance is nullptr!?");
2762 const std::unordered_set<sal_uInt16>& rFileIds = r.
m_pExtRefListener->getAllFileIds();
2763 for (
const auto& rFileId : rFileIds)
2772 if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) )
2779 vector<ScTokenRef>::const_iterator itrBeg =
m_aTokens.begin(), itrEnd =
m_aTokens.end();
2780 for (vector<ScTokenRef>::const_iterator itr = itrBeg ;itr != itrEnd; ++itr)
2787 sal_uInt32
nPos = distance(itrBeg, itr);
2793 "range list and range index list have different sizes.");
2795 unique_ptr<ScRangeList> pUndoRanges;
2807 "sc.ui",
"range list and range index list have different sizes after the reference update.");
2816 else if (
auto pUndoHint = dynamic_cast<const ScUnoRefUndoHint*>(&rHint) )
2828 assert(
false &&
" faulty range indices");
2832 const ScRangeList& rRanges = pUndoHint->GetRanges();
2837 assert(
false &&
"range count and range index count differ.");
2848 if ( nId ==SfxHintId::Dying )
2852 else if ( nId == SfxHintId::DataChanged )
2859 lang::EventObject
aEvent;
2860 aEvent.Source.set(static_cast<cppu::OWeakObject*>(
this));
2864 for (
const uno::Reference<util::XModifyListener> & xListener:
m_aValueListeners)
2871 else if ( nId == SfxHintId::ScCalcAll )
2879 else if (nId == SfxHintId::ScClearCache)
2889 if (
m_pDocument && (rHint.GetId() == SfxHintId::ScDataChanged) )
2900 ScChart2DataSequence& rParent,
ScDocument* pDoc) :
2908 if (!mpDoc || mpDoc->IsInDtorClear())
2913 mpDoc->GetExternalRefManager()->removeLinkListener(
this);
2922 if (maFileIds.count(nFileId))
2928 maFileIds.erase(nFileId);
2938 maFileIds.insert(nFileId);
2945 throw uno::RuntimeException();
2958 if (rItem.mbIsValue)
2959 *pArr <<= rItem.mfValue;
2960 else if (rItem.maString.isEmpty())
2966 *pArr <<= rItem.maString;
2969 *pArr <<= rItem.maString;
2982 throw uno::RuntimeException();
2987 uno::Sequence<double>
aSeq(nCount);
2988 double* pArr = aSeq.getArray();
2991 *pArr = rItem.mbIsValue ? rItem.mfValue : std::numeric_limits<double>::quiet_NaN();
3003 uno::Sequence<OUString>
aSeq;
3005 throw uno::RuntimeException();
3012 aSeq = uno::Sequence<OUString>(nCount);
3013 OUString* pArr = aSeq.getArray();
3016 *pArr = rItem.maString;
3024 aSeq = uno::Sequence<OUString> {
m_aTokens.front()->GetString().getString() };
3035 OSL_ENSURE(
m_pDocument,
"No Document -> no SourceRangeRepresentation" );
3048 class AccumulateRangeSize
3051 AccumulateRangeSize(
const ScDocument* pDoc) :
3052 mpDoc(pDoc), mnCols(0), mnRows(0) {}
3064 SCCOL getCols()
const {
return mnCols; }
3065 SCROW getRows()
const {
return mnRows; }
3076 class GenerateLabelStrings
3079 GenerateLabelStrings(
const ScDocument* pDoc, sal_Int32 nSize, chart2::data::LabelOrigin eOrigin,
bool bColumn) :
3084 mbColumn(bColumn) {}
3091 OUString* pArr = mpLabels->getArray();
3096 if ( meOrigin != chart2::data::LabelOrigin_LONG_SIDE)
3098 OUString aString =
ScResId(STR_COLUMN) +
" ";
3105 pArr[
mnCount] = OUString::number( mnCount+1 );
3111 for (sal_Int32 nRow = aRange.
aStart.
Row(); nRow <= aRange.
aEnd.
Row(); ++nRow)
3113 if (meOrigin != chart2::data::LabelOrigin_LONG_SIDE)
3115 OUString aString =
ScResId(STR_ROW) +
3116 " " + OUString::number( nRow+1 );
3120 pArr[
mnCount] = OUString::number( mnCount+1 );
3130 shared_ptr< Sequence<OUString> > mpLabels;
3131 chart2::data::LabelOrigin meOrigin;
3142 throw uno::RuntimeException();
3147 SCCOL nCols = func.getCols();
3148 SCROW nRows = func.getRows();
3151 bool bColumn =
true;
3152 if ((eOrigin == chart2::data::LabelOrigin_SHORT_SIDE) ||
3153 (eOrigin == chart2::data::LabelOrigin_LONG_SIDE))
3157 bColumn = eOrigin == chart2::data::LabelOrigin_SHORT_SIDE;
3159 else if (nCols > nRows)
3161 bColumn = eOrigin != chart2::data::LabelOrigin_SHORT_SIDE;
3168 sal_Int32
nCount = bColumn ? nCols : nRows;
3169 GenerateLabelStrings genLabels(
m_pDocument, nCount, eOrigin, bColumn);
3200 return static_cast<sal_Int32
>(getDisplayNumberFormat(
m_pDocument, rItem.mAddress));
3208 if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(
m_aDataArray.size()))
3210 SAL_WARN(
"sc.ui",
"Passed invalid index to getNumberFormatKeyByIndex(). Will return default value '0'.");
3224 vector<ScTokenRef> aTokensNew;
3229 aTokensNew.push_back(
p);
3288 for ( sal_uInt16
n=nCount;
n--; )
3291 if ( rObj == aListener )
3317 uno::Reference< beans::XPropertySetInfo> SAL_CALL
3321 static uno::Reference<beans::XPropertySetInfo> aRef =
3327 const OUString& rPropertyName,
const uno::Any& rValue)
3332 throw lang::IllegalArgumentException();
3338 throw lang::IllegalArgumentException();
3342 else if( rPropertyName ==
"TimeBased" )
3345 rValue>>= bTimeBased;
3349 throw beans::UnknownPropertyException(rPropertyName);
3375 bool bHasStringLabel =
false;
3381 aRet <<= bHasStringLabel;
3384 throw beans::UnknownPropertyException(rPropertyName);
3391 const uno::Reference< beans::XPropertyChangeListener>& )
3394 OSL_FAIL(
"Not yet implemented" );
3399 const uno::Reference< beans::XPropertyChangeListener>& )
3402 OSL_FAIL(
"Not yet implemented" );
3407 const uno::Reference< beans::XVetoableChangeListener>& )
3410 OSL_FAIL(
"Not yet implemented" );
3415 const uno::Reference< beans::XVetoableChangeListener>& )
3418 OSL_FAIL(
"Not yet implemented" );
css::uno::Sequence< sal_Int32 > m_aHiddenValues
Matrix data type that can store values of mixed types.
std::unique_ptr< HiddenRangeListener > m_pHiddenListener
#define LINK(Instance, Class, Member)
virtual OUString SAL_CALL convertRangeFromXML(const OUString &sXMLRange) override
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
#define SC_UNONAME_INCLUDEHIDDENCELLS
bool UpdateReference(UpdateRefMode, const ScDocument *, const ScRange &rWhere, SCCOL nDx, SCROW nDy, SCTAB nDz)
bool m_bIncludeHiddenCells
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.
ExternalRefListener * GetExtRefListener()
OUString getString() const
bool HasUnoRefUndo() const
#define SC_UNONAME_TIME_BASED
virtual css::uno::Sequence< OUString > SAL_CALL getTextualData() override
OUString ScResId(TranslateId aId)
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL detectArguments(const css::uno::Reference< css::chart2::data::XDataSource > &xDataSource) override
bool SC_DLLPUBLIC isExternalRef(const ScTokenRef &pToken)
void getTokenFromRange(const ScDocument *pDoc, ScTokenRef &pToken, const ScRange &rRange)
Create a double reference token from a range object.
#define SC_UNONAME_USE_INTERNAL_DATA_PROVIDER
Single reference (one address) into the sheet.
SfxItemPropertySet m_aPropSet
virtual void SAL_CALL removeModifyListener(const css::uno::Reference< css::util::XModifyListener > &aListener) override
void getRangeListFromTokens(const ScDocument *pDoc, ScRangeList &rRangeList, const ::std::vector< ScTokenRef > &pTokens, const ScAddress &rPos)
SCCOL GetMaxColCount() const
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual ~ScChart2DataSource() override
SC_DLLPUBLIC bool InitColumnBlockPosition(sc::ColumnBlockPosition &rBlockPos, SCTAB nTab, SCCOL nCol)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Store position data for column array storage.
void SC_DLLPUBLIC join(const ScDocument *pDoc,::std::vector< ScTokenRef > &rTokens, const ScTokenRef &pToken, const ScAddress &rPos)
bool m_bGotDataChangedHint
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
virtual void SAL_CALL addModifyListener(const css::uno::Reference< css::util::XModifyListener > &aListener) override
std::optional< std::vector< sal_uInt32 > > m_oRangeIndices
void SetAbsRow(SCROW nVal)
static const SharedString & getEmptyString()
This is very similar to ScCellValue, except that it references the original value instead of copying ...
std::vector< ScTokenRef > m_aTokens
SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const
std::shared_ptr< T > make_shared(Args &&...args)
void SetRowRel(bool bVal)
SCROW GetMaxRowCount() const
SwNodeOffset abs(const SwNodeOffset &a)
bool SC_DLLPUBLIC isRef(const ScTokenRef &pToken)
std::vector< sal_Int8 > maData
virtual void notify(sal_uInt16 nFileId, ScExternalRefManager::LinkUpdateType eType) override
css::uno::Sequence< css::uno::Any > m_aMixedDataCache
Cached data for getData.
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceByValueArray(const OUString &aRole, const OUString &aRangeRepresentation, const OUString &aRoleQualifier) override
void AddUnoRefChange(sal_Int64 nId, const ScRangeList &rOldRanges)
void StopListeningToAllExternalRefs()
double GetDouble(SCSIZE nC, SCSIZE nR) const
virtual ~ScChart2DataProvider() override
SfxItemPropertySet m_aPropSet
css::chart2::data::DataSequenceRole m_aRole
UpdateRefMode GetMode() const
const ScRange & GetRange() const
SC_DLLPUBLIC SCROW MaxRow() const
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 ...
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
void StartListeningHiddenRange(const ScRange &rRange, ScChartHiddenRangeListener *pListener)
Start listening on hide/show change within specified cell range.
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
ScChart2DataSequence(ScDocument *pDoc,::std::vector< ScTokenRef > &&rTokens, bool bIncludeHiddenCells)
virtual void SAL_CALL addPropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
void push_back(const ScRange &rRange)
virtual ~HiddenRangeListener() override
ScFormulaCell * mpFormula
void SetTabRel(bool bVal)
SC_SIMPLE_SERVICE_INFO(ScChart2DataProvider,"ScChart2DataProvider","com.sun.star.chart2.data.DataProvider") SC_SIMPLE_SERVICE_INFO(ScChart2DataSource
bool IsStringOrEmpty(SCSIZE nIndex) const
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
void removeLinkListener(sal_uInt16 nFileId, LinkListener *pListener)
Remove an existing link listener.
virtual sal_Bool SAL_CALL switchToNext(sal_Bool bWrap) override
bool HasReferences() const
virtual void SAL_CALL removeVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &rListener) override
constexpr OUStringLiteral aData
virtual void SAL_CALL setRange(sal_Int32 nStart, sal_Int32 nEnd) override
SC_DLLPUBLIC SCCOL MaxCol() const
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
bool PastingDrawFromOtherDoc() const
HiddenRangeListener(ScChart2DataSequence &rParent)
ScChart2DataSource(ScDocument *pDoc)
virtual void SAL_CALL addPropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const
virtual sal_Bool SAL_CALL createDataSequenceByRangeRepresentationPossible(const OUString &aRangeRepresentation) override
void SetFlag3D(bool bVal)
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
virtual void SAL_CALL removeVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &rListener) override
void SetAbsCol(SCCOL nVal)
bool getDoubleRefDataFromToken(ScComplexRefData &rData, const ScTokenRef &pToken)
ScSheetLimits & GetSheetLimits() const
bool IsBoolean(SCSIZE nC, SCSIZE nR) const
css::uno::Reference< css::chart2::data::XDataSource > mxCachedDataSource
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
ExternalRefListener(ScChart2DataSequence &rParent, ScDocument *pDoc)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
const SfxItemPropertyMap & getPropertyMap() const
bool ShrinkToDataArea(SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow) const
Shrink a range to only include data area.
virtual sal_Bool SAL_CALL setToPointInTime(sal_Int32 nPoint) override
static SC_DLLPUBLIC bool ConvertToTokenArray(ScDocument &rDoc, ScTokenArray &rTokenArray, const css::uno::Sequence< css::sheet::FormulaToken > &rSequence)
void BroadcastUno(const SfxHint &rHint)
ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
Get a cache table instance for specified table and table index.
css::uno::Type const & get()
void BuildDataCache()
Build an internal data array to cache the data ranges, and other information such as hidden values...
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
#define SC_UNONAME_HAS_STRING_LABEL
void SetAbsTab(SCTAB nVal)
css::uno::Reference< css::chart2::data::XDataSource > mxCreatedDataSource
SC_DLLPUBLIC bool HasValueData(SCCOL nCol, SCROW nRow, SCTAB nTab) const
std::vector< css::uno::Reference< css::chart2::data::XLabeledDataSequence > > m_aLabeledSequences
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceByRangeRepresentation(const OUString &aRangeRepresentation) override
void AddUnoObject(SfxListener &rObject)
virtual OUString SAL_CALL convertRangeToXML(const OUString &sRangeRepresentation) override
void EndListeningHiddenRange(ScChartHiddenRangeListener *pListener)
Remove all ranges associated with passed listener instance from the list of hidden range listeners...
std::unique_ptr< ExternalRefListener > m_pExtRefListener
std::unique_ptr< char[]> aBuffer
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< css::beans::PropertyValue > maCreateDataSourceArguments
void setDataChangedHint(bool b)
void CopyData(const ScChart2DataSequence &r)
#define SAL_WARN_IF(condition, area, stream)
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.
std::vector< Item > m_aDataArray
This vector contains the cached data which was calculated with BuildDataCache().
static const SfxItemPropertyMapEntry * lcl_GetDataSequencePropertyMap()
void addFileId(sal_uInt16 nFileId)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
XModifyListenerArr_Impl m_aValueListeners
#define SHRINK_RANGE_THRESHOLD
void InitFlags()
No default ctor, because used in ScRawToken union, set InitFlags!
virtual void SAL_CALL addVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &rListener) override
std::shared_ptr< ScTokenArray > TokenArrayRef
std::shared_ptr< Table > TableTypeRef
virtual css::uno::Reference< css::sheet::XRangeSelection > SAL_CALL getRangeSelection() override
::boost::intrusive_ptr< formula::FormulaToken > ScTokenRef
ScChart2DataProvider(ScDocument *pDoc)
void RemoveUnoObject(SfxListener &rObject)
virtual void SAL_CALL removePropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &rListener) override
virtual void notify() override
std::unique_ptr< ScLinkListener > m_pValueListener
SC_DLLPUBLIC bool HasData(SCCOL nCol, SCROW nRow, SCTAB nTab)
Reference< XComponentContext > getProcessComponentContext()
SC_DLLPUBLIC ScChartListenerCollection * GetChartListenerCollection() const
Sequence< sal_Int8 > aSeq
virtual css::uno::Sequence< double > SAL_CALL getNumericalData() override
FILE * init(int, char **)
void UpdateTokensFromRanges(const ScRangeList &rRanges)
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
SC_DLLPUBLIC bool IsReference(ScRange &rRef) const
Complex reference (a range) into the sheet.
IMPL_LINK(ScChart2DataSequence, ValueListenerHdl, const SfxHint &, rHint, void)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
void AddUnoListenerCall(const css::uno::Reference< css::util::XModifyListener > &rListener, const css::lang::EventObject &rEvent)
virtual css::uno::Sequence< css::uno::Reference< css::chart2::data::XLabeledDataSequence > > SAL_CALL getDataSequences() override
virtual void SAL_CALL addVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &rListener) override
virtual css::uno::Reference< css::chart2::data::XDataSequence > SAL_CALL createDataSequenceByFormulaTokens(const css::uno::Sequence< css::sheet::FormulaToken > &aTokens) override
virtual OUString SAL_CALL getSourceRangeRepresentation() override
static sal_Int32 IndexOf(const OUString &rString, sal_Unicode cSearchChar, sal_Int32 nOffset, sal_Unicode cQuote= '\'')
SfxObjectShell * GetDocumentShell() const
#define SAL_WARN(area, stream)
bool IsValue(SCSIZE nIndex) const
Reference< XModel > xModel
virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override
bool m_bIncludeHiddenCells
void StartListeningArea(const ScRange &rRange, bool bGroupListening, SvtListener *pListener)
virtual void SAL_CALL removePropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &rListener) override
sal_Int32 FillCacheFromExternalRef(const ScTokenRef &pToken)
css::uno::Sequence< css::beans::PropertyValue > maCachedArguments
OUString getString(const Any &_rAny)
bool getRangeFromToken(const ScDocument *pDoc, ScRange &rRange, const ScTokenRef &pToken, const ScAddress &rPos, bool bExternal=false)
static void GetStringFromXMLRangeString(OUString &rString, const OUString &rXMLRange, const ScDocument &rDoc)
XML Range to Calc Range.
ScRangeData * FindRangeNameBySheetAndIndex(SCTAB nTab, sal_uInt16 nIndex) const
Find a named expression / range name in either global or a local scope.
virtual ~ScChart2DataSequence() override
static void GetTokenByOffset(OUString &rToken, const OUString &rString, sal_Int32 &nOffset, sal_Unicode cSeparator= ' ', sal_Unicode cQuote= '\'')
virtual css::uno::Sequence< css::uno::Any > SAL_CALL getData() override
void AddLabeledSequence(const css::uno::Reference< css::chart2::data::XLabeledDataSequence > &xNew)
void SetColRel(bool bVal)
BaseContainerNodeSharedPtr & mrParent
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
void addLinkListener(sal_uInt16 nFileId, LinkListener *pListener)
Register a new link listener to a specified external document.
virtual sal_Bool SAL_CALL createDataSequenceByFormulaTokensPossible(const css::uno::Sequence< css::sheet::FormulaToken > &aTokens) override
#define SC_UNONAME_HIDDENVALUES
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual sal_Bool SAL_CALL createDataSourcePossible(const css::uno::Sequence< css::beans::PropertyValue > &aArguments) override
virtual css::uno::Sequence< OUString > SAL_CALL generateLabel(css::chart2::data::LabelOrigin nOrigin) override
virtual ~ExternalRefListener() override
SC_DLLPUBLIC sal_uInt32 GetNumberFormat(SCCOL nCol, SCROW nRow, SCTAB nTab) const
bool m_bDetectedRangeSegmentation false
virtual css::uno::Reference< css::chart2::data::XDataSource > SAL_CALL createDataSource(const css::uno::Sequence< css::beans::PropertyValue > &aArguments) override
bool m_bExtDataRebuildQueued