1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: 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"
48 #include "docoptio.hxx"
51 // -----------------------------------------------------------------------
53 ScMemChart::ScMemChart(short nCols
, short nRows
)
57 pData
= new double[nColCnt
* nRowCnt
];
61 double *pFill
= pData
;
63 for (short i
= 0; i
< nColCnt
; i
++)
64 for (short j
= 0; j
< nRowCnt
; j
++)
68 pColText
= new String
[nColCnt
];
69 pRowText
= new String
[nRowCnt
];
72 ScMemChart::~ScMemChart()
79 // -----------------------------------------------------------------------
81 ScChartArray::ScChartArray( ScDocument
* pDoc
, SCTAB nTab
,
82 SCCOL nStartColP
, SCROW nStartRowP
, SCCOL nEndColP
, SCROW nEndRowP
,
83 const String
& rChartName
) :
86 aPositioner(pDoc
, nTab
, nStartColP
, nStartRowP
, nEndColP
, nEndRowP
),
91 ScChartArray::ScChartArray( ScDocument
* pDoc
, const ScRangeListRef
& rRangeList
,
92 const String
& rChartName
) :
95 aPositioner(pDoc
, rRangeList
),
100 ScChartArray::ScChartArray( const ScChartArray
& rArr
) :
103 pDocument(rArr
.pDocument
),
104 aPositioner(rArr
.aPositioner
),
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
;
125 #pragma optimize("",off)
128 ScMemChart
* ScChartArray::CreateMemChart()
130 ScRangeListRef
aRangeListRef(GetRangeList());
131 ULONG nCount
= aRangeListRef
->Count();
133 return CreateMemChartMulti();
134 else if ( nCount
== 1 )
136 ScRange
* pR
= aRangeListRef
->First();
137 if ( pR
->aStart
.Tab() != pR
->aEnd
.Tab() )
138 return CreateMemChartMulti();
140 return CreateMemChartSingle();
143 return CreateMemChartMulti(); // kann 0 Range besser ab als Single
146 ScMemChart
* ScChartArray::CreateMemChartSingle()
152 // wirkliche Groesse (ohne versteckte Zeilen/Spalten)
155 SCCOL nColAdd
= HasRowHeaders() ? 1 : 0;
156 SCROW nRowAdd
= HasColHeaders() ? 1 : 0;
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 )
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
)
178 nCol1
= sal::static_int_cast
<SCCOL
>( nCol1
+ nColAdd
);
180 if ( nRow1
<= nRow2
)
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
)
206 BOOL bValidData
= TRUE
;
224 ScMemChart
* pMemChart
= new ScMemChart(
225 static_cast<short>(nColCount
), static_cast<short>(nRowCount
) );
228 // SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
229 // pMemChart->SetNumberFormatter( pFormatter );
232 BOOL bCalcAsShown
= pDocument
->GetDocOptions().IsCalcAsShown();
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
);
243 CellType eType
= pCell
->GetCellType();
244 if (eType
== CELLTYPE_VALUE
)
246 nVal
= ((ScValueCell
*)pCell
)->GetValue();
247 if ( bCalcAsShown
&& nVal
!= 0.0 )
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
);
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
);
279 for (nCol
=0; nCol
<nColCount
; nCol
++)
281 String aString
, aColStr
;
283 pDocument
->GetString( pCols
[nCol
], nStrRow
, nTab1
, aString
);
284 if ( !aString
.Len() )
286 aString
= ScGlobal::GetRscString(STR_COLUMN
);
288 // aString += String::CreateFromInt32( pCols[nCol]+1 );
289 ScAddress
aPos( pCols
[ nCol
], 0, 0 );
290 aPos
.Format( aColStr
, SCA_VALID_COL
, NULL
);
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 );
304 for (nRow
=0; nRow
<nRowCount
; nRow
++)
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
);
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 );
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));
339 // ULONG nNumberAttr = (nTotalCols && nTotalRows ?
340 // pDocument->GetNumberFormat( ScAddress( nCol1, nRow1, nTab1)) :
343 // pMemChart->SetDataType(pFormatter->GetType( nNumberAttr ));
349 // SetExtraStrings( *pMemChart );
360 ScMemChart
* ScChartArray::CreateMemChartMulti()
362 SCSIZE nColCount
= GetPositionMap()->GetColCount();
363 SCSIZE nRowCount
= GetPositionMap()->GetRowCount();
368 // May happen at least with more than 32k rows.
369 if (nColCount
> SHRT_MAX
|| nRowCount
> SHRT_MAX
)
375 BOOL bValidData
= TRUE
;
391 ScMemChart
* pMemChart
= new ScMemChart(
392 static_cast<short>(nColCount
), static_cast<short>(nRowCount
) );
395 // pMemChart->SetNumberFormatter( pDocument->GetFormatTable() );
396 BOOL bCalcAsShown
= pDocument
->GetDocOptions().IsCalcAsShown();
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
);
408 ScBaseCell
* pCell
= pDocument
->GetCell( *pPos
);
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
);
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
);
441 ScBaseCell
* pCell
= pDocument
->GetCell( *pPos
);
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
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
);
485 nPosCol
= pPos
->Col() + 1;
488 ScAddress
aPos( nPosCol
- 1, 0, 0 );
489 aPos
.Format( aColStr
, SCA_VALID_COL
, NULL
);
490 // aString += String::CreateFromInt32( nPosCol );
493 pMemChart
->SetColText( static_cast<short>(nCol
), aString
);
495 // ULONG nNumberAttr = 0;
496 // pPos = GetPositionMap()->GetPosition( nCol, 0 );
498 // nNumberAttr = pDocument->GetNumberFormat( *pPos );
499 // pMemChart->SetNumFormatIdCol( static_cast<long>(nCol), nNumberAttr );
507 for ( nRow
= 0; nRow
< nRowCount
; nRow
++ )
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
);
521 nPosRow
= pPos
->Row() + 1;
524 aString
+= String::CreateFromInt32( nPosRow
);
526 pMemChart
->SetRowText( static_cast<short>(nRow
), aString
);
528 // ULONG nNumberAttr = 0;
529 // pPos = GetPositionMap()->GetPosition( 0, nRow );
531 // nNumberAttr = pDocument->GetNumberFormat( *pPos );
532 // pMemChart->SetNumFormatIdRow( static_cast<long>(nRow), nNumberAttr );
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));
549 // SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
553 // ULONG nCount = GetPositionMap()->GetCount();
554 // const ScAddress* pPos;
557 // pPos = GetPositionMap()->GetPosition( nIndex );
558 // } while ( !pPos && ++nIndex < nCount );
559 // ULONG nFormat = ( pPos ? pDocument->GetNumberFormat( *pPos ) : 0 );
560 // pMemChart->SetDataType( pFormatter->GetType( nFormat ) );
567 // SetExtraStrings( *pMemChart );
574 #pragma optimize("",on)
582 ScDataObject
* ScChartCollection::Clone() const
584 return new ScChartCollection(*this);
587 BOOL
ScChartCollection::operator==(const ScChartCollection
& rCmp
) const
589 if (nCount
!= rCmp
.nCount
)
592 for (USHORT i
=0; i
<nCount
; i
++)
593 if (!((*(const ScChartArray
*)pItems
[i
]) == (*(const ScChartArray
*)rCmp
.pItems
[i
])))