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