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