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