fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / tool / consoli.cxx
blobec762b13150c4b1f1b729b7f5ef36304667ae6e3
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 "consoli.hxx"
21 #include "document.hxx"
22 #include "olinetab.hxx"
23 #include "globstr.hrc"
24 #include "subtotal.hxx"
25 #include <formula/errorcodes.hxx>
26 #include "formulacell.hxx"
27 #include "tokenarray.hxx"
28 #include <osl/diagnose.h>
30 #include <math.h>
31 #include <string.h>
32 #include <boost/scoped_array.hpp>
34 #define SC_CONS_NOTFOUND -1
36 // STATIC DATA
37 static const OpCode eOpCodeTable[] = { // Reihenfolge wie bei enum ScSubTotalFunc
38 ocBad, // none
39 ocAverage,
40 ocCount,
41 ocCount2,
42 ocMax,
43 ocMin,
44 ocProduct,
45 ocStDev,
46 ocStDevP,
47 ocSum,
48 ocVar,
49 ocVarP };
51 void ScReferenceList::AddEntry( SCCOL nCol, SCROW nRow, SCTAB nTab )
53 ScReferenceEntry* pOldData = pData;
54 pData = new ScReferenceEntry[ nFullSize+1 ];
55 if (pOldData)
57 memcpy( pData, pOldData, nCount * sizeof(ScReferenceEntry) );
58 delete[] pOldData;
60 while (nCount < nFullSize)
62 pData[nCount].nCol = SC_CONS_NOTFOUND;
63 pData[nCount].nRow = SC_CONS_NOTFOUND;
64 pData[nCount].nTab = SC_CONS_NOTFOUND;
65 ++nCount;
67 pData[nCount].nCol = nCol;
68 pData[nCount].nRow = nRow;
69 pData[nCount].nTab = nTab;
70 ++nCount;
71 nFullSize = nCount;
74 template< typename T >
75 static void lcl_AddString( ::std::vector<OUString>& rData, T& nCount, const OUString& rInsert )
77 rData.push_back( rInsert);
78 ++nCount;
81 ScConsData::ScConsData() :
82 eFunction(SUBTOTAL_FUNC_SUM),
83 bReference(false),
84 bColByName(false),
85 bRowByName(false),
86 nColCount(0),
87 nRowCount(0),
88 ppUsed(NULL),
89 ppSum(NULL),
90 ppCount(NULL),
91 ppSumSqr(NULL),
92 ppRefs(NULL),
93 nDataCount(0),
94 ppTitlePos(NULL),
95 bCornerUsed(false)
99 ScConsData::~ScConsData()
101 DeleteData();
104 #define DELETEARR(ppArray,nCount) \
106 sal_uLong i; \
107 if (ppArray) \
108 for(i=0; i<nCount; i++) \
109 delete[] ppArray[i]; \
110 delete[] ppArray; \
111 ppArray = NULL; \
114 void ScConsData::DeleteData()
116 if (ppRefs)
118 for (SCSIZE i=0; i<nColCount; i++)
120 for (SCSIZE j=0; j<nRowCount; j++)
121 if (ppUsed[i][j])
122 ppRefs[i][j].Clear();
123 delete[] ppRefs[i];
125 delete[] ppRefs;
126 ppRefs = NULL;
129 DELETEARR( ppCount, nColCount );
130 DELETEARR( ppSum, nColCount );
131 DELETEARR( ppSumSqr,nColCount );
132 DELETEARR( ppUsed, nColCount ); // erst nach ppRefs !!!
133 DELETEARR( ppTitlePos, nRowCount );
134 ::std::vector<OUString>().swap( maColHeaders);
135 ::std::vector<OUString>().swap( maRowHeaders);
136 ::std::vector<OUString>().swap( maTitles);
137 nDataCount = 0;
139 if (bColByName) nColCount = 0; // sonst stimmt maColHeaders nicht
140 if (bRowByName) nRowCount = 0;
142 bCornerUsed = false;
143 aCornerText.clear();
146 #undef DELETEARR
147 #undef DELETESTR
149 void ScConsData::InitData()
151 if (bReference && nColCount && !ppRefs)
153 ppRefs = new ScReferenceList*[nColCount];
154 for (SCSIZE i=0; i<nColCount; i++)
155 ppRefs[i] = new ScReferenceList[nRowCount];
157 else if (nColCount && !ppCount)
159 ppCount = new double*[nColCount];
160 ppSum = new double*[nColCount];
161 ppSumSqr = new double*[nColCount];
162 for (SCSIZE i=0; i<nColCount; i++)
164 ppCount[i] = new double[nRowCount];
165 ppSum[i] = new double[nRowCount];
166 ppSumSqr[i] = new double[nRowCount];
170 if (nColCount && !ppUsed)
172 ppUsed = new bool*[nColCount];
173 for (SCSIZE i=0; i<nColCount; i++)
175 ppUsed[i] = new bool[nRowCount];
176 memset( ppUsed[i], 0, nRowCount * sizeof(bool) );
180 if (nRowCount && nDataCount && !ppTitlePos)
182 ppTitlePos = new SCSIZE*[nRowCount];
183 for (SCSIZE i=0; i<nRowCount; i++)
185 ppTitlePos[i] = new SCSIZE[nDataCount];
186 memset( ppTitlePos[i], 0, nDataCount * sizeof(SCSIZE) ); //TODO: not necessary ?
190 // CornerText: einzelner String
193 void ScConsData::DoneFields()
195 InitData();
198 void ScConsData::SetSize( SCCOL nCols, SCROW nRows )
200 DeleteData();
201 nColCount = static_cast<SCSIZE>(nCols);
202 nRowCount = static_cast<SCSIZE>(nRows);
205 void ScConsData::GetSize( SCCOL& rCols, SCROW& rRows ) const
207 rCols = static_cast<SCCOL>(nColCount);
208 rRows = static_cast<SCROW>(nRowCount);
211 void ScConsData::SetFlags( ScSubTotalFunc eFunc, bool bColName, bool bRowName, bool bRef )
213 DeleteData();
214 bReference = bRef;
215 bColByName = bColName;
216 if (bColName) nColCount = 0;
217 bRowByName = bRowName;
218 if (bRowName) nRowCount = 0;
219 eFunction = eFunc;
222 void ScConsData::AddFields( ScDocument* pSrcDoc, SCTAB nTab,
223 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
225 ++nDataCount;
227 OUString aTitle;
229 SCCOL nStartCol = nCol1;
230 SCROW nStartRow = nRow1;
231 if (bColByName) ++nStartRow;
232 if (bRowByName) ++nStartCol;
234 if (bColByName)
236 for (SCCOL nCol=nStartCol; nCol<=nCol2; nCol++)
238 aTitle = pSrcDoc->GetString(nCol, nRow1, nTab);
239 if (!aTitle.isEmpty())
241 bool bFound = false;
242 for (SCSIZE i=0; i<nColCount && !bFound; i++)
243 if ( maColHeaders[i] == aTitle )
244 bFound = true;
245 if (!bFound)
246 lcl_AddString( maColHeaders, nColCount, aTitle );
251 if (bRowByName)
253 for (SCROW nRow=nStartRow; nRow<=nRow2; nRow++)
255 aTitle = pSrcDoc->GetString(nCol1, nRow, nTab);
256 if (!aTitle.isEmpty())
258 bool bFound = false;
259 for (SCSIZE i=0; i<nRowCount && !bFound; i++)
260 if ( maRowHeaders[i] == aTitle )
261 bFound = true;
262 if (!bFound)
263 lcl_AddString( maRowHeaders, nRowCount, aTitle );
269 void ScConsData::AddName( const OUString& rName )
271 SCSIZE nArrX;
272 SCSIZE nArrY;
274 if (bReference)
276 maTitles.push_back( rName);
277 size_t nTitleCount = maTitles.size();
279 for (nArrY=0; nArrY<nRowCount; nArrY++)
281 // Daten auf gleiche Laenge bringen
283 SCSIZE nMax = 0;
284 for (nArrX=0; nArrX<nColCount; nArrX++)
285 if (ppUsed[nArrX][nArrY])
286 nMax = std::max( nMax, ppRefs[nArrX][nArrY].GetCount() );
288 for (nArrX=0; nArrX<nColCount; nArrX++)
290 if (!ppUsed[nArrX][nArrY])
292 ppUsed[nArrX][nArrY] = true;
293 ppRefs[nArrX][nArrY].Init();
295 ppRefs[nArrX][nArrY].SetFullSize(nMax);
298 // Positionen eintragen
300 if (ppTitlePos)
301 if (nTitleCount < nDataCount)
302 ppTitlePos[nArrY][nTitleCount] = nMax;
307 // rCount < 0 <=> Fehler aufgetreten
309 static void lcl_UpdateArray( ScSubTotalFunc eFunc,
310 double& rCount, double& rSum, double& rSumSqr, double nVal )
312 if (rCount < 0.0)
313 return;
314 switch (eFunc)
316 case SUBTOTAL_FUNC_SUM:
317 if (!SubTotal::SafePlus(rSum, nVal))
318 rCount = -MAXDOUBLE;
319 break;
320 case SUBTOTAL_FUNC_PROD:
321 if (!SubTotal::SafeMult(rSum, nVal))
322 rCount = -MAXDOUBLE;
323 break;
324 case SUBTOTAL_FUNC_CNT:
325 case SUBTOTAL_FUNC_CNT2:
326 rCount += 1.0;
327 break;
328 case SUBTOTAL_FUNC_AVE:
329 if (!SubTotal::SafePlus(rSum, nVal))
330 rCount = -MAXDOUBLE;
331 else
332 rCount += 1.0;
333 break;
334 case SUBTOTAL_FUNC_MAX:
335 if (nVal > rSum)
336 rSum = nVal;
337 break;
338 case SUBTOTAL_FUNC_MIN:
339 if (nVal < rSum)
340 rSum = nVal;
341 break;
342 case SUBTOTAL_FUNC_STD:
343 case SUBTOTAL_FUNC_STDP:
344 case SUBTOTAL_FUNC_VAR:
345 case SUBTOTAL_FUNC_VARP:
347 bool bOk = SubTotal::SafePlus(rSum, nVal);
348 bOk = bOk && SubTotal::SafeMult(nVal, nVal);
349 bOk = bOk && SubTotal::SafePlus(rSumSqr, nVal);
350 if (!bOk)
351 rCount = -MAXDOUBLE;
352 else
353 rCount += 1.0;
354 break;
356 default:
358 // added to avoid warnings
363 static void lcl_InitArray( ScSubTotalFunc eFunc,
364 double& rCount, double& rSum, double& rSumSqr, double nVal )
366 rCount = 1.0;
367 switch (eFunc)
369 case SUBTOTAL_FUNC_SUM:
370 case SUBTOTAL_FUNC_MAX:
371 case SUBTOTAL_FUNC_MIN:
372 case SUBTOTAL_FUNC_PROD:
373 case SUBTOTAL_FUNC_AVE:
374 rSum = nVal;
375 break;
376 case SUBTOTAL_FUNC_STD:
377 case SUBTOTAL_FUNC_STDP:
378 case SUBTOTAL_FUNC_VAR:
379 case SUBTOTAL_FUNC_VARP:
381 rSum = nVal;
382 bool bOk = SubTotal::SafeMult(nVal, nVal);
383 if (bOk)
384 rSumSqr = nVal;
385 else
386 rCount = -MAXDOUBLE;
388 break;
389 default:
390 break;
394 static double lcl_CalcData( ScSubTotalFunc eFunc,
395 double& fCount, double fSum, double fSumSqr)
397 if (fCount < 0.0)
398 return 0.0;
399 double fVal = 0.0;
400 switch (eFunc)
402 case SUBTOTAL_FUNC_CNT:
403 case SUBTOTAL_FUNC_CNT2:
404 fVal = fCount;
405 break;
406 case SUBTOTAL_FUNC_SUM:
407 case SUBTOTAL_FUNC_MAX:
408 case SUBTOTAL_FUNC_MIN:
409 case SUBTOTAL_FUNC_PROD:
410 fVal = fSum;
411 break;
412 case SUBTOTAL_FUNC_AVE:
413 if (fCount > 0.0)
414 fVal = fSum / fCount;
415 else
416 fCount = -MAXDOUBLE;
417 break;
418 case SUBTOTAL_FUNC_STD:
420 if (fCount > 1 && SubTotal::SafeMult(fSum, fSum))
421 fVal = sqrt((fSumSqr - fSum/fCount)/(fCount-1.0));
422 else
423 fCount = -MAXDOUBLE;
425 break;
426 case SUBTOTAL_FUNC_STDP:
428 if (fCount > 0 && SubTotal::SafeMult(fSum, fSum))
429 fVal = sqrt((fSumSqr - fSum/fCount)/fCount);
430 else
431 fCount = -MAXDOUBLE;
433 break;
434 case SUBTOTAL_FUNC_VAR:
436 if (fCount > 1 && SubTotal::SafeMult(fSum, fSum))
437 fVal = (fSumSqr - fSum/fCount)/(fCount-1.0);
438 else
439 fCount = -MAXDOUBLE;
441 break;
442 case SUBTOTAL_FUNC_VARP:
444 if (fCount > 0 && SubTotal::SafeMult(fSum, fSum))
445 fVal = (fSumSqr - fSum/fCount)/fCount;
446 else
447 fCount = -MAXDOUBLE;
449 break;
450 default:
452 OSL_FAIL("Consoli::CalcData: unknown function");
453 fCount = -MAXDOUBLE;
455 break;
457 return fVal;
460 void ScConsData::AddData( ScDocument* pSrcDoc, SCTAB nTab,
461 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
463 PutInOrder(nCol1,nCol2);
464 PutInOrder(nRow1,nRow2);
465 if ( nCol2 >= sal::static_int_cast<SCCOL>(nCol1 + nColCount) && !bColByName )
467 OSL_FAIL("range too big");
468 nCol2 = sal::static_int_cast<SCCOL>( nCol1 + nColCount - 1 );
470 if ( nRow2 >= sal::static_int_cast<SCROW>(nRow1 + nRowCount) && !bRowByName )
472 OSL_FAIL("range too big");
473 nRow2 = sal::static_int_cast<SCROW>( nRow1 + nRowCount - 1 );
476 SCCOL nCol;
477 SCROW nRow;
479 // Ecke links oben
481 if ( bColByName && bRowByName )
483 OUString aThisCorner = pSrcDoc->GetString(nCol1, nRow1, nTab);
484 if (bCornerUsed)
486 if (aCornerText != aThisCorner)
487 aCornerText.clear();
489 else
491 aCornerText = aThisCorner;
492 bCornerUsed = true;
496 // Titel suchen
498 SCCOL nStartCol = nCol1;
499 SCROW nStartRow = nRow1;
500 if (bColByName) ++nStartRow;
501 if (bRowByName) ++nStartCol;
502 OUString aTitle;
503 boost::scoped_array<SCCOL> pDestCols;
504 boost::scoped_array<SCROW> pDestRows;
505 if (bColByName)
507 pDestCols.reset(new SCCOL[nCol2-nStartCol+1]);
508 for (nCol=nStartCol; nCol<=nCol2; nCol++)
510 aTitle = pSrcDoc->GetString(nCol, nRow1, nTab);
511 SCCOL nPos = SC_CONS_NOTFOUND;
512 if (!aTitle.isEmpty())
514 bool bFound = false;
515 for (SCSIZE i=0; i<nColCount && !bFound; i++)
516 if ( maColHeaders[i] == aTitle )
518 nPos = static_cast<SCCOL>(i);
519 bFound = true;
521 OSL_ENSURE(bFound, "column not found");
523 pDestCols[nCol-nStartCol] = nPos;
526 if (bRowByName)
528 pDestRows.reset(new SCROW[nRow2-nStartRow+1]);
529 for (nRow=nStartRow; nRow<=nRow2; nRow++)
531 aTitle = pSrcDoc->GetString(nCol1, nRow, nTab);
532 SCROW nPos = SC_CONS_NOTFOUND;
533 if (!aTitle.isEmpty())
535 bool bFound = false;
536 for (SCSIZE i=0; i<nRowCount && !bFound; i++)
537 if ( maRowHeaders[i] == aTitle )
539 nPos = static_cast<SCROW>(i);
540 bFound = true;
542 OSL_ENSURE(bFound, "row not found");
544 pDestRows[nRow-nStartRow] = nPos;
547 nCol1 = nStartCol;
548 nRow1 = nStartRow;
550 // Daten
552 bool bAnyCell = ( eFunction == SUBTOTAL_FUNC_CNT2 );
553 for (nCol=nCol1; nCol<=nCol2; nCol++)
555 SCCOL nArrX = nCol-nCol1;
556 if (bColByName) nArrX = pDestCols[nArrX];
557 if (nArrX != SC_CONS_NOTFOUND)
559 for (nRow=nRow1; nRow<=nRow2; nRow++)
561 SCROW nArrY = nRow-nRow1;
562 if (bRowByName) nArrY = pDestRows[nArrY];
563 if ( nArrY != SC_CONS_NOTFOUND && (
564 bAnyCell ? pSrcDoc->HasData( nCol, nRow, nTab )
565 : pSrcDoc->HasValueData( nCol, nRow, nTab ) ) )
567 if (bReference)
569 if (ppUsed[nArrX][nArrY])
570 ppRefs[nArrX][nArrY].AddEntry( nCol, nRow, nTab );
571 else
573 ppUsed[nArrX][nArrY] = true;
574 ppRefs[nArrX][nArrY].Init();
575 ppRefs[nArrX][nArrY].AddEntry( nCol, nRow, nTab );
578 else
580 double nVal;
581 pSrcDoc->GetValue( nCol, nRow, nTab, nVal );
582 if (ppUsed[nArrX][nArrY])
583 lcl_UpdateArray( eFunction, ppCount[nArrX][nArrY],
584 ppSum[nArrX][nArrY], ppSumSqr[nArrX][nArrY],
585 nVal);
586 else
588 ppUsed[nArrX][nArrY] = true;
589 lcl_InitArray( eFunction, ppCount[nArrX][nArrY],
590 ppSum[nArrX][nArrY],
591 ppSumSqr[nArrX][nArrY], nVal );
600 // vorher testen, wieviele Zeilen eingefuegt werden (fuer Undo)
602 SCROW ScConsData::GetInsertCount() const
604 SCROW nInsert = 0;
605 SCSIZE nArrX;
606 SCSIZE nArrY;
607 if ( ppRefs && ppUsed )
609 for (nArrY=0; nArrY<nRowCount; nArrY++)
611 SCSIZE nNeeded = 0;
612 for (nArrX=0; nArrX<nColCount; nArrX++)
613 if (ppUsed[nArrX][nArrY])
614 nNeeded = std::max( nNeeded, ppRefs[nArrX][nArrY].GetCount() );
616 nInsert += nNeeded;
619 return nInsert;
622 // store completed data to document
623 //TODO: optimize on columns?
625 void ScConsData::OutputToDocument( ScDocument* pDestDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
627 OpCode eOpCode = eOpCodeTable[eFunction];
629 SCSIZE nArrX;
630 SCSIZE nArrY;
632 // Ecke links oben
634 if ( bColByName && bRowByName && !aCornerText.isEmpty() )
635 pDestDoc->SetString( nCol, nRow, nTab, aCornerText );
637 // Titel
639 SCCOL nStartCol = nCol;
640 SCROW nStartRow = nRow;
641 if (bColByName) ++nStartRow;
642 if (bRowByName) ++nStartCol;
644 if (bColByName)
645 for (SCSIZE i=0; i<nColCount; i++)
646 pDestDoc->SetString( sal::static_int_cast<SCCOL>(nStartCol+i), nRow, nTab, maColHeaders[i] );
647 if (bRowByName)
648 for (SCSIZE j=0; j<nRowCount; j++)
649 pDestDoc->SetString( nCol, sal::static_int_cast<SCROW>(nStartRow+j), nTab, maRowHeaders[j] );
651 nCol = nStartCol;
652 nRow = nStartRow;
654 // Daten
656 if ( ppCount && ppUsed ) // Werte direkt einfuegen
658 for (nArrX=0; nArrX<nColCount; nArrX++)
659 for (nArrY=0; nArrY<nRowCount; nArrY++)
660 if (ppUsed[nArrX][nArrY])
662 double fVal = lcl_CalcData( eFunction, ppCount[nArrX][nArrY],
663 ppSum[nArrX][nArrY],
664 ppSumSqr[nArrX][nArrY]);
665 if (ppCount[nArrX][nArrY] < 0.0)
666 pDestDoc->SetError( sal::static_int_cast<SCCOL>(nCol+nArrX),
667 sal::static_int_cast<SCROW>(nRow+nArrY), nTab, errNoValue );
668 else
669 pDestDoc->SetValue( sal::static_int_cast<SCCOL>(nCol+nArrX),
670 sal::static_int_cast<SCROW>(nRow+nArrY), nTab, fVal );
674 if ( ppRefs && ppUsed ) // insert Reference
676 //TODO: differentiate, if split into categories
677 OUString aString;
679 ScSingleRefData aSRef; // data for Referece formula cells
680 aSRef.InitFlags(); // this reference is absolute at all times
681 aSRef.SetFlag3D(true);
683 ScComplexRefData aCRef; // data for Sum cells
684 aCRef.InitFlags();
685 aCRef.Ref1.SetColRel(true); aCRef.Ref1.SetRowRel(true); aCRef.Ref1.SetTabRel(true);
686 aCRef.Ref2.SetColRel(true); aCRef.Ref2.SetRowRel(true); aCRef.Ref2.SetTabRel(true);
688 for (nArrY=0; nArrY<nRowCount; nArrY++)
690 SCSIZE nNeeded = 0;
691 for (nArrX=0; nArrX<nColCount; nArrX++)
692 if (ppUsed[nArrX][nArrY])
693 nNeeded = std::max( nNeeded, ppRefs[nArrX][nArrY].GetCount() );
695 if (nNeeded)
697 pDestDoc->InsertRow( 0,nTab, MAXCOL,nTab, nRow+nArrY, nNeeded );
699 for (nArrX=0; nArrX<nColCount; nArrX++)
700 if (ppUsed[nArrX][nArrY])
702 ScReferenceList& rList = ppRefs[nArrX][nArrY];
703 SCSIZE nCount = rList.GetCount();
704 if (nCount)
706 for (SCSIZE nPos=0; nPos<nCount; nPos++)
708 ScReferenceEntry aRef = rList.GetEntry(nPos);
709 if (aRef.nTab != SC_CONS_NOTFOUND)
711 // Referenz einfuegen (absolut, 3d)
713 aSRef.SetAddress(ScAddress(aRef.nCol,aRef.nRow,aRef.nTab), ScAddress());
715 ScTokenArray aRefArr;
716 aRefArr.AddSingleReference(aSRef);
717 aRefArr.AddOpCode(ocStop);
718 ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX),
719 sal::static_int_cast<SCROW>(nRow+nArrY+nPos), nTab );
720 ScFormulaCell* pCell = new ScFormulaCell(pDestDoc, aDest, aRefArr);
721 pDestDoc->SetFormulaCell(aDest, pCell);
725 // Summe einfuegen (relativ, nicht 3d)
727 ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX),
728 sal::static_int_cast<SCROW>(nRow+nArrY+nNeeded), nTab );
730 ScRange aRange(sal::static_int_cast<SCCOL>(nCol+nArrX), nRow+nArrY, nTab);
731 aRange.aEnd.SetRow(nRow+nArrY+nNeeded-1);
732 aCRef.SetRange(aRange, aDest);
734 ScTokenArray aArr;
735 aArr.AddOpCode(eOpCode); // ausgewaehlte Funktion
736 aArr.AddOpCode(ocOpen);
737 aArr.AddDoubleReference(aCRef);
738 aArr.AddOpCode(ocClose);
739 aArr.AddOpCode(ocStop);
740 ScFormulaCell* pCell = new ScFormulaCell(pDestDoc, aDest, aArr);
741 pDestDoc->SetFormulaCell(aDest, pCell);
745 // Gliederung einfuegen
747 ScOutlineArray& rOutArr = pDestDoc->GetOutlineTable( nTab, true )->GetRowArray();
748 SCROW nOutStart = nRow+nArrY;
749 SCROW nOutEnd = nRow+nArrY+nNeeded-1;
750 bool bSize = false;
751 rOutArr.Insert( nOutStart, nOutEnd, bSize );
752 for (SCROW nOutRow=nOutStart; nOutRow<=nOutEnd; nOutRow++)
753 pDestDoc->ShowRow( nOutRow, nTab, false );
754 pDestDoc->SetDrawPageSize(nTab);
755 pDestDoc->UpdateOutlineRow( nOutStart, nOutEnd, nTab, false );
757 // Zwischentitel
759 if (ppTitlePos && !maTitles.empty() && !maRowHeaders.empty())
761 OUString aDelim( " / " );
762 for (SCSIZE nPos=0; nPos<nDataCount; nPos++)
764 SCSIZE nTPos = ppTitlePos[nArrY][nPos];
765 bool bDo = true;
766 if (nPos+1<nDataCount)
767 if (ppTitlePos[nArrY][nPos+1] == nTPos)
768 bDo = false; // leer
769 if ( bDo && nTPos < nNeeded )
771 aString = maRowHeaders[nArrY];
772 aString += aDelim;
773 aString += maTitles[nPos];
774 pDestDoc->SetString( nCol-1, nRow+nArrY+nTPos, nTab, aString );
779 nRow += nNeeded;
785 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */