Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / data / table1.cxx
blob4eed3b05ab6c51394d82c20507d6b7e964a4015e
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 "scitems.hxx"
21 #include <svx/algitem.hxx>
22 #include <editeng/justifyitem.hxx>
23 #include <unotools/textsearch.hxx>
24 #include <sfx2/objsh.hxx>
26 #include "attrib.hxx"
27 #include "patattr.hxx"
28 #include "formulacell.hxx"
29 #include "table.hxx"
30 #include "document.hxx"
31 #include "drwlayer.hxx"
32 #include "olinetab.hxx"
33 #include "stlsheet.hxx"
34 #include "global.hxx"
35 #include "globstr.hrc"
36 #include "refupdat.hxx"
37 #include "markdata.hxx"
38 #include "progress.hxx"
39 #include "hints.hxx"
40 #include "prnsave.hxx"
41 #include "tabprotection.hxx"
42 #include "sheetevents.hxx"
43 #include "segmenttree.hxx"
44 #include "dbdata.hxx"
45 #include "colorscale.hxx"
46 #include "conditio.hxx"
47 #include "globalnames.hxx"
48 #include "cellvalue.hxx"
49 #include "scmatrix.hxx"
50 #include "refupdatecontext.hxx"
52 #include "formula/vectortoken.hxx"
54 #include <vector>
56 using ::std::vector;
58 namespace {
60 ScProgress* GetProgressBar(
61 SCSIZE nCount, SCSIZE nTotalCount, ScProgress* pOuterProgress, ScDocument* pDoc)
63 if (nTotalCount < 1000)
65 // if the total number of rows is less than 1000, don't even bother
66 // with the progress bar because drawing progress bar can be very
67 // expensive especially in GTK.
68 return NULL;
71 if (pOuterProgress)
72 return pOuterProgress;
74 if (nCount > 1)
75 return new ScProgress(
76 pDoc->GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nTotalCount);
78 return NULL;
81 void GetOptimalHeightsInColumn(
82 ScColumn* pCol, SCROW nStartRow, SCROW nEndRow, vector<sal_uInt16>& aHeights,
83 OutputDevice* pDev, double nPPTX, double nPPTY, const Fraction& rZoomX, const Fraction& rZoomY, bool bForce,
84 ScProgress* pProgress, sal_uInt32 nProgressStart)
86 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
88 // zuerst einmal ueber den ganzen Bereich
89 // (mit der letzten Spalte in der Hoffnung, dass die am ehesten noch auf
90 // Standard formatiert ist)
92 pCol[MAXCOL].GetOptimalHeight(
93 nStartRow, nEndRow, &aHeights[0], pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce, 0, 0 );
95 // daraus Standardhoehe suchen, die im unteren Bereich gilt
97 sal_uInt16 nMinHeight = aHeights[nCount-1];
98 SCSIZE nPos = nCount-1;
99 while ( nPos && aHeights[nPos-1] >= nMinHeight )
100 --nPos;
101 SCROW nMinStart = nStartRow + nPos;
103 sal_uLong nWeightedCount = 0;
104 for (SCCOL nCol=0; nCol<MAXCOL; nCol++) // MAXCOL schon oben
106 pCol[nCol].GetOptimalHeight(
107 nStartRow, nEndRow, &aHeights[0], pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce,
108 nMinHeight, nMinStart );
110 if (pProgress)
112 sal_uLong nWeight = pCol[nCol].GetWeightedCount();
113 if (nWeight) // nochmal denselben Status muss auch nicht sein
115 nWeightedCount += nWeight;
116 pProgress->SetState( nWeightedCount + nProgressStart );
122 struct OptimalHeightsFuncObjBase
124 virtual ~OptimalHeightsFuncObjBase() {}
125 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight) = 0;
128 struct SetRowHeightOnlyFunc : public OptimalHeightsFuncObjBase
130 ScTable* mpTab;
131 SetRowHeightOnlyFunc(ScTable* pTab) :
132 mpTab(pTab)
135 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight)
137 mpTab->SetRowHeightOnly(nStartRow, nEndRow, nHeight);
138 return false;
142 struct SetRowHeightRangeFunc : public OptimalHeightsFuncObjBase
144 ScTable* mpTab;
145 double mnPPTX;
146 double mnPPTY;
148 SetRowHeightRangeFunc(ScTable* pTab, double nPPTX, double nPPTY) :
149 mpTab(pTab),
150 mnPPTX(nPPTX),
151 mnPPTY(nPPTY)
154 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight)
156 return mpTab->SetRowHeightRange(nStartRow, nEndRow, nHeight, mnPPTX, mnPPTY);
160 bool SetOptimalHeightsToRows(OptimalHeightsFuncObjBase& rFuncObj,
161 ScBitMaskCompressedArray<SCROW, sal_uInt8>* pRowFlags, SCROW nStartRow, SCROW nEndRow, sal_uInt16 nExtra,
162 const vector<sal_uInt16>& aHeights, bool bForce)
164 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
165 bool bChanged = false;
166 SCROW nRngStart = 0;
167 SCROW nRngEnd = 0;
168 sal_uInt16 nLast = 0;
169 for (SCSIZE i=0; i<nCount; i++)
171 size_t nIndex;
172 SCROW nRegionEndRow;
173 sal_uInt8 nRowFlag = pRowFlags->GetValue( nStartRow+i, nIndex, nRegionEndRow );
174 if ( nRegionEndRow > nEndRow )
175 nRegionEndRow = nEndRow;
176 SCSIZE nMoreRows = nRegionEndRow - ( nStartRow+i ); // additional equal rows after first
178 bool bAutoSize = ((nRowFlag & CR_MANUALSIZE) == 0);
179 if ( bAutoSize || bForce )
181 if (nExtra)
183 if (bAutoSize)
184 pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag | CR_MANUALSIZE);
186 else if (!bAutoSize)
187 pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag & ~CR_MANUALSIZE);
189 for (SCSIZE nInner = i; nInner <= i + nMoreRows; ++nInner)
191 if (nLast)
193 if (aHeights[nInner]+nExtra == nLast)
194 nRngEnd = nStartRow+nInner;
195 else
197 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
198 nLast = 0;
201 if (!nLast)
203 nLast = aHeights[nInner]+nExtra;
204 nRngStart = nStartRow+nInner;
205 nRngEnd = nStartRow+nInner;
209 else
211 if (nLast)
212 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
213 nLast = 0;
215 i += nMoreRows; // already handled - skip
217 if (nLast)
218 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
220 return bChanged;
225 // -----------------------------------------------------------------------
227 ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName,
228 bool bColInfo, bool bRowInfo ) :
229 aName( rNewName ),
230 aCodeName( rNewName ),
231 nLinkMode( 0 ),
232 aPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) ),
233 nRepeatStartX( SCCOL_REPEAT_NONE ),
234 nRepeatEndX( SCCOL_REPEAT_NONE ),
235 nRepeatStartY( SCROW_REPEAT_NONE ),
236 nRepeatEndY( SCROW_REPEAT_NONE ),
237 pTabProtection( NULL ),
238 pColWidth( NULL ),
239 mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(NULL) ),
240 pColFlags( NULL ),
241 pRowFlags( NULL ),
242 mpHiddenCols(new ScFlatBoolColSegments),
243 mpHiddenRows(new ScFlatBoolRowSegments),
244 mpFilteredCols(new ScFlatBoolColSegments),
245 mpFilteredRows(new ScFlatBoolRowSegments),
246 pOutlineTable( NULL ),
247 pSheetEvents( NULL ),
248 nTab( nNewTab ),
249 pDocument( pDoc ),
250 pSearchText ( NULL ),
251 pSortCollator( NULL ),
252 pRepeatColRange( NULL ),
253 pRepeatRowRange( NULL ),
254 nLockCount( 0 ),
255 pScenarioRanges( NULL ),
256 aScenarioColor( COL_LIGHTGRAY ),
257 aTabBgColor( COL_AUTO ),
258 nScenarioFlags( 0 ),
259 pDBDataNoName(NULL),
260 mpRangeName(NULL),
261 mpCondFormatList( new ScConditionalFormatList() ),
262 bScenario(false),
263 bLayoutRTL(false),
264 bLoadingRTL(false),
265 bPageSizeValid(false),
266 bTableAreaValid(false),
267 bVisible(true),
268 bStreamValid(false),
269 bPendingRowHeights(false),
270 bCalcNotification(false),
271 bGlobalKeepQuery(false),
272 bPrintEntireSheet(true),
273 bActiveScenario(false),
274 mbPageBreaksValid(false),
275 mbForceBreaks(false)
278 if (bColInfo)
280 pColWidth = new sal_uInt16[ MAXCOL+1 ];
281 pColFlags = new sal_uInt8[ MAXCOL+1 ];
283 for (SCCOL i=0; i<=MAXCOL; i++)
285 pColWidth[i] = STD_COL_WIDTH;
286 pColFlags[i] = 0;
290 if (bRowInfo)
292 mpRowHeights.reset(new ScFlatUInt16RowSegments(ScGlobal::nStdRowHeight));
293 pRowFlags = new ScBitMaskCompressedArray< SCROW, sal_uInt8>( MAXROW, 0);
296 if ( pDocument->IsDocVisible() )
298 // when a sheet is added to a visible document,
299 // initialize its RTL flag from the system locale
300 bLayoutRTL = ScGlobal::IsSystemRTL();
303 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
304 if (pDrawLayer)
306 if ( pDrawLayer->ScAddPage( nTab ) ) // sal_False (not inserted) during Undo
308 pDrawLayer->ScRenamePage( nTab, aName );
309 sal_uLong nx = (sal_uLong) ((double) (MAXCOL+1) * STD_COL_WIDTH * HMM_PER_TWIPS );
310 sal_uLong ny = (sal_uLong) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS );
311 pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( nx, ny ), false );
315 for (SCCOL k=0; k<=MAXCOL; k++)
316 aCol[k].Init( k, nTab, pDocument );
319 ScTable::~ScTable()
321 if (!pDocument->IsInDtorClear())
323 // nicht im dtor die Pages in der falschen Reihenfolge loeschen
324 // (nTab stimmt dann als Page-Number nicht!)
325 // In ScDocument::Clear wird hinterher per Clear am Draw Layer alles geloescht.
327 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
328 if (pDrawLayer)
329 pDrawLayer->ScRemovePage( nTab );
332 delete[] pColWidth;
333 delete[] pColFlags;
334 delete pRowFlags;
335 delete pSheetEvents;
336 delete pOutlineTable;
337 delete pSearchText;
338 delete pRepeatColRange;
339 delete pRepeatRowRange;
340 delete pScenarioRanges;
341 delete mpRangeName;
342 delete pDBDataNoName;
343 DestroySortCollator();
346 void ScTable::GetName( OUString& rName ) const
348 rName = aName;
351 void ScTable::SetName( const OUString& rNewName )
353 aName = rNewName;
354 aUpperName = OUString(); // invalidated if the name is changed
356 // SetStreamValid is handled in ScDocument::RenameTab
359 const OUString& ScTable::GetUpperName() const
361 if (aUpperName.isEmpty() && !aName.isEmpty())
362 aUpperName = ScGlobal::pCharClass->uppercase(aName);
363 return aUpperName;
366 void ScTable::SetVisible( bool bVis )
368 if (bVisible != bVis && IsStreamValid())
369 SetStreamValid(false);
371 bVisible = bVis;
374 void ScTable::SetStreamValid( bool bSet, bool bIgnoreLock )
376 if ( bIgnoreLock || !pDocument->IsStreamValidLocked() )
377 bStreamValid = bSet;
380 void ScTable::SetPendingRowHeights( bool bSet )
382 bPendingRowHeights = bSet;
385 void ScTable::SetLayoutRTL( bool bSet )
387 bLayoutRTL = bSet;
390 void ScTable::SetLoadingRTL( bool bSet )
392 bLoadingRTL = bSet;
395 const Color& ScTable::GetTabBgColor() const
397 return aTabBgColor;
400 void ScTable::SetTabBgColor(const Color& rColor)
402 if (aTabBgColor != rColor)
404 // The tab color has changed. Set this table 'modified'.
405 aTabBgColor = rColor;
406 if (IsStreamValid())
407 SetStreamValid(false);
411 void ScTable::SetScenario( bool bFlag )
413 bScenario = bFlag;
416 void ScTable::SetLink( sal_uInt8 nMode,
417 const OUString& rDoc, const OUString& rFlt, const OUString& rOpt,
418 const OUString& rTab, sal_uLong nRefreshDelay )
420 nLinkMode = nMode;
421 aLinkDoc = rDoc; // Datei
422 aLinkFlt = rFlt; // Filter
423 aLinkOpt = rOpt; // Filter-Optionen
424 aLinkTab = rTab; // Tabellenname in Quelldatei
425 nLinkRefreshDelay = nRefreshDelay; // refresh delay in seconds, 0==off
427 if (IsStreamValid())
428 SetStreamValid(false);
431 sal_uInt16 ScTable::GetOptimalColWidth( SCCOL nCol, OutputDevice* pDev,
432 double nPPTX, double nPPTY,
433 const Fraction& rZoomX, const Fraction& rZoomY,
434 bool bFormula, const ScMarkData* pMarkData,
435 const ScColWidthParam* pParam )
437 return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
438 bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, pParam );
441 long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
442 OutputDevice* pDev,
443 double nPPTX, double nPPTY,
444 const Fraction& rZoomX, const Fraction& rZoomY,
445 bool bWidth, bool bTotalSize )
447 ScNeededSizeOptions aOptions;
448 aOptions.bSkipMerged = false; // zusammengefasste mitzaehlen
449 aOptions.bTotalSize = bTotalSize;
451 return aCol[nCol].GetNeededSize
452 ( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, aOptions );
455 bool ScTable::SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nExtra,
456 OutputDevice* pDev,
457 double nPPTX, double nPPTY,
458 const Fraction& rZoomX, const Fraction& rZoomY,
459 bool bForce, ScProgress* pOuterProgress, sal_uLong nProgressStart )
461 OSL_ENSURE( nExtra==0 || bForce, "automatic OptimalHeight with Extra" );
463 if ( !pDocument->IsAdjustHeightEnabled() )
465 return false;
468 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
470 ScProgress* pProgress = GetProgressBar(nCount, GetWeightedCount(), pOuterProgress, pDocument);
472 vector<sal_uInt16> aHeights(nCount, 0);
474 GetOptimalHeightsInColumn(
475 aCol, nStartRow, nEndRow, aHeights, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce,
476 pProgress, nProgressStart);
478 SetRowHeightRangeFunc aFunc(this, nPPTX, nPPTY);
479 bool bChanged = SetOptimalHeightsToRows(
480 aFunc, pRowFlags, nStartRow, nEndRow, nExtra, aHeights, bForce);
482 if ( pProgress != pOuterProgress )
483 delete pProgress;
485 return bChanged;
488 void ScTable::SetOptimalHeightOnly( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nExtra,
489 OutputDevice* pDev,
490 double nPPTX, double nPPTY,
491 const Fraction& rZoomX, const Fraction& rZoomY,
492 bool bForce, ScProgress* pOuterProgress, sal_uLong nProgressStart )
494 OSL_ENSURE( nExtra==0 || bForce, "automatic OptimalHeight with Extra" );
496 if ( !pDocument->IsAdjustHeightEnabled() )
497 return;
499 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
501 ScProgress* pProgress = GetProgressBar(nCount, GetWeightedCount(), pOuterProgress, pDocument);
503 vector<sal_uInt16> aHeights(nCount, 0);
505 GetOptimalHeightsInColumn(
506 aCol, nStartRow, nEndRow, aHeights, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce,
507 pProgress, nProgressStart);
509 SetRowHeightOnlyFunc aFunc(this);
510 SetOptimalHeightsToRows(
511 aFunc, pRowFlags, nStartRow, nEndRow, nExtra, aHeights, bForce);
513 if ( pProgress != pOuterProgress )
514 delete pProgress;
517 bool ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const
519 bool bFound = false;
520 SCCOL nMaxX = 0;
521 SCROW nMaxY = 0;
522 for (SCCOL i=0; i<=MAXCOL; i++)
524 if (!aCol[i].IsEmptyData())
526 bFound = true;
527 nMaxX = i;
528 SCROW nRow = aCol[i].GetLastDataPos();
529 if (nRow > nMaxY)
530 nMaxY = nRow;
532 if ( aCol[i].HasCellNotes() )
534 SCROW maxNoteRow = aCol[i].GetCellNotesMaxRow();
535 if (maxNoteRow >= nMaxY)
537 bFound = true;
538 nMaxY = maxNoteRow;
540 if (i>nMaxX)
542 bFound = true;
543 nMaxX = i;
548 rEndCol = nMaxX;
549 rEndRow = nMaxY;
550 return bFound;
553 bool ScTable::GetTableArea( SCCOL& rEndCol, SCROW& rEndRow ) const
555 bool bRet = true; //! merken?
556 if (!bTableAreaValid)
558 bRet = GetPrintArea(nTableAreaX, nTableAreaY, true);
559 bTableAreaValid = true;
561 rEndCol = nTableAreaX;
562 rEndRow = nTableAreaY;
563 return bRet;
566 const SCCOL SC_COLUMNS_STOP = 30;
568 bool ScTable::GetPrintArea( SCCOL& rEndCol, SCROW& rEndRow, bool bNotes, bool bFullFormattedArea ) const
570 bool bFound = false;
571 SCCOL nMaxX = 0;
572 SCROW nMaxY = 0;
573 SCCOL i;
575 for (i=0; i<=MAXCOL; i++) // Daten testen
577 if (!aCol[i].IsEmptyData())
579 bFound = true;
580 if (i>nMaxX)
581 nMaxX = i;
582 SCROW nColY = aCol[i].GetLastDataPos();
583 if (nColY > nMaxY)
584 nMaxY = nColY;
586 if (bNotes)
588 if ( aCol[i].HasCellNotes() )
590 SCROW maxNoteRow = aCol[i].GetCellNotesMaxRow();
591 if (maxNoteRow >= nMaxY)
593 bFound = true;
594 nMaxY = maxNoteRow;
596 if (i>nMaxX)
598 bFound = true;
599 nMaxX = i;
605 SCCOL nMaxDataX = nMaxX;
607 for (i=0; i<=MAXCOL; i++) // Attribute testen
609 SCROW nLastRow;
610 if (aCol[i].GetLastVisibleAttr( nLastRow, bFullFormattedArea ))
612 bFound = true;
613 nMaxX = i;
614 if (nLastRow > nMaxY)
615 nMaxY = nLastRow;
619 if (nMaxX == MAXCOL) // Attribute rechts weglassen
621 --nMaxX;
622 while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1]) )
623 --nMaxX;
626 if ( nMaxX < nMaxDataX )
628 nMaxX = nMaxDataX;
630 else if ( nMaxX > nMaxDataX )
632 SCCOL nAttrStartX = nMaxDataX + 1;
633 while ( nAttrStartX < MAXCOL )
635 SCCOL nAttrEndX = nAttrStartX;
636 while ( nAttrEndX < MAXCOL && aCol[nAttrStartX].IsVisibleAttrEqual(aCol[nAttrEndX+1]) )
637 ++nAttrEndX;
638 if ( nAttrEndX + 1 - nAttrStartX >= SC_COLUMNS_STOP )
640 // found equally-formatted columns behind data -> stop before these columns
641 nMaxX = nAttrStartX - 1;
643 // also don't include default-formatted columns before that
644 SCROW nDummyRow;
645 while ( nMaxX > nMaxDataX && !aCol[nMaxX].GetLastVisibleAttr( nDummyRow ) )
646 --nMaxX;
647 break;
649 nAttrStartX = nAttrEndX + 1;
653 rEndCol = nMaxX;
654 rEndRow = nMaxY;
655 return bFound;
658 bool ScTable::GetPrintAreaHor( SCROW nStartRow, SCROW nEndRow,
659 SCCOL& rEndCol, bool /* bNotes */ ) const
661 bool bFound = false;
662 SCCOL nMaxX = 0;
663 SCCOL i;
665 for (i=0; i<=MAXCOL; i++) // Attribute testen
667 if (aCol[i].HasVisibleAttrIn( nStartRow, nEndRow ))
669 bFound = true;
670 nMaxX = i;
674 if (nMaxX == MAXCOL) // Attribute rechts weglassen
676 --nMaxX;
677 while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1], nStartRow, nEndRow) )
678 --nMaxX;
681 for (i=0; i<=MAXCOL; i++) // Daten testen
683 if (!aCol[i].IsEmptyBlock( nStartRow, nEndRow )) //! bNotes ??????
685 bFound = true;
686 if (i>nMaxX)
687 nMaxX = i;
691 rEndCol = nMaxX;
692 return bFound;
695 bool ScTable::GetPrintAreaVer( SCCOL nStartCol, SCCOL nEndCol,
696 SCROW& rEndRow, bool bNotes ) const
698 bool bFound = false;
699 SCROW nMaxY = 0;
700 SCCOL i;
702 for (i=nStartCol; i<=nEndCol; i++) // Attribute testen
704 SCROW nLastRow;
705 if (aCol[i].GetLastVisibleAttr( nLastRow ))
707 bFound = true;
708 if (nLastRow > nMaxY)
709 nMaxY = nLastRow;
713 for (i=nStartCol; i<=nEndCol; i++) // Daten testen
715 if (!aCol[i].IsEmptyData())
717 bFound = true;
718 SCROW nColY = aCol[i].GetLastDataPos();
719 if (nColY > nMaxY)
720 nMaxY = nColY;
722 if (bNotes)
724 if ( aCol[i].HasCellNotes() )
726 SCROW maxNoteRow =aCol[i].GetCellNotesMaxRow();
727 if (maxNoteRow > nMaxY)
729 bFound = true;
730 nMaxY = maxNoteRow;
736 rEndRow = nMaxY;
737 return bFound;
740 bool ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const
742 bool bFound = false;
743 SCCOL nMinX = MAXCOL;
744 SCROW nMinY = MAXROW;
745 SCCOL i;
747 for (i=0; i<=MAXCOL; i++) // Attribute testen
749 SCROW nFirstRow;
750 if (aCol[i].GetFirstVisibleAttr( nFirstRow ))
752 if (!bFound)
753 nMinX = i;
754 bFound = true;
755 if (nFirstRow < nMinY)
756 nMinY = nFirstRow;
760 if (nMinX == 0) // Attribute links weglassen
762 if ( aCol[0].IsVisibleAttrEqual(aCol[1]) ) // keine einzelnen
764 ++nMinX;
765 while ( nMinX<MAXCOL && aCol[nMinX].IsVisibleAttrEqual(aCol[nMinX-1]) )
766 ++nMinX;
770 bool bDatFound = false;
771 for (i=0; i<=MAXCOL; i++) // Daten testen
773 if (!aCol[i].IsEmptyData())
775 if (!bDatFound && i<nMinX)
776 nMinX = i;
777 bFound = bDatFound = true;
778 SCROW nRow = aCol[i].GetFirstDataPos();
779 if (nRow < nMinY)
780 nMinY = nRow;
782 if ( aCol[i].HasCellNotes() )
784 SCROW minNoteRow = aCol[i].GetCellNotesMinRow();
785 if (minNoteRow <= nMinY)
787 bFound = true;
788 nMinY = minNoteRow;
790 if (i<nMinX)
792 bFound = true;
793 nMinX = i;
797 rStartCol = nMinX;
798 rStartRow = nMinY;
799 return bFound;
802 void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
803 bool bIncludeOld, bool bOnlyDown ) const
805 // return the smallest area containing at least all contiguous cells having data. This area
806 // is a square containing also empty cells. It may shrink or extend the area given as input
807 // Flags as modifiers:
809 // bIncludeOld = true ensure that the returned area contains at least the initial area,
810 // independently of the emptniess of rows / columns (i.e. does not allow shrinking)
811 // bOnlyDown = true means extend / shrink the inputed area only down, i.e modifiy only rEndRow
813 bool bLeft = false;
814 bool bRight = false;
815 bool bTop = false;
816 bool bBottom = false;
817 bool bChanged = false;
821 bChanged = false;
823 if (!bOnlyDown)
825 SCROW nStart = rStartRow;
826 SCROW nEnd = rEndRow;
827 if (nStart>0) --nStart;
828 if (nEnd<MAXROW) ++nEnd;
830 if (rEndCol < MAXCOL)
831 if (!aCol[rEndCol+1].IsEmptyBlock(nStart,nEnd))
833 ++rEndCol;
834 bChanged = true;
835 bRight = true;
838 if (rStartCol > 0)
839 if (!aCol[rStartCol-1].IsEmptyBlock(nStart,nEnd))
841 --rStartCol;
842 bChanged = true;
843 bLeft = true;
846 if (rStartRow > 0)
848 SCROW nTest = rStartRow-1;
849 bool needExtend = false;
850 for ( SCCOL i = rStartCol; i<=rEndCol && !needExtend; i++)
851 if (aCol[i].HasDataAt(nTest))
852 needExtend = true;
853 if (needExtend)
855 --rStartRow;
856 bChanged = true;
857 bTop = true;
862 if (rEndRow < MAXROW)
864 SCROW nTest = rEndRow+1;
865 bool needExtend = false;
866 for ( SCCOL i = rStartCol; i<=rEndCol && !needExtend; i++)
867 if (aCol[i].HasDataAt(nTest))
868 needExtend = true;
869 if (needExtend)
871 ++rEndRow;
872 bChanged = true;
873 bBottom = true;
877 while( bChanged );
879 if ( !bIncludeOld && !bOnlyDown )
881 if ( !bLeft )
882 while ( aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) && rStartCol < MAXCOL && rStartCol < rEndCol)
883 ++rStartCol;
885 if ( !bRight )
886 while ( aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) && rEndCol > 0 && rStartCol < rEndCol)
887 --rEndCol;
889 if ( !bTop && rStartRow < MAXROW && rStartRow < rEndRow )
891 bool shrink = true;
894 for ( SCCOL i = rStartCol; i<=rEndCol && shrink; i++)
895 if (aCol[i].HasDataAt(rStartRow))
896 shrink = false;
897 if (shrink)
898 ++rStartRow;
899 }while( shrink && rStartRow < MAXROW && rStartRow < rEndRow);
903 if ( !bIncludeOld )
905 if ( !bBottom && rEndRow > 0 && rStartRow < rEndRow )
907 bool shrink = true;
910 for ( SCCOL i = rStartCol; i<=rEndCol && shrink; i++)
911 if (aCol[i].HasDataAt(rEndRow))
912 shrink = false;
913 if (shrink)
914 --rEndRow;
915 }while( shrink && rEndRow > 0 && rStartRow < rEndRow );
921 bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
922 SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const
924 o_bShrunk = false;
926 PutInOrder( rStartCol, rEndCol);
927 PutInOrder( rStartRow, rEndRow);
928 if (rStartCol < 0)
929 rStartCol = 0, o_bShrunk = true;
930 if (rStartRow < 0)
931 rStartRow = 0, o_bShrunk = true;
932 if (rEndCol > MAXCOL)
933 rEndCol = MAXCOL, o_bShrunk = true;
934 if (rEndRow > MAXROW)
935 rEndRow = MAXROW, o_bShrunk = true;
937 bool bChanged;
940 bChanged = false;
942 while (rStartCol < rEndCol)
944 if (aCol[rEndCol].IsEmptyBlock( rStartRow, rEndRow))
946 --rEndCol;
947 bChanged = true;
949 else
950 break; // while
953 while (rStartCol < rEndCol)
955 if (aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow))
957 ++rStartCol;
958 bChanged = true;
960 else
961 break; // while
964 if (!bColumnsOnly)
966 if (rStartRow < rEndRow)
968 bool bFound = false;
969 for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
970 if (aCol[i].HasDataAt( rStartRow))
971 bFound = true;
972 if (!bFound)
974 ++rStartRow;
975 bChanged = true;
979 if (rStartRow < rEndRow)
981 bool bFound = false;
982 for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
983 if (aCol[i].HasDataAt( rEndRow))
984 bFound = true;
985 if (!bFound)
987 --rEndRow;
988 bChanged = true;
993 if (bChanged)
994 o_bShrunk = true;
995 } while( bChanged );
997 return rStartCol != rEndCol || (bColumnsOnly ?
998 !aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow) :
999 (rStartRow != rEndRow || aCol[rStartCol].HasDataAt( rStartRow)));
1002 SCROW ScTable::GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow ) const
1004 if (!ValidCol(nCol1) || !ValidCol(nCol2))
1005 return -1;
1007 SCROW nNewLastRow = 0;
1008 for (SCCOL i = nCol1; i <= nCol2; ++i)
1010 SCROW nThis = aCol[i].GetLastDataPos(nLastRow);
1011 if (nNewLastRow < nThis)
1012 nNewLastRow = nThis;
1015 return nNewLastRow;
1018 SCSIZE ScTable::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
1019 SCCOL nEndCol, SCROW nEndRow, ScDirection eDir ) const
1021 SCSIZE nCount = 0;
1022 SCCOL nCol;
1023 if ((eDir == DIR_BOTTOM) || (eDir == DIR_TOP))
1025 nCount = static_cast<SCSIZE>(nEndRow - nStartRow + 1);
1026 for (nCol = nStartCol; nCol <= nEndCol; nCol++)
1027 nCount = std::min(nCount, aCol[nCol].GetEmptyLinesInBlock(nStartRow, nEndRow, eDir));
1029 else if (eDir == DIR_RIGHT)
1031 nCol = nEndCol;
1032 while (((SCsCOL)nCol >= (SCsCOL)nStartCol) &&
1033 aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
1035 nCount++;
1036 nCol--;
1039 else
1041 nCol = nStartCol;
1042 while ((nCol <= nEndCol) && aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
1044 nCount++;
1045 nCol++;
1048 return nCount;
1051 bool ScTable::IsEmptyLine( SCROW nRow, SCCOL nStartCol, SCCOL nEndCol ) const
1053 bool bFound = false;
1054 for (SCCOL i=nStartCol; i<=nEndCol && !bFound; i++)
1055 if (aCol[i].HasDataAt(nRow))
1056 bFound = true;
1057 return !bFound;
1060 void ScTable::LimitChartArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow ) const
1062 while ( rStartCol<rEndCol && aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) )
1063 ++rStartCol;
1065 while ( rStartCol<rEndCol && aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) )
1066 --rEndCol;
1068 while ( rStartRow<rEndRow && IsEmptyLine(rStartRow, rStartCol, rEndCol) )
1069 ++rStartRow;
1071 while ( rStartRow<rEndRow && IsEmptyLine(rEndRow, rStartCol, rEndCol) )
1072 --rEndRow;
1075 SCCOL ScTable::FindNextVisibleCol( SCCOL nCol, bool bRight ) const
1077 if(bRight)
1079 nCol++;
1080 SCCOL nEnd = 0;
1081 bool bHidden = pDocument->ColHidden(nCol, nTab, NULL, &nEnd);
1082 if(bHidden)
1083 nCol = nEnd +1;
1085 return std::min<SCCOL>(MAXCOL, nCol);
1087 else
1089 nCol--;
1090 SCCOL nStart = MAXCOL;
1091 bool bHidden = pDocument->ColHidden(nCol, nTab, &nStart, NULL);
1092 if(bHidden)
1093 nCol = nStart - 1;
1095 return std::max<SCCOL>(0, nCol);
1099 SCCOL ScTable::FindNextVisibleColWithContent( SCCOL nCol, bool bRight, SCROW nRow ) const
1101 if(bRight)
1103 if(nCol == MAXCOL)
1104 return MAXCOL;
1108 nCol++;
1109 SCCOL nEndCol = 0;
1110 bool bHidden = pDocument->ColHidden( nCol, nTab, NULL, &nEndCol );
1111 if(bHidden)
1113 nCol = nEndCol +1;
1114 if(nEndCol >= MAXCOL)
1115 return MAXCOL;
1118 if(aCol[nCol].HasVisibleDataAt(nRow))
1119 return nCol;
1121 while(nCol < MAXCOL);
1123 return MAXCOL;
1125 else
1127 if(nCol == 0)
1128 return 0;
1132 nCol--;
1133 SCCOL nStartCol = MAXCOL;
1134 bool bHidden = pDocument->ColHidden( nCol, nTab, &nStartCol, NULL );
1135 if(bHidden)
1137 nCol = nStartCol -1;
1138 if(nCol <= 0)
1139 return 0;
1142 if(aCol[nCol].HasVisibleDataAt(nRow))
1143 return nCol;
1145 while(nCol > 0);
1147 return 0;
1151 void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, ScMoveDirection eDirection ) const
1153 if (eDirection == SC_MOVE_LEFT || eDirection == SC_MOVE_RIGHT)
1155 SCCOL nNewCol = rCol;
1156 bool bThere = aCol[nNewCol].HasVisibleDataAt(rRow);
1157 bool bRight = (eDirection == SC_MOVE_RIGHT);
1158 if (bThere)
1160 if(nNewCol >= MAXCOL && eDirection == SC_MOVE_RIGHT)
1161 return;
1162 else if(nNewCol == 0 && eDirection == SC_MOVE_LEFT)
1163 return;
1165 SCCOL nNextCol = FindNextVisibleCol( nNewCol, bRight );
1167 if(aCol[nNextCol].HasVisibleDataAt(rRow))
1169 bool bFound = false;
1170 nNewCol = nNextCol;
1173 nNextCol = FindNextVisibleCol( nNewCol, bRight );
1174 if(aCol[nNextCol].HasVisibleDataAt(rRow))
1175 nNewCol = nNextCol;
1176 else
1177 bFound = true;
1179 while(!bFound && nNextCol > 0 && nNextCol < MAXCOL);
1181 else
1183 nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
1186 else
1188 nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
1191 if (nNewCol<0)
1192 nNewCol=0;
1193 if (nNewCol>MAXCOL)
1194 nNewCol=MAXCOL;
1195 rCol = nNewCol;
1197 else
1199 aCol[rCol].FindDataAreaPos(rRow,eDirection == SC_MOVE_DOWN);
1203 bool ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
1204 bool bMarked, bool bUnprotected ) const
1206 if (!ValidCol(nCol) || !ValidRow(nRow))
1207 return false;
1209 if (pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED))
1210 // Skip an overlapped cell.
1211 return false;
1213 if (bMarked && !rMark.IsCellMarked(nCol,nRow))
1214 return false;
1216 if (bUnprotected && ((const ScProtectionAttr*)
1217 GetAttr(nCol,nRow,ATTR_PROTECTION))->GetProtection())
1218 return false;
1220 if (bMarked || bUnprotected) //! auch sonst ???
1222 // ausgeblendete muessen uebersprungen werden, weil der Cursor sonst
1223 // auf der naechsten Zelle landet, auch wenn die geschuetzt/nicht markiert ist.
1224 //! per Extra-Parameter steuern, nur fuer Cursor-Bewegung ???
1226 if (RowHidden(nRow))
1227 return false;
1229 if (ColHidden(nCol))
1230 return false;
1233 return true;
1236 void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
1237 bool bMarked, bool bUnprotected, const ScMarkData& rMark ) const
1239 if (bUnprotected && !IsProtected()) // Tabelle ueberhaupt geschuetzt?
1240 bUnprotected = false;
1242 sal_uInt16 nWrap = 0;
1243 SCsCOL nCol = rCol;
1244 SCsROW nRow = rRow;
1246 nCol = sal::static_int_cast<SCsCOL>( nCol + nMovX );
1247 nRow = sal::static_int_cast<SCsROW>( nRow + nMovY );
1249 OSL_ENSURE( !nMovY || !bUnprotected,
1250 "GetNextPos mit bUnprotected horizontal nicht implementiert" );
1252 if ( nMovY && bMarked )
1254 bool bUp = ( nMovY < 0 );
1255 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1256 while ( ValidRow(nRow) &&
1257 (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
1259 // ausgeblendete ueberspringen (s.o.)
1260 nRow += nMovY;
1261 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1264 while ( nRow < 0 || nRow > MAXROW )
1266 nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );
1267 while ( ValidCol(nCol) && ColHidden(nCol) )
1268 nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) ); // skip hidden rows (see above)
1269 if (nCol < 0)
1271 nCol = MAXCOL;
1272 if (++nWrap >= 2)
1273 return;
1275 else if (nCol > MAXCOL)
1277 nCol = 0;
1278 if (++nWrap >= 2)
1279 return;
1281 if (nRow < 0)
1282 nRow = MAXROW;
1283 else if (nRow > MAXROW)
1284 nRow = 0;
1285 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1286 while ( ValidRow(nRow) &&
1287 (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
1289 // ausgeblendete ueberspringen (s.o.)
1290 nRow += nMovY;
1291 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1296 if ( nMovX && ( bMarked || bUnprotected ) )
1298 // initiales Weiterzaehlen wrappen:
1299 if (nCol<0)
1301 nCol = MAXCOL;
1302 --nRow;
1303 if (nRow<0)
1304 nRow = MAXROW;
1306 if (nCol>MAXCOL)
1308 nCol = 0;
1309 ++nRow;
1310 if (nRow>MAXROW)
1311 nRow = 0;
1314 if ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) )
1316 SCsROW* pNextRows = new SCsROW[MAXCOL+1];
1317 SCCOL i;
1319 if ( nMovX > 0 ) // vorwaerts
1321 for (i=0; i<=MAXCOL; i++)
1322 pNextRows[i] = (i<nCol) ? (nRow+1) : nRow;
1325 SCsROW nNextRow = pNextRows[nCol] + 1;
1326 if ( bMarked )
1327 nNextRow = rMark.GetNextMarked( nCol, nNextRow, false );
1328 if ( bUnprotected )
1329 nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, false );
1330 pNextRows[nCol] = nNextRow;
1332 SCsROW nMinRow = MAXROW+1;
1333 for (i=0; i<=MAXCOL; i++)
1334 if (pNextRows[i] < nMinRow) // bei gleichen den linken
1336 nMinRow = pNextRows[i];
1337 nCol = i;
1339 nRow = nMinRow;
1341 if ( nRow > MAXROW )
1343 if (++nWrap >= 2) break; // ungueltigen Wert behalten
1344 nCol = 0;
1345 nRow = 0;
1346 for (i=0; i<=MAXCOL; i++)
1347 pNextRows[i] = 0; // alles ganz von vorne
1350 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1352 else // rueckwaerts
1354 for (i=0; i<=MAXCOL; i++)
1355 pNextRows[i] = (i>nCol) ? (nRow-1) : nRow;
1358 SCsROW nNextRow = pNextRows[nCol] - 1;
1359 if ( bMarked )
1360 nNextRow = rMark.GetNextMarked( nCol, nNextRow, true );
1361 if ( bUnprotected )
1362 nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, true );
1363 pNextRows[nCol] = nNextRow;
1365 SCsROW nMaxRow = -1;
1366 for (i=0; i<=MAXCOL; i++)
1367 if (pNextRows[i] >= nMaxRow) // bei gleichen den rechten
1369 nMaxRow = pNextRows[i];
1370 nCol = i;
1372 nRow = nMaxRow;
1374 if ( nRow < 0 )
1376 if (++nWrap >= 2) break; // ungueltigen Wert behalten
1377 nCol = MAXCOL;
1378 nRow = MAXROW;
1379 for (i=0; i<=MAXCOL; i++)
1380 pNextRows[i] = MAXROW; // alles ganz von vorne
1383 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1386 delete[] pNextRows;
1390 // ungueltige Werte kommen z.b. bei Tab heraus,
1391 // wenn nicht markiert und nicht geschuetzt ist (linker / rechter Rand),
1392 // dann Werte unveraendert lassen
1394 if (ValidColRow(nCol,nRow))
1396 rCol = nCol;
1397 rRow = nRow;
1401 bool ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark ) const
1403 const ScMarkArray* pMarkArray = rMark.GetArray();
1404 OSL_ENSURE(pMarkArray,"GetNextMarkedCell without MarkArray");
1405 if ( !pMarkArray )
1406 return false;
1408 ++rRow; // naechste Zelle ist gesucht
1410 while ( rCol <= MAXCOL )
1412 const ScMarkArray& rArray = pMarkArray[rCol];
1413 while ( rRow <= MAXROW )
1415 SCROW nStart = (SCROW) rArray.GetNextMarked( (SCsROW) rRow, false );
1416 if ( nStart <= MAXROW )
1418 SCROW nEnd = rArray.GetMarkEnd( nStart, false );
1420 const sc::CellStoreType& rCells = aCol[rCol].maCells;
1421 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = rCells.position(nStart);
1422 sc::CellStoreType::const_iterator it = aPos.first;
1423 SCROW nTestRow = nStart;
1424 if (it->type == sc::element_type_empty)
1426 // Skip the empty block.
1427 nTestRow += it->size - aPos.second;
1428 ++it;
1429 if (it == rCells.end())
1431 // No more block.
1432 rRow = MAXROW + 1;
1433 return false;
1437 if (nTestRow < nEnd)
1439 // Cell found.
1440 rRow = nTestRow;
1441 return true;
1444 rRow = nEnd + 1; // naechsten markierten Bereich suchen
1446 else
1447 rRow = MAXROW + 1; // Ende der Spalte
1449 rRow = 0;
1450 ++rCol; // naechste Spalte testen
1453 return false; // alle Spalten durch
1456 void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1457 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
1458 SCsCOL nDx, SCsROW nDy, SCsTAB nDz, bool bUpdateNoteCaptionPos )
1460 if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // only within the table
1462 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
1463 if ( eUpdateRefMode != URM_COPY && pDrawLayer )
1465 if ( eUpdateRefMode == URM_MOVE )
1466 { // source range
1467 nCol1 = sal::static_int_cast<SCCOL>( nCol1 - nDx );
1468 nRow1 = sal::static_int_cast<SCROW>( nRow1 - nDy );
1469 nCol2 = sal::static_int_cast<SCCOL>( nCol2 - nDx );
1470 nRow2 = sal::static_int_cast<SCROW>( nRow2 - nDy );
1472 pDrawLayer->MoveArea( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy,
1473 (eUpdateRefMode == URM_INSDEL), bUpdateNoteCaptionPos );
1478 void ScTable::UpdateReference(
1479 sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, bool bIncludeDraw, bool bUpdateNoteCaptionPos )
1481 bool bUpdated = false;
1482 SCCOL i;
1483 SCCOL iMax;
1484 if (rCxt.meMode == URM_COPY )
1486 i = rCxt.maRange.aStart.Col();
1487 iMax = rCxt.maRange.aEnd.Col();
1489 else
1491 i = 0;
1492 iMax = MAXCOL;
1495 UpdateRefMode eUpdateRefMode = rCxt.meMode;
1496 SCCOL nDx = rCxt.mnColDelta;
1497 SCROW nDy = rCxt.mnRowDelta;
1498 SCTAB nDz = rCxt.mnTabDelta;
1499 SCCOL nCol1 = rCxt.maRange.aStart.Col(), nCol2 = rCxt.maRange.aEnd.Col();
1500 SCROW nRow1 = rCxt.maRange.aStart.Row(), nRow2 = rCxt.maRange.aEnd.Row();
1501 SCTAB nTab1 = rCxt.maRange.aStart.Tab(), nTab2 = rCxt.maRange.aEnd.Tab();
1503 // Named expressions need to be updated before formulas acessing them.
1504 if (mpRangeName)
1505 mpRangeName->UpdateReference(rCxt, nTab);
1507 for ( ; i<=iMax; i++)
1508 bUpdated |= aCol[i].UpdateReference(rCxt, pUndoDoc);
1510 if ( bIncludeDraw )
1511 UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
1513 if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // print ranges: only within the table
1515 SCTAB nSTab = nTab;
1516 SCTAB nETab = nTab;
1517 SCCOL nSCol = 0;
1518 SCROW nSRow = 0;
1519 SCCOL nECol = 0;
1520 SCROW nERow = 0;
1521 bool bRecalcPages = false;
1523 for ( ScRangeVec::iterator aIt = aPrintRanges.begin(), aEnd = aPrintRanges.end(); aIt != aEnd; ++aIt )
1525 nSCol = aIt->aStart.Col();
1526 nSRow = aIt->aStart.Row();
1527 nECol = aIt->aEnd.Col();
1528 nERow = aIt->aEnd.Row();
1530 // do not try to modify sheet index of print range
1531 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1532 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1533 nDx,nDy,0,
1534 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1536 *aIt = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1537 bRecalcPages = true;
1541 if ( pRepeatColRange )
1543 nSCol = pRepeatColRange->aStart.Col();
1544 nSRow = pRepeatColRange->aStart.Row();
1545 nECol = pRepeatColRange->aEnd.Col();
1546 nERow = pRepeatColRange->aEnd.Row();
1548 // do not try to modify sheet index of repeat range
1549 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1550 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1551 nDx,nDy,0,
1552 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1554 *pRepeatColRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1555 bRecalcPages = true;
1556 nRepeatStartX = nSCol; // fuer UpdatePageBreaks
1557 nRepeatEndX = nECol;
1561 if ( pRepeatRowRange )
1563 nSCol = pRepeatRowRange->aStart.Col();
1564 nSRow = pRepeatRowRange->aStart.Row();
1565 nECol = pRepeatRowRange->aEnd.Col();
1566 nERow = pRepeatRowRange->aEnd.Row();
1568 // do not try to modify sheet index of repeat range
1569 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1570 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1571 nDx,nDy,0,
1572 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1574 *pRepeatRowRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1575 bRecalcPages = true;
1576 nRepeatStartY = nSRow; // fuer UpdatePageBreaks
1577 nRepeatEndY = nERow;
1581 // updating print ranges is not necessary with multiple print ranges
1582 if ( bRecalcPages && GetPrintRangeCount() <= 1 )
1584 UpdatePageBreaks(NULL);
1586 pDocument->RepaintRange( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab) );
1590 if (bUpdated && IsStreamValid())
1591 SetStreamValid(false);
1593 if(mpCondFormatList)
1594 mpCondFormatList->UpdateReference(rCxt);
1597 void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
1598 ScDocument* pUndoDoc )
1600 for ( SCCOL i=0; i<=MAXCOL; i++ )
1601 aCol[i].UpdateTranspose( rSource, rDest, pUndoDoc );
1604 void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
1606 for ( SCCOL i=0; i<=MAXCOL; i++ )
1607 aCol[i].UpdateGrow( rArea, nGrowX, nGrowY );
1610 void ScTable::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt )
1612 if (nTab >= rCxt.mnInsertPos)
1614 nTab += rCxt.mnSheets;
1615 if (pDBDataNoName)
1616 pDBDataNoName->UpdateMoveTab(nTab - 1 ,nTab);
1619 if (mpRangeName)
1620 mpRangeName->UpdateInsertTab(rCxt, nTab);
1622 if (mpCondFormatList)
1623 mpCondFormatList->UpdateInsertTab(rCxt);
1625 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTab(rCxt);
1627 if (IsStreamValid())
1628 SetStreamValid(false);
1631 void ScTable::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt )
1633 if (nTab > rCxt.mnDeletePos)
1635 nTab -= rCxt.mnSheets;
1636 if (pDBDataNoName)
1637 pDBDataNoName->UpdateMoveTab(nTab + 1,nTab);
1640 if (mpRangeName)
1641 mpRangeName->UpdateDeleteTab(rCxt, nTab);
1643 if (mpCondFormatList)
1644 mpCondFormatList->UpdateDeleteTab(rCxt);
1646 for (SCCOL i = 0; i <= MAXCOL; ++i)
1647 aCol[i].UpdateDeleteTab(rCxt);
1649 if (IsStreamValid())
1650 SetStreamValid(false);
1653 void ScTable::UpdateMoveTab(
1654 sc::RefUpdateMoveTabContext& rCxt, SCTAB nTabNo, ScProgress* pProgress )
1656 nTab = nTabNo;
1657 if (mpRangeName)
1658 mpRangeName->UpdateMoveTab(rCxt, nTab);
1660 if (pDBDataNoName)
1661 pDBDataNoName->UpdateMoveTab(rCxt.mnOldPos, rCxt.mnNewPos);
1663 if(mpCondFormatList)
1664 mpCondFormatList->UpdateMoveTab(rCxt);
1666 for ( SCCOL i=0; i <= MAXCOL; i++ )
1668 aCol[i].UpdateMoveTab(rCxt, nTabNo);
1669 if (pProgress)
1670 pProgress->SetState(pProgress->GetState() + aCol[i].GetCodeCount());
1673 if (IsStreamValid())
1674 SetStreamValid(false);
1677 void ScTable::UpdateCompile( bool bForceIfNameInUse )
1679 for (SCCOL i=0; i <= MAXCOL; i++)
1681 aCol[i].UpdateCompile( bForceIfNameInUse );
1685 void ScTable::SetTabNo(SCTAB nNewTab)
1687 nTab = nNewTab;
1688 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].SetTabNo(nNewTab);
1691 void ScTable::FindRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1692 std::set<sal_uInt16>& rIndexes) const
1694 for (SCCOL i = nCol1; i <= nCol2 && ValidCol(i); i++)
1695 aCol[i].FindRangeNamesInUse(nRow1, nRow2, rIndexes);
1698 void ScTable::ExtendPrintArea( OutputDevice* pDev,
1699 SCCOL /* nStartCol */, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
1701 if ( !pColFlags || !pRowFlags )
1703 OSL_FAIL("ExtendPrintArea: No ColInfo or RowInfo");
1704 return;
1707 Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
1708 double nPPTX = aPix1000.X() / 1000.0;
1709 double nPPTY = aPix1000.Y() / 1000.0;
1711 // First, mark those columns that we need to skip i.e. hidden and empty columns.
1713 ScFlatBoolColSegments aSkipCols;
1714 aSkipCols.setFalse(0, MAXCOL);
1715 for (SCCOL i = 0; i <= MAXCOL; ++i)
1717 SCCOL nLastCol = i;
1718 if (ColHidden(i, NULL, &nLastCol))
1720 // Columns are hidden in this range.
1721 aSkipCols.setTrue(i, nLastCol);
1723 else
1725 // These columns are visible. Check for empty columns.
1726 for (SCCOL j = i; j <= nLastCol; ++j)
1728 if (aCol[j].GetCellCount() == 0)
1729 // empty
1730 aSkipCols.setTrue(j,j);
1733 i = nLastCol;
1736 ScFlatBoolColSegments::RangeData aColData;
1737 for (SCCOL nCol = rEndCol; nCol >= 0; --nCol)
1739 if (!aSkipCols.getRangeData(nCol, aColData))
1740 // Failed to get the data. This should never happen!
1741 return;
1743 if (aColData.mbValue)
1745 // Skip these columns.
1746 nCol = aColData.mnCol1; // move toward 0.
1747 continue;
1750 // These are visible and non-empty columns.
1751 for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= aColData.mnCol1; --nDataCol)
1753 SCCOL nPrintCol = nDataCol;
1754 VisibleDataCellIterator aIter(*mpHiddenRows, aCol[nDataCol]);
1755 ScRefCellValue aCell = aIter.reset(nStartRow);
1756 if (aCell.isEmpty())
1757 // No visible cells found in this column. Skip it.
1758 continue;
1760 while (!aCell.isEmpty())
1762 SCCOL nNewCol = nDataCol;
1763 SCROW nRow = aIter.getRow();
1764 if (nRow > nEndRow)
1765 // Went past the last row position. Bail out.
1766 break;
1768 MaybeAddExtraColumn(nNewCol, nRow, pDev, nPPTX, nPPTY);
1769 if (nNewCol > nPrintCol)
1770 nPrintCol = nNewCol;
1771 aCell = aIter.next();
1774 if (nPrintCol > rEndCol)
1775 // Make sure we don't shrink the print area.
1776 rEndCol = nPrintCol;
1778 nCol = aColData.mnCol1; // move toward 0.
1782 void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY)
1784 ScRefCellValue aCell = aCol[rCol].GetCellValue(nRow);
1785 if (!aCell.hasString())
1786 return;
1788 bool bFormula = false; //! ueberge
1789 long nPixel = aCol[rCol].GetTextWidth(nRow);
1791 // Breite bereits im Idle-Handler berechnet?
1792 if ( TEXTWIDTH_DIRTY == nPixel )
1794 ScNeededSizeOptions aOptions;
1795 aOptions.bTotalSize = true;
1796 aOptions.bFormula = bFormula;
1797 aOptions.bSkipMerged = false;
1799 Fraction aZoom(1,1);
1800 nPixel = aCol[rCol].GetNeededSize(
1801 nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions );
1803 aCol[rCol].SetTextWidth(nRow, static_cast<sal_uInt16>(nPixel));
1806 long nTwips = (long) (nPixel / nPPTX);
1807 long nDocW = GetColWidth( rCol );
1809 long nMissing = nTwips - nDocW;
1810 if ( nMissing > 0 )
1812 // look at alignment
1814 const ScPatternAttr* pPattern = GetPattern( rCol, nRow );
1815 const SfxItemSet* pCondSet = pDocument->GetCondResult( rCol, nRow, nTab );
1817 SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
1818 pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
1819 if ( eHorJust == SVX_HOR_JUSTIFY_CENTER )
1820 nMissing /= 2; // distributed into both directions
1821 else
1823 // STANDARD is LEFT (only text is handled here)
1824 bool bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT );
1825 if ( IsLayoutRTL() )
1826 bRight = !bRight;
1827 if ( bRight )
1828 nMissing = 0; // extended only to the left (logical)
1832 SCCOL nNewCol = rCol;
1833 while (nMissing > 0 && nNewCol < MAXCOL)
1835 ScRefCellValue aNextCell = aCol[nNewCol+1].GetCellValue(nRow);
1836 if (!aNextCell.isEmpty())
1837 // Cell content in a next column ends display of this string.
1838 nMissing = 0;
1839 else
1840 nMissing -= GetColWidth(++nNewCol);
1842 rCol = nNewCol;
1845 namespace {
1847 class SetTableIndex : public ::std::unary_function<ScRange, void>
1849 SCTAB mnTab;
1850 public:
1851 SetTableIndex(SCTAB nTab) : mnTab(nTab) {}
1853 void operator() (ScRange& rRange) const
1855 rRange.aStart.SetTab(mnTab);
1856 rRange.aEnd.SetTab(mnTab);
1860 void setPrintRange(ScRange*& pRange1, const ScRange* pRange2)
1862 if (pRange2)
1864 if (pRange1)
1865 *pRange1 = *pRange2;
1866 else
1867 pRange1 = new ScRange(*pRange2);
1869 else
1870 DELETEZ(pRange1);
1875 void ScTable::CopyPrintRange(const ScTable& rTable)
1877 // The table index shouldn't be used when the print range is used, but
1878 // just in case set the correct table index.
1880 aPrintRanges = rTable.aPrintRanges;
1881 ::std::for_each(aPrintRanges.begin(), aPrintRanges.end(), SetTableIndex(nTab));
1883 bPrintEntireSheet = rTable.bPrintEntireSheet;
1885 delete pRepeatColRange;
1886 pRepeatColRange = NULL;
1887 if (rTable.pRepeatColRange)
1889 pRepeatColRange = new ScRange(*rTable.pRepeatColRange);
1890 pRepeatColRange->aStart.SetTab(nTab);
1891 pRepeatColRange->aEnd.SetTab(nTab);
1894 delete pRepeatRowRange;
1895 pRepeatRowRange = NULL;
1896 if (rTable.pRepeatRowRange)
1898 pRepeatRowRange = new ScRange(*rTable.pRepeatRowRange);
1899 pRepeatRowRange->aStart.SetTab(nTab);
1900 pRepeatRowRange->aEnd.SetTab(nTab);
1904 void ScTable::SetRepeatColRange( const ScRange* pNew )
1906 setPrintRange( pRepeatColRange, pNew );
1908 if (IsStreamValid())
1909 SetStreamValid(false);
1911 InvalidatePageBreaks();
1914 void ScTable::SetRepeatRowRange( const ScRange* pNew )
1916 setPrintRange( pRepeatRowRange, pNew );
1918 if (IsStreamValid())
1919 SetStreamValid(false);
1921 InvalidatePageBreaks();
1924 void ScTable::ClearPrintRanges()
1926 aPrintRanges.clear();
1927 bPrintEntireSheet = false;
1929 if (IsStreamValid())
1930 SetStreamValid(false);
1932 InvalidatePageBreaks(); // #i117952# forget page breaks for an old print range
1935 void ScTable::AddPrintRange( const ScRange& rNew )
1937 bPrintEntireSheet = false;
1938 if( aPrintRanges.size() < 0xFFFF )
1939 aPrintRanges.push_back( rNew );
1941 if (IsStreamValid())
1942 SetStreamValid(false);
1944 InvalidatePageBreaks();
1948 void ScTable::SetPrintEntireSheet()
1950 if( !IsPrintEntireSheet() )
1952 ClearPrintRanges();
1953 bPrintEntireSheet = true;
1957 const ScRange* ScTable::GetPrintRange(sal_uInt16 nPos) const
1959 return (nPos < GetPrintRangeCount()) ? &aPrintRanges[ nPos ] : NULL;
1962 void ScTable::FillPrintSaver( ScPrintSaverTab& rSaveTab ) const
1964 rSaveTab.SetAreas( aPrintRanges, bPrintEntireSheet );
1965 rSaveTab.SetRepeat( pRepeatColRange, pRepeatRowRange );
1968 void ScTable::RestorePrintRanges( const ScPrintSaverTab& rSaveTab )
1970 aPrintRanges = rSaveTab.GetPrintRanges();
1971 bPrintEntireSheet = rSaveTab.IsEntireSheet();
1972 SetRepeatColRange( rSaveTab.GetRepeatCol() );
1973 SetRepeatRowRange( rSaveTab.GetRepeatRow() );
1975 InvalidatePageBreaks(); // #i117952# forget page breaks for an old print range
1976 UpdatePageBreaks(NULL);
1979 SCROW ScTable::VisibleDataCellIterator::ROW_NOT_FOUND = -1;
1981 ScTable::VisibleDataCellIterator::VisibleDataCellIterator(ScFlatBoolRowSegments& rRowSegs, ScColumn& rColumn) :
1982 mrRowSegs(rRowSegs),
1983 mrColumn(rColumn),
1984 mnCurRow(ROW_NOT_FOUND),
1985 mnUBound(ROW_NOT_FOUND)
1989 ScTable::VisibleDataCellIterator::~VisibleDataCellIterator()
1993 ScRefCellValue ScTable::VisibleDataCellIterator::reset(SCROW nRow)
1995 if (nRow > MAXROW)
1997 mnCurRow = ROW_NOT_FOUND;
1998 return ScRefCellValue();
2001 ScFlatBoolRowSegments::RangeData aData;
2002 if (!mrRowSegs.getRangeData(nRow, aData))
2004 mnCurRow = ROW_NOT_FOUND;
2005 return ScRefCellValue();
2008 if (!aData.mbValue)
2010 // specified row is visible. Take it.
2011 mnCurRow = nRow;
2012 mnUBound = aData.mnRow2;
2014 else
2016 // specified row is not-visible. The first visible row is the start of
2017 // the next segment.
2018 mnCurRow = aData.mnRow2 + 1;
2019 mnUBound = mnCurRow; // get range data on the next iteration.
2020 if (mnCurRow > MAXROW)
2022 // Make sure the row doesn't exceed our current limit.
2023 mnCurRow = ROW_NOT_FOUND;
2024 return ScRefCellValue();
2028 maCell = mrColumn.GetCellValue(mnCurRow);
2029 if (!maCell.isEmpty())
2030 // First visible cell found.
2031 return maCell;
2033 // Find a first visible cell below this row (if any).
2034 return next();
2037 ScRefCellValue ScTable::VisibleDataCellIterator::next()
2039 if (mnCurRow == ROW_NOT_FOUND)
2040 return ScRefCellValue();
2042 while (mrColumn.GetNextDataPos(mnCurRow))
2044 if (mnCurRow > mnUBound)
2046 // We don't know the visibility of this row range. Query it.
2047 ScFlatBoolRowSegments::RangeData aData;
2048 if (!mrRowSegs.getRangeData(mnCurRow, aData))
2050 mnCurRow = ROW_NOT_FOUND;
2051 return ScRefCellValue();
2054 if (aData.mbValue)
2056 // This row is invisible. Skip to the last invisible row and
2057 // try again.
2058 mnCurRow = mnUBound = aData.mnRow2;
2059 continue;
2062 // This row is visible.
2063 mnUBound = aData.mnRow2;
2066 maCell = mrColumn.GetCellValue(mnCurRow);
2067 if (!maCell.isEmpty())
2068 return maCell;
2071 mnCurRow = ROW_NOT_FOUND;
2072 return ScRefCellValue();
2075 SCROW ScTable::VisibleDataCellIterator::getRow() const
2077 return mnCurRow;
2080 void ScTable::SetAnonymousDBData(ScDBData* pDBData)
2082 delete pDBDataNoName;
2083 pDBDataNoName = pDBData;
2086 ScDBData* ScTable::GetAnonymousDBData()
2088 return pDBDataNoName;
2091 sal_uLong ScTable::AddCondFormat( ScConditionalFormat* pNew )
2093 if(!mpCondFormatList)
2094 mpCondFormatList.reset(new ScConditionalFormatList());
2096 sal_uLong nMax = 0;
2097 for(ScConditionalFormatList::const_iterator itr = mpCondFormatList->begin();
2098 itr != mpCondFormatList->end(); ++itr)
2100 sal_uLong nKey = itr->GetKey();
2101 if(nKey > nMax)
2102 nMax = nKey;
2105 pNew->SetKey(nMax+1);
2106 mpCondFormatList->InsertNew(pNew);
2108 return nMax + 1;
2111 sal_uInt8 ScTable::GetScriptType( SCCOL nCol, SCROW nRow ) const
2113 if (!ValidCol(nCol))
2114 return 0;
2116 return aCol[nCol].GetScriptType(nRow);
2119 void ScTable::SetScriptType( SCCOL nCol, SCROW nRow, sal_uInt8 nType )
2121 if (!ValidCol(nCol))
2122 return;
2124 aCol[nCol].SetScriptType(nRow, nType);
2127 sal_uInt8 ScTable::GetRangeScriptType(
2128 sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2130 if (!ValidCol(nCol))
2131 return 0;
2133 sc::CellStoreType::iterator itr = aCol[nCol].maCells.begin();
2134 return aCol[nCol].GetRangeScriptType(rBlockPos.miCellTextAttrPos, nRow1, nRow2, itr);
2137 size_t ScTable::GetFormulaHash( SCCOL nCol, SCROW nRow ) const
2139 if (!ValidCol(nCol))
2140 return 0;
2142 return aCol[nCol].GetFormulaHash(nRow);
2145 ScFormulaVectorState ScTable::GetFormulaVectorState( SCCOL nCol, SCROW nRow ) const
2147 if (!ValidCol(nCol))
2148 return FormulaVectorUnknown;
2150 return aCol[nCol].GetFormulaVectorState(nRow);
2153 formula::FormulaTokenRef ScTable::ResolveStaticReference( SCCOL nCol, SCROW nRow )
2155 if (!ValidCol(nCol) || !ValidRow(nRow))
2156 return formula::FormulaTokenRef();
2158 return aCol[nCol].ResolveStaticReference(nRow);
2161 formula::FormulaTokenRef ScTable::ResolveStaticReference( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2163 if (nCol2 < nCol1 || nRow2 < nRow1)
2164 return formula::FormulaTokenRef();
2166 if (!ValidCol(nCol1) || !ValidCol(nCol2) || !ValidRow(nRow1) || !ValidRow(nRow2))
2167 return formula::FormulaTokenRef();
2169 ScMatrixRef pMat(new ScMatrix(nCol2-nCol1+1, nRow2-nRow1+1, 0.0));
2170 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
2172 if (!aCol[nCol].ResolveStaticReference(*pMat, nCol2-nCol1, nRow1, nRow2))
2173 // Column contains non-static cell. Failed.
2174 return formula::FormulaTokenRef();
2177 return formula::FormulaTokenRef(new ScMatrixToken(pMat));
2180 formula::VectorRefArray ScTable::FetchVectorRefArray( SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2182 if (nRow2 < nRow1)
2183 return formula::VectorRefArray();
2185 if (!ValidCol(nCol) || !ValidRow(nRow1) || !ValidRow(nRow2))
2186 return formula::VectorRefArray();
2188 return aCol[nCol].FetchVectorRefArray(nRow1, nRow2);
2191 ScRefCellValue ScTable::GetRefCellValue( SCCOL nCol, SCROW nRow )
2193 if (!ValidColRow(nCol, nRow))
2194 return ScRefCellValue();
2196 return aCol[nCol].GetCellValue(nRow);
2199 SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow )
2201 if (!ValidColRow(nCol, nRow))
2202 return NULL;
2204 return aCol[nCol].GetBroadcaster(nRow);
2207 void ScTable::DeleteBroadcasters(
2208 sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2210 if (!ValidCol(nCol))
2211 return;
2213 aCol[nCol].DeleteBroadcasters(rBlockPos, nRow1, nRow2);
2216 bool ScTable::HasBroadcaster( SCCOL nCol ) const
2218 if (!ValidCol(nCol))
2219 return false;
2221 return aCol[nCol].HasBroadcaster();
2224 void ScTable::FillMatrix( ScMatrix& rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
2226 size_t nMatCol = 0;
2227 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nMatCol)
2228 aCol[nCol].FillMatrix(rMat, nMatCol, nRow1, nRow2);
2231 void ScTable::InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2233 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
2234 aCol[nCol].InterpretDirtyCells(nRow1, nRow2);
2237 void ScTable::SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen )
2239 if (!ValidCol(nCol))
2240 return;
2242 aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
2245 void ScTable::SetFormulaResults(
2246 SCCOL nCol, SCROW nRow, const formula::FormulaTokenRef* pResults, size_t nLen )
2248 if (!ValidCol(nCol))
2249 return;
2251 aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
2254 #if DEBUG_COLUMN_STORAGE
2255 void ScTable::DumpFormulaGroups( SCCOL nCol ) const
2257 if (!ValidCol(nCol))
2258 return;
2260 aCol[nCol].DumpFormulaGroups();
2262 #endif
2264 const SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow ) const
2266 if (!ValidColRow(nCol, nRow))
2267 return NULL;
2269 return aCol[nCol].GetBroadcaster(nRow);
2272 void ScTable::DeleteConditionalFormat( sal_uLong nIndex )
2274 mpCondFormatList->erase(nIndex);
2277 void ScTable::SetCondFormList( ScConditionalFormatList* pNew )
2279 mpCondFormatList.reset( pNew );
2282 ScConditionalFormatList* ScTable::GetCondFormList()
2284 if(!mpCondFormatList)
2285 mpCondFormatList.reset( new ScConditionalFormatList() );
2287 return mpCondFormatList.get();
2290 const ScConditionalFormatList* ScTable::GetCondFormList() const
2292 return mpCondFormatList.get();
2295 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */