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