update dev300-m57
[ooovba.git] / sc / source / core / tool / chartarr.cxx
blob5445a9d0abd933a205e95c06ac2ec2e7954cf76c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: chartarr.cxx,v $
10 * $Revision: 1.24.32.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <svtools/intitem.hxx>
40 #include <svtools/zforlist.hxx>
41 #include <float.h> // DBL_MIN
43 #include "chartarr.hxx"
44 #include "document.hxx"
45 #include "rechead.hxx"
46 #include "globstr.hrc"
47 #include "cell.hxx"
48 #include "docoptio.hxx"
51 // -----------------------------------------------------------------------
53 ScMemChart::ScMemChart(short nCols, short nRows)
55 nRowCnt = nRows;
56 nColCnt = nCols;
57 pData = new double[nColCnt * nRowCnt];
59 if (pData)
61 double *pFill = pData;
63 for (short i = 0; i < nColCnt; i++)
64 for (short j = 0; j < nRowCnt; j++)
65 *(pFill ++) = 0.0;
68 pColText = new String[nColCnt];
69 pRowText = new String[nRowCnt];
72 ScMemChart::~ScMemChart()
74 delete[] pRowText;
75 delete[] pColText;
76 delete[] pData;
79 // -----------------------------------------------------------------------
81 ScChartArray::ScChartArray( ScDocument* pDoc, SCTAB nTab,
82 SCCOL nStartColP, SCROW nStartRowP, SCCOL nEndColP, SCROW nEndRowP,
83 const String& rChartName ) :
84 aName( rChartName ),
85 pDocument( pDoc ),
86 aPositioner(pDoc, nTab, nStartColP, nStartRowP, nEndColP, nEndRowP),
87 bValid( TRUE )
91 ScChartArray::ScChartArray( ScDocument* pDoc, const ScRangeListRef& rRangeList,
92 const String& rChartName ) :
93 aName( rChartName ),
94 pDocument( pDoc ),
95 aPositioner(pDoc, rRangeList),
96 bValid( TRUE )
100 ScChartArray::ScChartArray( const ScChartArray& rArr ) :
101 ScDataObject(),
102 aName(rArr.aName),
103 pDocument(rArr.pDocument),
104 aPositioner(rArr.aPositioner),
105 bValid(rArr.bValid)
109 ScChartArray::~ScChartArray()
113 ScDataObject* ScChartArray::Clone() const
115 return new ScChartArray(*this);
118 BOOL ScChartArray::operator==(const ScChartArray& rCmp) const
120 return aPositioner == rCmp.aPositioner
121 && aName == rCmp.aName;
124 #ifdef _MSC_VER
125 #pragma optimize("",off)
126 #endif
128 ScMemChart* ScChartArray::CreateMemChart()
130 ScRangeListRef aRangeListRef(GetRangeList());
131 ULONG nCount = aRangeListRef->Count();
132 if ( nCount > 1 )
133 return CreateMemChartMulti();
134 else if ( nCount == 1 )
136 ScRange* pR = aRangeListRef->First();
137 if ( pR->aStart.Tab() != pR->aEnd.Tab() )
138 return CreateMemChartMulti();
139 else
140 return CreateMemChartSingle();
142 else
143 return CreateMemChartMulti(); // kann 0 Range besser ab als Single
146 ScMemChart* ScChartArray::CreateMemChartSingle()
148 SCSIZE nCol;
149 SCSIZE nRow;
152 // wirkliche Groesse (ohne versteckte Zeilen/Spalten)
155 SCCOL nColAdd = HasRowHeaders() ? 1 : 0;
156 SCROW nRowAdd = HasColHeaders() ? 1 : 0;
158 SCCOL nCol1;
159 SCROW nRow1;
160 SCTAB nTab1;
161 SCCOL nCol2;
162 SCROW nRow2;
163 SCTAB nTab2;
164 ScRangeListRef aRangeListRef(GetRangeList());
165 aRangeListRef->First()->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
167 SCCOL nStrCol = nCol1; // fuer Beschriftung merken
168 SCROW nStrRow = nRow1;
169 // Beschriftungen auch nach HiddenCols finden
170 while ( (pDocument->GetColFlags( nCol1, nTab1) & CR_HIDDEN) != 0 )
171 nCol1++;
172 nRow1 = pDocument->GetRowFlagsArray( nTab1).GetFirstForCondition( nRow1,
173 nRow2, CR_HIDDEN, 0);
174 // falls alles hidden ist, bleibt die Beschriftung am Anfang
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 SCCOL* pCols = new SCCOL[nTotalCols > 0 ? nTotalCols : 1];
188 SCSIZE nColCount = 0;
189 for (SCSIZE i=0; i<nTotalCols; i++)
190 if ((pDocument->GetColFlags(sal::static_int_cast<SCCOL>(nCol1+i),nTab1)&CR_HIDDEN)==0)
191 pCols[nColCount++] = sal::static_int_cast<SCCOL>(nCol1+i);
193 SCSIZE nTotalRows = ( nRow1 <= nRow2 ? nRow2 - nRow1 + 1 : 0 );
194 SCROW* pRows = new SCROW[nTotalRows > 0 ? nTotalRows : 1];
195 SCSIZE nRowCount = (nTotalRows ?
196 pDocument->GetRowFlagsArray( nTab1).FillArrayForCondition( nRow1,
197 nRow2, CR_HIDDEN, 0, pRows, nTotalRows) : 0);
199 // May happen at least with more than 32k rows.
200 if (nColCount > SHRT_MAX || nRowCount > SHRT_MAX)
202 nColCount = 0;
203 nRowCount = 0;
206 BOOL bValidData = TRUE;
207 if ( !nColCount )
209 bValidData = FALSE;
210 nColCount = 1;
211 pCols[0] = nStrCol;
213 if ( !nRowCount )
215 bValidData = FALSE;
216 nRowCount = 1;
217 pRows[0] = nStrRow;
221 // Daten
224 ScMemChart* pMemChart = new ScMemChart(
225 static_cast<short>(nColCount), static_cast<short>(nRowCount) );
226 if (pMemChart)
228 // SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
229 // pMemChart->SetNumberFormatter( pFormatter );
230 if ( bValidData )
232 BOOL bCalcAsShown = pDocument->GetDocOptions().IsCalcAsShown();
233 ScBaseCell* pCell;
234 for (nCol=0; nCol<nColCount; nCol++)
236 for (nRow=0; nRow<nRowCount; nRow++)
238 double nVal = DBL_MIN; // Hack fuer Chart, um leere Zellen zu erkennen
240 pDocument->GetCell( pCols[nCol], pRows[nRow], nTab1, pCell );
241 if (pCell)
243 CellType eType = pCell->GetCellType();
244 if (eType == CELLTYPE_VALUE)
246 nVal = ((ScValueCell*)pCell)->GetValue();
247 if ( bCalcAsShown && nVal != 0.0 )
249 sal_uInt32 nFormat;
250 pDocument->GetNumberFormat( pCols[nCol],
251 pRows[nRow], nTab1, nFormat );
252 nVal = pDocument->RoundValueAsShown( nVal, nFormat );
255 else if (eType == CELLTYPE_FORMULA)
257 ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
258 if ( (pFCell->GetErrCode() == 0) && pFCell->IsValue() )
259 nVal = pFCell->GetValue();
262 pMemChart->SetData(static_cast<short>(nCol), static_cast<short>(nRow), nVal);
266 else
268 //! Flag, dass Daten ungueltig ??
270 for (nCol=0; nCol<nColCount; nCol++)
271 for (nRow=0; nRow<nRowCount; nRow++)
272 pMemChart->SetData( static_cast<short>(nCol), static_cast<short>(nRow), DBL_MIN );
276 // Spalten-Header
279 for (nCol=0; nCol<nColCount; nCol++)
281 String aString, aColStr;
282 if (HasColHeaders())
283 pDocument->GetString( pCols[nCol], nStrRow, nTab1, aString );
284 if ( !aString.Len() )
286 aString = ScGlobal::GetRscString(STR_COLUMN);
287 aString += ' ';
288 // aString += String::CreateFromInt32( pCols[nCol]+1 );
289 ScAddress aPos( pCols[ nCol ], 0, 0 );
290 aPos.Format( aColStr, SCA_VALID_COL, NULL );
291 aString += aColStr;
293 pMemChart->SetColText( static_cast<short>(nCol), aString);
295 // ULONG nNumberAttr = (nTotalRows ? pDocument->GetNumberFormat(
296 // ScAddress( pCols[nCol], nRow1, nTab1)) : 0);
297 // pMemChart->SetNumFormatIdCol( static_cast<long>(nCol), nNumberAttr );
301 // Zeilen-Header
304 for (nRow=0; nRow<nRowCount; nRow++)
306 String aString;
307 if (HasRowHeaders())
309 ScAddress aAddr( nStrCol, pRows[nRow], nTab1 );
310 pDocument->GetString( nStrCol, pRows[nRow], nTab1, aString );
312 if ( !aString.Len() )
314 aString = ScGlobal::GetRscString(STR_ROW);
315 aString += ' ';
316 aString += String::CreateFromInt32( pRows[nRow]+1 );
318 pMemChart->SetRowText( static_cast<short>(nRow), aString);
320 // ULONG nNumberAttr = (nTotalCols ? pDocument->GetNumberFormat(
321 // ScAddress( nCol1, pRows[nRow], nTab1)) : 0);
322 // pMemChart->SetNumFormatIdRow( static_cast<long>(nRow), nNumberAttr );
326 // Titel
329 // pMemChart->SetMainTitle(ScGlobal::GetRscString(STR_CHART_MAINTITLE));
330 // pMemChart->SetSubTitle(ScGlobal::GetRscString(STR_CHART_SUBTITLE));
331 // pMemChart->SetXAxisTitle(ScGlobal::GetRscString(STR_CHART_XTITLE));
332 // pMemChart->SetYAxisTitle(ScGlobal::GetRscString(STR_CHART_YTITLE));
333 // pMemChart->SetZAxisTitle(ScGlobal::GetRscString(STR_CHART_ZTITLE));
336 // Zahlen-Typ
339 // ULONG nNumberAttr = (nTotalCols && nTotalRows ?
340 // pDocument->GetNumberFormat( ScAddress( nCol1, nRow1, nTab1)) :
341 // 0);
342 // if (pFormatter)
343 // pMemChart->SetDataType(pFormatter->GetType( nNumberAttr ));
346 // Parameter-Strings
349 // SetExtraStrings( *pMemChart );
352 // Aufraeumen
354 delete[] pRows;
355 delete[] pCols;
357 return pMemChart;
360 ScMemChart* ScChartArray::CreateMemChartMulti()
362 SCSIZE nColCount = GetPositionMap()->GetColCount();
363 SCSIZE nRowCount = GetPositionMap()->GetRowCount();
365 SCSIZE nCol = 0;
366 SCSIZE nRow = 0;
368 // May happen at least with more than 32k rows.
369 if (nColCount > SHRT_MAX || nRowCount > SHRT_MAX)
371 nColCount = 0;
372 nRowCount = 0;
375 BOOL bValidData = TRUE;
376 if ( !nColCount )
378 bValidData = FALSE;
379 nColCount = 1;
381 if ( !nRowCount )
383 bValidData = FALSE;
384 nRowCount = 1;
388 // Daten
391 ScMemChart* pMemChart = new ScMemChart(
392 static_cast<short>(nColCount), static_cast<short>(nRowCount) );
393 if (pMemChart)
395 // pMemChart->SetNumberFormatter( pDocument->GetFormatTable() );
396 BOOL bCalcAsShown = pDocument->GetDocOptions().IsCalcAsShown();
397 ULONG nIndex = 0;
398 if (bValidData)
400 for ( nCol = 0; nCol < nColCount; nCol++ )
402 for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
404 double nVal = DBL_MIN; // Hack fuer Chart, um leere Zellen zu erkennen
405 const ScAddress* pPos = GetPositionMap()->GetPosition( nIndex );
406 if ( pPos )
407 { // sonst: Luecke
408 ScBaseCell* pCell = pDocument->GetCell( *pPos );
409 if (pCell)
411 CellType eType = pCell->GetCellType();
412 if (eType == CELLTYPE_VALUE)
414 nVal = ((ScValueCell*)pCell)->GetValue();
415 if ( bCalcAsShown && nVal != 0.0 )
417 ULONG nFormat = pDocument->GetNumberFormat( *pPos );
418 nVal = pDocument->RoundValueAsShown( nVal, nFormat );
421 else if (eType == CELLTYPE_FORMULA)
423 ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
424 if ( (pFCell->GetErrCode() == 0) && pFCell->IsValue() )
425 nVal = pFCell->GetValue();
429 pMemChart->SetData(static_cast<short>(nCol), static_cast<short>(nRow), nVal);
433 else
435 for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
437 double nVal = DBL_MIN; // Hack fuer Chart, um leere Zellen zu erkennen
438 const ScAddress* pPos = GetPositionMap()->GetPosition( nIndex );
439 if ( pPos )
440 { // sonst: Luecke
441 ScBaseCell* pCell = pDocument->GetCell( *pPos );
442 if (pCell)
444 CellType eType = pCell->GetCellType();
445 if (eType == CELLTYPE_VALUE)
447 nVal = ((ScValueCell*)pCell)->GetValue();
448 if ( bCalcAsShown && nVal != 0.0 )
450 ULONG nFormat = pDocument->GetNumberFormat( *pPos );
451 nVal = pDocument->RoundValueAsShown( nVal, nFormat );
454 else if (eType == CELLTYPE_FORMULA)
456 ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
457 if ( (pFCell->GetErrCode() == 0) && pFCell->IsValue() )
458 nVal = pFCell->GetValue();
462 pMemChart->SetData(static_cast<short>(nCol), static_cast<short>(nRow), nVal);
466 //2do: Beschriftung bei Luecken
469 // Spalten-Header
472 SCCOL nPosCol = 0;
473 for ( nCol = 0; nCol < nColCount; nCol++ )
475 String aString, aColStr;
476 const ScAddress* pPos = GetPositionMap()->GetColHeaderPosition( static_cast<SCCOL>(nCol) );
477 if ( HasColHeaders() && pPos )
478 pDocument->GetString(
479 pPos->Col(), pPos->Row(), pPos->Tab(), aString );
480 if ( !aString.Len() )
482 aString = ScGlobal::GetRscString(STR_COLUMN);
483 aString += ' ';
484 if ( pPos )
485 nPosCol = pPos->Col() + 1;
486 else
487 nPosCol++;
488 ScAddress aPos( nPosCol - 1, 0, 0 );
489 aPos.Format( aColStr, SCA_VALID_COL, NULL );
490 // aString += String::CreateFromInt32( nPosCol );
491 aString += aColStr;
493 pMemChart->SetColText( static_cast<short>(nCol), aString);
495 // ULONG nNumberAttr = 0;
496 // pPos = GetPositionMap()->GetPosition( nCol, 0 );
497 // if ( pPos )
498 // nNumberAttr = pDocument->GetNumberFormat( *pPos );
499 // pMemChart->SetNumFormatIdCol( static_cast<long>(nCol), nNumberAttr );
503 // Zeilen-Header
506 SCROW nPosRow = 0;
507 for ( nRow = 0; nRow < nRowCount; nRow++ )
509 String aString;
510 const ScAddress* pPos = GetPositionMap()->GetRowHeaderPosition( nRow );
511 if ( HasRowHeaders() && pPos )
513 pDocument->GetString(
514 pPos->Col(), pPos->Row(), pPos->Tab(), aString );
516 if ( !aString.Len() )
518 aString = ScGlobal::GetRscString(STR_ROW);
519 aString += ' ';
520 if ( pPos )
521 nPosRow = pPos->Row() + 1;
522 else
523 nPosRow++;
524 aString += String::CreateFromInt32( nPosRow );
526 pMemChart->SetRowText( static_cast<short>(nRow), aString);
528 // ULONG nNumberAttr = 0;
529 // pPos = GetPositionMap()->GetPosition( 0, nRow );
530 // if ( pPos )
531 // nNumberAttr = pDocument->GetNumberFormat( *pPos );
532 // pMemChart->SetNumFormatIdRow( static_cast<long>(nRow), nNumberAttr );
536 // Titel
539 // pMemChart->SetMainTitle(ScGlobal::GetRscString(STR_CHART_MAINTITLE));
540 // pMemChart->SetSubTitle(ScGlobal::GetRscString(STR_CHART_SUBTITLE));
541 // pMemChart->SetXAxisTitle(ScGlobal::GetRscString(STR_CHART_XTITLE));
542 // pMemChart->SetYAxisTitle(ScGlobal::GetRscString(STR_CHART_YTITLE));
543 // pMemChart->SetZAxisTitle(ScGlobal::GetRscString(STR_CHART_ZTITLE));
546 // Zahlen-Typ
549 // SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
550 // if (pFormatter)
551 // {
552 // ULONG nIndex = 0;
553 // ULONG nCount = GetPositionMap()->GetCount();
554 // const ScAddress* pPos;
555 // do
556 // {
557 // pPos = GetPositionMap()->GetPosition( nIndex );
558 // } while ( !pPos && ++nIndex < nCount );
559 // ULONG nFormat = ( pPos ? pDocument->GetNumberFormat( *pPos ) : 0 );
560 // pMemChart->SetDataType( pFormatter->GetType( nFormat ) );
561 // }
564 // Parameter-Strings
567 // SetExtraStrings( *pMemChart );
570 return pMemChart;
573 #ifdef _MSC_VER
574 #pragma optimize("",on)
575 #endif
579 // Collection
582 ScDataObject* ScChartCollection::Clone() const
584 return new ScChartCollection(*this);
587 BOOL ScChartCollection::operator==(const ScChartCollection& rCmp) const
589 if (nCount != rCmp.nCount)
590 return FALSE;
592 for (USHORT i=0; i<nCount; i++)
593 if (!((*(const ScChartArray*)pItems[i]) == (*(const ScChartArray*)rCmp.pItems[i])))
594 return FALSE;
596 return TRUE;