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