1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*b3f79822SAndrew Rist * distributed with this work for additional information
6*b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10*b3f79822SAndrew Rist *
11*b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist *
13*b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17*b3f79822SAndrew Rist * specific language governing permissions and limitations
18*b3f79822SAndrew Rist * under the License.
19*b3f79822SAndrew Rist *
20*b3f79822SAndrew Rist *************************************************************/
21*b3f79822SAndrew Rist
22*b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include <tools/table.hxx>
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include "chartpos.hxx"
32cdf0e10cSrcweir #include "document.hxx"
33cdf0e10cSrcweir #include "rechead.hxx"
34cdf0e10cSrcweir
35cdf0e10cSrcweir namespace
36cdf0e10cSrcweir {
lcl_hasValueDataButNoDates(ScDocument * pDocument,SCCOL nCol,SCROW nRow,SCTAB nTab)37cdf0e10cSrcweir bool lcl_hasValueDataButNoDates( ScDocument* pDocument, SCCOL nCol, SCROW nRow, SCTAB nTab )
38cdf0e10cSrcweir {
39cdf0e10cSrcweir bool bReturn = false;
40cdf0e10cSrcweir if (pDocument->HasValueData( nCol, nRow, nTab ))
41cdf0e10cSrcweir {
42cdf0e10cSrcweir //treat dates like text #i25706#
43cdf0e10cSrcweir sal_uInt32 nNumberFormat = pDocument->GetNumberFormat( ScAddress( nCol, nRow, nTab ) );
44cdf0e10cSrcweir short nType = pDocument->GetFormatTable()->GetType(nNumberFormat);
45cdf0e10cSrcweir bool bIsDate = (nType & NUMBERFORMAT_DATE);
46cdf0e10cSrcweir bReturn = !bIsDate;
47cdf0e10cSrcweir }
48cdf0e10cSrcweir return bReturn;
49cdf0e10cSrcweir }
50cdf0e10cSrcweir }
51cdf0e10cSrcweir
ScChartPositioner(ScDocument * pDoc,SCTAB nTab,SCCOL nStartColP,SCROW nStartRowP,SCCOL nEndColP,SCROW nEndRowP)52cdf0e10cSrcweir ScChartPositioner::ScChartPositioner( ScDocument* pDoc, SCTAB nTab,
53cdf0e10cSrcweir SCCOL nStartColP, SCROW nStartRowP, SCCOL nEndColP, SCROW nEndRowP) :
54cdf0e10cSrcweir pDocument( pDoc ),
55cdf0e10cSrcweir pPositionMap( NULL ),
56cdf0e10cSrcweir eGlue( SC_CHARTGLUE_NA ),
57cdf0e10cSrcweir nStartCol(0),
58cdf0e10cSrcweir nStartRow(0),
59cdf0e10cSrcweir bColHeaders( sal_False ),
60cdf0e10cSrcweir bRowHeaders( sal_False ),
61cdf0e10cSrcweir bDummyUpperLeft( sal_False )
62cdf0e10cSrcweir {
63cdf0e10cSrcweir SetRangeList( ScRange( nStartColP, nStartRowP, nTab, nEndColP, nEndRowP, nTab ) );
64cdf0e10cSrcweir CheckColRowHeaders();
65cdf0e10cSrcweir }
66cdf0e10cSrcweir
ScChartPositioner(ScDocument * pDoc,const ScRangeListRef & rRangeList)67cdf0e10cSrcweir ScChartPositioner::ScChartPositioner( ScDocument* pDoc, const ScRangeListRef& rRangeList ) :
68cdf0e10cSrcweir aRangeListRef( rRangeList ),
69cdf0e10cSrcweir pDocument( pDoc ),
70cdf0e10cSrcweir pPositionMap( NULL ),
71cdf0e10cSrcweir eGlue( SC_CHARTGLUE_NA ),
72cdf0e10cSrcweir nStartCol(0),
73cdf0e10cSrcweir nStartRow(0),
74cdf0e10cSrcweir bColHeaders( sal_False ),
75cdf0e10cSrcweir bRowHeaders( sal_False ),
76cdf0e10cSrcweir bDummyUpperLeft( sal_False )
77cdf0e10cSrcweir {
78cdf0e10cSrcweir if ( aRangeListRef.Is() )
79cdf0e10cSrcweir CheckColRowHeaders();
80cdf0e10cSrcweir }
81cdf0e10cSrcweir
ScChartPositioner(const ScChartPositioner & rPositioner)82cdf0e10cSrcweir ScChartPositioner::ScChartPositioner( const ScChartPositioner& rPositioner ) :
83cdf0e10cSrcweir aRangeListRef( rPositioner.aRangeListRef ),
84cdf0e10cSrcweir pDocument(rPositioner.pDocument),
85cdf0e10cSrcweir pPositionMap( NULL ),
86cdf0e10cSrcweir eGlue(rPositioner.eGlue),
87cdf0e10cSrcweir nStartCol(rPositioner.nStartCol),
88cdf0e10cSrcweir nStartRow(rPositioner.nStartRow),
89cdf0e10cSrcweir bColHeaders(rPositioner.bColHeaders),
90cdf0e10cSrcweir bRowHeaders(rPositioner.bRowHeaders),
91cdf0e10cSrcweir bDummyUpperLeft( rPositioner.bDummyUpperLeft )
92cdf0e10cSrcweir {
93cdf0e10cSrcweir }
94cdf0e10cSrcweir
~ScChartPositioner()95cdf0e10cSrcweir ScChartPositioner::~ScChartPositioner()
96cdf0e10cSrcweir {
97cdf0e10cSrcweir delete pPositionMap;
98cdf0e10cSrcweir }
99cdf0e10cSrcweir
operator ==(const ScChartPositioner & rCmp) const100cdf0e10cSrcweir sal_Bool ScChartPositioner::operator==(const ScChartPositioner& rCmp) const
101cdf0e10cSrcweir {
102cdf0e10cSrcweir return bColHeaders == rCmp.bColHeaders
103cdf0e10cSrcweir && bRowHeaders == rCmp.bRowHeaders
104cdf0e10cSrcweir && *aRangeListRef == *rCmp.aRangeListRef;
105cdf0e10cSrcweir }
106cdf0e10cSrcweir
SetRangeList(const ScRange & rRange)107cdf0e10cSrcweir void ScChartPositioner::SetRangeList( const ScRange& rRange )
108cdf0e10cSrcweir {
109cdf0e10cSrcweir aRangeListRef = new ScRangeList;
110cdf0e10cSrcweir aRangeListRef->Append( rRange );
111cdf0e10cSrcweir InvalidateGlue();
112cdf0e10cSrcweir }
113cdf0e10cSrcweir
GlueState()114cdf0e10cSrcweir void ScChartPositioner::GlueState()
115cdf0e10cSrcweir {
116cdf0e10cSrcweir if ( eGlue != SC_CHARTGLUE_NA )
117cdf0e10cSrcweir return;
118cdf0e10cSrcweir bDummyUpperLeft = sal_False;
119cdf0e10cSrcweir ScRangePtr pR;
120cdf0e10cSrcweir if ( aRangeListRef->Count() <= 1 )
121cdf0e10cSrcweir {
122cdf0e10cSrcweir if ( (pR = aRangeListRef->First())!=NULL )
123cdf0e10cSrcweir {
124cdf0e10cSrcweir if ( pR->aStart.Tab() == pR->aEnd.Tab() )
125cdf0e10cSrcweir eGlue = SC_CHARTGLUE_NONE;
126cdf0e10cSrcweir else
127cdf0e10cSrcweir eGlue = SC_CHARTGLUE_COLS; // mehrere Tabellen spaltenweise
128cdf0e10cSrcweir nStartCol = pR->aStart.Col();
129cdf0e10cSrcweir nStartRow = pR->aStart.Row();
130cdf0e10cSrcweir }
131cdf0e10cSrcweir else
132cdf0e10cSrcweir {
133cdf0e10cSrcweir InvalidateGlue();
134cdf0e10cSrcweir nStartCol = 0;
135cdf0e10cSrcweir nStartRow = 0;
136cdf0e10cSrcweir }
137cdf0e10cSrcweir return;
138cdf0e10cSrcweir }
139cdf0e10cSrcweir // sal_uLong nOldPos = aRangeListRef->GetCurPos();
140cdf0e10cSrcweir
141cdf0e10cSrcweir pR = aRangeListRef->First();
142cdf0e10cSrcweir nStartCol = pR->aStart.Col();
143cdf0e10cSrcweir nStartRow = pR->aStart.Row();
144cdf0e10cSrcweir SCCOL nMaxCols, nEndCol;
145cdf0e10cSrcweir SCROW nMaxRows, nEndRow;
146cdf0e10cSrcweir nMaxCols = nEndCol = 0;
147cdf0e10cSrcweir nMaxRows = nEndRow = 0;
148cdf0e10cSrcweir do
149cdf0e10cSrcweir { // umspannenden Bereich etc. feststellen
150cdf0e10cSrcweir SCCOLROW nTmp, n1, n2;
151cdf0e10cSrcweir if ( (n1 = pR->aStart.Col()) < nStartCol )
152cdf0e10cSrcweir nStartCol = static_cast<SCCOL>(n1);
153cdf0e10cSrcweir if ( (n2 = pR->aEnd.Col()) > nEndCol )
154cdf0e10cSrcweir nEndCol = static_cast<SCCOL>(n2);
155cdf0e10cSrcweir if ( (nTmp = n2 - n1 + 1) > nMaxCols )
156cdf0e10cSrcweir nMaxCols = static_cast<SCCOL>(nTmp);
157cdf0e10cSrcweir if ( (n1 = pR->aStart.Row()) < nStartRow )
158cdf0e10cSrcweir nStartRow = static_cast<SCROW>(n1);
159cdf0e10cSrcweir if ( (n2 = pR->aEnd.Row()) > nEndRow )
160cdf0e10cSrcweir nEndRow = static_cast<SCROW>(n2);
161cdf0e10cSrcweir if ( (nTmp = n2 - n1 + 1) > nMaxRows )
162cdf0e10cSrcweir nMaxRows = static_cast<SCROW>(nTmp);
163cdf0e10cSrcweir } while ( (pR = aRangeListRef->Next())!=NULL );
164cdf0e10cSrcweir SCCOL nC = nEndCol - nStartCol + 1;
165cdf0e10cSrcweir if ( nC == 1 )
166cdf0e10cSrcweir {
167cdf0e10cSrcweir eGlue = SC_CHARTGLUE_ROWS;
168cdf0e10cSrcweir return;
169cdf0e10cSrcweir }
170cdf0e10cSrcweir SCROW nR = nEndRow - nStartRow + 1;
171cdf0e10cSrcweir if ( nR == 1 )
172cdf0e10cSrcweir {
173cdf0e10cSrcweir eGlue = SC_CHARTGLUE_COLS;
174cdf0e10cSrcweir return;
175cdf0e10cSrcweir }
176cdf0e10cSrcweir sal_uLong nCR = (sal_uLong)nC * nR;
177cdf0e10cSrcweir //2do:
178cdf0e10cSrcweir /*
179cdf0e10cSrcweir Erstmal simpel ohne Bitmaskiererei, maximal koennten so 8MB alloziert
180cdf0e10cSrcweir werden (256 Cols mal 32000 Rows), das liesse sich mit 2 Bit je Eintrag
181cdf0e10cSrcweir auf 2MB reduzieren, andererseits ist es so schneller.
182cdf0e10cSrcweir Weitere Platz-Optimierung waere, in dem Array nur die wirklich benutzten
183cdf0e10cSrcweir Zeilen/Spalten abzulegen, wuerde aber ein weiteres durchlaufen der
184cdf0e10cSrcweir RangeList und indirekten Zugriff auf das Array bedeuten.
185cdf0e10cSrcweir */
186cdf0e10cSrcweir const sal_uInt8 nHole = 0;
187cdf0e10cSrcweir const sal_uInt8 nOccu = 1;
188cdf0e10cSrcweir const sal_uInt8 nFree = 2;
189cdf0e10cSrcweir const sal_uInt8 nGlue = 3;
190cdf0e10cSrcweir sal_uInt8* p;
191cdf0e10cSrcweir sal_uInt8* pA = new sal_uInt8[ nCR ];
192cdf0e10cSrcweir memset( pA, 0, nCR * sizeof(sal_uInt8) );
193cdf0e10cSrcweir
194cdf0e10cSrcweir SCCOL nCol, nCol1, nCol2;
195cdf0e10cSrcweir SCROW nRow, nRow1, nRow2;
196cdf0e10cSrcweir for ( pR = aRangeListRef->First(); pR; pR = aRangeListRef->Next() )
197cdf0e10cSrcweir { // Selektionen 2D als belegt markieren
198cdf0e10cSrcweir nCol1 = pR->aStart.Col() - nStartCol;
199cdf0e10cSrcweir nCol2 = pR->aEnd.Col() - nStartCol;
200cdf0e10cSrcweir nRow1 = pR->aStart.Row() - nStartRow;
201cdf0e10cSrcweir nRow2 = pR->aEnd.Row() - nStartRow;
202cdf0e10cSrcweir for ( nCol = nCol1; nCol <= nCol2; nCol++ )
203cdf0e10cSrcweir {
204cdf0e10cSrcweir p = pA + (sal_uLong)nCol * nR + nRow1;
205cdf0e10cSrcweir for ( nRow = nRow1; nRow <= nRow2; nRow++, p++ )
206cdf0e10cSrcweir *p = nOccu;
207cdf0e10cSrcweir }
208cdf0e10cSrcweir }
209cdf0e10cSrcweir sal_Bool bGlue = sal_True;
210cdf0e10cSrcweir
211cdf0e10cSrcweir sal_Bool bGlueCols = sal_False;
212cdf0e10cSrcweir for ( nCol = 0; bGlue && nCol < nC; nCol++ )
213cdf0e10cSrcweir { // Spalten probieren durchzugehen und als frei markieren
214cdf0e10cSrcweir p = pA + (sal_uLong)nCol * nR;
215cdf0e10cSrcweir for ( nRow = 0; bGlue && nRow < nR; nRow++, p++ )
216cdf0e10cSrcweir {
217cdf0e10cSrcweir if ( *p == nOccu )
218cdf0e10cSrcweir { // Wenn einer mittendrin liegt ist keine Zusammenfassung
219cdf0e10cSrcweir // moeglich. Am Rand koennte ok sein, wenn in dieser Spalte
220cdf0e10cSrcweir // in jeder belegten Zeile einer belegt ist.
221cdf0e10cSrcweir if ( nRow > 0 && nCol > 0 )
222cdf0e10cSrcweir bGlue = sal_False; // nCol==0 kann DummyUpperLeft sein
223cdf0e10cSrcweir else
224cdf0e10cSrcweir nRow = nR;
225cdf0e10cSrcweir }
226cdf0e10cSrcweir else
227cdf0e10cSrcweir *p = nFree;
228cdf0e10cSrcweir }
229cdf0e10cSrcweir if ( bGlue && *(p = (pA + ((((sal_uLong)nCol+1) * nR) - 1))) == nFree )
230cdf0e10cSrcweir { // Spalte als komplett frei markieren
231cdf0e10cSrcweir *p = nGlue;
232cdf0e10cSrcweir bGlueCols = sal_True; // mindestens eine freie Spalte
233cdf0e10cSrcweir }
234cdf0e10cSrcweir }
235cdf0e10cSrcweir
236cdf0e10cSrcweir sal_Bool bGlueRows = sal_False;
237cdf0e10cSrcweir for ( nRow = 0; bGlue && nRow < nR; nRow++ )
238cdf0e10cSrcweir { // Zeilen probieren durchzugehen und als frei markieren
239cdf0e10cSrcweir p = pA + nRow;
240cdf0e10cSrcweir for ( nCol = 0; bGlue && nCol < nC; nCol++, p+=nR )
241cdf0e10cSrcweir {
242cdf0e10cSrcweir if ( *p == nOccu )
243cdf0e10cSrcweir {
244cdf0e10cSrcweir if ( nCol > 0 && nRow > 0 )
245cdf0e10cSrcweir bGlue = sal_False; // nRow==0 kann DummyUpperLeft sein
246cdf0e10cSrcweir else
247cdf0e10cSrcweir nCol = nC;
248cdf0e10cSrcweir }
249cdf0e10cSrcweir else
250cdf0e10cSrcweir *p = nFree;
251cdf0e10cSrcweir }
252cdf0e10cSrcweir if ( bGlue && *(p = (pA + ((((sal_uLong)nC-1) * nR) + nRow))) == nFree )
253cdf0e10cSrcweir { // Zeile als komplett frei markieren
254cdf0e10cSrcweir *p = nGlue;
255cdf0e10cSrcweir bGlueRows = sal_True; // mindestens eine freie Zeile
256cdf0e10cSrcweir }
257cdf0e10cSrcweir }
258cdf0e10cSrcweir
259cdf0e10cSrcweir // n=1: die linke obere Ecke koennte bei Beschriftung automagisch
260cdf0e10cSrcweir // hinzugezogen werden
261cdf0e10cSrcweir p = pA + 1;
262cdf0e10cSrcweir for ( sal_uLong n = 1; bGlue && n < nCR; n++, p++ )
263cdf0e10cSrcweir { // ein unberuehrtes Feld heisst, dass es weder spaltenweise noch
264cdf0e10cSrcweir // zeilenweise zu erreichen war, also nichts zusamenzufassen
265cdf0e10cSrcweir if ( *p == nHole )
266cdf0e10cSrcweir bGlue = sal_False;
267cdf0e10cSrcweir }
268cdf0e10cSrcweir if ( bGlue )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir if ( bGlueCols && bGlueRows )
271cdf0e10cSrcweir eGlue = SC_CHARTGLUE_BOTH;
272cdf0e10cSrcweir else if ( bGlueRows )
273cdf0e10cSrcweir eGlue = SC_CHARTGLUE_ROWS;
274cdf0e10cSrcweir else
275cdf0e10cSrcweir eGlue = SC_CHARTGLUE_COLS;
276cdf0e10cSrcweir if ( *pA != nOccu )
277cdf0e10cSrcweir bDummyUpperLeft = sal_True;
278cdf0e10cSrcweir }
279cdf0e10cSrcweir else
280cdf0e10cSrcweir {
281cdf0e10cSrcweir eGlue = SC_CHARTGLUE_NONE;
282cdf0e10cSrcweir }
283cdf0e10cSrcweir
284cdf0e10cSrcweir delete [] pA;
285cdf0e10cSrcweir }
286cdf0e10cSrcweir
CheckColRowHeaders()287cdf0e10cSrcweir void ScChartPositioner::CheckColRowHeaders()
288cdf0e10cSrcweir {
289cdf0e10cSrcweir SCCOL nCol1, nCol2, iCol;
290cdf0e10cSrcweir SCROW nRow1, nRow2, iRow;
291cdf0e10cSrcweir SCTAB nTab1, nTab2;
292cdf0e10cSrcweir
293cdf0e10cSrcweir sal_Bool bColStrings = sal_True;
294cdf0e10cSrcweir sal_Bool bRowStrings = sal_True;
295cdf0e10cSrcweir GlueState();
296cdf0e10cSrcweir if ( aRangeListRef->Count() == 1 )
297cdf0e10cSrcweir {
298cdf0e10cSrcweir aRangeListRef->First()->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
299cdf0e10cSrcweir if ( nCol1 > nCol2 || nRow1 > nRow2 )
300cdf0e10cSrcweir bColStrings = bRowStrings = sal_False;
301cdf0e10cSrcweir else
302cdf0e10cSrcweir {
303cdf0e10cSrcweir for (iCol=nCol1; iCol<=nCol2 && bColStrings; iCol++)
304cdf0e10cSrcweir {
305cdf0e10cSrcweir if (lcl_hasValueDataButNoDates( pDocument, iCol, nRow1, nTab1 ))
306cdf0e10cSrcweir bColStrings = sal_False;
307cdf0e10cSrcweir }
308cdf0e10cSrcweir for (iRow=nRow1; iRow<=nRow2 && bRowStrings; iRow++)
309cdf0e10cSrcweir {
310cdf0e10cSrcweir if (lcl_hasValueDataButNoDates( pDocument, nCol1, iRow, nTab1 ))
311cdf0e10cSrcweir bRowStrings = sal_False;
312cdf0e10cSrcweir }
313cdf0e10cSrcweir }
314cdf0e10cSrcweir }
315cdf0e10cSrcweir else
316cdf0e10cSrcweir {
317cdf0e10cSrcweir sal_Bool bVert = (eGlue == SC_CHARTGLUE_NONE || eGlue == SC_CHARTGLUE_ROWS);
318cdf0e10cSrcweir for ( ScRangePtr pR = aRangeListRef->First();
319cdf0e10cSrcweir pR && (bColStrings || bRowStrings);
320cdf0e10cSrcweir pR = aRangeListRef->Next() )
321cdf0e10cSrcweir {
322cdf0e10cSrcweir pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
323cdf0e10cSrcweir sal_Bool bTopRow = (nRow1 == nStartRow);
324cdf0e10cSrcweir if ( bRowStrings && (bVert || nCol1 == nStartCol) )
325cdf0e10cSrcweir { // NONE oder ROWS: RowStrings in jeder Selektion moeglich
326cdf0e10cSrcweir // COLS oder BOTH: nur aus der ersten Spalte
327cdf0e10cSrcweir if ( nCol1 <= nCol2 )
328cdf0e10cSrcweir for (iRow=nRow1; iRow<=nRow2 && bRowStrings; iRow++)
329cdf0e10cSrcweir {
330cdf0e10cSrcweir if (lcl_hasValueDataButNoDates( pDocument, nCol1, iRow, nTab1 ))
331cdf0e10cSrcweir bRowStrings = sal_False;
332cdf0e10cSrcweir }
333cdf0e10cSrcweir }
334cdf0e10cSrcweir if ( bColStrings && bTopRow )
335cdf0e10cSrcweir { // ColStrings nur aus der ersten Zeile
336cdf0e10cSrcweir if ( nRow1 <= nRow2 )
337cdf0e10cSrcweir for (iCol=nCol1; iCol<=nCol2 && bColStrings; iCol++)
338cdf0e10cSrcweir {
339cdf0e10cSrcweir if (lcl_hasValueDataButNoDates( pDocument, iCol, nRow1, nTab1 ))
340cdf0e10cSrcweir bColStrings = sal_False;
341cdf0e10cSrcweir }
342cdf0e10cSrcweir }
343cdf0e10cSrcweir }
344cdf0e10cSrcweir }
345cdf0e10cSrcweir bColHeaders = bColStrings;
346cdf0e10cSrcweir bRowHeaders = bRowStrings;
347cdf0e10cSrcweir }
348cdf0e10cSrcweir
GetPositionMap()349cdf0e10cSrcweir const ScChartPositionMap* ScChartPositioner::GetPositionMap()
350cdf0e10cSrcweir {
351cdf0e10cSrcweir CreatePositionMap();
352cdf0e10cSrcweir return pPositionMap;
353cdf0e10cSrcweir }
354cdf0e10cSrcweir
355cdf0e10cSrcweir
CreatePositionMap()356cdf0e10cSrcweir void ScChartPositioner::CreatePositionMap()
357cdf0e10cSrcweir {
358cdf0e10cSrcweir if ( eGlue == SC_CHARTGLUE_NA && pPositionMap )
359cdf0e10cSrcweir {
360cdf0e10cSrcweir delete pPositionMap;
361cdf0e10cSrcweir pPositionMap = NULL;
362cdf0e10cSrcweir }
363cdf0e10cSrcweir
364cdf0e10cSrcweir if ( pPositionMap )
365cdf0e10cSrcweir return ;
366cdf0e10cSrcweir
367cdf0e10cSrcweir SCSIZE nColAdd = bRowHeaders ? 1 : 0;
368cdf0e10cSrcweir SCSIZE nRowAdd = bColHeaders ? 1 : 0;
369cdf0e10cSrcweir
370cdf0e10cSrcweir SCCOL nCol, nCol1, nCol2;
371cdf0e10cSrcweir SCROW nRow, nRow1, nRow2;
372cdf0e10cSrcweir SCTAB nTab, nTab1, nTab2;
373cdf0e10cSrcweir
374cdf0e10cSrcweir //
375cdf0e10cSrcweir // wirkliche Groesse (ohne versteckte Zeilen/Spalten)
376cdf0e10cSrcweir //
377cdf0e10cSrcweir
378cdf0e10cSrcweir SCSIZE nColCount = 0;
379cdf0e10cSrcweir SCSIZE nRowCount = 0;
380cdf0e10cSrcweir
381cdf0e10cSrcweir GlueState();
382cdf0e10cSrcweir
383cdf0e10cSrcweir sal_Bool bNoGlue = (eGlue == SC_CHARTGLUE_NONE);
384cdf0e10cSrcweir Table* pCols = new Table;
385cdf0e10cSrcweir Table* pNewRowTable = new Table;
386cdf0e10cSrcweir ScAddress* pNewAddress = new ScAddress;
387cdf0e10cSrcweir ScRangePtr pR;
388cdf0e10cSrcweir Table* pCol;
389cdf0e10cSrcweir ScAddress* pPos;
390cdf0e10cSrcweir SCROW nNoGlueRow = 0;
391cdf0e10cSrcweir for ( pR = aRangeListRef->First(); pR; pR = aRangeListRef->Next() )
392cdf0e10cSrcweir {
393cdf0e10cSrcweir pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
394cdf0e10cSrcweir for ( nTab = nTab1; nTab <= nTab2; nTab++ )
395cdf0e10cSrcweir {
396cdf0e10cSrcweir // nTab im ColKey, um gleiche Col/Row in anderer Table haben zu koennen
397cdf0e10cSrcweir sal_uLong nInsCol = (static_cast<sal_uLong>(nTab) << 16) | (bNoGlue ? 0 :
398cdf0e10cSrcweir static_cast<sal_uLong>(nCol1));
399cdf0e10cSrcweir for ( nCol = nCol1; nCol <= nCol2; ++nCol, ++nInsCol )
400cdf0e10cSrcweir {
401cdf0e10cSrcweir if ( bNoGlue || eGlue == SC_CHARTGLUE_ROWS )
402cdf0e10cSrcweir { // meistens gleiche Cols
403cdf0e10cSrcweir if ( (pCol = (Table*) pCols->Get( nInsCol ))==NULL )
404cdf0e10cSrcweir {
405cdf0e10cSrcweir pCols->Insert( nInsCol, pNewRowTable );
406cdf0e10cSrcweir pCol = pNewRowTable;
407cdf0e10cSrcweir pNewRowTable = new Table;
408cdf0e10cSrcweir }
409cdf0e10cSrcweir }
410cdf0e10cSrcweir else
411cdf0e10cSrcweir { // meistens neue Cols
412cdf0e10cSrcweir if ( pCols->Insert( nInsCol, pNewRowTable ) )
413cdf0e10cSrcweir {
414cdf0e10cSrcweir pCol = pNewRowTable;
415cdf0e10cSrcweir pNewRowTable = new Table;
416cdf0e10cSrcweir }
417cdf0e10cSrcweir else
418cdf0e10cSrcweir pCol = (Table*) pCols->Get( nInsCol );
419cdf0e10cSrcweir }
420cdf0e10cSrcweir // bei anderer Tabelle wurde bereits neuer ColKey erzeugt,
421cdf0e10cSrcweir // die Zeilen muessen fuer's Dummy fuellen gleich sein!
422cdf0e10cSrcweir sal_uLong nInsRow = (bNoGlue ? nNoGlueRow : nRow1);
423cdf0e10cSrcweir for ( nRow = nRow1; nRow <= nRow2; nRow++, nInsRow++ )
424cdf0e10cSrcweir {
425cdf0e10cSrcweir if ( pCol->Insert( nInsRow, pNewAddress ) )
426cdf0e10cSrcweir {
427cdf0e10cSrcweir pNewAddress->Set( nCol, nRow, nTab );
428cdf0e10cSrcweir pNewAddress = new ScAddress;
429cdf0e10cSrcweir }
430cdf0e10cSrcweir }
431cdf0e10cSrcweir }
432cdf0e10cSrcweir }
433cdf0e10cSrcweir // bei NoGlue werden zusammengehoerige Tabellen als ColGlue dargestellt
434cdf0e10cSrcweir nNoGlueRow += nRow2 - nRow1 + 1;
435cdf0e10cSrcweir }
436cdf0e10cSrcweir delete pNewAddress;
437cdf0e10cSrcweir delete pNewRowTable;
438cdf0e10cSrcweir
439cdf0e10cSrcweir // Anzahl der Daten
440cdf0e10cSrcweir nColCount = static_cast< SCSIZE >( pCols->Count());
441cdf0e10cSrcweir if ( (pCol = (Table*) pCols->First())!=NULL )
442cdf0e10cSrcweir {
443cdf0e10cSrcweir if ( bDummyUpperLeft )
444cdf0e10cSrcweir pCol->Insert( 0, (void*)0 ); // Dummy fuer Beschriftung
445cdf0e10cSrcweir nRowCount = static_cast< SCSIZE >( pCol->Count());
446cdf0e10cSrcweir }
447cdf0e10cSrcweir else
448cdf0e10cSrcweir nRowCount = 0;
449cdf0e10cSrcweir if ( nColCount > 0 )
450cdf0e10cSrcweir nColCount -= nColAdd;
451cdf0e10cSrcweir if ( nRowCount > 0 )
452cdf0e10cSrcweir nRowCount -= nRowAdd;
453cdf0e10cSrcweir
454cdf0e10cSrcweir if ( nColCount==0 || nRowCount==0 )
455cdf0e10cSrcweir { // einen Eintrag ohne Daten erzeugen
456cdf0e10cSrcweir pR = aRangeListRef->First();
457cdf0e10cSrcweir if ( pCols->Count() > 0 )
458cdf0e10cSrcweir pCol = (Table*) pCols->First();
459cdf0e10cSrcweir else
460cdf0e10cSrcweir {
461cdf0e10cSrcweir pCol = new Table;
462cdf0e10cSrcweir pCols->Insert( 0, pCol );
463cdf0e10cSrcweir }
464cdf0e10cSrcweir nColCount = 1;
465cdf0e10cSrcweir if ( pCol->Count() > 0 )
466cdf0e10cSrcweir { // kann ja eigentlich nicht sein, wenn nColCount==0 || nRowCount==0
467cdf0e10cSrcweir pPos = (ScAddress*) pCol->First();
468cdf0e10cSrcweir if ( pPos )
469cdf0e10cSrcweir {
470cdf0e10cSrcweir delete pPos;
471cdf0e10cSrcweir pCol->Replace( pCol->GetCurKey(), (void*)0 );
472cdf0e10cSrcweir }
473cdf0e10cSrcweir }
474cdf0e10cSrcweir else
475cdf0e10cSrcweir pCol->Insert( 0, (void*)0 );
476cdf0e10cSrcweir nRowCount = 1;
477cdf0e10cSrcweir nColAdd = 0;
478cdf0e10cSrcweir nRowAdd = 0;
479cdf0e10cSrcweir }
480cdf0e10cSrcweir else
481cdf0e10cSrcweir {
482cdf0e10cSrcweir if ( bNoGlue )
483cdf0e10cSrcweir { // Luecken mit Dummies fuellen, erste Spalte ist Master
484cdf0e10cSrcweir Table* pFirstCol = (Table*) pCols->First();
485cdf0e10cSrcweir sal_uLong nCount = pFirstCol->Count();
486cdf0e10cSrcweir pFirstCol->First();
487cdf0e10cSrcweir for ( sal_uLong n = 0; n < nCount; n++, pFirstCol->Next() )
488cdf0e10cSrcweir {
489cdf0e10cSrcweir sal_uLong nKey = pFirstCol->GetCurKey();
490cdf0e10cSrcweir pCols->First();
491cdf0e10cSrcweir while ( (pCol = (Table*) pCols->Next())!=NULL )
492cdf0e10cSrcweir pCol->Insert( nKey, (void*)0 ); // keine Daten
493cdf0e10cSrcweir }
494cdf0e10cSrcweir }
495cdf0e10cSrcweir }
496cdf0e10cSrcweir
497cdf0e10cSrcweir pPositionMap = new ScChartPositionMap( static_cast<SCCOL>(nColCount), static_cast<SCROW>(nRowCount),
498cdf0e10cSrcweir static_cast<SCCOL>(nColAdd), static_cast<SCROW>(nRowAdd), *pCols );
499cdf0e10cSrcweir
500cdf0e10cSrcweir // Aufraeumen
501cdf0e10cSrcweir for ( pCol = (Table*) pCols->First(); pCol; pCol = (Table*) pCols->Next() )
502cdf0e10cSrcweir { //! nur Tables loeschen, nicht die ScAddress*
503cdf0e10cSrcweir delete pCol;
504cdf0e10cSrcweir }
505cdf0e10cSrcweir delete pCols;
506cdf0e10cSrcweir }
507cdf0e10cSrcweir
508cdf0e10cSrcweir
ScChartPositionMap(SCCOL nChartCols,SCROW nChartRows,SCCOL nColAdd,SCROW nRowAdd,Table & rCols)509cdf0e10cSrcweir ScChartPositionMap::ScChartPositionMap( SCCOL nChartCols, SCROW nChartRows,
510cdf0e10cSrcweir SCCOL nColAdd, SCROW nRowAdd, Table& rCols ) :
511cdf0e10cSrcweir ppData( new ScAddress* [ nChartCols * nChartRows ] ),
512cdf0e10cSrcweir ppColHeader( new ScAddress* [ nChartCols ] ),
513cdf0e10cSrcweir ppRowHeader( new ScAddress* [ nChartRows ] ),
514cdf0e10cSrcweir nCount( (sal_uLong) nChartCols * nChartRows ),
515cdf0e10cSrcweir nColCount( nChartCols ),
516cdf0e10cSrcweir nRowCount( nChartRows )
517cdf0e10cSrcweir {
518cdf0e10cSrcweir DBG_ASSERT( nColCount && nRowCount, "ScChartPositionMap without dimension" );
519cdf0e10cSrcweir
520cdf0e10cSrcweir ScAddress* pPos;
521cdf0e10cSrcweir SCCOL nCol;
522cdf0e10cSrcweir SCROW nRow;
523cdf0e10cSrcweir
524cdf0e10cSrcweir Table* pCol = (Table*) rCols.First();
525cdf0e10cSrcweir
526cdf0e10cSrcweir // Zeilen-Header
527cdf0e10cSrcweir pPos = (ScAddress*) pCol->First();
528cdf0e10cSrcweir if ( nRowAdd )
529cdf0e10cSrcweir pPos = (ScAddress*) pCol->Next();
530cdf0e10cSrcweir if ( nColAdd )
531cdf0e10cSrcweir { // eigenstaendig
532cdf0e10cSrcweir for ( nRow = 0; nRow < nRowCount; nRow++ )
533cdf0e10cSrcweir {
534cdf0e10cSrcweir ppRowHeader[ nRow ] = pPos;
535cdf0e10cSrcweir pPos = (ScAddress*) pCol->Next();
536cdf0e10cSrcweir }
537cdf0e10cSrcweir }
538cdf0e10cSrcweir else
539cdf0e10cSrcweir { // Kopie
540cdf0e10cSrcweir for ( nRow = 0; nRow < nRowCount; nRow++ )
541cdf0e10cSrcweir {
542cdf0e10cSrcweir ppRowHeader[ nRow ] = ( pPos ? new ScAddress( *pPos ) : NULL );
543cdf0e10cSrcweir pPos = (ScAddress*) pCol->Next();
544cdf0e10cSrcweir }
545cdf0e10cSrcweir }
546cdf0e10cSrcweir if ( nColAdd )
547cdf0e10cSrcweir pCol = (Table*) rCols.Next();
548cdf0e10cSrcweir
549cdf0e10cSrcweir // Daten spaltenweise und Spalten-Header
550cdf0e10cSrcweir sal_uLong nIndex = 0;
551cdf0e10cSrcweir for ( nCol = 0; nCol < nColCount; nCol++ )
552cdf0e10cSrcweir {
553cdf0e10cSrcweir if ( pCol )
554cdf0e10cSrcweir {
555cdf0e10cSrcweir pPos = (ScAddress*) pCol->First();
556cdf0e10cSrcweir if ( nRowAdd )
557cdf0e10cSrcweir {
558cdf0e10cSrcweir ppColHeader[ nCol ] = pPos; // eigenstaendig
559cdf0e10cSrcweir pPos = (ScAddress*) pCol->Next();
560cdf0e10cSrcweir }
561cdf0e10cSrcweir else
562cdf0e10cSrcweir ppColHeader[ nCol ] = ( pPos ? new ScAddress( *pPos ) : NULL );
563cdf0e10cSrcweir for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
564cdf0e10cSrcweir {
565cdf0e10cSrcweir ppData[ nIndex ] = pPos;
566cdf0e10cSrcweir pPos = (ScAddress*) pCol->Next();
567cdf0e10cSrcweir }
568cdf0e10cSrcweir }
569cdf0e10cSrcweir else
570cdf0e10cSrcweir {
571cdf0e10cSrcweir ppColHeader[ nCol ] = NULL;
572cdf0e10cSrcweir for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
573cdf0e10cSrcweir {
574cdf0e10cSrcweir ppData[ nIndex ] = NULL;
575cdf0e10cSrcweir }
576cdf0e10cSrcweir }
577cdf0e10cSrcweir pCol = (Table*) rCols.Next();
578cdf0e10cSrcweir }
579cdf0e10cSrcweir }
580cdf0e10cSrcweir
581cdf0e10cSrcweir
~ScChartPositionMap()582cdf0e10cSrcweir ScChartPositionMap::~ScChartPositionMap()
583cdf0e10cSrcweir {
584cdf0e10cSrcweir for ( sal_uLong nIndex=0; nIndex < nCount; nIndex++ )
585cdf0e10cSrcweir {
586cdf0e10cSrcweir delete ppData[nIndex];
587cdf0e10cSrcweir }
588cdf0e10cSrcweir delete [] ppData;
589cdf0e10cSrcweir
590cdf0e10cSrcweir SCCOL j;
591cdf0e10cSrcweir for ( j=0; j < nColCount; j++ )
592cdf0e10cSrcweir {
593cdf0e10cSrcweir delete ppColHeader[j];
594cdf0e10cSrcweir }
595cdf0e10cSrcweir delete [] ppColHeader;
596cdf0e10cSrcweir SCROW i;
597cdf0e10cSrcweir for ( i=0; i < nRowCount; i++ )
598cdf0e10cSrcweir {
599cdf0e10cSrcweir delete ppRowHeader[i];
600cdf0e10cSrcweir }
601cdf0e10cSrcweir delete [] ppRowHeader;
602cdf0e10cSrcweir }
603cdf0e10cSrcweir
604cdf0e10cSrcweir
605cdf0e10cSrcweir //UNUSED2009-05 ScRangeListRef ScChartPositionMap::GetColRanges( SCCOL nChartCol ) const
606cdf0e10cSrcweir //UNUSED2009-05 {
607cdf0e10cSrcweir //UNUSED2009-05 ScRangeListRef xRangeList = new ScRangeList;
608cdf0e10cSrcweir //UNUSED2009-05 if ( nChartCol < nColCount )
609cdf0e10cSrcweir //UNUSED2009-05 {
610cdf0e10cSrcweir //UNUSED2009-05 sal_uLong nStop = GetIndex( nChartCol, nRowCount );
611cdf0e10cSrcweir //UNUSED2009-05 for ( sal_uLong nIndex = GetIndex( nChartCol, 0 ); nIndex < nStop; nIndex++ )
612cdf0e10cSrcweir //UNUSED2009-05 {
613cdf0e10cSrcweir //UNUSED2009-05 if ( ppData[ nIndex ] )
614cdf0e10cSrcweir //UNUSED2009-05 xRangeList->Join( *ppData[ nIndex ] );
615cdf0e10cSrcweir //UNUSED2009-05 }
616cdf0e10cSrcweir //UNUSED2009-05 }
617cdf0e10cSrcweir //UNUSED2009-05 return xRangeList;
618cdf0e10cSrcweir //UNUSED2009-05 }
619cdf0e10cSrcweir
620cdf0e10cSrcweir
621cdf0e10cSrcweir //UNUSED2009-05 ScRangeListRef ScChartPositionMap::GetRowRanges( SCROW nChartRow ) const
622cdf0e10cSrcweir //UNUSED2009-05 {
623cdf0e10cSrcweir //UNUSED2009-05 ScRangeListRef xRangeList = new ScRangeList;
624cdf0e10cSrcweir //UNUSED2009-05 if ( nChartRow < nRowCount )
625cdf0e10cSrcweir //UNUSED2009-05 {
626cdf0e10cSrcweir //UNUSED2009-05 sal_uLong nStop = GetIndex( nColCount, nChartRow );
627cdf0e10cSrcweir //UNUSED2009-05 for ( sal_uLong nIndex = GetIndex( 0, nChartRow ); nIndex < nStop;
628cdf0e10cSrcweir //UNUSED2009-05 nIndex += nRowCount )
629cdf0e10cSrcweir //UNUSED2009-05 {
630cdf0e10cSrcweir //UNUSED2009-05 if ( ppData[ nIndex ] )
631cdf0e10cSrcweir //UNUSED2009-05 xRangeList->Join( *ppData[ nIndex ] );
632cdf0e10cSrcweir //UNUSED2009-05 }
633cdf0e10cSrcweir //UNUSED2009-05 }
634cdf0e10cSrcweir //UNUSED2009-05 return xRangeList;
635cdf0e10cSrcweir //UNUSED2009-05 }
636