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* pDoc, SCTAB nNewTab, const OUString& rNewName,
233  bool bColInfo, bool bRowInfo ) :
234  aCol( INITIALCOLCOUNT ),
235  aName( rNewName ),
236  aCodeName( rNewName ),
237  nLinkRefreshDelay( 0 ),
238  nLinkMode( ScLinkMode::NONE ),
239  aPageStyle( ScResId(STR_STYLENAME_STANDARD_PAGE) ),
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(pDoc->MaxCol())),
246  mpHiddenRows(new ScFlatBoolRowSegments(pDoc->MaxRow())),
247  mpFilteredCols(new ScFlatBoolColSegments(pDoc->MaxCol())),
248  mpFilteredRows(new ScFlatBoolRowSegments(pDoc->MaxRow())),
249  nTableAreaX( 0 ),
250  nTableAreaY( 0 ),
251  nTab( nNewTab ),
252  pDocument( pDoc ),
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, pDoc, nullptr)
275 {
276  if (bColInfo)
277  {
280  }
281 
282  if (bRowInfo)
283  {
286  }
287 
288  if ( pDocument->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 = pDocument->GetDrawLayer();
296  if (pDrawLayer)
297  {
298  if ( pDrawLayer->ScAddPage( nTab ) ) // sal_False (not inserted) during Undo
299  {
300  pDrawLayer->ScRenamePage( nTab, aName );
301  sal_uLong const nx = sal_uLong(double(pDocument->MaxCol()+1) * STD_COL_WIDTH * HMM_PER_TWIPS );
302  sal_uLong ny = static_cast<sal_uLong>(double(pDocument->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, pDocument, true );
309 }
310 
311 ScTable::~ScTable() COVERITY_NOEXCEPT_FALSE
312 {
313  if (!pDocument->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 = pDocument->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 || !pDocument->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, pDocument);
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, pDocument);
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 == pDocument->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 == pDocument->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 = pDocument->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<pDocument->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 < pDocument->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 < pDocument->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 < pDocument->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 > pDocument->MaxRow())
979  {
980  rEndRow = pDocument->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  rEndRow = std::max( rStartRow, std::min(rEndRow, lastDataPos));
1168 }
1169 
1170 SCCOL ScTable::FindNextVisibleCol( SCCOL nCol, bool bRight ) const
1171 {
1172  if(bRight)
1173  {
1174  nCol++;
1175  SCCOL nEnd = 0;
1176  bool bHidden = pDocument->ColHidden(nCol, nTab, nullptr, &nEnd);
1177  if(bHidden)
1178  nCol = nEnd +1;
1179 
1180  return std::min<SCCOL>(pDocument->MaxCol(), nCol);
1181  }
1182  else
1183  {
1184  nCol--;
1185  SCCOL nStart = pDocument->MaxCol();
1186  bool bHidden = pDocument->ColHidden(nCol, nTab, &nStart);
1187  if(bHidden)
1188  nCol = nStart - 1;
1189 
1190  return std::max<SCCOL>(0, nCol);
1191  }
1192 }
1193 
1195 {
1196  const SCCOL nLastCol = aCol.size() - 1;
1197  if(bRight)
1198  {
1199  // If nCol is the last allocated column index, there won't be any content to its right.
1200  // To maintain the original return behaviour, return pDocument->MaxCol().
1201  if(nCol >= nLastCol)
1202  return pDocument->MaxCol();
1203 
1204  do
1205  {
1206  nCol++;
1207  SCCOL nEndCol = 0;
1208  bool bHidden = pDocument->ColHidden( nCol, nTab, nullptr, &nEndCol );
1209  if(bHidden)
1210  {
1211  nCol = nEndCol +1;
1212  // Can end search early as there is no data after nLastCol.
1213  // For nCol == nLastCol, it may still have data so don't want to return pDocument->MaxCol().
1214  if(nCol > nLastCol)
1215  return pDocument->MaxCol();
1216  }
1217 
1218  if(aCol[nCol].HasVisibleDataAt(nRow))
1219  return nCol;
1220  }
1221  while(nCol < nLastCol); // Stop search as soon as the last allocated column is searched.
1222 
1223  return pDocument->MaxCol();
1224  }
1225  else
1226  {
1227  // If nCol is in the unallocated range [nLastCol+1, pDocument->MaxCol()], then move it directly to nLastCol
1228  // as there is no data in the unallocated range. This also makes the search faster and avoids
1229  // the need for more range checks in the loop below.
1230  if ( nCol > nLastCol )
1231  nCol = nLastCol;
1232 
1233  if(nCol == 0)
1234  return 0;
1235 
1236  do
1237  {
1238  nCol--;
1239  SCCOL nStartCol = pDocument->MaxCol();
1240  bool bHidden = pDocument->ColHidden( nCol, nTab, &nStartCol );
1241  if(bHidden)
1242  {
1243  nCol = nStartCol -1;
1244  if(nCol <= 0)
1245  return 0;
1246  }
1247 
1248  if(aCol[nCol].HasVisibleDataAt(nRow))
1249  return nCol;
1250  }
1251  while(nCol > 0);
1252 
1253  return 0;
1254  }
1255 }
1256 
1257 void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, ScMoveDirection eDirection ) const
1258 {
1259  const SCCOL nLastCol = aCol.size() - 1;
1260 
1261  if (eDirection == SC_MOVE_LEFT || eDirection == SC_MOVE_RIGHT)
1262  {
1263  SCCOL nNewCol = rCol;
1264  bool bThere = ( nNewCol <= nLastCol ) && aCol[nNewCol].HasVisibleDataAt(rRow);
1265  bool bRight = (eDirection == SC_MOVE_RIGHT);
1266  if (bThere)
1267  {
1268  if(nNewCol >= pDocument->MaxCol() && eDirection == SC_MOVE_RIGHT)
1269  return;
1270  else if(nNewCol == 0 && eDirection == SC_MOVE_LEFT)
1271  return;
1272 
1273  SCCOL nNextCol = FindNextVisibleCol( nNewCol, bRight );
1274 
1275  if( nNextCol <= nLastCol && aCol[nNextCol].HasVisibleDataAt(rRow) )
1276  {
1277  bool bFound = false;
1278  nNewCol = nNextCol;
1279  do
1280  {
1281  nNextCol = FindNextVisibleCol( nNewCol, bRight );
1282  if( nNextCol <= nLastCol && aCol[nNextCol].HasVisibleDataAt(rRow) )
1283  nNewCol = nNextCol;
1284  else
1285  bFound = true;
1286  }
1287  while(!bFound && nNextCol > 0 && nNextCol < pDocument->MaxCol());
1288  }
1289  else
1290  {
1291  nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
1292  }
1293  }
1294  else
1295  {
1296  nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow);
1297  }
1298 
1299  if (nNewCol<0)
1300  nNewCol=0;
1301  if (nNewCol>pDocument->MaxCol())
1302  nNewCol=pDocument->MaxCol();
1303  rCol = nNewCol;
1304  }
1305  else
1306  {
1307  if ( rCol <= nLastCol )
1308  aCol[rCol].FindDataAreaPos(rRow,eDirection == SC_MOVE_DOWN);
1309  else
1310  {
1311  // The cell (rCol, rRow) is equivalent to an empty cell (although not allocated).
1312  // Set rRow to 0 or pDocument->MaxRow() depending on eDirection to maintain the behaviour of
1313  // ScColumn::FindDataAreaPos() when the given column is empty.
1314  rRow = ( eDirection == SC_MOVE_DOWN ) ? pDocument->MaxRow() : 0;
1315  }
1316  }
1317 }
1318 
1319 bool ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
1320  bool bMarked, bool bUnprotected ) const
1321 {
1322  if (!ValidCol(nCol) || !ValidRow(nRow))
1323  return false;
1324 
1325  if (pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HasAttrFlags::Overlapped))
1326  // Skip an overlapped cell.
1327  return false;
1328 
1329  if (bMarked && !rMark.IsCellMarked(nCol,nRow))
1330  return false;
1331 
1332  /* TODO: for cursor movement *only* this should even take the protection
1333  * options (select locked, select unlocked) into account, see
1334  * ScTabView::SkipCursorHorizontal() and ScTabView::SkipCursorVertical(). */
1335  if (bUnprotected && pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HasAttrFlags::Protected))
1336  return false;
1337 
1338  if (bMarked || bUnprotected) //TODO: also in other case ???
1339  {
1340  // Hidden cells must be skipped, as the cursor would end up on the next cell
1341  // even if it is protected or not marked.
1342  //TODO: control per Extra-Parameter, only for Cursor movement ???
1343 
1344  if (RowHidden(nRow))
1345  return false;
1346 
1347  if (ColHidden(nCol))
1348  return false;
1349  }
1350 
1351  return true;
1352 }
1353 
1354 // Skips the current cell if it is Hidden, Overlapped or Protected and Sheet is Protected
1355 bool ScTable::SkipRow( const SCCOL nCol, SCROW& rRow, const SCROW nMovY,
1356  const ScMarkData& rMark, const bool bUp, const SCROW nUsedY,
1357  const bool bMarked, const bool bSheetProtected ) const
1358 {
1359  if ( !ValidRow( rRow ))
1360  return false;
1361 
1362  if (bSheetProtected && pDocument->HasAttrib( nCol, rRow, nTab, nCol, rRow, nTab, HasAttrFlags::Protected))
1363  {
1364  if ( rRow > nUsedY )
1365  rRow = (bUp ? nUsedY : pDocument->MaxRow() + nMovY);
1366  else
1367  rRow += nMovY;
1368 
1369  if (bMarked)
1370  rRow = rMark.GetNextMarked( nCol, rRow, bUp );
1371 
1372  return true;
1373  }
1374  else
1375  {
1376  bool bRowHidden = RowHidden( rRow );
1377  bool bOverlapped = pDocument->HasAttrib( nCol, rRow, nTab, nCol, rRow, nTab, HasAttrFlags::Overlapped );
1378 
1379  if ( bRowHidden || bOverlapped )
1380  {
1381  rRow += nMovY;
1382  if (bMarked)
1383  rRow = rMark.GetNextMarked( nCol, rRow, bUp );
1384 
1385  return true;
1386  }
1387  }
1388 
1389  return false;
1390 }
1391 
1392 void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCCOL nMovX, SCROW nMovY,
1393  bool bMarked, bool bUnprotected, const ScMarkData& rMark, SCCOL nTabStartCol ) const
1394 {
1395  // Ensure bMarked is set only if there is a mark.
1396  assert( !bMarked || rMark.IsMarked() || rMark.IsMultiMarked());
1397 
1398  const bool bSheetProtected = IsProtected();
1399 
1400  if ( bUnprotected && !bSheetProtected ) // Is sheet really protected?
1401  bUnprotected = false;
1402 
1403  SCCOL nCol = rCol + nMovX;
1404  SCROW nRow = rRow + nMovY;
1405 
1406  SCCOL nStartCol, nEndCol;
1407  SCROW nStartRow, nEndRow;
1408  if (bMarked)
1409  {
1411  if (rMark.IsMarked())
1412  rMark.GetMarkArea( aRange);
1413  else if (rMark.IsMultiMarked())
1414  rMark.GetMultiMarkArea( aRange);
1415  else
1416  {
1417  // Covered by assert() above, but for NDEBUG build.
1418  if (ValidColRow(nCol,nRow))
1419  {
1420  rCol = nCol;
1421  rRow = nRow;
1422  }
1423  return;
1424  }
1425  nStartCol = aRange.aStart.Col();
1426  nStartRow = aRange.aStart.Row();
1427  nEndCol = aRange.aEnd.Col();
1428  nEndRow = aRange.aEnd.Row();
1429  }
1430  else if (bUnprotected)
1431  {
1432  nStartCol = 0;
1433  nStartRow = 0;
1434  nEndCol = rCol;
1435  nEndRow = rRow;
1436  pDocument->GetPrintArea( nTab, nEndCol, nEndRow, true );
1437  // Add some cols/rows to the print area (which is "content or
1438  // visually different from empty") to enable travelling through
1439  // protected forms with empty cells and no visual indicator.
1440  // 42 might be good enough and not too much...
1441  nEndCol = std::min<SCCOL>( nEndCol+42, pDocument->MaxCol());
1442  nEndRow = std::min<SCROW>( nEndRow+42, pDocument->MaxRow());
1443  }
1444  else
1445  {
1446  // Invalid values show up for instance for Tab, when nothing is
1447  // selected and not protected (left / right edge), then leave values
1448  // unchanged.
1449  if (ValidColRow(nCol,nRow))
1450  {
1451  rCol = nCol;
1452  rRow = nRow;
1453  }
1454 
1455  // Caller ensures actually moving nMovY to jump to prev/next row's
1456  // start col.
1457  if (nTabStartCol != SC_TABSTART_NONE)
1458  rCol = nTabStartCol;
1459 
1460  return;
1461  }
1462 
1463  if ( nMovY && (bMarked || bUnprotected))
1464  {
1465  do
1466  {
1467  const bool bUp = (nMovY < 0);
1468  const SCCOL nColAdd = (bUp ? -1 : 1);
1469 
1470  if (bMarked)
1471  nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1472 
1473  if (nTabStartCol != SC_TABSTART_NONE)
1474  {
1475  /* NOTE: If current rCol < nTabStartCol when going down, there
1476  * is no way to detect if the previous Tab wrapped around to
1477  * the next row or if it was a Shift+Tab going backwards. The
1478  * result after a wrap is an odd jump to the next row's
1479  * nTabStartCol, which is logical though and always has been
1480  * the case. Similar for rCol > nTabStartCol when going up.
1481  * Related, it would be nice to limit advancing the position
1482  * within bounds even if another wrap would occur, but again we
1483  * can't tell if previously Tab or Shift+Tab was used, so we
1484  * don't know if it would be nTabStartCol to nEndCol (for Tab)
1485  * or nStartCol to nTabStartCol (for Shift+Tab). */
1486 
1487  // Continue moving horizontally.
1488  nMovX = nColAdd;
1489  nCol = nTabStartCol;
1490  break; // do
1491  }
1492 
1493  while ( SkipRow( nCol, nRow, nMovY, rMark, bUp, nEndRow, bMarked, bSheetProtected ))
1494  ;
1495 
1496  sal_uInt16 nWrap = 0;
1497  while ( nRow < nStartRow || nRow > nEndRow )
1498  {
1499  nCol += nColAdd;
1500 
1501  while (nStartCol <= nCol && nCol <= nEndCol && ValidCol(nCol) && ColHidden(nCol))
1502  nCol += nColAdd; // skip hidden cols
1503 
1504  if (nCol < nStartCol)
1505  {
1506  nCol = nEndCol;
1507 
1508  if (++nWrap >= 2)
1509  return;
1510  }
1511  else if (nCol > nEndCol)
1512  {
1513  nCol = nStartCol;
1514 
1515  if (++nWrap >= 2)
1516  return;
1517  }
1518  if (nRow < nStartRow)
1519  nRow = nEndRow;
1520  else if (nRow > nEndRow)
1521  nRow = nStartRow;
1522 
1523  if (bMarked)
1524  nRow = rMark.GetNextMarked( nCol, nRow, bUp );
1525 
1526  while ( SkipRow( nCol, nRow, nMovY, rMark, bUp, nEndRow, bMarked, bSheetProtected ))
1527  ;
1528  }
1529  } while (false);
1530  }
1531 
1532  if ( nMovX && ( bMarked || bUnprotected ) )
1533  {
1534  // wrap initial skip counting:
1535  if (nCol < nStartCol)
1536  {
1537  nCol = nEndCol;
1538  --nRow;
1539  if (nRow < nStartRow)
1540  nRow = nEndRow;
1541  }
1542  if (nCol > nEndCol)
1543  {
1544  nCol = nStartCol;
1545  ++nRow;
1546  if (nRow > nEndRow)
1547  nRow = nStartRow;
1548  }
1549 
1550  if ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) )
1551  {
1552  const SCCOL nColCount = nEndCol - nStartCol + 1;
1553  std::unique_ptr<SCROW[]> pNextRows( new SCROW[nColCount]);
1554  const SCCOL nLastCol = aCol.size() - 1;
1555  const bool bUp = (nMovX < 0); // Moving left also means moving up in rows.
1556  const SCROW nRowAdd = (bUp ? -1 : 1);
1557  sal_uInt16 nWrap = 0;
1558 
1559  if (bUp)
1560  {
1561  for (SCCOL i = 0; i < nColCount; ++i)
1562  pNextRows[i] = (i + nStartCol > nCol) ? (nRow + nRowAdd) : nRow;
1563  }
1564  else
1565  {
1566  for (SCCOL i = 0; i < nColCount; ++i)
1567  pNextRows[i] = (i + nStartCol < nCol) ? (nRow + nRowAdd) : nRow;
1568  }
1569  do
1570  {
1571  SCROW nNextRow = pNextRows[nCol - nStartCol] + nRowAdd;
1572  if ( bMarked )
1573  nNextRow = rMark.GetNextMarked( nCol, nNextRow, bUp );
1574  if ( bUnprotected )
1575  nNextRow = ( nCol <= nLastCol ) ? aCol[nCol].GetNextUnprotected( nNextRow, bUp ) :
1576  aDefaultColAttrArray.GetNextUnprotected( nNextRow, bUp );
1577  pNextRows[nCol - nStartCol] = nNextRow;
1578 
1579  if (bUp)
1580  {
1581  SCROW nMaxRow = nStartRow - 1;
1582  for (SCCOL i = 0; i < nColCount; ++i)
1583  {
1584  if (pNextRows[i] >= nMaxRow) // when two equal the right one
1585  {
1586  nMaxRow = pNextRows[i];
1587  nCol = i + nStartCol;
1588  }
1589  }
1590  nRow = nMaxRow;
1591 
1592  if ( nRow < nStartRow )
1593  {
1594  if (++nWrap >= 2)
1595  return;
1596  nCol = nEndCol;
1597  nRow = nEndRow;
1598  for (SCCOL i = 0; i < nColCount; ++i)
1599  pNextRows[i] = nEndRow; // do it all over again
1600  }
1601  }
1602  else
1603  {
1604  SCROW nMinRow = nEndRow + 1;
1605  for (SCCOL i = 0; i < nColCount; ++i)
1606  {
1607  if (pNextRows[i] < nMinRow) // when two equal the left one
1608  {
1609  nMinRow = pNextRows[i];
1610  nCol = i + nStartCol;
1611  }
1612  }
1613  nRow = nMinRow;
1614 
1615  if ( nRow > nEndRow )
1616  {
1617  if (++nWrap >= 2)
1618  return;
1619  nCol = nStartCol;
1620  nRow = nStartRow;
1621  for (SCCOL i = 0; i < nColCount; ++i)
1622  pNextRows[i] = nStartRow; // do it all over again
1623  }
1624  }
1625  }
1626  while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1627  }
1628  }
1629 
1630  if (ValidColRow(nCol,nRow))
1631  {
1632  rCol = nCol;
1633  rRow = nRow;
1634  }
1635 }
1636 
1637 bool ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark ) const
1638 {
1639  ++rRow; // next row
1640 
1641  while ( rCol < aCol.size() )
1642  {
1643  ScMarkArray aArray( rMark.GetMarkArray( rCol ) );
1644  while ( rRow <= pDocument->MaxRow() )
1645  {
1646  SCROW nStart = aArray.GetNextMarked( rRow, false );
1647  if ( nStart <= pDocument->MaxRow() )
1648  {
1649  SCROW nEnd = aArray.GetMarkEnd( nStart, false );
1650 
1651  const sc::CellStoreType& rCells = aCol[rCol].maCells;
1652  std::pair<sc::CellStoreType::const_iterator,size_t> aPos = rCells.position(nStart);
1653  sc::CellStoreType::const_iterator it = aPos.first;
1654  SCROW nTestRow = nStart;
1655  if (it->type == sc::element_type_empty)
1656  {
1657  // Skip the empty block.
1658  nTestRow += it->size - aPos.second;
1659  ++it;
1660  if (it == rCells.end())
1661  {
1662  // No more block. Move on to the next column.
1663  rRow = pDocument->MaxRow() + 1;
1664  continue;
1665  }
1666  }
1667 
1668  if (nTestRow <= nEnd)
1669  {
1670  // Cell found.
1671  rRow = nTestRow;
1672  return true;
1673  }
1674 
1675  rRow = nEnd + 1; // Search for next selected range
1676  }
1677  else
1678  rRow = pDocument->MaxRow() + 1; // End of column
1679  }
1680  rRow = 0;
1681  ++rCol; // test next column
1682  }
1683 
1684  // Though searched only the allocated columns, it is equivalent to a search till pDocument->MaxCol().
1685  rCol = pDocument->MaxCol() + 1;
1686  return false; // Through all columns
1687 }
1688 
1689 void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1690  SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
1691  SCCOL nDx, SCROW nDy, SCTAB nDz, bool bUpdateNoteCaptionPos )
1692 {
1693  if ( !(nTab >= nTab1 && nTab <= nTab2 && nDz == 0) ) // only within the table
1694  return;
1695 
1696  ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
1697  if ( eUpdateRefMode != URM_COPY && pDrawLayer )
1698  {
1699  if ( eUpdateRefMode == URM_MOVE )
1700  { // source range
1701  nCol1 = sal::static_int_cast<SCCOL>( nCol1 - nDx );
1702  nRow1 = sal::static_int_cast<SCROW>( nRow1 - nDy );
1703  nCol2 = sal::static_int_cast<SCCOL>( nCol2 - nDx );
1704  nRow2 = sal::static_int_cast<SCROW>( nRow2 - nDy );
1705  }
1706  pDrawLayer->MoveArea( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy,
1707  (eUpdateRefMode == URM_INSDEL), bUpdateNoteCaptionPos );
1708  }
1709 }
1710 
1712  sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, bool bIncludeDraw, bool bUpdateNoteCaptionPos )
1713 {
1714  bool bUpdated = false;
1715  SCCOL i;
1716  SCCOL iMax;
1717  if (rCxt.meMode == URM_COPY )
1718  {
1719  i = rCxt.maRange.aStart.Col();
1720  iMax = rCxt.maRange.aEnd.Col();
1721  }
1722  else
1723  {
1724  i = 0;
1725  iMax = pDocument->MaxCol();
1726  }
1727 
1728  UpdateRefMode eUpdateRefMode = rCxt.meMode;
1729  SCCOL nDx = rCxt.mnColDelta;
1730  SCROW nDy = rCxt.mnRowDelta;
1731  SCTAB nDz = rCxt.mnTabDelta;
1732  SCCOL nCol1 = rCxt.maRange.aStart.Col(), nCol2 = rCxt.maRange.aEnd.Col();
1733  SCROW nRow1 = rCxt.maRange.aStart.Row(), nRow2 = rCxt.maRange.aEnd.Row();
1734  SCTAB nTab1 = rCxt.maRange.aStart.Tab(), nTab2 = rCxt.maRange.aEnd.Tab();
1735 
1736  // Named expressions need to be updated before formulas accessing them.
1737  if (mpRangeName)
1738  mpRangeName->UpdateReference(rCxt, nTab);
1739 
1740  for ( ; i<=iMax; i++)
1741  bUpdated |= CreateColumnIfNotExists(i).UpdateReference(rCxt, pUndoDoc);
1742 
1743  if ( bIncludeDraw )
1744  UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
1745 
1746  if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // print ranges: only within the table
1747  {
1748  SCTAB nSTab = nTab;
1749  SCTAB nETab = nTab;
1750  SCCOL nSCol = 0;
1751  SCROW nSRow = 0;
1752  SCCOL nECol = 0;
1753  SCROW nERow = 0;
1754  bool bRecalcPages = false;
1755 
1756  for ( auto& rPrintRange : aPrintRanges )
1757  {
1758  nSCol = rPrintRange.aStart.Col();
1759  nSRow = rPrintRange.aStart.Row();
1760  nECol = rPrintRange.aEnd.Col();
1761  nERow = rPrintRange.aEnd.Row();
1762 
1763  // do not try to modify sheet index of print range
1764  if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1765  nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1766  nDx,nDy,0,
1767  nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1768  {
1769  rPrintRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1770  bRecalcPages = true;
1771  }
1772  }
1773 
1774  if ( pRepeatColRange )
1775  {
1776  nSCol = pRepeatColRange->aStart.Col();
1777  nSRow = pRepeatColRange->aStart.Row();
1778  nECol = pRepeatColRange->aEnd.Col();
1779  nERow = pRepeatColRange->aEnd.Row();
1780 
1781  // do not try to modify sheet index of repeat range
1782  if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1783  nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1784  nDx,nDy,0,
1785  nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1786  {
1787  *pRepeatColRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1788  bRecalcPages = true;
1789  nRepeatStartX = nSCol; // for UpdatePageBreaks
1790  nRepeatEndX = nECol;
1791  }
1792  }
1793 
1794  if ( pRepeatRowRange )
1795  {
1796  nSCol = pRepeatRowRange->aStart.Col();
1797  nSRow = pRepeatRowRange->aStart.Row();
1798  nECol = pRepeatRowRange->aEnd.Col();
1799  nERow = pRepeatRowRange->aEnd.Row();
1800 
1801  // do not try to modify sheet index of repeat range
1802  if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1803  nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1804  nDx,nDy,0,
1805  nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1806  {
1807  *pRepeatRowRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1808  bRecalcPages = true;
1809  nRepeatStartY = nSRow; // for UpdatePageBreaks
1810  nRepeatEndY = nERow;
1811  }
1812  }
1813 
1814  // updating print ranges is not necessary with multiple print ranges
1815  if ( bRecalcPages && GetPrintRangeCount() <= 1 )
1816  {
1817  UpdatePageBreaks(nullptr);
1818 
1820  }
1821  }
1822 
1823  if (bUpdated)
1824  SetStreamValid(false);
1825 
1826  if(mpCondFormatList)
1827  mpCondFormatList->UpdateReference(rCxt);
1828 
1829  if (pTabProtection)
1830  pTabProtection->updateReference( eUpdateRefMode, pDocument, rCxt.maRange, nDx, nDy, nDz);
1831 }
1832 
1833 void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
1834  ScDocument* pUndoDoc )
1835 {
1836  for (auto const & rpCol : aCol)
1837  rpCol->UpdateTranspose( rSource, rDest, pUndoDoc );
1838 }
1839 
1840 void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
1841 {
1842  for (auto const & rpCol : aCol)
1843  rpCol->UpdateGrow( rArea, nGrowX, nGrowY );
1844 }
1845 
1847 {
1848  // Store the old tab number in sc::UpdatedRangeNames for
1849  // ScTokenArray::AdjustReferenceOnInsertedTab() to check with
1850  // isNameModified()
1851  if (mpRangeName)
1852  mpRangeName->UpdateInsertTab(rCxt, nTab);
1853 
1854  if (nTab >= rCxt.mnInsertPos)
1855  {
1856  nTab += rCxt.mnSheets;
1857  if (pDBDataNoName)
1858  pDBDataNoName->UpdateMoveTab(nTab - 1 ,nTab);
1859  }
1860 
1861  if (mpCondFormatList)
1862  mpCondFormatList->UpdateInsertTab(rCxt);
1863 
1864  if (pTabProtection)
1865  pTabProtection->updateReference( URM_INSDEL, pDocument,
1866  ScRange( 0, 0, rCxt.mnInsertPos, pDocument->MaxCol(), pDocument->MaxRow(), MAXTAB),
1867  0, 0, rCxt.mnSheets);
1868 
1869  for (SCCOL i=0; i < aCol.size(); i++)
1870  aCol[i].UpdateInsertTab(rCxt);
1871 
1872  SetStreamValid(false);
1873 }
1874 
1876 {
1877  // Store the old tab number in sc::UpdatedRangeNames for
1878  // ScTokenArray::AdjustReferenceOnDeletedTab() to check with
1879  // isNameModified()
1880  if (mpRangeName)
1881  mpRangeName->UpdateDeleteTab(rCxt, nTab);
1882 
1883  if (nTab > rCxt.mnDeletePos)
1884  {
1885  nTab -= rCxt.mnSheets;
1886  if (pDBDataNoName)
1887  pDBDataNoName->UpdateMoveTab(nTab + 1,nTab);
1888  }
1889 
1890  if (mpCondFormatList)
1891  mpCondFormatList->UpdateDeleteTab(rCxt);
1892 
1893  if (pTabProtection)
1894  pTabProtection->updateReference( URM_INSDEL, pDocument,
1895  ScRange( 0, 0, rCxt.mnDeletePos, pDocument->MaxCol(), pDocument->MaxRow(), MAXTAB),
1896  0, 0, -rCxt.mnSheets);
1897 
1898  for (SCCOL i = 0; i < aCol.size(); ++i)
1899  aCol[i].UpdateDeleteTab(rCxt);
1900 
1901  SetStreamValid(false);
1902 }
1903 
1905  sc::RefUpdateMoveTabContext& rCxt, SCTAB nTabNo, ScProgress* pProgress )
1906 {
1907  nTab = nTabNo;
1908  if (mpRangeName)
1909  mpRangeName->UpdateMoveTab(rCxt, nTab);
1910 
1911  if (pDBDataNoName)
1912  pDBDataNoName->UpdateMoveTab(rCxt.mnOldPos, rCxt.mnNewPos);
1913 
1914  if(mpCondFormatList)
1915  mpCondFormatList->UpdateMoveTab(rCxt);
1916 
1917  if (pTabProtection)
1918  pTabProtection->updateReference( URM_REORDER, pDocument,
1919  ScRange( 0, 0, rCxt.mnOldPos, pDocument->MaxCol(), pDocument->MaxRow(), MAXTAB),
1920  0, 0, rCxt.mnNewPos - rCxt.mnOldPos);
1921 
1922  for ( SCCOL i=0; i < aCol.size(); i++ )
1923  {
1924  aCol[i].UpdateMoveTab(rCxt, nTabNo);
1925  if (pProgress)
1926  pProgress->SetState(pProgress->GetState() + aCol[i].GetCodeCount());
1927  }
1928 
1929  SetStreamValid(false);
1930 }
1931 
1932 void ScTable::UpdateCompile( bool bForceIfNameInUse )
1933 {
1934  for (SCCOL i=0; i < aCol.size(); i++)
1935  {
1936  aCol[i].UpdateCompile( bForceIfNameInUse );
1937  }
1938 }
1939 
1941 {
1942  nTab = nNewTab;
1943  for (SCCOL i=0; i < aCol.size(); i++)
1944  aCol[i].SetTabNo(nNewTab);
1945 }
1946 
1947 void ScTable::FindRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1948  sc::UpdatedRangeNames& rIndexes) const
1949 {
1950  for (SCCOL i = nCol1; i <= nCol2 && IsColValid( i ); i++)
1951  aCol[i].FindRangeNamesInUse(nRow1, nRow2, rIndexes);
1952 }
1953 
1955  SCCOL /* nStartCol */, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
1956 {
1957  if ( !mpColFlags || !pRowFlags )
1958  {
1959  OSL_FAIL("ExtendPrintArea: No ColInfo or RowInfo");
1960  return;
1961  }
1962 
1963  Point aPix1000 = pDev->LogicToPixel(Point(1000,1000), MapMode(MapUnit::MapTwip));
1964  double nPPTX = aPix1000.X() / 1000.0;
1965  double nPPTY = aPix1000.Y() / 1000.0;
1966 
1967  // First, mark those columns that we need to skip i.e. hidden and empty columns.
1968 
1969  ScFlatBoolColSegments aSkipCols(pDocument->MaxCol());
1970  aSkipCols.setFalse(0, pDocument->MaxCol());
1971  for (SCCOL i = 0; i <= pDocument->MaxCol(); ++i)
1972  {
1973  SCCOL nLastCol = i;
1974  if (ColHidden(i, nullptr, &nLastCol))
1975  {
1976  // Columns are hidden in this range.
1977  aSkipCols.setTrue(i, nLastCol);
1978  }
1979  else
1980  {
1981  // These columns are visible. Check for empty columns.
1982  for (SCCOL j = i; j <= nLastCol; ++j)
1983  {
1984  if ( j >= aCol.size() )
1985  {
1986  aSkipCols.setTrue( j, pDocument->MaxCol() );
1987  break;
1988  }
1989  if (aCol[j].GetCellCount() == 0)
1990  // empty
1991  aSkipCols.setTrue(j,j);
1992  }
1993  }
1994  i = nLastCol;
1995  }
1996 
1998  for (SCCOL nCol = rEndCol; nCol >= 0; --nCol)
1999  {
2000  if (!aSkipCols.getRangeData(nCol, aColData))
2001  // Failed to get the data. This should never happen!
2002  return;
2003 
2004  if (aColData.mbValue)
2005  {
2006  // Skip these columns.
2007  nCol = aColData.mnCol1; // move toward 0.
2008  continue;
2009  }
2010 
2011  // These are visible and non-empty columns.
2012  for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= aColData.mnCol1; --nDataCol)
2013  {
2014  SCCOL nPrintCol = nDataCol;
2015  VisibleDataCellIterator aIter(pDocument, *mpHiddenRows, aCol[nDataCol]);
2016  ScRefCellValue aCell = aIter.reset(nStartRow);
2017  if (aCell.isEmpty())
2018  // No visible cells found in this column. Skip it.
2019  continue;
2020 
2021  while (!aCell.isEmpty())
2022  {
2023  SCCOL nNewCol = nDataCol;
2024  SCROW nRow = aIter.getRow();
2025  if (nRow > nEndRow)
2026  // Went past the last row position. Bail out.
2027  break;
2028 
2029  MaybeAddExtraColumn(nNewCol, nRow, pDev, nPPTX, nPPTY);
2030  if (nNewCol > nPrintCol)
2031  nPrintCol = nNewCol;
2032  aCell = aIter.next();
2033  }
2034 
2035  if (nPrintCol > rEndCol)
2036  // Make sure we don't shrink the print area.
2037  rEndCol = nPrintCol;
2038  }
2039  nCol = aColData.mnCol1; // move toward 0.
2040  }
2041 }
2042 
2043 void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY)
2044 {
2045  // tdf#128873 we do not need to calculate text width (heavy operation)
2046  // when we for sure know that an additional column will not be added
2047  if (GetAllocatedColumnsCount() > rCol + 1)
2048  {
2049  ScRefCellValue aNextCell = aCol[rCol + 1].GetCellValue(nRow);
2050  if (!aNextCell.isEmpty())
2051  {
2052  // return rCol as is
2053  return;
2054  }
2055  }
2056 
2057  ScColumn& rColumn = aCol[rCol];
2058  ScRefCellValue aCell = rColumn.GetCellValue(nRow);
2059  if (!aCell.hasString())
2060  return;
2061 
2062  long nPixel = rColumn.GetTextWidth(nRow);
2063 
2064  // Width already calculated in Idle-Handler ?
2065  if ( TEXTWIDTH_DIRTY == nPixel )
2066  {
2067  ScNeededSizeOptions aOptions;
2068  aOptions.bTotalSize = true;
2069  aOptions.bFormula = false; //TODO: pass as parameter
2070  aOptions.bSkipMerged = false;
2071 
2072  Fraction aZoom(1,1);
2073  nPixel = rColumn.GetNeededSize(
2074  nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions, nullptr );
2075 
2076  rColumn.SetTextWidth(nRow, static_cast<sal_uInt16>(nPixel));
2077  }
2078 
2079  long nTwips = static_cast<long>(nPixel / nPPTX);
2080  long nDocW = GetColWidth( rCol );
2081 
2082  long nMissing = nTwips - nDocW;
2083  if ( nMissing > 0 )
2084  {
2085  // look at alignment
2086 
2087  const ScPatternAttr* pPattern = GetPattern( rCol, nRow );
2088  const SfxItemSet* pCondSet = pDocument->GetCondResult( rCol, nRow, nTab );
2089 
2090  SvxCellHorJustify eHorJust =
2091  pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet ).GetValue();
2092  if ( eHorJust == SvxCellHorJustify::Center )
2093  nMissing /= 2; // distributed into both directions
2094  else
2095  {
2096  // STANDARD is LEFT (only text is handled here)
2097  bool bRight = ( eHorJust == SvxCellHorJustify::Right );
2098  if ( IsLayoutRTL() )
2099  bRight = !bRight;
2100  if ( bRight )
2101  nMissing = 0; // extended only to the left (logical)
2102  }
2103  }
2104 
2105  SCCOL nNewCol = rCol;
2106  while (nMissing > 0 && nNewCol < pDocument->MaxCol())
2107  {
2108  auto nNextCol = nNewCol + 1;
2109  bool bNextEmpty = true;
2110  if (GetAllocatedColumnsCount() > nNextCol)
2111  {
2112  ScRefCellValue aNextCell = aCol[nNextCol].GetCellValue(nRow);
2113  bNextEmpty = aNextCell.isEmpty();
2114  }
2115  if (!bNextEmpty)
2116  {
2117  // Cell content in a next column ends display of this string.
2118  nMissing = 0;
2119  }
2120  else
2121  nMissing -= GetColWidth(++nNewCol);
2122  }
2123  rCol = nNewCol;
2124 }
2125 
2126 namespace {
2127 
2128 class SetTableIndex
2129 {
2130  SCTAB mnTab;
2131 public:
2132  explicit SetTableIndex(SCTAB nTab) : mnTab(nTab) {}
2133 
2134  void operator() (ScRange& rRange) const
2135  {
2136  rRange.aStart.SetTab(mnTab);
2137  rRange.aEnd.SetTab(mnTab);
2138  }
2139 };
2140 
2141 }
2142 
2144 {
2145  // The table index shouldn't be used when the print range is used, but
2146  // just in case set the correct table index.
2147 
2148  aPrintRanges = rTable.aPrintRanges;
2149  ::std::for_each(aPrintRanges.begin(), aPrintRanges.end(), SetTableIndex(nTab));
2150 
2152 
2153  pRepeatColRange.reset();
2154  if (rTable.pRepeatColRange)
2155  {
2156  pRepeatColRange.reset(new ScRange(*rTable.pRepeatColRange));
2157  pRepeatColRange->aStart.SetTab(nTab);
2158  pRepeatColRange->aEnd.SetTab(nTab);
2159  }
2160 
2161  pRepeatRowRange.reset();
2162  if (rTable.pRepeatRowRange)
2163  {
2164  pRepeatRowRange.reset(new ScRange(*rTable.pRepeatRowRange));
2165  pRepeatRowRange->aStart.SetTab(nTab);
2166  pRepeatRowRange->aEnd.SetTab(nTab);
2167  }
2168 }
2169 
2170 void ScTable::SetRepeatColRange( std::unique_ptr<ScRange> pNew )
2171 {
2172  pRepeatColRange = std::move(pNew);
2173 
2174  SetStreamValid(false);
2175 
2177 }
2178 
2179 void ScTable::SetRepeatRowRange( std::unique_ptr<ScRange> pNew )
2180 {
2181  pRepeatRowRange = std::move(pNew);
2182 
2183  SetStreamValid(false);
2184 
2186 }
2187 
2189 {
2190  aPrintRanges.clear();
2191  bPrintEntireSheet = false;
2192 
2193  SetStreamValid(false);
2194 
2195  InvalidatePageBreaks(); // #i117952# forget page breaks for an old print range
2196 }
2197 
2198 void ScTable::AddPrintRange( const ScRange& rNew )
2199 {
2200  bPrintEntireSheet = false;
2201  if( aPrintRanges.size() < 0xFFFF )
2202  aPrintRanges.push_back( rNew );
2203 
2204  SetStreamValid(false);
2205 
2207 }
2208 
2210 {
2211  if( !IsPrintEntireSheet() )
2212  {
2213  ClearPrintRanges();
2214  bPrintEntireSheet = true;
2215  }
2216 }
2217 
2218 const ScRange* ScTable::GetPrintRange(sal_uInt16 nPos) const
2219 {
2220  return (nPos < GetPrintRangeCount()) ? &aPrintRanges[ nPos ] : nullptr;
2221 }
2222 
2224 {
2226  rSaveTab.SetRepeat( pRepeatColRange.get(), pRepeatRowRange.get() );
2227 }
2228 
2230 {
2231  aPrintRanges = rSaveTab.GetPrintRanges();
2232  bPrintEntireSheet = rSaveTab.IsEntireSheet();
2233  auto p = rSaveTab.GetRepeatCol();
2234  SetRepeatColRange( std::unique_ptr<ScRange>(p ? new ScRange(*p) : nullptr) );
2235  p = rSaveTab.GetRepeatRow();
2236  SetRepeatRowRange( std::unique_ptr<ScRange>(p ? new ScRange(*p) : nullptr) );
2237 
2238  InvalidatePageBreaks(); // #i117952# forget page breaks for an old print range
2239  UpdatePageBreaks(nullptr);
2240 }
2241 
2243  mpDocument(pDoc),
2244  mrRowSegs(rRowSegs),
2245  mrColumn(rColumn),
2246  mnCurRow(ROW_NOT_FOUND),
2247  mnUBound(ROW_NOT_FOUND)
2248 {
2249 }
2250 
2252 {
2253 }
2254 
2256 {
2257  if (nRow > mpDocument->MaxRow())
2258  {
2259  mnCurRow = ROW_NOT_FOUND;
2260  return ScRefCellValue();
2261  }
2262 
2264  if (!mrRowSegs.getRangeData(nRow, aData))
2265  {
2266  mnCurRow = ROW_NOT_FOUND;
2267  return ScRefCellValue();
2268  }
2269 
2270  if (!aData.mbValue)
2271  {
2272  // specified row is visible. Take it.
2273  mnCurRow = nRow;
2274  mnUBound = aData.mnRow2;
2275  }
2276  else
2277  {
2278  // specified row is not-visible. The first visible row is the start of
2279  // the next segment.
2280  mnCurRow = aData.mnRow2 + 1;
2281  mnUBound = mnCurRow; // get range data on the next iteration.
2282  if (mnCurRow > mpDocument->MaxRow())
2283  {
2284  // Make sure the row doesn't exceed our current limit.
2285  mnCurRow = ROW_NOT_FOUND;
2286  return ScRefCellValue();
2287  }
2288  }
2289 
2290  maCell = mrColumn.GetCellValue(mnCurRow);
2291  if (!maCell.isEmpty())
2292  // First visible cell found.
2293  return maCell;
2294 
2295  // Find a first visible cell below this row (if any).
2296  return next();
2297 }
2298 
2300 {
2301  if (mnCurRow == ROW_NOT_FOUND)
2302  return ScRefCellValue();
2303 
2304  while (mrColumn.GetNextDataPos(mnCurRow))
2305  {
2306  if (mnCurRow > mnUBound)
2307  {
2308  // We don't know the visibility of this row range. Query it.
2310  if (!mrRowSegs.getRangeData(mnCurRow, aData))
2311  {
2312  mnCurRow = ROW_NOT_FOUND;
2313  return ScRefCellValue();
2314  }
2315 
2316  if (aData.mbValue)
2317  {
2318  // This row is invisible. Skip to the last invisible row and
2319  // try again.
2320  mnCurRow = mnUBound = aData.mnRow2;
2321  continue;
2322  }
2323 
2324  // This row is visible.
2325  mnUBound = aData.mnRow2;
2326  }
2327 
2328  maCell = mrColumn.GetCellValue(mnCurRow);
2329  if (!maCell.isEmpty())
2330  return maCell;
2331  }
2332 
2333  mnCurRow = ROW_NOT_FOUND;
2334  return ScRefCellValue();
2335 }
2336 
2337 void ScTable::SetAnonymousDBData(std::unique_ptr<ScDBData> pDBData)
2338 {
2339  pDBDataNoName = std::move(pDBData);
2340 }
2341 
2342 sal_uLong ScTable::AddCondFormat( std::unique_ptr<ScConditionalFormat> pNew )
2343 {
2344  if(!mpCondFormatList)
2346 
2347  sal_uInt32 nMax = mpCondFormatList->getMaxKey();
2348 
2349  pNew->SetKey(nMax+1);
2350  mpCondFormatList->InsertNew(std::move(pNew));
2351 
2352  return nMax + 1;
2353 }
2354 
2356 {
2357  if ( !IsColValid( nCol ) )
2358  return SvtScriptType::NONE;
2359 
2360  return aCol[nCol].GetScriptType(nRow);
2361 }
2362 
2364 {
2365  if (!ValidCol(nCol))
2366  return;
2367 
2368  aCol[nCol].SetScriptType(nRow, nType);
2369 }
2370 
2372  sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2373 {
2374  if ( !IsColValid( nCol ) )
2375  return SvtScriptType::NONE;
2376 
2377  sc::CellStoreType::iterator itr = aCol[nCol].maCells.begin();
2378  return aCol[nCol].GetRangeScriptType(rBlockPos.miCellTextAttrPos, nRow1, nRow2, itr);
2379 }
2380 
2381 size_t ScTable::GetFormulaHash( SCCOL nCol, SCROW nRow ) const
2382 {
2383  if ( !IsColValid( nCol ) )
2384  return 0;
2385 
2386  return aCol[nCol].GetFormulaHash(nRow);
2387 }
2388 
2390 {
2391  if ( !IsColValid( nCol ) )
2392  return FormulaVectorUnknown;
2393 
2394  return aCol[nCol].GetFormulaVectorState(nRow);
2395 }
2396 
2398 {
2399  if ( !ValidCol( nCol ) || !ValidRow( nRow ) )
2400  return formula::FormulaTokenRef();
2401  if ( nCol >= aCol.size() )
2402  // Return a value of 0.0 if column not exists
2404  return aCol[nCol].ResolveStaticReference(nRow);
2405 }
2406 
2408 {
2409  if (nCol2 < nCol1 || nRow2 < nRow1)
2410  return formula::FormulaTokenRef();
2411 
2412  if ( !ValidCol( nCol1 ) || !ValidCol( nCol2 ) || !ValidRow( nRow1 ) || !ValidRow( nRow2 ) )
2413  return formula::FormulaTokenRef();
2414 
2415  SCCOL nMaxCol;
2416  if ( nCol2 >= aCol.size() )
2417  nMaxCol = aCol.size() - 1;
2418  else
2419  nMaxCol = nCol2;
2420 
2421  ScMatrixRef pMat(new ScMatrix(nCol2-nCol1+1, nRow2-nRow1+1, 0.0));
2422  for (SCCOL nCol = nCol1; nCol <= nMaxCol; ++nCol)
2423  {
2424  if (!aCol[nCol].ResolveStaticReference(*pMat, nCol2-nCol1, nRow1, nRow2))
2425  // Column contains non-static cell. Failed.
2426  return formula::FormulaTokenRef();
2427  }
2428 
2429  return formula::FormulaTokenRef(new ScMatrixToken(pMat));
2430 }
2431 
2433 {
2434  if (nRow2 < nRow1)
2435  return formula::VectorRefArray();
2436 
2437  if ( !IsColValid( nCol ) || !ValidRow( nRow1 ) || !ValidRow( nRow2 ) )
2438  return formula::VectorRefArray();
2439 
2440  return aCol[nCol].FetchVectorRefArray(nRow1, nRow2);
2441 }
2442 
2443 #ifdef DBG_UTIL
2445 {
2446  assert( nRow2 >= nRow1 );
2447  assert( IsColValid( nCol ) && ValidRow( nRow1 ) && ValidRow( nRow2 ) );
2448  return aCol[nCol].AssertNoInterpretNeeded(nRow1, nRow2);
2449 }
2450 #endif
2451 
2453 {
2454  if (nRow2 < nRow1)
2455  return false;
2456 
2457  if ( !IsColValid( nCol ) || !ValidRow( nRow1 ) || !ValidRow( nRow2 ) )
2458  return false;
2459 
2460  return aCol[nCol].HandleRefArrayForParallelism(nRow1, nRow2, mxGroup);
2461 }
2462 
2464 {
2465  if ( !IsColRowValid( nCol, nRow ) )
2466  return ScRefCellValue();
2467 
2468  return aCol[nCol].GetCellValue(nRow);
2469 }
2470 
2472 {
2473  if ( !IsColRowValid( nCol, nRow ) )
2474  return ScRefCellValue();
2475 
2476  return aCol[nCol].GetCellValue(rBlockPos, nRow);
2477 }
2478 
2480 {
2481  if ( !IsColRowValid( nCol, nRow ) )
2482  return nullptr;
2483 
2484  return aCol[nCol].GetBroadcaster(nRow);
2485 }
2486 
2488  sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 )
2489 {
2490  if ( !IsColValid( nCol ) )
2491  return;
2492 
2493  aCol[nCol].DeleteBroadcasters(rBlockPos, nRow1, nRow2);
2494 }
2495 
2496 void ScTable::FillMatrix( ScMatrix& rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, svl::SharedStringPool* pPool ) const
2497 {
2498  size_t nMatCol = 0;
2499  for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nMatCol)
2500  CreateColumnIfNotExists(nCol).FillMatrix(rMat, nMatCol, nRow1, nRow2, pPool);
2501 }
2502 
2503 void ScTable::InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2504 {
2505  nCol2 = ClampToAllocatedColumns(nCol2);
2506  for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
2507  aCol[nCol].InterpretDirtyCells(nRow1, nRow2);
2508 }
2509 
2510 void ScTable::SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen )
2511 {
2512  if (!ValidCol(nCol))
2513  return;
2514 
2515  aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
2516 }
2517 
2519  SCCOL nColStart, SCCOL nColEnd,
2520  SCROW nRowStart, SCROW nRowEnd,
2521  unsigned nThisThread, unsigned nThreadsTotal)
2522 {
2523  if (!ValidCol(nColStart) || !ValidCol(nColEnd))
2524  return;
2525 
2526  size_t nLen = nRowEnd - nRowStart + 1;
2527  size_t nOffset = 0;
2528  for (SCCOL nCurrCol = nColStart; nCurrCol <= nColEnd; ++nCurrCol)
2529  {
2530  aCol[nCurrCol].CalculateInThread( rContext, nRowStart, nLen, nOffset, nThisThread, nThreadsTotal );
2531  nOffset += nLen;
2532  }
2533 }
2534 
2535 void ScTable::HandleStuffAfterParallelCalculation( SCCOL nColStart, SCCOL nColEnd, SCROW nRow, size_t nLen,
2536  ScInterpreter* pInterpreter)
2537 {
2538  assert(ValidCol(nColStart) && ValidCol(nColEnd));
2539 
2540  for (SCCOL nCurrCol = nColStart; nCurrCol <= nColEnd; ++nCurrCol)
2541  aCol[nCurrCol].HandleStuffAfterParallelCalculation( nRow, nLen, pInterpreter );
2542 }
2543 
2544 #if DUMP_COLUMN_STORAGE
2545 void ScTable::DumpColumnStorage( SCCOL nCol ) const
2546 {
2547  if ( !IsColValid( nCol ) )
2548  return;
2549 
2550  aCol[nCol].DumpColumnStorage();
2551 }
2552 #endif
2553 
2555 {
2556  if ( !IsColRowValid( nCol, nRow ) )
2557  return nullptr;
2558 
2559  return aCol[nCol].GetBroadcaster(nRow);
2560 }
2561 
2563 {
2564  mpCondFormatList->erase(nIndex);
2565 }
2566 
2568 {
2569  mpCondFormatList.reset( pNew );
2570 }
2571 
2573 {
2574  if(!mpCondFormatList)
2576 
2577  return mpCondFormatList.get();
2578 }
2579 
2581 {
2582  return mpCondFormatList.get();
2583 }
2584 
2586 {
2587  ScColContainer::ScColumnVector::const_iterator beginIter;
2588  ScColContainer::ScColumnVector::const_iterator endIter;
2589 
2590  // because the range is inclusive, some code will pass nColEnd<nColBegin to indicate an empty range
2591  if (nColEnd < nColBegin)
2592  {
2593  beginIter = aCol.end();
2594  endIter = aCol.end();
2595  }
2596  else if (nColBegin >= aCol.size())
2597  {
2598  beginIter = aCol.end();
2599  endIter = aCol.end();
2600  }
2601  else
2602  {
2603  // clamp end of range to available columns
2604  if (nColEnd >= aCol.size())
2605  nColEnd = aCol.size() - 1;
2606  beginIter = aCol.begin() + nColBegin;
2607  endIter = aCol.begin() + nColEnd + 1;
2608  }
2610 }
2611 
2612 // out-of-line the cold part of the CreateColumnIfNotExists function
2614 {
2615  // When doing multi-threaded load of, e.g. XLS files, we can hit this, which calls
2616  // into SfxItemPool::Put, in parallel with other code that calls into SfxItemPool::Put,
2617  // which is bad since that code is not thread-safe.
2618  SolarMutexGuard aGuard;
2619  const SCCOL aOldColSize = aCol.size();
2620  aCol.resize( static_cast< size_t >( nScCol + 1 ) );
2621  for (SCCOL i = aOldColSize; i <= nScCol; i++)
2622  aCol[i].Init( i, nTab, pDocument, false );
2623 }
2624 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
formula::FormulaTokenRef ResolveStaticReference(SCCOL nCol, SCROW nRow)
Definition: table1.cxx:2397
static bool IsSystemRTL()
Definition: global.cxx:853
SC_DLLPUBLIC bool GetPrintArea(SCTAB nTab, SCCOL &rEndCol, SCROW &rEndRow, bool bNotes=true) const
Definition: documen2.cxx:573
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:49
sal_Int64 GetHashCode() const
Definition: table1.cxx:340
sal_uLong GetWeightedCount() const
Definition: column2.cxx:3577
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:189
sal_Int32 nIndex
ScAddress aStart
Definition: address.hxx:500
bool bVisible
void SetTextWidth(SCROW nRow, sal_uInt16 nWidth)
Definition: column2.cxx:2045
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:3502
~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:2562
void DestroySortCollator()
Definition: table3.cxx:633
std::unique_ptr< ScFlatUInt16RowSegments > mpRowHeights
Definition: table.hxx:180
SCROW Row() const
Definition: address.hxx:262
const char aData[]
const ScRange * GetPrintRange(sal_uInt16 nPos) const
Definition: table1.cxx:2218
void UpdateGrow(const ScRange &rArea, SCCOL nGrowX, SCROW nGrowY)
Definition: table1.cxx:1840
SCCOL FindNextVisibleColWithContent(SCCOL nCol, bool bRight, SCROW nRow) const
Definition: table1.cxx:1194
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:3094
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:2503
void SetScriptType(SCCOL nCol, SCROW nRow, SvtScriptType nType)
Definition: table1.cxx:2363
ScScenarioFlags
Definition: global.hxx:236
sal_uInt16 GetPrintRangeCount() const
Definition: table.hxx:761
void SetPrintEntireSheet()
Marks the specified sheet to be printed completely.
Definition: table1.cxx:2209
double ny
SCCOL size() const
sal_uIntPtr sal_uLong
Context for reference update during shifting, moving or copying of cell ranges.
SvtScriptType GetScriptType(SCCOL nCol, SCROW nRow) const
Definition: table1.cxx:2355
SCCOL FindNextVisibleCol(SCCOL nCol, bool bRight) const
Definition: table1.cxx:1170
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:2255
SCROW getRow() const
Get the current row position.
Definition: table.hxx:1300
void SetFormulaResults(SCCOL nCol, SCROW nRow, const double *pResults, size_t nLen)
Definition: table1.cxx:2510
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:2389
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:1711
bool bVisible
Definition: table.hxx:234
constexpr::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
RowHeightsArray & getHeightArray()
void SetLoadingRTL(bool bSet)
Definition: table1.cxx:386
ScDocument * pDocument
Definition: table.hxx:202
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:5181
void LimitChartArea(SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow) const
Definition: table1.cxx:1148
VisibleDataCellIterator(const ScDocument *pDoc, ScFlatBoolRowSegments &rRowSegs, ScColumn &rColumn)
Definition: table1.cxx:2242
std::unique_ptr< ScRangeName > mpRangeName
Definition: table.hxx:223
bool IsAdjustHeightLocked() const
Definition: document.hxx:1538
void MoveArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCCOL nDx, SCROW nDy, bool bInsDel, bool bUpdateNoteCaptionPos)
Definition: drwlayer.cxx:1268
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:2043
void SetRepeatColRange(std::unique_ptr< ScRange > pNew)
Definition: table1.cxx:2170
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:2223
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:2518
void RepaintRange(const ScRange &rRange)
Definition: documen8.cxx:687
#define STD_COL_WIDTH
Definition: global.hxx:93
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:1689
ScRefCellValue GetCellValue(SCROW nRow) const
Definition: column.cxx:732
void resize(const size_t aNewSize)
bool ValidNextPos(SCCOL nCol, SCROW nRow, const ScMarkData &rMark, bool bMarked, bool bUnprotected) const
Definition: table1.cxx:1319
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:876
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:2337
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
This is a rather odd datastructure.
Definition: markarr.hxx:43
void FillMatrix(ScMatrix &rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, svl::SharedStringPool *pPool) const
Definition: table1.cxx:2496
bool IsMultiMarked() const
Definition: markdata.hxx:83
bool hasString() const
Definition: cellvalue.cxx:617
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
void ClearPrintRanges()
Removes all print ranges.
Definition: table1.cxx:2188
#define STD_EXTRA_WIDTH
Definition: global.hxx:94
SC_DLLPUBLIC bool IsDocVisible() const
Definition: document.hxx:1555
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:2535
ScLinkMode
Definition: global.hxx:225
#define HMM_PER_TWIPS
Definition: global.hxx:91
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:2299
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:1257
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:1355
std::unique_ptr< ScBitMaskCompressedArray< SCCOL, CRFlags > > mpColFlags
Definition: table.hxx:182
void SetRepeatRowRange(std::unique_ptr< ScRange > pNew)
Definition: table1.cxx:2179
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:70
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
bool SetRowHeightRange(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight, double nPPTY)
Definition: table2.cxx:3041
constexpr double nPPTX
void SetRepeat(const ScRange *pCol, const ScRange *pRow)
Definition: prnsave.cxx:45
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:587
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:1062
void SetPageSize(sal_uInt16 nPageNo, const Size &rSize, bool bUpdateNoteCaptionPos)
Definition: drwlayer.cxx:566
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:875
bool ColHidden(SCCOL nCol, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: table5.cxx:561
bool IsProtected() const
Definition: table5.cxx:1040
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4447
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:2444
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:2446
#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:1947
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:335
void RestorePrintRanges(const ScPrintSaverTab &rSaveTab)
Definition: table1.cxx:2229
void UpdateInsertTab(sc::RefUpdateInsertTabContext &rCxt)
Definition: table1.cxx:1846
sal_Int16 SCCOL
Definition: types.hxx:22
sal_uInt16 GetColWidth(SCCOL nCol, bool bHiddenAsZero=true) const
Definition: table2.cxx:3120
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:2613
OUString aLinkDoc
Definition: table.hxx:162
void UpdateCompile(bool bForceIfNameInUse=false)
Definition: table1.cxx:1932
void AddPrintRange(const ScRange &rNew)
Adds a new print ranges.
Definition: table1.cxx:2198
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:385
ScMarkArray GetMarkArray(SCCOL nCol) const
Definition: markdata.cxx:943
ScRefCellValue GetRefCellValue(SCCOL nCol, SCROW nRow)
Definition: table1.cxx:2463
void GetLastDataPos(SCCOL &rCol, SCROW &rRow) const
Definition: table2.cxx:1811
OUString ScResId(const char *pId)
Definition: scdll.cxx:95
const ScRangeVec & GetPrintRanges() const
Definition: prnsave.hxx:43
bool GetNextMarkedCell(SCCOL &rCol, SCROW &rRow, const ScMarkData &rMark) const
Definition: table1.cxx:1637
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:2381
std::unique_ptr< ScConditionalFormatList > mpCondFormatList
Definition: table.hxx:225
Color aTabBgColor
Definition: table.hxx:220
SvtScriptType GetRangeScriptType(sc::ColumnBlockPosition &rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2)
Definition: table1.cxx:2371
void UpdateTranspose(const ScRange &rSource, const ScAddress &rDest, ScDocument *pUndoDoc)
Definition: table1.cxx:1833
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:1940
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:2567
void UpdateMoveTab(sc::RefUpdateMoveTabContext &rCxt, SCTAB nTabNo, ScProgress *pProgress)
Definition: table1.cxx:1904
Point LogicToPixel(const Point &rLogicPt) const
bool GetDataAreaSubrange(ScRange &rRange) const
Definition: table1.cxx:911
void UpdateDeleteTab(sc::RefUpdateDeleteTabContext &rCxt)
Definition: table1.cxx:1875
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:814
bool IsInDtorClear() const
Definition: document.hxx:2358
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:486
UpdateRefMode
Definition: global.hxx:310
CRFlags
Definition: global.hxx:135
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:417
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:3492
OUString aName
void DumpColumnStorage(SCCOL nCol) const
ScColumnsRange GetColumnsRange(SCCOL begin, SCCOL end) const
Definition: table1.cxx:2585
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:2487
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:2432
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:2452
static SC_DLLPUBLIC const CharClass * getCharClassPtr()
Definition: global.cxx:1018
void * p
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:401
SvtBroadcaster * GetBroadcaster(SCCOL nCol, SCROW nRow)
Definition: table1.cxx:2479
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:2143
SCCOL nRepeatStartX
Definition: table.hxx:172
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:82
std::unique_ptr< ScRange > pRepeatRowRange
Definition: table.hxx:214
std::unique_ptr< ScRangeList > pScenarioRanges
Definition: table.hxx:218
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1061
The data type represents bits, manageable by bitwise operations.
ScDirection
Definition: global.hxx:351
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
sal_uLong AddCondFormat(std::unique_ptr< ScConditionalFormat > pNew)
Definition: table1.cxx:2342
void GetNextPos(SCCOL &rCol, SCROW &rRow, SCCOL nMovX, SCROW nMovY, bool bMarked, bool bUnprotected, const ScMarkData &rMark, SCCOL nTabStartCol) const
Definition: table1.cxx:1392
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:2040
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:1954
void ScRemovePage(SCTAB nTab)
Definition: drwlayer.cxx:399
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:293
bool IsStreamValidLocked() const
Definition: document.hxx:969
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:1270
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:39
bool GetDataStart(SCCOL &rStartCol, SCROW &rStartRow) const
Definition: table1.cxx:726
ScTable(ScDocument *pDoc, SCTAB nNewTab, const OUString &rNewName, bool bColInfo=true, bool bRowInfo=true)
Definition: table1.cxx:232
#define TEXTWIDTH_DIRTY
Definition: globalnames.hxx:18
ScConditionalFormatList * GetCondFormList()
Definition: table1.cxx:2572