LibreOffice Module sc (master) 1
table1.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <scitems.hxx>
22#include <o3tl/safeint.hxx>
26#include <osl/diagnose.h>
27
28#include <patattr.hxx>
29#include <table.hxx>
30#include <document.hxx>
31#include <drwlayer.hxx>
32#include <olinetab.hxx>
33#include <global.hxx>
34#include <globstr.hrc>
35#include <scresid.hxx>
36#include <refupdat.hxx>
37#include <markdata.hxx>
38#include <progress.hxx>
39#include <prnsave.hxx>
40#include <printopt.hxx>
41#include <scmod.hxx>
42#include <tabprotection.hxx>
43#include <sheetevents.hxx>
44#include <segmenttree.hxx>
45#include <dbdata.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>
52#include <compressedarray.hxx>
53#include <vcl/svapp.hxx>
54
56#include <token.hxx>
57
58#include <vector>
59#include <memory>
60
61using ::std::vector;
62
63namespace {
64
65ScProgress* GetProgressBar(
66 SCSIZE nCount, SCSIZE nTotalCount, ScProgress* pOuterProgress, const ScDocument* pDoc)
67{
68 if (nTotalCount < 1000)
69 {
70 // if the total number of rows is less than 1000, don't even bother
71 // with the progress bar because drawing progress bar can be very
72 // expensive especially in GTK.
73 return nullptr;
74 }
75
76 if (pOuterProgress)
77 return pOuterProgress;
78
79 if (nCount > 1)
80 return new ScProgress(
81 pDoc->GetDocumentShell(), ScResId(STR_PROGRESS_HEIGHTING), nTotalCount, true);
82
83 return nullptr;
84}
85
86void GetOptimalHeightsInColumn(
87 sc::RowHeightContext& rCxt, ScColContainer& rCol, SCROW nStartRow, SCROW nEndRow,
88 ScProgress* pProgress, sal_uLong nProgressStart )
89{
90 assert(nStartRow <= nEndRow);
91
92 // first, one time over the whole range
93 // (with the last column in the hope that they most likely still are
94 // on standard format)
95
96
97 rCol.back().GetOptimalHeight(rCxt, nStartRow, nEndRow, 0, 0);
98
99 // from there search for the standard height that is in use in the lower part
100
101 RowHeightsArray& rHeights = rCxt.getHeightArray();
102 sal_uInt16 nMinHeight = rHeights.GetValue(nEndRow);
103 SCSIZE nPos = nEndRow - 1;
104 while ( nPos )
105 {
106 auto aRangeData = rHeights.GetRangeData(nPos-1);
107 if (aRangeData.maValue < nMinHeight)
108 break;
109 nPos = std::max<SCSIZE>(0, aRangeData.mnRow1);
110 }
111
112 const SCROW nMinStart = nPos;
113
114 sal_uInt64 nWeightedCount = nProgressStart + rCol.back().GetWeightedCount(nStartRow, nEndRow);
115 const SCCOL maxCol = rCol.size() - 1; // last col done already above
116 for (SCCOL nCol=0; nCol<maxCol; nCol++)
117 {
118 rCol[nCol].GetOptimalHeight(rCxt, nStartRow, nEndRow, nMinHeight, nMinStart);
119
120 if (pProgress)
121 {
122 nWeightedCount += rCol[nCol].GetWeightedCount(nStartRow, nEndRow);
123 pProgress->SetState( nWeightedCount );
124 }
125 }
126}
127
128struct OptimalHeightsFuncObjBase
129{
130 virtual ~OptimalHeightsFuncObjBase() {}
131 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight, bool bApi) = 0;
132};
133
134struct SetRowHeightOnlyFunc : public OptimalHeightsFuncObjBase
135{
136 ScTable* mpTab;
137 explicit SetRowHeightOnlyFunc(ScTable* pTab) :
138 mpTab(pTab)
139 {}
140
141 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight, bool /* bApi */) override
142 {
143 mpTab->SetRowHeightOnly(nStartRow, nEndRow, nHeight);
144 return false;
145 }
146};
147
148struct SetRowHeightRangeFunc : public OptimalHeightsFuncObjBase
149{
150 ScTable* mpTab;
151 double mnPPTY;
152
153 SetRowHeightRangeFunc(ScTable* pTab, double nPPTY) :
154 mpTab(pTab),
155 mnPPTY(nPPTY)
156 {}
157
158 virtual bool operator() (SCROW nStartRow, SCROW nEndRow, sal_uInt16 nHeight, bool bApi) override
159 {
160 return mpTab->SetRowHeightRange(nStartRow, nEndRow, nHeight, mnPPTY, bApi);
161 }
162};
163
164bool SetOptimalHeightsToRows(
166 OptimalHeightsFuncObjBase& rFuncObj,
167 ScBitMaskCompressedArray<SCROW, CRFlags>* pRowFlags, SCROW nStartRow, SCROW nEndRow,
168 bool bApi )
169{
170 bool bChanged = false;
171 SCROW nRngStart = 0;
172 SCROW nRngEnd = 0;
173 sal_uInt16 nLast = 0;
174 sal_uInt16 nExtraHeight = rCxt.getExtraHeight();
175 for (SCSIZE i = nStartRow; i <= o3tl::make_unsigned(nEndRow); i++)
176 {
177 size_t nIndex;
178 SCROW nRegionEndRow;
179 CRFlags nRowFlag = pRowFlags->GetValue( i, nIndex, nRegionEndRow );
180 if ( nRegionEndRow > nEndRow )
181 nRegionEndRow = nEndRow;
182 SCSIZE nMoreRows = nRegionEndRow - i; // additional equal rows after first
183
184 bool bAutoSize = !(nRowFlag & CRFlags::ManualSize);
185 if (bAutoSize || rCxt.isForceAutoSize())
186 {
187 if (nExtraHeight)
188 {
189 if (bAutoSize)
190 pRowFlags->SetValue( i, nRegionEndRow, nRowFlag | CRFlags::ManualSize);
191 }
192 else if (!bAutoSize)
193 pRowFlags->SetValue( i, nRegionEndRow, nRowFlag & ~CRFlags::ManualSize);
194
195 for (SCSIZE nInner = i; nInner <= i + nMoreRows; ++nInner)
196 {
197 if (nLast)
198 {
199 SCROW nRangeRowEnd;
200 size_t nTmp;
201 sal_uInt16 nRangeValue = rCxt.getHeightArray().GetValue(nInner, nTmp, nRangeRowEnd);
202 if (nRangeValue + nExtraHeight == nLast)
203 {
204 nRngEnd = std::min<SCSIZE>(i + nMoreRows, nRangeRowEnd);
205 nInner = nRangeRowEnd;
206 }
207 else
208 {
209 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast, bApi);
210 nLast = 0;
211 }
212 }
213 if (!nLast)
214 {
215 nLast = rCxt.getHeightArray().GetValue(nInner) + rCxt.getExtraHeight();
216 nRngStart = nInner;
217 nRngEnd = nInner;
218 }
219 }
220 }
221 else
222 {
223 if (nLast)
224 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast, bApi);
225 nLast = 0;
226 }
227 i += nMoreRows; // already handled - skip
228 }
229 if (nLast)
230 bChanged |= rFuncObj(nRngStart, nRngEnd, nLast, bApi);
231
232 return bChanged;
233}
234
235}
236
237ScTable::ScTable( ScDocument& rDoc, SCTAB nNewTab, const OUString& rNewName,
238 bool bColInfo, bool bRowInfo ) :
239 aCol( rDoc.GetSheetLimits(), INITIALCOLCOUNT ),
240 aName( rNewName ),
241 aCodeName( rNewName ),
242 nLinkRefreshDelay( 0 ),
243 nLinkMode( ScLinkMode::NONE ),
244 aPageStyle( ScResId(STR_STYLENAME_STANDARD) ),
245 nRepeatStartX( SCCOL_REPEAT_NONE ),
246 nRepeatEndX( SCCOL_REPEAT_NONE ),
247 nRepeatStartY( SCROW_REPEAT_NONE ),
248 nRepeatEndY( SCROW_REPEAT_NONE ),
249 mbCellAreaDirty( true ),
250 mbCellAreaEmpty( true ),
251 mnEndCol( -1 ),
252 mnEndRow( -1 ),
253 mnOptimalMinRowHeight(0),
254 mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(nullptr) ),
255 mpHiddenCols(new ScFlatBoolColSegments(rDoc.MaxCol())),
256 mpHiddenRows(new ScFlatBoolRowSegments(rDoc.MaxRow())),
257 mpFilteredCols(new ScFlatBoolColSegments(rDoc.MaxCol())),
258 mpFilteredRows(new ScFlatBoolRowSegments(rDoc.MaxRow())),
259 nTableAreaX( 0 ),
260 nTableAreaY( 0 ),
261 nTableAreaVisibleX( 0 ),
262 nTableAreaVisibleY( 0 ),
263 nTab( nNewTab ),
264 rDocument( rDoc ),
265 pSortCollator( nullptr ),
266 nLockCount( 0 ),
267 aScenarioColor( COL_LIGHTGRAY ),
268 aTabBgColor( COL_AUTO ),
269 nScenarioFlags(ScScenarioFlags::NONE),
270 mpCondFormatList( new ScConditionalFormatList() ),
271 maLOKFreezeCell(-1, -1, nNewTab),
272 bScenario(false),
273 bLayoutRTL(false),
274 bLoadingRTL(false),
275 bPageSizeValid(false),
276 bTableAreaValid(false),
277 bTableAreaVisibleValid(false),
278 bVisible(true),
279 bPendingRowHeights(false),
280 bCalcNotification(false),
281 bGlobalKeepQuery(false),
282 bPrintEntireSheet(true),
283 bActiveScenario(false),
284 mbPageBreaksValid(false),
285 mbForceBreaks(false),
286 bStreamValid(false)
287{
288 aDefaultColData.InitAttrArray(new ScAttrArray(static_cast<SCCOL>(-1), nNewTab, rDoc, nullptr));
289 if (bColInfo)
290 {
293 }
294
295 if (bRowInfo)
296 {
299 }
300
301 if ( rDocument.IsDocVisible() )
302 {
303 // when a sheet is added to a visible document,
304 // initialize its RTL flag from the system locale
306 }
307
308 ScDrawLayer* pDrawLayer = rDocument.GetDrawLayer();
309 if (pDrawLayer)
310 {
311 if ( pDrawLayer->ScAddPage( nTab ) ) // sal_False (not inserted) during Undo
312 {
313 pDrawLayer->ScRenamePage( nTab, aName );
317 pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( nx, ny ), false );
318 }
319 }
320
321 for (SCCOL k=0; k < aCol.size(); k++)
322 aCol[k].Init( k, nTab, rDocument, true );
323}
324
325ScTable::~ScTable() COVERITY_NOEXCEPT_FALSE
326{
328 {
329 for (SCCOL nCol = 0; nCol < aCol.size(); ++nCol)
330 {
331 aCol[nCol].FreeNotes();
332 }
333 // In the dtor, don't delete the pages in the wrong order.
334 // (or else nTab does not reflect the page number!)
335 // In ScDocument::Clear is afterwards used from Clear at the Draw Layer to delete everything.
336
337 ScDrawLayer* pDrawLayer = rDocument.GetDrawLayer();
338 if (pDrawLayer)
339 pDrawLayer->ScRemovePage( nTab );
340 }
341
342 pRowFlags.reset();
343 pSheetEvents.reset();
344 pOutlineTable.reset();
345 pSearchText.reset();
346 moRepeatColRange.reset();
347 moRepeatRowRange.reset();
348 pScenarioRanges.reset();
349 mpRangeName.reset();
350 pDBDataNoName.reset();
352}
353
354sal_Int64 ScTable::GetHashCode() const
355{
356 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
357}
358
359void ScTable::SetName( const OUString& rNewName )
360{
361 aName = rNewName;
362 aUpperName.clear(); // invalidated if the name is changed
363
364 // SetStreamValid is handled in ScDocument::RenameTab
365}
366
367const OUString& ScTable::GetUpperName() const
368{
369 if (aUpperName.isEmpty() && !aName.isEmpty())
371 return aUpperName;
372}
373
374void ScTable::SetVisible( bool bVis )
375{
376 if (bVisible != bVis)
377 SetStreamValid(false);
378
379 bVisible = bVis;
380}
381
382void ScTable::SetStreamValid( bool bSet, bool bIgnoreLock )
383{
384 if (!bStreamValid && !bSet)
385 return; // shortcut
386 if ( bIgnoreLock || !rDocument.IsStreamValidLocked() )
387 bStreamValid = bSet;
388}
389
391{
392 bPendingRowHeights = bSet;
393}
394
395void ScTable::SetLayoutRTL( bool bSet )
396{
397 bLayoutRTL = bSet;
398}
399
400void ScTable::SetLoadingRTL( bool bSet )
401{
402 bLoadingRTL = bSet;
403}
404
405void ScTable::SetTabBgColor(const Color& rColor)
406{
407 if (aTabBgColor != rColor)
408 {
409 // The tab color has changed. Set this table 'modified'.
410 aTabBgColor = rColor;
411 SetStreamValid(false);
412 }
413}
414
415void ScTable::SetScenario( bool bFlag )
416{
417 bScenario = bFlag;
418}
419
421 const OUString& rDoc, const OUString& rFlt, const OUString& rOpt,
422 const OUString& rTab, sal_uLong nRefreshDelay )
423{
424 nLinkMode = nMode;
425 aLinkDoc = rDoc; // File
426 aLinkFlt = rFlt; // Filter
427 aLinkOpt = rOpt; // Filter options
428 aLinkTab = rTab; // Sheet name in source file
429 nLinkRefreshDelay = nRefreshDelay; // refresh delay in seconds, 0==off
430
431 SetStreamValid(false);
432}
433
435 double nPPTX, double nPPTY,
436 const Fraction& rZoomX, const Fraction& rZoomY,
437 bool bFormula, const ScMarkData* pMarkData,
438 const ScColWidthParam* pParam )
439{
440 if ( nCol >= aCol.size() )
441 return ( STD_COL_WIDTH - STD_EXTRA_WIDTH );
442
443 return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
444 bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, pParam );
445}
446
448 OutputDevice* pDev,
449 double nPPTX, double nPPTY,
450 const Fraction& rZoomX, const Fraction& rZoomY,
451 bool bWidth, bool bTotalSize, bool bInPrintTwips )
452{
453 if ( nCol >= aCol.size() )
454 return 0;
455
456 ScNeededSizeOptions aOptions;
457 aOptions.bSkipMerged = false; // count merged cells
458 aOptions.bTotalSize = bTotalSize;
459
460 return aCol[nCol].GetNeededSize
461 ( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, aOptions, nullptr, bInPrintTwips );
462}
463
465 sc::RowHeightContext& rCxt, SCROW nStartRow, SCROW nEndRow, bool bApi,
466 ScProgress* pOuterProgress, sal_uInt64 nProgressStart )
467{
468 assert(nStartRow <= nEndRow);
469
470 OSL_ENSURE( rCxt.getExtraHeight() == 0 || rCxt.isForceAutoSize(),
471 "automatic OptimalHeight with Extra" );
472
474 {
475 return false;
476 }
477
478 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
479
480 ScProgress* pProgress = GetProgressBar(nCount, GetWeightedCount(), pOuterProgress, &rDocument);
481
482 mpRowHeights->enableTreeSearch(false);
483
484 GetOptimalHeightsInColumn(rCxt, aCol, nStartRow, nEndRow, pProgress, nProgressStart);
485
486 SetRowHeightRangeFunc aFunc(this, rCxt.getPPTY());
487 bool bChanged = SetOptimalHeightsToRows(rCxt, aFunc, pRowFlags.get(), nStartRow, nEndRow, bApi);
488
489 if ( pProgress != pOuterProgress )
490 delete pProgress;
491
492 mpRowHeights->enableTreeSearch(true);
493
494 return bChanged;
495}
496
498 sc::RowHeightContext& rCxt, SCROW nStartRow, SCROW nEndRow,
499 ScProgress* pOuterProgress, sal_uInt64 nProgressStart )
500{
501 OSL_ENSURE( rCxt.getExtraHeight() == 0 || rCxt.isForceAutoSize(),
502 "automatic OptimalHeight with Extra" );
503
505 return;
506
507 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
508
509 ScProgress* pProgress = GetProgressBar(nCount, GetWeightedCount(), pOuterProgress, &rDocument);
510
511 GetOptimalHeightsInColumn(rCxt, aCol, nStartRow, nEndRow, pProgress, nProgressStart);
512
513 SetRowHeightOnlyFunc aFunc(this);
514
515 SetOptimalHeightsToRows(rCxt, aFunc, pRowFlags.get(), nStartRow, nEndRow, true);
516
517 if ( pProgress != pOuterProgress )
518 delete pProgress;
519}
520
521bool ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow )
522{
523 if (!mbCellAreaDirty)
524 {
525 rEndCol = mnEndCol;
526 rEndRow = mnEndRow;
527 return !mbCellAreaEmpty;
528 }
529
530 bool bFound = false;
531 SCCOL nMaxX = 0;
532 SCROW nMaxY = 0;
533 for (SCCOL i=0; i<aCol.size(); i++)
534 {
535 if (!aCol[i].IsEmptyData())
536 {
537 bFound = true;
538 nMaxX = i;
539 SCROW nRow = aCol[i].GetLastDataPos();
540 if (nRow > nMaxY)
541 nMaxY = nRow;
542 }
543 if ( aCol[i].HasCellNotes() )
544 {
545 SCROW maxNoteRow = aCol[i].GetCellNotesMaxRow();
546 if (maxNoteRow >= nMaxY)
547 {
548 bFound = true;
549 nMaxY = maxNoteRow;
550 }
551 if (i>nMaxX)
552 {
553 bFound = true;
554 nMaxX = i;
555 }
556 }
557 if (aCol[i].HasSparklines())
558 {
559 SCROW maxSparklineRow = aCol[i].GetSparklinesMaxRow();
560 if (maxSparklineRow >= nMaxY)
561 {
562 bFound = true;
563 nMaxY = maxSparklineRow;
564 }
565 if (i > nMaxX)
566 {
567 bFound = true;
568 nMaxX = i;
569 }
570 }
571 }
572
573 mnEndCol = rEndCol = nMaxX;
574 mnEndRow = rEndRow = nMaxY;
575 mbCellAreaEmpty = !bFound;
576 mbCellAreaDirty = false;
577 return bFound;
578}
579
580bool ScTable::GetTableArea( SCCOL& rEndCol, SCROW& rEndRow, bool bCalcHiddens) const
581{
582 bool bRet = true; //TODO: remember?
583 if (bCalcHiddens)
584 {
585 if (!bTableAreaValid)
586 {
587 bRet = GetPrintArea(nTableAreaX, nTableAreaY, true, bCalcHiddens);
588 bTableAreaValid = true;
589 }
590 rEndCol = nTableAreaX;
591 rEndRow = nTableAreaY;
592 }
593 else
594 {
596 {
597 bRet = GetPrintArea(nTableAreaVisibleX, nTableAreaVisibleY, true, bCalcHiddens);
599 }
600 rEndCol = nTableAreaVisibleX;
601 rEndRow = nTableAreaVisibleY;
602 }
603 return bRet;
604}
605
607
608bool ScTable::GetPrintArea( SCCOL& rEndCol, SCROW& rEndRow, bool bNotes, bool bCalcHiddens ) const
609{
610 bool bFound = false;
611 SCCOL nMaxX = 0;
612 SCROW nMaxY = 0;
613 SCCOL i;
614
615 bool bSkipEmpty = SC_MOD()->GetPrintOptions().GetSkipEmpty();
616
617 for (i=0; i<aCol.size(); i++) // Test data
618 {
619 if (bCalcHiddens || !rDocument.ColHidden(i, nTab))
620 {
621 if (!aCol[i].IsEmptyData())
622 {
623 bFound = true;
624 if (i>nMaxX)
625 nMaxX = i;
626 SCROW nColY = aCol[i].GetLastDataPos();
627 if (nColY > nMaxY)
628 nMaxY = nColY;
629 }
630 if (bNotes && aCol[i].HasCellNotes() )
631 {
632 SCROW maxNoteRow = aCol[i].GetCellNotesMaxRow();
633 if (maxNoteRow >= nMaxY)
634 {
635 bFound = true;
636 nMaxY = maxNoteRow;
637 }
638 if (i>nMaxX)
639 {
640 bFound = true;
641 nMaxX = i;
642 }
643 }
644 if (aCol[i].HasSparklines())
645 {
646 SCROW maxSparklineRow = aCol[i].GetSparklinesMaxRow();
647 if (maxSparklineRow >= nMaxY)
648 {
649 bFound = true;
650 nMaxY = maxSparklineRow;
651 }
652 if (i > nMaxX)
653 {
654 bFound = true;
655 nMaxX = i;
656 }
657 }
658 }
659 }
660
661 SCCOL nMaxDataX = nMaxX;
662
663 for (i=0; i<aCol.size(); i++) // Test attribute
664 {
665 if (bCalcHiddens || !rDocument.ColHidden(i, nTab))
666 {
667 SCROW nLastRow;
668 if (aCol[i].GetLastVisibleAttr( nLastRow, bSkipEmpty ))
669 {
670 bFound = true;
671 nMaxX = i;
672 if (nLastRow > nMaxY)
673 nMaxY = nLastRow;
674 }
675 }
676 }
677
678 if (nMaxX == rDocument.MaxCol()) // omit attribute at the right
679 {
680 --nMaxX;
681 while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1], 0, rDocument.MaxRow()) )
682 --nMaxX;
683 }
684
685 if ( nMaxX < nMaxDataX )
686 {
687 nMaxX = nMaxDataX;
688 }
689 else if ( nMaxX > nMaxDataX )
690 {
691 SCCOL nAttrStartX = nMaxDataX + 1;
692 while ( nAttrStartX < (aCol.size()-1) )
693 {
694 SCCOL nAttrEndX = nAttrStartX;
695 while ( nAttrEndX < (aCol.size()-1) && aCol[nAttrStartX].IsVisibleAttrEqual(aCol[nAttrEndX+1], 0, rDocument.MaxRow()) )
696 ++nAttrEndX;
697 if ( nAttrEndX + 1 - nAttrStartX >= SC_COLUMNS_STOP )
698 {
699 // found equally-formatted columns behind data -> stop before these columns
700 nMaxX = nAttrStartX - 1;
701
702 // also don't include default-formatted columns before that
703 SCROW nDummyRow;
704 while ( nMaxX > nMaxDataX && !aCol[nMaxX].GetLastVisibleAttr( nDummyRow, bSkipEmpty ) )
705 --nMaxX;
706 break;
707 }
708 nAttrStartX = nAttrEndX + 1;
709 }
710 }
711
712 rEndCol = nMaxX;
713 rEndRow = nMaxY;
714 return bFound;
715}
716
717bool ScTable::GetPrintAreaHor( SCROW nStartRow, SCROW nEndRow,
718 SCCOL& rEndCol ) const
719{
720 bool bFound = false;
721 SCCOL nMaxX = 0;
722 SCCOL i;
723
724 for (i=0; i<aCol.size(); i++) // Test attribute
725 {
726 if (aCol[i].HasVisibleAttrIn( nStartRow, nEndRow ))
727 {
728 bFound = true;
729 nMaxX = i;
730 }
731 }
732
733 if (nMaxX == rDocument.MaxCol()) // omit attribute at the right
734 {
735 --nMaxX;
736 while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1], nStartRow, nEndRow) )
737 --nMaxX;
738 }
739
740 for (i=0; i<aCol.size(); i++) // test the data
741 {
742 if (!aCol[i].IsEmptyData( nStartRow, nEndRow )) //TODO: bNotes ??????
743 {
744 bFound = true;
745 if (i > nMaxX)
746 nMaxX = i;
747 }
748 else if (aCol[i].HasSparklines())
749 {
750 if (i > nMaxX)
751 {
752 bFound = true;
753 nMaxX = i;
754 }
755 }
756 }
757
758 rEndCol = nMaxX;
759 return bFound;
760}
761
762bool ScTable::GetPrintAreaVer( SCCOL nStartCol, SCCOL nEndCol,
763 SCROW& rEndRow, bool bNotes ) const
764{
765 bool bFound = false;
766 SCROW nMaxY = 0;
767 SCCOL i;
768
769 bool bSkipEmpty = SC_MOD()->GetPrintOptions().GetSkipEmpty();
770
771 for (i=nStartCol; i<=nEndCol && i < aCol.size(); i++) // Test attribute
772 {
773 SCROW nLastRow;
774 if (aCol[i].GetLastVisibleAttr( nLastRow, bSkipEmpty ))
775 {
776 bFound = true;
777 if (nLastRow > nMaxY)
778 nMaxY = nLastRow;
779 }
780 }
781
782 for (i=nStartCol; i<=nEndCol && i < aCol.size(); i++) // Test data
783 {
784 if (!aCol[i].IsEmptyData())
785 {
786 bFound = true;
787 SCROW nColY = aCol[i].GetLastDataPos();
788 if (nColY > nMaxY)
789 nMaxY = nColY;
790 }
791 if (bNotes && aCol[i].HasCellNotes() )
792 {
793 SCROW maxNoteRow =aCol[i].GetCellNotesMaxRow();
794 if (maxNoteRow > nMaxY)
795 {
796 bFound = true;
797 nMaxY = maxNoteRow;
798 }
799 }
800 if (aCol[i].HasSparklines())
801 {
802 SCROW maxNoteRow = aCol[i].GetSparklinesMaxRow();
803 if (maxNoteRow > nMaxY)
804 {
805 bFound = true;
806 nMaxY = maxNoteRow;
807 }
808 }
809 }
810
811 rEndRow = nMaxY;
812 return bFound;
813}
814
815bool ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const
816{
817 bool bFound = false;
818 SCCOL nMinX = aCol.size()-1;
819 SCROW nMinY = rDocument.MaxRow();
820 SCCOL i;
821
822 for (i=0; i<aCol.size(); i++) // Test attribute
823 {
824 SCROW nFirstRow;
825 if (aCol[i].GetFirstVisibleAttr( nFirstRow ))
826 {
827 if (!bFound)
828 nMinX = i;
829 bFound = true;
830 if (nFirstRow < nMinY)
831 nMinY = nFirstRow;
832 }
833 }
834
835 if (nMinX == 0) // omit attribute at the right
836 {
837 if ( aCol.size() > 1 && aCol[0].IsVisibleAttrEqual(aCol[1], 0, rDocument.MaxRow())) // no single ones
838 {
839 ++nMinX;
840 while ( nMinX<(aCol.size()-1) && aCol[nMinX].IsVisibleAttrEqual(aCol[nMinX-1], 0, rDocument.MaxRow()))
841 ++nMinX;
842 }
843 }
844
845 bool bDatFound = false;
846 for (i=0; i<aCol.size(); i++) // Test data
847 {
848 if (!aCol[i].IsEmptyData())
849 {
850 if (!bDatFound && i<nMinX)
851 nMinX = i;
852 bFound = bDatFound = true;
853 SCROW nRow = aCol[i].GetFirstDataPos();
854 if (nRow < nMinY)
855 nMinY = nRow;
856 }
857 if ( aCol[i].HasCellNotes() )
858 {
859 SCROW minNoteRow = aCol[i].GetCellNotesMinRow();
860 if (minNoteRow <= nMinY)
861 {
862 bFound = true;
863 nMinY = minNoteRow;
864 }
865 if (i<nMinX)
866 {
867 bFound = true;
868 nMinX = i;
869 }
870 }
871 if (aCol[i].HasSparklines())
872 {
873 SCROW minSparkline = aCol[i].GetSparklinesMinRow();
874 if (minSparkline <= nMinY)
875 {
876 bFound = true;
877 nMinY = minSparkline;
878 }
879 if (i < nMinX)
880 {
881 bFound = true;
882 nMinX = i;
883 }
884 }
885 }
886 rStartCol = nMinX;
887 rStartRow = nMinY;
888 return bFound;
889}
890
891void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
892 bool bIncludeOld, bool bOnlyDown ) const
893{
894 // return the smallest area containing at least all contiguous cells having data. This area
895 // is a square containing also empty cells. It may shrink or extend the area given as input
896 // Flags as modifiers:
897 //
898 // bIncludeOld = true ensure that the returned area contains at least the initial area,
899 // independently of the emptiness of rows / columns (i.e. does not allow shrinking)
900 // bOnlyDown = true means extend / shrink the inputted area only down, i.e modify only rEndRow
901
902 rStartCol = std::min<SCCOL>( rStartCol, aCol.size()-1 );
903 rEndCol = std::min<SCCOL>( rEndCol, aCol.size()-1 );
904
905 bool bLeft = false;
906 bool bRight = false;
907 bool bTop = false;
908 bool bBottom = false;
909 bool bChanged = false;
910
911 // We need to cache sc::ColumnBlockConstPosition per each column.
912 std::vector< sc::ColumnBlockConstPosition > blockPos( rEndCol + 1 );
913 for( SCCOL i = 0; i <= rEndCol; ++i )
914 aCol[ i ].InitBlockPosition( blockPos[ i ] );
915
916 do
917 {
918 bChanged = false;
919
920 if (!bOnlyDown)
921 {
922 SCROW nStart = rStartRow;
923 SCROW nEnd = rEndRow;
924 if (nStart>0) --nStart;
925 if (nEnd<rDocument.MaxRow()) ++nEnd;
926
927 if (rEndCol < (aCol.size()-1))
928 if (!aCol[rEndCol+1].IsEmptyData(nStart,nEnd))
929 {
930 assert( int( blockPos.size()) == rEndCol + 1 );
931 ++rEndCol;
932 blockPos.resize( blockPos.size() + 1 );
933 aCol[ rEndCol ].InitBlockPosition( blockPos[ rEndCol ] );
934 bChanged = true;
935 bRight = true;
936 }
937
938 if (rStartCol > 0)
939 if (!aCol[rStartCol-1].IsEmptyData(nStart,nEnd))
940 {
941 --rStartCol;
942 bChanged = true;
943 bLeft = true;
944 }
945
946 if (rStartRow > 0)
947 {
948 SCROW nTest = rStartRow-1;
949 bool needExtend = false;
950 for ( SCCOL i = rStartCol; i<=rEndCol && !needExtend; i++)
951 if (aCol[i].HasDataAt(blockPos[i], nTest))
952 needExtend = true;
953 if (needExtend)
954 {
955 --rStartRow;
956 bChanged = true;
957 bTop = true;
958 }
959 }
960 }
961
962 if (rEndRow < rDocument.MaxRow())
963 {
964 SCROW nTest = rEndRow+1;
965 bool needExtend = false;
966 for ( SCCOL i = rStartCol; i<=rEndCol && !needExtend; i++)
967 if (aCol[i].HasDataAt(blockPos[ i ], nTest))
968 needExtend = true;
969 if (needExtend)
970 {
971 ++rEndRow;
972 bChanged = true;
973 bBottom = true;
974 }
975 }
976 }
977 while( bChanged );
978
979 if ( !bIncludeOld && !bOnlyDown )
980 {
981 if ( !bLeft )
982 while ( rStartCol < rEndCol && rStartCol < (aCol.size()-1) && aCol[rStartCol].IsEmptyData(rStartRow,rEndRow) )
983 ++rStartCol;
984
985 if ( !bRight )
986 while ( rEndCol > 0 && rStartCol < rEndCol && aCol[rEndCol].IsEmptyData(rStartRow,rEndRow) )
987 --rEndCol;
988
989 if ( !bTop && rStartRow < rDocument.MaxRow() && rStartRow < rEndRow )
990 {
991 bool bShrink = true;
992 do
993 {
994 for ( SCCOL i = rStartCol; i<=rEndCol && bShrink; i++)
995 if (aCol[i].HasDataAt(rStartRow))
996 bShrink = false;
997 if (bShrink)
998 ++rStartRow;
999 } while (bShrink && rStartRow < rDocument.MaxRow() && rStartRow < rEndRow);
1000 }
1001 }
1002
1003 if ( !bIncludeOld )
1004 {
1005 if ( !bBottom && rEndRow > 0 && rStartRow < rEndRow )
1006 {
1007 SCROW nLastDataRow = GetLastDataRow( rStartCol, rEndCol, rEndRow);
1008 if (nLastDataRow < rEndRow)
1009 rEndRow = std::max( rStartRow, nLastDataRow);
1010 }
1011 }
1012}
1013
1015{
1016 SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col();
1017
1018 if ( nCol1 >= aCol.size() )
1019 return false;
1020
1021 nCol2 = std::min<SCCOL>( nCol2, aCol.size()-1 );
1022
1023 SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row();
1024
1025 SCCOL nFirstNonEmptyCol = -1, nLastNonEmptyCol = -1;
1026 SCROW nRowStart = nRow2, nRowEnd = nRow1;
1027
1028 for ( SCCOL nCol = nCol1; nCol <= nCol2; ++nCol )
1029 {
1030 SCROW nRowStartThis = nRow1, nRowEndThis = nRow2;
1031 bool bTrimmed = aCol[nCol].TrimEmptyBlocks(nRowStartThis, nRowEndThis);
1032 if ( bTrimmed )
1033 {
1034 if ( nFirstNonEmptyCol == -1 )
1035 nFirstNonEmptyCol = nCol;
1036 nLastNonEmptyCol = nCol;
1037
1038 nRowStart = std::min<SCROW>(nRowStart, nRowStartThis);
1039 nRowEnd = std::max<SCROW>(nRowEnd, nRowEndThis);
1040 }
1041 }
1042
1043 if ( nFirstNonEmptyCol == -1 )
1044 return false;
1045
1046 assert(nFirstNonEmptyCol <= nLastNonEmptyCol);
1047 assert(nRowStart <= nRowEnd);
1048
1049 rRange.aStart.Set(nFirstNonEmptyCol, nRowStart, rRange.aStart.Tab());
1050 rRange.aEnd.Set(nLastNonEmptyCol, nRowEnd, rRange.aEnd.Tab());
1051
1052 return true;
1053}
1054
1055bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
1056 SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly, bool bStickyTopRow, bool bStickyLeftCol,
1057 ScDataAreaExtras* pDataAreaExtras ) const
1058{
1059 rStartCol = std::min<SCCOL>( rStartCol, aCol.size()-1 );
1060 // check for rEndCol is done below.
1061
1062 o_bShrunk = false;
1063
1064 PutInOrder( rStartCol, rEndCol);
1065 PutInOrder( rStartRow, rEndRow);
1066 if (rStartCol < 0)
1067 {
1068 rStartCol = 0;
1069 o_bShrunk = true;
1070 }
1071 if (rStartRow < 0)
1072 {
1073 rStartRow = 0;
1074 o_bShrunk = true;
1075 }
1076 if (rEndCol >= aCol.size())
1077 {
1078 rEndCol = aCol.size()-1;
1079 o_bShrunk = true;
1080 }
1081 if (rEndRow > rDocument.MaxRow())
1082 {
1083 rEndRow = rDocument.MaxRow();
1084 o_bShrunk = true;
1085 }
1086
1087 while (rStartCol < rEndCol)
1088 {
1089 if (aCol[rEndCol].IsEmptyData( rStartRow, rEndRow))
1090 {
1091 if (pDataAreaExtras && pDataAreaExtras->mnEndCol < rEndCol)
1092 {
1093 // Check in order of likeliness.
1094 if ( (pDataAreaExtras->mbCellFormats
1095 && aCol[rEndCol].GetPatternCount( rStartRow, rEndRow) > 1
1096 && aCol[rEndCol].HasVisibleAttrIn( rStartRow, rEndRow)) ||
1097 (pDataAreaExtras->mbCellNotes
1098 && !aCol[rEndCol].IsNotesEmptyBlock( rStartRow, rEndRow)) ||
1099 (pDataAreaExtras->mbCellDrawObjects
1100 && !aCol[rEndCol].IsDrawObjectsEmptyBlock( rStartRow, rEndRow)))
1101 pDataAreaExtras->mnEndCol = rEndCol;
1102 }
1103
1104 --rEndCol;
1105 o_bShrunk = true;
1106 }
1107 else
1108 break; // while
1109 }
1110
1111 if (!bStickyLeftCol)
1112 {
1113 while (rStartCol < rEndCol)
1114 {
1115 if (aCol[rStartCol].IsEmptyData( rStartRow, rEndRow))
1116 {
1117 if (pDataAreaExtras && pDataAreaExtras->mnStartCol > rStartCol)
1118 {
1119 // Check in order of likeliness.
1120 if ( (pDataAreaExtras->mbCellFormats
1121 && aCol[rStartCol].GetPatternCount( rStartRow, rEndRow) > 1
1122 && aCol[rStartCol].HasVisibleAttrIn( rStartRow, rEndRow)) ||
1123 (pDataAreaExtras->mbCellNotes
1124 && !aCol[rStartCol].IsNotesEmptyBlock( rStartRow, rEndRow)) ||
1125 (pDataAreaExtras->mbCellDrawObjects
1126 && !aCol[rStartCol].IsDrawObjectsEmptyBlock( rStartRow, rEndRow)))
1127 pDataAreaExtras->mnStartCol = rStartCol;
1128 }
1129
1130 ++rStartCol;
1131 o_bShrunk = true;
1132 }
1133 else
1134 break; // while
1135 }
1136 }
1137
1138 if (!bColumnsOnly)
1139 {
1140 while (rStartRow < rEndRow)
1141 {
1142 SCROW nLastDataRow = GetLastDataRow(rStartCol, rEndCol, rEndRow, pDataAreaExtras);
1143 if (0 <= nLastDataRow && nLastDataRow < rEndRow)
1144 {
1145 rEndRow = std::max( rStartRow, nLastDataRow);
1146 o_bShrunk = true;
1147 }
1148 else
1149 break; // while
1150 }
1151
1152 if (!bStickyTopRow)
1153 {
1154 while (rStartRow < rEndRow)
1155 {
1156 bool bFound = false;
1157 for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
1158 {
1159 if (aCol[i].HasDataAt(rStartRow, pDataAreaExtras))
1160 bFound = true;
1161 }
1162 if (!bFound)
1163 {
1164 ++rStartRow;
1165 o_bShrunk = true;
1166 }
1167 else
1168 break; // while
1169 }
1170 }
1171 }
1172
1173 return rStartCol != rEndCol || (bColumnsOnly ?
1174 !aCol[rStartCol].IsEmptyData( rStartRow, rEndRow) :
1175 (rStartRow != rEndRow ||
1176 aCol[rStartCol].HasDataAt( rStartRow, pDataAreaExtras)));
1177}
1178
1179SCROW ScTable::GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow, ScDataAreaExtras* pDataAreaExtras ) const
1180{
1181 if ( !IsColValid( nCol1 ) || !ValidCol( nCol2 ) )
1182 return -1;
1183
1184 nCol2 = std::min<SCCOL>( nCol2, aCol.size() - 1 );
1185
1186 SCROW nNewLastRow = 0;
1187 for (SCCOL i = nCol1; i <= nCol2; ++i)
1188 {
1189 SCROW nThis = aCol[i].GetLastDataPos(nLastRow, pDataAreaExtras);
1190 if (nNewLastRow < nThis)
1191 nNewLastRow = nThis;
1192 }
1193
1194 return nNewLastRow;
1195}
1196
1197bool ScTable::IsEmptyData( SCCOL nStartCol, SCROW nStartRow,
1198 SCCOL nEndCol, SCROW nEndRow ) const
1199{
1200 for( SCCOL col : GetAllocatedColumnsRange( nStartCol, nEndCol ))
1201 if( !aCol[col].IsEmptyData( nStartRow, nEndRow ))
1202 return false;
1203 return true;
1204}
1205
1207 SCCOL nEndCol, SCROW nEndRow, ScDirection eDir ) const
1208{
1209 SCCOL nStartColOrig = nStartCol;
1210 SCCOL nEndColOrig = nEndCol;
1211 nStartCol = std::min<SCCOL>( nStartCol, aCol.size()-1 );
1212 nEndCol = std::min<SCCOL>( nEndCol, aCol.size()-1 );
1213
1214 // The region is not allocated and does not contain any data.
1215 if ( nStartColOrig != nStartCol )
1216 return ( ((eDir == DIR_BOTTOM) || (eDir == DIR_TOP)) ?
1217 static_cast<SCSIZE>(nEndRow - nStartRow + 1) :
1218 static_cast<SCSIZE>(nEndColOrig - nStartColOrig + 1) );
1219
1220 SCSIZE nGapRight = static_cast<SCSIZE>(nEndColOrig - nEndCol);
1221 SCSIZE nCount = 0;
1222 SCCOL nCol;
1223 if ((eDir == DIR_BOTTOM) || (eDir == DIR_TOP))
1224 {
1225 nCount = static_cast<SCSIZE>(nEndRow - nStartRow + 1);
1226 for (nCol = nStartCol; nCol <= nEndCol; nCol++)
1227 nCount = std::min(nCount, aCol[nCol].GetEmptyLinesInBlock(nStartRow, nEndRow, eDir));
1228 }
1229 else if (eDir == DIR_RIGHT)
1230 {
1231 nCol = nEndCol;
1232 while ((nCol >= nStartCol) &&
1233 aCol[nCol].IsEmptyData(nStartRow, nEndRow))
1234 {
1235 nCount++;
1236 nCol--;
1237 }
1238 nCount += nGapRight;
1239 }
1240 else
1241 {
1242 nCol = nStartCol;
1243 while ((nCol <= nEndCol) && aCol[nCol].IsEmptyData(nStartRow, nEndRow))
1244 {
1245 nCount++;
1246 nCol++;
1247 }
1248
1249 // If the area between nStartCol and nEndCol are empty,
1250 // add the count of unallocated columns on the right.
1251 if ( nCol > nEndCol )
1252 nCount += nGapRight;
1253 }
1254 return nCount;
1255}
1256
1257bool ScTable::IsEmptyLine( SCROW nRow, SCCOL nStartCol, SCCOL nEndCol ) const
1258{
1259 // The range of columns are unallocated hence empty.
1260 if ( nStartCol >= aCol.size() )
1261 return true;
1262
1263 nEndCol = std::min<SCCOL>( nEndCol, aCol.size()-1 );
1264
1265 for (SCCOL i=nStartCol; i<=nEndCol; i++)
1266 if (aCol[i].HasDataAt(nRow))
1267 return false;
1268 return true;
1269}
1270
1271void ScTable::LimitChartArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow ) const
1272{
1273 rStartCol = std::min<SCCOL>( rStartCol, aCol.size()-1 );
1274 rEndCol = std::min<SCCOL>( rEndCol, aCol.size()-1 );
1275
1276 while ( rStartCol<rEndCol && aCol[rStartCol].IsEmptyData(rStartRow,rEndRow) )
1277 ++rStartCol;
1278
1279 while ( rStartCol<rEndCol && aCol[rEndCol].IsEmptyData(rStartRow,rEndRow) )
1280 --rEndCol;
1281
1282 while ( rStartRow<rEndRow && IsEmptyLine(rStartRow, rStartCol, rEndCol) )
1283 ++rStartRow;
1284
1285 // Optimised loop for finding the bottom of the area, can be costly in large
1286 // spreadsheets.
1287 SCROW lastDataPos = 0;
1288 for (SCCOL i=rStartCol; i<=rEndCol; i++)
1289 lastDataPos = std::max(lastDataPos, aCol[i].GetLastDataPos());
1290 // reduce EndRow to the last row with data
1291 rEndRow = std::min(rEndRow, lastDataPos);
1292 // but make sure EndRow is >= StartRow
1293 rEndRow = std::max(rStartRow, rEndRow);
1294}
1295
1296SCCOL ScTable::FindNextVisibleCol( SCCOL nCol, bool bRight ) const
1297{
1298 if(bRight)
1299 {
1300 nCol++;
1301 SCCOL nEnd = 0;
1302 bool bHidden = rDocument.ColHidden(nCol, nTab, nullptr, &nEnd);
1303 if(bHidden)
1304 nCol = nEnd +1;
1305
1306 return std::min<SCCOL>(rDocument.MaxCol(), nCol);
1307 }
1308 else
1309 {
1310 nCol--;
1311 SCCOL nStart = rDocument.MaxCol();
1312 bool bHidden = rDocument.ColHidden(nCol, nTab, &nStart);
1313 if(bHidden)
1314 nCol = nStart - 1;
1315
1316 return std::max<SCCOL>(0, nCol);
1317 }
1318}
1319
1321{
1322 const SCCOL nLastCol = aCol.size() - 1;
1323 if(bRight)
1324 {
1325 // If nCol is the last allocated column index, there won't be any content to its right.
1326 // To maintain the original return behaviour, return rDocument.MaxCol().
1327 if(nCol >= nLastCol)
1328 return rDocument.MaxCol();
1329
1330 do
1331 {
1332 nCol++;
1333 SCCOL nEndCol = 0;
1334 bool bHidden = rDocument.ColHidden( nCol, nTab, nullptr, &nEndCol );
1335 if(bHidden)
1336 {
1337 nCol = nEndCol +1;
1338 // Can end search early as there is no data after nLastCol.
1339 // For nCol == nLastCol, it may still have data so don't want to return rDocument.MaxCol().
1340 if(nCol > nLastCol)
1341 return rDocument.MaxCol();
1342 }
1343
1344 if(aCol[nCol].HasVisibleDataAt(nRow))
1345 return nCol;
1346 }
1347 while(nCol < nLastCol); // Stop search as soon as the last allocated column is searched.
1348
1349 return rDocument.MaxCol();
1350 }
1351 else
1352 {
1353 if(nCol == 0)
1354 return 0;
1355
1356 // If nCol is in the unallocated range [nLastCol+1, rDocument.MaxCol()], then move it directly after nLastCol
1357 // as there is no data in the unallocated range. This also makes the search faster and avoids
1358 // the need for more range checks in the loop below.
1359 if ( nCol > nLastCol )
1360 nCol = nLastCol + 1;
1361
1362 do
1363 {
1364 nCol--;
1365 SCCOL nStartCol = rDocument.MaxCol();
1366 bool bHidden = rDocument.ColHidden( nCol, nTab, &nStartCol );
1367 if(bHidden)
1368 {
1369 nCol = nStartCol -1;
1370 if(nCol <= 0)
1371 return 0;
1372 }
1373
1374 if(aCol[nCol].HasVisibleDataAt(nRow))
1375 return nCol;
1376 }
1377 while(nCol > 0);
1378
1379 return 0;
1380 }
1381}
1382
1383void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, ScMoveDirection eDirection ) const
1384{
1385 const SCCOL nLastCol = aCol.size() - 1;
1386
1387 if (eDirection == SC_MOVE_LEFT || eDirection == SC_MOVE_RIGHT)
1388 {
1389 SCCOL nNewCol = rCol;
1390 bool bThere = ( nNewCol <= nLastCol ) && aCol[nNewCol].HasVisibleDataAt(rRow);
1391 bool bRight = (eDirection == SC_MOVE_RIGHT);
1392 if (bThere)
1393 {
1394 if(nNewCol >= rDocument.MaxCol() && eDirection == SC_MOVE_RIGHT)
1395 return;
1396 else if(nNewCol == 0 && eDirection == SC_MOVE_LEFT)
1397 return;
1398
1399 SCCOL nNextCol = FindNextVisibleCol( nNewCol, bRight );
1400
1401 if( nNextCol <= nLastCol && aCol[nNextCol].HasVisibleDataAt(rRow) )
1402 {
1403 bool bFound = false;
1404 nNewCol = nNextCol;
1405 do
1406 {
1407 nNextCol = FindNextVisibleCol( nNewCol, bRight );
1408 if( nNextCol <= nLastCol && aCol[nNextCol].HasVisibleDataAt(rRow) )
1409 nNewCol = nNextCol;
1410 else
1411 bFound = true;
1412 }
1413 while(!bFound && nNextCol > 0 && nNextCol < rDocument.MaxCol());
1414 }
1415 else
1416 {
1417 nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
1418 }
1419 }
1420 else
1421 {
1422 nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
1423 }
1424
1425 if (nNewCol<0)
1426 nNewCol=0;
1427 if (nNewCol>rDocument.MaxCol())
1428 nNewCol=rDocument.MaxCol();
1429 rCol = nNewCol;
1430 }
1431 else
1432 {
1433 if ( rCol <= nLastCol )
1434 aCol[rCol].FindDataAreaPos(rRow,eDirection == SC_MOVE_DOWN);
1435 else
1436 {
1437 // The cell (rCol, rRow) is equivalent to an empty cell (although not allocated).
1438 // Set rRow to 0 or rDocument.MaxRow() depending on eDirection to maintain the behaviour of
1439 // ScColumn::FindDataAreaPos() when the given column is empty.
1440 rRow = ( eDirection == SC_MOVE_DOWN ) ? rDocument.MaxRow() : 0;
1441 }
1442 }
1443}
1444
1445bool ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
1446 bool bMarked, bool bUnprotected ) const
1447{
1448 if (!ValidCol(nCol) || !ValidRow(nRow))
1449 return false;
1450
1451 if (rDocument.HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HasAttrFlags::Overlapped))
1452 // Skip an overlapped cell.
1453 return false;
1454
1455 if (bMarked && !rMark.IsCellMarked(nCol,nRow))
1456 return false;
1457
1458 /* TODO: for cursor movement *only* this should even take the protection
1459 * options (select locked, select unlocked) into account, see
1460 * ScTabView::SkipCursorHorizontal() and ScTabView::SkipCursorVertical(). */
1461 if (bUnprotected && rDocument.HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HasAttrFlags::Protected))
1462 return false;
1463
1464 if (bMarked || bUnprotected) //TODO: also in other case ???
1465 {
1466 // Hidden cells must be skipped, as the cursor would end up on the next cell
1467 // even if it is protected or not marked.
1468 //TODO: control per Extra-Parameter, only for Cursor movement ???
1469
1470 if (RowHidden(nRow))
1471 return false;
1472
1473 if (ColHidden(nCol))
1474 return false;
1475 }
1476
1477 return true;
1478}
1479
1480// Skips the current cell if it is Hidden, Overlapped or Protected and Sheet is Protected
1481bool ScTable::SkipRow( const SCCOL nCol, SCROW& rRow, const SCROW nMovY,
1482 const ScMarkData& rMark, const bool bUp, const SCROW nUsedY,
1483 const bool bMarked, const bool bSheetProtected ) const
1484{
1485 if ( !ValidRow( rRow ))
1486 return false;
1487
1488 if (bSheetProtected && rDocument.HasAttrib( nCol, rRow, nTab, nCol, rRow, nTab, HasAttrFlags::Protected))
1489 {
1490 if ( rRow > nUsedY )
1491 rRow = (bUp ? nUsedY : rDocument.MaxRow() + nMovY);
1492 else
1493 rRow += nMovY;
1494
1495 if (bMarked)
1496 rRow = rMark.GetNextMarked( nCol, rRow, bUp );
1497
1498 return true;
1499 }
1500 else
1501 {
1502 bool bRowHidden = RowHidden( rRow );
1503 bool bOverlapped = rDocument.HasAttrib( nCol, rRow, nTab, nCol, rRow, nTab, HasAttrFlags::Overlapped );
1504
1505 if ( bRowHidden || bOverlapped )
1506 {
1507 rRow += nMovY;
1508 if (bMarked)
1509 rRow = rMark.GetNextMarked( nCol, rRow, bUp );
1510
1511 return true;
1512 }
1513 }
1514
1515 return false;
1516}
1517
1518void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCCOL nMovX, SCROW nMovY,
1519 bool bMarked, bool bUnprotected, const ScMarkData& rMark, SCCOL nTabStartCol ) const
1520{
1521 // Ensure bMarked is set only if there is a mark.
1522 assert( !bMarked || rMark.IsMarked() || rMark.IsMultiMarked());
1523
1524 const bool bSheetProtected = IsProtected();
1525
1526 if ( bUnprotected && !bSheetProtected ) // Is sheet really protected?
1527 bUnprotected = false;
1528
1529 SCCOL nCol = rCol + nMovX;
1530 SCROW nRow = rRow + nMovY;
1531
1532 SCCOL nStartCol, nEndCol;
1533 SCROW nStartRow, nEndRow;
1534 if (bMarked)
1535 {
1537 if (rMark.IsMarked())
1538 aRange = rMark.GetMarkArea();
1539 else if (rMark.IsMultiMarked())
1540 aRange = rMark.GetMultiMarkArea();
1541 else
1542 {
1543 // Covered by assert() above, but for NDEBUG build.
1544 if (ValidColRow(nCol,nRow))
1545 {
1546 rCol = nCol;
1547 rRow = nRow;
1548 }
1549 return;
1550 }
1551 nStartCol = aRange.aStart.Col();
1552 nStartRow = aRange.aStart.Row();
1553 nEndCol = aRange.aEnd.Col();
1554 nEndRow = aRange.aEnd.Row();
1555 }
1556 else if (bUnprotected)
1557 {
1558 nStartCol = 0;
1559 nStartRow = 0;
1560 nEndCol = rCol;
1561 nEndRow = rRow;
1562 rDocument.GetPrintArea( nTab, nEndCol, nEndRow, true );
1563 // Add some cols/rows to the print area (which is "content or
1564 // visually different from empty") to enable travelling through
1565 // protected forms with empty cells and no visual indicator.
1566 // 42 might be good enough and not too much...
1567 nEndCol = std::min<SCCOL>( nEndCol+42, rDocument.MaxCol());
1568 nEndRow = std::min<SCROW>( nEndRow+42, rDocument.MaxRow());
1569 }
1570 else
1571 {
1572 // Invalid values show up for instance for Tab, when nothing is
1573 // selected and not protected (left / right edge), then leave values
1574 // unchanged.
1575 if (ValidColRow(nCol,nRow))
1576 {
1577 rCol = nCol;
1578 rRow = nRow;
1579 }
1580
1581 // Caller ensures actually moving nMovY to jump to prev/next row's
1582 // start col.
1583 if (nTabStartCol != SC_TABSTART_NONE)
1584 rCol = nTabStartCol;
1585
1586 return;
1587 }
1588
1589 if ( nMovY && (bMarked || bUnprotected))
1590 {
1591 do
1592 {
1593 const bool bUp = (nMovY < 0);
1594 const SCCOL nColAdd = (bUp ? -1 : 1);
1595
1596 if (bMarked)
1597 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1598
1599 if (nTabStartCol != SC_TABSTART_NONE)
1600 {
1601 /* NOTE: If current rCol < nTabStartCol when going down, there
1602 * is no way to detect if the previous Tab wrapped around to
1603 * the next row or if it was a Shift+Tab going backwards. The
1604 * result after a wrap is an odd jump to the next row's
1605 * nTabStartCol, which is logical though and always has been
1606 * the case. Similar for rCol > nTabStartCol when going up.
1607 * Related, it would be nice to limit advancing the position
1608 * within bounds even if another wrap would occur, but again we
1609 * can't tell if previously Tab or Shift+Tab was used, so we
1610 * don't know if it would be nTabStartCol to nEndCol (for Tab)
1611 * or nStartCol to nTabStartCol (for Shift+Tab). */
1612
1613 // Continue moving horizontally.
1614 nMovX = nColAdd;
1615 nCol = nTabStartCol;
1616 break; // do
1617 }
1618
1619 while ( SkipRow( nCol, nRow, nMovY, rMark, bUp, nEndRow, bMarked, bSheetProtected ))
1620 ;
1621
1622 sal_uInt16 nWrap = 0;
1623 while ( nRow < nStartRow || nRow > nEndRow )
1624 {
1625 nCol += nColAdd;
1626
1627 while (nStartCol <= nCol && nCol <= nEndCol && ValidCol(nCol) && ColHidden(nCol))
1628 nCol += nColAdd; // skip hidden cols
1629
1630 if (nCol < nStartCol)
1631 {
1632 nCol = nEndCol;
1633
1634 if (++nWrap >= 2)
1635 return;
1636 }
1637 else if (nCol > nEndCol)
1638 {
1639 nCol = nStartCol;
1640
1641 if (++nWrap >= 2)
1642 return;
1643 }
1644 if (nRow < nStartRow)
1645 nRow = nEndRow;
1646 else if (nRow > nEndRow)
1647 nRow = nStartRow;
1648
1649 if (bMarked)
1650 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1651
1652 while ( SkipRow( nCol, nRow, nMovY, rMark, bUp, nEndRow, bMarked, bSheetProtected ))
1653 ;
1654 }
1655 } while (false);
1656 }
1657
1658 if ( nMovX && ( bMarked || bUnprotected ) )
1659 {
1660 // wrap initial skip counting:
1661 if (nCol < nStartCol)
1662 {
1663 nCol = nEndCol;
1664 --nRow;
1665 if (nRow < nStartRow)
1666 nRow = nEndRow;
1667 }
1668 if (nCol > nEndCol)
1669 {
1670 nCol = nStartCol;
1671 ++nRow;
1672 if (nRow > nEndRow)
1673 nRow = nStartRow;
1674 }
1675
1676 if ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) )
1677 {
1678 const SCCOL nColCount = nEndCol - nStartCol + 1;
1679 std::unique_ptr<SCROW[]> pNextRows( new SCROW[nColCount]);
1680 const SCCOL nLastCol = aCol.size() - 1;
1681 const bool bUp = (nMovX < 0); // Moving left also means moving up in rows.
1682 const SCROW nRowAdd = (bUp ? -1 : 1);
1683 sal_uInt16 nWrap = 0;
1684
1685 if (bUp)
1686 {
1687 for (SCCOL i = 0; i < nColCount; ++i)
1688 pNextRows[i] = (i + nStartCol > nCol) ? (nRow + nRowAdd) : nRow;
1689 }
1690 else
1691 {
1692 for (SCCOL i = 0; i < nColCount; ++i)
1693 pNextRows[i] = (i + nStartCol < nCol) ? (nRow + nRowAdd) : nRow;
1694 }
1695 do
1696 {
1697 SCROW nNextRow = pNextRows[nCol - nStartCol] + nRowAdd;
1698 if ( bMarked )
1699 nNextRow = rMark.GetNextMarked( nCol, nNextRow, bUp );
1700 if ( bUnprotected )
1701 nNextRow = ( nCol <= nLastCol ) ? aCol[nCol].GetNextUnprotected( nNextRow, bUp ) :
1702 aDefaultColData.GetNextUnprotected( nNextRow, bUp );
1703 pNextRows[nCol - nStartCol] = nNextRow;
1704
1705 if (bUp)
1706 {
1707 SCROW nMaxRow = nStartRow - 1;
1708 for (SCCOL i = 0; i < nColCount; ++i)
1709 {
1710 if (pNextRows[i] >= nMaxRow) // when two equal the right one
1711 {
1712 nMaxRow = pNextRows[i];
1713 nCol = i + nStartCol;
1714 }
1715 }
1716 nRow = nMaxRow;
1717
1718 if ( nRow < nStartRow )
1719 {
1720 if (++nWrap >= 2)
1721 return;
1722 nCol = nEndCol;
1723 nRow = nEndRow;
1724 for (SCCOL i = 0; i < nColCount; ++i)
1725 pNextRows[i] = nEndRow; // do it all over again
1726 }
1727 }
1728 else
1729 {
1730 SCROW nMinRow = nEndRow + 1;
1731 for (SCCOL i = 0; i < nColCount; ++i)
1732 {
1733 if (pNextRows[i] < nMinRow) // when two equal the left one
1734 {
1735 nMinRow = pNextRows[i];
1736 nCol = i + nStartCol;
1737 }
1738 }
1739 nRow = nMinRow;
1740
1741 if ( nRow > nEndRow )
1742 {
1743 if (++nWrap >= 2)
1744 return;
1745 nCol = nStartCol;
1746 nRow = nStartRow;
1747 for (SCCOL i = 0; i < nColCount; ++i)
1748 pNextRows[i] = nStartRow; // do it all over again
1749 }
1750 }
1751 }
1752 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1753 }
1754 }
1755
1756 if (ValidColRow(nCol,nRow))
1757 {
1758 rCol = nCol;
1759 rRow = nRow;
1760 }
1761}
1762
1763bool ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark ) const
1764{
1765 ++rRow; // next row
1766
1767 while ( rCol < aCol.size() )
1768 {
1769 ScMarkArray aArray( rMark.GetMarkArray( rCol ) );
1770 while ( rRow <= rDocument.MaxRow() )
1771 {
1772 SCROW nStart = aArray.GetNextMarked( rRow, false );
1773 if ( nStart <= rDocument.MaxRow() )
1774 {
1775 SCROW nEnd = aArray.GetMarkEnd( nStart, false );
1776
1777 const sc::CellStoreType& rCells = aCol[rCol].maCells;
1778 std::pair<sc::CellStoreType::const_iterator,size_t> aPos = rCells.position(nStart);
1779 sc::CellStoreType::const_iterator it = aPos.first;
1780 SCROW nTestRow = nStart;
1781 if (it->type == sc::element_type_empty)
1782 {
1783 // Skip the empty block.
1784 nTestRow += it->size - aPos.second;
1785 ++it;
1786 if (it == rCells.end())
1787 {
1788 // No more block. Move on to the next column.
1789 rRow = rDocument.MaxRow() + 1;
1790 continue;
1791 }
1792 }
1793
1794 if (nTestRow <= nEnd)
1795 {
1796 // Cell found.
1797 rRow = nTestRow;
1798 return true;
1799 }
1800
1801 rRow = nEnd + 1; // Search for next selected range
1802 }
1803 else
1804 rRow = rDocument.MaxRow() + 1; // End of column
1805 }
1806 rRow = 0;
1807 ++rCol; // test next column
1808 }
1809
1810 // Though searched only the allocated columns, it is equivalent to a search till rDocument.MaxCol().
1811 rCol = rDocument.MaxCol() + 1;
1812 return false; // Through all columns
1813}
1814
1815void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1816 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
1817 SCCOL nDx, SCROW nDy, SCTAB nDz, bool bUpdateNoteCaptionPos )
1818{
1819 if ( !(nTab >= nTab1 && nTab <= nTab2 && nDz == 0) ) // only within the table
1820 return;
1821
1822 ScDrawLayer* pDrawLayer = rDocument.GetDrawLayer();
1823 if ( eUpdateRefMode != URM_COPY && pDrawLayer )
1824 {
1825 if ( eUpdateRefMode == URM_MOVE )
1826 { // source range
1827 nCol1 = sal::static_int_cast<SCCOL>( nCol1 - nDx );
1828 nRow1 = sal::static_int_cast<SCROW>( nRow1 - nDy );
1829 nCol2 = sal::static_int_cast<SCCOL>( nCol2 - nDx );
1830 nRow2 = sal::static_int_cast<SCROW>( nRow2 - nDy );
1831 }
1832 pDrawLayer->MoveArea( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy,
1833 (eUpdateRefMode == URM_INSDEL), bUpdateNoteCaptionPos );
1834 }
1835}
1836
1838 sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, bool bIncludeDraw, bool bUpdateNoteCaptionPos )
1839{
1840 bool bUpdated = false;
1841 UpdateRefMode eUpdateRefMode = rCxt.meMode;
1842 SCCOL nDx = rCxt.mnColDelta;
1843 SCROW nDy = rCxt.mnRowDelta;
1844 SCTAB nDz = rCxt.mnTabDelta;
1845 SCCOL nCol1 = rCxt.maRange.aStart.Col(), nCol2 = rCxt.maRange.aEnd.Col();
1846 SCROW nRow1 = rCxt.maRange.aStart.Row(), nRow2 = rCxt.maRange.aEnd.Row();
1847 SCTAB nTab1 = rCxt.maRange.aStart.Tab(), nTab2 = rCxt.maRange.aEnd.Tab();
1848
1849 // Named expressions need to be updated before formulas accessing them.
1850 if (mpRangeName)
1851 mpRangeName->UpdateReference(rCxt, nTab);
1852
1853 if (rCxt.meMode == URM_COPY )
1854 {
1856 bUpdated |= aCol[col].UpdateReference(rCxt, pUndoDoc);
1857 }
1858 else
1859 {
1861 bUpdated |= aCol[col].UpdateReference(rCxt, pUndoDoc);
1862 // When deleting row(s), delete same row from the default attribute
1863 if (nDy < 0)
1864 aDefaultColData.DeleteRow(nRow1+nDy, -nDy);
1865 }
1866
1867 if ( bIncludeDraw )
1868 UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
1869
1870 if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // print ranges: only within the table
1871 {
1872 SCTAB nSTab = nTab;
1873 SCTAB nETab = nTab;
1874 SCCOL nSCol = 0;
1875 SCROW nSRow = 0;
1876 SCCOL nECol = 0;
1877 SCROW nERow = 0;
1878 bool bRecalcPages = false;
1879
1880 for ( auto& rPrintRange : aPrintRanges )
1881 {
1882 nSCol = rPrintRange.aStart.Col();
1883 nSRow = rPrintRange.aStart.Row();
1884 nECol = rPrintRange.aEnd.Col();
1885 nERow = rPrintRange.aEnd.Row();
1886
1887 // do not try to modify sheet index of print range
1888 if ( ScRefUpdate::Update( &rDocument, eUpdateRefMode,
1889 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1890 nDx,nDy,0,
1891 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1892 {
1893 rPrintRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1894 bRecalcPages = true;
1895 }
1896 }
1897
1898 if ( moRepeatColRange )
1899 {
1900 nSCol = moRepeatColRange->aStart.Col();
1901 nSRow = moRepeatColRange->aStart.Row();
1902 nECol = moRepeatColRange->aEnd.Col();
1903 nERow = moRepeatColRange->aEnd.Row();
1904
1905 // do not try to modify sheet index of repeat range
1906 if ( ScRefUpdate::Update( &rDocument, eUpdateRefMode,
1907 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1908 nDx,nDy,0,
1909 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1910 {
1911 *moRepeatColRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1912 bRecalcPages = true;
1913 nRepeatStartX = nSCol; // for UpdatePageBreaks
1914 nRepeatEndX = nECol;
1915 }
1916 }
1917
1918 if ( moRepeatRowRange )
1919 {
1920 nSCol = moRepeatRowRange->aStart.Col();
1921 nSRow = moRepeatRowRange->aStart.Row();
1922 nECol = moRepeatRowRange->aEnd.Col();
1923 nERow = moRepeatRowRange->aEnd.Row();
1924
1925 // do not try to modify sheet index of repeat range
1926 if ( ScRefUpdate::Update( &rDocument, eUpdateRefMode,
1927 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1928 nDx,nDy,0,
1929 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1930 {
1931 *moRepeatRowRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1932 bRecalcPages = true;
1933 nRepeatStartY = nSRow; // for UpdatePageBreaks
1934 nRepeatEndY = nERow;
1935 }
1936 }
1937
1938 // updating print ranges is not necessary with multiple print ranges
1939 if ( bRecalcPages && GetPrintRangeCount() <= 1 )
1940 {
1941 UpdatePageBreaks(nullptr);
1942
1944 }
1945 }
1946
1947 if (bUpdated)
1948 SetStreamValid(false);
1949
1951 mpCondFormatList->UpdateReference(rCxt);
1952
1953 if (pTabProtection)
1954 pTabProtection->updateReference( eUpdateRefMode, rDocument, rCxt.maRange, nDx, nDy, nDz);
1955}
1956
1957void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
1958 ScDocument* pUndoDoc )
1959{
1960 for (auto const & rpCol : aCol)
1961 rpCol->UpdateTranspose( rSource, rDest, pUndoDoc );
1962}
1963
1964void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
1965{
1966 for (auto const & rpCol : aCol)
1967 rpCol->UpdateGrow( rArea, nGrowX, nGrowY );
1968}
1969
1971{
1972 // Store the old tab number in sc::UpdatedRangeNames for
1973 // ScTokenArray::AdjustReferenceOnInsertedTab() to check with
1974 // isNameModified()
1975 if (mpRangeName)
1976 mpRangeName->UpdateInsertTab(rCxt, nTab);
1977
1978 if (nTab >= rCxt.mnInsertPos)
1979 {
1980 nTab += rCxt.mnSheets;
1981 if (pDBDataNoName)
1982 pDBDataNoName->UpdateMoveTab(nTab - 1 ,nTab);
1983 }
1984
1985 if (mpCondFormatList)
1986 mpCondFormatList->UpdateInsertTab(rCxt);
1987
1988 if (pTabProtection)
1989 pTabProtection->updateReference( URM_INSDEL, rDocument,
1991 0, 0, rCxt.mnSheets);
1992
1993 for (SCCOL i=0; i < aCol.size(); i++)
1994 aCol[i].UpdateInsertTab(rCxt);
1995
1996 SetStreamValid(false);
1997}
1998
2000{
2001 // Store the old tab number in sc::UpdatedRangeNames for
2002 // ScTokenArray::AdjustReferenceOnDeletedTab() to check with
2003 // isNameModified()
2004 if (mpRangeName)
2005 mpRangeName->UpdateDeleteTab(rCxt, nTab);
2006
2007 if (nTab > rCxt.mnDeletePos)
2008 {
2009 nTab -= rCxt.mnSheets;
2010 if (pDBDataNoName)
2011 pDBDataNoName->UpdateMoveTab(nTab + 1,nTab);
2012 }
2013
2014 if (mpCondFormatList)
2015 mpCondFormatList->UpdateDeleteTab(rCxt);
2016
2017 if (pTabProtection)
2018 pTabProtection->updateReference( URM_INSDEL, rDocument,
2020 0, 0, -rCxt.mnSheets);
2021
2022 for (SCCOL i = 0; i < aCol.size(); ++i)
2023 aCol[i].UpdateDeleteTab(rCxt);
2024
2025 SetStreamValid(false);
2026}
2027
2029 sc::RefUpdateMoveTabContext& rCxt, SCTAB nTabNo, ScProgress* pProgress )
2030{
2031 nTab = nTabNo;
2032 if (mpRangeName)
2033 mpRangeName->UpdateMoveTab(rCxt, nTab);
2034
2035 if (pDBDataNoName)
2036 pDBDataNoName->UpdateMoveTab(rCxt.mnOldPos, rCxt.mnNewPos);
2037
2039 mpCondFormatList->UpdateMoveTab(rCxt);
2040
2041 if (pTabProtection)
2042 pTabProtection->updateReference( URM_REORDER, rDocument,
2044 0, 0, rCxt.mnNewPos - rCxt.mnOldPos);
2045
2046 for ( SCCOL i=0; i < aCol.size(); i++ )
2047 {
2048 aCol[i].UpdateMoveTab(rCxt, nTabNo);
2049 if (pProgress)
2050 pProgress->SetState(pProgress->GetState() + aCol[i].GetCodeCount());
2051 }
2052
2053 SetStreamValid(false);
2054}
2055
2056void ScTable::UpdateCompile( bool bForceIfNameInUse )
2057{
2058 for (SCCOL i=0; i < aCol.size(); i++)
2059 {
2060 aCol[i].UpdateCompile( bForceIfNameInUse );
2061 }
2062}
2063
2065{
2066 nTab = nNewTab;
2067 for (SCCOL i=0; i < aCol.size(); i++)
2068 aCol[i].SetTabNo(nNewTab);
2069}
2070
2071void ScTable::FindRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
2072 sc::UpdatedRangeNames& rIndexes) const
2073{
2074 for (SCCOL i = nCol1; i <= nCol2 && IsColValid( i ); i++)
2075 aCol[i].FindRangeNamesInUse(nRow1, nRow2, rIndexes);
2076}
2077
2079 SCCOL /* nStartCol */, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
2080{
2081 if ( !mpColFlags || !pRowFlags )
2082 {
2083 OSL_FAIL("ExtendPrintArea: No ColInfo or RowInfo");
2084 return;
2085 }
2086
2087 Point aPix1000 = pDev->LogicToPixel(Point(1000,1000), MapMode(MapUnit::MapTwip));
2088 double nPPTX = aPix1000.X() / 1000.0;
2089 double nPPTY = aPix1000.Y() / 1000.0;
2090
2091 // First, mark those columns that we need to skip i.e. hidden and empty columns.
2092
2094 aSkipCols.setFalse(0, rDocument.MaxCol());
2095 for (SCCOL i = 0; i <= rDocument.MaxCol(); ++i)
2096 {
2097 SCCOL nLastCol = i;
2098 if (ColHidden(i, nullptr, &nLastCol))
2099 {
2100 // Columns are hidden in this range.
2101 aSkipCols.setTrue(i, nLastCol);
2102 }
2103 else
2104 {
2105 // These columns are visible. Check for empty columns.
2106 for (SCCOL j = i; j <= nLastCol; ++j)
2107 {
2108 if ( j >= aCol.size() )
2109 {
2110 aSkipCols.setTrue( j, rDocument.MaxCol() );
2111 break;
2112 }
2113 if (aCol[j].GetCellCount() == 0)
2114 // empty
2115 aSkipCols.setTrue(j,j);
2116 }
2117 }
2118 i = nLastCol;
2119 }
2120
2122 for (SCCOL nCol = rEndCol; nCol >= 0; --nCol)
2123 {
2124 if (!aSkipCols.getRangeData(nCol, aColData))
2125 // Failed to get the data. This should never happen!
2126 return;
2127
2128 if (aColData.mbValue)
2129 {
2130 // Skip these columns.
2131 nCol = aColData.mnCol1; // move toward 0.
2132 continue;
2133 }
2134
2135 // These are visible and non-empty columns.
2136 for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= aColData.mnCol1; --nDataCol)
2137 {
2138 SCCOL nPrintCol = nDataCol;
2140 ScRefCellValue aCell = aIter.reset(nStartRow);
2141 if (aCell.isEmpty())
2142 // No visible cells found in this column. Skip it.
2143 continue;
2144
2145 while (!aCell.isEmpty())
2146 {
2147 SCCOL nNewCol = nDataCol;
2148 SCROW nRow = aIter.getRow();
2149 if (nRow > nEndRow)
2150 // Went past the last row position. Bail out.
2151 break;
2152
2153 MaybeAddExtraColumn(nNewCol, nRow, pDev, nPPTX, nPPTY);
2154 if (nNewCol > nPrintCol)
2155 nPrintCol = nNewCol;
2156 aCell = aIter.next();
2157 }
2158
2159 if (nPrintCol > rEndCol)
2160 // Make sure we don't shrink the print area.
2161 rEndCol = nPrintCol;
2162 }
2163 nCol = aColData.mnCol1; // move toward 0.
2164 }
2165}
2166
2167void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY)
2168{
2169 // tdf#128873 we do not need to calculate text width (heavy operation)
2170 // when we for sure know that an additional column will not be added
2171 if (GetAllocatedColumnsCount() > rCol + 1)
2172 {
2173 ScRefCellValue aNextCell = aCol[rCol + 1].GetCellValue(nRow);
2174 if (!aNextCell.isEmpty())
2175 {
2176 // return rCol as is
2177 return;
2178 }
2179 }
2180
2181 ScColumn& rColumn = aCol[rCol];
2182 ScRefCellValue aCell = rColumn.GetCellValue(nRow);
2183 if (!aCell.hasString())
2184 return;
2185
2186 tools::Long nPixel = rColumn.GetTextWidth(nRow);
2187
2188 // Width already calculated in Idle-Handler ?
2189 if ( TEXTWIDTH_DIRTY == nPixel )
2190 {
2191 ScNeededSizeOptions aOptions;
2192 aOptions.bTotalSize = true;
2193 aOptions.bFormula = false; //TODO: pass as parameter
2194 aOptions.bSkipMerged = false;
2195
2196 Fraction aZoom(1,1);
2197 nPixel = rColumn.GetNeededSize(
2198 nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions, nullptr );
2199
2200 rColumn.SetTextWidth(nRow, static_cast<sal_uInt16>(nPixel));
2201 }
2202
2203 tools::Long nTwips = static_cast<tools::Long>(nPixel / nPPTX);
2204 tools::Long nDocW = GetColWidth( rCol );
2205
2206 tools::Long nMissing = nTwips - nDocW;
2207 if ( nMissing > 0 )
2208 {
2209 // look at alignment
2210
2211 const ScPatternAttr* pPattern = GetPattern( rCol, nRow );
2212 const SfxItemSet* pCondSet = rDocument.GetCondResult( rCol, nRow, nTab );
2213
2214 SvxCellHorJustify eHorJust =
2215 pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet ).GetValue();
2216 if ( eHorJust == SvxCellHorJustify::Center )
2217 nMissing /= 2; // distributed into both directions
2218 else
2219 {
2220 // STANDARD is LEFT (only text is handled here)
2221 bool bRight = ( eHorJust == SvxCellHorJustify::Right );
2222 if ( IsLayoutRTL() )
2223 bRight = !bRight;
2224 if ( bRight )
2225 nMissing = 0; // extended only to the left (logical)
2226 }
2227 }
2228
2229 SCCOL nNewCol = rCol;
2230 while (nMissing > 0 && nNewCol < rDocument.MaxCol())
2231 {
2232 auto nNextCol = nNewCol + 1;
2233 bool bNextEmpty = true;
2234 if (GetAllocatedColumnsCount() > nNextCol)
2235 {
2236 ScRefCellValue aNextCell = aCol[nNextCol].GetCellValue(nRow);
2237 bNextEmpty = aNextCell.isEmpty();
2238 }
2239 if (!bNextEmpty)
2240 {
2241 // Cell content in a next column ends display of this string.
2242 nMissing = 0;
2243 }
2244 else
2245 nMissing -= GetColWidth(++nNewCol);
2246 }
2247 rCol = nNewCol;
2248}
2249
2250namespace {
2251
2252class SetTableIndex
2253{
2254 SCTAB mnTab;
2255public:
2256 explicit SetTableIndex(SCTAB nTab) : mnTab(nTab) {}
2257
2258 void operator() (ScRange& rRange) const
2259 {
2260 rRange.aStart.SetTab(mnTab);
2261 rRange.aEnd.SetTab(mnTab);
2262 }
2263};
2264
2265}
2266
2268{
2269 // The table index shouldn't be used when the print range is used, but
2270 // just in case set the correct table index.
2271
2272 aPrintRanges = rTable.aPrintRanges;
2273 ::std::for_each(aPrintRanges.begin(), aPrintRanges.end(), SetTableIndex(nTab));
2274
2276
2277 moRepeatColRange.reset();
2278 if (rTable.moRepeatColRange)
2279 {
2280 moRepeatColRange.emplace(*rTable.moRepeatColRange);
2281 moRepeatColRange->aStart.SetTab(nTab);
2282 moRepeatColRange->aEnd.SetTab(nTab);
2283 }
2284
2285 moRepeatRowRange.reset();
2286 if (rTable.moRepeatRowRange)
2287 {
2288 moRepeatRowRange.emplace(*rTable.moRepeatRowRange);
2289 moRepeatRowRange->aStart.SetTab(nTab);
2290 moRepeatRowRange->aEnd.SetTab(nTab);
2291 }
2292}
2293
2294void ScTable::SetRepeatColRange( std::optional<ScRange> oNew )
2295{
2296 moRepeatColRange = std::move(oNew);
2297
2298 SetStreamValid(false);
2299
2301}
2302
2303void ScTable::SetRepeatRowRange( std::optional<ScRange> oNew )
2304{
2305 moRepeatRowRange = std::move(oNew);
2306
2307 SetStreamValid(false);
2308
2310}
2311
2313{
2314 aPrintRanges.clear();
2315 bPrintEntireSheet = false;
2316
2317 SetStreamValid(false);
2318
2319 InvalidatePageBreaks(); // #i117952# forget page breaks for an old print range
2320}
2321
2323{
2324 bPrintEntireSheet = false;
2325 if( aPrintRanges.size() < 0xFFFF )
2326 aPrintRanges.push_back( rNew );
2327
2328 SetStreamValid(false);
2329
2331}
2332
2334{
2335 if( !IsPrintEntireSheet() )
2336 {
2338 bPrintEntireSheet = true;
2339 }
2340}
2341
2342const ScRange* ScTable::GetPrintRange(sal_uInt16 nPos) const
2343{
2344 return (nPos < GetPrintRangeCount()) ? &aPrintRanges[ nPos ] : nullptr;
2345}
2346
2348{
2349 rSaveTab.SetAreas( std::vector(aPrintRanges), bPrintEntireSheet );
2351}
2352
2354{
2355 aPrintRanges = rSaveTab.GetPrintRanges();
2356 bPrintEntireSheet = rSaveTab.IsEntireSheet();
2357 SetRepeatColRange( rSaveTab.GetRepeatCol() );
2358 SetRepeatRowRange( rSaveTab.GetRepeatRow() );
2359
2360 InvalidatePageBreaks(); // #i117952# forget page breaks for an old print range
2361 UpdatePageBreaks(nullptr);
2362}
2363
2365 mrDocument(rDoc),
2366 mrRowSegs(rRowSegs),
2367 mrColumn(rColumn),
2368 mnCurRow(ROW_NOT_FOUND),
2369 mnUBound(ROW_NOT_FOUND)
2370{
2371}
2372
2374{
2375 if (nRow > mrDocument.MaxRow())
2376 {
2377 mnCurRow = ROW_NOT_FOUND;
2378 return ScRefCellValue();
2379 }
2380
2382 if (!mrRowSegs.getRangeData(nRow, aData))
2383 {
2384 mnCurRow = ROW_NOT_FOUND;
2385 return ScRefCellValue();
2386 }
2387
2388 if (!aData.mbValue)
2389 {
2390 // specified row is visible. Take it.
2391 mnCurRow = nRow;
2392 mnUBound = aData.mnRow2;
2393 }
2394 else
2395 {
2396 // specified row is not-visible. The first visible row is the start of
2397 // the next segment.
2398 mnCurRow = aData.mnRow2 + 1;
2399 mnUBound = mnCurRow; // get range data on the next iteration.
2400 if (mnCurRow > mrDocument.MaxRow())
2401 {
2402 // Make sure the row doesn't exceed our current limit.
2403 mnCurRow = ROW_NOT_FOUND;
2404 return ScRefCellValue();
2405 }
2406 }
2407
2408 maCell = mrColumn.GetCellValue(mnCurRow);
2409 if (!maCell.isEmpty())
2410 // First visible cell found.
2411 return maCell;
2412
2413 // Find a first visible cell below this row (if any).
2414 return next();
2415}
2416
2418{
2419 if (mnCurRow == ROW_NOT_FOUND)
2420 return ScRefCellValue();
2421
2422 while (mrColumn.GetNextDataPos(mnCurRow))
2423 {
2424 if (mnCurRow > mnUBound)
2425 {
2426 // We don't know the visibility of this row range. Query it.
2428 if (!mrRowSegs.getRangeData(mnCurRow, aData))
2429 {
2430 mnCurRow = ROW_NOT_FOUND;
2431 return ScRefCellValue();
2432 }
2433
2434 if (aData.mbValue)
2435 {
2436 // This row is invisible. Skip to the last invisible row and
2437 // try again.
2438 mnCurRow = mnUBound = aData.mnRow2;
2439 continue;
2440 }
2441
2442 // This row is visible.
2443 mnUBound = aData.mnRow2;
2444 }
2445
2446 maCell = mrColumn.GetCellValue(mnCurRow);
2447 if (!maCell.isEmpty())
2448 return maCell;
2449 }
2450
2451 mnCurRow = ROW_NOT_FOUND;
2452 return ScRefCellValue();
2453}
2454
2455void ScTable::SetAnonymousDBData(std::unique_ptr<ScDBData> pDBData)
2456{
2457 pDBDataNoName = std::move(pDBData);
2458}
2459
2460sal_uLong ScTable::AddCondFormat( std::unique_ptr<ScConditionalFormat> pNew )
2461{
2462 if(!mpCondFormatList)
2464
2465 sal_uInt32 nMax = mpCondFormatList->getMaxKey();
2466
2467 pNew->SetKey(nMax+1);
2468 mpCondFormatList->InsertNew(std::move(pNew));
2469
2470 return nMax + 1;
2471}
2472
2474{
2475 if ( !IsColValid( nCol ) )
2476 return SvtScriptType::NONE;
2477
2478 return aCol[nCol].GetScriptType(nRow);
2479}
2480
2482{
2483 if (!ValidCol(nCol))
2484 return;
2485
2486 aCol[nCol].SetScriptType(nRow, nType);
2487}
2488
2490 sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2491{
2492 if ( !IsColValid( nCol ) )
2493 return SvtScriptType::NONE;
2494
2495 sc::CellStoreType::iterator itr = aCol[nCol].maCells.begin();
2496 return aCol[nCol].GetRangeScriptType(rBlockPos.miCellTextAttrPos, nRow1, nRow2, itr);
2497}
2498
2500{
2501 if ( !ValidCol( nCol ) || !ValidRow( nRow ) )
2502 return formula::FormulaTokenRef();
2503 if ( nCol >= aCol.size() )
2504 // Return a value of 0.0 if column not exists
2506 return aCol[nCol].ResolveStaticReference(nRow);
2507}
2508
2510{
2511 if (nCol2 < nCol1 || nRow2 < nRow1)
2512 return formula::FormulaTokenRef();
2513
2514 if ( !ValidCol( nCol1 ) || !ValidCol( nCol2 ) || !ValidRow( nRow1 ) || !ValidRow( nRow2 ) )
2515 return formula::FormulaTokenRef();
2516
2517 SCCOL nMaxCol;
2518 if ( nCol2 >= aCol.size() )
2519 nMaxCol = aCol.size() - 1;
2520 else
2521 nMaxCol = nCol2;
2522
2523 ScMatrixRef pMat(new ScMatrix(nCol2-nCol1+1, nRow2-nRow1+1, 0.0));
2524 for (SCCOL nCol = nCol1; nCol <= nMaxCol; ++nCol)
2525 {
2526 if (!aCol[nCol].ResolveStaticReference(*pMat, nCol2-nCol1, nRow1, nRow2))
2527 // Column contains non-static cell. Failed.
2528 return formula::FormulaTokenRef();
2529 }
2530
2531 return formula::FormulaTokenRef(new ScMatrixToken(std::move(pMat)));
2532}
2533
2535{
2536 if (nRow2 < nRow1)
2537 return formula::VectorRefArray();
2538
2539 if ( !IsColValid( nCol ) || !ValidRow( nRow1 ) || !ValidRow( nRow2 ) )
2540 return formula::VectorRefArray();
2541
2542 return aCol[nCol].FetchVectorRefArray(nRow1, nRow2);
2543}
2544
2545#ifdef DBG_UTIL
2547{
2548 assert( nRow2 >= nRow1 );
2549 assert( IsColValid( nCol ) && ValidRow( nRow1 ) && ValidRow( nRow2 ) );
2550 return aCol[nCol].AssertNoInterpretNeeded(nRow1, nRow2);
2551}
2552#endif
2553
2555{
2556 if (nRow2 < nRow1)
2557 return false;
2558
2559 if ( !IsColValid( nCol ) || !ValidRow( nRow1 ) || !ValidRow( nRow2 ) )
2560 return false;
2561
2562 mpHiddenCols->makeReady();
2563 mpHiddenRows->makeReady();
2564 mpFilteredCols->makeReady();
2565 mpFilteredRows->makeReady();
2566
2567 return aCol[nCol].HandleRefArrayForParallelism(nRow1, nRow2, mxGroup);
2568}
2569
2571{
2572 if ( !IsColRowValid( nCol, nRow ) )
2573 return ScRefCellValue();
2574
2575 return aCol[nCol].GetCellValue(nRow);
2576}
2577
2579{
2580 if ( !IsColRowValid( nCol, nRow ) )
2581 return ScRefCellValue();
2582
2583 return aCol[nCol].GetCellValue(rBlockPos, nRow);
2584}
2585
2587{
2588 if ( !IsColRowValid( nCol, nRow ) )
2589 return nullptr;
2590
2591 return aCol[nCol].GetBroadcaster(nRow);
2592}
2593
2595 sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2596{
2597 if ( !IsColValid( nCol ) )
2598 return;
2599
2600 aCol[nCol].DeleteBroadcasters(rBlockPos, nRow1, nRow2);
2601}
2602
2604{
2605 for( auto& col : aCol )
2606 col->DeleteEmptyBroadcasters();
2607}
2608
2609void ScTable::FillMatrix( ScMatrix& rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, svl::SharedStringPool* pPool ) const
2610{
2611 size_t nMatCol = 0;
2612 nCol2 = ClampToAllocatedColumns(nCol2);
2613 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nMatCol)
2614 aCol[nCol].FillMatrix(rMat, nMatCol, nRow1, nRow2, pPool);
2615}
2616
2617void ScTable::InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2618{
2619 nCol2 = ClampToAllocatedColumns(nCol2);
2620 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
2621 aCol[nCol].InterpretDirtyCells(nRow1, nRow2);
2622}
2623
2624bool ScTable::InterpretCellsIfNeeded( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2625{
2626 nCol2 = ClampToAllocatedColumns(nCol2);
2627 bool allInterpreted = true;
2628 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
2629 if(!aCol[nCol].InterpretCellsIfNeeded(nRow1, nRow2))
2630 allInterpreted = false;
2631 return allInterpreted;
2632}
2633
2634void ScTable::SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen )
2635{
2636 if (!ValidCol(nCol))
2637 return;
2638
2639 aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
2640}
2641
2643 SCCOL nColStart, SCCOL nColEnd,
2644 SCROW nRowStart, SCROW nRowEnd,
2645 unsigned nThisThread, unsigned nThreadsTotal)
2646{
2647 if (!ValidCol(nColStart) || !ValidCol(nColEnd))
2648 return;
2649
2650 size_t nLen = nRowEnd - nRowStart + 1;
2651 size_t nOffset = 0;
2652 for (SCCOL nCurrCol = nColStart; nCurrCol <= nColEnd; ++nCurrCol)
2653 {
2654 aCol[nCurrCol].CalculateInThread( rContext, nRowStart, nLen, nOffset, nThisThread, nThreadsTotal );
2655 nOffset += nLen;
2656 }
2657}
2658
2659void ScTable::HandleStuffAfterParallelCalculation( SCCOL nColStart, SCCOL nColEnd, SCROW nRow, size_t nLen,
2660 ScInterpreter* pInterpreter)
2661{
2662 assert(ValidCol(nColStart) && ValidCol(nColEnd));
2663
2664 for (SCCOL nCurrCol = nColStart; nCurrCol <= nColEnd; ++nCurrCol)
2665 aCol[nCurrCol].HandleStuffAfterParallelCalculation( nRow, nLen, pInterpreter );
2666}
2667
2668#if DUMP_COLUMN_STORAGE
2669void ScTable::DumpColumnStorage( SCCOL nCol ) const
2670{
2671 if ( !IsColValid( nCol ) )
2672 return;
2673
2674 aCol[nCol].DumpColumnStorage();
2675}
2676#endif
2677
2679{
2680 if ( !IsColRowValid( nCol, nRow ) )
2681 return nullptr;
2682
2683 return aCol[nCol].GetBroadcaster(nRow);
2684}
2685
2687{
2688 mpCondFormatList->erase(nIndex);
2689}
2690
2692{
2693 mpCondFormatList.reset( pNew );
2694}
2695
2697{
2698 if(!mpCondFormatList)
2700
2701 return mpCondFormatList.get();
2702}
2703
2705{
2706 return mpCondFormatList.get();
2707}
2708
2710{
2711 // because the range is inclusive, some code will pass nColEnd<nColBegin to indicate an empty range
2712 if (nColEnd < nColBegin)
2713 return ScColumnsRange(-1, -1);
2714 assert( nColEnd >= 0 && nColEnd <= GetDoc().MaxCol());
2715 CreateColumnIfNotExists(nColEnd);
2716 return GetColumnsRange(nColBegin, nColEnd);
2717}
2718
2720{
2721 if (nColBegin >= aCol.size())
2722 return ScColumnsRange(-1, -1);
2723 // clamp end of range to available columns
2724 if (nColEnd >= aCol.size())
2725 nColEnd = aCol.size() - 1;
2726 return GetColumnsRange(nColBegin, nColEnd);
2727}
2728
2730{
2731 // because the range is inclusive, some code will pass nColEnd<nColBegin to indicate an empty range
2732 if (nColEnd < nColBegin)
2733 return ScColumnsRange(-1, -1);
2734 assert( nColBegin >= 0 && nColBegin <= GetDoc().MaxCol());
2735 assert( nColEnd >= 0 && nColEnd <= GetDoc().MaxCol());
2736 return ScColumnsRange(nColBegin, nColEnd + 1); // change inclusive end to past-end
2737}
2738
2739// out-of-line the cold part of the CreateColumnIfNotExists function
2741{
2742 // When doing multi-threaded load of, e.g. XLS files, we can hit this, which calls
2743 // into SfxItemPool::Put, in parallel with other code that calls into SfxItemPool::Put,
2744 // which is bad since that code is not thread-safe.
2745 SolarMutexGuard aGuard;
2746 const SCCOL aOldColSize = aCol.size();
2747 aCol.resize( rDocument.GetSheetLimits(), static_cast< size_t >( nScCol + 1 ) );
2748 for (SCCOL i = aOldColSize; i <= nScCol; i++)
2749 aCol[i].Init( i, nTab, rDocument, false );
2750}
2751/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SCROW SCROW_REPEAT_NONE
Definition: address.hxx:94
const SCCOL SCCOL_REPEAT_NONE
Definition: address.hxx:93
const SCTAB MAXTAB
Definition: address.hxx:70
const SCCOL INITIALCOLCOUNT
Definition: address.hxx:64
const SCCOL SC_TABSTART_NONE
Definition: address.hxx:95
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:150
double ny
double nx
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
constexpr tools::Long Y() const
constexpr tools::Long X() const
@ UNINITIALIZED
Definition: address.hxx:220
SCTAB Tab() const
Definition: address.hxx:283
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:403
SCROW Row() const
Definition: address.hxx:274
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
SCCOL Col() const
Definition: address.hxx:279
The data type represents bits, manageable by bitwise operations.
SCCOL size() const
ScColumnVector::const_iterator begin() const
const ScColumn & back() const
void resize(ScSheetLimits const &, const size_t aNewSize)
void DeleteRow(SCROW nStartRow, SCSIZE nSize)
Definition: column.hxx:1061
void InitAttrArray(ScAttrArray *attrArray)
Definition: column.hxx:125
SCROW GetNextUnprotected(SCROW nRow, bool bUp) const
Including current, may return -1.
Definition: column.hxx:925
void GetOptimalHeight(sc::RowHeightContext &rCxt, SCROW nStartRow, SCROW nEndRow, sal_uInt16 nMinHeight, SCROW nMinStart)
Definition: column2.cxx:891
sal_uInt64 GetWeightedCount() const
Definition: column2.cxx:3784
tools::Long GetNeededSize(SCROW nRow, OutputDevice *pDev, double nPPTX, double nPPTY, const Fraction &rZoomX, const Fraction &rZoomY, bool bWidth, const ScNeededSizeOptions &rOptions, const ScPatternAttr **pPatternChange, bool bInPrintTwips=false) const
Definition: column2.cxx:85
ScRefCellValue GetCellValue(SCROW nRow) const
Definition: column.cxx:638
void SetTextWidth(SCROW nRow, sal_uInt16 nWidth)
Definition: column2.cxx:2302
sal_uInt16 GetTextWidth(SCROW nRow) const
Definition: column2.cxx:2297
RangeData GetRangeData(A nPos) const
Get range data for a row, i.e.
void SetValue(A nPos, const D &rValue)
const D & GetValue(A nPos) const
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:898
bool IsStreamValidLocked() const
Definition: document.hxx:990
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:892
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
bool IsAdjustHeightLocked() const
Definition: document.hxx:1599
void RepaintRange(const ScRange &rRange)
Definition: documen8.cxx:689
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1084
SC_DLLPUBLIC bool HasAttrib(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, HasAttrFlags nMask) const
Definition: document.cxx:5161
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1083
SC_DLLPUBLIC bool IsDocVisible() const
Definition: document.hxx:1616
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4430
bool IsInDtorClear() const
Definition: document.hxx:2455
SC_DLLPUBLIC bool GetPrintArea(SCTAB nTab, SCCOL &rEndCol, SCROW &rEndRow, bool bNotes=true) const
Definition: documen2.cxx:611
SC_DLLPUBLIC const SfxItemSet * GetCondResult(SCCOL nCol, SCROW nRow, SCTAB nTab, ScRefCellValue *pCell=nullptr) const
Definition: documen4.cxx:791
void MoveArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCCOL nDx, SCROW nDy, bool bInsDel, bool bUpdateNoteCaptionPos)
Definition: drwlayer.cxx:1529
void ScRenamePage(SCTAB nTab, const OUString &rNewName)
Definition: drwlayer.cxx:485
void SetPageSize(sal_uInt16 nPageNo, const Size &rSize, bool bUpdateNoteCaptionPos, const ScObjectHandling eObjectHandling=ScObjectHandling::RecalcPosMode)
Definition: drwlayer.cxx:644
bool ScAddPage(SCTAB nTab)
Definition: drwlayer.cxx:453
void ScRemovePage(SCTAB nTab)
Definition: drwlayer.cxx:467
bool setFalse(SCCOL nCol1, SCCOL nCol2)
bool setTrue(SCCOL nCol1, SCCOL nCol2)
bool getRangeData(SCCOL nCol, RangeData &rData)
static bool IsSystemRTL()
Definition: global.cxx:895
static SC_DLLPUBLIC const CharClass & getCharClass()
Definition: global.cxx:1064
This is a rather odd datastructure.
Definition: markarr.hxx:44
SCROW GetNextMarked(SCROW nRow, bool bUp) const
Including current row, may return -1 if bUp and not found.
Definition: markarr.cxx:286
SCROW GetMarkEnd(SCROW nRow, bool bUp) const
Definition: markarr.cxx:309
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
const ScRange & GetMultiMarkArea() const
Definition: markdata.hxx:84
const ScRange & GetMarkArea() const
Definition: markdata.hxx:83
SCROW GetNextMarked(SCCOL nCol, SCROW nRow, bool bUp) const
May return -1.
Definition: markdata.cxx:609
bool IsMultiMarked() const
Definition: markdata.hxx:81
bool IsCellMarked(SCCOL nCol, SCROW nRow, bool bNoSimple=false) const
Definition: markdata.cxx:270
bool IsMarked() const
Definition: markdata.hxx:80
ScMarkArray GetMarkArray(SCCOL nCol) const
Definition: markdata.hxx:107
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:101
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:73
const std::optional< ScRange > & GetRepeatCol() const
Definition: prnsave.hxx:47
bool IsEntireSheet() const
Definition: prnsave.hxx:46
const std::optional< ScRange > & GetRepeatRow() const
Definition: prnsave.hxx:48
const ScRangeVec & GetPrintRanges() const
Definition: prnsave.hxx:45
void SetRepeat(std::optional< ScRange > oCol, std::optional< ScRange > oRow)
Definition: prnsave.cxx:43
void SetAreas(ScRangeVec &&rRanges, bool bEntireSheet)
Definition: prnsave.cxx:37
sal_uInt64 GetState() const
Definition: progress.hxx:109
void SetState(sal_uInt64 nVal, sal_uInt64 nNewRange=0)
Definition: progress.hxx:78
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
static ScRefUpdateRes Update(const ScDocument *pDoc, UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCCOL nDx, SCROW nDy, SCTAB nDz, SCCOL &theCol1, SCROW &theRow1, SCTAB &theTab1, SCCOL &theCol2, SCROW &theRow2, SCTAB &theTab2)
Definition: refupdat.cxx:188
Use this to iterate through non-empty visible cells in a single column.
Definition: table.hxx:1391
VisibleDataCellIterator(const ScDocument &rDoc, ScFlatBoolRowSegments &rRowSegs, ScColumn &rColumn)
Definition: table1.cxx:2364
ScRefCellValue next()
Find the next visible data cell position.
Definition: table1.cxx:2417
SCROW getRow() const
Get the current row position.
Definition: table.hxx:1419
ScRefCellValue reset(SCROW nRow)
Set the start row position.
Definition: table1.cxx:2373
std::unique_ptr< ScFlatBoolColSegments > mpHiddenCols
Definition: table.hxx:199
SCCOL mnEndCol
Definition: table.hxx:186
bool bTableAreaVisibleValid
Definition: table.hxx:252
bool ValidCol(SCCOL nCol) const
Definition: table.hxx:356
void UpdateInsertTab(sc::RefUpdateInsertTabContext &rCxt)
Definition: table1.cxx:1970
SCCOL FindNextVisibleCol(SCCOL nCol, bool bRight) const
Definition: table1.cxx:1296
ScLinkMode nLinkMode
Definition: table.hxx:173
void UpdateDrawRef(UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCCOL nDx, SCROW nDy, SCTAB nDz, bool bUpdateNoteCaptionPos=true)
Definition: table1.cxx:1815
bool SkipRow(const SCCOL rCol, SCROW &rRow, const SCROW nMovY, const ScMarkData &rMark, const bool bUp, const SCROW nUsedY, const bool bMarked, const bool bSheetProtected) const
Definition: table1.cxx:1481
void FillMatrix(ScMatrix &rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, svl::SharedStringPool *pPool) const
Definition: table1.cxx:2609
void AssertNoInterpretNeeded(SCCOL nCol, SCROW nRow1, SCROW nRow2)
Definition: table1.cxx:2546
std::unique_ptr< ScFlatBoolRowSegments > mpFilteredRows
Definition: table.hxx:202
ScRefCellValue GetRefCellValue(SCCOL nCol, SCROW nRow)
Definition: table1.cxx:2570
ScColumnsRange GetAllocatedColumnsRange(SCCOL begin, SCCOL end) const
Definition: table1.cxx:2719
const OUString & GetUpperName() const
Definition: table1.cxx:367
void UpdateDeleteTab(sc::RefUpdateDeleteTabContext &rCxt)
Definition: table1.cxx:1999
void UpdateGrow(const ScRange &rArea, SCCOL nGrowX, SCROW nGrowY)
Definition: table1.cxx:1964
ScColumnsRange GetColumnsRange(SCCOL begin, SCCOL end) const
Definition: table1.cxx:2729
bool GetPrintAreaHor(SCROW nStartRow, SCROW nEndRow, SCCOL &rEndCol) const
Definition: table1.cxx:717
bool GetCellArea(SCCOL &rEndCol, SCROW &rEndRow)
Definition: table1.cxx:521
OUString aLinkFlt
Definition: table.hxx:169
Color aTabBgColor
Definition: table.hxx:237
OUString aUpperName
Definition: table.hxx:222
void SetLink(ScLinkMode nMode, const OUString &rDoc, const OUString &rFlt, const OUString &rOpt, const OUString &rTab, sal_uLong nRefreshDelay)
Definition: table1.cxx:420
std::unique_ptr< ScDBData > pDBDataNoName
Definition: table.hxx:239
std::unique_ptr< ScConditionalFormatList > mpCondFormatList
Definition: table.hxx:242
void SetTabBgColor(const Color &rColor)
Definition: table1.cxx:405
bool bVisible
Definition: table.hxx:253
void InvalidatePageBreaks()
Definition: table2.cxx:1563
bool InterpretCellsIfNeeded(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: table1.cxx:2624
bool bPendingRowHeights
Definition: table.hxx:254
~ScTable() COVERITY_NOEXCEPT_FALSE
Definition: table1.cxx:325
sal_uInt16 GetColWidth(SCCOL nCol, bool bHiddenAsZero=true) const
Definition: table2.cxx:3455
ScColContainer aCol
Definition: table.hxx:162
bool ValidColRow(SCCOL nCol, SCROW nRow) const
Definition: table.hxx:358
std::unique_ptr< ScBitMaskCompressedArray< SCROW, CRFlags > > pRowFlags
Definition: table.hxx:198
void SetLoadingRTL(bool bSet)
Definition: table1.cxx:400
bool HandleRefArrayForParallelism(SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScFormulaCellGroupRef &mxGroup)
Definition: table1.cxx:2554
void FillPrintSaver(ScPrintSaverTab &rSaveTab) const
Definition: table1.cxx:2347
bool bScenario
Definition: table.hxx:247
ScColumn & CreateColumnIfNotExists(const SCCOL nScCol)
Definition: table.hxx:303
bool IsEmptyLine(SCROW nRow, SCCOL nStartCol, SCCOL nEndCol) const
Definition: table1.cxx:1257
SCROW nRepeatEndY
Definition: table.hxx:181
bool GetDataStart(SCCOL &rStartCol, SCROW &rStartRow) const
Definition: table1.cxx:815
bool IsColValid(const SCCOL nScCol) const
Definition: table.hxx:344
std::unique_ptr< ScBitMaskCompressedArray< SCCOL, CRFlags > > mpColFlags
Definition: table.hxx:197
void SetStreamValid(bool bSet, bool bIgnoreLock=false)
Definition: table1.cxx:382
void GetDataArea(SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow, bool bIncludeOld, bool bOnlyDown) const
Definition: table1.cxx:891
bool bLoadingRTL
Definition: table.hxx:249
sal_uInt64 GetWeightedCount() const
Definition: table3.cxx:3068
sal_uLong nLinkRefreshDelay
Definition: table.hxx:172
bool bTableAreaValid
Definition: table.hxx:251
void CalculateInColumnInThread(ScInterpreterContext &rContext, SCCOL nColStart, SCCOL nColEnd, SCROW nRowStart, SCROW nRowEnd, unsigned nThisThread, unsigned nThreadsTotal)
Definition: table1.cxx:2642
std::optional< ScRange > moRepeatRowRange
Definition: table.hxx:231
std::unique_ptr< ScFlatBoolColSegments > mpFilteredCols
Definition: table.hxx:201
void FindAreaPos(SCCOL &rCol, SCROW &rRow, ScMoveDirection eDirection) const
Definition: table1.cxx:1383
void SetCondFormList(ScConditionalFormatList *pList)
Definition: table1.cxx:2691
SCCOL nRepeatStartX
Definition: table.hxx:178
void RestorePrintRanges(const ScPrintSaverTab &rSaveTab)
Definition: table1.cxx:2353
void CreateColumnIfNotExistsImpl(const SCCOL nScCol)
Definition: table1.cxx:2740
void SetScriptType(SCCOL nCol, SCROW nRow, SvtScriptType nType)
Definition: table1.cxx:2481
void AddPrintRange(const ScRange &rNew)
Adds a new print ranges.
Definition: table1.cxx:2322
bool GetPrintArea(SCCOL &rEndCol, SCROW &rEndRow, bool bNotes, bool bCalcHiddens=false) const
Definition: table1.cxx:608
OUString aLinkTab
Definition: table.hxx:171
void UpdateTranspose(const ScRange &rSource, const ScAddress &rDest, ScDocument *pUndoDoc)
Definition: table1.cxx:1957
void DeleteConditionalFormat(sal_uLong nOldIndex)
Definition: table1.cxx:2686
SCCOL nTableAreaX
Definition: table.hxx:213
SCROW nTableAreaVisibleY
Definition: table.hxx:216
bool ColHidden(SCCOL nCol, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: table5.cxx:562
OUString aLinkDoc
Definition: table.hxx:168
void UpdateReference(sc::RefUpdateContext &rCxt, ScDocument *pUndoDoc=nullptr, bool bIncludeDraw=true, bool bUpdateNoteCaptionPos=true)
Definition: table1.cxx:1837
SCTAB nTab
Definition: table.hxx:218
std::unique_ptr< ScRangeList > pScenarioRanges
Definition: table.hxx:235
bool GetPrintAreaVer(SCCOL nStartCol, SCCOL nEndCol, SCROW &rEndRow, bool bNotes) const
Definition: table1.cxx:762
bool IsLayoutRTL() const
Definition: table.hxx:366
std::unique_ptr< ScOutlineTable > pOutlineTable
Definition: table.hxx:209
sal_uInt16 GetPrintRangeCount() const
Definition: table.hxx:827
formula::VectorRefArray FetchVectorRefArray(SCCOL nCol, SCROW nRow1, SCROW nRow2)
Definition: table1.cxx:2534
void DumpColumnStorage(SCCOL nCol) const
void InterpretDirtyCells(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: table1.cxx:2617
OUString aName
Definition: table.hxx:164
void UpdateMoveTab(sc::RefUpdateMoveTabContext &rCxt, SCTAB nTabNo, ScProgress *pProgress)
Definition: table1.cxx:2028
void DestroySortCollator()
Definition: table3.cxx:644
bool IsColRowValid(const SCCOL nScCol, const SCROW nScRow) const
Definition: table.hxx:348
bool IsProtected() const
Definition: table5.cxx:1171
void SetRepeatColRange(std::optional< ScRange > oNew)
Definition: table1.cxx:2294
void SetFormulaResults(SCCOL nCol, SCROW nRow, const double *pResults, size_t nLen)
Definition: table1.cxx:2634
void LimitChartArea(SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow) const
Definition: table1.cxx:1271
void MaybeAddExtraColumn(SCCOL &rCol, SCROW nRow, OutputDevice *pDev, double nPPTX, double nPPTY)
In case the cell text goes beyond the column width, move the max column position to the right.
Definition: table1.cxx:2167
bool bLayoutRTL
Definition: table.hxx:248
void GetLastDataPos(SCCOL &rCol, SCROW &rRow) const
Definition: table2.cxx:2053
sal_uInt16 GetOptimalColWidth(SCCOL nCol, OutputDevice *pDev, double nPPTX, double nPPTY, const Fraction &rZoomX, const Fraction &rZoomY, bool bFormula, const ScMarkData *pMarkData, const ScColWidthParam *pParam)
Definition: table1.cxx:434
bool GetTableArea(SCCOL &rEndCol, SCROW &rEndRow, bool bCalcHiddens=false) const
Definition: table1.cxx:580
tools::Long GetNeededSize(SCCOL nCol, SCROW nRow, OutputDevice *pDev, double nPPTX, double nPPTY, const Fraction &rZoomX, const Fraction &rZoomY, bool bWidth, bool bTotalSize, bool bInPrintTwips=false)
Definition: table1.cxx:447
void HandleStuffAfterParallelCalculation(SCCOL nColStart, SCCOL nColEnd, SCROW nRow, size_t nLen, ScInterpreter *pInterpreter)
Definition: table1.cxx:2659
SCROW nTableAreaY
Definition: table.hxx:214
ScTable(ScDocument &rDoc, SCTAB nNewTab, const OUString &rNewName, bool bColInfo=true, bool bRowInfo=true)
Definition: table1.cxx:237
void UpdateCompile(bool bForceIfNameInUse=false)
Definition: table1.cxx:2056
ScColumnData aDefaultColData
Definition: table.hxx:268
ScColumnsRange GetWritableColumnsRange(SCCOL begin, SCCOL end)
Definition: table1.cxx:2709
ScConditionalFormatList * GetCondFormList()
Definition: table1.cxx:2696
SCROW mnEndRow
Definition: table.hxx:187
bool SetRowHeightRange(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight, double nPPTY, bool bApi)
Definition: table2.cxx:3373
formula::FormulaTokenRef ResolveStaticReference(SCCOL nCol, SCROW nRow)
Definition: table1.cxx:2499
bool RowHidden(SCROW nRow, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: table5.cxx:487
SCCOL nRepeatEndX
Definition: table.hxx:179
ScRangeVec aPrintRanges
Definition: table.hxx:228
bool IsEmptyData(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow) const
Definition: table1.cxx:1197
SCSIZE GetEmptyLinesInBlock(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScDirection eDir) const
Definition: table1.cxx:1206
bool mbCellAreaEmpty
Definition: table.hxx:185
sal_uInt16 GetOptimalMinRowHeight() const
Definition: table.hxx:879
void SetAnonymousDBData(std::unique_ptr< ScDBData > pDBData)
Definition: table1.cxx:2455
void SetPendingRowHeights(bool bSet)
Definition: table1.cxx:390
std::unique_ptr< ScCompressedArray< SCCOL, sal_uInt16 > > mpColWidth
Definition: table.hxx:194
bool ShrinkToUsedDataArea(bool &o_bShrunk, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow, bool bColumnsOnly, bool bStickyTopRow, bool bStickyLeftCol, ScDataAreaExtras *pDataAreaExtras) const
Definition: table1.cxx:1055
SCCOL GetAllocatedColumnsCount() const
Definition: table.hxx:1164
void SetVisible(bool bVis)
Definition: table1.cxx:374
SCROW nRepeatStartY
Definition: table.hxx:180
sal_Int64 GetHashCode() const
Definition: table1.cxx:354
bool GetDataAreaSubrange(ScRange &rRange) const
Definition: table1.cxx:1014
void SetOptimalHeightOnly(sc::RowHeightContext &rCxt, SCROW nStartRow, SCROW nEndRow, ScProgress *pOuterProgress=nullptr, sal_uInt64 nProgressStart=0)
Definition: table1.cxx:497
void ExtendPrintArea(OutputDevice *pDev, SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW nEndRow)
Definition: table1.cxx:2078
void SetLayoutRTL(bool bSet)
Definition: table1.cxx:395
sal_uLong AddCondFormat(std::unique_ptr< ScConditionalFormat > pNew)
Definition: table1.cxx:2460
void SetRowHeightOnly(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight)
Set specified row height to specified ranges.
Definition: table2.cxx:3429
void UpdatePageBreaks(const ScRange *pUserArea)
Definition: table5.cxx:59
OUString aLinkOpt
Definition: table.hxx:170
std::unique_ptr< ScFlatBoolRowSegments > mpHiddenRows
Definition: table.hxx:200
std::unique_ptr< ScFlatUInt16RowSegments > mpRowHeights
Definition: table.hxx:195
bool GetNextMarkedCell(SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark) const
Definition: table1.cxx:1763
std::unique_ptr< ScRangeName > mpRangeName
Definition: table.hxx:240
SvtScriptType GetRangeScriptType(sc::ColumnBlockPosition &rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2)
Definition: table1.cxx:2489
SvtBroadcaster * GetBroadcaster(SCCOL nCol, SCROW nRow)
Definition: table1.cxx:2586
const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:2282
bool SetOptimalHeight(sc::RowHeightContext &rCxt, SCROW nStartRow, SCROW nEndRow, bool bApi, ScProgress *pOuterProgress=nullptr, sal_uInt64 nProgressStart=0)
Definition: table1.cxx:464
SCCOL nTableAreaVisibleX
Definition: table.hxx:215
void FindRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sc::UpdatedRangeNames &rIndexes) const
Definition: table1.cxx:2071
void SetScenario(bool bFlag)
Definition: table1.cxx:415
bool IsPrintEntireSheet() const
Returns true, if the sheet is always printed.
Definition: table.hxx:830
void CopyPrintRange(const ScTable &rTable)
Definition: table1.cxx:2267
void SetPrintEntireSheet()
Marks the specified sheet to be printed completely.
Definition: table1.cxx:2333
bool bPrintEntireSheet
Definition: table.hxx:257
SCCOL ClampToAllocatedColumns(SCCOL nCol) const
Definition: table.hxx:1163
sal_uInt64 GetCellCount() const
Definition: table3.cxx:3058
ScDocument & rDocument
Definition: table.hxx:219
SCCOL FindNextVisibleColWithContent(SCCOL nCol, bool bRight, SCROW nRow) const
Definition: table1.cxx:1320
SvtScriptType GetScriptType(SCCOL nCol, SCROW nRow) const
Definition: table1.cxx:2473
bool ValidNextPos(SCCOL nCol, SCROW nRow, const ScMarkData &rMark, bool bMarked, bool bUnprotected) const
Definition: table1.cxx:1445
ScDocument & GetDoc()
Definition: table.hxx:297
void GetNextPos(SCCOL &rCol, SCROW &rRow, SCCOL nMovX, SCROW nMovY, bool bMarked, bool bUnprotected, const ScMarkData &rMark, SCCOL nTabStartCol) const
Definition: table1.cxx:1518
SCROW GetLastDataRow(SCCOL nCol1, SCCOL nCol2, SCROW nLastRow, ScDataAreaExtras *pDataAreaExtras=nullptr) const
Definition: table1.cxx:1179
const ScRange * GetPrintRange(sal_uInt16 nPos) const
Definition: table1.cxx:2342
void SetName(const OUString &rNewName)
Definition: table1.cxx:359
void DeleteBroadcasters(sc::ColumnBlockPosition &rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2)
Definition: table1.cxx:2594
std::unique_ptr< ScTableProtection > pTabProtection
Definition: table.hxx:192
std::optional< ScRange > moRepeatColRange
Definition: table.hxx:230
void SetTabNo(SCTAB nNewTab)
Definition: table1.cxx:2064
std::atomic< bool > bStreamValid
this is touched from formula group threading context
Definition: table.hxx:262
void DeleteEmptyBroadcasters()
Definition: table1.cxx:2603
std::unique_ptr< utl::TextSearch > pSearchText
Definition: table.hxx:220
void ClearPrintRanges()
Removes all print ranges.
Definition: table1.cxx:2312
std::unique_ptr< ScSheetEvents > pSheetEvents
Definition: table.hxx:211
bool ValidRow(SCROW nRow) const
Definition: table.hxx:357
bool mbCellAreaDirty
Definition: table.hxx:184
void SetRepeatRowRange(std::optional< ScRange > oNew)
Definition: table1.cxx:2303
RowHeightsArray & getHeightArray()
sal_uInt16 getExtraHeight() const
bool isForceAutoSize() const
Keep track of all named expressions that have been updated during reference update.
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
constexpr ::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
void Init()
int nCount
constexpr double nPPTX
constexpr double nPPTY
ScMoveDirection
Definition: global.hxx:326
@ SC_MOVE_RIGHT
Definition: global.hxx:327
@ SC_MOVE_LEFT
Definition: global.hxx:328
@ SC_MOVE_DOWN
Definition: global.hxx:330
UpdateRefMode
Definition: global.hxx:301
@ URM_COPY
Definition: global.hxx:303
@ URM_MOVE
Definition: global.hxx:304
@ URM_REORDER
Definition: global.hxx:305
@ URM_INSDEL
Definition: global.hxx:302
ScLinkMode
Definition: global.hxx:215
ScScenarioFlags
Definition: global.hxx:226
ScDirection
Definition: global.hxx:343
@ DIR_TOP
Definition: global.hxx:346
@ DIR_RIGHT
Definition: global.hxx:345
@ DIR_BOTTOM
Definition: global.hxx:344
constexpr sal_Int32 STD_EXTRA_WIDTH
Definition: global.hxx:88
CRFlags
Definition: global.hxx:125
constexpr sal_Int32 STD_COL_WIDTH
Definition: global.hxx:87
#define TEXTWIDTH_DIRTY
Definition: globalnames.hxx:19
sal_Int32 nIndex
OUString aName
SvtScriptType
sal_uInt16 nPos
RttiCompleteObjectLocator col
constexpr OUStringLiteral aData
::boost::intrusive_ptr< FormulaToken > FormulaTokenRef
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
mdds::mtv::soa::multi_type_vector< CellStoreTraits > CellStoreType
Cell container.
const mdds::mtv::element_t element_type_empty
Definition: mtvelements.hxx:56
long Long
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
constexpr TypedWhichId< SvxHorJustifyItem > ATTR_HOR_JUSTIFY(129)
#define SC_MOD()
Definition: scmod.hxx:247
sal_uIntPtr sal_uLong
#define nPixel
Struct to hold non-data extended area, used with ScDocument::ShrinkToUsedDataArea().
Definition: sortparam.hxx:53
bool mbCellDrawObjects
If TRUE, consider the presence of draw objects anchored to the cell.
Definition: sortparam.hxx:57
bool mbCellFormats
If TRUE, consider the presence of cell formats.
Definition: sortparam.hxx:59
bool mbCellNotes
If TRUE, consider the presence of cell notes besides data.
Definition: sortparam.hxx:55
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:108
bool isEmpty() const
Definition: cellvalue.cxx:667
bool hasString() const
Definition: cellvalue.cxx:614
Store position data for column array storage.
CellTextAttrStoreType::iterator miCellTextAttrPos
Context for reference update during shifting, moving or copying of cell ranges.
SCROW mnRowDelta
Amount and direction of movement in the row direction.
UpdateRefMode meMode
update mode - insert/delete, copy, or move.
SCCOL mnColDelta
Amount and direction of movement in the column direction.
SCTAB mnTabDelta
Amount and direction of movement in the sheet direction.
ScRange maRange
Range of cells that are about to be moved for insert/delete/move modes.
SvxCellHorJustify
const SCCOL SC_COLUMNS_STOP
Definition: table1.cxx:606
bool bVisible
sal_Int16 SCTAB
Definition: types.hxx:22
::boost::intrusive_ptr< ScFormulaCellGroup > ScFormulaCellGroupRef
Definition: types.hxx:43
sal_Int16 SCCOL
Definition: types.hxx:21
::boost::intrusive_ptr< ScMatrix > ScMatrixRef
Definition: types.hxx:25
sal_Int32 SCROW
Definition: types.hxx:17