fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / data / table1.cxx
blobd93d1f4d7ed3789ec266bb3c87afe669832ccdeb
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"
51 #include <rowheightcontext.hxx>
53 #include <formula/vectortoken.hxx>
55 #include <vector>
56 #include <boost/scoped_array.hpp>
58 using ::std::vector;
60 namespace {
62 ScProgress* GetProgressBar(
63 SCSIZE nCount, SCSIZE nTotalCount, ScProgress* pOuterProgress, ScDocument* pDoc)
65 if (nTotalCount < 1000)
67 // if the total number of rows is less than 1000, don't even bother
68 // with the progress bar because drawing progress bar can be very
69 // expensive especially in GTK.
70 return NULL;
73 if (pOuterProgress)
74 return pOuterProgress;
76 if (nCount > 1)
77 return new ScProgress(
78 pDoc->GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nTotalCount);
80 return NULL;
83 void GetOptimalHeightsInColumn(
84 sc::RowHeightContext& rCxt, ScColumn* pCol, SCROW nStartRow, SCROW nEndRow,
85 ScProgress* pProgress, sal_uInt32 nProgressStart )
87 assert(nStartRow <= nEndRow);
89 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
91 // first, one time over the whole range
92 // (with the last column in the hope that they most likely still are
93 // on standard format)
95 std::vector<sal_uInt16>& rHeights = rCxt.getHeightArray();
97 pCol[MAXCOL].GetOptimalHeight(rCxt, nStartRow, nEndRow, 0, 0);
99 // from there search for the standard height that is in use in the lower part
101 sal_uInt16 nMinHeight = rHeights[nCount-1];
102 SCSIZE nPos = nCount-1;
103 while ( nPos && rHeights[nPos-1] >= nMinHeight )
104 --nPos;
105 SCROW nMinStart = nStartRow + nPos;
107 sal_uLong nWeightedCount = 0;
108 for (SCCOL nCol=0; nCol<MAXCOL; nCol++) // MAXCOL already above
110 pCol[nCol].GetOptimalHeight(rCxt, nStartRow, nEndRow, nMinHeight, nMinStart);
112 if (pProgress)
114 sal_uLong nWeight = pCol[nCol].GetWeightedCount();
115 if (nWeight) // does not have to be the same Status
117 nWeightedCount += nWeight;
118 pProgress->SetState( nWeightedCount + nProgressStart );
124 struct OptimalHeightsFuncObjBase
126 virtual ~OptimalHeightsFuncObjBase() {}
127 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight) = 0;
130 struct SetRowHeightOnlyFunc : public OptimalHeightsFuncObjBase
132 ScTable* mpTab;
133 SetRowHeightOnlyFunc(ScTable* pTab) :
134 mpTab(pTab)
137 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight) SAL_OVERRIDE
139 mpTab->SetRowHeightOnly(nStartRow, nEndRow, nHeight);
140 return false;
144 struct SetRowHeightRangeFunc : public OptimalHeightsFuncObjBase
146 ScTable* mpTab;
147 double mnPPTX;
148 double mnPPTY;
150 SetRowHeightRangeFunc(ScTable* pTab, double nPPTX, double nPPTY) :
151 mpTab(pTab),
152 mnPPTX(nPPTX),
153 mnPPTY(nPPTY)
156 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight) SAL_OVERRIDE
158 return mpTab->SetRowHeightRange(nStartRow, nEndRow, nHeight, mnPPTX, mnPPTY);
162 bool SetOptimalHeightsToRows(
163 sc::RowHeightContext& rCxt,
164 OptimalHeightsFuncObjBase& rFuncObj,
165 ScBitMaskCompressedArray<SCROW, sal_uInt8>* pRowFlags, SCROW nStartRow, SCROW nEndRow )
167 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
168 bool bChanged = false;
169 SCROW nRngStart = 0;
170 SCROW nRngEnd = 0;
171 sal_uInt16 nLast = 0;
172 for (SCSIZE i=0; i<nCount; i++)
174 size_t nIndex;
175 SCROW nRegionEndRow;
176 sal_uInt8 nRowFlag = pRowFlags->GetValue( nStartRow+i, nIndex, nRegionEndRow );
177 if ( nRegionEndRow > nEndRow )
178 nRegionEndRow = nEndRow;
179 SCSIZE nMoreRows = nRegionEndRow - ( nStartRow+i ); // additional equal rows after first
181 bool bAutoSize = ((nRowFlag & CR_MANUALSIZE) == 0);
182 if (bAutoSize || rCxt.isForceAutoSize())
184 if (rCxt.getExtraHeight())
186 if (bAutoSize)
187 pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag | CR_MANUALSIZE);
189 else if (!bAutoSize)
190 pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag & ~CR_MANUALSIZE);
192 for (SCSIZE nInner = i; nInner <= i + nMoreRows; ++nInner)
194 if (nLast)
196 if (rCxt.getHeightArray()[nInner] + rCxt.getExtraHeight() == nLast)
197 nRngEnd = nStartRow+nInner;
198 else
200 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
201 nLast = 0;
204 if (!nLast)
206 nLast = rCxt.getHeightArray()[nInner] + rCxt.getExtraHeight();
207 nRngStart = nStartRow+nInner;
208 nRngEnd = nStartRow+nInner;
212 else
214 if (nLast)
215 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
216 nLast = 0;
218 i += nMoreRows; // already handled - skip
220 if (nLast)
221 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
223 return bChanged;
228 ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName,
229 bool bColInfo, bool bRowInfo ) :
230 aName( rNewName ),
231 aCodeName( rNewName ),
232 nLinkRefreshDelay( 0 ),
233 nLinkMode( 0 ),
234 aPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) ),
235 nRepeatStartX( SCCOL_REPEAT_NONE ),
236 nRepeatEndX( SCCOL_REPEAT_NONE ),
237 nRepeatStartY( SCROW_REPEAT_NONE ),
238 nRepeatEndY( SCROW_REPEAT_NONE ),
239 pTabProtection( NULL ),
240 pColWidth( NULL ),
241 mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(NULL) ),
242 pColFlags( NULL ),
243 pRowFlags( NULL ),
244 mpHiddenCols(new ScFlatBoolColSegments),
245 mpHiddenRows(new ScFlatBoolRowSegments),
246 mpFilteredCols(new ScFlatBoolColSegments),
247 mpFilteredRows(new ScFlatBoolRowSegments),
248 pOutlineTable( NULL ),
249 pSheetEvents( NULL ),
250 nTableAreaX( 0 ),
251 nTableAreaY( 0 ),
252 nTab( nNewTab ),
253 pDocument( pDoc ),
254 pSearchText ( NULL ),
255 pSortCollator( NULL ),
256 pRepeatColRange( NULL ),
257 pRepeatRowRange( NULL ),
258 nLockCount( 0 ),
259 pScenarioRanges( NULL ),
260 aScenarioColor( COL_LIGHTGRAY ),
261 aTabBgColor( COL_AUTO ),
262 nScenarioFlags( 0 ),
263 pDBDataNoName(NULL),
264 mpRangeName(NULL),
265 mpCondFormatList( new ScConditionalFormatList() ),
266 bScenario(false),
267 bLayoutRTL(false),
268 bLoadingRTL(false),
269 bPageSizeValid(false),
270 bTableAreaValid(false),
271 bVisible(true),
272 bStreamValid(false),
273 bPendingRowHeights(false),
274 bCalcNotification(false),
275 bGlobalKeepQuery(false),
276 bPrintEntireSheet(true),
277 bActiveScenario(false),
278 mbPageBreaksValid(false),
279 mbForceBreaks(false)
282 if (bColInfo)
284 pColWidth = new sal_uInt16[ MAXCOL+1 ];
285 pColFlags = new sal_uInt8[ MAXCOL+1 ];
287 for (SCCOL i=0; i<=MAXCOL; i++)
289 pColWidth[i] = STD_COL_WIDTH;
290 pColFlags[i] = 0;
294 if (bRowInfo)
296 mpRowHeights.reset(new ScFlatUInt16RowSegments(ScGlobal::nStdRowHeight));
297 pRowFlags = new ScBitMaskCompressedArray< SCROW, sal_uInt8>( MAXROW, 0);
300 if ( pDocument->IsDocVisible() )
302 // when a sheet is added to a visible document,
303 // initialize its RTL flag from the system locale
304 bLayoutRTL = ScGlobal::IsSystemRTL();
307 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
308 if (pDrawLayer)
310 if ( pDrawLayer->ScAddPage( nTab ) ) // sal_False (not inserted) during Undo
312 pDrawLayer->ScRenamePage( nTab, aName );
313 sal_uLong nx = (sal_uLong) ((double) (MAXCOL+1) * STD_COL_WIDTH * HMM_PER_TWIPS );
314 sal_uLong ny = (sal_uLong) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS );
315 pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( nx, ny ), false );
319 for (SCCOL k=0; k<=MAXCOL; k++)
320 aCol[k].Init( k, nTab, pDocument );
323 ScTable::~ScTable()
325 if (!pDocument->IsInDtorClear())
327 for (SCCOL nCol = 0; nCol < MAXCOL; ++nCol)
329 aCol[nCol].FreeNotes();
331 // In the dtor, don't delete the pages in the wrong order.
332 // (or else nTab does not reflect the page number!)
333 // In ScDocument::Clear is afterwards used from Clear at the Draw Layer to delete everything.
335 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
336 if (pDrawLayer)
337 pDrawLayer->ScRemovePage( nTab );
340 delete[] pColWidth;
341 delete[] pColFlags;
342 delete pRowFlags;
343 delete pSheetEvents;
344 delete pOutlineTable;
345 delete pSearchText;
346 delete pRepeatColRange;
347 delete pRepeatRowRange;
348 delete pScenarioRanges;
349 delete mpRangeName;
350 delete pDBDataNoName;
351 DestroySortCollator();
353 for (SCCOL k=0; k<=MAXCOL; k++)
354 aCol[k].PrepareBroadcastersForDestruction();
357 void ScTable::GetName( OUString& rName ) const
359 rName = aName;
362 void ScTable::SetName( const OUString& rNewName )
364 aName = rNewName;
365 aUpperName.clear(); // invalidated if the name is changed
367 // SetStreamValid is handled in ScDocument::RenameTab
370 const OUString& ScTable::GetUpperName() const
372 if (aUpperName.isEmpty() && !aName.isEmpty())
373 aUpperName = ScGlobal::pCharClass->uppercase(aName);
374 return aUpperName;
377 void ScTable::SetVisible( bool bVis )
379 if (bVisible != bVis && IsStreamValid())
380 SetStreamValid(false);
382 bVisible = bVis;
385 void ScTable::SetStreamValid( bool bSet, bool bIgnoreLock )
387 if ( bIgnoreLock || !pDocument->IsStreamValidLocked() )
388 bStreamValid = bSet;
391 void ScTable::SetPendingRowHeights( bool bSet )
393 bPendingRowHeights = bSet;
396 void ScTable::SetLayoutRTL( bool bSet )
398 bLayoutRTL = bSet;
401 void ScTable::SetLoadingRTL( bool bSet )
403 bLoadingRTL = bSet;
406 void ScTable::SetTabBgColor(const Color& rColor)
408 if (aTabBgColor != rColor)
410 // The tab color has changed. Set this table 'modified'.
411 aTabBgColor = rColor;
412 if (IsStreamValid())
413 SetStreamValid(false);
417 void ScTable::SetScenario( bool bFlag )
419 bScenario = bFlag;
422 void ScTable::SetLink( sal_uInt8 nMode,
423 const OUString& rDoc, const OUString& rFlt, const OUString& rOpt,
424 const OUString& rTab, sal_uLong nRefreshDelay )
426 nLinkMode = nMode;
427 aLinkDoc = rDoc; // File
428 aLinkFlt = rFlt; // Filter
429 aLinkOpt = rOpt; // Filter options
430 aLinkTab = rTab; // Sheet name in source file
431 nLinkRefreshDelay = nRefreshDelay; // refresh delay in seconds, 0==off
433 if (IsStreamValid())
434 SetStreamValid(false);
437 sal_uInt16 ScTable::GetOptimalColWidth( SCCOL nCol, OutputDevice* pDev,
438 double nPPTX, double nPPTY,
439 const Fraction& rZoomX, const Fraction& rZoomY,
440 bool bFormula, const ScMarkData* pMarkData,
441 const ScColWidthParam* pParam )
443 return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
444 bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, pParam );
447 long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
448 OutputDevice* pDev,
449 double nPPTX, double nPPTY,
450 const Fraction& rZoomX, const Fraction& rZoomY,
451 bool bWidth, bool bTotalSize )
453 ScNeededSizeOptions aOptions;
454 aOptions.bSkipMerged = false; // count merged cells
455 aOptions.bTotalSize = bTotalSize;
457 return aCol[nCol].GetNeededSize
458 ( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, aOptions, NULL );
461 bool ScTable::SetOptimalHeight(
462 sc::RowHeightContext& rCxt, SCROW nStartRow, SCROW nEndRow,
463 ScProgress* pOuterProgress, sal_uLong nProgressStart )
465 assert(nStartRow <= nEndRow);
467 OSL_ENSURE( rCxt.getExtraHeight() == 0 || rCxt.isForceAutoSize(),
468 "automatic OptimalHeight with Extra" );
470 if ( !pDocument->IsAdjustHeightEnabled() )
472 return false;
475 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
477 ScProgress* pProgress = GetProgressBar(nCount, GetWeightedCount(), pOuterProgress, pDocument);
479 rCxt.getHeightArray().resize(nCount, 0);
481 GetOptimalHeightsInColumn(rCxt, aCol, nStartRow, nEndRow, pProgress, nProgressStart);
483 SetRowHeightRangeFunc aFunc(this, rCxt.getPPTX(), rCxt.getPPTY());
484 bool bChanged = SetOptimalHeightsToRows(rCxt, aFunc, pRowFlags, nStartRow, nEndRow);
486 if ( pProgress != pOuterProgress )
487 delete pProgress;
489 return bChanged;
492 void ScTable::SetOptimalHeightOnly(
493 sc::RowHeightContext& rCxt, SCROW nStartRow, SCROW nEndRow,
494 ScProgress* pOuterProgress, sal_uLong nProgressStart )
496 OSL_ENSURE( rCxt.getExtraHeight() == 0 || rCxt.isForceAutoSize(),
497 "automatic OptimalHeight with Extra" );
499 if ( !pDocument->IsAdjustHeightEnabled() )
500 return;
502 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
504 ScProgress* pProgress = GetProgressBar(nCount, GetWeightedCount(), pOuterProgress, pDocument);
506 rCxt.getHeightArray().resize(nCount, 0);
508 GetOptimalHeightsInColumn(rCxt, aCol, nStartRow, nEndRow, pProgress, nProgressStart);
510 SetRowHeightOnlyFunc aFunc(this);
511 SetOptimalHeightsToRows(rCxt, aFunc, pRowFlags, nStartRow, nEndRow);
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; //TODO: remember?
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++) // Test data
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++) // Test attribute
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) // omit attribute at the right
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++) // Test attribute
667 if (aCol[i].HasVisibleAttrIn( nStartRow, nEndRow ))
669 bFound = true;
670 nMaxX = i;
674 if (nMaxX == MAXCOL) // omit attribute at the right
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 )) //TODO: 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++) // Test attribute
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++) // Test data
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++) // Test attribute
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) // omit attribute at the right
762 if ( aCol[0].IsVisibleAttrEqual(aCol[1]) ) // no single ones
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++) // Test data
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 bShrink = true;
894 for ( SCCOL i = rStartCol; i<=rEndCol && bShrink; i++)
895 if (aCol[i].HasDataAt(rStartRow))
896 bShrink = false;
897 if (bShrink)
898 ++rStartRow;
899 } while (bShrink && rStartRow < MAXROW && rStartRow < rEndRow);
903 if ( !bIncludeOld )
905 if ( !bBottom && rEndRow > 0 && rStartRow < rEndRow )
907 SCROW nLastDataRow = GetLastDataRow( rStartCol, rEndCol, rEndRow);
908 if (nLastDataRow < rEndRow)
909 rEndRow = std::max( rStartRow, nLastDataRow);
914 bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
915 SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly, bool bStickyTopRow, bool bStickyLeftCol ) const
917 o_bShrunk = false;
919 PutInOrder( rStartCol, rEndCol);
920 PutInOrder( rStartRow, rEndRow);
921 if (rStartCol < 0)
922 rStartCol = 0, o_bShrunk = true;
923 if (rStartRow < 0)
924 rStartRow = 0, o_bShrunk = true;
925 if (rEndCol > MAXCOL)
926 rEndCol = MAXCOL, o_bShrunk = true;
927 if (rEndRow > MAXROW)
928 rEndRow = MAXROW, o_bShrunk = true;
930 while (rStartCol < rEndCol)
932 if (aCol[rEndCol].IsEmptyBlock( rStartRow, rEndRow))
934 --rEndCol;
935 o_bShrunk = true;
937 else
938 break; // while
941 if (!bStickyLeftCol)
943 while (rStartCol < rEndCol)
945 if (aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow))
947 ++rStartCol;
948 o_bShrunk = true;
950 else
951 break; // while
955 if (!bColumnsOnly)
957 if (!bStickyTopRow)
959 while (rStartRow < rEndRow)
961 bool bFound = false;
962 for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
964 if (aCol[i].HasDataAt( rStartRow))
965 bFound = true;
967 if (!bFound)
969 ++rStartRow;
970 o_bShrunk = true;
972 else
973 break; // while
977 while (rStartRow < rEndRow)
979 SCROW nLastDataRow = GetLastDataRow( rStartCol, rEndCol, rEndRow);
980 if (0 <= nLastDataRow && nLastDataRow < rEndRow)
982 rEndRow = std::max( rStartRow, nLastDataRow);
983 o_bShrunk = true;
985 else
986 break; // while
990 return rStartCol != rEndCol || (bColumnsOnly ?
991 !aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow) :
992 (rStartRow != rEndRow || aCol[rStartCol].HasDataAt( rStartRow)));
995 SCROW ScTable::GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow ) const
997 if (!ValidCol(nCol1) || !ValidCol(nCol2))
998 return -1;
1000 SCROW nNewLastRow = 0;
1001 for (SCCOL i = nCol1; i <= nCol2; ++i)
1003 SCROW nThis = aCol[i].GetLastDataPos(nLastRow);
1004 if (nNewLastRow < nThis)
1005 nNewLastRow = nThis;
1008 return nNewLastRow;
1011 SCSIZE ScTable::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
1012 SCCOL nEndCol, SCROW nEndRow, ScDirection eDir ) const
1014 SCSIZE nCount = 0;
1015 SCCOL nCol;
1016 if ((eDir == DIR_BOTTOM) || (eDir == DIR_TOP))
1018 nCount = static_cast<SCSIZE>(nEndRow - nStartRow + 1);
1019 for (nCol = nStartCol; nCol <= nEndCol; nCol++)
1020 nCount = std::min(nCount, aCol[nCol].GetEmptyLinesInBlock(nStartRow, nEndRow, eDir));
1022 else if (eDir == DIR_RIGHT)
1024 nCol = nEndCol;
1025 while (((SCsCOL)nCol >= (SCsCOL)nStartCol) &&
1026 aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
1028 nCount++;
1029 nCol--;
1032 else
1034 nCol = nStartCol;
1035 while ((nCol <= nEndCol) && aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
1037 nCount++;
1038 nCol++;
1041 return nCount;
1044 bool ScTable::IsEmptyLine( SCROW nRow, SCCOL nStartCol, SCCOL nEndCol ) const
1046 bool bFound = false;
1047 for (SCCOL i=nStartCol; i<=nEndCol && !bFound; i++)
1048 if (aCol[i].HasDataAt(nRow))
1049 bFound = true;
1050 return !bFound;
1053 void ScTable::LimitChartArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow ) const
1055 while ( rStartCol<rEndCol && aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) )
1056 ++rStartCol;
1058 while ( rStartCol<rEndCol && aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) )
1059 --rEndCol;
1061 while ( rStartRow<rEndRow && IsEmptyLine(rStartRow, rStartCol, rEndCol) )
1062 ++rStartRow;
1064 while ( rStartRow<rEndRow && IsEmptyLine(rEndRow, rStartCol, rEndCol) )
1065 --rEndRow;
1068 SCCOL ScTable::FindNextVisibleCol( SCCOL nCol, bool bRight ) const
1070 if(bRight)
1072 nCol++;
1073 SCCOL nEnd = 0;
1074 bool bHidden = pDocument->ColHidden(nCol, nTab, NULL, &nEnd);
1075 if(bHidden)
1076 nCol = nEnd +1;
1078 return std::min<SCCOL>(MAXCOL, nCol);
1080 else
1082 nCol--;
1083 SCCOL nStart = MAXCOL;
1084 bool bHidden = pDocument->ColHidden(nCol, nTab, &nStart, NULL);
1085 if(bHidden)
1086 nCol = nStart - 1;
1088 return std::max<SCCOL>(0, nCol);
1092 SCCOL ScTable::FindNextVisibleColWithContent( SCCOL nCol, bool bRight, SCROW nRow ) const
1094 if(bRight)
1096 if(nCol == MAXCOL)
1097 return MAXCOL;
1101 nCol++;
1102 SCCOL nEndCol = 0;
1103 bool bHidden = pDocument->ColHidden( nCol, nTab, NULL, &nEndCol );
1104 if(bHidden)
1106 nCol = nEndCol +1;
1107 if(nEndCol >= MAXCOL)
1108 return MAXCOL;
1111 if(aCol[nCol].HasVisibleDataAt(nRow))
1112 return nCol;
1114 while(nCol < MAXCOL);
1116 return MAXCOL;
1118 else
1120 if(nCol == 0)
1121 return 0;
1125 nCol--;
1126 SCCOL nStartCol = MAXCOL;
1127 bool bHidden = pDocument->ColHidden( nCol, nTab, &nStartCol, NULL );
1128 if(bHidden)
1130 nCol = nStartCol -1;
1131 if(nCol <= 0)
1132 return 0;
1135 if(aCol[nCol].HasVisibleDataAt(nRow))
1136 return nCol;
1138 while(nCol > 0);
1140 return 0;
1144 void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, ScMoveDirection eDirection ) const
1146 if (eDirection == SC_MOVE_LEFT || eDirection == SC_MOVE_RIGHT)
1148 SCCOL nNewCol = rCol;
1149 bool bThere = aCol[nNewCol].HasVisibleDataAt(rRow);
1150 bool bRight = (eDirection == SC_MOVE_RIGHT);
1151 if (bThere)
1153 if(nNewCol >= MAXCOL && eDirection == SC_MOVE_RIGHT)
1154 return;
1155 else if(nNewCol == 0 && eDirection == SC_MOVE_LEFT)
1156 return;
1158 SCCOL nNextCol = FindNextVisibleCol( nNewCol, bRight );
1160 if(aCol[nNextCol].HasVisibleDataAt(rRow))
1162 bool bFound = false;
1163 nNewCol = nNextCol;
1166 nNextCol = FindNextVisibleCol( nNewCol, bRight );
1167 if(aCol[nNextCol].HasVisibleDataAt(rRow))
1168 nNewCol = nNextCol;
1169 else
1170 bFound = true;
1172 while(!bFound && nNextCol > 0 && nNextCol < MAXCOL);
1174 else
1176 nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
1179 else
1181 nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
1184 if (nNewCol<0)
1185 nNewCol=0;
1186 if (nNewCol>MAXCOL)
1187 nNewCol=MAXCOL;
1188 rCol = nNewCol;
1190 else
1192 aCol[rCol].FindDataAreaPos(rRow,eDirection == SC_MOVE_DOWN);
1196 bool ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
1197 bool bMarked, bool bUnprotected ) const
1199 if (!ValidCol(nCol) || !ValidRow(nRow))
1200 return false;
1202 if (pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED))
1203 // Skip an overlapped cell.
1204 return false;
1206 if (bMarked && !rMark.IsCellMarked(nCol,nRow))
1207 return false;
1209 if (bUnprotected && static_cast<const ScProtectionAttr*>(
1210 GetAttr(nCol,nRow,ATTR_PROTECTION))->GetProtection())
1211 return false;
1213 if (bMarked || bUnprotected) //TODO: also in other case ???
1215 // Hidden cells must be skipped, as the cursor would end up on the next cell
1216 // even if it is protected or not marked.
1217 //TODO: control per Extra-Parameter, only for Cursor movement ???
1219 if (RowHidden(nRow))
1220 return false;
1222 if (ColHidden(nCol))
1223 return false;
1226 return true;
1229 void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
1230 bool bMarked, bool bUnprotected, const ScMarkData& rMark ) const
1232 if (bUnprotected && !IsProtected()) // Is sheet really protected?
1233 bUnprotected = false;
1235 sal_uInt16 nWrap = 0;
1236 SCsCOL nCol = rCol;
1237 SCsROW nRow = rRow;
1239 nCol = sal::static_int_cast<SCsCOL>( nCol + nMovX );
1240 nRow = sal::static_int_cast<SCsROW>( nRow + nMovY );
1242 OSL_ENSURE( !nMovY || !bUnprotected,
1243 "GetNextPos with bUnprotected horizontal not implemented" );
1245 if ( nMovY && bMarked )
1247 bool bUp = ( nMovY < 0 );
1248 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1249 while ( ValidRow(nRow) &&
1250 (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
1252 // skip hidden rows (see above)
1253 nRow += nMovY;
1254 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1257 while ( nRow < 0 || nRow > MAXROW )
1259 nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );
1260 while ( ValidCol(nCol) && ColHidden(nCol) )
1261 nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) ); // skip hidden rows (see above)
1262 if (nCol < 0)
1264 nCol = MAXCOL;
1265 if (++nWrap >= 2)
1266 return;
1268 else if (nCol > MAXCOL)
1270 nCol = 0;
1271 if (++nWrap >= 2)
1272 return;
1274 if (nRow < 0)
1275 nRow = MAXROW;
1276 else if (nRow > MAXROW)
1277 nRow = 0;
1278 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1279 while ( ValidRow(nRow) &&
1280 (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
1282 // skip hidden rows (see above)
1283 nRow += nMovY;
1284 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1289 if ( nMovX && ( bMarked || bUnprotected ) )
1291 // wrap initial skip counting:
1292 if (nCol<0)
1294 nCol = MAXCOL;
1295 --nRow;
1296 if (nRow<0)
1297 nRow = MAXROW;
1299 if (nCol>MAXCOL)
1301 nCol = 0;
1302 ++nRow;
1303 if (nRow>MAXROW)
1304 nRow = 0;
1307 if ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) )
1309 boost::scoped_array<SCsROW> pNextRows(new SCsROW[MAXCOL+1]);
1310 SCCOL i;
1312 if ( nMovX > 0 ) // forward
1314 for (i=0; i<=MAXCOL; i++)
1315 pNextRows[i] = (i<nCol) ? (nRow+1) : nRow;
1318 SCsROW nNextRow = pNextRows[nCol] + 1;
1319 if ( bMarked )
1320 nNextRow = rMark.GetNextMarked( nCol, nNextRow, false );
1321 if ( bUnprotected )
1322 nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, false );
1323 pNextRows[nCol] = nNextRow;
1325 SCsROW nMinRow = MAXROW+1;
1326 for (i=0; i<=MAXCOL; i++)
1327 if (pNextRows[i] < nMinRow) // when two equal on the left
1329 nMinRow = pNextRows[i];
1330 nCol = i;
1332 nRow = nMinRow;
1334 if ( nRow > MAXROW )
1336 if (++nWrap >= 2) break; // handle invalid value
1337 nCol = 0;
1338 nRow = 0;
1339 for (i=0; i<=MAXCOL; i++)
1340 pNextRows[i] = 0; // do it all over again
1343 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1345 else // backwards
1347 for (i=0; i<=MAXCOL; i++)
1348 pNextRows[i] = (i>nCol) ? (nRow-1) : nRow;
1351 SCsROW nNextRow = pNextRows[nCol] - 1;
1352 if ( bMarked )
1353 nNextRow = rMark.GetNextMarked( nCol, nNextRow, true );
1354 if ( bUnprotected )
1355 nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, true );
1356 pNextRows[nCol] = nNextRow;
1358 SCsROW nMaxRow = -1;
1359 for (i=0; i<=MAXCOL; i++)
1360 if (pNextRows[i] >= nMaxRow) // when two equal on the right
1362 nMaxRow = pNextRows[i];
1363 nCol = i;
1365 nRow = nMaxRow;
1367 if ( nRow < 0 )
1369 if (++nWrap >= 2) break; // handle invalid value
1370 nCol = MAXCOL;
1371 nRow = MAXROW;
1372 for (i=0; i<=MAXCOL; i++)
1373 pNextRows[i] = MAXROW; // do it all over again
1376 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1381 // Invalid values show up for instane for Tab, when nothing is selected and not
1382 // protected (left / right edge), then leave values unchanged.
1384 if (ValidColRow(nCol,nRow))
1386 rCol = nCol;
1387 rRow = nRow;
1391 bool ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark ) const
1393 const ScMarkArray* pMarkArray = rMark.GetArray();
1394 OSL_ENSURE(pMarkArray,"GetNextMarkedCell without MarkArray");
1395 if ( !pMarkArray )
1396 return false;
1398 ++rRow; // next row
1400 while ( rCol <= MAXCOL )
1402 const ScMarkArray& rArray = pMarkArray[rCol];
1403 while ( rRow <= MAXROW )
1405 SCROW nStart = (SCROW) rArray.GetNextMarked( (SCsROW) rRow, false );
1406 if ( nStart <= MAXROW )
1408 SCROW nEnd = rArray.GetMarkEnd( nStart, false );
1410 const sc::CellStoreType& rCells = aCol[rCol].maCells;
1411 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = rCells.position(nStart);
1412 sc::CellStoreType::const_iterator it = aPos.first;
1413 SCROW nTestRow = nStart;
1414 if (it->type == sc::element_type_empty)
1416 // Skip the empty block.
1417 nTestRow += it->size - aPos.second;
1418 ++it;
1419 if (it == rCells.end())
1421 // No more block.
1422 rRow = MAXROW + 1;
1423 return false;
1427 if (nTestRow <= nEnd)
1429 // Cell found.
1430 rRow = nTestRow;
1431 return true;
1434 rRow = nEnd + 1; // Search for next selected range
1436 else
1437 rRow = MAXROW + 1; // End of column
1439 rRow = 0;
1440 ++rCol; // test next column
1443 return false; // Through all columns
1446 void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1447 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
1448 SCsCOL nDx, SCsROW nDy, SCsTAB nDz, bool bUpdateNoteCaptionPos )
1450 if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // only within the table
1452 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
1453 if ( eUpdateRefMode != URM_COPY && pDrawLayer )
1455 if ( eUpdateRefMode == URM_MOVE )
1456 { // source range
1457 nCol1 = sal::static_int_cast<SCCOL>( nCol1 - nDx );
1458 nRow1 = sal::static_int_cast<SCROW>( nRow1 - nDy );
1459 nCol2 = sal::static_int_cast<SCCOL>( nCol2 - nDx );
1460 nRow2 = sal::static_int_cast<SCROW>( nRow2 - nDy );
1462 pDrawLayer->MoveArea( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy,
1463 (eUpdateRefMode == URM_INSDEL), bUpdateNoteCaptionPos );
1468 void ScTable::UpdateReference(
1469 sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, bool bIncludeDraw, bool bUpdateNoteCaptionPos )
1471 bool bUpdated = false;
1472 SCCOL i;
1473 SCCOL iMax;
1474 if (rCxt.meMode == URM_COPY )
1476 i = rCxt.maRange.aStart.Col();
1477 iMax = rCxt.maRange.aEnd.Col();
1479 else
1481 i = 0;
1482 iMax = MAXCOL;
1485 UpdateRefMode eUpdateRefMode = rCxt.meMode;
1486 SCCOL nDx = rCxt.mnColDelta;
1487 SCROW nDy = rCxt.mnRowDelta;
1488 SCTAB nDz = rCxt.mnTabDelta;
1489 SCCOL nCol1 = rCxt.maRange.aStart.Col(), nCol2 = rCxt.maRange.aEnd.Col();
1490 SCROW nRow1 = rCxt.maRange.aStart.Row(), nRow2 = rCxt.maRange.aEnd.Row();
1491 SCTAB nTab1 = rCxt.maRange.aStart.Tab(), nTab2 = rCxt.maRange.aEnd.Tab();
1493 // Named expressions need to be updated before formulas acessing them.
1494 if (mpRangeName)
1495 mpRangeName->UpdateReference(rCxt, nTab);
1497 for ( ; i<=iMax; i++)
1498 bUpdated |= aCol[i].UpdateReference(rCxt, pUndoDoc);
1500 if ( bIncludeDraw )
1501 UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
1503 if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // print ranges: only within the table
1505 SCTAB nSTab = nTab;
1506 SCTAB nETab = nTab;
1507 SCCOL nSCol = 0;
1508 SCROW nSRow = 0;
1509 SCCOL nECol = 0;
1510 SCROW nERow = 0;
1511 bool bRecalcPages = false;
1513 for ( ScRangeVec::iterator aIt = aPrintRanges.begin(), aEnd = aPrintRanges.end(); aIt != aEnd; ++aIt )
1515 nSCol = aIt->aStart.Col();
1516 nSRow = aIt->aStart.Row();
1517 nECol = aIt->aEnd.Col();
1518 nERow = aIt->aEnd.Row();
1520 // do not try to modify sheet index of print range
1521 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1522 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1523 nDx,nDy,0,
1524 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1526 *aIt = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1527 bRecalcPages = true;
1531 if ( pRepeatColRange )
1533 nSCol = pRepeatColRange->aStart.Col();
1534 nSRow = pRepeatColRange->aStart.Row();
1535 nECol = pRepeatColRange->aEnd.Col();
1536 nERow = pRepeatColRange->aEnd.Row();
1538 // do not try to modify sheet index of repeat range
1539 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1540 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1541 nDx,nDy,0,
1542 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1544 *pRepeatColRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1545 bRecalcPages = true;
1546 nRepeatStartX = nSCol; // for UpdatePageBreaks
1547 nRepeatEndX = nECol;
1551 if ( pRepeatRowRange )
1553 nSCol = pRepeatRowRange->aStart.Col();
1554 nSRow = pRepeatRowRange->aStart.Row();
1555 nECol = pRepeatRowRange->aEnd.Col();
1556 nERow = pRepeatRowRange->aEnd.Row();
1558 // do not try to modify sheet index of repeat range
1559 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1560 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1561 nDx,nDy,0,
1562 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1564 *pRepeatRowRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1565 bRecalcPages = true;
1566 nRepeatStartY = nSRow; // for UpdatePageBreaks
1567 nRepeatEndY = nERow;
1571 // updating print ranges is not necessary with multiple print ranges
1572 if ( bRecalcPages && GetPrintRangeCount() <= 1 )
1574 UpdatePageBreaks(NULL);
1576 pDocument->RepaintRange( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab) );
1580 if (bUpdated && IsStreamValid())
1581 SetStreamValid(false);
1583 if(mpCondFormatList)
1584 mpCondFormatList->UpdateReference(rCxt);
1586 if (pTabProtection)
1587 pTabProtection->updateReference( eUpdateRefMode, pDocument, rCxt.maRange, nDx, nDy, nDz);
1590 void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
1591 ScDocument* pUndoDoc )
1593 for ( SCCOL i=0; i<=MAXCOL; i++ )
1594 aCol[i].UpdateTranspose( rSource, rDest, pUndoDoc );
1597 void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
1599 for ( SCCOL i=0; i<=MAXCOL; i++ )
1600 aCol[i].UpdateGrow( rArea, nGrowX, nGrowY );
1603 void ScTable::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt )
1605 // Store the old tab number in sc::UpdatedRangeNames for
1606 // ScTokenArray::AdjustReferenceOnInsertedTab() to check with
1607 // isNameModified()
1608 if (mpRangeName)
1609 mpRangeName->UpdateInsertTab(rCxt, nTab);
1611 if (nTab >= rCxt.mnInsertPos)
1613 nTab += rCxt.mnSheets;
1614 if (pDBDataNoName)
1615 pDBDataNoName->UpdateMoveTab(nTab - 1 ,nTab);
1618 if (mpCondFormatList)
1619 mpCondFormatList->UpdateInsertTab(rCxt);
1621 if (pTabProtection)
1622 pTabProtection->updateReference( URM_INSDEL, pDocument,
1623 ScRange( 0, 0, rCxt.mnInsertPos, MAXCOL, MAXROW, MAXTAB),
1624 0, 0, rCxt.mnSheets);
1626 for (SCCOL i=0; i <= MAXCOL; i++)
1627 aCol[i].UpdateInsertTab(rCxt);
1629 if (IsStreamValid())
1630 SetStreamValid(false);
1633 void ScTable::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt )
1635 // Store the old tab number in sc::UpdatedRangeNames for
1636 // ScTokenArray::AdjustReferenceOnDeletedTab() to check with
1637 // isNameModified()
1638 if (mpRangeName)
1639 mpRangeName->UpdateDeleteTab(rCxt, nTab);
1641 if (nTab > rCxt.mnDeletePos)
1643 nTab -= rCxt.mnSheets;
1644 if (pDBDataNoName)
1645 pDBDataNoName->UpdateMoveTab(nTab + 1,nTab);
1648 if (mpCondFormatList)
1649 mpCondFormatList->UpdateDeleteTab(rCxt);
1651 if (pTabProtection)
1652 pTabProtection->updateReference( URM_INSDEL, pDocument,
1653 ScRange( 0, 0, rCxt.mnDeletePos, MAXCOL, MAXROW, MAXTAB),
1654 0, 0, -rCxt.mnSheets);
1656 for (SCCOL i = 0; i <= MAXCOL; ++i)
1657 aCol[i].UpdateDeleteTab(rCxt);
1659 if (IsStreamValid())
1660 SetStreamValid(false);
1663 void ScTable::UpdateMoveTab(
1664 sc::RefUpdateMoveTabContext& rCxt, SCTAB nTabNo, ScProgress* pProgress )
1666 nTab = nTabNo;
1667 if (mpRangeName)
1668 mpRangeName->UpdateMoveTab(rCxt, nTab);
1670 if (pDBDataNoName)
1671 pDBDataNoName->UpdateMoveTab(rCxt.mnOldPos, rCxt.mnNewPos);
1673 if(mpCondFormatList)
1674 mpCondFormatList->UpdateMoveTab(rCxt);
1676 if (pTabProtection)
1677 pTabProtection->updateReference( URM_REORDER, pDocument,
1678 ScRange( 0, 0, rCxt.mnOldPos, MAXCOL, MAXROW, MAXTAB),
1679 0, 0, rCxt.mnNewPos - rCxt.mnOldPos);
1681 for ( SCCOL i=0; i <= MAXCOL; i++ )
1683 aCol[i].UpdateMoveTab(rCxt, nTabNo);
1684 if (pProgress)
1685 pProgress->SetState(pProgress->GetState() + aCol[i].GetCodeCount());
1688 if (IsStreamValid())
1689 SetStreamValid(false);
1692 void ScTable::UpdateCompile( bool bForceIfNameInUse )
1694 for (SCCOL i=0; i <= MAXCOL; i++)
1696 aCol[i].UpdateCompile( bForceIfNameInUse );
1700 void ScTable::SetTabNo(SCTAB nNewTab)
1702 nTab = nNewTab;
1703 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].SetTabNo(nNewTab);
1706 void ScTable::FindRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1707 std::set<sal_uInt16>& rIndexes) const
1709 for (SCCOL i = nCol1; i <= nCol2 && ValidCol(i); i++)
1710 aCol[i].FindRangeNamesInUse(nRow1, nRow2, rIndexes);
1713 void ScTable::ExtendPrintArea( OutputDevice* pDev,
1714 SCCOL /* nStartCol */, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
1716 if ( !pColFlags || !pRowFlags )
1718 OSL_FAIL("ExtendPrintArea: No ColInfo or RowInfo");
1719 return;
1722 Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
1723 double nPPTX = aPix1000.X() / 1000.0;
1724 double nPPTY = aPix1000.Y() / 1000.0;
1726 // First, mark those columns that we need to skip i.e. hidden and empty columns.
1728 ScFlatBoolColSegments aSkipCols;
1729 aSkipCols.setFalse(0, MAXCOL);
1730 for (SCCOL i = 0; i <= MAXCOL; ++i)
1732 SCCOL nLastCol = i;
1733 if (ColHidden(i, NULL, &nLastCol))
1735 // Columns are hidden in this range.
1736 aSkipCols.setTrue(i, nLastCol);
1738 else
1740 // These columns are visible. Check for empty columns.
1741 for (SCCOL j = i; j <= nLastCol; ++j)
1743 if (aCol[j].GetCellCount() == 0)
1744 // empty
1745 aSkipCols.setTrue(j,j);
1748 i = nLastCol;
1751 ScFlatBoolColSegments::RangeData aColData;
1752 for (SCCOL nCol = rEndCol; nCol >= 0; --nCol)
1754 if (!aSkipCols.getRangeData(nCol, aColData))
1755 // Failed to get the data. This should never happen!
1756 return;
1758 if (aColData.mbValue)
1760 // Skip these columns.
1761 nCol = aColData.mnCol1; // move toward 0.
1762 continue;
1765 // These are visible and non-empty columns.
1766 for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= aColData.mnCol1; --nDataCol)
1768 SCCOL nPrintCol = nDataCol;
1769 VisibleDataCellIterator aIter(*mpHiddenRows, aCol[nDataCol]);
1770 ScRefCellValue aCell = aIter.reset(nStartRow);
1771 if (aCell.isEmpty())
1772 // No visible cells found in this column. Skip it.
1773 continue;
1775 while (!aCell.isEmpty())
1777 SCCOL nNewCol = nDataCol;
1778 SCROW nRow = aIter.getRow();
1779 if (nRow > nEndRow)
1780 // Went past the last row position. Bail out.
1781 break;
1783 MaybeAddExtraColumn(nNewCol, nRow, pDev, nPPTX, nPPTY);
1784 if (nNewCol > nPrintCol)
1785 nPrintCol = nNewCol;
1786 aCell = aIter.next();
1789 if (nPrintCol > rEndCol)
1790 // Make sure we don't shrink the print area.
1791 rEndCol = nPrintCol;
1793 nCol = aColData.mnCol1; // move toward 0.
1797 void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY)
1799 ScRefCellValue aCell = aCol[rCol].GetCellValue(nRow);
1800 if (!aCell.hasString())
1801 return;
1803 bool bFormula = false; //TODO: pass as parameter
1804 long nPixel = aCol[rCol].GetTextWidth(nRow);
1806 // Width already calculated in Idle-Handler ?
1807 if ( TEXTWIDTH_DIRTY == nPixel )
1809 ScNeededSizeOptions aOptions;
1810 aOptions.bTotalSize = true;
1811 aOptions.bFormula = bFormula;
1812 aOptions.bSkipMerged = false;
1814 Fraction aZoom(1,1);
1815 nPixel = aCol[rCol].GetNeededSize(
1816 nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions, NULL );
1818 aCol[rCol].SetTextWidth(nRow, static_cast<sal_uInt16>(nPixel));
1821 long nTwips = (long) (nPixel / nPPTX);
1822 long nDocW = GetColWidth( rCol );
1824 long nMissing = nTwips - nDocW;
1825 if ( nMissing > 0 )
1827 // look at alignment
1829 const ScPatternAttr* pPattern = GetPattern( rCol, nRow );
1830 const SfxItemSet* pCondSet = pDocument->GetCondResult( rCol, nRow, nTab );
1832 SvxCellHorJustify eHorJust = (SvxCellHorJustify)static_cast<const SvxHorJustifyItem&>(
1833 pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
1834 if ( eHorJust == SVX_HOR_JUSTIFY_CENTER )
1835 nMissing /= 2; // distributed into both directions
1836 else
1838 // STANDARD is LEFT (only text is handled here)
1839 bool bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT );
1840 if ( IsLayoutRTL() )
1841 bRight = !bRight;
1842 if ( bRight )
1843 nMissing = 0; // extended only to the left (logical)
1847 SCCOL nNewCol = rCol;
1848 while (nMissing > 0 && nNewCol < MAXCOL)
1850 ScRefCellValue aNextCell = aCol[nNewCol+1].GetCellValue(nRow);
1851 if (!aNextCell.isEmpty())
1852 // Cell content in a next column ends display of this string.
1853 nMissing = 0;
1854 else
1855 nMissing -= GetColWidth(++nNewCol);
1857 rCol = nNewCol;
1860 namespace {
1862 class SetTableIndex : public ::std::unary_function<ScRange, void>
1864 SCTAB mnTab;
1865 public:
1866 SetTableIndex(SCTAB nTab) : mnTab(nTab) {}
1868 void operator() (ScRange& rRange) const
1870 rRange.aStart.SetTab(mnTab);
1871 rRange.aEnd.SetTab(mnTab);
1875 void setPrintRange(ScRange*& pRange1, const ScRange* pRange2)
1877 if (pRange2)
1879 if (pRange1)
1880 *pRange1 = *pRange2;
1881 else
1882 pRange1 = new ScRange(*pRange2);
1884 else
1885 DELETEZ(pRange1);
1890 void ScTable::CopyPrintRange(const ScTable& rTable)
1892 // The table index shouldn't be used when the print range is used, but
1893 // just in case set the correct table index.
1895 aPrintRanges = rTable.aPrintRanges;
1896 ::std::for_each(aPrintRanges.begin(), aPrintRanges.end(), SetTableIndex(nTab));
1898 bPrintEntireSheet = rTable.bPrintEntireSheet;
1900 delete pRepeatColRange;
1901 pRepeatColRange = NULL;
1902 if (rTable.pRepeatColRange)
1904 pRepeatColRange = new ScRange(*rTable.pRepeatColRange);
1905 pRepeatColRange->aStart.SetTab(nTab);
1906 pRepeatColRange->aEnd.SetTab(nTab);
1909 delete pRepeatRowRange;
1910 pRepeatRowRange = NULL;
1911 if (rTable.pRepeatRowRange)
1913 pRepeatRowRange = new ScRange(*rTable.pRepeatRowRange);
1914 pRepeatRowRange->aStart.SetTab(nTab);
1915 pRepeatRowRange->aEnd.SetTab(nTab);
1919 void ScTable::SetRepeatColRange( const ScRange* pNew )
1921 setPrintRange( pRepeatColRange, pNew );
1923 if (IsStreamValid())
1924 SetStreamValid(false);
1926 InvalidatePageBreaks();
1929 void ScTable::SetRepeatRowRange( const ScRange* pNew )
1931 setPrintRange( pRepeatRowRange, pNew );
1933 if (IsStreamValid())
1934 SetStreamValid(false);
1936 InvalidatePageBreaks();
1939 void ScTable::ClearPrintRanges()
1941 aPrintRanges.clear();
1942 bPrintEntireSheet = false;
1944 if (IsStreamValid())
1945 SetStreamValid(false);
1947 InvalidatePageBreaks(); // #i117952# forget page breaks for an old print range
1950 void ScTable::AddPrintRange( const ScRange& rNew )
1952 bPrintEntireSheet = false;
1953 if( aPrintRanges.size() < 0xFFFF )
1954 aPrintRanges.push_back( rNew );
1956 if (IsStreamValid())
1957 SetStreamValid(false);
1959 InvalidatePageBreaks();
1962 void ScTable::SetPrintEntireSheet()
1964 if( !IsPrintEntireSheet() )
1966 ClearPrintRanges();
1967 bPrintEntireSheet = true;
1971 const ScRange* ScTable::GetPrintRange(sal_uInt16 nPos) const
1973 return (nPos < GetPrintRangeCount()) ? &aPrintRanges[ nPos ] : NULL;
1976 void ScTable::FillPrintSaver( ScPrintSaverTab& rSaveTab ) const
1978 rSaveTab.SetAreas( aPrintRanges, bPrintEntireSheet );
1979 rSaveTab.SetRepeat( pRepeatColRange, pRepeatRowRange );
1982 void ScTable::RestorePrintRanges( const ScPrintSaverTab& rSaveTab )
1984 aPrintRanges = rSaveTab.GetPrintRanges();
1985 bPrintEntireSheet = rSaveTab.IsEntireSheet();
1986 SetRepeatColRange( rSaveTab.GetRepeatCol() );
1987 SetRepeatRowRange( rSaveTab.GetRepeatRow() );
1989 InvalidatePageBreaks(); // #i117952# forget page breaks for an old print range
1990 UpdatePageBreaks(NULL);
1993 SCROW ScTable::VisibleDataCellIterator::ROW_NOT_FOUND = -1;
1995 ScTable::VisibleDataCellIterator::VisibleDataCellIterator(ScFlatBoolRowSegments& rRowSegs, ScColumn& rColumn) :
1996 mrRowSegs(rRowSegs),
1997 mrColumn(rColumn),
1998 mnCurRow(ROW_NOT_FOUND),
1999 mnUBound(ROW_NOT_FOUND)
2003 ScTable::VisibleDataCellIterator::~VisibleDataCellIterator()
2007 ScRefCellValue ScTable::VisibleDataCellIterator::reset(SCROW nRow)
2009 if (nRow > MAXROW)
2011 mnCurRow = ROW_NOT_FOUND;
2012 return ScRefCellValue();
2015 ScFlatBoolRowSegments::RangeData aData;
2016 if (!mrRowSegs.getRangeData(nRow, aData))
2018 mnCurRow = ROW_NOT_FOUND;
2019 return ScRefCellValue();
2022 if (!aData.mbValue)
2024 // specified row is visible. Take it.
2025 mnCurRow = nRow;
2026 mnUBound = aData.mnRow2;
2028 else
2030 // specified row is not-visible. The first visible row is the start of
2031 // the next segment.
2032 mnCurRow = aData.mnRow2 + 1;
2033 mnUBound = mnCurRow; // get range data on the next iteration.
2034 if (mnCurRow > MAXROW)
2036 // Make sure the row doesn't exceed our current limit.
2037 mnCurRow = ROW_NOT_FOUND;
2038 return ScRefCellValue();
2042 maCell = mrColumn.GetCellValue(mnCurRow);
2043 if (!maCell.isEmpty())
2044 // First visible cell found.
2045 return maCell;
2047 // Find a first visible cell below this row (if any).
2048 return next();
2051 ScRefCellValue ScTable::VisibleDataCellIterator::next()
2053 if (mnCurRow == ROW_NOT_FOUND)
2054 return ScRefCellValue();
2056 while (mrColumn.GetNextDataPos(mnCurRow))
2058 if (mnCurRow > mnUBound)
2060 // We don't know the visibility of this row range. Query it.
2061 ScFlatBoolRowSegments::RangeData aData;
2062 if (!mrRowSegs.getRangeData(mnCurRow, aData))
2064 mnCurRow = ROW_NOT_FOUND;
2065 return ScRefCellValue();
2068 if (aData.mbValue)
2070 // This row is invisible. Skip to the last invisible row and
2071 // try again.
2072 mnCurRow = mnUBound = aData.mnRow2;
2073 continue;
2076 // This row is visible.
2077 mnUBound = aData.mnRow2;
2080 maCell = mrColumn.GetCellValue(mnCurRow);
2081 if (!maCell.isEmpty())
2082 return maCell;
2085 mnCurRow = ROW_NOT_FOUND;
2086 return ScRefCellValue();
2089 void ScTable::SetAnonymousDBData(ScDBData* pDBData)
2091 delete pDBDataNoName;
2092 pDBDataNoName = pDBData;
2095 sal_uLong ScTable::AddCondFormat( ScConditionalFormat* pNew )
2097 if(!mpCondFormatList)
2098 mpCondFormatList.reset(new ScConditionalFormatList());
2100 sal_uLong nMax = 0;
2101 for(ScConditionalFormatList::const_iterator itr = mpCondFormatList->begin();
2102 itr != mpCondFormatList->end(); ++itr)
2104 sal_uLong nKey = itr->GetKey();
2105 if(nKey > nMax)
2106 nMax = nKey;
2109 pNew->SetKey(nMax+1);
2110 mpCondFormatList->InsertNew(pNew);
2112 return nMax + 1;
2115 SvtScriptType ScTable::GetScriptType( SCCOL nCol, SCROW nRow ) const
2117 if (!ValidCol(nCol))
2118 return SvtScriptType::NONE;
2120 return aCol[nCol].GetScriptType(nRow);
2123 void ScTable::SetScriptType( SCCOL nCol, SCROW nRow, SvtScriptType nType )
2125 if (!ValidCol(nCol))
2126 return;
2128 aCol[nCol].SetScriptType(nRow, nType);
2131 SvtScriptType ScTable::GetRangeScriptType(
2132 sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2134 if (!ValidCol(nCol))
2135 return SvtScriptType::NONE;
2137 sc::CellStoreType::iterator itr = aCol[nCol].maCells.begin();
2138 return aCol[nCol].GetRangeScriptType(rBlockPos.miCellTextAttrPos, nRow1, nRow2, itr);
2141 size_t ScTable::GetFormulaHash( SCCOL nCol, SCROW nRow ) const
2143 if (!ValidCol(nCol))
2144 return 0;
2146 return aCol[nCol].GetFormulaHash(nRow);
2149 ScFormulaVectorState ScTable::GetFormulaVectorState( SCCOL nCol, SCROW nRow ) const
2151 if (!ValidCol(nCol))
2152 return FormulaVectorUnknown;
2154 return aCol[nCol].GetFormulaVectorState(nRow);
2157 formula::FormulaTokenRef ScTable::ResolveStaticReference( SCCOL nCol, SCROW nRow )
2159 if (!ValidCol(nCol) || !ValidRow(nRow))
2160 return formula::FormulaTokenRef();
2162 return aCol[nCol].ResolveStaticReference(nRow);
2165 formula::FormulaTokenRef ScTable::ResolveStaticReference( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2167 if (nCol2 < nCol1 || nRow2 < nRow1)
2168 return formula::FormulaTokenRef();
2170 if (!ValidCol(nCol1) || !ValidCol(nCol2) || !ValidRow(nRow1) || !ValidRow(nRow2))
2171 return formula::FormulaTokenRef();
2173 ScMatrixRef pMat(new ScMatrix(nCol2-nCol1+1, nRow2-nRow1+1, 0.0));
2174 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
2176 if (!aCol[nCol].ResolveStaticReference(*pMat, nCol2-nCol1, nRow1, nRow2))
2177 // Column contains non-static cell. Failed.
2178 return formula::FormulaTokenRef();
2181 return formula::FormulaTokenRef(new ScMatrixToken(pMat));
2184 formula::VectorRefArray ScTable::FetchVectorRefArray( SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2186 if (nRow2 < nRow1)
2187 return formula::VectorRefArray();
2189 if (!ValidCol(nCol) || !ValidRow(nRow1) || !ValidRow(nRow2))
2190 return formula::VectorRefArray();
2192 return aCol[nCol].FetchVectorRefArray(nRow1, nRow2);
2195 ScRefCellValue ScTable::GetRefCellValue( SCCOL nCol, SCROW nRow )
2197 if (!ValidColRow(nCol, nRow))
2198 return ScRefCellValue();
2200 return aCol[nCol].GetCellValue(nRow);
2203 SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow )
2205 if (!ValidColRow(nCol, nRow))
2206 return NULL;
2208 return aCol[nCol].GetBroadcaster(nRow);
2211 void ScTable::DeleteBroadcasters(
2212 sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2214 if (!ValidCol(nCol))
2215 return;
2217 aCol[nCol].DeleteBroadcasters(rBlockPos, nRow1, nRow2);
2220 bool ScTable::HasBroadcaster( SCCOL nCol ) const
2222 if (!ValidCol(nCol))
2223 return false;
2225 return aCol[nCol].HasBroadcaster();
2228 void ScTable::FillMatrix( ScMatrix& rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
2230 size_t nMatCol = 0;
2231 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nMatCol)
2232 aCol[nCol].FillMatrix(rMat, nMatCol, nRow1, nRow2);
2235 void ScTable::InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2237 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
2238 aCol[nCol].InterpretDirtyCells(nRow1, nRow2);
2241 void ScTable::SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen )
2243 if (!ValidCol(nCol))
2244 return;
2246 aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
2249 void ScTable::SetFormulaResults(
2250 SCCOL nCol, SCROW nRow, const formula::FormulaTokenRef* pResults, size_t nLen )
2252 if (!ValidCol(nCol))
2253 return;
2255 aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
2258 #if DEBUG_COLUMN_STORAGE
2259 void ScTable::DumpFormulaGroups( SCCOL nCol ) const
2261 if (!ValidCol(nCol))
2262 return;
2264 aCol[nCol].DumpFormulaGroups();
2266 #endif
2268 const SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow ) const
2270 if (!ValidColRow(nCol, nRow))
2271 return NULL;
2273 return aCol[nCol].GetBroadcaster(nRow);
2276 void ScTable::DeleteConditionalFormat( sal_uLong nIndex )
2278 mpCondFormatList->erase(nIndex);
2281 void ScTable::SetCondFormList( ScConditionalFormatList* pNew )
2283 mpCondFormatList.reset( pNew );
2286 ScConditionalFormatList* ScTable::GetCondFormList()
2288 if(!mpCondFormatList)
2289 mpCondFormatList.reset( new ScConditionalFormatList() );
2291 return mpCondFormatList.get();
2294 const ScConditionalFormatList* ScTable::GetCondFormList() const
2296 return mpCondFormatList.get();
2299 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */