re-enabled user-defined numeric fields for dBase export
[LibreOffice.git] / sc / source / core / data / table1.cxx
blobc0e2c3f94e8261ad9a376336b22445c8cb5c69e6
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" // fuer Paint-Broadcast
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"
50 #include <vector>
52 using ::std::vector;
54 namespace {
56 ScProgress* GetProgressBar(
57 SCSIZE nCount, SCSIZE nTotalCount, ScProgress* pOuterProgress, ScDocument* pDoc)
59 if (nTotalCount < 1000)
61 // if the total number of rows is less than 1000, don't even bother
62 // with the progress bar because drawing progress bar can be very
63 // expensive especially in GTK.
64 return NULL;
67 if (pOuterProgress)
68 return pOuterProgress;
70 if (nCount > 1)
71 return new ScProgress(
72 pDoc->GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nTotalCount);
74 return NULL;
77 void GetOptimalHeightsInColumn(
78 ScColumn* pCol, SCROW nStartRow, SCROW nEndRow, vector<sal_uInt16>& aHeights,
79 OutputDevice* pDev, double nPPTX, double nPPTY, const Fraction& rZoomX, const Fraction& rZoomY, bool bForce,
80 ScProgress* pProgress, sal_uInt32 nProgressStart)
82 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
84 // zuerst einmal ueber den ganzen Bereich
85 // (mit der letzten Spalte in der Hoffnung, dass die am ehesten noch auf
86 // Standard formatiert ist)
88 pCol[MAXCOL].GetOptimalHeight(
89 nStartRow, nEndRow, &aHeights[0], pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce, 0, 0 );
91 // daraus Standardhoehe suchen, die im unteren Bereich gilt
93 sal_uInt16 nMinHeight = aHeights[nCount-1];
94 SCSIZE nPos = nCount-1;
95 while ( nPos && aHeights[nPos-1] >= nMinHeight )
96 --nPos;
97 SCROW nMinStart = nStartRow + nPos;
99 sal_uLong nWeightedCount = 0;
100 for (SCCOL nCol=0; nCol<MAXCOL; nCol++) // MAXCOL schon oben
102 pCol[nCol].GetOptimalHeight(
103 nStartRow, nEndRow, &aHeights[0], pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce,
104 nMinHeight, nMinStart );
106 if (pProgress)
108 sal_uLong nWeight = pCol[nCol].GetWeightedCount();
109 if (nWeight) // nochmal denselben Status muss auch nicht sein
111 nWeightedCount += nWeight;
112 pProgress->SetState( nWeightedCount + nProgressStart );
118 struct OptimalHeightsFuncObjBase
120 virtual ~OptimalHeightsFuncObjBase() {}
121 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight) = 0;
124 struct SetRowHeightOnlyFunc : public OptimalHeightsFuncObjBase
126 ScTable* mpTab;
127 SetRowHeightOnlyFunc(ScTable* pTab) :
128 mpTab(pTab)
131 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight)
133 mpTab->SetRowHeightOnly(nStartRow, nEndRow, nHeight);
134 return false;
138 struct SetRowHeightRangeFunc : public OptimalHeightsFuncObjBase
140 ScTable* mpTab;
141 double mnPPTX;
142 double mnPPTY;
144 SetRowHeightRangeFunc(ScTable* pTab, double nPPTX, double nPPTY) :
145 mpTab(pTab),
146 mnPPTX(nPPTX),
147 mnPPTY(nPPTY)
150 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight)
152 return mpTab->SetRowHeightRange(nStartRow, nEndRow, nHeight, mnPPTX, mnPPTY);
156 bool SetOptimalHeightsToRows(OptimalHeightsFuncObjBase& rFuncObj,
157 ScBitMaskCompressedArray<SCROW, sal_uInt8>* pRowFlags, SCROW nStartRow, SCROW nEndRow, sal_uInt16 nExtra,
158 const vector<sal_uInt16>& aHeights, bool bForce)
160 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
161 bool bChanged = false;
162 SCROW nRngStart = 0;
163 SCROW nRngEnd = 0;
164 sal_uInt16 nLast = 0;
165 for (SCSIZE i=0; i<nCount; i++)
167 size_t nIndex;
168 SCROW nRegionEndRow;
169 sal_uInt8 nRowFlag = pRowFlags->GetValue( nStartRow+i, nIndex, nRegionEndRow );
170 if ( nRegionEndRow > nEndRow )
171 nRegionEndRow = nEndRow;
172 SCSIZE nMoreRows = nRegionEndRow - ( nStartRow+i ); // additional equal rows after first
174 bool bAutoSize = ((nRowFlag & CR_MANUALSIZE) == 0);
175 if ( bAutoSize || bForce )
177 if (nExtra)
179 if (bAutoSize)
180 pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag | CR_MANUALSIZE);
182 else if (!bAutoSize)
183 pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag & ~CR_MANUALSIZE);
185 for (SCSIZE nInner = i; nInner <= i + nMoreRows; ++nInner)
187 if (nLast)
189 if (aHeights[nInner]+nExtra == nLast)
190 nRngEnd = nStartRow+nInner;
191 else
193 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
194 nLast = 0;
197 if (!nLast)
199 nLast = aHeights[nInner]+nExtra;
200 nRngStart = nStartRow+nInner;
201 nRngEnd = nStartRow+nInner;
205 else
207 if (nLast)
208 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
209 nLast = 0;
211 i += nMoreRows; // already handled - skip
213 if (nLast)
214 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast);
216 return bChanged;
221 // -----------------------------------------------------------------------
223 ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName,
224 bool bColInfo, bool bRowInfo ) :
225 aName( rNewName ),
226 aCodeName( rNewName ),
227 nLinkMode( 0 ),
228 aPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) ),
229 nRepeatStartX( SCCOL_REPEAT_NONE ),
230 nRepeatEndX( SCCOL_REPEAT_NONE ),
231 nRepeatStartY( SCROW_REPEAT_NONE ),
232 nRepeatEndY( SCROW_REPEAT_NONE ),
233 pTabProtection( NULL ),
234 pColWidth( NULL ),
235 mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(NULL) ),
236 pColFlags( NULL ),
237 pRowFlags( NULL ),
238 mpHiddenCols(new ScFlatBoolColSegments),
239 mpHiddenRows(new ScFlatBoolRowSegments),
240 mpFilteredCols(new ScFlatBoolColSegments),
241 mpFilteredRows(new ScFlatBoolRowSegments),
242 pOutlineTable( NULL ),
243 pSheetEvents( NULL ),
244 nTab( nNewTab ),
245 pDocument( pDoc ),
246 pSearchText ( NULL ),
247 pSortCollator( NULL ),
248 pRepeatColRange( NULL ),
249 pRepeatRowRange( NULL ),
250 nLockCount( 0 ),
251 pScenarioRanges( NULL ),
252 aScenarioColor( COL_LIGHTGRAY ),
253 aTabBgColor( COL_AUTO ),
254 nScenarioFlags( 0 ),
255 pDBDataNoName(NULL),
256 mpRangeName(NULL),
257 mpCondFormatList( new ScConditionalFormatList() ),
258 maNotes(pDoc),
259 bScenario(false),
260 bLayoutRTL(false),
261 bLoadingRTL(false),
262 bPageSizeValid(false),
263 bTableAreaValid(false),
264 bVisible(true),
265 bStreamValid(false),
266 bPendingRowHeights(false),
267 bCalcNotification(false),
268 bGlobalKeepQuery(false),
269 bPrintEntireSheet(true),
270 bActiveScenario(false),
271 mbPageBreaksValid(false)
274 if (bColInfo)
276 pColWidth = new sal_uInt16[ MAXCOL+1 ];
277 pColFlags = new sal_uInt8[ MAXCOL+1 ];
279 for (SCCOL i=0; i<=MAXCOL; i++)
281 pColWidth[i] = STD_COL_WIDTH;
282 pColFlags[i] = 0;
286 if (bRowInfo)
288 mpRowHeights.reset(new ScFlatUInt16RowSegments(ScGlobal::nStdRowHeight));
289 pRowFlags = new ScBitMaskCompressedArray< SCROW, sal_uInt8>( MAXROW, 0);
292 if ( pDocument->IsDocVisible() )
294 // when a sheet is added to a visible document,
295 // initialize its RTL flag from the system locale
296 bLayoutRTL = ScGlobal::IsSystemRTL();
299 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
300 if (pDrawLayer)
302 if ( pDrawLayer->ScAddPage( nTab ) ) // sal_False (not inserted) during Undo
304 pDrawLayer->ScRenamePage( nTab, aName );
305 sal_uLong nx = (sal_uLong) ((double) (MAXCOL+1) * STD_COL_WIDTH * HMM_PER_TWIPS );
306 sal_uLong ny = (sal_uLong) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS );
307 pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( nx, ny ), false );
311 for (SCCOL k=0; k<=MAXCOL; k++)
312 aCol[k].Init( k, nTab, pDocument );
315 ScTable::~ScTable()
317 if (!pDocument->IsInDtorClear())
319 // nicht im dtor die Pages in der falschen Reihenfolge loeschen
320 // (nTab stimmt dann als Page-Number nicht!)
321 // In ScDocument::Clear wird hinterher per Clear am Draw Layer alles geloescht.
323 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
324 if (pDrawLayer)
325 pDrawLayer->ScRemovePage( nTab );
328 delete[] pColWidth;
329 delete[] pColFlags;
330 delete pRowFlags;
331 delete pSheetEvents;
332 delete pOutlineTable;
333 delete pSearchText;
334 delete pRepeatColRange;
335 delete pRepeatRowRange;
336 delete pScenarioRanges;
337 delete mpRangeName;
338 delete pDBDataNoName;
339 DestroySortCollator();
342 void ScTable::GetName( OUString& rName ) const
344 rName = aName;
347 void ScTable::SetName( const OUString& rNewName )
349 aName = rNewName;
350 aUpperName = OUString(); // invalidated if the name is changed
352 // SetStreamValid is handled in ScDocument::RenameTab
355 const OUString& ScTable::GetUpperName() const
357 if (aUpperName.isEmpty() && !aName.isEmpty())
358 aUpperName = ScGlobal::pCharClass->uppercase(aName);
359 return aUpperName;
362 void ScTable::SetVisible( bool bVis )
364 if (bVisible != bVis && IsStreamValid())
365 SetStreamValid(false);
367 bVisible = bVis;
370 void ScTable::SetStreamValid( bool bSet, bool bIgnoreLock )
372 if ( bIgnoreLock || !pDocument->IsStreamValidLocked() )
373 bStreamValid = bSet;
376 void ScTable::SetPendingRowHeights( bool bSet )
378 bPendingRowHeights = bSet;
381 void ScTable::SetLayoutRTL( bool bSet )
383 bLayoutRTL = bSet;
386 void ScTable::SetLoadingRTL( bool bSet )
388 bLoadingRTL = bSet;
391 const Color& ScTable::GetTabBgColor() const
393 return aTabBgColor;
396 void ScTable::SetTabBgColor(const Color& rColor)
398 if (aTabBgColor != rColor)
400 // The tab color has changed. Set this table 'modified'.
401 aTabBgColor = rColor;
402 if (IsStreamValid())
403 SetStreamValid(false);
407 void ScTable::SetScenario( bool bFlag )
409 bScenario = bFlag;
412 void ScTable::SetLink( sal_uInt8 nMode,
413 const String& rDoc, const String& rFlt, const String& rOpt,
414 const String& rTab, sal_uLong nRefreshDelay )
416 nLinkMode = nMode;
417 aLinkDoc = rDoc; // Datei
418 aLinkFlt = rFlt; // Filter
419 aLinkOpt = rOpt; // Filter-Optionen
420 aLinkTab = rTab; // Tabellenname in Quelldatei
421 nLinkRefreshDelay = nRefreshDelay; // refresh delay in seconds, 0==off
423 if (IsStreamValid())
424 SetStreamValid(false);
427 sal_uInt16 ScTable::GetOptimalColWidth( SCCOL nCol, OutputDevice* pDev,
428 double nPPTX, double nPPTY,
429 const Fraction& rZoomX, const Fraction& rZoomY,
430 bool bFormula, const ScMarkData* pMarkData,
431 const ScColWidthParam* pParam )
433 return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
434 bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, pParam );
437 long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
438 OutputDevice* pDev,
439 double nPPTX, double nPPTY,
440 const Fraction& rZoomX, const Fraction& rZoomY,
441 bool bWidth, bool bTotalSize )
443 ScNeededSizeOptions aOptions;
444 aOptions.bSkipMerged = false; // zusammengefasste mitzaehlen
445 aOptions.bTotalSize = bTotalSize;
447 return aCol[nCol].GetNeededSize
448 ( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, aOptions );
451 bool ScTable::SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nExtra,
452 OutputDevice* pDev,
453 double nPPTX, double nPPTY,
454 const Fraction& rZoomX, const Fraction& rZoomY,
455 bool bForce, ScProgress* pOuterProgress, sal_uLong nProgressStart )
457 OSL_ENSURE( nExtra==0 || bForce, "automatic OptimalHeight with Extra" );
459 if ( !pDocument->IsAdjustHeightEnabled() )
461 return false;
464 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
466 ScProgress* pProgress = GetProgressBar(nCount, GetWeightedCount(), pOuterProgress, pDocument);
468 vector<sal_uInt16> aHeights(nCount, 0);
470 GetOptimalHeightsInColumn(
471 aCol, nStartRow, nEndRow, aHeights, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce,
472 pProgress, nProgressStart);
474 SetRowHeightRangeFunc aFunc(this, nPPTX, nPPTY);
475 bool bChanged = SetOptimalHeightsToRows(
476 aFunc, pRowFlags, nStartRow, nEndRow, nExtra, aHeights, bForce);
478 if ( pProgress != pOuterProgress )
479 delete pProgress;
481 return bChanged;
484 void ScTable::SetOptimalHeightOnly( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nExtra,
485 OutputDevice* pDev,
486 double nPPTX, double nPPTY,
487 const Fraction& rZoomX, const Fraction& rZoomY,
488 bool bForce, ScProgress* pOuterProgress, sal_uLong nProgressStart )
490 OSL_ENSURE( nExtra==0 || bForce, "automatic OptimalHeight with Extra" );
492 if ( !pDocument->IsAdjustHeightEnabled() )
493 return;
495 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
497 ScProgress* pProgress = GetProgressBar(nCount, GetWeightedCount(), pOuterProgress, pDocument);
499 vector<sal_uInt16> aHeights(nCount, 0);
501 GetOptimalHeightsInColumn(
502 aCol, nStartRow, nEndRow, aHeights, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce,
503 pProgress, nProgressStart);
505 SetRowHeightOnlyFunc aFunc(this);
506 SetOptimalHeightsToRows(
507 aFunc, pRowFlags, nStartRow, nEndRow, nExtra, aHeights, bForce);
509 if ( pProgress != pOuterProgress )
510 delete pProgress;
513 bool ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const
515 bool bFound = false;
516 SCCOL nMaxX = 0;
517 SCROW nMaxY = 0;
518 for (SCCOL i=0; i<=MAXCOL; i++)
519 if (!aCol[i].IsEmptyVisData())
521 bFound = true;
522 nMaxX = i;
523 SCROW nColY = aCol[i].GetLastVisDataPos();
524 if (nColY > nMaxY)
525 nMaxY = nColY;
528 for (ScNotes::const_iterator itr = maNotes.begin(); itr != maNotes.end(); ++itr)
530 SCCOL nCol = itr->first.first;
531 SCROW nRow = itr->first.second;
533 if (nMaxX < nCol)
534 nMaxX = nCol;
535 if (nMaxY < nRow)
536 nMaxY = nRow;
539 rEndCol = nMaxX;
540 rEndRow = nMaxY;
541 return bFound;
544 bool ScTable::GetTableArea( SCCOL& rEndCol, SCROW& rEndRow ) const
546 bool bRet = true; //! merken?
547 if (!bTableAreaValid)
549 bRet = GetPrintArea(nTableAreaX, nTableAreaY, true);
550 bTableAreaValid = true;
552 rEndCol = nTableAreaX;
553 rEndRow = nTableAreaY;
554 return bRet;
557 const SCCOL SC_COLUMNS_STOP = 30;
559 bool ScTable::GetPrintArea( SCCOL& rEndCol, SCROW& rEndRow, bool bNotes, bool bFullFormattedArea ) const
561 bool bFound = false;
562 SCCOL nMaxX = 0;
563 SCROW nMaxY = 0;
564 SCCOL i;
566 for (i=0; i<=MAXCOL; i++) // Daten testen
567 if (!aCol[i].IsEmptyVisData())
569 bFound = true;
570 if (i>nMaxX)
571 nMaxX = i;
572 SCROW nColY = aCol[i].GetLastVisDataPos();
573 if (nColY > nMaxY)
574 nMaxY = nColY;
577 if (bNotes)
579 for (ScNotes::const_iterator itr = maNotes.begin(); itr != maNotes.end(); ++itr)
581 SCCOL nCol = itr->first.first;
582 SCROW nRow = itr->first.second;
584 if (nMaxX < nCol)
585 nMaxX = nCol;
586 if (nMaxY < nRow)
587 nMaxY = nRow;
591 SCCOL nMaxDataX = nMaxX;
593 for (i=0; i<=MAXCOL; i++) // Attribute testen
595 SCROW nLastRow;
596 if (aCol[i].GetLastVisibleAttr( nLastRow, bFullFormattedArea ))
598 bFound = true;
599 nMaxX = i;
600 if (nLastRow > nMaxY)
601 nMaxY = nLastRow;
605 if (nMaxX == MAXCOL) // Attribute rechts weglassen
607 --nMaxX;
608 while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1]) )
609 --nMaxX;
612 if ( nMaxX < nMaxDataX )
614 nMaxX = nMaxDataX;
616 else if ( nMaxX > nMaxDataX )
618 SCCOL nAttrStartX = nMaxDataX + 1;
619 while ( nAttrStartX < MAXCOL )
621 SCCOL nAttrEndX = nAttrStartX;
622 while ( nAttrEndX < MAXCOL && aCol[nAttrStartX].IsVisibleAttrEqual(aCol[nAttrEndX+1]) )
623 ++nAttrEndX;
624 if ( nAttrEndX + 1 - nAttrStartX >= SC_COLUMNS_STOP )
626 // found equally-formatted columns behind data -> stop before these columns
627 nMaxX = nAttrStartX - 1;
629 // also don't include default-formatted columns before that
630 SCROW nDummyRow;
631 while ( nMaxX > nMaxDataX && !aCol[nMaxX].GetLastVisibleAttr( nDummyRow ) )
632 --nMaxX;
633 break;
635 nAttrStartX = nAttrEndX + 1;
639 rEndCol = nMaxX;
640 rEndRow = nMaxY;
641 return bFound;
644 bool ScTable::GetPrintAreaHor( SCROW nStartRow, SCROW nEndRow,
645 SCCOL& rEndCol, bool /* bNotes */ ) const
647 bool bFound = false;
648 SCCOL nMaxX = 0;
649 SCCOL i;
651 for (i=0; i<=MAXCOL; i++) // Attribute testen
653 if (aCol[i].HasVisibleAttrIn( nStartRow, nEndRow ))
655 bFound = true;
656 nMaxX = i;
660 if (nMaxX == MAXCOL) // Attribute rechts weglassen
662 --nMaxX;
663 while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1], nStartRow, nEndRow) )
664 --nMaxX;
667 for (i=0; i<=MAXCOL; i++) // Daten testen
669 if (!aCol[i].IsEmptyBlock( nStartRow, nEndRow )) //! bNotes ??????
671 bFound = true;
672 if (i>nMaxX)
673 nMaxX = i;
677 rEndCol = nMaxX;
678 return bFound;
681 bool ScTable::GetPrintAreaVer( SCCOL nStartCol, SCCOL nEndCol,
682 SCROW& rEndRow, bool bNotes ) const
684 bool bFound = false;
685 SCROW nMaxY = 0;
686 SCCOL i;
688 for (i=nStartCol; i<=nEndCol; i++) // Attribute testen
690 SCROW nLastRow;
691 if (aCol[i].GetLastVisibleAttr( nLastRow ))
693 bFound = true;
694 if (nLastRow > nMaxY)
695 nMaxY = nLastRow;
699 for (i=nStartCol; i<=nEndCol; i++) // Daten testen
700 if (!aCol[i].IsEmptyVisData())
702 bFound = true;
703 SCROW nColY = aCol[i].GetLastVisDataPos();
704 if (nColY > nMaxY)
705 nMaxY = nColY;
708 if (bNotes)
710 for (ScNotes::const_iterator itr = maNotes.begin(); itr != maNotes.end(); ++itr)
712 SCCOL nCol = itr->first.first;
713 SCROW nRow = itr->first.second;
715 if (nStartCol > nCol || nEndCol < nCol)
716 continue;
718 if (nMaxY < nRow)
719 nMaxY = nRow;
723 rEndRow = nMaxY;
724 return bFound;
727 bool ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const
729 bool bFound = false;
730 SCCOL nMinX = MAXCOL;
731 SCROW nMinY = MAXROW;
732 SCCOL i;
734 for (i=0; i<=MAXCOL; i++) // Attribute testen
736 SCROW nFirstRow;
737 if (aCol[i].GetFirstVisibleAttr( nFirstRow ))
739 if (!bFound)
740 nMinX = i;
741 bFound = true;
742 if (nFirstRow < nMinY)
743 nMinY = nFirstRow;
747 if (nMinX == 0) // Attribute links weglassen
749 if ( aCol[0].IsVisibleAttrEqual(aCol[1]) ) // keine einzelnen
751 ++nMinX;
752 while ( nMinX<MAXCOL && aCol[nMinX].IsVisibleAttrEqual(aCol[nMinX-1]) )
753 ++nMinX;
757 bool bDatFound = false;
758 for (i=0; i<=MAXCOL; i++) // Daten testen
759 if (!aCol[i].IsEmptyVisData())
761 if (!bDatFound && i<nMinX)
762 nMinX = i;
763 bFound = bDatFound = true;
764 SCROW nColY = aCol[i].GetFirstVisDataPos();
765 if (nColY < nMinY)
766 nMinY = nColY;
769 for (ScNotes::const_iterator itr = maNotes.begin(); itr != maNotes.end(); ++itr)
771 bFound = bDatFound = true;
772 SCCOL nCol = itr->first.first;
773 SCROW nRow = itr->first.second;
775 if (nMinX > nCol)
776 nMinX = nCol;
777 if (nMinY > nRow)
778 nMinY = nRow;
781 rStartCol = nMinX;
782 rStartRow = nMinY;
783 return bFound;
786 void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
787 bool bIncludeOld, bool bOnlyDown ) const
789 // return the smallest area containing at least all contiguous cells having data. This area
790 // is a square containing also empty cells. It may shrink or extend the area given as input
791 // Flags as modifiers:
793 // bIncludeOld = true ensure that the returned area contains at least the initial area,
794 // independently of the emptniess of rows / columns (i.e. does not allow shrinking)
795 // bOnlyDown = true means extend / shrink the inputed area only down, i.e modifiy only rEndRow
797 bool bLeft = false;
798 bool bRight = false;
799 bool bTop = false;
800 bool bBottom = false;
801 bool bChanged = false;
805 bChanged = false;
807 if (!bOnlyDown)
809 SCROW nStart = rStartRow;
810 SCROW nEnd = rEndRow;
811 if (nStart>0) --nStart;
812 if (nEnd<MAXROW) ++nEnd;
814 if (rEndCol < MAXCOL)
815 if (!aCol[rEndCol+1].IsEmptyBlock(nStart,nEnd))
817 ++rEndCol;
818 bChanged = true;
819 bRight = true;
822 if (rStartCol > 0)
823 if (!aCol[rStartCol-1].IsEmptyBlock(nStart,nEnd))
825 --rStartCol;
826 bChanged = true;
827 bLeft = true;
830 if (rStartRow > 0)
832 SCROW nTest = rStartRow-1;
833 bool needExtend = false;
834 for ( SCCOL i = rStartCol; i<=rEndCol && !needExtend; i++)
835 if (aCol[i].HasDataAt(nTest))
836 needExtend = true;
837 if (needExtend)
839 --rStartRow;
840 bChanged = true;
841 bTop = true;
846 if (rEndRow < MAXROW)
848 SCROW nTest = rEndRow+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 ++rEndRow;
856 bChanged = true;
857 bBottom = true;
861 while( bChanged );
863 if ( !bIncludeOld && !bOnlyDown )
865 if ( !bLeft )
866 while ( aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) && rStartCol < MAXCOL && rStartCol < rEndCol)
867 ++rStartCol;
869 if ( !bRight )
870 while ( aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) && rEndCol > 0 && rStartCol < rEndCol)
871 --rEndCol;
873 if ( !bTop && rStartRow < MAXROW && rStartRow < rEndRow )
875 bool shrink = true;
878 for ( SCCOL i = rStartCol; i<=rEndCol && shrink; i++)
879 if (aCol[i].HasDataAt(rStartRow))
880 shrink = false;
881 if (shrink)
882 ++rStartRow;
883 }while( shrink && rStartRow < MAXROW && rStartRow < rEndRow);
887 if ( !bIncludeOld )
889 if ( !bBottom && rEndRow > 0 && rStartRow < rEndRow )
891 bool shrink = true;
894 for ( SCCOL i = rStartCol; i<=rEndCol && shrink; i++)
895 if (aCol[i].HasDataAt(rEndRow))
896 shrink = false;
897 if (shrink)
898 --rEndRow;
899 }while( shrink && rEndRow > 0 && rStartRow < rEndRow );
905 bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
906 SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const
908 o_bShrunk = false;
910 PutInOrder( rStartCol, rEndCol);
911 PutInOrder( rStartRow, rEndRow);
912 if (rStartCol < 0)
913 rStartCol = 0, o_bShrunk = true;
914 if (rStartRow < 0)
915 rStartRow = 0, o_bShrunk = true;
916 if (rEndCol > MAXCOL)
917 rEndCol = MAXCOL, o_bShrunk = true;
918 if (rEndRow > MAXROW)
919 rEndRow = MAXROW, o_bShrunk = true;
921 bool bChanged;
924 bChanged = false;
926 while (rStartCol < rEndCol)
928 if (aCol[rEndCol].IsEmptyBlock( rStartRow, rEndRow))
930 --rEndCol;
931 bChanged = true;
933 else
934 break; // while
937 while (rStartCol < rEndCol)
939 if (aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow))
941 ++rStartCol;
942 bChanged = true;
944 else
945 break; // while
948 if (!bColumnsOnly)
950 if (rStartRow < rEndRow)
952 bool bFound = false;
953 for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
954 if (aCol[i].HasDataAt( rStartRow))
955 bFound = true;
956 if (!bFound)
958 ++rStartRow;
959 bChanged = true;
963 if (rStartRow < rEndRow)
965 bool bFound = false;
966 for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
967 if (aCol[i].HasDataAt( rEndRow))
968 bFound = true;
969 if (!bFound)
971 --rEndRow;
972 bChanged = true;
977 if (bChanged)
978 o_bShrunk = true;
979 } while( bChanged );
981 return rStartCol != rEndCol || (bColumnsOnly ?
982 !aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow) :
983 (rStartRow != rEndRow || aCol[rStartCol].HasDataAt( rStartRow)));
987 SCSIZE ScTable::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
988 SCCOL nEndCol, SCROW nEndRow, ScDirection eDir ) const
990 SCSIZE nCount = 0;
991 SCCOL nCol;
992 if ((eDir == DIR_BOTTOM) || (eDir == DIR_TOP))
994 nCount = static_cast<SCSIZE>(nEndRow - nStartRow);
995 for (nCol = nStartCol; nCol <= nEndCol; nCol++)
996 nCount = std::min(nCount, aCol[nCol].GetEmptyLinesInBlock(nStartRow, nEndRow, eDir));
998 else if (eDir == DIR_RIGHT)
1000 nCol = nEndCol;
1001 while (((SCsCOL)nCol >= (SCsCOL)nStartCol) &&
1002 aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
1004 nCount++;
1005 nCol--;
1008 else
1010 nCol = nStartCol;
1011 while ((nCol <= nEndCol) && aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
1013 nCount++;
1014 nCol++;
1017 return nCount;
1020 bool ScTable::IsEmptyLine( SCROW nRow, SCCOL nStartCol, SCCOL nEndCol ) const
1022 bool bFound = false;
1023 for (SCCOL i=nStartCol; i<=nEndCol && !bFound; i++)
1024 if (aCol[i].HasDataAt(nRow))
1025 bFound = true;
1026 return !bFound;
1029 void ScTable::LimitChartArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow ) const
1031 while ( rStartCol<rEndCol && aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) )
1032 ++rStartCol;
1034 while ( rStartCol<rEndCol && aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) )
1035 --rEndCol;
1037 while ( rStartRow<rEndRow && IsEmptyLine(rStartRow, rStartCol, rEndCol) )
1038 ++rStartRow;
1040 while ( rStartRow<rEndRow && IsEmptyLine(rEndRow, rStartCol, rEndCol) )
1041 --rEndRow;
1044 SCCOL ScTable::FindNextVisibleCol( SCCOL nCol, bool bRight ) const
1046 if(bRight)
1048 nCol++;
1049 SCCOL nEnd = 0;
1050 bool bHidden = pDocument->ColHidden(nCol, nTab, NULL, &nEnd);
1051 if(bHidden)
1052 nCol = nEnd +1;
1054 return std::min<SCCOL>(MAXCOL, nCol);
1056 else
1058 nCol--;
1059 SCCOL nStart = MAXCOL;
1060 bool bHidden = pDocument->ColHidden(nCol, nTab, &nStart, NULL);
1061 if(bHidden)
1062 nCol = nStart - 1;
1064 return std::max<SCCOL>(0, nCol);
1068 SCCOL ScTable::FindNextVisibleColWithContent( SCCOL nCol, bool bRight, SCROW nRow ) const
1070 if(bRight)
1072 if(nCol == MAXCOL)
1073 return MAXCOL;
1077 nCol++;
1078 SCCOL nEndCol = 0;
1079 bool bHidden = pDocument->ColHidden( nCol, nTab, NULL, &nEndCol );
1080 if(bHidden)
1082 nCol = nEndCol +1;
1083 if(nEndCol >= MAXCOL)
1084 return MAXCOL;
1087 if(aCol[nCol].HasVisibleDataAt(nRow))
1088 return nCol;
1090 while(nCol < MAXCOL);
1092 return MAXCOL;
1094 else
1096 if(nCol == 0)
1097 return 0;
1101 nCol--;
1102 SCCOL nStartCol = MAXCOL;
1103 bool bHidden = pDocument->ColHidden( nCol, nTab, &nStartCol, NULL );
1104 if(bHidden)
1106 nCol = nStartCol -1;
1107 if(nCol <= 0)
1108 return 0;
1111 if(aCol[nCol].HasVisibleDataAt(nRow))
1112 return nCol;
1114 while(nCol > 0);
1116 return 0;
1120 void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, ScMoveDirection eDirection ) const
1122 if (eDirection == SC_MOVE_LEFT || eDirection == SC_MOVE_RIGHT)
1124 SCCOL nNewCol = rCol;
1125 bool bThere = aCol[nNewCol].HasVisibleDataAt(rRow);
1126 bool bRight = (eDirection == SC_MOVE_RIGHT);
1127 if (bThere)
1129 if(nNewCol >= MAXCOL && eDirection == SC_MOVE_RIGHT)
1130 return;
1131 else if(nNewCol == 0 && eDirection == SC_MOVE_LEFT)
1132 return;
1134 SCCOL nNextCol = FindNextVisibleCol( nNewCol, bRight );
1136 if(aCol[nNextCol].HasVisibleDataAt(rRow))
1138 bool bFound = false;
1139 nNewCol = nNextCol;
1142 nNextCol = FindNextVisibleCol( nNewCol, bRight );
1143 if(aCol[nNextCol].HasVisibleDataAt(rRow))
1144 nNewCol = nNextCol;
1145 else
1146 bFound = true;
1148 while(!bFound && nNextCol > 0 && nNextCol < MAXCOL);
1150 else
1152 nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
1155 else
1157 nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
1160 if (nNewCol<0)
1161 nNewCol=0;
1162 if (nNewCol>MAXCOL)
1163 nNewCol=MAXCOL;
1164 rCol = nNewCol;
1166 else
1168 aCol[rCol].FindDataAreaPos(rRow,eDirection == SC_MOVE_DOWN);
1172 bool ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
1173 bool bMarked, bool bUnprotected ) const
1175 if (!ValidCol(nCol) || !ValidRow(nRow))
1176 return false;
1178 if (pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED))
1179 // Skip an overlapped cell.
1180 return false;
1182 if (bMarked && !rMark.IsCellMarked(nCol,nRow))
1183 return false;
1185 if (bUnprotected && ((const ScProtectionAttr*)
1186 GetAttr(nCol,nRow,ATTR_PROTECTION))->GetProtection())
1187 return false;
1189 if (bMarked || bUnprotected) //! auch sonst ???
1191 // ausgeblendete muessen uebersprungen werden, weil der Cursor sonst
1192 // auf der naechsten Zelle landet, auch wenn die geschuetzt/nicht markiert ist.
1193 //! per Extra-Parameter steuern, nur fuer Cursor-Bewegung ???
1195 if (RowHidden(nRow))
1196 return false;
1198 if (ColHidden(nCol))
1199 return false;
1202 return true;
1205 void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
1206 bool bMarked, bool bUnprotected, const ScMarkData& rMark ) const
1208 if (bUnprotected && !IsProtected()) // Tabelle ueberhaupt geschuetzt?
1209 bUnprotected = false;
1211 sal_uInt16 nWrap = 0;
1212 SCsCOL nCol = rCol;
1213 SCsROW nRow = rRow;
1215 nCol = sal::static_int_cast<SCsCOL>( nCol + nMovX );
1216 nRow = sal::static_int_cast<SCsROW>( nRow + nMovY );
1218 OSL_ENSURE( !nMovY || !bUnprotected,
1219 "GetNextPos mit bUnprotected horizontal nicht implementiert" );
1221 if ( nMovY && bMarked )
1223 bool bUp = ( nMovY < 0 );
1224 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1225 while ( ValidRow(nRow) &&
1226 (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
1228 // ausgeblendete ueberspringen (s.o.)
1229 nRow += nMovY;
1230 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1233 while ( nRow < 0 || nRow > MAXROW )
1235 nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );
1236 while ( ValidCol(nCol) && ColHidden(nCol) )
1237 nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) ); // skip hidden rows (see above)
1238 if (nCol < 0)
1240 nCol = MAXCOL;
1241 if (++nWrap >= 2)
1242 return;
1244 else if (nCol > MAXCOL)
1246 nCol = 0;
1247 if (++nWrap >= 2)
1248 return;
1250 if (nRow < 0)
1251 nRow = MAXROW;
1252 else if (nRow > MAXROW)
1253 nRow = 0;
1254 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1255 while ( ValidRow(nRow) &&
1256 (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
1258 // ausgeblendete ueberspringen (s.o.)
1259 nRow += nMovY;
1260 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1265 if ( nMovX && ( bMarked || bUnprotected ) )
1267 // initiales Weiterzaehlen wrappen:
1268 if (nCol<0)
1270 nCol = MAXCOL;
1271 --nRow;
1272 if (nRow<0)
1273 nRow = MAXROW;
1275 if (nCol>MAXCOL)
1277 nCol = 0;
1278 ++nRow;
1279 if (nRow>MAXROW)
1280 nRow = 0;
1283 if ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) )
1285 SCsROW* pNextRows = new SCsROW[MAXCOL+1];
1286 SCCOL i;
1288 if ( nMovX > 0 ) // vorwaerts
1290 for (i=0; i<=MAXCOL; i++)
1291 pNextRows[i] = (i<nCol) ? (nRow+1) : nRow;
1294 SCsROW nNextRow = pNextRows[nCol] + 1;
1295 if ( bMarked )
1296 nNextRow = rMark.GetNextMarked( nCol, nNextRow, false );
1297 if ( bUnprotected )
1298 nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, false );
1299 pNextRows[nCol] = nNextRow;
1301 SCsROW nMinRow = MAXROW+1;
1302 for (i=0; i<=MAXCOL; i++)
1303 if (pNextRows[i] < nMinRow) // bei gleichen den linken
1305 nMinRow = pNextRows[i];
1306 nCol = i;
1308 nRow = nMinRow;
1310 if ( nRow > MAXROW )
1312 if (++nWrap >= 2) break; // ungueltigen Wert behalten
1313 nCol = 0;
1314 nRow = 0;
1315 for (i=0; i<=MAXCOL; i++)
1316 pNextRows[i] = 0; // alles ganz von vorne
1319 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1321 else // rueckwaerts
1323 for (i=0; i<=MAXCOL; i++)
1324 pNextRows[i] = (i>nCol) ? (nRow-1) : nRow;
1327 SCsROW nNextRow = pNextRows[nCol] - 1;
1328 if ( bMarked )
1329 nNextRow = rMark.GetNextMarked( nCol, nNextRow, true );
1330 if ( bUnprotected )
1331 nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, true );
1332 pNextRows[nCol] = nNextRow;
1334 SCsROW nMaxRow = -1;
1335 for (i=0; i<=MAXCOL; i++)
1336 if (pNextRows[i] >= nMaxRow) // bei gleichen den rechten
1338 nMaxRow = pNextRows[i];
1339 nCol = i;
1341 nRow = nMaxRow;
1343 if ( nRow < 0 )
1345 if (++nWrap >= 2) break; // ungueltigen Wert behalten
1346 nCol = MAXCOL;
1347 nRow = MAXROW;
1348 for (i=0; i<=MAXCOL; i++)
1349 pNextRows[i] = MAXROW; // alles ganz von vorne
1352 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1355 delete[] pNextRows;
1359 // ungueltige Werte kommen z.b. bei Tab heraus,
1360 // wenn nicht markiert und nicht geschuetzt ist (linker / rechter Rand),
1361 // dann Werte unveraendert lassen
1363 if (ValidColRow(nCol,nRow))
1365 rCol = nCol;
1366 rRow = nRow;
1370 bool ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark ) const
1372 const ScMarkArray* pMarkArray = rMark.GetArray();
1373 OSL_ENSURE(pMarkArray,"GetNextMarkedCell without MarkArray");
1374 if ( !pMarkArray )
1375 return false;
1377 ++rRow; // naechste Zelle ist gesucht
1379 while ( rCol <= MAXCOL )
1381 const ScMarkArray& rArray = pMarkArray[rCol];
1382 while ( rRow <= MAXROW )
1384 SCROW nStart = (SCROW) rArray.GetNextMarked( (SCsROW) rRow, false );
1385 if ( nStart <= MAXROW )
1387 SCROW nEnd = rArray.GetMarkEnd( nStart, false );
1388 ScColumnIterator aColIter( &aCol[rCol], nStart, nEnd );
1389 SCROW nCellRow;
1390 ScBaseCell* pCell = NULL;
1391 while ( aColIter.Next( nCellRow, pCell ) )
1393 if (pCell)
1395 rRow = nCellRow;
1396 return true; // Zelle gefunden
1399 rRow = nEnd + 1; // naechsten markierten Bereich suchen
1401 else
1402 rRow = MAXROW + 1; // Ende der Spalte
1404 rRow = 0;
1405 ++rCol; // naechste Spalte testen
1408 return false; // alle Spalten durch
1411 void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1412 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
1413 SCsCOL nDx, SCsROW nDy, SCsTAB nDz, bool bUpdateNoteCaptionPos )
1415 if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // only within the table
1417 InitializeNoteCaptions();
1418 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
1419 if ( eUpdateRefMode != URM_COPY && pDrawLayer )
1421 if ( eUpdateRefMode == URM_MOVE )
1422 { // source range
1423 nCol1 = sal::static_int_cast<SCCOL>( nCol1 - nDx );
1424 nRow1 = sal::static_int_cast<SCROW>( nRow1 - nDy );
1425 nCol2 = sal::static_int_cast<SCCOL>( nCol2 - nDx );
1426 nRow2 = sal::static_int_cast<SCROW>( nRow2 - nDy );
1428 pDrawLayer->MoveArea( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy,
1429 (eUpdateRefMode == URM_INSDEL), bUpdateNoteCaptionPos );
1434 void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1435 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
1436 ScDocument* pUndoDoc, bool bIncludeDraw, bool bUpdateNoteCaptionPos )
1438 bool bUpdated = false;
1439 SCCOL i;
1440 SCCOL iMax;
1441 if ( eUpdateRefMode == URM_COPY )
1443 i = nCol1;
1444 iMax = nCol2;
1446 else
1448 i = 0;
1449 iMax = MAXCOL;
1452 // Named expressions need to be updated before formulas acessing them.
1453 if (mpRangeName)
1455 ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );;
1456 mpRangeName->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, true );
1459 for ( ; i<=iMax; i++)
1460 bUpdated |= aCol[i].UpdateReference(
1461 eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, pUndoDoc );
1463 if ( bIncludeDraw )
1464 UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
1466 if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // print ranges: only within the table
1468 SCTAB nSTab = nTab;
1469 SCTAB nETab = nTab;
1470 SCCOL nSCol = 0;
1471 SCROW nSRow = 0;
1472 SCCOL nECol = 0;
1473 SCROW nERow = 0;
1474 bool bRecalcPages = false;
1476 for ( ScRangeVec::iterator aIt = aPrintRanges.begin(), aEnd = aPrintRanges.end(); aIt != aEnd; ++aIt )
1478 nSCol = aIt->aStart.Col();
1479 nSRow = aIt->aStart.Row();
1480 nECol = aIt->aEnd.Col();
1481 nERow = aIt->aEnd.Row();
1483 // do not try to modify sheet index of print range
1484 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1485 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1486 nDx,nDy,0,
1487 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1489 *aIt = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1490 bRecalcPages = true;
1494 if ( pRepeatColRange )
1496 nSCol = pRepeatColRange->aStart.Col();
1497 nSRow = pRepeatColRange->aStart.Row();
1498 nECol = pRepeatColRange->aEnd.Col();
1499 nERow = pRepeatColRange->aEnd.Row();
1501 // do not try to modify sheet index of repeat range
1502 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1503 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1504 nDx,nDy,0,
1505 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1507 *pRepeatColRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1508 bRecalcPages = true;
1509 nRepeatStartX = nSCol; // fuer UpdatePageBreaks
1510 nRepeatEndX = nECol;
1514 if ( pRepeatRowRange )
1516 nSCol = pRepeatRowRange->aStart.Col();
1517 nSRow = pRepeatRowRange->aStart.Row();
1518 nECol = pRepeatRowRange->aEnd.Col();
1519 nERow = pRepeatRowRange->aEnd.Row();
1521 // do not try to modify sheet index of repeat range
1522 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1523 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1524 nDx,nDy,0,
1525 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1527 *pRepeatRowRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1528 bRecalcPages = true;
1529 nRepeatStartY = nSRow; // fuer UpdatePageBreaks
1530 nRepeatEndY = nERow;
1534 // updating print ranges is not necessary with multiple print ranges
1535 if ( bRecalcPages && GetPrintRangeCount() <= 1 )
1537 UpdatePageBreaks(NULL);
1539 pDocument->RepaintRange( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab) );
1543 if (bUpdated && IsStreamValid())
1544 SetStreamValid(false);
1546 if(mpCondFormatList)
1547 mpCondFormatList->UpdateReference( eUpdateRefMode, ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2), nDx, nDy, nDz);
1550 void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
1551 ScDocument* pUndoDoc )
1553 for ( SCCOL i=0; i<=MAXCOL; i++ )
1554 aCol[i].UpdateTranspose( rSource, rDest, pUndoDoc );
1557 void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
1559 for ( SCCOL i=0; i<=MAXCOL; i++ )
1560 aCol[i].UpdateGrow( rArea, nGrowX, nGrowY );
1563 void ScTable::UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets)
1565 if (nTab >= nTable)
1567 nTab += nNewSheets;
1568 if (pDBDataNoName)
1569 pDBDataNoName->UpdateMoveTab(nTab - 1 ,nTab);
1571 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTab(nTable, nNewSheets);
1573 if (mpRangeName)
1574 mpRangeName->UpdateTabRef( nTable, 1, 0, nNewSheets);
1576 if (mpRangeName)
1577 mpRangeName->UpdateTabRef( nTable, 1);
1579 if (IsStreamValid())
1580 SetStreamValid(false);
1582 if(mpCondFormatList)
1583 mpCondFormatList->UpdateReference( URM_INSDEL, ScRange(0,0, nTable, MAXCOL, MAXROW, nTable+nNewSheets-1),0,0, nNewSheets);
1586 void ScTable::UpdateDeleteTab( SCTAB nTable, bool bIsMove, ScTable* pRefUndo, SCTAB nSheets )
1588 if (nTab > nTable)
1590 nTab -= nSheets;
1591 if (pDBDataNoName)
1592 pDBDataNoName->UpdateMoveTab(nTab + 1,nTab);
1595 SCCOL i;
1596 if (pRefUndo)
1597 for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, &pRefUndo->aCol[i], nSheets);
1598 else
1599 for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, NULL, nSheets);
1601 if (mpRangeName)
1603 for (SCTAB aTab = 0; aTab < nSheets; ++aTab)
1605 mpRangeName->UpdateTabRef( nTable + aTab, 2 );
1609 if (mpRangeName)
1611 mpRangeName->UpdateTabRef( nTable, 2 );
1614 if (IsStreamValid())
1615 SetStreamValid(false);
1617 if(mpCondFormatList)
1618 mpCondFormatList->UpdateReference( URM_INSDEL, ScRange(0,0, nTable, MAXCOL, MAXROW, nTable+nSheets-1),0,0, -1*nSheets);
1621 void ScTable::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo,
1622 ScProgress* pProgress )
1624 nTab = nTabNo;
1625 for ( SCCOL i=0; i <= MAXCOL; i++ )
1627 aCol[i].UpdateMoveTab( nOldPos, nNewPos, nTabNo );
1628 if (pProgress)
1629 pProgress->SetState(pProgress->GetState() + aCol[i].GetCodeCount());
1632 if (mpRangeName)
1633 mpRangeName->UpdateTabRef(nOldPos, 3, nNewPos);
1635 if (IsStreamValid())
1636 SetStreamValid(false);
1637 if (pDBDataNoName)
1638 pDBDataNoName->UpdateMoveTab(nOldPos, nNewPos);
1640 if(mpCondFormatList)
1641 mpCondFormatList->UpdateMoveTab(nOldPos, nNewPos);
1644 void ScTable::UpdateCompile( bool bForceIfNameInUse )
1646 for (SCCOL i=0; i <= MAXCOL; i++)
1648 aCol[i].UpdateCompile( bForceIfNameInUse );
1652 void ScTable::SetTabNo(SCTAB nNewTab)
1654 nTab = nNewTab;
1655 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].SetTabNo(nNewTab);
1658 void ScTable::FindRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1659 std::set<sal_uInt16>& rIndexes) const
1661 for (SCCOL i = nCol1; i <= nCol2 && ValidCol(i); i++)
1662 aCol[i].FindRangeNamesInUse(nRow1, nRow2, rIndexes);
1665 void ScTable::ExtendPrintArea( OutputDevice* pDev,
1666 SCCOL /* nStartCol */, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
1668 if ( !pColFlags || !pRowFlags )
1670 OSL_FAIL("ExtendPrintArea: No ColInfo or RowInfo");
1671 return;
1674 Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
1675 double nPPTX = aPix1000.X() / 1000.0;
1676 double nPPTY = aPix1000.Y() / 1000.0;
1678 // First, mark those columns that we need to skip i.e. hidden and empty columns.
1680 ScFlatBoolColSegments aSkipCols;
1681 aSkipCols.setFalse(0, MAXCOL);
1682 for (SCCOL i = 0; i <= MAXCOL; ++i)
1684 SCCOL nLastCol = i;
1685 if (ColHidden(i, NULL, &nLastCol))
1687 // Columns are hidden in this range.
1688 aSkipCols.setTrue(i, nLastCol);
1690 else
1692 // These columns are visible. Check for empty columns.
1693 for (SCCOL j = i; j <= nLastCol; ++j)
1695 if (aCol[j].GetCellCount() == 0)
1696 // empty
1697 aSkipCols.setTrue(j,j);
1700 i = nLastCol;
1703 ScFlatBoolColSegments::RangeData aColData;
1704 for (SCCOL nCol = rEndCol; nCol >= 0; --nCol)
1706 if (!aSkipCols.getRangeData(nCol, aColData))
1707 // Failed to get the data. This should never happen!
1708 return;
1710 if (aColData.mbValue)
1712 // Skip these columns.
1713 nCol = aColData.mnCol1; // move toward 0.
1714 continue;
1717 // These are visible and non-empty columns.
1718 for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= aColData.mnCol1; --nDataCol)
1720 SCCOL nPrintCol = nDataCol;
1721 VisibleDataCellIterator aIter(*mpHiddenRows, aCol[nDataCol]);
1722 ScBaseCell* pCell = aIter.reset(nStartRow);
1723 if (!pCell)
1724 // No visible cells found in this column. Skip it.
1725 continue;
1727 while (pCell)
1729 SCCOL nNewCol = nDataCol;
1730 SCROW nRow = aIter.getRow();
1731 if (nRow > nEndRow)
1732 // Went past the last row position. Bail out.
1733 break;
1735 MaybeAddExtraColumn(nNewCol, nRow, pDev, nPPTX, nPPTY);
1736 if (nNewCol > nPrintCol)
1737 nPrintCol = nNewCol;
1738 pCell = aIter.next();
1741 if (nPrintCol > rEndCol)
1742 // Make sure we don't shrink the print area.
1743 rEndCol = nPrintCol;
1745 nCol = aColData.mnCol1; // move toward 0.
1749 void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY)
1751 ScBaseCell* pCell = aCol[rCol].GetCell(nRow);
1752 if (!pCell || !pCell->HasStringData())
1753 return;
1755 bool bFormula = false; //! ueberge
1756 long nPixel = aCol[rCol].GetTextWidth(nRow);
1758 // Breite bereits im Idle-Handler berechnet?
1759 if ( TEXTWIDTH_DIRTY == nPixel )
1761 ScNeededSizeOptions aOptions;
1762 aOptions.bTotalSize = true;
1763 aOptions.bFormula = bFormula;
1764 aOptions.bSkipMerged = false;
1766 Fraction aZoom(1,1);
1767 nPixel = aCol[rCol].GetNeededSize(
1768 nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions );
1770 aCol[rCol].SetTextWidth(nRow, static_cast<sal_uInt16>(nPixel));
1773 long nTwips = (long) (nPixel / nPPTX);
1774 long nDocW = GetColWidth( rCol );
1776 long nMissing = nTwips - nDocW;
1777 if ( nMissing > 0 )
1779 // look at alignment
1781 const ScPatternAttr* pPattern = GetPattern( rCol, nRow );
1782 const SfxItemSet* pCondSet = pDocument->GetCondResult( rCol, nRow, nTab );
1784 SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
1785 pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
1786 if ( eHorJust == SVX_HOR_JUSTIFY_CENTER )
1787 nMissing /= 2; // distributed into both directions
1788 else
1790 // STANDARD is LEFT (only text is handled here)
1791 bool bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT );
1792 if ( IsLayoutRTL() )
1793 bRight = !bRight;
1794 if ( bRight )
1795 nMissing = 0; // extended only to the left (logical)
1799 SCCOL nNewCol = rCol;
1800 while (nMissing > 0 && nNewCol < MAXCOL)
1802 ScBaseCell* pNextCell = aCol[nNewCol+1].GetCell(nRow);
1803 if (pNextCell)
1804 // Cell content in a next column ends display of this string.
1805 nMissing = 0;
1806 else
1807 nMissing -= GetColWidth(++nNewCol);
1809 rCol = nNewCol;
1812 namespace {
1814 class SetTableIndex : public ::std::unary_function<ScRange, void>
1816 SCTAB mnTab;
1817 public:
1818 SetTableIndex(SCTAB nTab) : mnTab(nTab) {}
1820 void operator() (ScRange& rRange) const
1822 rRange.aStart.SetTab(mnTab);
1823 rRange.aEnd.SetTab(mnTab);
1827 void setPrintRange(ScRange*& pRange1, const ScRange* pRange2)
1829 if (pRange2)
1831 if (pRange1)
1832 *pRange1 = *pRange2;
1833 else
1834 pRange1 = new ScRange(*pRange2);
1836 else
1837 DELETEZ(pRange1);
1842 void ScTable::CopyPrintRange(const ScTable& rTable)
1844 // The table index shouldn't be used when the print range is used, but
1845 // just in case set the correct table index.
1847 aPrintRanges = rTable.aPrintRanges;
1848 ::std::for_each(aPrintRanges.begin(), aPrintRanges.end(), SetTableIndex(nTab));
1850 bPrintEntireSheet = rTable.bPrintEntireSheet;
1852 delete pRepeatColRange;
1853 pRepeatColRange = NULL;
1854 if (rTable.pRepeatColRange)
1856 pRepeatColRange = new ScRange(*rTable.pRepeatColRange);
1857 pRepeatColRange->aStart.SetTab(nTab);
1858 pRepeatColRange->aEnd.SetTab(nTab);
1861 delete pRepeatRowRange;
1862 pRepeatRowRange = NULL;
1863 if (rTable.pRepeatRowRange)
1865 pRepeatRowRange = new ScRange(*rTable.pRepeatRowRange);
1866 pRepeatRowRange->aStart.SetTab(nTab);
1867 pRepeatRowRange->aEnd.SetTab(nTab);
1871 void ScTable::DoColResize( SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd )
1873 for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
1874 aCol[nCol].ReserveSize(aCol[nCol].GetCellCount() + nAdd);
1877 void ScTable::SetRepeatColRange( const ScRange* pNew )
1879 setPrintRange( pRepeatColRange, pNew );
1881 if (IsStreamValid())
1882 SetStreamValid(false);
1884 InvalidatePageBreaks();
1887 void ScTable::SetRepeatRowRange( const ScRange* pNew )
1889 setPrintRange( pRepeatRowRange, pNew );
1891 if (IsStreamValid())
1892 SetStreamValid(false);
1894 InvalidatePageBreaks();
1897 void ScTable::ClearPrintRanges()
1899 aPrintRanges.clear();
1900 bPrintEntireSheet = false;
1902 if (IsStreamValid())
1903 SetStreamValid(false);
1905 InvalidatePageBreaks(); // #i117952# forget page breaks for an old print range
1908 void ScTable::AddPrintRange( const ScRange& rNew )
1910 bPrintEntireSheet = false;
1911 if( aPrintRanges.size() < 0xFFFF )
1912 aPrintRanges.push_back( rNew );
1914 if (IsStreamValid())
1915 SetStreamValid(false);
1917 InvalidatePageBreaks();
1921 void ScTable::SetPrintEntireSheet()
1923 if( !IsPrintEntireSheet() )
1925 ClearPrintRanges();
1926 bPrintEntireSheet = true;
1930 const ScRange* ScTable::GetPrintRange(sal_uInt16 nPos) const
1932 return (nPos < GetPrintRangeCount()) ? &aPrintRanges[ nPos ] : NULL;
1935 void ScTable::FillPrintSaver( ScPrintSaverTab& rSaveTab ) const
1937 rSaveTab.SetAreas( aPrintRanges, bPrintEntireSheet );
1938 rSaveTab.SetRepeat( pRepeatColRange, pRepeatRowRange );
1941 void ScTable::RestorePrintRanges( const ScPrintSaverTab& rSaveTab )
1943 aPrintRanges = rSaveTab.GetPrintRanges();
1944 bPrintEntireSheet = rSaveTab.IsEntireSheet();
1945 SetRepeatColRange( rSaveTab.GetRepeatCol() );
1946 SetRepeatRowRange( rSaveTab.GetRepeatRow() );
1948 InvalidatePageBreaks(); // #i117952# forget page breaks for an old print range
1949 UpdatePageBreaks(NULL);
1952 SCROW ScTable::VisibleDataCellIterator::ROW_NOT_FOUND = -1;
1954 ScTable::VisibleDataCellIterator::VisibleDataCellIterator(ScFlatBoolRowSegments& rRowSegs, ScColumn& rColumn) :
1955 mrRowSegs(rRowSegs),
1956 mrColumn(rColumn),
1957 mpCell(NULL),
1958 mnCurRow(ROW_NOT_FOUND),
1959 mnUBound(ROW_NOT_FOUND)
1963 ScTable::VisibleDataCellIterator::~VisibleDataCellIterator()
1967 ScBaseCell* ScTable::VisibleDataCellIterator::reset(SCROW nRow)
1969 if (nRow > MAXROW)
1971 mnCurRow = ROW_NOT_FOUND;
1972 return NULL;
1975 ScFlatBoolRowSegments::RangeData aData;
1976 if (!mrRowSegs.getRangeData(nRow, aData))
1978 mnCurRow = ROW_NOT_FOUND;
1979 return NULL;
1982 if (!aData.mbValue)
1984 // specified row is visible. Take it.
1985 mnCurRow = nRow;
1986 mnUBound = aData.mnRow2;
1988 else
1990 // specified row is not-visible. The first visible row is the start of
1991 // the next segment.
1992 mnCurRow = aData.mnRow2 + 1;
1993 mnUBound = mnCurRow; // get range data on the next iteration.
1994 if (mnCurRow > MAXROW)
1996 // Make sure the row doesn't exceed our current limit.
1997 mnCurRow = ROW_NOT_FOUND;
1998 return NULL;
2002 mpCell = mrColumn.GetCell(mnCurRow);
2003 if (mpCell)
2004 // First visible cell found.
2005 return mpCell;
2007 // Find a first visible cell below this row (if any).
2008 return next();
2011 ScBaseCell* ScTable::VisibleDataCellIterator::next()
2013 if (mnCurRow == ROW_NOT_FOUND)
2014 return NULL;
2016 while (mrColumn.GetNextDataPos(mnCurRow))
2018 if (mnCurRow > mnUBound)
2020 // We don't know the visibility of this row range. Query it.
2021 ScFlatBoolRowSegments::RangeData aData;
2022 if (!mrRowSegs.getRangeData(mnCurRow, aData))
2024 mnCurRow = ROW_NOT_FOUND;
2025 return NULL;
2028 if (aData.mbValue)
2030 // This row is invisible. Skip to the last invisible row and
2031 // try again.
2032 mnCurRow = mnUBound = aData.mnRow2;
2033 continue;
2036 // This row is visible.
2037 mnUBound = aData.mnRow2;
2040 mpCell = mrColumn.GetCell(mnCurRow);
2041 if (mpCell)
2042 return mpCell;
2044 mnCurRow = ROW_NOT_FOUND;
2045 return NULL;
2048 SCROW ScTable::VisibleDataCellIterator::getRow() const
2050 return mnCurRow;
2053 void ScTable::SetAnonymousDBData(ScDBData* pDBData)
2055 delete pDBDataNoName;
2056 pDBDataNoName = pDBData;
2059 ScDBData* ScTable::GetAnonymousDBData()
2061 return pDBDataNoName;
2064 sal_uLong ScTable::AddCondFormat( ScConditionalFormat* pNew )
2066 if(!mpCondFormatList)
2067 mpCondFormatList.reset(new ScConditionalFormatList());
2069 sal_uLong nMax = 0;
2070 for(ScConditionalFormatList::const_iterator itr = mpCondFormatList->begin();
2071 itr != mpCondFormatList->end(); ++itr)
2073 sal_uLong nKey = itr->GetKey();
2074 if(nKey > nMax)
2075 nMax = nKey;
2078 pNew->SetKey(nMax+1);
2079 mpCondFormatList->InsertNew(pNew);
2081 return nMax + 1;
2084 sal_uInt8 ScTable::GetScriptType( SCCOL nCol, SCROW nRow ) const
2086 if (!ValidCol(nCol))
2087 return 0;
2089 return aCol[nCol].GetScriptType(nRow);
2092 void ScTable::SetScriptType( SCCOL nCol, SCROW nRow, sal_uInt8 nType )
2094 if (!ValidCol(nCol))
2095 return;
2097 aCol[nCol].SetScriptType(nRow, nType);
2100 sal_uInt8 ScTable::GetRangeScriptType(
2101 sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2103 if (!ValidCol(nCol))
2104 return 0;
2106 return aCol[nCol].GetRangeScriptType(rBlockPos.miCellTextAttrPos, nRow1, nRow2);
2109 size_t ScTable::GetFormulaHash( SCCOL nCol, SCROW nRow ) const
2111 if (!ValidCol(nCol))
2112 return 0;
2114 return aCol[nCol].GetFormulaHash(nRow);
2117 ScFormulaVectorState ScTable::GetFormulaVectorState( SCCOL nCol, SCROW nRow ) const
2119 if (!ValidCol(nCol))
2120 return FormulaVectorUnknown;
2122 return aCol[nCol].GetFormulaVectorState(nRow);
2125 formula::FormulaTokenRef ScTable::ResolveStaticReference( SCCOL nCol, SCROW nRow )
2127 if (!ValidCol(nCol) || !ValidRow(nRow))
2128 return formula::FormulaTokenRef();
2130 return aCol[nCol].ResolveStaticReference(nRow);
2133 formula::FormulaTokenRef ScTable::ResolveStaticReference( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2135 if (nCol2 < nCol1 || nRow2 < nRow1)
2136 return formula::FormulaTokenRef();
2138 if (!ValidCol(nCol1) || !ValidCol(nCol2) || !ValidRow(nRow1) || !ValidRow(nRow2))
2139 return formula::FormulaTokenRef();
2141 ScMatrixRef pMat(new ScMatrix(nCol2-nCol1+1, nRow2-nRow1+1, 0.0));
2142 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
2144 if (!aCol[nCol].ResolveStaticReference(*pMat, nCol2-nCol1, nRow1, nRow2))
2145 // Column contains non-static cell. Failed.
2146 return formula::FormulaTokenRef();
2149 return formula::FormulaTokenRef(new ScMatrixToken(pMat));
2152 const double* ScTable::FetchDoubleArray(
2153 sc::FormulaGroupContext& rCxt, SCCOL nCol, SCROW nRow1, SCROW nRow2 ) const
2155 if (nRow2 < nRow1)
2156 return NULL;
2158 if (!ValidCol(nCol) || !ValidRow(nRow1) || !ValidRow(nRow2))
2159 return NULL;
2161 return aCol[nCol].FetchDoubleArray(rCxt, nRow1, nRow2);
2164 ScRefCellValue ScTable::GetRefCellValue( SCCOL nCol, SCROW nRow )
2166 if (!ValidColRow(nCol, nRow))
2167 return ScRefCellValue();
2169 return aCol[nCol].GetRefCellValue(nRow);
2172 SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow )
2174 if (!ValidColRow(nCol, nRow))
2175 return NULL;
2177 return aCol[nCol].GetBroadcaster(nRow);
2180 void ScTable::DeleteBroadcasters(
2181 sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2183 if (!ValidCol(nCol))
2184 return;
2186 aCol[nCol].DeleteBroadcasters(rBlockPos, nRow1, nRow2);
2189 bool ScTable::HasBroadcaster( SCCOL nCol ) const
2191 if (!ValidCol(nCol))
2192 return false;
2194 return aCol[nCol].HasBroadcaster();
2197 const SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow ) const
2199 if (!ValidColRow(nCol, nRow))
2200 return NULL;
2202 return aCol[nCol].GetBroadcaster(nRow);
2205 void ScTable::DeleteConditionalFormat( sal_uLong nIndex )
2207 mpCondFormatList->erase(nIndex);
2210 void ScTable::SetCondFormList( ScConditionalFormatList* pNew )
2212 mpCondFormatList.reset( pNew );
2215 ScConditionalFormatList* ScTable::GetCondFormList()
2217 if(!mpCondFormatList)
2218 mpCondFormatList.reset( new ScConditionalFormatList() );
2220 return mpCondFormatList.get();
2223 const ScConditionalFormatList* ScTable::GetCondFormList() const
2225 return mpCondFormatList.get();
2228 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */