fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / tool / chartarr.cxx
blob33cbddbde7ad50ca222784d1e2e2751c64d404d6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
21 #include <svl/intitem.hxx>
22 #include <svl/zforlist.hxx>
23 #include <float.h>
25 #include "chartarr.hxx"
26 #include "document.hxx"
27 #include "rechead.hxx"
28 #include "globstr.hrc"
29 #include "formulacell.hxx"
30 #include "docoptio.hxx"
32 #include <vector>
34 using ::std::vector;
36 ScMemChart::ScMemChart(SCCOL nCols, SCROW nRows)
38 nRowCnt = nRows;
39 nColCnt = nCols;
40 pData = new double[nColCnt * nRowCnt];
42 double *pFill = pData;
44 for (SCCOL i = 0; i < nColCnt; i++)
45 for (SCROW j = 0; j < nRowCnt; j++)
46 *(pFill ++) = 0.0;
48 pColText = new OUString[nColCnt];
49 pRowText = new OUString[nRowCnt];
52 ScMemChart::~ScMemChart()
54 delete[] pRowText;
55 delete[] pColText;
56 delete[] pData;
59 ScChartArray::ScChartArray( ScDocument* pDoc, SCTAB nTab,
60 SCCOL nStartColP, SCROW nStartRowP, SCCOL nEndColP, SCROW nEndRowP,
61 const OUString& rChartName ) :
62 aName( rChartName ),
63 pDocument( pDoc ),
64 aPositioner(pDoc, nTab, nStartColP, nStartRowP, nEndColP, nEndRowP),
65 bValid( true )
69 ScChartArray::ScChartArray(
70 ScDocument* pDoc, const ScRangeListRef& rRangeList, const OUString& rChartName ) :
71 aName( rChartName ),
72 pDocument( pDoc ),
73 aPositioner(pDoc, rRangeList),
74 bValid( true ) {}
76 ScChartArray::ScChartArray( const ScChartArray& rArr ) :
77 aName(rArr.aName),
78 pDocument(rArr.pDocument),
79 aPositioner(rArr.aPositioner),
80 bValid(rArr.bValid) {}
82 ScChartArray::~ScChartArray() {}
84 bool ScChartArray::operator==(const ScChartArray& rCmp) const
86 return aPositioner == rCmp.aPositioner
87 && aName == rCmp.aName;
90 ScMemChart* ScChartArray::CreateMemChart()
92 ScRangeListRef aRangeListRef(GetRangeList());
93 size_t nCount = aRangeListRef->size();
94 if ( nCount > 1 )
95 return CreateMemChartMulti();
96 else if ( nCount == 1 )
98 ScRange* pR = aRangeListRef->front();
99 if ( pR->aStart.Tab() != pR->aEnd.Tab() )
100 return CreateMemChartMulti();
101 else
102 return CreateMemChartSingle();
104 else
105 return CreateMemChartMulti(); // Can handle 0 range better than Single
108 namespace {
110 double getCellValue( ScDocument& rDoc, const ScAddress& rPos, double fDefault, bool bCalcAsShown )
112 double fRet = fDefault;
114 CellType eType = rDoc.GetCellType(rPos);
115 switch (eType)
117 case CELLTYPE_VALUE:
119 fRet = rDoc.GetValue(rPos);
120 if (bCalcAsShown && fRet != 0.0)
122 sal_uInt32 nFormat = rDoc.GetNumberFormat(rPos);
123 fRet = rDoc.RoundValueAsShown(fRet, nFormat);
126 break;
127 case CELLTYPE_FORMULA:
129 ScFormulaCell* pFCell = rDoc.GetFormulaCell(rPos);
130 if (pFCell && !pFCell->GetErrCode() && pFCell->IsValue())
131 fRet = pFCell->GetValue();
133 break;
134 default:
137 return fRet;
142 ScMemChart* ScChartArray::CreateMemChartSingle()
144 SCSIZE nCol;
145 SCSIZE nRow;
147 // real size (without hidden rows/columns)
149 SCCOL nColAdd = HasRowHeaders() ? 1 : 0;
150 SCROW nRowAdd = HasColHeaders() ? 1 : 0;
152 SCCOL nCol1;
153 SCROW nRow1;
154 SCTAB nTab1;
155 SCCOL nCol2;
156 SCROW nRow2;
157 SCTAB nTab2;
158 ScRangeListRef aRangeListRef(GetRangeList());
159 aRangeListRef->front()->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
161 SCCOL nStrCol = nCol1; // remember for labeling
162 SCROW nStrRow = nRow1;
163 // Skip hidden columns.
164 // TODO: make use of last column value once implemented.
165 SCCOL nLastCol = -1;
166 while (pDocument->ColHidden(nCol1, nTab1, NULL, &nLastCol))
167 ++nCol1;
169 // Skip hidden rows.
170 SCROW nLastRow = -1;
171 if (pDocument->RowHidden(nRow1, nTab1, NULL, &nLastRow))
172 nRow1 = nLastRow + 1;
174 // if everything is hidden then the label remains at the beginning
175 if ( nCol1 <= nCol2 )
177 nStrCol = nCol1;
178 nCol1 = sal::static_int_cast<SCCOL>( nCol1 + nColAdd );
180 if ( nRow1 <= nRow2 )
182 nStrRow = nRow1;
183 nRow1 = sal::static_int_cast<SCROW>( nRow1 + nRowAdd );
186 SCSIZE nTotalCols = ( nCol1 <= nCol2 ? nCol2 - nCol1 + 1 : 0 );
187 vector<SCCOL> aCols;
188 aCols.reserve(nTotalCols);
189 for (SCSIZE i=0; i<nTotalCols; i++)
191 SCCOL nThisCol = sal::static_int_cast<SCCOL>(nCol1+i);
192 if (!pDocument->ColHidden(nThisCol, nTab1, NULL, &nLastCol))
193 aCols.push_back(nThisCol);
195 SCSIZE nColCount = aCols.size();
197 SCSIZE nTotalRows = ( nRow1 <= nRow2 ? nRow2 - nRow1 + 1 : 0 );
198 vector<SCROW> aRows;
199 aRows.reserve(nTotalRows);
200 if (nRow1 <= nRow2)
202 // Get all visible rows between nRow1 and nRow2.
203 SCROW nThisRow = nRow1;
204 while (nThisRow <= nRow2)
206 if (pDocument->RowHidden(nThisRow, nTab1, NULL, &nLastRow))
207 nThisRow = nLastRow;
208 else
209 aRows.push_back(nThisRow);
210 ++nThisRow;
213 SCSIZE nRowCount = aRows.size();
215 // May happen at least with more than 32k rows.
216 if (nColCount > SHRT_MAX || nRowCount > SHRT_MAX)
218 nColCount = 0;
219 nRowCount = 0;
222 bool bValidData = true;
223 if ( !nColCount )
225 bValidData = false;
226 nColCount = 1;
227 aCols.push_back(nStrCol);
229 if ( !nRowCount )
231 bValidData = false;
232 nRowCount = 1;
233 aRows.push_back(nStrRow);
236 // Data
237 ScMemChart* pMemChart = new ScMemChart( nColCount, nRowCount );
239 if ( bValidData )
241 bool bCalcAsShown = pDocument->GetDocOptions().IsCalcAsShown();
242 for (nCol=0; nCol<nColCount; nCol++)
244 for (nRow=0; nRow<nRowCount; nRow++)
246 // DBL_MIN is a Hack for Chart to recognize empty cells.
247 ScAddress aPos(aCols[nCol], aRows[nRow], nTab1);
248 double nVal = getCellValue(*pDocument, aPos, DBL_MIN, bCalcAsShown);
249 pMemChart->SetData(nCol, nRow, nVal);
253 else
255 // Flag marking data as invalid?
256 for (nCol=0; nCol<nColCount; nCol++)
257 for (nRow=0; nRow<nRowCount; nRow++)
258 pMemChart->SetData( nCol, nRow, DBL_MIN );
261 // Column Header
263 for (nCol=0; nCol<nColCount; nCol++)
265 OUString aString;
266 if (HasColHeaders())
267 aString = pDocument->GetString(aCols[nCol], nStrRow, nTab1);
268 if (aString.isEmpty())
270 OUStringBuffer aBuf;
271 aBuf.append(ScGlobal::GetRscString(STR_COLUMN));
272 aBuf.append(' ');
274 ScAddress aPos( aCols[ nCol ], 0, 0 );
275 aBuf.append(aPos.Format(SCA_VALID_COL, NULL));
277 aString = aBuf.makeStringAndClear();
279 pMemChart->SetColText( nCol, aString);
282 // Row Header
284 for (nRow=0; nRow<nRowCount; nRow++)
286 OUString aString;
287 if (HasRowHeaders())
289 ScAddress aAddr( nStrCol, aRows[nRow], nTab1 );
290 aString = pDocument->GetString(nStrCol, aRows[nRow], nTab1);
292 if (aString.isEmpty())
294 OUStringBuffer aBuf;
295 aBuf.append(ScGlobal::GetRscString(STR_ROW));
296 aBuf.append(' ');
297 aBuf.append(static_cast<sal_Int32>(aRows[nRow]+1));
298 aString = aBuf.makeStringAndClear();
300 pMemChart->SetRowText( nRow, aString);
303 return pMemChart;
306 ScMemChart* ScChartArray::CreateMemChartMulti()
308 SCSIZE nColCount = GetPositionMap()->GetColCount();
309 SCSIZE nRowCount = GetPositionMap()->GetRowCount();
311 // May happen at least with more than 32k rows.
312 if (nColCount > SHRT_MAX || nRowCount > SHRT_MAX)
314 nColCount = 0;
315 nRowCount = 0;
318 bool bValidData = true;
319 if ( !nColCount )
321 bValidData = false;
322 nColCount = 1;
324 if ( !nRowCount )
326 bValidData = false;
327 nRowCount = 1;
330 // Data
331 ScMemChart* pMemChart = new ScMemChart( nColCount, nRowCount );
333 SCSIZE nCol = 0;
334 SCSIZE nRow = 0;
335 bool bCalcAsShown = pDocument->GetDocOptions().IsCalcAsShown();
336 sal_uLong nIndex = 0;
337 if (bValidData)
339 for ( nCol = 0; nCol < nColCount; nCol++ )
341 for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
343 double nVal = DBL_MIN; // Hack for Chart to recognize empty cells
344 const ScAddress* pPos = GetPositionMap()->GetPosition( nIndex );
345 if (pPos)
346 // otherwise: Gap
347 nVal = getCellValue(*pDocument, *pPos, DBL_MIN, bCalcAsShown);
349 pMemChart->SetData(nCol, nRow, nVal);
353 else
355 for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
357 double nVal = DBL_MIN; // Hack for Chart to recognize empty cells
358 const ScAddress* pPos = GetPositionMap()->GetPosition( nIndex );
359 if (pPos)
360 // otherwise: Gap
361 nVal = getCellValue(*pDocument, *pPos, DBL_MIN, bCalcAsShown);
363 pMemChart->SetData(nCol, nRow, nVal);
367 //TODO: Label when gaps
369 // Column header
371 SCCOL nPosCol = 0;
372 for ( nCol = 0; nCol < nColCount; nCol++ )
374 OUString aString;
375 const ScAddress* pPos = GetPositionMap()->GetColHeaderPosition( static_cast<SCCOL>(nCol) );
376 if ( HasColHeaders() && pPos )
377 aString = pDocument->GetString(pPos->Col(), pPos->Row(), pPos->Tab());
379 if (aString.isEmpty())
381 OUStringBuffer aBuf(ScGlobal::GetRscString(STR_COLUMN));
382 aBuf.append(' ');
383 if ( pPos )
384 nPosCol = pPos->Col() + 1;
385 else
386 nPosCol++;
387 ScAddress aPos( nPosCol - 1, 0, 0 );
388 aBuf.append(aPos.Format(SCA_VALID_COL, NULL));
389 aString = aBuf.makeStringAndClear();
391 pMemChart->SetColText( nCol, aString);
394 // Row header
396 SCROW nPosRow = 0;
397 for ( nRow = 0; nRow < nRowCount; nRow++ )
399 OUString aString;
400 const ScAddress* pPos = GetPositionMap()->GetRowHeaderPosition( nRow );
401 if ( HasRowHeaders() && pPos )
402 aString = pDocument->GetString(pPos->Col(), pPos->Row(), pPos->Tab());
404 if (aString.isEmpty())
406 OUStringBuffer aBuf(ScGlobal::GetRscString(STR_ROW));
407 aBuf.append(' ');
408 if ( pPos )
409 nPosRow = pPos->Row() + 1;
410 else
411 nPosRow++;
412 aBuf.append(static_cast<sal_Int32>(nPosRow));
413 aString = aBuf.makeStringAndClear();
415 pMemChart->SetRowText( nRow, aString);
418 return pMemChart;
421 ScChartCollection::ScChartCollection() {}
422 ScChartCollection::ScChartCollection(const ScChartCollection& r) :
423 maData(r.maData) {}
425 void ScChartCollection::push_back(ScChartArray* p)
427 maData.push_back(p);
430 void ScChartCollection::clear()
432 maData.clear();
435 size_t ScChartCollection::size() const
437 return maData.size();
440 bool ScChartCollection::empty() const
442 return maData.empty();
445 ScChartArray* ScChartCollection::operator[](size_t nIndex)
447 if (maData.size() <= nIndex)
448 return NULL;
449 return &maData[nIndex];
452 const ScChartArray* ScChartCollection::operator[](size_t nIndex) const
454 if (maData.size() <= nIndex)
455 return NULL;
456 return &maData[nIndex];
459 bool ScChartCollection::operator==(const ScChartCollection& rCmp) const
461 return maData == rCmp.maData;
464 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */