LibreOffice Module sc (master)  1
table2.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 <algorithm>
21 #include <memory>
22 #include <table.hxx>
23 #include <patattr.hxx>
24 #include <docpool.hxx>
25 #include <formulacell.hxx>
26 #include <document.hxx>
27 #include <drwlayer.hxx>
28 #include <olinetab.hxx>
29 #include <stlpool.hxx>
30 #include <attarray.hxx>
31 #include <markdata.hxx>
32 #include <dociter.hxx>
33 #include <conditio.hxx>
34 #include <chartlis.hxx>
35 #include <fillinfo.hxx>
36 #include <bcaslot.hxx>
37 #include <postit.hxx>
38 #include <sheetevents.hxx>
39 #include <segmenttree.hxx>
40 #include <dbdata.hxx>
41 #include <tokenarray.hxx>
42 #include <clipcontext.hxx>
43 #include <types.hxx>
44 #include <editutil.hxx>
45 #include <mtvcellfunc.hxx>
46 #include <refupdatecontext.hxx>
47 #include <scopetools.hxx>
48 #include <tabprotection.hxx>
49 #include <columnspanset.hxx>
50 #include <rowheightcontext.hxx>
51 #include <listenercontext.hxx>
52 #include <compressedarray.hxx>
53 #include <brdcst.hxx>
54 #include <refdata.hxx>
55 #include <docsh.hxx>
56 
57 #include <scitems.hxx>
58 #include <editeng/boxitem.hxx>
59 #include <editeng/editobj.hxx>
60 #include <o3tl/safeint.hxx>
61 #include <svl/poolcach.hxx>
62 #include <unotools/charclass.hxx>
63 #include <math.h>
64 
65 namespace {
66 
67 class ColumnRegroupFormulaCells
68 {
69  ScColContainer& mrCols;
70  std::vector<ScAddress>* mpGroupPos;
71 
72 public:
73  ColumnRegroupFormulaCells( ScColContainer& rCols, std::vector<ScAddress>* pGroupPos ) :
74  mrCols(rCols), mpGroupPos(pGroupPos) {}
75 
76  void operator() (SCCOL nCol)
77  {
78  mrCols[nCol].RegroupFormulaCells(mpGroupPos);
79  }
80 };
81 
82 }
83 
84 sal_uInt16 ScTable::GetTextWidth(SCCOL nCol, SCROW nRow) const
85 {
86  return aCol[nCol].GetTextWidth(nRow);
87 }
88 
89 bool ScTable::SetOutlineTable( const ScOutlineTable* pNewOutline )
90 {
91  sal_uInt16 nOldSizeX = 0;
92  sal_uInt16 nOldSizeY = 0;
93  sal_uInt16 nNewSizeX = 0;
94  sal_uInt16 nNewSizeY = 0;
95 
96  if (pOutlineTable)
97  {
98  nOldSizeX = pOutlineTable->GetColArray().GetDepth();
99  nOldSizeY = pOutlineTable->GetRowArray().GetDepth();
100  pOutlineTable.reset();
101  }
102 
103  if (pNewOutline)
104  {
105  pOutlineTable.reset(new ScOutlineTable( *pNewOutline ));
106  nNewSizeX = pOutlineTable->GetColArray().GetDepth();
107  nNewSizeY = pOutlineTable->GetRowArray().GetDepth();
108  }
109 
110  return ( nNewSizeX != nOldSizeX || nNewSizeY != nOldSizeY ); // changed size?
111 }
112 
114 {
115  if (!pOutlineTable)
116  pOutlineTable.reset(new ScOutlineTable);
117 }
118 
119 void ScTable::SetSheetEvents( std::unique_ptr<ScSheetEvents> pNew )
120 {
121  pSheetEvents = std::move(pNew);
122 
123  SetCalcNotification( false ); // discard notifications before the events were set
124 
125  SetStreamValid(false);
126 }
127 
129 {
130  bCalcNotification = bSet;
131 }
132 
133 bool ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize ) const
134 {
135  bool bTest = true;
136 
137  if ( nStartCol==0 && nEndCol==rDocument.MaxCol() && pOutlineTable )
138  bTest = pOutlineTable->TestInsertRow(nSize);
139 
140  for (SCCOL i=nStartCol; (i<=nEndCol) && bTest; i++)
141  bTest = CreateColumnIfNotExists(i).TestInsertRow(nStartRow, nSize);
142 
143  return bTest;
144 }
145 
146 void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize )
147 {
148  if (nStartCol==0 && nEndCol==rDocument.MaxCol())
149  {
150  if (mpRowHeights && pRowFlags)
151  {
152  mpRowHeights->insertSegment(nStartRow, nSize);
153  CRFlags nNewFlags = pRowFlags->Insert( nStartRow, nSize);
154  // only copy manual size flag, clear all others
155  if (nNewFlags != CRFlags::NONE && (nNewFlags != CRFlags::ManualSize))
156  pRowFlags->SetValue( nStartRow, nStartRow + nSize - 1,
157  nNewFlags & CRFlags::ManualSize);
158  }
159 
160  if (pOutlineTable)
161  pOutlineTable->InsertRow( nStartRow, nSize );
162 
163  mpFilteredRows->insertSegment(nStartRow, nSize);
164  mpHiddenRows->insertSegment(nStartRow, nSize);
165 
166  if (!maRowManualBreaks.empty())
167  {
168  // Copy all breaks up to nStartRow (non-inclusive).
169  ::std::set<SCROW>::iterator itr1 = maRowManualBreaks.lower_bound(nStartRow);
170  ::std::set<SCROW> aNewBreaks(maRowManualBreaks.begin(), itr1);
171 
172  // Copy all breaks from nStartRow (inclusive) to the last element,
173  // but add nSize to each value.
174  ::std::set<SCROW>::iterator itr2 = maRowManualBreaks.end();
175  for (; itr1 != itr2; ++itr1)
176  aNewBreaks.insert(static_cast<SCROW>(*itr1 + nSize));
177 
178  maRowManualBreaks.swap(aNewBreaks);
179  }
180  }
181 
182  for (SCCOL j=nStartCol; j<=nEndCol; j++)
183  aCol[j].InsertRow( nStartRow, nSize );
184 
185  mpCondFormatList->InsertRow(nTab, nStartCol, nEndCol, nStartRow, nSize);
186 
188 
189  // TODO: In the future we may want to check if the table has been
190  // really modified before setting the stream invalid.
191  SetStreamValid(false);
192 }
193 
195  const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize,
196  bool* pUndoOutline, std::vector<ScAddress>* pGroupPos )
197 {
198  if (nStartCol==0 && nEndCol==rDocument.MaxCol())
199  {
200  if (pRowFlags)
201  pRowFlags->Remove( nStartRow, nSize);
202 
203  if (mpRowHeights)
204  mpRowHeights->removeSegment(nStartRow, nStartRow+nSize);
205 
206  if (pOutlineTable)
207  if (pOutlineTable->DeleteRow( nStartRow, nSize ))
208  if (pUndoOutline)
209  *pUndoOutline = true;
210 
211  mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize);
212  mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize);
213 
214  if (!maRowManualBreaks.empty())
215  {
216  // Erase all manual breaks between nStartRow and nStartRow + nSize - 1 (inclusive).
217  std::set<SCROW>::iterator itr1 = maRowManualBreaks.lower_bound(nStartRow);
218  std::set<SCROW>::iterator itr2 = maRowManualBreaks.upper_bound(static_cast<SCROW>(nStartRow + nSize - 1));
219  maRowManualBreaks.erase(itr1, itr2);
220 
221  // Copy all breaks from the 1st element up to nStartRow to the new container.
222  itr1 = maRowManualBreaks.lower_bound(nStartRow);
223  ::std::set<SCROW> aNewBreaks(maRowManualBreaks.begin(), itr1);
224 
225  // Copy all breaks from nStartRow to the last element, but subtract each value by nSize.
226  itr2 = maRowManualBreaks.end();
227  for (; itr1 != itr2; ++itr1)
228  aNewBreaks.insert(static_cast<SCROW>(*itr1 - nSize));
229 
230  maRowManualBreaks.swap(aNewBreaks);
231  }
232  }
233 
234  { // scope for bulk broadcast
235  ScBulkBroadcast aBulkBroadcast( rDocument.GetBASM(), SfxHintId::ScDataChanged);
236  for (SCCOL j=nStartCol; j<=nEndCol; j++)
237  aCol[j].DeleteRow(nStartRow, nSize, pGroupPos);
238  }
239 
240  std::vector<SCCOL> aRegroupCols;
241  rRegroupCols.getColumns(nTab, aRegroupCols);
242  std::for_each(
243  aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol, pGroupPos));
244 
246 
247  // TODO: In the future we may want to check if the table has been
248  // really modified before setting the stream invalid.
249  SetStreamValid(false);
250 }
251 
252 bool ScTable::TestInsertCol( SCROW nStartRow, SCROW nEndRow, SCSIZE nSize ) const
253 {
254  if ( nSize > o3tl::make_unsigned(rDocument.MaxCol()) )
255  return false;
256 
257  if ( nStartRow==0 && nEndRow==rDocument.MaxRow() && pOutlineTable
258  && ! pOutlineTable->TestInsertCol(nSize) )
259  return false;
260 
261  auto range = GetColumnsRange( rDocument.MaxCol() - static_cast<SCCOL>(nSize) + 1, rDocument.MaxCol() );
262  for (auto it = range.rbegin(); it != range.rend(); ++it )
263  if (! aCol[*it].TestInsertCol(nStartRow, nEndRow))
264  return false;
265 
266  return true;
267 }
268 
270  const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
271 {
272  if (nStartRow==0 && nEndRow==rDocument.MaxRow())
273  {
274  if (mpColWidth && mpColFlags)
275  {
276  mpColWidth->InsertPreservingSize(nStartCol, nSize, STD_COL_WIDTH);
277  // The inserted columns have the same widths as the columns, which were selected for insert.
278  for (SCSIZE i=0; i < std::min(rDocument.MaxCol()-nSize-nStartCol, nSize); ++i)
279  mpColWidth->SetValue(nStartCol + i, mpColWidth->GetValue(nStartCol+i+nSize));
280  mpColFlags->InsertPreservingSize(nStartCol, nSize, CRFlags::NONE);
281  }
282  if (pOutlineTable)
283  pOutlineTable->InsertCol( nStartCol, nSize );
284 
285  mpHiddenCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize));
286  mpFilteredCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize));
287 
288  if (!maColManualBreaks.empty())
289  {
290  // Copy all breaks up to nStartCol (non-inclusive).
291  ::std::set<SCCOL>::iterator itr1 = maColManualBreaks.lower_bound(nStartCol);
292  ::std::set<SCCOL> aNewBreaks(maColManualBreaks.begin(), itr1);
293 
294  // Copy all breaks from nStartCol (inclusive) to the last element,
295  // but add nSize to each value.
296  ::std::set<SCCOL>::iterator itr2 = maColManualBreaks.end();
297  for (; itr1 != itr2; ++itr1)
298  aNewBreaks.insert(static_cast<SCCOL>(*itr1 + nSize));
299 
300  maColManualBreaks.swap(aNewBreaks);
301  }
302  }
303 
304  if ((nStartRow == 0) && (nEndRow == rDocument.MaxRow()))
305  {
306  for (SCSIZE i=0; i < nSize; i++)
307  for (SCCOL nCol = aCol.size() - 1; nCol > nStartCol; nCol--)
308  aCol[nCol].SwapCol(aCol[nCol-1]);
309  }
310  else
311  {
312  for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol < aCol.size(); i++)
313  aCol[aCol.size() - 1 - nSize - i].MoveTo(nStartRow, nEndRow, aCol[aCol.size() - 1 - i]);
314  }
315 
316  std::vector<SCCOL> aRegroupCols;
317  rRegroupCols.getColumns(nTab, aRegroupCols);
318  std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol, nullptr));
319 
320  if (nStartCol>0) // copy old attributes
321  {
322  sal_uInt16 nWhichArray[2];
323  nWhichArray[0] = ATTR_MERGE;
324  nWhichArray[1] = 0;
325 
327  for (SCSIZE i=0; i<nSize; i++)
328  {
329  aCol[nStartCol-1].CopyToColumn(aCxt, nStartRow, nEndRow, InsertDeleteFlags::ATTRIB,
330  false, aCol[nStartCol+i] );
331  aCol[nStartCol+i].RemoveFlags( nStartRow, nEndRow,
333  aCol[nStartCol+i].ClearItems( nStartRow, nEndRow, nWhichArray );
334  }
335  }
336 
337  mpCondFormatList->InsertCol(nTab, nStartRow, nEndRow, nStartCol, nSize);
338 
340 
341  // TODO: In the future we may want to check if the table has been
342  // really modified before setting the stream invalid.
343  SetStreamValid(false);
344 }
345 
347  const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize, bool* pUndoOutline )
348 {
349  if (nStartRow==0 && nEndRow==rDocument.MaxRow())
350  {
351  if (mpColWidth && mpColFlags)
352  {
353  assert( nStartCol + nSize <= o3tl::make_unsigned(rDocument.MaxCol()+1) ); // moving 0 if ==rDocument.MaxCol()+1 is correct
354  mpColWidth->RemovePreservingSize(nStartCol, nSize, STD_COL_WIDTH);
355  mpColFlags->RemovePreservingSize(nStartCol, nSize, CRFlags::NONE);
356  }
357  if (pOutlineTable)
358  if (pOutlineTable->DeleteCol( nStartCol, nSize ))
359  if (pUndoOutline)
360  *pUndoOutline = true;
361 
362  SCCOL nRmSize = nStartCol + static_cast<SCCOL>(nSize);
363  mpHiddenCols->removeSegment(nStartCol, nRmSize);
364  mpFilteredCols->removeSegment(nStartCol, nRmSize);
365 
366  if (!maColManualBreaks.empty())
367  {
368  // Erase all manual breaks between nStartCol and nStartCol + nSize - 1 (inclusive).
369  std::set<SCCOL>::iterator itr1 = maColManualBreaks.lower_bound(nStartCol);
370  std::set<SCCOL>::iterator itr2 = maColManualBreaks.upper_bound(static_cast<SCCOL>(nStartCol + nSize - 1));
371  maColManualBreaks.erase(itr1, itr2);
372 
373  // Copy all breaks from the 1st element up to nStartCol to the new container.
374  itr1 = maColManualBreaks.lower_bound(nStartCol);
375  ::std::set<SCCOL> aNewBreaks(maColManualBreaks.begin(), itr1);
376 
377  // Copy all breaks from nStartCol to the last element, but subtract each value by nSize.
378  itr2 = maColManualBreaks.end();
379  for (; itr1 != itr2; ++itr1)
380  aNewBreaks.insert(static_cast<SCCOL>(*itr1 - nSize));
381 
382  maColManualBreaks.swap(aNewBreaks);
383  }
384  }
385 
386  for (SCSIZE i = 0; i < nSize; i++)
387  aCol[nStartCol + i].DeleteArea(nStartRow, nEndRow, InsertDeleteFlags::ALL, false);
388 
389  if ((nStartRow == 0) && (nEndRow == rDocument.MaxRow()))
390  {
391  for (SCSIZE i=0; i < nSize; i++)
392  for (SCCOL nCol = nStartCol; nCol < aCol.size() - 1; nCol++)
393  aCol[nCol].SwapCol(aCol[nCol+1]);
394  }
395  else
396  {
397  for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol < aCol.size(); i++)
398  aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]);
399  }
400 
401  std::vector<SCCOL> aRegroupCols;
402  rRegroupCols.getColumns(nTab, aRegroupCols);
403  std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol, nullptr));
404 
406 
407  // TODO: In the future we may want to check if the table has been
408  // really modified before setting the stream invalid.
409  SetStreamValid(false);
410 }
411 
413  SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, InsertDeleteFlags nDelFlag,
414  bool bBroadcast, sc::ColumnSpanSet* pBroadcastSpans )
415 {
416  if ( nCol2 >= aCol.size() ) nCol2 = aCol.size() - 1;
417  if (nRow2 > rDocument.MaxRow()) nRow2 = rDocument.MaxRow();
418  if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
419  {
420  { // scope for bulk broadcast
421  ScBulkBroadcast aBulkBroadcast( rDocument.GetBASM(), SfxHintId::ScDataChanged);
422  for (SCCOL i = nCol1; i <= nCol2; i++)
423  aCol[i].DeleteArea(nRow1, nRow2, nDelFlag, bBroadcast, pBroadcastSpans);
424  }
425 
426  // Do not set protected cell in a protected table
427 
428  if ( IsProtected() && (nDelFlag & InsertDeleteFlags::ATTRIB) )
429  {
430  ScPatternAttr aPattern(rDocument.GetPool());
431  aPattern.GetItemSet().Put( ScProtectionAttr( false ) );
432  ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
433  }
434 
435  if( nDelFlag & InsertDeleteFlags::ATTRIB )
436  mpCondFormatList->DeleteArea( nCol1, nRow1, nCol2, nRow2 );
437  }
438 
439  // TODO: In the future we may want to check if the table has been
440  // really modified before setting the stream invalid.
441  SetStreamValid(false);
442 }
443 
444 void ScTable::DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast )
445 {
446  { // scope for bulk broadcast
447  ScBulkBroadcast aBulkBroadcast( rDocument.GetBASM(), SfxHintId::ScDataChanged);
448  for (SCCOL i=0; i < aCol.size(); i++)
449  aCol[i].DeleteSelection(nDelFlag, rMark, bBroadcast);
450  }
451 
452  ScRangeList aRangeList;
453  rMark.FillRangeListWithMarks(&aRangeList, false);
454 
455  for (size_t i = 0; i < aRangeList.size(); ++i)
456  {
457  const ScRange & rRange = aRangeList[i];
458 
459  if((nDelFlag & InsertDeleteFlags::ATTRIB) && rRange.aStart.Tab() == nTab)
460  mpCondFormatList->DeleteArea( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row() );
461  }
462 
463  // Do not set protected cell in a protected sheet
464 
465  if ( IsProtected() && (nDelFlag & InsertDeleteFlags::ATTRIB) )
466  {
467  ScDocumentPool* pPool = rDocument.GetPool();
469  aSet.Put( ScProtectionAttr( false ) );
470  SfxItemPoolCache aCache( pPool, &aSet );
471  ApplySelectionCache( &aCache, rMark );
472  }
473 
474  // TODO: In the future we may want to check if the table has been
475  // really modified before setting the stream invalid.
476  SetStreamValid(false);
477 }
478 
479 // pTable = Clipboard
481  sc::CopyToClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
482  ScTable* pTable )
483 {
484  if (!ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2))
485  return;
486 
487  // copy content
488  //local range names need to be copied first for formula cells
489  if (!pTable->mpRangeName && mpRangeName)
490  pTable->mpRangeName.reset( new ScRangeName(*mpRangeName) );
491 
492  nCol2 = ClampToAllocatedColumns(nCol2);
493 
494  for ( SCCOL i = nCol1; i <= nCol2; i++)
495  aCol[i].CopyToClip(rCxt, nRow1, nRow2, pTable->CreateColumnIfNotExists(i)); // notes are handled at column level
496 
497  // copy widths/heights, and only "hidden", "filtered" and "manual" flags
498  // also for all preceding columns/rows, to have valid positions for drawing objects
499 
500  if (mpColWidth && pTable->mpColWidth)
501  pTable->mpColWidth->CopyFrom(*mpColWidth, 0, nCol2);
502 
503  pTable->CopyColHidden(*this, 0, nCol2);
504  pTable->CopyColFiltered(*this, 0, nCol2);
505  if (pDBDataNoName)
506  pTable->SetAnonymousDBData(std::unique_ptr<ScDBData>(new ScDBData(*pDBDataNoName)));
507 
508  if (pRowFlags && pTable->pRowFlags && mpRowHeights && pTable->mpRowHeights)
509  {
510  pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CRFlags::ManualSize);
511  pTable->CopyRowHeight(*this, 0, nRow2, 0);
512  }
513 
514  pTable->CopyRowHidden(*this, 0, nRow2);
515  pTable->CopyRowFiltered(*this, 0, nRow2);
516 
517  // If necessary replace formulas with values
518 
519  if ( IsProtected() )
520  for (SCCOL i = nCol1; i <= nCol2; i++)
521  pTable->aCol[i].RemoveProtected(nRow1, nRow2);
522 
524 }
525 
527  sc::CopyToClipContext& rCxt, const ScRangeList& rRanges, ScTable* pTable )
528 {
529  for ( size_t i = 0, nListSize = rRanges.size(); i < nListSize; ++i )
530  {
531  const ScRange & r = rRanges[ i ];
532  CopyToClip( rCxt, r.aStart.Col(), r.aStart.Row(), r.aEnd.Col(), r.aEnd.Row(), pTable);
533  }
534 }
535 
537  SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const SvNumberFormatterMergeMap& rMap, ScTable* pDestTab )
538 {
539  if (nCol1 > nCol2 || nRow1 > nRow2)
540  return;
541 
542  const SCCOL nFirstUnallocated = std::clamp<SCCOL>(GetAllocatedColumnsCount(), nCol1, nCol2 + 1);
543  if (nFirstUnallocated > nCol1)
544  pDestTab->CreateColumnIfNotExists(nFirstUnallocated - 1);
545 
546  for (SCCOL i = nCol1; i < nFirstUnallocated; ++i)
547  {
548  ScColumn& rSrcCol = aCol[i];
549  ScColumn& rDestCol = pDestTab->aCol[i];
550  rSrcCol.CopyStaticToDocument(nRow1, nRow2, rMap, rDestCol);
551  }
552 
553  // Maybe copy this table's default attrs to dest not limiting to already allocated in dest?
554  const SCCOL nLastInDest = std::min<SCCOL>(pDestTab->GetAllocatedColumnsCount() - 1, nCol2);
555  for (SCCOL i = nFirstUnallocated; i <= nLastInDest; ++i)
556  {
557  ScColumn& rDestCol = pDestTab->aCol[i];
558  rDestCol.maCellTextAttrs.set_empty(nRow1, nRow2);
559  rDestCol.maCells.set_empty(nRow1, nRow2);
560  for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
561  {
562  sal_uInt32 nNumFmt = aDefaultColAttrArray.GetPattern(nRow)->GetNumberFormat(
564  SvNumberFormatterMergeMap::const_iterator itNum = rMap.find(nNumFmt);
565  if (itNum != rMap.end())
566  nNumFmt = itNum->second;
567 
568  rDestCol.SetNumberFormat(nRow, nNumFmt);
569  }
570  rDestCol.CellStorageModified();
571  }
572 }
573 
574 void ScTable::CopyCellToDocument(SCCOL nSrcCol, SCROW nSrcRow, SCCOL nDestCol, SCROW nDestRow, ScTable& rDestTab )
575 {
576  if (!ValidColRow(nSrcCol, nSrcRow) || !ValidColRow(nDestCol, nDestRow))
577  return;
578 
579  if (nSrcCol >= GetAllocatedColumnsCount())
580  {
581  if (nDestCol < rDestTab.GetAllocatedColumnsCount())
582  {
583  ScColumn& rDestCol = rDestTab.aCol[nDestCol];
584  rDestCol.maCells.set_empty(nDestRow, nDestRow);
585  rDestCol.maCellTextAttrs.set_empty(nDestRow, nDestRow);
586  rDestCol.maCellNotes.set_empty(nDestRow, nDestRow);
587  rDestCol.CellStorageModified();
588  }
589  return;
590  }
591 
592  ScColumn& rSrcCol = aCol[nSrcCol];
593  ScColumn& rDestCol = rDestTab.CreateColumnIfNotExists(nDestCol);
594  rSrcCol.CopyCellToDocument(nSrcRow, nDestRow, rDestCol);
595 }
596 
597 namespace {
598 
599 bool CheckAndDeduplicateCondFormat(ScDocument& rDocument, ScConditionalFormat* pOldFormat, const ScConditionalFormat* pNewFormat, SCTAB nTab)
600 {
601  if (!pOldFormat)
602  return false;
603 
604  if (pOldFormat->EqualEntries(*pNewFormat, true))
605  {
606  const ScRangeList& rNewRangeList = pNewFormat->GetRange();
607  ScRangeList& rDstRangeList = pOldFormat->GetRangeList();
608  for (size_t i = 0; i < rNewRangeList.size(); ++i)
609  {
610  rDstRangeList.Join(rNewRangeList[i]);
611  }
612  rDocument.AddCondFormatData(rNewRangeList, nTab, pOldFormat->GetKey());
613  return true;
614  }
615 
616  return false;
617 }
618 
619 }
620 
621 void ScTable::CopyConditionalFormat( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
622  SCCOL nDx, SCROW nDy, const ScTable* pTable)
623 {
624  ScRange aOldRange( nCol1 - nDx, nRow1 - nDy, pTable->nTab, nCol2 - nDx, nRow2 - nDy, pTable->nTab);
625  ScRange aNewRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
626  bool bSameDoc = rDocument.GetStyleSheetPool() == pTable->rDocument.GetStyleSheetPool();
627 
628  for(const auto& rxCondFormat : *pTable->mpCondFormatList)
629  {
630  const ScRangeList& rCondFormatRange = rxCondFormat->GetRange();
631  if(!rCondFormatRange.Intersects( aOldRange ))
632  continue;
633 
634  ScRangeList aIntersectedRange = rCondFormatRange.GetIntersectedRange(aOldRange);
635  std::unique_ptr<ScConditionalFormat> pNewFormat = rxCondFormat->Clone(&rDocument);
636 
637  pNewFormat->SetRange(aIntersectedRange);
638  sc::RefUpdateContext aRefCxt(rDocument);
639  aRefCxt.meMode = URM_COPY;
640  aRefCxt.maRange = aNewRange;
641  aRefCxt.mnColDelta = nDx;
642  aRefCxt.mnRowDelta = nDy;
643  aRefCxt.mnTabDelta = nTab - pTable->nTab;
644  pNewFormat->UpdateReference(aRefCxt, true);
645 
646  if (bSameDoc && pTable->nTab == nTab && CheckAndDeduplicateCondFormat(rDocument, mpCondFormatList->GetFormat(rxCondFormat->GetKey()), pNewFormat.get(), nTab))
647  {
648  continue;
649  }
650  sal_uLong nMax = 0;
651  bool bDuplicate = false;
652  for(const auto& rxCond : *mpCondFormatList)
653  {
654  // Check if there is the same format in the destination
655  // If there is, then simply expand its range
656  if (CheckAndDeduplicateCondFormat(rDocument, rxCond.get(), pNewFormat.get(), nTab))
657  {
658  bDuplicate = true;
659  break;
660  }
661 
662  if (rxCond->GetKey() > nMax)
663  nMax = rxCond->GetKey();
664  }
665  // Do not add duplicate entries
666  if (bDuplicate)
667  {
668  continue;
669  }
670 
671  pNewFormat->SetKey(nMax + 1);
672  auto pNewFormatTmp = pNewFormat.get();
673  mpCondFormatList->InsertNew(std::move(pNewFormat));
674 
675  if(!bSameDoc)
676  {
677  for(size_t i = 0, n = pNewFormatTmp->size();
678  i < n; ++i)
679  {
680  OUString aStyleName;
681  const ScFormatEntry* pEntry = pNewFormatTmp->GetEntry(i);
682  if(pEntry->GetType() == ScFormatEntry::Type::Condition ||
684  aStyleName = static_cast<const ScCondFormatEntry*>(pEntry)->GetStyle();
685  else if(pEntry->GetType() == ScFormatEntry::Type::Date)
686  aStyleName = static_cast<const ScCondDateFormatEntry*>(pEntry)->GetStyleName();
687 
688  if(!aStyleName.isEmpty())
689  {
690  if(rDocument.GetStyleSheetPool()->Find(aStyleName, SfxStyleFamily::Para))
691  continue;
692 
693  rDocument.GetStyleSheetPool()->CopyStyleFrom(
694  pTable->rDocument.GetStyleSheetPool(), aStyleName, SfxStyleFamily::Para );
695  }
696  }
697  }
698 
699  rDocument.AddCondFormatData( pNewFormatTmp->GetRange(), nTab, pNewFormatTmp->GetKey() );
700  }
701 }
702 
704 {
705  if (!ValidCol(nCol))
706  return false;
707 
709  return true;
710 }
711 
712 // pTable is source
713 
715  sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
716  SCCOL nDx, SCROW nDy, ScTable* pTable )
717 {
718  if (nCol2 > rDocument.MaxCol())
719  nCol2 = rDocument.MaxCol();
720  if (nRow2 > rDocument.MaxRow())
721  nRow2 = rDocument.MaxRow();
722 
723  if (!(ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2)))
724  return;
725 
727  for ( SCCOL i = nCol1; i <= nCol2; i++)
728  {
729  pTable->CreateColumnIfNotExists(i - nDx);
730  aCol[i].CopyFromClip(rCxt, nRow1, nRow2, nDy, pTable->aCol[i - nDx]); // notes are handles at column level
731  }
732 
734  {
735  // make sure that there are no old references to the cond formats
736  sal_uInt16 nWhichArray[2];
737  nWhichArray[0] = ATTR_CONDITIONAL;
738  nWhichArray[1] = 0;
739  for ( SCCOL i = nCol1; i <= nCol2; ++i)
740  aCol[i].ClearItems(nRow1, nRow2, nWhichArray);
741  }
742 
744  return;
745 
746  if (nRow1==0 && nRow2==rDocument.MaxRow() && mpColWidth && pTable->mpColWidth)
747  mpColWidth->CopyFrom(*pTable->mpColWidth, nCol1, nCol2, nCol1 - nDx);
748 
749  if (nCol1==0 && nCol2==rDocument.MaxCol() && mpRowHeights && pTable->mpRowHeights &&
750  pRowFlags && pTable->pRowFlags)
751  {
752  CopyRowHeight(*pTable, nRow1, nRow2, -nDy);
753  // Must copy CRFlags::ManualSize bit too, otherwise pRowHeight doesn't make sense
754  for (SCROW j=nRow1; j<=nRow2; j++)
755  {
756  if ( pTable->pRowFlags->GetValue(j-nDy) & CRFlags::ManualSize )
757  pRowFlags->OrValue( j, CRFlags::ManualSize);
758  else
759  pRowFlags->AndValue( j, ~CRFlags::ManualSize);
760  }
761  }
762 
763  // Do not set protected cell in a protected sheet
765  {
766  ScPatternAttr aPattern(rDocument.GetPool());
767  aPattern.GetItemSet().Put( ScProtectionAttr( false ) );
768  ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
769  }
770 
771  // create deep copies for conditional formatting
772  CopyConditionalFormat( nCol1, nRow1, nCol2, nRow2, nDx, nDy, pTable);
773 }
774 
776  sc::MixDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
777  ScPasteFunc nFunction, bool bSkipEmpty, const ScTable* pSrcTab )
778 {
779  for (SCCOL i=nCol1; i<=nCol2; i++)
780  aCol[i].MixData(rCxt, nRow1, nRow2, nFunction, bSkipEmpty, pSrcTab->aCol[i]);
781 }
782 
783 // Selection form this document
785  sc::MixDocContext& rCxt, const ScMarkData& rMark, ScPasteFunc nFunction,
786  bool bSkipEmpty, const ScTable* pSrcTab )
787 {
788  for (SCCOL i=0; i < aCol.size(); i++)
789  aCol[i].MixMarked(rCxt, rMark, nFunction, bSkipEmpty, pSrcTab->aCol[i]);
790 }
791 
792 namespace {
793 
794 class TransClipHandler
795 {
796  ScTable& mrClipTab;
797  SCTAB mnSrcTab;
798  SCCOL mnSrcCol;
799  size_t mnTopRow;
800  SCROW mnTransRow;
801  bool mbAsLink;
802  bool mbWasCut;
803 
804  ScAddress getDestPos(size_t nRow) const
805  {
806  return ScAddress(static_cast<SCCOL>(nRow-mnTopRow), mnTransRow, mrClipTab.GetTab());
807  }
808 
809  ScFormulaCell* createRefCell(size_t nSrcRow, const ScAddress& rDestPos) const
810  {
811  ScAddress aSrcPos(mnSrcCol, nSrcRow, mnSrcTab);
812  ScSingleRefData aRef;
813  aRef.InitAddress(aSrcPos); // Absolute reference.
814  aRef.SetFlag3D(true);
815 
816  ScTokenArray aArr(mrClipTab.GetDoc());
817  aArr.AddSingleReference(aRef);
818  return new ScFormulaCell(mrClipTab.GetDoc(), rDestPos, aArr);
819  }
820 
821  void setLink(size_t nRow)
822  {
823  SCCOL nTransCol = nRow - mnTopRow;
824  mrClipTab.SetFormulaCell(
825  nTransCol, mnTransRow, createRefCell(nRow, getDestPos(nRow)));
826  }
827 
828 public:
829  TransClipHandler(ScTable& rClipTab, SCTAB nSrcTab, SCCOL nSrcCol, size_t nTopRow, SCROW nTransRow, bool bAsLink, bool bWasCut) :
830  mrClipTab(rClipTab), mnSrcTab(nSrcTab), mnSrcCol(nSrcCol),
831  mnTopRow(nTopRow), mnTransRow(nTransRow), mbAsLink(bAsLink), mbWasCut(bWasCut) {}
832 
833  void operator() (size_t nRow, double fVal)
834  {
835  if (mbAsLink)
836  {
837  setLink(nRow);
838  return;
839  }
840 
841  SCCOL nTransCol = nRow - mnTopRow;
842  mrClipTab.SetValue(nTransCol, mnTransRow, fVal);
843  }
844 
845  void operator() (size_t nRow, const svl::SharedString& rStr)
846  {
847  if (mbAsLink)
848  {
849  setLink(nRow);
850  return;
851  }
852 
853  SCCOL nTransCol = nRow - mnTopRow;
854  mrClipTab.SetRawString(nTransCol, mnTransRow, rStr);
855  }
856 
857  void operator() (size_t nRow, const EditTextObject* p)
858  {
859  if (mbAsLink)
860  {
861  setLink(nRow);
862  return;
863  }
864 
865  SCCOL nTransCol = nRow - mnTopRow;
866  mrClipTab.SetEditText(nTransCol, mnTransRow, ScEditUtil::Clone(*p, mrClipTab.GetDoc()));
867  }
868 
869  void operator() (size_t nRow, const ScFormulaCell* p)
870  {
871  if (mbAsLink)
872  {
873  setLink(nRow);
874  return;
875  }
876 
877  ScFormulaCell* pNew = new ScFormulaCell(
878  *p, mrClipTab.GetDoc(), getDestPos(nRow), ScCloneFlags::StartListening);
879 
880  // rotate reference
881  // for Cut, the references are later adjusted through UpdateTranspose
882 
883  if (!mbWasCut)
884  pNew->TransposeReference();
885 
886  SCCOL nTransCol = nRow - mnTopRow;
887  mrClipTab.SetFormulaCell(nTransCol, mnTransRow, pNew);
888  }
889 };
890 
891 }
892 
893 void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
894  ScTable* pTransClip, InsertDeleteFlags nFlags, bool bAsLink )
895 {
896  bool bWasCut = rDocument.IsCutMode();
897 
898  ScDocument& rDestDoc = pTransClip->rDocument;
899 
900  for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
901  {
902  SCROW nRow;
903  if ( bAsLink && nFlags == InsertDeleteFlags::ALL )
904  {
905  // with InsertDeleteFlags::ALL, also create links (formulas) for empty cells
906 
907  for ( nRow=nRow1; nRow<=nRow2; nRow++ )
908  {
909  // create simple formula, as in ScColumn::CreateRefCell
910 
911  ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
912  ScSingleRefData aRef;
913  aRef.InitAddress(ScAddress(nCol,nRow,nTab));
914  aRef.SetFlag3D(true);
915  ScTokenArray aArr(rDestDoc);
916  aArr.AddSingleReference( aRef );
917 
918  pTransClip->SetFormulaCell(
919  static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1),
920  new ScFormulaCell(rDestDoc, aDestPos, aArr));
921  }
922  }
923  else
924  {
925  TransClipHandler aFunc(*pTransClip, nTab, nCol, nRow1, static_cast<SCROW>(nCol-nCol1), bAsLink, bWasCut);
926  const sc::CellStoreType& rCells = aCol[nCol].maCells;
927  sc::ParseAllNonEmpty(rCells.begin(), rCells, nRow1, nRow2, aFunc);
928  }
929 
930  // Attribute
931 
932  SCROW nAttrRow1 = {}; // spurious -Werror=maybe-uninitialized
933  SCROW nAttrRow2 = {}; // spurious -Werror=maybe-uninitialized
934  const ScPatternAttr* pPattern;
935  std::unique_ptr<ScAttrIterator> pAttrIter(aCol[nCol].CreateAttrIterator( nRow1, nRow2 ));
936  while ( (pPattern = pAttrIter->Next( nAttrRow1, nAttrRow2 )) != nullptr )
937  {
938  if ( !IsDefaultItem( pPattern ) )
939  {
940  const SfxItemSet& rSet = pPattern->GetItemSet();
941  if ( rSet.GetItemState( ATTR_MERGE, false ) == SfxItemState::DEFAULT &&
942  rSet.GetItemState( ATTR_MERGE_FLAG, false ) == SfxItemState::DEFAULT &&
943  rSet.GetItemState( ATTR_BORDER, false ) == SfxItemState::DEFAULT )
944  {
945  // no borders or merge items involved - use pattern as-is
946  for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
947  pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), *pPattern );
948  }
949  else
950  {
951  // transpose borders and merge values, remove merge flags (refreshed after pasting)
952  ScPatternAttr aNewPattern( *pPattern );
953  SfxItemSet& rNewSet = aNewPattern.GetItemSet();
954 
955  const SvxBoxItem& rOldBox = rSet.Get(ATTR_BORDER);
956  if ( rOldBox.GetTop() || rOldBox.GetBottom() || rOldBox.GetLeft() || rOldBox.GetRight() )
957  {
958  SvxBoxItem aNew( ATTR_BORDER );
959  aNew.SetLine( rOldBox.GetLine( SvxBoxItemLine::TOP ), SvxBoxItemLine::LEFT );
960  aNew.SetLine( rOldBox.GetLine( SvxBoxItemLine::LEFT ), SvxBoxItemLine::TOP );
961  aNew.SetLine( rOldBox.GetLine( SvxBoxItemLine::BOTTOM ), SvxBoxItemLine::RIGHT );
962  aNew.SetLine( rOldBox.GetLine( SvxBoxItemLine::RIGHT ), SvxBoxItemLine::BOTTOM );
963  aNew.SetDistance( rOldBox.GetDistance( SvxBoxItemLine::TOP ), SvxBoxItemLine::LEFT );
964  aNew.SetDistance( rOldBox.GetDistance( SvxBoxItemLine::LEFT ), SvxBoxItemLine::TOP );
965  aNew.SetDistance( rOldBox.GetDistance( SvxBoxItemLine::BOTTOM ), SvxBoxItemLine::RIGHT );
966  aNew.SetDistance( rOldBox.GetDistance( SvxBoxItemLine::RIGHT ), SvxBoxItemLine::BOTTOM );
967  rNewSet.Put( aNew );
968  }
969 
970  const ScMergeAttr& rOldMerge = rSet.Get(ATTR_MERGE);
971  if (rOldMerge.IsMerged())
972  rNewSet.Put( ScMergeAttr( std::min(
973  static_cast<SCCOL>(rOldMerge.GetRowMerge()),
974  static_cast<SCCOL>(rDocument.MaxCol()+1 - (nAttrRow2-nRow1))),
975  std::min(
976  static_cast<SCROW>(rOldMerge.GetColMerge()),
977  static_cast<SCROW>(rDocument.MaxRow()+1 - (nCol-nCol1)))));
978  const ScMergeFlagAttr& rOldFlag = rSet.Get(ATTR_MERGE_FLAG);
979  if (rOldFlag.IsOverlapped())
980  {
981  ScMF nNewFlags = rOldFlag.GetValue() & ~ScMF( ScMF::Hor | ScMF::Ver );
982  if ( nNewFlags != ScMF::NONE )
983  rNewSet.Put( ScMergeFlagAttr( nNewFlags ) );
984  else
985  rNewSet.ClearItem( ATTR_MERGE_FLAG );
986  }
987 
988  for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
989  pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1),
990  static_cast<SCROW>(nCol-nCol1), aNewPattern);
991  }
992  }
993  }
994 
995  // Cell Notes - fdo#68381 paste cell notes on Transpose
996  if ( rDocument.HasColNotes(nCol, nTab) )
997  TransposeColNotes(pTransClip, nCol1, nCol, nRow1, nRow2);
998  }
999 }
1000 
1001 void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1, SCROW nRow2)
1002 {
1003  sc::CellNoteStoreType::const_iterator itBlk = aCol[nCol].maCellNotes.begin(), itBlkEnd = aCol[nCol].maCellNotes.end();
1004 
1005  // Locate the top row position.
1006  size_t nOffsetInBlock = 0;
1007  size_t nBlockStart = 0, nBlockEnd = 0, nRowPos = static_cast<size_t>(nRow1);
1008  for (; itBlk != itBlkEnd; ++itBlk, nBlockStart = nBlockEnd)
1009  {
1010  nBlockEnd = nBlockStart + itBlk->size;
1011  if (nBlockStart <= nRowPos && nRowPos < nBlockEnd)
1012  {
1013  // Found.
1014  nOffsetInBlock = nRowPos - nBlockStart;
1015  break;
1016  }
1017  }
1018 
1019  if (itBlk == itBlkEnd)
1020  // Specified range found
1021  return;
1022 
1023  nRowPos = static_cast<size_t>(nRow2); // End row position.
1024 
1025  // Keep processing until we hit the end row position.
1026  sc::cellnote_block::const_iterator itData, itDataEnd;
1027  for (; itBlk != itBlkEnd; ++itBlk, nBlockStart = nBlockEnd, nOffsetInBlock = 0)
1028  {
1029  nBlockEnd = nBlockStart + itBlk->size;
1030 
1031  if (itBlk->data)
1032  {
1033  itData = sc::cellnote_block::begin(*itBlk->data);
1034  std::advance(itData, nOffsetInBlock);
1035 
1036  if (nBlockStart <= nRowPos && nRowPos < nBlockEnd)
1037  {
1038  // This block contains the end row. Only process partially.
1039  size_t nOffsetEnd = nRowPos - nBlockStart + 1;
1040  itDataEnd = sc::cellnote_block::begin(*itBlk->data);
1041  std::advance(itDataEnd, nOffsetEnd);
1042  size_t curRow = nBlockStart + nOffsetInBlock;
1043  for (; itData != itDataEnd; ++itData, ++curRow)
1044  {
1045  ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
1046  pTransClip->rDocument.ReleaseNote(aDestPos);
1047  ScPostIt* pNote = *itData;
1048  if (pNote)
1049  {
1050  std::unique_ptr<ScPostIt> pClonedNote = pNote->Clone( ScAddress(nCol, curRow, nTab), pTransClip->rDocument, aDestPos, true );
1051  pTransClip->rDocument.SetNote(aDestPos, std::move(pClonedNote));
1052  }
1053  }
1054  break; // we reached the last valid block
1055  }
1056  else
1057  {
1058  itDataEnd = sc::cellnote_block::end(*itBlk->data);
1059  size_t curRow = nBlockStart + nOffsetInBlock;
1060  for (; itData != itDataEnd; ++itData, ++curRow)
1061  {
1062  ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
1063  pTransClip->rDocument.ReleaseNote(aDestPos);
1064  ScPostIt* pNote = *itData;
1065  if (pNote)
1066  {
1067  std::unique_ptr<ScPostIt> pClonedNote = pNote->Clone( ScAddress(nCol, curRow, nTab), pTransClip->rDocument, aDestPos, true );
1068  pTransClip->rDocument.SetNote(aDestPos, std::move(pClonedNote));
1069  }
1070  }
1071  }
1072  }
1073  else
1074  {
1075  size_t curRow;
1076  for ( curRow = nBlockStart + nOffsetInBlock; curRow <= nBlockEnd && curRow <= nRowPos; ++curRow)
1077  {
1078  ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
1079  pTransClip->rDocument.ReleaseNote(aDestPos);
1080  }
1081  if (curRow == nRowPos)
1082  break;
1083  }
1084  }
1085 }
1086 
1088 {
1089  if (!ValidCol(nCol))
1090  return nullptr;
1091 
1092  return &CreateColumnIfNotExists(nCol);
1093 }
1094 
1096 {
1097  if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount())
1098  return nullptr;
1099 
1100  return &aCol[nCol];
1101 }
1102 
1104 {
1105  std::shared_ptr<const sc::ColumnSet> pColSet = rCxt.getColumnSet();
1106  if (!pColSet)
1107  {
1108  for (SCCOL i=0; i < aCol.size(); i++)
1109  aCol[i].StartListeners(rCxt, bAll);
1110  }
1111  else if (pColSet->hasTab( nTab))
1112  {
1113  std::vector<SCCOL> aColumns;
1114  pColSet->getColumns( nTab, aColumns);
1115  for (auto i : aColumns)
1116  {
1117  if (0 <= i && i < aCol.size())
1118  aCol[i].StartListeners(rCxt, bAll);
1119  }
1120  }
1121 }
1122 
1124  sc::StartListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1125 {
1126  nCol2 = ClampToAllocatedColumns(nCol2);
1127  for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
1128  aCol[nCol].AttachFormulaCells(rCxt, nRow1, nRow2);
1129 }
1130 
1132  sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1133 {
1134  nCol2 = ClampToAllocatedColumns(nCol2);
1135  for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
1136  aCol[nCol].DetachFormulaCells(rCxt, nRow1, nRow2, nullptr);
1137 }
1138 
1140  SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sc::ColumnSpanSet& rBroadcastSpans )
1141 {
1142  if ( nCol2 >= aCol.size() ) nCol2 = aCol.size() - 1;
1143  if (nCol2 > rDocument.MaxCol()) nCol2 = rDocument.MaxCol();
1144  if (nRow2 > rDocument.MaxRow()) nRow2 = rDocument.MaxRow();
1145  if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
1146  for (SCCOL i = nCol1; i <= nCol2; i++)
1147  aCol[i].SetDirtyFromClip(nRow1, nRow2, rBroadcastSpans);
1148 }
1149 
1152  SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1153 {
1154  if ( nCol2 >= aCol.size() ) nCol2 = aCol.size() - 1;
1155  if (nCol2 > rDocument.MaxCol()) nCol2 = rDocument.MaxCol();
1156  if (nRow2 > rDocument.MaxRow()) nRow2 = rDocument.MaxRow();
1157  if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
1158  for (SCCOL i = nCol1; i <= nCol2; i++)
1159  aCol[i].StartListeningFormulaCells(rStartCxt, rEndCxt, nRow1, nRow2);
1160 }
1161 
1163  sc::CopyToDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1164  InsertDeleteFlags nFlags, bool bMarked, ScTable* pDestTab, const ScMarkData* pMarkData,
1165  bool bAsLink, bool bColRowFlags, bool bGlobalNamesToLocal, bool bCopyCaptions )
1166 {
1167  if (!ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2))
1168  return;
1169 
1170  bool bIsUndoDoc = pDestTab->rDocument.IsUndo();
1171 
1172  if (bIsUndoDoc && (nFlags & InsertDeleteFlags::CONTENTS))
1173  {
1174  // Copying formulas may create sheet-local named expressions on the
1175  // destination sheet. Add existing to Undo first.
1176  pDestTab->SetRangeName( std::unique_ptr<ScRangeName>( new ScRangeName( *GetRangeName())));
1177  }
1178 
1179  if (nFlags != InsertDeleteFlags::NONE)
1180  {
1181  InsertDeleteFlags nTempFlags( nFlags &
1183  // tdf#102364 - in some pathological cases CopyToTable() replacing cells with new cells
1184  // can lead to repetitive splitting and rejoining of the same formula group, which can get
1185  // quadratically expensive with large groups. So do the grouping just once at the end.
1186  sc::DelayFormulaGroupingSwitch delayGrouping( pDestTab->rDocument, true );
1187  for (SCCOL i = nCol1; i <= ClampToAllocatedColumns(nCol2); i++)
1188  aCol[i].CopyToColumn(rCxt, nRow1, nRow2, bIsUndoDoc ? nFlags : nTempFlags, bMarked,
1189  pDestTab->CreateColumnIfNotExists(i), pMarkData, bAsLink, bGlobalNamesToLocal);
1190  }
1191 
1192  if (!bColRowFlags) // Column widths/Row heights/Flags
1193  return;
1194 
1195  if(bIsUndoDoc && (nFlags & InsertDeleteFlags::ATTRIB))
1196  {
1197  pDestTab->mpCondFormatList.reset(new ScConditionalFormatList(pDestTab->rDocument, *mpCondFormatList));
1198  }
1199 
1200  if (pDBDataNoName)
1201  {
1202  std::unique_ptr<ScDBData> pNewDBData(new ScDBData(*pDBDataNoName));
1203  SCCOL aCol1, aCol2;
1204  SCROW aRow1, aRow2;
1205  SCTAB aTab;
1206  pNewDBData->GetArea(aTab, aCol1, aRow1, aCol2, aRow2);
1207  pNewDBData->MoveTo(pDestTab->nTab, aCol1, aRow1, aCol2, aRow2);
1208  pDestTab->SetAnonymousDBData(std::move(pNewDBData));
1209  }
1210  // Charts have to be adjusted when hide/show
1212 
1213  bool bFlagChange = false;
1214 
1215  bool bWidth = (nRow1==0 && nRow2==rDocument.MaxRow() && mpColWidth && pDestTab->mpColWidth);
1216  bool bHeight = (nCol1==0 && nCol2==rDocument.MaxCol() && mpRowHeights && pDestTab->mpRowHeights);
1217 
1218  if (bWidth || bHeight)
1219  {
1220  if (bWidth)
1221  {
1222  auto destTabColWidthIt = pDestTab->mpColWidth->begin() + nCol1;
1223  auto thisTabColWidthIt = mpColWidth->begin() + nCol1;
1224  pDestTab->mpColWidth->CopyFrom(*mpColWidth, nCol1, nCol2);
1225  pDestTab->mpColFlags->CopyFrom(*mpColFlags, nCol1, nCol2);
1226  for (SCCOL i = nCol1; i <= nCol2; ++i)
1227  {
1228  bool bThisHidden = ColHidden(i);
1229  bool bHiddenChange = (pDestTab->ColHidden(i) != bThisHidden);
1230  bool bChange = bHiddenChange || (*destTabColWidthIt != *thisTabColWidthIt);
1231  pDestTab->SetColHidden(i, i, bThisHidden);
1232  //TODO: collect changes?
1233  if (bHiddenChange && pCharts)
1234  pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, rDocument.MaxRow(), nTab ));
1235 
1236  if (bChange)
1237  bFlagChange = true;
1238 
1239  ++destTabColWidthIt;
1240  ++thisTabColWidthIt;
1241  }
1243  }
1244 
1245  if (bHeight)
1246  {
1247  bool bChange = pDestTab->GetRowHeight(nRow1, nRow2) != GetRowHeight(nRow1, nRow2);
1248 
1249  if (bChange)
1250  bFlagChange = true;
1251 
1252  pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0);
1253  pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2);
1254 
1255  // Hidden flags.
1256  for (SCROW i = nRow1; i <= nRow2; ++i)
1257  {
1258  SCROW nLastRow;
1259  bool bHidden = RowHidden(i, nullptr, &nLastRow);
1260  if (nLastRow >= nRow2)
1261  // the last row shouldn't exceed the upper bound the caller specified.
1262  nLastRow = nRow2;
1263 
1264  bool bHiddenChanged = pDestTab->SetRowHidden(i, nLastRow, bHidden);
1265  if (bHiddenChanged && pCharts)
1266  // Hidden flags differ.
1267  pCharts->SetRangeDirty(ScRange(0, i, nTab, rDocument.MaxCol(), nLastRow, nTab));
1268 
1269  if (bHiddenChanged)
1270  bFlagChange = true;
1271 
1272  // Jump to the last row of the identical flag segment.
1273  i = nLastRow;
1274  }
1275 
1276  // Filtered flags.
1277  for (SCROW i = nRow1; i <= nRow2; ++i)
1278  {
1279  SCROW nLastRow;
1280  bool bFiltered = RowFiltered(i, nullptr, &nLastRow);
1281  if (nLastRow >= nRow2)
1282  // the last row shouldn't exceed the upper bound the caller specified.
1283  nLastRow = nRow2;
1284  pDestTab->SetRowFiltered(i, nLastRow, bFiltered);
1285  i = nLastRow;
1286  }
1288  }
1289  }
1290 
1291  if (bFlagChange)
1292  pDestTab->InvalidatePageBreaks();
1293 
1294  if(nFlags & InsertDeleteFlags::ATTRIB)
1295  {
1296  pDestTab->mpCondFormatList->DeleteArea(nCol1, nRow1, nCol2, nRow2);
1297  pDestTab->CopyConditionalFormat(nCol1, nRow1, nCol2, nRow2, 0, 0, this);
1298  }
1299 
1300  if(nFlags & InsertDeleteFlags::OUTLINE) // also only when bColRowFlags
1301  pDestTab->SetOutlineTable( pOutlineTable.get() );
1302 
1303  if (!bIsUndoDoc && bCopyCaptions && (nFlags & (InsertDeleteFlags::NOTE | InsertDeleteFlags::ADDNOTES)))
1304  {
1305  bool bCloneCaption = (nFlags & InsertDeleteFlags::NOCAPTIONS) == InsertDeleteFlags::NONE;
1306  CopyCaptionsToTable( nCol1, nRow1, nCol2, nRow2, pDestTab, bCloneCaption);
1307  }
1308 }
1309 
1310 void ScTable::CopyCaptionsToTable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScTable* pDestTab,
1311  bool bCloneCaption )
1312 {
1313  if (!ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2))
1314  return;
1315 
1316  nCol2 = ClampToAllocatedColumns(nCol2);
1317  for (SCCOL i = nCol1; i <= nCol2; i++)
1318  {
1319  aCol[i].CopyCellNotesToDocument(nRow1, nRow2, pDestTab->CreateColumnIfNotExists(i), bCloneCaption);
1320  pDestTab->aCol[i].UpdateNoteCaptions(nRow1, nRow2);
1321  }
1322 }
1323 
1325  sc::CopyToDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1326  InsertDeleteFlags nFlags, bool bMarked, ScTable* pDestTab )
1327 {
1328  if (!(ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2)))
1329  return;
1330 
1331  bool bWidth = (nRow1==0 && nRow2==rDocument.MaxRow() && mpColWidth && pDestTab->mpColWidth);
1332  bool bHeight = (nCol1==0 && nCol2==rDocument.MaxCol() && mpRowHeights && pDestTab->mpRowHeights);
1333 
1334  if ((nFlags & InsertDeleteFlags::CONTENTS) && mpRangeName)
1335  {
1336  // Undo sheet-local named expressions created during copying
1337  // formulas. If mpRangeName is not set then the Undo wasn't even
1338  // set to an empty ScRangeName map so don't "undo" that.
1339  pDestTab->SetRangeName( std::unique_ptr<ScRangeName>( new ScRangeName( *GetRangeName())));
1340  if (!pDestTab->rDocument.IsClipOrUndo())
1341  {
1342  ScDocShell* pDocSh = static_cast<ScDocShell*>(pDestTab->rDocument.GetDocumentShell());
1343  if (pDocSh)
1344  pDocSh->SetAreasChangedNeedBroadcast();
1345  }
1346 
1347  }
1348 
1349  for ( SCCOL i = 0; i < aCol.size(); i++)
1350  {
1351  auto& rDestCol = pDestTab->CreateColumnIfNotExists(i);
1352  if ( i >= nCol1 && i <= nCol2 )
1353  aCol[i].UndoToColumn(rCxt, nRow1, nRow2, nFlags, bMarked, rDestCol);
1354  else
1355  aCol[i].CopyToColumn(rCxt, 0, rDocument.MaxRow(), InsertDeleteFlags::FORMULA, false, rDestCol);
1356  }
1357 
1358  if (nFlags & InsertDeleteFlags::ATTRIB)
1359  pDestTab->mpCondFormatList.reset(new ScConditionalFormatList(pDestTab->rDocument, *mpCondFormatList));
1360 
1361  if (!(bWidth||bHeight))
1362  return;
1363 
1364  if (bWidth)
1365  {
1366  pDestTab->mpColWidth->CopyFrom(*mpColWidth, nCol1, nCol2);
1368  }
1369  if (bHeight)
1370  {
1371  pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0);
1373  }
1374 }
1375 
1376 void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const
1377 {
1378  pPosTab->CreateColumnIfNotExists(aCol.size()-1);
1379  pDestTab->CreateColumnIfNotExists(aCol.size()-1);
1380  for (SCCOL i=0; i < aCol.size(); i++)
1381  aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
1382 }
1383 
1385 {
1386  bTableAreaValid = false;
1387 }
1388 
1390 {
1391  mbPageBreaksValid = false;
1392 }
1393 
1394 void ScTable::CopyScenarioTo( const ScTable* pDestTab ) const
1395 {
1396  OSL_ENSURE( bScenario, "bScenario == FALSE" );
1397 
1398  for (SCCOL i=0; i < aCol.size(); i++)
1400 }
1401 
1402 void ScTable::CopyScenarioFrom( const ScTable* pSrcTab )
1403 {
1404  OSL_ENSURE( bScenario, "bScenario == FALSE" );
1405 
1406  SCCOL nEndCol = pSrcTab->aCol.size();
1407  CreateColumnIfNotExists(nEndCol);
1408  for (SCCOL i=0; i < nEndCol; i++)
1409  aCol[i].CopyScenarioFrom( pSrcTab->aCol[i] );
1410 }
1411 
1412 void ScTable::MarkScenarioIn( ScMarkData& rDestMark, ScScenarioFlags nNeededBits ) const
1413 {
1414  OSL_ENSURE( bScenario, "bScenario == FALSE" );
1415 
1416  if ( ( nScenarioFlags & nNeededBits ) != nNeededBits ) // Are all Bits set?
1417  return;
1418 
1419  for (SCCOL i=0; i < aCol.size(); i++)
1420  aCol[i].MarkScenarioIn( rDestMark );
1421 }
1422 
1423 bool ScTable::HasScenarioRange( const ScRange& rRange ) const
1424 {
1425  OSL_ENSURE( bScenario, "bScenario == FALSE" );
1426 
1427  ScRange aTabRange = rRange;
1428  aTabRange.aStart.SetTab( nTab );
1429  aTabRange.aEnd.SetTab( nTab );
1430 
1431  const ScRangeList* pList = GetScenarioRanges();
1432 
1433  if (pList)
1434  {
1435  for ( size_t j = 0, n = pList->size(); j < n; j++ )
1436  {
1437  const ScRange & rR = (*pList)[j];
1438  if ( rR.Intersects( aTabRange ) )
1439  return true;
1440  }
1441  }
1442 
1443  return false;
1444 }
1445 
1447 {
1448  pScenarioRanges.reset();
1449 }
1450 
1452 {
1453  OSL_ENSURE( bScenario, "bScenario == FALSE" );
1454 
1455  if (!pScenarioRanges)
1456  {
1457  const_cast<ScTable*>(this)->pScenarioRanges.reset(new ScRangeList);
1458  ScMarkData aMark(rDocument.GetSheetLimits());
1459  MarkScenarioIn( aMark, ScScenarioFlags::NONE ); // always
1460  aMark.FillRangeListWithMarks( pScenarioRanges.get(), false );
1461  }
1462  return pScenarioRanges.get();
1463 }
1464 
1465 bool ScTable::TestCopyScenarioTo( const ScTable* pDestTab ) const
1466 {
1467  OSL_ENSURE( bScenario, "bScenario == FALSE" );
1468 
1469  if (!pDestTab->IsProtected())
1470  return true;
1471 
1472  bool bOk = true;
1473  for (SCCOL i=0; i < aCol.size() && bOk; i++)
1474  bOk = aCol[i].TestCopyScenarioTo( pDestTab->aCol[i] );
1475  return bOk;
1476 }
1477 
1478 bool ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const OUString& rString,
1479  const ScSetStringParam * pParam )
1480 {
1481  if (!ValidColRow(nCol,nRow))
1482  {
1483  return false;
1484  }
1485 
1486  return CreateColumnIfNotExists(nCol).SetString(
1487  nRow, nTabP, rString, rDocument.GetAddressConvention(), pParam);
1488 }
1489 
1490 bool ScTable::SetEditText( SCCOL nCol, SCROW nRow, std::unique_ptr<EditTextObject> pEditText )
1491 {
1492  if (!ValidColRow(nCol, nRow))
1493  {
1494  return false;
1495  }
1496 
1497  CreateColumnIfNotExists(nCol).SetEditText(nRow, std::move(pEditText));
1498  return true;
1499 }
1500 
1501 void ScTable::SetEditText( SCCOL nCol, SCROW nRow, const EditTextObject& rEditText, const SfxItemPool* pEditPool )
1502 {
1503  if (!ValidColRow(nCol, nRow))
1504  return;
1505 
1506  CreateColumnIfNotExists(nCol).SetEditText(nRow, rEditText, pEditPool);
1507 }
1508 
1509 SCROW ScTable::GetFirstEditTextRow( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
1510 {
1511  if (!ValidCol(nCol1) || !ValidCol(nCol2) || nCol2 < nCol1)
1512  return -1;
1513 
1514  if (!ValidRow(nRow1) || !ValidRow(nRow2) || nRow2 < nRow1)
1515  return -1;
1516 
1517  nCol2 = ClampToAllocatedColumns(nCol2);
1518  SCROW nFirst = rDocument.MaxRow()+1;
1519  for (SCCOL i = nCol1; i <= nCol2; ++i)
1520  {
1521  const ScColumn& rCol = aCol[i];
1522  SCROW nThisFirst = -1;
1523  if (const_cast<ScColumn&>(rCol).HasEditCells(nRow1, nRow2, nThisFirst))
1524  {
1525  if (nThisFirst == nRow1)
1526  return nRow1;
1527 
1528  if (nThisFirst < nFirst)
1529  nFirst = nThisFirst;
1530  }
1531  }
1532 
1533  return nFirst == (rDocument.MaxRow()+1) ? -1 : nFirst;
1534 }
1535 
1537 {
1538  if (!ValidColRow(nCol, nRow) || nCol >= GetAllocatedColumnsCount())
1539  return;
1540 
1541  aCol[nCol].Delete(nRow);
1542 }
1543 
1545  SCCOL nCol, SCROW nRow, const ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGram )
1546 {
1547  if (!ValidColRow(nCol, nRow))
1548  return;
1549 
1550  CreateColumnIfNotExists(nCol).SetFormula(nRow, rArray, eGram);
1551 }
1552 
1554  SCCOL nCol, SCROW nRow, const OUString& rFormula, formula::FormulaGrammar::Grammar eGram )
1555 {
1556  if (!ValidColRow(nCol, nRow))
1557  return;
1558 
1559  CreateColumnIfNotExists(nCol).SetFormula(nRow, rFormula, eGram);
1560 }
1561 
1563 {
1564  if (!ValidColRow(nCol, nRow))
1565  {
1566  delete pCell;
1567  return nullptr;
1568  }
1569 
1571 }
1572 
1573 bool ScTable::SetFormulaCells( SCCOL nCol, SCROW nRow, std::vector<ScFormulaCell*>& rCells )
1574 {
1575  if (!ValidCol(nCol))
1576  return false;
1577 
1578  return CreateColumnIfNotExists(nCol).SetFormulaCells(nRow, rCells);
1579 }
1580 
1582 {
1583  if (!ValidColRow(nCol, nRow) || nCol >= GetAllocatedColumnsCount())
1584  return svl::SharedString();
1585 
1586  return aCol[nCol].GetSharedString(nRow);
1587 }
1588 
1589 void ScTable::SetValue( SCCOL nCol, SCROW nRow, const double& rVal )
1590 {
1591  if (ValidColRow(nCol, nRow))
1592  CreateColumnIfNotExists(nCol).SetValue(nRow, rVal);
1593 }
1594 
1595 void ScTable::SetRawString( SCCOL nCol, SCROW nRow, const svl::SharedString& rStr )
1596 {
1597  if (ValidColRow(nCol, nRow))
1598  CreateColumnIfNotExists(nCol).SetRawString(nRow, rStr);
1599 }
1600 
1601 void ScTable::GetString( SCCOL nCol, SCROW nRow, OUString& rString, const ScInterpreterContext* pContext ) const
1602 {
1603  if (ValidColRow(nCol,nRow) && nCol < GetAllocatedColumnsCount())
1604  aCol[nCol].GetString( nRow, rString, pContext );
1605  else
1606  rString.clear();
1607 }
1608 
1609 double* ScTable::GetValueCell( SCCOL nCol, SCROW nRow )
1610 {
1611  if (!ValidColRow(nCol, nRow))
1612  return nullptr;
1613 
1614  return CreateColumnIfNotExists(nCol).GetValueCell(nRow);
1615 }
1616 
1617 void ScTable::GetInputString( SCCOL nCol, SCROW nRow, OUString& rString ) const
1618 {
1619  if (ValidColRow(nCol, nRow) && nCol < GetAllocatedColumnsCount())
1620  aCol[nCol].GetInputString( nRow, rString );
1621  else
1622  rString.clear();
1623 }
1624 
1625 double ScTable::GetValue( SCCOL nCol, SCROW nRow ) const
1626 {
1627  if (ValidColRow(nCol, nRow) && nCol < GetAllocatedColumnsCount())
1628  return aCol[nCol].GetValue( nRow );
1629  return 0.0;
1630 }
1631 
1633 {
1634  if (!ValidColRow(nCol, nRow) || nCol >= GetAllocatedColumnsCount())
1635  return nullptr;
1636 
1637  return aCol[nCol].GetEditText(nRow);
1638 }
1639 
1641 {
1642  if (!ValidColRow(nCol, nRow) || nCol >= GetAllocatedColumnsCount())
1643  return;
1644 
1645  return aCol[nCol].RemoveEditTextCharAttribs(nRow, rAttr);
1646 }
1647 
1648 void ScTable::GetFormula( SCCOL nCol, SCROW nRow, OUString& rFormula ) const
1649 {
1650  if (ValidColRow(nCol, nRow) && nCol < GetAllocatedColumnsCount())
1651  aCol[nCol].GetFormula( nRow, rFormula );
1652  else
1653  rFormula.clear();
1654 }
1655 
1657 {
1658  if (!ValidColRow(nCol, nRow) || nCol >= GetAllocatedColumnsCount())
1659  return nullptr;
1660 
1661  return aCol[nCol].GetFormulaCell(nRow);
1662 }
1663 
1665 {
1666  if (!ValidColRow(nCol, nRow))
1667  return nullptr;
1668  return CreateColumnIfNotExists(nCol).GetFormulaCell(nRow);
1669 }
1670 
1671 std::unique_ptr<ScPostIt> ScTable::ReleaseNote( SCCOL nCol, SCROW nRow )
1672 {
1673  if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount())
1674  return nullptr;
1675 
1676  return aCol[nCol].ReleaseNote(nRow);
1677 }
1678 
1679 size_t ScTable::GetNoteCount( SCCOL nCol ) const
1680 {
1681  if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount())
1682  return 0;
1683 
1684  return aCol[nCol].GetNoteCount();
1685 }
1686 
1687 SCROW ScTable::GetNotePosition( SCCOL nCol, size_t nIndex ) const
1688 {
1689  if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount())
1690  return -1;
1691 
1692  return aCol[nCol].GetNotePosition(nIndex);
1693 }
1694 
1696 {
1697  for (SCCOL i = 0; i < aCol.size(); ++i)
1699 }
1700 
1701 void ScTable::ForgetNoteCaptions( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bPreserveData )
1702 {
1703  if (!ValidCol(nCol1) || !ValidCol(nCol2))
1704  return;
1705  if ( nCol2 >= aCol.size() ) nCol2 = aCol.size() - 1;
1706  for (SCCOL i = nCol1; i <= nCol2; ++i)
1707  aCol[i].ForgetNoteCaptions(nRow1, nRow2, bPreserveData);
1708 }
1709 
1710 void ScTable::GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const
1711 {
1712  for (SCCOL nCol = 0; nCol < aCol.size(); ++nCol)
1713  aCol[nCol].GetAllNoteEntries(rNotes);
1714 }
1715 
1716 void ScTable::GetNotesInRange( const ScRange& rRange, std::vector<sc::NoteEntry>& rNotes ) const
1717 {
1718  SCROW nStartRow = rRange.aStart.Row();
1719  SCROW nEndRow = rRange.aEnd.Row();
1720  SCCOL nEndCol = ClampToAllocatedColumns(rRange.aEnd.Col());
1721  for (SCCOL nCol = rRange.aStart.Col(); nCol <= nEndCol; ++nCol)
1722  {
1723  aCol[nCol].GetNotesInRange(nStartRow, nEndRow, rNotes);
1724  }
1725 }
1726 
1727 CommentCaptionState ScTable::GetAllNoteCaptionsState(const ScRange& rRange, std::vector<sc::NoteEntry>& rNotes )
1728 {
1729  SCROW nStartRow = rRange.aStart.Row();
1730  SCROW nEndRow = rRange.aEnd.Row();
1731  bool bIsFirstNoteShownState = true; // because of error: -Werror=maybe-uninitialized
1732  bool bFirstControl = true;
1733 
1734  ScTable* pTab = rDocument.FetchTable(nTab);
1735  assert(pTab);
1736  const SCCOL nEndCol = pTab->ClampToAllocatedColumns(rRange.aEnd.Col());
1737  for (SCCOL nCol = rRange.aStart.Col(); nCol <= nEndCol; ++nCol)
1738  {
1739  if (bFirstControl && rDocument.HasColNotes(nCol, nTab)) // detect status of first note caption
1740  {
1741  aCol[nCol].GetNotesInRange(nStartRow, nEndRow, rNotes);
1742  bIsFirstNoteShownState = rNotes.begin()->mpNote->IsCaptionShown();
1743  bFirstControl = false;
1744  }
1745 
1746  if (rDocument.HasColNotes(nCol, nTab))
1747  {
1748  aCol[nCol].GetNotesInRange(nStartRow, nEndRow, rNotes);
1749 
1750  bool bIsMixedState = std::any_of(rNotes.begin(), rNotes.end(), [bIsFirstNoteShownState](const sc::NoteEntry& rNote) {
1751  // compare the first note caption with others
1752  return bIsFirstNoteShownState != rNote.mpNote->IsCaptionShown(); });
1753  if (bIsMixedState)
1755  }
1756  }
1757  return bIsFirstNoteShownState ? CommentCaptionState::ALLSHOWN : CommentCaptionState::ALLHIDDEN;
1758 }
1759 
1761 {
1762  for (auto const & pCol : aCol)
1763  pCol->GetUnprotectedCells(0, rDocument.MaxRow(), rRangeList);
1764 }
1765 
1766 bool ScTable::ContainsNotesInRange( const ScRange& rRange ) const
1767 {
1768  SCROW nStartRow = rRange.aStart.Row();
1769  SCROW nEndRow = rRange.aEnd.Row();
1770  SCCOL nEndCol = ClampToAllocatedColumns(rRange.aEnd.Col());
1771  for (SCCOL nCol = rRange.aStart.Col(); nCol <= nEndCol; ++nCol)
1772  {
1773  bool bContainsNote = !aCol[nCol].IsNotesEmptyBlock(nStartRow, nEndRow);
1774  if(bContainsNote)
1775  return true;
1776  }
1777 
1778  return false;
1779 }
1780 
1782 {
1783  if (ValidColRow(nCol, nRow) && nCol < GetAllocatedColumnsCount())
1784  return aCol[nCol].GetCellType( nRow );
1785  return CELLTYPE_NONE;
1786 }
1787 
1789 {
1790  if (!ValidColRow(nCol, nRow) || nCol >= GetAllocatedColumnsCount())
1791  return ScRefCellValue();
1792 
1793  return aCol[nCol].GetCellValue(nRow);
1794 }
1795 
1796 void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
1797 {
1798  rCol = 0;
1799  rRow = rDocument.MaxRow()+1;
1800  while (rCol < (aCol.size() - 1) && aCol[rCol].IsEmptyData() )
1801  ++rCol;
1802  SCCOL nCol = rCol;
1803  while (nCol < aCol.size() && rRow > 0)
1804  {
1805  if (!aCol[nCol].IsEmptyData())
1806  rRow = ::std::min( rRow, aCol[nCol].GetFirstDataPos());
1807  ++nCol;
1808  }
1809 }
1810 
1811 void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
1812 {
1813  rCol = aCol.size() - 1;
1814  rRow = 0;
1815  while (aCol[rCol].IsEmptyData() && (rCol > 0))
1816  rCol--;
1817  SCCOL nCol = rCol;
1818  while (nCol >= 0 && rRow < rDocument.MaxRow())
1819  rRow = ::std::max( rRow, aCol[nCol--].GetLastDataPos());
1820 }
1821 
1822 bool ScTable::HasData( SCCOL nCol, SCROW nRow ) const
1823 {
1824  if (ValidColRow(nCol, nRow) && nCol < GetAllocatedColumnsCount())
1825  return aCol[nCol].HasDataAt( nRow );
1826  else
1827  return false;
1828 }
1829 
1830 bool ScTable::HasStringData( SCCOL nCol, SCROW nRow ) const
1831 {
1832  if (ValidColRow(nCol, nRow) && nCol < GetAllocatedColumnsCount())
1833  return aCol[nCol].HasStringData( nRow );
1834  else
1835  return false;
1836 }
1837 
1838 bool ScTable::HasValueData( SCCOL nCol, SCROW nRow ) const
1839 {
1840  if (ValidColRow(nCol, nRow) && nCol < GetAllocatedColumnsCount())
1841  return aCol[nCol].HasValueData( nRow );
1842  else
1843  return false;
1844 }
1845 
1846 bool ScTable::HasStringCells( SCCOL nStartCol, SCROW nStartRow,
1847  SCCOL nEndCol, SCROW nEndRow ) const
1848 {
1849  if (ValidCol(nEndCol))
1850  {
1851  nEndCol = ClampToAllocatedColumns(nEndCol);
1852  for (SCCOL nCol = nStartCol; nCol <= nEndCol; nCol++)
1853  if (aCol[nCol].HasStringCells(nStartRow, nEndRow))
1854  return true;
1855  }
1856 
1857  return false;
1858 }
1859 
1861 {
1862  for (SCCOL i=0; i < aCol.size(); i++)
1863  aCol[i].SetDirtyVar();
1864 }
1865 
1867 {
1868  sc::AutoCalcSwitch aACSwitch(rDocument, false);
1869 
1870  for (SCCOL i = 0; i < aCol.size(); i++)
1872 }
1873 
1875 {
1876  sc::AutoCalcSwitch aACSwitch(rDocument, false);
1877 
1878  for (SCCOL i=0; i < aCol.size(); i++)
1879  aCol[i].SetAllFormulasDirty(rCxt);
1880 }
1881 
1883 {
1884  bool bOldAutoCalc = rDocument.GetAutoCalc();
1885  rDocument.SetAutoCalc( false ); // avoid multiple recalculations
1886  SCCOL nCol2 = rRange.aEnd.Col();
1887  nCol2 = ClampToAllocatedColumns(nCol2);
1888  for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
1889  aCol[i].SetDirty(rRange.aStart.Row(), rRange.aEnd.Row(), eMode);
1890  rDocument.SetAutoCalc( bOldAutoCalc );
1891 }
1892 
1893 void ScTable::SetTableOpDirty( const ScRange& rRange )
1894 {
1895  bool bOldAutoCalc = rDocument.GetAutoCalc();
1896  rDocument.SetAutoCalc( false ); // no multiple recalculation
1897  const SCCOL nCol2 = ClampToAllocatedColumns(rRange.aEnd.Col());
1898  for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
1899  aCol[i].SetTableOpDirty( rRange );
1900  rDocument.SetAutoCalc( bOldAutoCalc );
1901 }
1902 
1904 {
1905  bool bOldAutoCalc = rDocument.GetAutoCalc();
1906  rDocument.SetAutoCalc( false ); // avoid multiple recalculations
1907  for (SCCOL i=0; i < aCol.size(); i++)
1909  rDocument.SetAutoCalc( bOldAutoCalc );
1910 }
1911 
1913 {
1914  bool bOldAutoCalc = rDocument.GetAutoCalc();
1915  rDocument.SetAutoCalc( false ); // avoid multiple recalculations
1916  for (SCCOL i=0; i < aCol.size(); i++)
1918  rDocument.SetAutoCalc( bOldAutoCalc );
1919 }
1920 
1922 {
1923  sc::AutoCalcSwitch aSwitch(rDocument, false);
1924  for (SCCOL i = 0; i < aCol.size(); ++i)
1926 }
1927 
1928 bool ScTable::BroadcastBroadcasters( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScHint& rHint )
1929 {
1930  bool bBroadcasted = false;
1931  sc::AutoCalcSwitch aSwitch(rDocument, false);
1932  rHint.GetAddress().SetTab(nTab);
1933  nCol2 = ClampToAllocatedColumns(nCol2);
1934  for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
1935  bBroadcasted |= aCol[nCol].BroadcastBroadcasters( nRow1, nRow2, rHint);
1936  return bBroadcasted;
1937 }
1938 
1939 void ScTable::SetLoadingMedium(bool bLoading)
1940 {
1941  mpRowHeights->enableTreeSearch(!bLoading);
1942 }
1943 
1945 {
1946  for (SCCOL i=0; i < aCol.size(); i++)
1947  aCol[i].CalcAll();
1948 
1949  mpCondFormatList->CalcAll();
1950 }
1951 
1953 {
1954  for (SCCOL i = 0; i < aCol.size(); ++i)
1955  aCol[i].CompileAll(rCxt);
1956 
1957  if(mpCondFormatList)
1958  mpCondFormatList->CompileAll();
1959 }
1960 
1962 {
1963  if (mpRangeName)
1964  mpRangeName->CompileUnresolvedXML(rCxt);
1965 
1966  for (SCCOL i=0; i < aCol.size(); i++)
1967  {
1968  aCol[i].CompileXML(rCxt, rProgress);
1969  }
1970 
1971  if(mpCondFormatList)
1972  mpCondFormatList->CompileXML();
1973 }
1974 
1976 {
1977  bool bCompiled = false;
1978  for (SCCOL i = 0; i < aCol.size(); ++i)
1979  {
1980  if (aCol[i].CompileErrorCells(rCxt, nErrCode))
1981  bCompiled = true;
1982  }
1983 
1984  return bCompiled;
1985 }
1986 
1987 void ScTable::CalcAfterLoad( sc::CompileFormulaContext& rCxt, bool bStartListening )
1988 {
1989  for (SCCOL i = 0; i < aCol.size(); ++i)
1990  aCol[i].CalcAfterLoad(rCxt, bStartListening);
1991 }
1992 
1993 void ScTable::ResetChanged( const ScRange& rRange )
1994 {
1995  SCCOL nStartCol = rRange.aStart.Col();
1996  SCROW nStartRow = rRange.aStart.Row();
1997  SCCOL nEndCol = ClampToAllocatedColumns(rRange.aEnd.Col());
1998  SCROW nEndRow = rRange.aEnd.Row();
1999 
2000  for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
2001  aCol[nCol].ResetChanged(nStartRow, nEndRow);
2002 }
2003 
2004 // Attribute
2005 
2006 const SfxPoolItem* ScTable::GetAttr( SCCOL nCol, SCROW nRow, sal_uInt16 nWhich ) const
2007 {
2008  if (ValidColRow(nCol, nRow) && nCol < GetAllocatedColumnsCount())
2009  return &aCol[nCol].GetAttr( nRow, nWhich );
2010  else
2011  return nullptr;
2012 }
2013 
2014 sal_uInt32 ScTable::GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& rPos ) const
2015 {
2016  if (ValidColRow(rPos.Col(), rPos.Row()))
2017  {
2018  if (rPos.Col() < GetAllocatedColumnsCount())
2019  return aCol[rPos.Col()].GetNumberFormat(rContext, rPos.Row());
2020  return aDefaultColAttrArray.GetPattern(rPos.Row())
2021  ->GetNumberFormat(rContext.GetFormatTable());
2022  }
2023  return 0;
2024 }
2025 
2026 sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nRow ) const
2027 {
2028  if (ValidColRow(nCol,nRow))
2029  return CreateColumnIfNotExists(nCol).GetNumberFormat(rDocument.GetNonThreadedContext(), nRow);
2030  else
2031  return 0;
2032 }
2033 
2034 sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
2035 {
2036  if (!ValidCol(nCol) || !ValidRow(nStartRow) || !ValidRow(nEndRow))
2037  return 0;
2038 
2039  return CreateColumnIfNotExists(nCol).GetNumberFormat(nStartRow, nEndRow);
2040 }
2041 
2042 void ScTable::SetNumberFormat( SCCOL nCol, SCROW nRow, sal_uInt32 nNumberFormat )
2043 {
2044  if (!ValidColRow(nCol, nRow))
2045  return;
2046 
2047  CreateColumnIfNotExists(nCol).SetNumberFormat(nRow, nNumberFormat);
2048 }
2049 
2050 const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
2051 {
2052  if (ValidColRow(nCol,nRow))
2053  return CreateColumnIfNotExists(nCol).GetPattern( nRow );
2054  else
2055  {
2056  OSL_FAIL("wrong column or row");
2057  return rDocument.GetDefPattern(); // for safety
2058  }
2059 }
2060 
2061 const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
2062 {
2063  if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow)
2064  && nCol < GetAllocatedColumnsCount())
2065  return aCol[nCol].GetMostUsedPattern( nStartRow, nEndRow );
2066  else
2067  return nullptr;
2068 }
2069 
2070 bool ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, HasAttrFlags nMask ) const
2071 {
2072  if ( nCol1 >= aCol.size() )
2073  return false;
2074  if ( nCol2 >= aCol.size() )
2075  nCol2 = aCol.size() - 1; // Rows above range, doesn't contains flags
2076 
2077  bool bFound = false;
2078  for (SCCOL i=nCol1; i<=nCol2 && !bFound; i++)
2079  bFound |= aCol[i].HasAttrib( nRow1, nRow2, nMask );
2080  return bFound;
2081 }
2082 
2083 bool ScTable::HasAttribSelection( const ScMarkData& rMark, HasAttrFlags nMask ) const
2084 {
2085  std::vector<sc::ColRowSpan> aSpans = rMark.GetMarkedColSpans();
2086 
2087  for (const sc::ColRowSpan & aSpan : aSpans)
2088  {
2089  for (SCCOLROW j = aSpan.mnStart; j <= aSpan.mnEnd; ++j)
2090  {
2091  if (aCol[j].HasAttribSelection(rMark, nMask))
2092  return true;
2093  }
2094  }
2095  return false;
2096 }
2097 
2098 bool ScTable::ExtendMerge( SCCOL nStartCol, SCROW nStartRow,
2099  SCCOL& rEndCol, SCROW& rEndRow,
2100  bool bRefresh )
2101 {
2102  if (!(ValidCol(nStartCol) && ValidCol(rEndCol)))
2103  {
2104  OSL_FAIL("ScTable::ExtendMerge: invalid column number");
2105  return false;
2106  }
2107  if ( nStartCol >= aCol.size() )
2108  {
2109  OSL_FAIL("ScTable::ExtendMerge: invalid nStartCol");
2110  return false;
2111  }
2112  bool bFound = false;
2113  SCCOL nOldEndX = std::min( rEndCol, static_cast<SCCOL>(aCol.size()-1) );
2114  SCROW nOldEndY = rEndRow;
2115  for (SCCOL i=nStartCol; i<=nOldEndX; i++)
2116  bFound |= aCol[i].ExtendMerge( i, nStartRow, nOldEndY, rEndCol, rEndRow, bRefresh );
2117  return bFound;
2118 }
2119 
2120 void ScTable::SetMergedCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2121 {
2122  ScMergeAttr aAttr(nCol2-nCol1+1, nRow2-nRow1+1);
2123  ApplyAttr(nCol1, nRow1, aAttr);
2124 
2125  if (nCol1 < nCol2)
2126  ApplyFlags(nCol1+1, nRow1, nCol2, nRow2, ScMF::Hor);
2127 
2128  if (nRow1 < nRow2)
2129  ApplyFlags(nCol1, nRow1+1, nCol1, nRow2, ScMF::Ver);
2130 
2131  if (nCol1 < nCol2 && nRow1 < nRow2)
2132  ApplyFlags(nCol1+1, nRow1+1, nCol2, nRow2, ScMF::Hor | ScMF::Ver);
2133 }
2134 
2135 bool ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes ) const
2136 {
2137  if (!(ValidCol(nCol1) && ValidCol(nCol2)))
2138  {
2139  OSL_FAIL("ScTable::IsBlockEmpty: invalid column number");
2140  return false;
2141  }
2142  nCol2 = ClampToAllocatedColumns(nCol2);
2143  bool bEmpty = true;
2144  for (SCCOL i=nCol1; i<=nCol2 && bEmpty; i++)
2145  {
2146  bEmpty = aCol[i].IsEmptyBlock( nRow1, nRow2 );
2147  if (!bIgnoreNotes && bEmpty)
2148  {
2149  bEmpty = aCol[i].IsNotesEmptyBlock(nRow1, nRow2);
2150  }
2151  }
2152  return bEmpty;
2153 }
2154 
2155 SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
2156  SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY,
2157  const ScPatternAttr* pPattern, const SfxItemSet* pCondSet )
2158 {
2159  // Return value = new nArrY
2160 
2161  ScRotateDir nRotDir = pPattern->GetRotateDir( pCondSet );
2162  if ( nRotDir != ScRotateDir::NONE )
2163  {
2164  bool bHit = true;
2165  if ( nCol+1 < nX1 ) // column to the left
2166  bHit = ( nRotDir != ScRotateDir::Left );
2167  else if ( nCol > nX2+1 ) // column to the right
2168  bHit = ( nRotDir != ScRotateDir::Right ); // ScRotateDir::Standard may now also be extended to the left
2169 
2170  if ( bHit )
2171  {
2172  double nFactor = 0.0;
2173  if ( nCol > nX2+1 )
2174  {
2175  long nRotVal = pPattern->
2176  GetItem( ATTR_ROTATE_VALUE, pCondSet ).GetValue();
2177  double nRealOrient = nRotVal * F_PI18000; // 1/100 degree
2178  double nCos = cos( nRealOrient );
2179  double nSin = sin( nRealOrient );
2180  //TODO: limit !!!
2181  //TODO: additional factor for varying PPT X/Y !!!
2182 
2183  // for ScRotateDir::Left this gives a negative value,
2184  // if the mode is considered
2185  nFactor = -fabs( nCos / nSin );
2186  }
2187 
2188  for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ )
2189  {
2190  if (!RowHidden(nRow))
2191  {
2192  bool bHitOne = true;
2193  if ( nCol > nX2+1 )
2194  {
2195  // Does the rotated cell extend into the visible range?
2196 
2197  SCCOL nTouchedCol = nCol;
2198  long nWidth = static_cast<long>(mpRowHeights->getValue(nRow) * nFactor);
2199  OSL_ENSURE(nWidth <= 0, "Wrong direction");
2200  while ( nWidth < 0 && nTouchedCol > 0 )
2201  {
2202  --nTouchedCol;
2203  nWidth += GetColWidth( nTouchedCol );
2204  }
2205  if ( nTouchedCol > nX2 )
2206  bHitOne = false;
2207  }
2208 
2209  if (bHitOne)
2210  {
2211  while ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo < nRow )
2212  ++nArrY;
2213  if ( nArrY<nArrCount && pRowInfo[nArrY].nRowNo == nRow )
2214  pRowInfo[nArrY].nRotMaxCol = nCol;
2215  }
2216  }
2217  }
2218  }
2219  }
2220 
2221  return nArrY;
2222 }
2223 
2224 void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 )
2225 {
2226  if ( !mpColWidth || !mpRowHeights || !mpColFlags || !pRowFlags )
2227  {
2228  OSL_FAIL( "Row/column info missing" );
2229  return;
2230  }
2231 
2232  // nRotMaxCol is initialized to SC_ROTMAX_NONE, nRowNo is already set
2233 
2234  SCROW nY1 = pRowInfo[0].nRowNo;
2235  SCROW nY2 = pRowInfo[nArrCount-1].nRowNo;
2236 
2237  for (SCCOL nCol : GetColumnsRange(0, rDocument.MaxCol()))
2238  {
2239  if (!ColHidden(nCol))
2240  {
2241  SCSIZE nArrY = 0;
2242  ScDocAttrIterator aIter( rDocument, nTab, nCol, nY1, nCol, nY2 );
2243  SCCOL nAttrCol;
2244  SCROW nAttrRow1, nAttrRow2;
2245  const ScPatternAttr* pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
2246  while ( pPattern )
2247  {
2248  const SfxPoolItem* pCondItem;
2249  if ( pPattern->GetItemSet().GetItemState( ATTR_CONDITIONAL, true, &pCondItem )
2250  == SfxItemState::SET )
2251  {
2252  // Run through all formats, so that each cell does not have to be
2253  // handled individually
2254 
2255  const ScCondFormatIndexes& rCondFormatData = static_cast<const ScCondFormatItem*>(pCondItem)->GetCondFormatData();
2256  ScStyleSheetPool* pStylePool = rDocument.GetStyleSheetPool();
2257  if (mpCondFormatList && pStylePool && !rCondFormatData.empty())
2258  {
2259  for(const auto& rItem : rCondFormatData)
2260  {
2261  const ScConditionalFormat* pFormat = mpCondFormatList->GetFormat(rItem);
2262  if ( pFormat )
2263  {
2264  size_t nEntryCount = pFormat->size();
2265  for (size_t nEntry=0; nEntry<nEntryCount; nEntry++)
2266  {
2267  const ScFormatEntry* pEntry = pFormat->GetEntry(nEntry);
2268  if(pEntry->GetType() != ScFormatEntry::Type::Condition &&
2270  continue;
2271 
2272  OUString aStyleName = static_cast<const ScCondFormatEntry*>(pEntry)->GetStyle();
2273  if (!aStyleName.isEmpty())
2274  {
2275  SfxStyleSheetBase* pStyleSheet =
2276  pStylePool->Find( aStyleName, SfxStyleFamily::Para );
2277  if ( pStyleSheet )
2278  {
2279  FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
2280  nCol, nAttrRow1, nAttrRow2,
2281  nArrY, pPattern, &pStyleSheet->GetItemSet() );
2282  // not changing nArrY
2283  }
2284  }
2285  }
2286  }
2287  }
2288  }
2289  }
2290 
2291  nArrY = FillMaxRot( pRowInfo, nArrCount, nX1, nX2,
2292  nCol, nAttrRow1, nAttrRow2,
2293  nArrY, pPattern, nullptr );
2294 
2295  pPattern = aIter.GetNext( nAttrCol, nAttrRow1, nAttrRow2 );
2296  }
2297  }
2298  }
2299 }
2300 
2301 bool ScTable::HasBlockMatrixFragment( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2,
2302  bool bNoMatrixAtAll ) const
2303 {
2304  using namespace sc;
2305 
2306  if ( !IsColValid( nCol1 ) )
2307  return false;
2308 
2309  const SCCOL nMaxCol2 = std::min<SCCOL>( nCol2, aCol.size() - 1 );
2310 
2311  MatrixEdge nEdges = MatrixEdge::Nothing;
2312 
2313  if ( nCol1 == nMaxCol2 )
2314  { // left and right column
2316  nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, n, bNoMatrixAtAll );
2317  if ((nEdges != MatrixEdge::Nothing) && (((nEdges & n)!=n) || (nEdges & (MatrixEdge::Inside|MatrixEdge::Open))))
2318  return true; // left or right edge is missing or open
2319  }
2320  else
2321  { // left column
2322  nEdges = aCol[nCol1].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdge::Left, bNoMatrixAtAll);
2323  if ((nEdges != MatrixEdge::Nothing) && ((!(nEdges & MatrixEdge::Left)) || (nEdges & (MatrixEdge::Inside|MatrixEdge::Open))))
2324  return true; // left edge missing or open
2325  // right column
2326  nEdges = aCol[nMaxCol2].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdge::Right, bNoMatrixAtAll);
2327  if ((nEdges != MatrixEdge::Nothing) && ((!(nEdges & MatrixEdge::Right)) || (nEdges & (MatrixEdge::Inside|MatrixEdge::Open))))
2328  return true; // right edge is missing or open
2329  }
2330 
2331  if (bNoMatrixAtAll)
2332  {
2333  for (SCCOL i=nCol1; i<=nMaxCol2; i++)
2334  {
2335  nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow2, MatrixEdge::Nothing, bNoMatrixAtAll);
2336  if (nEdges != MatrixEdge::Nothing
2337  && (nEdges != (MatrixEdge::Top | MatrixEdge::Left | MatrixEdge::Bottom | MatrixEdge::Right)))
2338  return true;
2339  }
2340  }
2341  else if ( nRow1 == nRow2 )
2342  { // Row on top and on bottom
2343  bool bOpen = false;
2344  const MatrixEdge n = MatrixEdge::Bottom | MatrixEdge::Top;
2345  for ( SCCOL i=nCol1; i<=nMaxCol2; i++)
2346  {
2347  nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow1, n, bNoMatrixAtAll );
2348  if (nEdges != MatrixEdge::Nothing)
2349  {
2350  if ( (nEdges & n) != n )
2351  return true; // Top or bottom edge missing
2352  if (nEdges & MatrixEdge::Left)
2353  bOpen = true; // left edge open, continue
2354  else if ( !bOpen )
2355  return true; // Something exist that has not been opened
2356  if (nEdges & MatrixEdge::Right)
2357  bOpen = false; // Close right edge
2358  }
2359  }
2360  if ( bOpen )
2361  return true;
2362  }
2363  else
2364  {
2365  int j;
2366  MatrixEdge n;
2367  SCROW nR;
2368  // first top row, then bottom row
2369  for ( j=0, n = MatrixEdge::Top, nR=nRow1; j<2;
2370  j++, n = MatrixEdge::Bottom, nR=nRow2)
2371  {
2372  bool bOpen = false;
2373  for ( SCCOL i=nCol1; i<=nMaxCol2; i++)
2374  {
2375  nEdges = aCol[i].GetBlockMatrixEdges( nR, nR, n, bNoMatrixAtAll );
2376  if ( nEdges != MatrixEdge::Nothing)
2377  {
2378  // in top row no top edge respectively
2379  // in bottom row no bottom edge
2380  if ( (nEdges & n) != n )
2381  return true;
2382  if (nEdges & MatrixEdge::Left)
2383  bOpen = true; // open left edge, continue
2384  else if ( !bOpen )
2385  return true; // Something exist that has not been opened
2386  if (nEdges & MatrixEdge::Right)
2387  bOpen = false; // Close right edge
2388  }
2389  }
2390  if ( bOpen )
2391  return true;
2392  }
2393  }
2394  return false;
2395 }
2396 
2398 {
2399  std::vector<sc::ColRowSpan> aSpans = rMark.GetMarkedColSpans();
2400 
2401  for (const sc::ColRowSpan & aSpan : aSpans)
2402  {
2403  SCCOL nEndCol = ClampToAllocatedColumns(aSpan.mnEnd);
2404  for ( SCCOLROW j=aSpan.mnStart; j<=nEndCol; j++ )
2405  {
2406  if ( aCol[j].HasSelectionMatrixFragment(rMark) )
2407  return true;
2408  }
2409  }
2410  return false;
2411 }
2412 
2413 bool ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
2414  SCROW nRow2, bool* pOnlyNotBecauseOfMatrix /* = NULL */,
2415  bool bNoMatrixAtAll ) const
2416 {
2417  if ( !ValidColRow( nCol2, nRow2 ) )
2418  {
2419  SAL_WARN("sc", "IsBlockEditable: invalid column or row " << nCol2 << " " << nRow2);
2420  if (pOnlyNotBecauseOfMatrix)
2421  *pOnlyNotBecauseOfMatrix = false;
2422  return false;
2423  }
2424  nCol1 = ClampToAllocatedColumns(nCol1);
2425  nCol2 = ClampToAllocatedColumns(nCol2);
2426 
2427  bool bIsEditable = true;
2428  if ( nLockCount )
2429  bIsEditable = false;
2430  else if ( IsProtected() && !rDocument.IsScenario(nTab) )
2431  {
2432  bIsEditable = !HasAttrib( nCol1, nRow1, nCol2, nRow2, HasAttrFlags::Protected );
2433  if (!bIsEditable)
2434  {
2435  // An enhanced protection permission may override the attribute.
2436  if (pTabProtection)
2437  bIsEditable = pTabProtection->isBlockEditable( ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab));
2438  }
2439  if (bIsEditable)
2440  {
2441  // If Sheet is protected and cells are not protected then
2442  // check the active scenario protect flag if this range is
2443  // on the active scenario range. Note the 'copy back' must also
2444  // be set to apply protection.
2445  sal_uInt16 nScenTab = nTab+1;
2446  while(rDocument.IsScenario(nScenTab))
2447  {
2448  ScRange aEditRange(nCol1, nRow1, nScenTab, nCol2, nRow2, nScenTab);
2449  if(rDocument.IsActiveScenario(nScenTab) && rDocument.HasScenarioRange(nScenTab, aEditRange))
2450  {
2451  ScScenarioFlags nFlags;
2452  rDocument.GetScenarioFlags(nScenTab,nFlags);
2453  bIsEditable = !((nFlags & ScScenarioFlags::Protected) && (nFlags & ScScenarioFlags::TwoWay));
2454  break;
2455  }
2456  nScenTab++;
2457  }
2458  }
2459  }
2460  else if (rDocument.IsScenario(nTab))
2461  {
2462  // Determine if the preceding sheet is protected
2463  SCTAB nActualTab = nTab;
2464  do
2465  {
2466  nActualTab--;
2467  }
2468  while(rDocument.IsScenario(nActualTab));
2469 
2470  if(rDocument.IsTabProtected(nActualTab))
2471  {
2472  ScRange aEditRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
2473  if(rDocument.HasScenarioRange(nTab, aEditRange))
2474  {
2475  ScScenarioFlags nFlags;
2476  rDocument.GetScenarioFlags(nTab,nFlags);
2477  bIsEditable = !(nFlags & ScScenarioFlags::Protected);
2478  }
2479  }
2480  }
2481  if ( bIsEditable )
2482  {
2483  if (HasBlockMatrixFragment( nCol1, nRow1, nCol2, nRow2, bNoMatrixAtAll))
2484  {
2485  bIsEditable = false;
2486  if ( pOnlyNotBecauseOfMatrix )
2487  *pOnlyNotBecauseOfMatrix = true;
2488  }
2489  else if ( pOnlyNotBecauseOfMatrix )
2490  *pOnlyNotBecauseOfMatrix = false;
2491  }
2492  else if ( pOnlyNotBecauseOfMatrix )
2493  *pOnlyNotBecauseOfMatrix = false;
2494  return bIsEditable;
2495 }
2496 
2498  bool* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
2499 {
2500  bool bIsEditable = true;
2501  if ( nLockCount )
2502  bIsEditable = false;
2503  else if ( IsProtected() && !rDocument.IsScenario(nTab) )
2504  {
2505  ScRangeList aRanges;
2506  rMark.FillRangeListWithMarks( &aRanges, false );
2507  bIsEditable = !HasAttribSelection( rMark, HasAttrFlags::Protected );
2508  if (!bIsEditable)
2509  {
2510  // An enhanced protection permission may override the attribute.
2511  if (pTabProtection)
2512  bIsEditable = pTabProtection->isSelectionEditable( aRanges);
2513  }
2514  if (bIsEditable)
2515  {
2516  // If Sheet is protected and cells are not protected then
2517  // check the active scenario protect flag if this area is
2518  // in the active scenario range.
2519  SCTAB nScenTab = nTab+1;
2520  while(rDocument.IsScenario(nScenTab) && bIsEditable)
2521  {
2522  if(rDocument.IsActiveScenario(nScenTab))
2523  {
2524  for (size_t i=0, nRange = aRanges.size(); (i < nRange) && bIsEditable; i++ )
2525  {
2526  const ScRange & rRange = aRanges[ i ];
2527  if(rDocument.HasScenarioRange(nScenTab, rRange))
2528  {
2529  ScScenarioFlags nFlags;
2530  rDocument.GetScenarioFlags(nScenTab,nFlags);
2531  bIsEditable = !((nFlags & ScScenarioFlags::Protected) && (nFlags & ScScenarioFlags::TwoWay));
2532  }
2533  }
2534  }
2535  nScenTab++;
2536  }
2537  }
2538  }
2539  else if (rDocument.IsScenario(nTab))
2540  {
2541  // Determine if the preceding sheet is protected
2542  SCTAB nActualTab = nTab;
2543  do
2544  {
2545  nActualTab--;
2546  }
2547  while(rDocument.IsScenario(nActualTab));
2548 
2549  if(rDocument.IsTabProtected(nActualTab))
2550  {
2551  ScRangeList aRanges;
2552  rMark.FillRangeListWithMarks( &aRanges, false );
2553  for (size_t i = 0, nRange = aRanges.size(); (i < nRange) && bIsEditable; i++)
2554  {
2555  const ScRange & rRange = aRanges[ i ];
2556  if(rDocument.HasScenarioRange(nTab, rRange))
2557  {
2558  ScScenarioFlags nFlags;
2559  rDocument.GetScenarioFlags(nTab,nFlags);
2560  bIsEditable = !(nFlags & ScScenarioFlags::Protected);
2561  }
2562  }
2563  }
2564  }
2565  if ( bIsEditable )
2566  {
2567  if ( HasSelectionMatrixFragment( rMark ) )
2568  {
2569  bIsEditable = false;
2570  if ( pOnlyNotBecauseOfMatrix )
2571  *pOnlyNotBecauseOfMatrix = true;
2572  }
2573  else if ( pOnlyNotBecauseOfMatrix )
2574  *pOnlyNotBecauseOfMatrix = false;
2575  }
2576  else if ( pOnlyNotBecauseOfMatrix )
2577  *pOnlyNotBecauseOfMatrix = false;
2578  return bIsEditable;
2579 }
2580 
2582 {
2583  ++nLockCount;
2584 }
2585 
2587 {
2588  if (nLockCount)
2589  --nLockCount;
2590  else
2591  {
2592  OSL_FAIL("UnlockTable without LockTable");
2593  }
2594 }
2595 
2596 void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, bool bDeep ) const
2597 {
2598  std::vector<sc::ColRowSpan> aSpans = rMark.GetMarkedColSpans();
2599 
2600  for (const sc::ColRowSpan & rSpan : aSpans)
2601  {
2602  for (SCCOLROW i = rSpan.mnStart; i <= rSpan.mnEnd; ++i)
2603  {
2604  CreateColumnIfNotExists(i).MergeSelectionPattern( rState, rMark, bDeep );
2605  }
2606  }
2607 }
2608 
2610  SCCOL nCol2, SCROW nRow2, bool bDeep ) const
2611 {
2612  nCol2 = ClampToAllocatedColumns(nCol2);
2613  for (SCCOL i=nCol1; i<=nCol2; i++)
2614  aCol[i].MergePatternArea( rState, nRow1, nRow2, bDeep );
2615 }
2616 
2617 void ScTable::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
2618  SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const
2619 {
2620  if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
2621  {
2622  PutInOrder(nStartCol, nEndCol);
2623  PutInOrder(nStartRow, nEndRow);
2624  nEndCol = ClampToAllocatedColumns(nEndCol);
2625  for (SCCOL i=nStartCol; i<=nEndCol; i++)
2626  aCol[i].MergeBlockFrame( pLineOuter, pLineInner, rFlags,
2627  nStartRow, nEndRow, (i==nStartCol), nEndCol-i );
2628  }
2629 }
2630 
2631 void ScTable::ApplyBlockFrame(const SvxBoxItem& rLineOuter, const SvxBoxInfoItem* pLineInner,
2632  SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow)
2633 {
2634  if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
2635  {
2636  PutInOrder(nStartCol, nEndCol);
2637  PutInOrder(nStartRow, nEndRow);
2638  nEndCol = ClampToAllocatedColumns(nEndCol);
2639  for (SCCOL i=nStartCol; i<=nEndCol; i++)
2640  aCol[i].ApplyBlockFrame(rLineOuter, pLineInner,
2641  nStartRow, nEndRow, (i==nStartCol), nEndCol-i);
2642  }
2643 }
2644 
2645 void ScTable::ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
2646 {
2647  if (ValidColRow(nCol,nRow))
2648  CreateColumnIfNotExists(nCol).ApplyPattern( nRow, rAttr );
2649 }
2650 
2651 void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
2652  const ScPatternAttr& rAttr, ScEditDataArray* pDataArray,
2653  bool* const pIsChanged )
2654 {
2655  if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
2656  {
2657  PutInOrder(nStartCol, nEndCol);
2658  PutInOrder(nStartRow, nEndRow);
2659  for (SCCOL i = nStartCol; i <= nEndCol; i++)
2660  CreateColumnIfNotExists(i).ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray, pIsChanged);
2661  }
2662 }
2663 
2665  const ScPatternAttr& rPattern, SvNumFormatType nNewType )
2666 {
2667  SCCOL nEndCol = rRange.aEnd.Col();
2668  for ( SCCOL nCol = rRange.aStart.Col(); nCol <= nEndCol; nCol++ )
2669  {
2670  aCol[nCol].ApplyPatternIfNumberformatIncompatible( rRange, rPattern, nNewType );
2671  }
2672 }
2673 
2674 void ScTable::AddCondFormatData( const ScRangeList& rRangeList, sal_uInt32 nIndex )
2675 {
2676  size_t n = rRangeList.size();
2677  for(size_t i = 0; i < n; ++i)
2678  {
2679  const ScRange & rRange = rRangeList[i];
2680  SCCOL nColStart = rRange.aStart.Col();
2681  SCCOL nColEnd = rRange.aEnd.Col();
2682  SCROW nRowStart = rRange.aStart.Row();
2683  SCROW nRowEnd = rRange.aEnd.Row();
2684  for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
2685  {
2686  CreateColumnIfNotExists(nCol).AddCondFormat(nRowStart, nRowEnd, nIndex);
2687  }
2688  }
2689 }
2690 
2691 void ScTable::RemoveCondFormatData( const ScRangeList& rRangeList, sal_uInt32 nIndex )
2692 {
2693  size_t n = rRangeList.size();
2694  for(size_t i = 0; i < n; ++i)
2695  {
2696  const ScRange & rRange = rRangeList[i];
2697  SCCOL nColStart = rRange.aStart.Col();
2698  SCCOL nColEnd = ClampToAllocatedColumns(rRange.aEnd.Col());
2699  SCROW nRowStart = rRange.aStart.Row();
2700  SCROW nRowEnd = rRange.aEnd.Row();
2701  for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
2702  {
2703  aCol[nCol].RemoveCondFormat(nRowStart, nRowEnd, nIndex);
2704  }
2705  }
2706 }
2707 
2708 void ScTable::SetPatternAreaCondFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow,
2709  const ScPatternAttr& rAttr, const ScCondFormatIndexes& rCondFormatIndexes )
2710 {
2711  aCol[nCol].SetPatternArea( nStartRow, nEndRow, rAttr);
2712 
2713  for (const auto& rIndex : rCondFormatIndexes)
2714  {
2715  ScConditionalFormat* pCondFormat = mpCondFormatList->GetFormat(rIndex);
2716  if (pCondFormat)
2717  {
2718  ScRangeList aRange = pCondFormat->GetRange();
2719  aRange.Join( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab));
2720  pCondFormat->SetRange(aRange);
2721  }
2722  }
2723 }
2724 
2725 void ScTable::ApplyStyle( SCCOL nCol, SCROW nRow, const ScStyleSheet* rStyle )
2726 {
2727  if (ValidColRow(nCol,nRow))
2728  // If column not exists then we need to create it
2729  CreateColumnIfNotExists( nCol ).ApplyStyle( nRow, rStyle );
2730 }
2731 
2732 void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
2733 {
2734  if (!(ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow)))
2735  return;
2736 
2737  PutInOrder(nStartCol, nEndCol);
2738  PutInOrder(nStartRow, nEndRow);
2739  if ( nEndCol == rDocument.MaxCol() )
2740  {
2741  if ( nStartCol < aCol.size() )
2742  {
2743  // If we would like set all columns to specific style, then change only default style for not existing columns
2744  nEndCol = aCol.size() - 1;
2745  for (SCCOL i = nStartCol; i <= nEndCol; i++)
2746  aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
2747  aDefaultColAttrArray.ApplyStyleArea(nStartRow, nEndRow, rStyle );
2748  }
2749  else
2750  {
2751  CreateColumnIfNotExists( nStartCol - 1 );
2752  aDefaultColAttrArray.ApplyStyleArea(nStartRow, nEndRow, rStyle );
2753  }
2754  }
2755  else
2756  {
2757  CreateColumnIfNotExists( nEndCol );
2758  for (SCCOL i = nStartCol; i <= nEndCol; i++)
2759  aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
2760  }
2761 }
2762 
2763 void ScTable::ApplySelectionStyle(const ScStyleSheet& rStyle, const ScMarkData& rMark)
2764 {
2765  for (SCCOL i=0; i < aCol.size(); i++)
2766  aCol[i].ApplySelectionStyle( rStyle, rMark );
2767 }
2768 
2770  const ::editeng::SvxBorderLine* pLine, bool bColorOnly )
2771 {
2772  if ( bColorOnly && !pLine )
2773  return;
2774 
2775  for (SCCOL i=0; i < aCol.size(); i++)
2776  aCol[i].ApplySelectionLineStyle( rMark, pLine, bColorOnly );
2777 }
2778 
2779 const ScStyleSheet* ScTable::GetStyle( SCCOL nCol, SCROW nRow ) const
2780 {
2781  if ( !ValidColRow( nCol, nRow ) )
2782  return nullptr;
2783  if ( nCol < aCol.size() )
2784  return aCol[nCol].GetStyle( nRow );
2785  else
2786  return aDefaultColAttrArray.GetPattern( nRow )->GetStyleSheet();
2787 }
2788 
2789 const ScStyleSheet* ScTable::GetSelectionStyle( const ScMarkData& rMark, bool& rFound ) const
2790 {
2791  rFound = false;
2792 
2793  bool bEqual = true;
2794  bool bColFound;
2795 
2796  const ScStyleSheet* pStyle = nullptr;
2797  const ScStyleSheet* pNewStyle;
2798 
2799  for (SCCOL i=0; i < aCol.size() && bEqual; i++)
2800  if (rMark.HasMultiMarks(i))
2801  {
2802  pNewStyle = aCol[i].GetSelectionStyle( rMark, bColFound );
2803  if (bColFound)
2804  {
2805  rFound = true;
2806  if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
2807  bEqual = false;
2808  pStyle = pNewStyle;
2809  }
2810  }
2811 
2812  return bEqual ? pStyle : nullptr;
2813 }
2814 
2815 const ScStyleSheet* ScTable::GetAreaStyle( bool& rFound, SCCOL nCol1, SCROW nRow1,
2816  SCCOL nCol2, SCROW nRow2 ) const
2817 {
2818  rFound = false;
2819 
2820  bool bEqual = true;
2821  bool bColFound;
2822 
2823  const ScStyleSheet* pStyle = nullptr;
2824  const ScStyleSheet* pNewStyle;
2825  nCol2 = ClampToAllocatedColumns(nCol2);
2826  for (SCCOL i=nCol1; i<=nCol2 && bEqual; i++)
2827  {
2828  pNewStyle = aCol[i].GetAreaStyle(bColFound, nRow1, nRow2);
2829  if (bColFound)
2830  {
2831  rFound = true;
2832  if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
2833  bEqual = false;
2834  pStyle = pNewStyle;
2835  }
2836  }
2837 
2838  return bEqual ? pStyle : nullptr;
2839 }
2840 
2841 bool ScTable::IsStyleSheetUsed( const ScStyleSheet& rStyle ) const
2842 {
2843  bool bIsUsed = false;
2844 
2845  for ( SCCOL i=0; i < aCol.size(); i++ )
2846  {
2847  if ( aCol[i].IsStyleSheetUsed( rStyle ) )
2848  {
2849  bIsUsed = true;
2850  }
2851  }
2852 
2853  return bIsUsed;
2854 }
2855 
2856 void ScTable::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, bool bRemoved,
2857  OutputDevice* pDev,
2858  double nPPTX, double nPPTY,
2859  const Fraction& rZoomX, const Fraction& rZoomY )
2860 {
2861  ScFlatBoolRowSegments aUsedRows(rDocument.MaxRow());
2862  for (SCCOL i = 0; i < aCol.size(); ++i)
2863  aCol[i].FindStyleSheet(pStyleSheet, aUsedRows, bRemoved);
2864 
2865  sc::RowHeightContext aCxt(rDocument.MaxRow(), nPPTX, nPPTY, rZoomX, rZoomY, pDev);
2866  SCROW nRow = 0;
2867  while (nRow <= rDocument.MaxRow())
2868  {
2870  if (!aUsedRows.getRangeData(nRow, aData))
2871  // search failed!
2872  return;
2873 
2874  SCROW nEndRow = aData.mnRow2;
2875  if (aData.mbValue)
2876  SetOptimalHeight(aCxt, nRow, nEndRow);
2877 
2878  nRow = nEndRow + 1;
2879  }
2880 }
2881 
2882 bool ScTable::ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
2883  ScMF nFlags )
2884 {
2885  bool bChanged = false;
2886  if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
2887  for (SCCOL i = nStartCol; i <= nEndCol; i++)
2888  bChanged |= CreateColumnIfNotExists(i).ApplyFlags(nStartRow, nEndRow, nFlags);
2889  return bChanged;
2890 }
2891 
2892 bool ScTable::RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
2893  ScMF nFlags )
2894 {
2895  if (!ValidColRow(nStartCol, nStartRow) || !ValidColRow(nEndCol, nEndRow))
2896  return false;
2897  bool bChanged = false;
2898  nEndCol = ClampToAllocatedColumns(nEndCol);
2899  for (SCCOL i = nStartCol; i <= nEndCol; i++)
2900  bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags);
2901  return bChanged;
2902 }
2903 
2904 void ScTable::SetPattern( const ScAddress& rPos, const ScPatternAttr& rAttr )
2905 {
2906  if (ValidColRow(rPos.Col(),rPos.Row()))
2907  aCol[rPos.Col()].SetPattern( rPos.Row(), rAttr );
2908 }
2909 
2910 const ScPatternAttr* ScTable::SetPattern( SCCOL nCol, SCROW nRow, std::unique_ptr<ScPatternAttr> pAttr )
2911 {
2912  if (ValidColRow(nCol,nRow))
2913  return aCol[nCol].SetPattern( nRow, std::move(pAttr) );
2914  return nullptr;
2915 }
2916 
2917 void ScTable::SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
2918 {
2919  if (ValidColRow(nCol,nRow))
2920  aCol[nCol].SetPattern( nRow, rAttr );
2921 }
2922 
2923 void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr )
2924 {
2925  if (ValidColRow(nCol,nRow))
2926  CreateColumnIfNotExists(nCol).ApplyAttr( nRow, rAttr );
2927 }
2928 
2930  ScEditDataArray* pDataArray, bool* const pIsChanged )
2931 {
2932  for (SCCOL i=0; i < aCol.size(); i++)
2933  aCol[i].ApplySelectionCache( pCache, rMark, pDataArray, pIsChanged );
2934 }
2935 
2936 void ScTable::ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark )
2937 {
2938  for (SCCOL i=0; i < aCol.size(); i++)
2939  aCol[i].ChangeSelectionIndent( bIncrement, rMark );
2940 }
2941 
2942 void ScTable::ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData& rMark )
2943 {
2944  for (SCCOL i=0; i < aCol.size(); i++)
2945  aCol[i].ClearSelectionItems( pWhich, rMark );
2946 }
2947 
2948 // Column widths / Row heights
2949 
2950 void ScTable::SetColWidth( SCCOL nCol, sal_uInt16 nNewWidth )
2951 {
2952  if (ValidCol(nCol) && mpColWidth)
2953  {
2954  if (!nNewWidth)
2955  {
2956  nNewWidth = STD_COL_WIDTH;
2957  }
2958 
2959  if ( nNewWidth != mpColWidth->GetValue(nCol) )
2960  {
2961  mpColWidth->SetValue(nCol, nNewWidth);
2963  }
2964  }
2965  else
2966  {
2967  OSL_FAIL("Invalid column number or no widths");
2968  }
2969 }
2970 
2971 void ScTable::SetColWidthOnly( SCCOL nCol, sal_uInt16 nNewWidth )
2972 {
2973  if (!ValidCol(nCol) || !mpColWidth)
2974  return;
2975 
2976  if (!nNewWidth)
2977  nNewWidth = STD_COL_WIDTH;
2978 
2979  if (nNewWidth != mpColWidth->GetValue(nCol))
2980  mpColWidth->SetValue(nCol, nNewWidth);
2981 }
2982 
2983 void ScTable::SetRowHeight( SCROW nRow, sal_uInt16 nNewHeight )
2984 {
2985  if (ValidRow(nRow) && mpRowHeights)
2986  {
2987  if (!nNewHeight)
2988  {
2989  OSL_FAIL("SetRowHeight: Row height zero");
2990  nNewHeight = ScGlobal::nStdRowHeight;
2991  }
2992 
2993  sal_uInt16 nOldHeight = mpRowHeights->getValue(nRow);
2994  if ( nNewHeight != nOldHeight )
2995  {
2996  mpRowHeights->setValue(nRow, nRow, nNewHeight);
2998  }
2999  }
3000  else
3001  {
3002  OSL_FAIL("Invalid row number or no heights");
3003  }
3004 }
3005 
3006 namespace {
3007 
3012 bool lcl_pixelSizeChanged(
3013  ScFlatUInt16RowSegments& rRowHeights, SCROW nStartRow, SCROW nEndRow,
3014  sal_uInt16 nNewHeight, double nPPTY)
3015 {
3016  long nNewPix = static_cast<long>(nNewHeight * nPPTY);
3017 
3018  ScFlatUInt16RowSegments::ForwardIterator aFwdIter(rRowHeights);
3019  for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
3020  {
3021  sal_uInt16 nHeight;
3022  if (!aFwdIter.getValue(nRow, nHeight))
3023  break;
3024 
3025  if (nHeight != nNewHeight)
3026  {
3027  bool bChanged = (nNewPix != static_cast<long>(nHeight * nPPTY));
3028  if (bChanged)
3029  return true;
3030  }
3031 
3032  // Skip ahead to the last position of the current range.
3033  nRow = aFwdIter.getLastPos();
3034  }
3035  return false;
3036 }
3037 
3038 }
3039 
3040 bool ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight,
3041  double nPPTY )
3042 {
3043  bool bChanged = false;
3044  if (ValidRow(nStartRow) && ValidRow(nEndRow) && mpRowHeights)
3045  {
3046  if (!nNewHeight)
3047  {
3048  OSL_FAIL("SetRowHeight: Row height zero");
3049  nNewHeight = ScGlobal::nStdRowHeight;
3050  }
3051 
3052  bool bSingle = false; // true = process every row for its own
3053  ScDrawLayer* pDrawLayer = rDocument.GetDrawLayer();
3054  if (pDrawLayer)
3055  if (pDrawLayer->HasObjectsInRows( nTab, nStartRow, nEndRow ))
3056  bSingle = true;
3057 
3058  if (bSingle)
3059  {
3061  if (mpRowHeights->getRangeData(nStartRow, aData) &&
3062  nNewHeight == aData.mnValue && nEndRow <= aData.mnRow2)
3063  {
3064  bSingle = false; // no difference in this range
3065  }
3066  }
3067 
3068  if (!bSingle || nEndRow - nStartRow < 20)
3069  {
3070  bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY);
3071  mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
3072  }
3073  else
3074  {
3075  SCROW nMid = (nStartRow + nEndRow) / 2;
3076  if (SetRowHeightRange(nStartRow, nMid, nNewHeight, 1.0))
3077  bChanged = true;
3078  if (SetRowHeightRange(nMid + 1, nEndRow, nNewHeight, 1.0))
3079  bChanged = true;
3080  }
3081 
3082  if (bChanged)
3084  }
3085  else
3086  {
3087  OSL_FAIL("Invalid row number or no heights");
3088  }
3089 
3090  return bChanged;
3091 }
3092 
3093 void ScTable::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight )
3094 {
3095  if (!ValidRow(nStartRow) || !ValidRow(nEndRow) || !mpRowHeights)
3096  return;
3097 
3098  if (!nNewHeight)
3099  nNewHeight = ScGlobal::nStdRowHeight;
3100 
3101  mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
3102 }
3103 
3104 void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, bool bManual )
3105 {
3106  if (ValidRow(nStartRow) && ValidRow(nEndRow) && pRowFlags)
3107  {
3108  if (bManual)
3109  pRowFlags->OrValue( nStartRow, nEndRow, CRFlags::ManualSize);
3110  else
3111  pRowFlags->AndValue( nStartRow, nEndRow, ~CRFlags::ManualSize);
3112  }
3113  else
3114  {
3115  OSL_FAIL("Invalid row number or no column flags");
3116  }
3117 }
3118 
3119 sal_uInt16 ScTable::GetColWidth( SCCOL nCol, bool bHiddenAsZero ) const
3120 {
3121  OSL_ENSURE(ValidCol(nCol),"wrong column number");
3122 
3123  if (ValidCol(nCol) && mpColFlags && mpColWidth)
3124  {
3125  if (bHiddenAsZero && ColHidden(nCol))
3126  return 0;
3127  else
3128  return mpColWidth->GetValue(nCol);
3129  }
3130  else
3131  return sal_uInt16(STD_COL_WIDTH);
3132 }
3133 
3134 sal_uLong ScTable::GetColWidth( SCCOL nStartCol, SCCOL nEndCol ) const
3135 {
3136  if (!ValidCol(nStartCol) || !ValidCol(nEndCol) || nStartCol > nEndCol)
3137  return 0;
3138 
3139  sal_uLong nW = 0;
3140  bool bHidden = false;
3141  SCCOL nLastHiddenCol = -1;
3142  auto colWidthIt = mpColWidth->begin() + nStartCol;
3143  for (SCCOL nCol = nStartCol; nCol <= nEndCol; (++nCol <= nEndCol) ? ++colWidthIt : (void)false)
3144  {
3145  if (nCol > nLastHiddenCol)
3146  bHidden = ColHidden(nCol, nullptr, &nLastHiddenCol);
3147 
3148  if (bHidden)
3149  continue;
3150 
3151  nW += *colWidthIt;
3152  }
3153  return nW;
3154 }
3155 
3156 sal_uInt16 ScTable::GetOriginalWidth( SCCOL nCol ) const // always the set value
3157 {
3158  OSL_ENSURE(ValidCol(nCol),"wrong column number");
3159 
3160  if (ValidCol(nCol) && mpColWidth)
3161  return mpColWidth->GetValue(nCol);
3162  else
3163  return sal_uInt16(STD_COL_WIDTH);
3164 }
3165 
3166 sal_uInt16 ScTable::GetCommonWidth( SCCOL nEndCol ) const
3167 {
3168  // get the width that is used in the largest continuous column range (up to nEndCol)
3169 
3170  if ( !ValidCol(nEndCol) )
3171  {
3172  OSL_FAIL("wrong column");
3173  nEndCol = rDocument.MaxCol();
3174  }
3175 
3176  sal_uInt16 nMaxWidth = 0;
3177  sal_uInt16 nMaxCount = 0;
3178  SCCOL nRangeStart = 0;
3179  while ( nRangeStart <= nEndCol )
3180  {
3181  // skip hidden columns
3182  while ( nRangeStart <= nEndCol && ColHidden(nRangeStart) )
3183  ++nRangeStart;
3184  if ( nRangeStart <= nEndCol )
3185  {
3186  sal_uInt16 nThisCount = 0;
3187  auto colWidthIt = mpColWidth->begin() + nRangeStart;
3188  sal_uInt16 nThisWidth = *colWidthIt;
3189  SCCOL nRangeEnd = nRangeStart;
3190  while ( nRangeEnd <= nEndCol && *colWidthIt == nThisWidth )
3191  {
3192  ++nThisCount;
3193  ++nRangeEnd;
3194  ++colWidthIt;
3195 
3196  // skip hidden columns
3197  while ( nRangeEnd <= nEndCol && ColHidden(nRangeEnd) )
3198  {
3199  ++nRangeEnd;
3200  ++colWidthIt;
3201  }
3202  }
3203 
3204  if ( nThisCount > nMaxCount )
3205  {
3206  nMaxCount = nThisCount;
3207  nMaxWidth = nThisWidth;
3208  }
3209 
3210  nRangeStart = nRangeEnd; // next range
3211  }
3212  }
3213 
3214  return nMaxWidth;
3215 }
3216 
3217 sal_uInt16 ScTable::GetRowHeight( SCROW nRow, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) const
3218 {
3219  SAL_WARN_IF(!ValidRow(nRow), "sc", "Invalid row number " << nRow);
3220 
3221  if (ValidRow(nRow) && mpRowHeights)
3222  {
3223  if (bHiddenAsZero && RowHidden( nRow, pStartRow, pEndRow))
3224  return 0;
3225  else
3226  {
3228  if (!mpRowHeights->getRangeData(nRow, aData))
3229  {
3230  if (pStartRow)
3231  *pStartRow = nRow;
3232  if (pEndRow)
3233  *pEndRow = nRow;
3234  // TODO: What should we return in case the search fails?
3235  return 0;
3236  }
3237 
3238  // If bHiddenAsZero, pStartRow and pEndRow were initialized to
3239  // boundaries of a non-hidden segment. Assume that the previous and
3240  // next segment are hidden then and limit the current height
3241  // segment.
3242  if (pStartRow)
3243  *pStartRow = (bHiddenAsZero ? std::max( *pStartRow, aData.mnRow1) : aData.mnRow1);
3244  if (pEndRow)
3245  *pEndRow = (bHiddenAsZero ? std::min( *pEndRow, aData.mnRow2) : aData.mnRow2);
3246  return aData.mnValue;
3247  }
3248  }
3249  else
3250  {
3251  if (pStartRow)
3252  *pStartRow = nRow;
3253  if (pEndRow)
3254  *pEndRow = nRow;
3255  return ScGlobal::nStdRowHeight;
3256  }
3257 }
3258 
3259 sal_uLong ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow, bool bHiddenAsZero ) const
3260 {
3261  OSL_ENSURE(ValidRow(nStartRow) && ValidRow(nEndRow),"wrong row number");
3262 
3263  if (ValidRow(nStartRow) && ValidRow(nEndRow) && mpRowHeights)
3264  {
3265  sal_uLong nHeight = 0;
3266  SCROW nRow = nStartRow;
3267  while (nRow <= nEndRow)
3268  {
3269  SCROW nLastRow = -1;
3270  if (!( ( RowHidden(nRow, nullptr, &nLastRow) ) && bHiddenAsZero ) )
3271  {
3272  if (nLastRow > nEndRow)
3273  nLastRow = nEndRow;
3274  nHeight += mpRowHeights->getSumValue(nRow, nLastRow);
3275  }
3276  nRow = nLastRow + 1;
3277  }
3278  return nHeight;
3279  }
3280  else
3281  return (nEndRow - nStartRow + 1) * static_cast<sal_uLong>(ScGlobal::nStdRowHeight);
3282 }
3283 
3284 sal_uLong ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale, const sal_uLong* pnMaxHeight ) const
3285 {
3286  OSL_ENSURE(ValidRow(nStartRow) && ValidRow(nEndRow),"wrong row number");
3287 
3288  if (ValidRow(nStartRow) && ValidRow(nEndRow) && mpRowHeights)
3289  {
3290  sal_uLong nHeight = 0;
3291  SCROW nRow = nStartRow;
3292  while (nRow <= nEndRow)
3293  {
3294  SCROW nLastRow = -1;
3295  if (!RowHidden(nRow, nullptr, &nLastRow))
3296  {
3297  if (nLastRow > nEndRow)
3298  nLastRow = nEndRow;
3299 
3300  // #i117315# can't use getSumValue, because individual values must be rounded
3301  while (nRow <= nLastRow)
3302  {
3304  if (!mpRowHeights->getRangeData(nRow, aData))
3305  return nHeight; // shouldn't happen
3306 
3307  SCROW nSegmentEnd = std::min( nLastRow, aData.mnRow2 );
3308 
3309  // round-down a single height value, multiply resulting (pixel) values
3310  const sal_uLong nOneHeight = static_cast<sal_uLong>( aData.mnValue * fScale );
3311  // sometimes scaling results in zero height
3312  if (nOneHeight)
3313  {
3314  SCROW nRowsInSegment = nSegmentEnd + 1 - nRow;
3315  if (pnMaxHeight)
3316  {
3317  nRowsInSegment = std::min(nRowsInSegment, static_cast<SCROW>(*pnMaxHeight / nOneHeight + 1));
3318  nHeight += nOneHeight * nRowsInSegment;
3319  if (nHeight > *pnMaxHeight)
3320  return nHeight;
3321  }
3322  else
3323  nHeight += nOneHeight * nRowsInSegment;
3324  }
3325 
3326  nRow = nSegmentEnd + 1;
3327  }
3328  }
3329  nRow = nLastRow + 1;
3330  }
3331  return nHeight;
3332  }
3333  else
3334  {
3335  const sal_uLong nOneHeight = static_cast<sal_uLong>(ScGlobal::nStdRowHeight * fScale);
3336  SCROW nRowsInSegment = nEndRow - nStartRow + 1;
3337  if (pnMaxHeight)
3338  {
3339  nRowsInSegment = std::min(nRowsInSegment, static_cast<SCROW>(*pnMaxHeight / nOneHeight + 1));
3340  return nOneHeight * nRowsInSegment;
3341  }
3342  else
3343  return static_cast<sal_uLong>(nRowsInSegment * nOneHeight);
3344  }
3345 }
3346 
3347 sal_uInt16 ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hidden
3348 {
3349  OSL_ENSURE(ValidRow(nRow),"wrong row number");
3350 
3351  if (ValidRow(nRow) && mpRowHeights)
3352  return mpRowHeights->getValue(nRow);
3353  else
3354  return ScGlobal::nStdRowHeight;
3355 }
3356 
3357 // Column/Row -Flags
3358 
3360 {
3361  if (!ValidRow(nRow))
3362  return 0;
3363 
3364  SCROW nLastRow = -1;
3365  if (!RowHidden(nRow, nullptr, &nLastRow) || !ValidRow(nLastRow))
3366  return 0;
3367 
3368  return nLastRow - nRow + 1;
3369 }
3370 
3371 //TODO: combine ShowRows / DBShowRows
3372 
3373 void ScTable::ShowCol(SCCOL nCol, bool bShow)
3374 {
3375  if (ValidCol(nCol))
3376  {
3377  bool bWasVis = !ColHidden(nCol);
3378  if (bWasVis != bShow)
3379  {
3380  SetColHidden(nCol, nCol, !bShow);
3381 
3383  if ( pCharts )
3384  pCharts->SetRangeDirty(ScRange( nCol, 0, nTab, nCol, rDocument.MaxRow(), nTab ));
3385  }
3386  }
3387  else
3388  {
3389  OSL_FAIL("Invalid column number or no flags");
3390  }
3391 }
3392 
3393 void ScTable::ShowRow(SCROW nRow, bool bShow)
3394 {
3395  if (ValidRow(nRow) && pRowFlags)
3396  {
3397  bool bWasVis = !RowHidden(nRow);
3398  if (bWasVis != bShow)
3399  {
3400  SetRowHidden(nRow, nRow, !bShow);
3401  if (bShow)
3402  SetRowFiltered(nRow, nRow, false);
3404  if ( pCharts )
3405  pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, rDocument.MaxCol(), nRow, nTab ));
3406 
3408  }
3409  }
3410  else
3411  {
3412  OSL_FAIL("Invalid row number or no flags");
3413  }
3414 }
3415 
3416 void ScTable::DBShowRow(SCROW nRow, bool bShow)
3417 {
3418  if (ValidRow(nRow) && pRowFlags)
3419  {
3420  // Always set filter flag; unchanged when Hidden
3421  bool bChanged = SetRowHidden(nRow, nRow, !bShow);
3422  SetRowFiltered(nRow, nRow, !bShow);
3423 
3424  if (bChanged)
3425  {
3427  if ( pCharts )
3428  pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, rDocument.MaxCol(), nRow, nTab ));
3429 
3430  if (pOutlineTable)
3431  UpdateOutlineRow( nRow, nRow, bShow );
3432 
3434  }
3435  }
3436  else
3437  {
3438  OSL_FAIL("Invalid row number or no flags");
3439  }
3440 }
3441 
3442 void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
3443 {
3444  SCROW nStartRow = nRow1;
3445  while (nStartRow <= nRow2)
3446  {
3447  SCROW nEndRow = -1;
3448  bool bWasVis = !RowHiddenLeaf(nStartRow, nullptr, &nEndRow);
3449  if (nEndRow > nRow2)
3450  nEndRow = nRow2;
3451 
3452  bool bChanged = ( bWasVis != bShow );
3453 
3454  SetRowHidden(nStartRow, nEndRow, !bShow);
3455  SetRowFiltered(nStartRow, nEndRow, !bShow);
3456 
3457  if ( bChanged )
3458  {
3460  if ( pCharts )
3461  pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, rDocument.MaxCol(), nEndRow, nTab ));
3462  }
3463 
3464  nStartRow = nEndRow + 1;
3465  }
3466 
3467  // #i12341# For Show/Hide rows, the outlines are updated separately from the outside.
3468  // For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
3469  // to be done here.
3470  if (pOutlineTable)
3471  UpdateOutlineRow( nRow1, nRow2, bShow );
3472 }
3473 
3474 void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
3475 {
3476  SCROW nStartRow = nRow1;
3477 
3478  // #i116164# if there are no drawing objects within the row range, a single HeightChanged call is enough
3479  ScDrawLayer* pDrawLayer = rDocument.GetDrawLayer();
3480  bool bHasObjects = pDrawLayer && pDrawLayer->HasObjectsInRows( nTab, nRow1, nRow2 );
3481 
3482  while (nStartRow <= nRow2)
3483  {
3484  SCROW nEndRow = -1;
3485  bool bWasVis = !RowHiddenLeaf(nStartRow, nullptr, &nEndRow);
3486  if (nEndRow > nRow2)
3487  nEndRow = nRow2;
3488 
3489  bool bChanged = ( bWasVis != bShow );
3490 
3491  SetRowHidden(nStartRow, nEndRow, !bShow);
3492  if (bShow)
3493  SetRowFiltered(nStartRow, nEndRow, false);
3494 
3495  if ( bChanged )
3496  {
3498  if ( pCharts )
3499  pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, rDocument.MaxCol(), nEndRow, nTab ));
3500 
3502  }
3503 
3504  nStartRow = nEndRow + 1;
3505  }
3506 
3507  if ( !bHasObjects )
3508  {
3509  // #i116164# set the flags for the whole range at once
3510  SetRowHidden(nRow1, nRow2, !bShow);
3511  if (bShow)
3512  SetRowFiltered(nRow1, nRow2, false);
3513  }
3514 }
3515 
3516 bool ScTable::IsDataFiltered(SCCOL nColStart, SCROW nRowStart, SCCOL nColEnd, SCROW nRowEnd) const
3517 {
3518  for (SCROW i = nRowStart; i <= nRowEnd; ++i)
3519  {
3520  if (RowHidden(i))
3521  return true;
3522  }
3523  for (SCCOL i = nColStart; i <= nColEnd; ++i)
3524  {
3525  if (ColHidden(i))
3526  return true;
3527  }
3528  return false;
3529 }
3530 
3531 bool ScTable::IsDataFiltered(const ScRange& rRange) const
3532 {
3533  return IsDataFiltered(rRange.aStart.Col(), rRange.aStart.Row(),
3534  rRange.aEnd.Col(), rRange.aEnd.Row());
3535 }
3536 
3537 void ScTable::SetRowFlags( SCROW nRow, CRFlags nNewFlags )
3538 {
3539  if (ValidRow(nRow) && pRowFlags)
3540  pRowFlags->SetValue( nRow, nNewFlags);
3541  else
3542  {
3543  OSL_FAIL("Invalid row number or no flags");
3544  }
3545 }
3546 
3547 void ScTable::SetRowFlags( SCROW nStartRow, SCROW nEndRow, CRFlags nNewFlags )
3548 {
3549  if (ValidRow(nStartRow) && ValidRow(nEndRow) && pRowFlags)
3550  pRowFlags->SetValue( nStartRow, nEndRow, nNewFlags);
3551  else
3552  {
3553  OSL_FAIL("Invalid row number(s) or no flags");
3554  }
3555 }
3556 
3558 {
3559  if (ValidCol(nCol) && mpColFlags)
3560  return mpColFlags->GetValue(nCol);
3561  else
3562  return CRFlags::NONE;
3563 }
3564 
3566 {
3567  if (ValidRow(nRow) && pRowFlags)
3568  return pRowFlags->GetValue(nRow);
3569  else
3570  return CRFlags::NONE;
3571 }
3572 
3574 {
3575  SCROW nLastFound = 0;
3576  if (pRowFlags)
3577  {
3578  SCROW nRow = pRowFlags->GetLastAnyBitAccess( CRFlags::All );
3579  if (ValidRow(nRow))
3580  nLastFound = nRow;
3581  }
3582 
3583  if (!maRowManualBreaks.empty())
3584  nLastFound = ::std::max(nLastFound, *maRowManualBreaks.rbegin());
3585 
3586  if (mpHiddenRows)
3587  {
3588  SCROW nRow = mpHiddenRows->findLastTrue();
3589  if (ValidRow(nRow))
3590  nLastFound = ::std::max(nLastFound, nRow);
3591  }
3592 
3593  if (mpFilteredRows)
3594  {
3595  SCROW nRow = mpFilteredRows->findLastTrue();
3596  if (ValidRow(nRow))
3597  nLastFound = ::std::max(nLastFound, nRow);
3598  }
3599 
3600  return nLastFound;
3601 }
3602 
3604 {
3605  if ( !mpColFlags )
3606  return 0;
3607 
3608  SCCOL nLastFound = 0;
3609  const auto nColSize = aCol.size();
3610  auto colWidthIt = mpColWidth->begin() + 1;
3611  for (SCCOL nCol = 1; nCol < nColSize; (++nCol < nColSize) ? ++colWidthIt : (void)false)
3612  if ((mpColFlags->GetValue(nCol) & CRFlags::All) || (*colWidthIt != STD_COL_WIDTH))
3613  nLastFound = nCol;
3614 
3615  return nLastFound;
3616 }
3617 
3619 {
3620  if ( !pRowFlags )
3621  return 0;
3622 
3623  SCROW nLastFlags = GetLastFlaggedRow();
3624 
3625  // Find the last row position where the height is NOT the standard row
3626  // height.
3627  // KOHEI: Test this to make sure it does what it's supposed to.
3628  SCROW nLastHeight = mpRowHeights->findLastTrue(ScGlobal::nStdRowHeight);
3629  if (!ValidRow(nLastHeight))
3630  nLastHeight = 0;
3631 
3632  return std::max( nLastFlags, nLastHeight);
3633 }
3634 
3635 bool ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, bool bShow )
3636 {
3637  if (pOutlineTable && mpColFlags)
3638  {
3639  return pOutlineTable->GetColArray().ManualAction( nStartCol, nEndCol, bShow, *this, true );
3640  }
3641  else
3642  return false;
3643 }
3644 
3645 bool ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, bool bShow )
3646 {
3647  if (pOutlineTable && pRowFlags)
3648  return pOutlineTable->GetRowArray().ManualAction( nStartRow, nEndRow, bShow, *this, false );
3649  else
3650  return false;
3651 }
3652 
3653 void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
3654 {
3655  // Column-wise expansion
3656 
3657  while (rX1 > 0 && ColHidden(rX1-1))
3658  --rX1;
3659 
3660  while (rX2 < rDocument.MaxCol() && ColHidden(rX2+1))
3661  ++rX2;
3662 
3663  // Row-wise expansion
3664 
3665  if (rY1 > 0)
3666  {
3668  if (mpHiddenRows->getRangeData(rY1-1, aData) && aData.mbValue)
3669  {
3670  SCROW nStartRow = aData.mnRow1;
3671  if (ValidRow(nStartRow))
3672  rY1 = nStartRow;
3673  }
3674  }
3675  if (rY2 < rDocument.MaxRow())
3676  {
3677  SCROW nEndRow = -1;
3678  if (RowHidden(rY2+1, nullptr, &nEndRow) && ValidRow(nEndRow))
3679  rY2 = nEndRow;
3680  }
3681 }
3682 
3683 void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
3684 {
3685  while ( rX2>rX1 && ColHidden(rX2) )
3686  --rX2;
3687  while ( rX2>rX1 && ColHidden(rX1) )
3688  ++rX1;
3689 
3690  if (rY1 < rY2)
3691  {
3693  if (mpHiddenRows->getRangeData(rY2, aData) && aData.mbValue)
3694  {
3695  SCROW nStartRow = aData.mnRow1;
3696  if (ValidRow(nStartRow) && nStartRow >= rY1)
3697  rY2 = nStartRow;
3698  }
3699  }
3700 
3701  if (rY1 < rY2)
3702  {
3703  SCROW nEndRow = -1;
3704  if (RowHidden(rY1, nullptr, &nEndRow) && ValidRow(nEndRow) && nEndRow <= rY2)
3705  rY1 = nEndRow;
3706  }
3707 }
3708 
3709 // Auto-Outline
3710 
3711 template< typename T >
3712 static short DiffSign( T a, T b )
3713 {
3714  return (a<b) ? -1 :
3715  (a>b) ? 1 : 0;
3716 }
3717 
3718 namespace {
3719 
3720 class OutlineArrayFinder
3721 {
3722  ScRange maRef;
3723  SCCOL mnCol;
3724  SCTAB mnTab;
3726  bool mbSizeChanged;
3727 
3728 public:
3729  OutlineArrayFinder(const ScRange& rRef, SCCOL nCol, SCTAB nTab, ScOutlineArray* pArray, bool bSizeChanged) :
3730  maRef(rRef), mnCol(nCol), mnTab(nTab), mpArray(pArray),
3731  mbSizeChanged(bSizeChanged) {}
3732 
3733  bool operator() (size_t nRow, const ScFormulaCell* pCell)
3734  {
3735  SCROW nRow2 = static_cast<SCROW>(nRow);
3736 
3737  if (!pCell->HasRefListExpressibleAsOneReference(maRef))
3738  return false;
3739 
3740  if (maRef.aStart.Row() != nRow2 || maRef.aEnd.Row() != nRow2 ||
3741  maRef.aStart.Tab() != mnTab || maRef.aEnd.Tab() != mnTab)
3742  return false;
3743 
3744  if (DiffSign(maRef.aStart.Col(), mnCol) != DiffSign(maRef.aEnd.Col(), mnCol))
3745  return false;
3746 
3747  return mpArray->Insert(maRef.aStart.Col(), maRef.aEnd.Col(), mbSizeChanged);
3748  }
3749 };
3750 
3751 }
3752 
3753 void ScTable::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
3754 {
3755  typedef mdds::flat_segment_tree<SCROW, bool> UsedRowsType;
3756 
3757  bool bSizeChanged = false;
3758 
3759  SCCOL nCol;
3760  SCROW nRow;
3761  bool bFound;
3762  ScRange aRef;
3763 
3764  nEndCol = ClampToAllocatedColumns(nEndCol);
3765 
3767 
3768  // Rows
3769 
3770  UsedRowsType aUsed(0, rDocument.MaxRow()+1, false);
3771  for (nCol=nStartCol; nCol<=nEndCol; nCol++)
3772  aCol[nCol].FindUsed(nStartRow, nEndRow, aUsed);
3773  aUsed.build_tree();
3774 
3775  ScOutlineArray& rRowArray = pOutlineTable->GetRowArray();
3776  for (nRow=nStartRow; nRow<=nEndRow; nRow++)
3777  {
3778  bool bUsed = false;
3779  SCROW nLastRow = nRow;
3780  aUsed.search_tree(nRow, bUsed, nullptr, &nLastRow);
3781  if (!bUsed)
3782  {
3783  nRow = nLastRow;
3784  continue;
3785  }
3786 
3787  bFound = false;
3788  for (nCol=nStartCol; nCol<=nEndCol && !bFound; nCol++)
3789  {
3790  ScRefCellValue aCell = aCol[nCol].GetCellValue(nRow);
3791 
3792  if (aCell.meType != CELLTYPE_FORMULA)
3793  continue;
3794 
3796  continue;
3797 
3798  if ( aRef.aStart.Col() == nCol && aRef.aEnd.Col() == nCol &&
3799  aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
3800  DiffSign( aRef.aStart.Row(), nRow ) ==
3801  DiffSign( aRef.aEnd.Row(), nRow ) )
3802  {
3803  if (rRowArray.Insert( aRef.aStart.Row(), aRef.aEnd.Row(), bSizeChanged ))
3804  {
3805  bFound = true;
3806  }
3807  }
3808  }
3809  }
3810 
3811  // Column
3812  ScOutlineArray& rColArray = pOutlineTable->GetColArray();
3813  for (nCol=nStartCol; nCol<=nEndCol; nCol++)
3814  {
3815  if (aCol[nCol].IsEmptyData())
3816  continue;
3817 
3818  OutlineArrayFinder aFunc(aRef, nCol, nTab, &rColArray, bSizeChanged);
3819  sc::FindFormula(aCol[nCol].maCells, nStartRow, nEndRow, aFunc);
3820  }
3821 }
3822 
3823  // CopyData - for Query in other range
3824 
3825 void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
3826  SCCOL nDestCol, SCROW nDestRow, SCTAB nDestTab )
3827 {
3828  //TODO: if used for multiple rows, optimize after columns!
3829 
3830  ScAddress aSrc( nStartCol, nStartRow, nTab );
3831  ScAddress aDest( nDestCol, nDestRow, nDestTab );
3832  ScRange aRange( aSrc, aDest );
3833  bool bThisTab = ( nDestTab == nTab );
3834  SCROW nDestY = nDestRow;
3835  for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
3836  {
3837  aSrc.SetRow( nRow );
3838  aDest.SetRow( nDestY );
3839  SCCOL nDestX = nDestCol;
3840  for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
3841  {
3842  aSrc.SetCol( nCol );
3843  aDest.SetCol( nDestX );
3844  ScCellValue aCell;
3845  aCell.assign(rDocument, ScAddress(nCol, nRow, nTab));
3846 
3847  if (aCell.meType == CELLTYPE_FORMULA)
3848  {
3849  sc::RefUpdateContext aCxt(rDocument);
3850  aCxt.meMode = URM_COPY;
3851  aCxt.maRange = aRange;
3852  aCxt.mnColDelta = nDestCol - nStartCol;
3853  aCxt.mnRowDelta = nDestRow - nStartRow;
3854  aCxt.mnTabDelta = nDestTab - nTab;
3855  aCell.mpFormula->UpdateReference(aCxt);
3856  aCell.mpFormula->aPos = aDest;
3857  }
3858 
3859  if (bThisTab)
3860  {
3861  aCell.release(CreateColumnIfNotExists(nDestX), nDestY);
3862  SetPattern( nDestX, nDestY, *GetPattern( nCol, nRow ) );
3863  }
3864  else
3865  {
3866  aCell.release(rDocument, aDest);
3867  rDocument.SetPattern( aDest, *GetPattern( nCol, nRow ) );
3868  }
3869 
3870  ++nDestX;
3871  }
3872  ++nDestY;
3873  }
3874 }
3875 
3877 {
3878  ScRange aRef;
3879 
3880  if (pCell->HasOneReference(aRef))
3881  {
3882  if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab())
3883  {
3884  SCROW nEndRow;
3885  if (!RowFiltered(aRef.aStart.Row(), nullptr, &nEndRow))
3886  // row not filtered.
3887  nEndRow = ::std::numeric_limits<SCROW>::max();
3888 
3889  if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row())
3890  return true; // at least partly visible
3891  return false; // completely invisible
3892  }
3893  }
3894 
3895  return true; // somehow different
3896 }
3897 
3898 void ScTable::GetUpperCellString(SCCOL nCol, SCROW nRow, OUString& rStr)
3899 {
3900  GetInputString(nCol, nRow, rStr);
3901  rStr = ScGlobal::getCharClassPtr()->uppercase(rStr.trim());
3902 }
3903 
3904 // Calculate the size of the sheet and set the size on DrawPage
3905 
3906 void ScTable::SetDrawPageSize(bool bResetStreamValid, bool bUpdateNoteCaptionPos)
3907 {
3908  ScDrawLayer* pDrawLayer = rDocument.GetDrawLayer();
3909  if( pDrawLayer )
3910  {
3911  double fValX = GetColOffset( rDocument.MaxCol() + 1 ) * HMM_PER_TWIPS;
3912  double fValY = GetRowOffset( rDocument.MaxRow() + 1 ) * HMM_PER_TWIPS;
3913  const long nMax = ::std::numeric_limits<long>::max();
3914  // #i113884# Avoid int32 overflow with possible negative results than can cause bad effects.
3915  // If the draw page size is smaller than all rows, only the bottom of the sheet is affected.
3916  long x = ( fValX > static_cast<double>(nMax) ) ? nMax : static_cast<long>(fValX);
3917  long y = ( fValY > static_cast<double>(nMax) ) ? nMax : static_cast<long>(fValY);
3918 
3919  if ( IsLayoutRTL() ) // IsNegativePage
3920  x = -x;
3921 
3922  pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( x, y ), bUpdateNoteCaptionPos );
3923  }
3924 
3925  // #i102616# actions that modify the draw page size count as sheet modification
3926  // (exception: InitDrawLayer)
3927  if (bResetStreamValid)
3928  SetStreamValid(false);
3929 }
3930 
3931 void ScTable::SetRangeName(std::unique_ptr<ScRangeName> pNew)
3932 {
3933  mpRangeName = std::move(pNew);
3934 
3935  //fdo#39792: mark stream as invalid, otherwise new ScRangeName will not be written to file
3936  SetStreamValid(false);
3937 }
3938 
3940 {
3941  if (!mpRangeName)
3942  mpRangeName.reset(new ScRangeName);
3943  return mpRangeName.get();
3944 }
3945 
3946 sal_uLong ScTable::GetRowOffset( SCROW nRow, bool bHiddenAsZero ) const
3947 {
3948  sal_uLong n = 0;
3949  if ( mpHiddenRows && mpRowHeights )
3950  {
3951  if (nRow == 0)
3952  return 0;
3953  else if (nRow == 1)
3954  return GetRowHeight(0, nullptr, nullptr, bHiddenAsZero );
3955 
3956  n = GetTotalRowHeight(0, nRow-1, bHiddenAsZero);
3957 #if OSL_DEBUG_LEVEL > 0
3958  if (n == ::std::numeric_limits<unsigned long>::max())
3959  OSL_FAIL("ScTable::GetRowOffset: row heights overflow");
3960 #endif
3961  }
3962  else
3963  {
3964  OSL_FAIL("GetRowOffset: Data missing");
3965  }
3966  return n;
3967 }
3968 
3970 {
3971  sal_uLong nSum = 0;
3972 
3974 
3975  ScFlatUInt16RowSegments::RangeData aRowHeightRange;
3976  aRowHeightRange.mnRow2 = -1;
3977  aRowHeightRange.mnValue = 0; // silence MSVC C4701
3978 
3979  for (SCROW nRow = 0; nRow <= rDocument.MaxRow(); ++nRow)
3980  {
3981  if (!mpHiddenRows->getRangeData(nRow, aData))
3982  // Failed to fetch the range data for whatever reason.
3983  break;
3984 
3985  if (aData.mbValue)
3986  {
3987  // This row is hidden. Skip ahead all hidden rows.
3988  nRow = aData.mnRow2;
3989  continue;
3990  }
3991 
3992  if (aRowHeightRange.mnRow2 < nRow)
3993  {
3994  if (!mpRowHeights->getRangeData(nRow, aRowHeightRange))
3995  // Failed to fetch the range data for whatever reason.
3996  break;
3997  }
3998 
3999  nSum += aRowHeightRange.mnValue;
4000 
4001  if (nSum > nHeight)
4002  {
4003  if (nRow >= rDocument.MaxRow())
4004  return rDocument.MaxRow();
4005 
4006  // Find the next visible row.
4007  ++nRow;
4008 
4009  if (!mpHiddenRows->getRangeData(nRow, aData))
4010  // Failed to fetch the range data for whatever reason.
4011  break;
4012 
4013  if (aData.mbValue)
4014  // These rows are hidden.
4015  nRow = aData.mnRow2 + 1;
4016 
4017  return nRow <= rDocument.MaxRow() ? nRow : rDocument.MaxRow();
4018  }
4019  }
4020  return -1;
4021 }
4022 
4023 sal_uLong ScTable::GetColOffset( SCCOL nCol, bool bHiddenAsZero ) const
4024 {
4025  sal_uLong n = 0;
4026  if ( mpColWidth )
4027  {
4028  auto colWidthIt = mpColWidth->begin();
4029  for (SCCOL i = 0; i < nCol; (++i < nCol) ? ++colWidthIt : (void)false)
4030  if (!( bHiddenAsZero && ColHidden(i) ))
4031  n += *colWidthIt;
4032  }
4033  else
4034  {
4035  OSL_FAIL("GetColumnOffset: Data missing");
4036  }
4037  return n;
4038 }
4039 
4040 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
If set, cloned formula cells will start to listen to the document.
void FindMaxRotCol(RowInfo *pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2)
Definition: table2.cxx:2224
void SetFormula(SCCOL nCol, SCROW nRow, const ScTokenArray &rArray, formula::FormulaGrammar::Grammar eGram)
Definition: table2.cxx:1544
void SetMergedCells(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: table2.cxx:2120
void CellStorageModified()
Called whenever the state of cell array gets modified i.e.
Definition: column2.cxx:1596
void ApplyStyle(SCROW nRow, const ScStyleSheet *rStyle)
Definition: column.cxx:559
void CalcAfterLoad(sc::CompileFormulaContext &rCxt, bool bStartListening)
Definition: table2.cxx:1987
void CopyUpdated(const ScTable *pPosTab, ScTable *pDestTab) const
Definition: table2.cxx:1376
svl::SharedString GetSharedString(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:1581
constexpr double nPPTY
bool TestCopyScenarioTo(const ScTable *pDestTab) const
Definition: table2.cxx:1465
SCCOL GetColMerge() const
Definition: attrib.hxx:69
SCTAB nTab
Definition: table.hxx:201
SCROW mnRowDelta
Amount and direction of movement in the row direction.
const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:2050
Temporarily switch on/off auto calculation mode.
Definition: scopetools.hxx:24
SCCOL GetLastChangedCol() const
Definition: table2.cxx:3603
bool Intersects(const ScRange &) const
Definition: rangelst.cxx:1084
CellType meType
Definition: cellvalue.hxx:38
ScRotateDir GetRotateDir(const SfxItemSet *pCondSet) const
Definition: patattr.cxx:1329
ScFormulaCell * SetFormulaCell(SCCOL nCol, SCROW nRow, ScFormulaCell *pCell)
Takes ownership of pCell.
Definition: table2.cxx:1562
void ApplyStyleArea(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet &rStyle)
Definition: table2.cxx:2732
bool HasAttrib(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, HasAttrFlags nMask) const
Definition: table2.cxx:2070
bool HasScenarioRange(SCTAB nTab, const ScRange &rRange) const
Definition: documen3.cxx:859
ScAddress aStart
Definition: address.hxx:500
ScRotateDir
Definition: fillinfo.hxx:41
SC_DLLPUBLIC bool IsTabProtected(SCTAB nTab) const
Definition: documen3.cxx:1890
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
void UnlockTable()
Definition: table2.cxx:2586
bool HasBlockMatrixFragment(const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2, bool bNoMatrixAtAll=false) const
Definition: table2.cxx:2301
void CompileAll(sc::CompileFormulaContext &rCxt)
Definition: table2.cxx:1952
Store parameters used in the ScDocument::SetString() method.
Definition: stringutil.hxx:35
void ForgetNoteCaptions(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bPreserveData)
Definition: table2.cxx:1701
void SetAllFormulasDirty(const sc::SetFormulaDirtyContext &rCxt)
Definition: table2.cxx:1874
void SetRowFlags(SCROW nRow, CRFlags nNewFlags)
Definition: table2.cxx:3537
bool IsBlockEmpty(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes) const
Definition: table2.cxx:2135
void MergeSelectionPattern(ScMergePatternState &rState, const ScMarkData &rMark, bool bDeep) const
Definition: column.cxx:334
const ScPatternAttr * GetPattern(SCROW nRow) const
Definition: column.cxx:369
void SetRowHeight(SCROW nRow, sal_uInt16 nNewHeight)
Definition: table2.cxx:2983
std::unique_ptr< ScFlatUInt16RowSegments > mpRowHeights
Definition: table.hxx:180
HasAttrFlags
Definition: global.hxx:193
constexpr TypedWhichId< SvxBoxItem > ATTR_BORDER(150)
void SetPatternAreaCondFormat(SCCOL nCol, SCROW nStartRow, SCROW nEndRow, const ScPatternAttr &rAttr, const ScCondFormatIndexes &rCondFormatIndexes)
Definition: table2.cxx:2708
Sheet / outlining (grouping) information.
SCROW Row() const
Definition: address.hxx:262
Simple container to keep track of sheet - column pair.
Definition: columnset.hxx:23
const char aData[]
Single reference (one address) into the sheet.
Definition: refdata.hxx:30
ScTable * FetchTable(SCTAB nTab)
Definition: document.cxx:2505
bool IsDataFiltered(SCCOL nColStart, SCROW nRowStart, SCCOL nColEnd, SCROW nRowEnd) const
Definition: table2.cxx:3516
bool IsSelectionEditable(const ScMarkData &rMark, bool *pOnlyNotBecauseOfMatrix=nullptr) const
Definition: table2.cxx:2497
void SetRowHeightOnly(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight)
Set specified row height to specified ranges.
Definition: table2.cxx:3093
SCTAB GetTab() const
Definition: table.hxx:277
SC_DLLPUBLIC bool IsActiveScenario(SCTAB nTab) const
Definition: documen3.cxx:872
size_t GetNoteCount(SCCOL nCol) const
Definition: table2.cxx:1679
ScRangeList & GetRangeList()
Definition: conditio.hxx:562
void ApplyPattern(SCCOL nCol, SCROW nRow, const ScPatternAttr &rAttr)
Definition: table2.cxx:2645
ScColumn * FetchColumn(SCCOL nCol)
Definition: table2.cxx:1087
std::unique_ptr< ScPostIt > ReleaseNote(SCCOL nCol, SCROW nRow)
Definition: table2.cxx:1671
ScScenarioFlags
Definition: global.hxx:236
const SfxPoolItem * GetItem(const SwTextAttr &rAttr, sal_uInt16 nWhich)
void CopyData(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCCOL nDestCol, SCROW nDestRow, SCTAB nDestTab)
Definition: table2.cxx:3825
SC_DLLPUBLIC bool Intersects(const ScRange &rRange) const
Definition: address.cxx:1549
void TransposeReference()
SCCOL size() const
ScMF GetValue() const
Definition: attrib.hxx:98
sal_uIntPtr sal_uLong
bool TestInsertRow(SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize) const
Definition: table2.cxx:133
Context for reference update during shifting, moving or copying of cell ranges.
void CopyRowFiltered(const ScTable &rTable, SCROW nStartRow, SCROW nEndRow)
Definition: table5.cxx:856
bool IsOverlapped() const
Definition: attrib.hxx:102
CellType GetCellType(const ScAddress &rPos) const
Definition: table.hxx:454
void SetCalcNotification(bool bSet)
Definition: table2.cxx:128
void SetEditText(SCROW nRow, std::unique_ptr< EditTextObject > pEditText)
Definition: column3.cxx:2210
sal_Int64 n
void GetString(SCCOL nCol, SCROW nRow, OUString &rString, const ScInterpreterContext *pContext=nullptr) const
Definition: table2.cxx:1601
bool IsUndo() const
Definition: document.hxx:1529
void DetachFormulaCells(sc::EndListeningContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: table2.cxx:1131
std::unique_ptr< ScFlatBoolColSegments > mpFilteredCols
Definition: table.hxx:186
const ScStyleSheet * GetSelectionStyle(const ScMarkData &rMark, bool &rFound) const
Definition: table2.cxx:2789
Rich-text attributes.
ScColumnVector::const_iterator end() const
bool HasScenarioRange(const ScRange &rRange) const
Definition: table2.cxx:1423
sal_Int32 mnCol
sal_uInt16 nLockCount
Definition: table.hxx:216
CommentCaptionState GetAllNoteCaptionsState(const ScRange &rRange, std::vector< sc::NoteEntry > &rNotes)
Definition: table2.cxx:1727
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
Definition: markdata.cxx:387
formula::FormulaToken * AddSingleReference(const ScSingleRefData &rRef)
ScSingleRefToken with ocPush.
Definition: token.cxx:2202
Store position data for column array storage.
const SfxItemSet & GetItemSet() const
sal_uInt16 GetDistance(SvxBoxItemLine nLine) const
bool mbPageBreaksValid
Definition: table.hxx:241
InsertDeleteFlags getInsertFlag() const
bool IsClipOrUndo() const
Definition: document.hxx:1528
bool HasObjectsInRows(SCTAB nTab, SCROW nStartRow, SCROW nEndRow)
Definition: drwlayer.cxx:1314
void CopyStaticToDocument(SCROW nRow1, SCROW nRow2, const SvNumberFormatterMergeMap &rMap, ScColumn &rDestCol)
Definition: column.cxx:1061
bool CompileErrorCells(sc::CompileFormulaContext &rCxt, FormulaError nErrCode)
Definition: table2.cxx:1975
sal_uInt16 GetTextWidth(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:84
void GetFirstDataPos(SCCOL &rCol, SCROW &rRow) const
Definition: table2.cxx:1796
ScAddress aEnd
Definition: address.hxx:501
CellStoreType::const_iterator ParseAllNonEmpty(const typename CellStoreType::const_iterator &itPos, const CellStoreType &rCells, SCROW nRow1, SCROW nRow2, Func &rFunc)
Definition: mtvcellfunc.hxx:96
void SetManualHeight(SCROW nStartRow, SCROW nEndRow, bool bManual)
Definition: table2.cxx:3104
void SetColHidden(SCCOL nStartCol, SCCOL nEndCol, bool bHidden)
Definition: table5.cxx:616
void ApplyPatternArea(SCROW nStartRow, SCROW nEndRow, const ScPatternAttr &rPatAttr, ScEditDataArray *pDataArray=nullptr, bool *const pIsChanged=nullptr)
Definition: column.cxx:515
virtual SfxItemSet & GetItemSet()
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:104
void CopyScenarioTo(const ScTable *pDestTab) const
Definition: table2.cxx:1394
void UndoToTable(sc::CopyToDocContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, InsertDeleteFlags nFlags, bool bMarked, ScTable *pDestTab)
Definition: table2.cxx:1324
void DeleteRow(const sc::ColumnSet &rRegroupCols, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize, bool *pUndoOutline, std::vector< ScAddress > *pGroupPos)
Definition: table2.cxx:194
sal_uInt16 GetOriginalHeight(SCROW nRow) const
Definition: table2.cxx:3347
void RemoveEditTextCharAttribs(SCCOL nCol, SCROW nRow, const ScPatternAttr &rAttr)
Definition: table2.cxx:1640
const editeng::SvxBorderLine * GetRight() const
mdds::multi_type_vector< CellFunc, CellStoreEvent > CellStoreType
const ScStyleSheet * GetStyle(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:2779
float x
void MixData(sc::MixDocContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScPasteFunc nFunction, bool bSkipEmpty, const ScTable *pSrcTab)
Definition: table2.cxx:775
bool HasData(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:1822
void SetDirtyAfterLoad()
Definition: table2.cxx:1903
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:489
void MergeBlockFrame(SvxBoxItem *pLineOuter, SvxBoxInfoItem *pLineInner, ScLineFlags &rFlags, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow) const
Definition: table2.cxx:2617
void ApplySelectionStyle(const ScStyleSheet &rStyle, const ScMarkData &rMark)
Definition: table2.cxx:2763
std::unique_ptr< ScRangeName > mpRangeName
Definition: table.hxx:223
SCROW nRowNo
Definition: fillinfo.hxx:182
SCROW GetRowForHeight(sal_uLong nHeight) const
Get the last row such that the height of row 0 to the end row is as high as possible without exceedin...
Definition: table2.cxx:3969
const ScAddress & GetAddress() const
Definition: brdcst.hxx:31
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
void ApplyAttr(SCCOL nCol, SCROW nRow, const SfxPoolItem &rAttr)
Definition: table2.cxx:2923
void TransposeClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScTable *pTransClip, InsertDeleteFlags nFlags, bool bAsLink)
Definition: table2.cxx:893
Internal use only (d&d undo): do not delete caption objects of cell notes.
void MarkScenarioIn(ScMarkData &rMark, ScScenarioFlags nNeededBits) const
Definition: table2.cxx:1412
bool UpdateReference(const sc::RefUpdateContext &rCxt, ScDocument *pUndoDoc=nullptr, const ScAddress *pUndoCellPos=nullptr)
bool ValidRow(SCROW nRow) const
Definition: table.hxx:327
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6061
void StartListeners(sc::StartListeningContext &rCxt, bool bAll)
Either start all formula cells as listeners unconditionally, or start those that are marked "needs li...
Definition: table2.cxx:1103
void SetStreamValid(bool bSet, bool bIgnoreLock=false)
Definition: table1.cxx:368
ScColumn & CreateColumnIfNotExists(const SCCOL nScCol) const
Definition: table.hxx:281
void AttachFormulaCells(sc::StartListeningContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: table2.cxx:1123
Store arbitrary cell value of any kind.
Definition: cellvalue.hxx:36
void TransposeColNotes(ScTable *pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1, SCROW nRow2)
Definition: table2.cxx:1001
constexpr TypedWhichId< ScRotateValueItem > ATTR_ROTATE_VALUE(135)
void ResetChanged(const ScRange &rRange)
Definition: table2.cxx:1993
ScFormulaCell * SetFormulaCell(SCROW nRow, ScFormulaCell *pCell, sc::StartListeningType eListenType=sc::SingleCellListening, bool bInheritNumFormatIfNeeded=true)
Takes ownership of pCell.
Definition: column3.cxx:2308
const ScRangeList & GetRange() const
Definition: conditio.hxx:560
sal_uLong GetColOffset(SCCOL nCol, bool bHiddenAsZero=true) const
Definition: table2.cxx:4023
#define STD_COL_WIDTH
Definition: global.hxx:93
void SetNumberFormat(SCCOL nCol, SCROW nRow, sal_uInt32 nNumberFormat)
Definition: table2.cxx:2042
bool IsBlockEditable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool *pOnlyNotBecauseOfMatrix=nullptr, bool bNoMatrixAtAll=false) const
Definition: table2.cxx:2413
void InsertRow(SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize)
Definition: table2.cxx:146
ScFormulaCell * mpFormula
Definition: cellvalue.hxx:43
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:873
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:45
void SetTableOpDirty(const ScRange &)
Definition: table2.cxx:1893
void SetAnonymousDBData(std::unique_ptr< ScDBData > pDBData)
Definition: table1.cxx:2337
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:24
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
Additional class containing cell annotation data.
Definition: postit.hxx:160
void SetColManualBreaks(const ::std::set< SCCOL > &rBreaks)
Definition: table5.cxx:322
static short DiffSign(T a, T b)
Definition: table2.cxx:3712
void GetFormula(SCCOL nCol, SCROW nRow, OUString &rFormula) const
Definition: table2.cxx:1648
sal_uLong GetScaledRowHeight(SCROW nStartRow, SCROW nEndRow, double fScale, const sal_uLong *pnMaxHeight=nullptr) const
Definition: table2.cxx:3284
bool UpdateOutlineCol(SCCOL nStartCol, SCCOL nEndCol, bool bShow)
Definition: table2.cxx:3635
void SetNumberFormat(SCROW nRow, sal_uInt32 nNumberFormat)
Definition: column2.cxx:3040
double * GetValueCell(SCCOL nCol, SCROW nRow)
Definition: table2.cxx:1609
sc::CellStoreType maCells
Definition: column.hxx:129
const std::shared_ptr< const ColumnSet > & getColumnSet() const
void SetColWidthOnly(SCCOL nCol, sal_uInt16 nNewWidth)
Definition: table2.cxx:2971
ScFormulaCell * mpFormula
Definition: cellvalue.hxx:111
#define HMM_PER_TWIPS
Definition: global.hxx:91
SCTAB Tab() const
Definition: address.hxx:271
void CopyToClip(sc::CopyToClipContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScTable *pTable)
Definition: table2.cxx:480
void StripHidden(SCCOL &rX1, SCROW &rY1, SCCOL &rX2, SCROW &rY2)
Definition: table2.cxx:3683
void SetRow(SCROW nRowP)
Definition: address.hxx:275
void release(ScDocument &rDoc, const ScAddress &rPos)
Set cell value at specified position in specified document.
Definition: cellvalue.cxx:432
void CopyColHidden(const ScTable &rTable, SCCOL nStartCol, SCCOL nEndCol)
Definition: table5.cxx:628
bool SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden)
Definition: table5.cxx:578
void SetColWidth(SCCOL nCol, sal_uInt16 nNewWidth)
Definition: table2.cxx:2950
const editeng::SvxBorderLine * GetLine(SvxBoxItemLine nLine) const
bool HasValueData(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:1838
bool SetFormulaCells(SCROW nRow, std::vector< ScFormulaCell * > &rCells)
Definition: column3.cxx:2346
sal_uInt32 GetNumberFormat(const ScInterpreterContext &rContext, SCROW nRow) const
Definition: column.cxx:420
ScColumnVector::const_iterator begin() const
void SetValue(SCCOL nCol, SCROW nRow, const double &rVal)
Definition: table2.cxx:1589
std::unique_ptr< ScOutlineTable > pOutlineTable
Definition: table.hxx:194
ScAddress aPos
void DoAutoOutline(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow)
Definition: table2.cxx:3753
void SetRangeName(std::unique_ptr< ScRangeName > pNew)
Definition: table2.cxx:3931
void SetPattern(const ScAddress &rPos, const ScPatternAttr &rAttr)
Definition: table2.cxx:2904
bool RemoveFlags(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScMF nFlags)
Definition: table2.cxx:2892
ScBroadcastAreaSlotMachine * GetBASM() const
Definition: document.hxx:2141
void SetRowManualBreaks(const ::std::set< SCROW > &rBreaks)
Definition: table5.cxx:315
void SetCol(SCCOL nColP)
Definition: address.hxx:279
size_t size() const
Definition: conditio.cxx:1767
sal_uInt16 GetOriginalWidth(SCCOL nCol) const
Definition: table2.cxx:3156
bool HasSelectionMatrixFragment(const ScMarkData &rMark) const
Definition: table2.cxx:2397
std::unique_ptr< ScBitMaskCompressedArray< SCCOL, CRFlags > > mpColFlags
Definition: table.hxx:182
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:954
bool IsLayoutRTL() const
Definition: table.hxx:336
float y
bool IsColValid(const SCCOL nScCol) const
Definition: table.hxx:314
bool SetRowHeightRange(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nNewHeight, double nPPTY)
Definition: table2.cxx:3040
bool SetString(SCROW nRow, SCTAB nTab, const OUString &rString, formula::FormulaGrammar::AddressConvention eConv, const ScSetStringParam *pParam=nullptr)
Returns true if the cell format was set as well.
Definition: column3.cxx:2190
bool HasRefListExpressibleAsOneReference(ScRange &rRange) const
constexpr double nPPTX
bool SetOutlineTable(const ScOutlineTable *pNewOutline)
Definition: table2.cxx:89
static SC_DLLPUBLIC sal_uInt16 nStdRowHeight
Definition: global.hxx:583
sal_uInt32 GetKey() const
Definition: conditio.hxx:592
void SetRange(const ScRangeList &rRanges)
Definition: conditio.cxx:1741
std::unique_ptr< ScFlatBoolColSegments > mpHiddenCols
Definition: table.hxx:184
bool SetFormulaCells(SCCOL nCol, SCROW nRow, std::vector< ScFormulaCell * > &rCells)
Definition: table2.cxx:1573
const ScFormatEntry * GetEntry(sal_uInt16 nPos) const
Definition: conditio.cxx:1781
ScPasteFunc
Definition: global.hxx:189
void ShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
Definition: table2.cxx:3474
void ApplyStyle(SCCOL nCol, SCROW nRow, const ScStyleSheet *rStyle)
Definition: table2.cxx:2725
void SetTab(SCTAB nTabP)
Definition: address.hxx:283
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1059
const editeng::SvxBorderLine * GetTop() const
void SetPageSize(sal_uInt16 nPageNo, const Size &rSize, bool bUpdateNoteCaptionPos)
Definition: drwlayer.cxx:566
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:872
bool ColHidden(SCCOL nCol, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: table5.cxx:561
bool IsProtected() const
Definition: table5.cxx:1040
SC_DLLPUBLIC void SetPattern(const ScAddress &, const ScPatternAttr &rAttr)
Definition: document.cxx:5049
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
void GetScenarioFlags(SCTAB nTab, ScScenarioFlags &rFlags) const
Definition: documen3.cxx:474
bool ValidCol(SCCOL nCol) const
Definition: table.hxx:326
SCCOL nRotMaxCol
Definition: fillinfo.hxx:183
const ScFormulaCell * GetFormulaCell(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:1656
ScDocument & GetDoc()
Definition: table.hxx:275
void InitBlockPosition(sc::ColumnBlockPosition &rBlockPos)
Definition: column3.cxx:1043
const editeng::SvxBorderLine * GetLeft() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
int i
void SetDirtyVar()
Definition: table2.cxx:1860
void SetRawString(SCROW nRow, const OUString &rStr)
Definition: column3.cxx:2827
void AddCondFormatData(const ScRangeList &rRange, sal_uInt32 nIndex)
Definition: table2.cxx:2674
UpdateRefMode meMode
update mode - insert/delete, copy, or move.
const ScRangeList * GetScenarioRanges() const
Definition: table2.cxx:1451
void CheckVectorizationState()
Definition: table2.cxx:1866
void SetFlag3D(bool bVal)
Definition: refdata.hxx:90
void InitAddress(const ScAddress &rAdr)
InitAddress: InitFlags and set address.
Definition: refdata.cxx:27
sal_Int16 SCCOL
Definition: types.hxx:22
sal_uInt16 GetColWidth(SCCOL nCol, bool bHiddenAsZero=true) const
Definition: table2.cxx:3119
InsertDeleteFlags
Definition: global.hxx:158
void InvalidateScenarioRanges()
Definition: table2.cxx:1446
void CopyCaptionsToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScTable *pDestTab, bool bCloneCaption)
Definition: table2.cxx:1310
std::unique_ptr< ScDBData > pDBDataNoName
Definition: table.hxx:222
SC_DLLPUBLIC void SetAutoCalc(bool bNewAutoCalc)
Definition: documen7.cxx:602
void CopyRowHidden(const ScTable &rTable, SCROW nStartRow, SCROW nEndRow)
Definition: table5.cxx:643
sc::CellTextAttrStoreType maCellTextAttrs
Definition: column.hxx:118
std::unique_ptr< ScPostIt > Clone(const ScAddress &rOwnPos, ScDocument &rDestDoc, const ScAddress &rDestPos, bool bCloneCaption) const
Clones this note and its caption object, if specified.
Definition: postit.cxx:876
CRFlags GetRowFlags(SCROW nRow) const
Definition: table2.cxx:3565
void SetEmptyCell(SCCOL nCol, SCROW nRow)
Definition: table2.cxx:1536
::std::map< sal_uInt32, sal_uInt32 > SvNumberFormatterMergeMap
const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, sal_uInt16 nWhich) const
Definition: table2.cxx:2006
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:874
SvNumberFormatter * GetFormatTable() const
const SvxPageUsage aArr[]
ScScenarioFlags nScenarioFlags
Definition: table.hxx:221
void ApplyStyleArea(SCROW nStartRow, SCROW nEndRow, const ScStyleSheet &rStyle)
Definition: attarray.cxx:626
const ScStyleSheet * GetStyleSheet() const
Definition: patattr.hxx:126
void GetUnprotectedCells(ScRangeList &rRangeList) const
Definition: table2.cxx:1760
void ShowCol(SCCOL nCol, bool bShow)
Definition: table2.cxx:3373
bool HasAttribSelection(const ScMarkData &rMark, HasAttrFlags nMask) const
Definition: table2.cxx:2083
void CopyFromClip(sc::CopyFromClipContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCCOL nDx, SCROW nDy, ScTable *pTable)
Definition: table2.cxx:714
const EditTextObject * GetEditText(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:1632
void DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
Definition: table2.cxx:3442
void GetNotesInRange(const ScRange &rRange, std::vector< sc::NoteEntry > &rNotes) const
Definition: table2.cxx:1716
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
bool TestInsertRow(SCROW nStartRow, SCSIZE nSize) const
Definition: column.cxx:836
size_t size() const
Definition: rangelst.hxx:90
std::unique_ptr< ScTableProtection > pTabProtection
Definition: table.hxx:177
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
void GetLastDataPos(SCCOL &rCol, SCROW &rRow) const
Definition: table2.cxx:1811
Structure that stores segments of boolean flags per column, and perform custom action on those segmen...
bool IsCutMode()
Definition: document.cxx:2065
void SetNote(const ScAddress &rPos, std::unique_ptr< ScPostIt > pNote)
Definition: document.cxx:6523
void SetRangeDirty(const ScRange &rRange)
Definition: chartlis.cxx:570
void CompileXML(sc::CompileFormulaContext &rCxt, ScProgress &rProgress)
Definition: table2.cxx:1961
SvNumFormatType
bool EqualEntries(const ScConditionalFormat &r, bool bIgnoreSrcPos=false) const
Definition: conditio.cxx:1722
bool bTableAreaValid
Definition: table.hxx:233
ScColContainer aCol
Definition: table.hxx:156
void SetRawString(SCCOL nCol, SCROW nRow, const svl::SharedString &rStr)
Definition: table2.cxx:1595
sal_uInt32 GetNumberFormat(SvNumberFormatter *) const
Definition: patattr.cxx:1257
void StartListeningFormulaCells(sc::StartListeningContext &rStartCxt, sc::EndListeningContext &rEndCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: table2.cxx:1150
void LockTable()
Definition: table2.cxx:2581
void DBShowRow(SCROW nRow, bool bShow)
Definition: table2.cxx:3416
::std::set< SCROW > maRowManualBreaks
Definition: table.hxx:190
std::unique_ptr< ScConditionalFormatList > mpCondFormatList
Definition: table.hxx:225
double * GetValueCell(SCROW nRow)
Definition: column3.cxx:2925
void SetDistance(sal_uInt16 nNew, SvxBoxItemLine nLine)
void ApplySelectionLineStyle(const ScMarkData &rMark, const ::editeng::SvxBorderLine *pLine, bool bColorOnly)
Definition: table2.cxx:2769
void BroadcastRecalcOnRefMove()
Broadcast dirty formula cells that contain functions such as CELL(), COLUMN() or ROW() which may chan...
Definition: table2.cxx:1921
bool empty() const
CommentCaptionState
Definition: document.hxx:252
void ExtendHidden(SCCOL &rX1, SCROW &rY1, SCCOL &rX2, SCROW &rY2)
Definition: table2.cxx:3653
void SetAreasChangedNeedBroadcast()
Definition: docsh.hxx:383
bool ApplyFlags(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScMF nFlags)
Definition: table2.cxx:2882
ScRange maRange
Range of cells that are about to be moved for insert/delete/move modes.
void ApplyAttr(SCROW nRow, const SfxPoolItem &rAttr)
Definition: column.cxx:714
BroadcastMode
Broadcast mode for SetDirty(SCROW,SCROW,BroadcastMode).
Definition: column.hxx:170
bool ContainsNotesInRange(const ScRange &rRange) const
Definition: table2.cxx:1766
void getColumns(SCTAB nTab, std::vector< SCCOL > &rCols) const
Definition: columnset.cxx:34
FormulaError
SCCOL Col() const
Definition: address.hxx:267
bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: table2.cxx:1478
bool RefVisible(const ScFormulaCell *pCell)
Definition: table2.cxx:3876
void DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, InsertDeleteFlags nDelFlag, bool bBroadcast=true, sc::ColumnSpanSet *pBroadcastSpans=nullptr)
Definition: table2.cxx:412
void MergePatternArea(ScMergePatternState &rState, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bDeep) const
Definition: table2.cxx:2609
Internal use only (undo etc.): do not copy/delete caption objects of cell notes.
bool IsMerged() const
Definition: attrib.hxx:72
void CopyToTable(sc::CopyToDocContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, InsertDeleteFlags nFlags, bool bMarked, ScTable *pDestTab, const ScMarkData *pMarkData, bool bAsLink, bool bColRowFlags, bool bGlobalNamesToLocal, bool bCopyCaptions)
Definition: table2.cxx:1162
void InvalidatePageBreaks()
Definition: table2.cxx:1389
bool ApplyFlags(SCROW nStartRow, SCROW nEndRow, ScMF nFlags)
Definition: column.cxx:683
CellType meType
Definition: cellvalue.hxx:106
bool RowHidden(SCROW nRow, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: table5.cxx:486
void SetDrawPageSize(bool bResetStreamValid=true, bool bUpdateNoteCaptionPos=true)
Definition: table2.cxx:3906
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
CRFlags
Definition: global.hxx:135
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_Int32 SCROW
Definition: types.hxx:18
void SetFormula(SCROW nRow, const ScTokenArray &rArray, formula::FormulaGrammar::Grammar eGram)
Definition: column3.cxx:2272
ScMF
Definition: attrib.hxx:35
std::unique_ptr< ScFlatBoolRowSegments > mpFilteredRows
Definition: table.hxx:187
sc::CellNoteStoreType maCellNotes
Definition: column.hxx:121
SC_DLLPUBLIC bool IsScenario(SCTAB nTab) const
Definition: documen3.cxx:427
void CopyScenarioFrom(const ScTable *pSrcTab)
Definition: table2.cxx:1402
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
#define SAL_WARN_IF(condition, area, stream)
sal_uInt32 GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow, bool bHiddenAsZero=true) const
Definition: table5.cxx:743
ScRangeName * GetRangeName() const
Definition: table2.cxx:3939
void CopyStyleFrom(ScStyleSheetPool *pSrcPool, const OUString &rName, SfxStyleFamily eFamily)
Definition: stlpool.cxx:131
void Join(const ScRange &, bool bIsInList=false)
Definition: rangelst.cxx:166
ScRefCellValue GetCellValue(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:1788
void DeleteCol(const sc::ColumnSet &rRegroupCols, SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize, bool *pUndoOutline)
Definition: table2.cxx:346
bool ValidColRow(SCCOL nCol, SCROW nRow) const
Definition: table.hxx:328
SCTAB mnTabDelta
Amount and direction of movement in the sheet direction.
CellType
Definition: global.hxx:281
bool BroadcastBroadcasters(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScHint &rHint)
Broadcast single broadcasters in range, without explicitly setting anything dirty, not doing area broadcasts.
Definition: table2.cxx:1928
sal_uInt16 GetCommonWidth(SCCOL nEndCol) const
Definition: table2.cxx:3166
void CopyConditionalFormat(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCCOL nDx, SCROW nDy, const ScTable *pTable)
Definition: table2.cxx:621
void MergeSelectionPattern(ScMergePatternState &rState, const ScMarkData &rMark, bool bDeep) const
Definition: table2.cxx:2596
void assign(const ScDocument &rDoc, const ScAddress &rPos)
Take cell value from specified position in specified document.
Definition: cellvalue.cxx:330
ScColumnsRange GetColumnsRange(SCCOL begin, SCCOL end) const
Definition: table1.cxx:2585
const ScPatternAttr * GetMostUsedPattern(SCCOL nCol, SCROW nStartRow, SCROW nEndRow) const
Definition: table2.cxx:2061
SCROW GetLastChangedRow() const
Definition: table2.cxx:3618
::std::set< SCCOL > maColManualBreaks
Definition: table.hxx:192
void CopyRowHeight(const ScTable &rSrcTable, SCROW nStartRow, SCROW nEndRow, SCROW nSrcOffset)
Definition: table5.cxx:657
SC_DLLPUBLIC bool HasColNotes(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:6554
void ApplyPattern(SCROW nRow, const ScPatternAttr &rPatAttr)
Definition: column.cxx:500
void CalcAll()
Definition: table2.cxx:1944
void GetInputString(SCCOL nCol, SCROW nRow, OUString &rString) const
Definition: table2.cxx:1617
#define F_PI18000
const ScFormulaCell * GetFormulaCell(SCROW nRow) const
Definition: column3.cxx:3001
void DeleteSelection(InsertDeleteFlags nDelFlag, const ScMarkData &rMark, bool bBroadcast=true)
Definition: table2.cxx:444
std::unique_ptr< ScCompressedArray< SCCOL, sal_uInt16 > > mpColWidth
Definition: table.hxx:179
void InvalidateTableArea()
Definition: table2.cxx:1384
void ClearSelectionItems(const sal_uInt16 *pWhich, const ScMarkData &rMark)
Definition: table2.cxx:2942
bool TestInsertCol(SCROW nStartRow, SCROW nEndRow, SCSIZE nSize) const
Definition: table2.cxx:252
static SC_DLLPUBLIC const CharClass * getCharClassPtr()
Definition: global.cxx:1010
constexpr TypedWhichId< ScCondFormatItem > ATTR_CONDITIONAL(154)
SC_DLLPUBLIC ScChartListenerCollection * GetChartListenerCollection() const
Definition: document.hxx:2143
void GetAllNoteEntries(std::vector< sc::NoteEntry > &rNotes) const
Definition: table2.cxx:1710
const ScPatternAttr * GetNext(SCCOL &rCol, SCROW &rRow1, SCROW &rRow2)
Definition: dociter.cxx:2653
SC_DLLPUBLIC ScPatternAttr * GetDefPattern() const
Definition: document.cxx:6056
ScRangeList GetIntersectedRange(const ScRange &rRange) const
Definition: rangelst.cxx:1172
void SetDirty(const ScRange &, ScColumn::BroadcastMode)
Definition: table2.cxx:1882
bool HasOneReference(ScRange &r) const
SCROW GetNotePosition(SCCOL nCol, size_t nIndex) const
Definition: table2.cxx:1687
void AddCondFormat(SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex)
Definition: column.cxx:549
SC_DLLPUBLIC ScStyleSheetPool * GetStyleSheetPool() const
Definition: document.cxx:6066
SCSIZE FillMaxRot(RowInfo *pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2, SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY, const ScPatternAttr *pPattern, const SfxItemSet *pCondSet)
Definition: table2.cxx:2155
void SetDirtyIfPostponed()
Mark formula cells dirty that have the mbPostponedDirty flag set or contain named ranges with relativ...
Definition: table2.cxx:1912