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