LibreOffice Module sc (master) 1
document.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <scitems.hxx>
21
22#include <editeng/boxitem.hxx>
23#include <editeng/editobj.hxx>
24#include <o3tl/safeint.hxx>
26#include <svx/svditer.hxx>
27#include <sfx2/objsh.hxx>
28#include <sfx2/docfile.hxx>
29#include <svl/numformat.hxx>
30#include <svl/poolcach.hxx>
31#include <svl/zforlist.hxx>
34#include <tools/urlobj.hxx>
35#include <sal/log.hxx>
36#include <osl/diagnose.h>
37
38#include <com/sun/star/text/WritingMode2.hpp>
39#include <com/sun/star/script/vba/XVBACompatibility.hpp>
40#include <com/sun/star/sheet/TablePageBreakData.hpp>
41#include <com/sun/star/lang/NotInitializedException.hpp>
42
43#include <document.hxx>
44#include <docsh.hxx>
45#include <docuno.hxx>
46#include <table.hxx>
47#include <column.hxx>
48#include <attrib.hxx>
49#include <attarray.hxx>
50#include <patattr.hxx>
51#include <rangenam.hxx>
52#include <poolhelp.hxx>
53#include <docpool.hxx>
54#include <stlpool.hxx>
55#include <stlsheet.hxx>
56#include <globstr.hrc>
57#include <scresid.hxx>
58#include <dbdata.hxx>
59#include <chartlis.hxx>
60#include <rangelst.hxx>
61#include <markdata.hxx>
62#include <drwlayer.hxx>
63#include <validat.hxx>
64#include <prnsave.hxx>
65#include <chgtrack.hxx>
66#include <hints.hxx>
67#include <detdata.hxx>
68#include <dpobject.hxx>
69#include <scmod.hxx>
70#include <dociter.hxx>
71#include <progress.hxx>
72#include <autonamecache.hxx>
73#include <bcaslot.hxx>
74#include <postit.hxx>
75#include <clipparam.hxx>
76#include <defaultsoptions.hxx>
77#include <editutil.hxx>
78#include <stringutil.hxx>
79#include <formulaiter.hxx>
80#include <formulacell.hxx>
81#include <clipcontext.hxx>
82#include <listenercontext.hxx>
83#include <scopetools.hxx>
84#include <refupdatecontext.hxx>
85#include <formulagroup.hxx>
87#include <compressedarray.hxx>
88#include <recursionhelper.hxx>
89#include <SparklineGroup.hxx>
90#include <SparklineList.hxx>
91#include <undomanager.hxx>
92
94
95#include <limits>
96#include <memory>
97#include <utility>
98
99#include <comphelper/lok.hxx>
101
102#include <vcl/uitest/logger.hxx>
104
105#include <mtvelements.hxx>
106#include <sfx2/lokhelper.hxx>
107
108using ::editeng::SvxBorderLine;
109using namespace ::com::sun::star;
110
111namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
112using ::com::sun::star::uno::Sequence;
113using ::com::sun::star::sheet::TablePageBreakData;
114using ::std::set;
115
116namespace {
117
118std::pair<SCTAB,SCTAB> getMarkedTableRange(const std::vector<ScTableUniquePtr>& rTables, const ScMarkData& rMark)
119{
120 SCTAB nTabStart = MAXTAB;
121 SCTAB nTabEnd = 0;
122 SCTAB nMax = static_cast<SCTAB>(rTables.size());
123 for (const auto& rTab : rMark)
124 {
125 if (rTab >= nMax)
126 break;
127
128 if (!rTables[rTab])
129 continue;
130
131 if (rTab < nTabStart)
132 nTabStart = rTab;
133 nTabEnd = rTab;
134 }
135
136 return std::pair<SCTAB,SCTAB>(nTabStart,nTabEnd);
137}
138
139void collectUIInformation(std::map<OUString, OUString>&& aParameters, const OUString& rAction)
140{
141 EventDescription aDescription;
142 aDescription.aID = "grid_window";
143 aDescription.aAction = rAction;
144 aDescription.aParameters = std::move(aParameters);
145 aDescription.aParent = "MainWindow";
146 aDescription.aKeyWord = "ScGridWinUIObject";
147
148 UITestLogger::getInstance().logEvent(aDescription);
149}
150
151struct ScDefaultAttr
152{
153 const ScPatternAttr* pAttr;
154 SCROW nFirst;
156 explicit ScDefaultAttr(const ScPatternAttr* pPatAttr) : pAttr(pPatAttr), nFirst(0), nCount(0) {}
157};
158
159struct ScLessDefaultAttr
160{
161 bool operator() (const ScDefaultAttr& rValue1, const ScDefaultAttr& rValue2) const
162 {
163 return rValue1.pAttr < rValue2.pAttr;
164 }
165};
166
167}
168
169typedef std::set<ScDefaultAttr, ScLessDefaultAttr> ScDefaultAttrSet;
170
171void ScDocument::MakeTable( SCTAB nTab,bool _bNeedsNameCheck )
172{
173 if (!ValidTab(nTab) || HasTable(nTab))
174 return;
175
176 // Get Custom prefix
177 const ScDefaultsOptions& rOpt = SC_MOD()->GetDefaultsOptions();
178 OUString aString = rOpt.GetInitTabPrefix() + OUString::number(nTab+1);
179 if ( _bNeedsNameCheck )
180 CreateValidTabName( aString ); // no doubles
181 if (nTab < GetTableCount())
182 {
183 maTabs[nTab].reset( new ScTable(*this, nTab, aString) );
184 }
185 else
186 {
187 while (nTab > GetTableCount())
188 maTabs.push_back(nullptr);
189 maTabs.emplace_back( new ScTable(*this, nTab, aString) );
190 }
191 maTabs[nTab]->SetLoadingMedium(bLoadingMedium);
192}
193
194bool ScDocument::GetHashCode( SCTAB nTab, sal_Int64& rHashCode ) const
195{
196 if (const ScTable* pTable = FetchTable(nTab))
197 {
198 rHashCode = pTable->GetHashCode();
199 return true;
200 }
201 return false;
202}
203
204bool ScDocument::GetName( SCTAB nTab, OUString& rName ) const
205{
206 if (const ScTable* pTable = FetchTable(nTab))
207 {
208 rName = pTable->GetName();
209 return true;
210 }
211 rName.clear();
212 return false;
213}
214
215OUString ScDocument::GetCopyTabName( SCTAB nTab ) const
216{
217 if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabNames.size()))
218 return maTabNames[nTab];
219 return OUString();
220}
221
222bool ScDocument::SetCodeName( SCTAB nTab, const OUString& rName )
223{
224 if (ScTable* pTable = FetchTable(nTab))
225 {
226 pTable->SetCodeName(rName);
227 return true;
228 }
229 SAL_WARN("sc", "can't set code name " << rName );
230 return false;
231}
232
233bool ScDocument::GetCodeName( SCTAB nTab, OUString& rName ) const
234{
235 if (const ScTable* pTable = FetchTable(nTab))
236 {
237 rName = pTable->GetCodeName();
238 return true;
239 }
240 rName.clear();
241 return false;
242}
243
244bool ScDocument::GetTable( const OUString& rName, SCTAB& rTab ) const
245{
246 static OUString aCacheName, aCacheUpperName;
247
249 if (aCacheName != rName)
250 {
251 aCacheName = rName;
252 // surprisingly slow ...
253 aCacheUpperName = ScGlobal::getCharClass().uppercase(rName);
254 }
255 const OUString aUpperName = aCacheUpperName;
256
257 for (SCTAB i = 0; i < GetTableCount(); i++)
258 if (maTabs[i])
259 {
260 if (aUpperName == maTabs[i]->GetUpperName())
261 {
262 rTab = i;
263 return true;
264 }
265 }
266 rTab = 0;
267 return false;
268}
269
270std::vector<OUString> ScDocument::GetAllTableNames() const
271{
272 std::vector<OUString> aNames;
273 aNames.reserve(maTabs.size());
274 for (const auto& a : maTabs)
275 {
276 // Positions need to be preserved for ScCompiler and address convention
277 // context, so still push an empty string for NULL tabs.
278 OUString aName;
279 if (a)
280 {
281 const ScTable& rTab = *a;
282 aName = rTab.GetName();
283 }
284 aNames.push_back(aName);
285 }
286
287 return aNames;
288}
289
291{
292 if (ScTable* pTable = FetchTable(nTab))
293 return pTable->GetAnonymousDBData();
294 return nullptr;
295}
296
298{
299 return static_cast<SCTAB>(maTabs.size());
300}
301
302void ScDocument::SetAnonymousDBData(SCTAB nTab, std::unique_ptr<ScDBData> pDBData)
303{
304 if (ScTable* pTable = FetchTable(nTab))
305 pTable->SetAnonymousDBData(std::move(pDBData));
306}
307
308void ScDocument::SetAnonymousDBData( std::unique_ptr<ScDBData> pDBData )
309{
310 mpAnonymousDBData = std::move(pDBData);
311}
312
314{
315 return mpAnonymousDBData.get();
316}
317
318bool ScDocument::ValidTabName( const OUString& rName )
319{
320 if (rName.isEmpty())
321 return false;
322 sal_Int32 nLen = rName.getLength();
323
324#if 1
325 // Restrict sheet names to what Excel accepts.
326 /* TODO: We may want to remove this restriction for full ODFF compliance.
327 * Merely loading and calculating ODF documents using these characters in
328 * sheet names is not affected by this, but all sheet name editing and
329 * copying functionality is, maybe falling back to "Sheet4" or similar. */
330 for (sal_Int32 i = 0; i < nLen; ++i)
331 {
332 const sal_Unicode c = rName[i];
333 switch (c)
334 {
335 case ':':
336 case '\\':
337 case '/':
338 case '?':
339 case '*':
340 case '[':
341 case ']':
342 // these characters are not allowed to match XL's convention.
343 return false;
344 case '\'':
345 if (i == 0 || i == nLen - 1)
346 // single quote is not allowed at the first or last
347 // character position.
348 return false;
349 break;
350 }
351 }
352#endif
353
354 return true;
355}
356
357bool ScDocument::ValidNewTabName( const OUString& rName ) const
358{
359 bool bValid = ValidTabName(rName);
360 if (!bValid)
361 return false;
362 OUString aUpperName = ScGlobal::getCharClass().uppercase(rName);
363 for (const auto& a : maTabs)
364 {
365 if (!a)
366 continue;
367 const OUString& rOldName = a->GetUpperName();
368 bValid = rOldName != aUpperName;
369 if (!bValid)
370 break;
371 }
372 return bValid;
373}
374
375void ScDocument::CreateValidTabName(OUString& rName) const
376{
377 if ( !ValidTabName(rName) )
378 {
379 // Find new one
380
381 // Get Custom prefix
382 const ScDefaultsOptions& rOpt = SC_MOD()->GetDefaultsOptions();
383 const OUString& aStrTable = rOpt.GetInitTabPrefix();
384
385 bool bOk = false;
386
387 // First test if the prefix is valid, if so only avoid doubles
388 bool bPrefix = ValidTabName( aStrTable );
389 OSL_ENSURE(bPrefix, "Invalid Table Name");
390 SCTAB nDummy;
391
392 for (SCTAB i = GetTableCount() + 1; !bOk ; i++)
393 {
394 rName = aStrTable + OUString::number(static_cast<sal_Int32>(i));
395 if (bPrefix)
396 bOk = ValidNewTabName( rName );
397 else
398 bOk = !GetTable( rName, nDummy );
399 }
400 }
401 else
402 {
403 // testing the supplied Name
404
405 if ( !ValidNewTabName(rName) )
406 {
407 SCTAB i = 1;
408 OUString aName;
409 do
410 {
411 i++;
412 aName = rName + "_" + OUString::number(static_cast<sal_Int32>(i));
413 }
414 while (!ValidNewTabName(aName) && (i < MAXTAB+1));
415 rName = aName;
416 }
417 }
418}
419
420void ScDocument::CreateValidTabNames(std::vector<OUString>& aNames, SCTAB nCount) const
421{
422 aNames.clear();//ensure that the vector is empty
423
424 // Get Custom prefix
425 const ScDefaultsOptions& rOpt = SC_MOD()->GetDefaultsOptions();
426 const OUString& aStrTable = rOpt.GetInitTabPrefix();
427
428 OUStringBuffer rName;
429
430 // First test if the prefix is valid, if so only avoid doubles
431 bool bPrefix = ValidTabName( aStrTable );
432 OSL_ENSURE(bPrefix, "Invalid Table Name");
433 SCTAB nDummy;
434 SCTAB i = GetTableCount() + 1;
435
436 for (SCTAB j = 0; j < nCount; ++j)
437 {
438 bool bOk = false;
439 while(!bOk)
440 {
441 rName = aStrTable;
442 rName.append(static_cast<sal_Int32>(i));
443 if (bPrefix)
444 bOk = ValidNewTabName( rName.toString() );
445 else
446 bOk = !GetTable( rName.toString(), nDummy );
447 i++;
448 }
449 aNames.push_back(rName.makeStringAndClear());
450 }
451}
452
453void ScDocument::AppendTabOnLoad(const OUString& rName)
454{
455 SCTAB nTabCount = GetTableCount();
456 if (!ValidTab(nTabCount))
457 // max table count reached. No more tables.
458 return;
459
460 OUString aName = rName;
462 maTabs.emplace_back( new ScTable(*this, nTabCount, aName) );
463}
464
465void ScDocument::SetTabNameOnLoad(SCTAB nTab, const OUString& rName)
466{
467 if (!ValidTab(nTab) || GetTableCount() <= nTab)
468 return;
469
470 if (!ValidTabName(rName))
471 return;
472
473 maTabs[nTab]->SetName(rName);
474}
475
477{
478 for (const auto& a : maTabs)
479 {
480 if (a)
481 a->SetStreamValid(false);
482 }
483}
484
486 SCTAB nPos, const OUString& rName, bool bExternalDocument, bool bUndoDeleteTab )
487{
488 SCTAB nTabCount = GetTableCount();
489 bool bValid = ValidTab(nTabCount);
490 if ( !bExternalDocument ) // else test rName == "'Doc'!Tab" first
491 bValid = (bValid && ValidNewTabName(rName));
492 if (bValid)
493 {
494 if (nPos == SC_TAB_APPEND || nPos >= nTabCount)
495 {
496 nPos = maTabs.size();
497 maTabs.emplace_back( new ScTable(*this, nTabCount, rName) );
498 if ( bExternalDocument )
499 maTabs[nTabCount]->SetVisible( false );
500 }
501 else
502 {
503 if (ValidTab(nPos) && (nPos < nTabCount))
504 {
505 sc::RefUpdateInsertTabContext aCxt( *this, nPos, 1);
506
507 ScRange aRange( 0,0,nPos, MaxCol(),MaxRow(),MAXTAB );
508 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
509 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
510 if (pRangeName)
511 pRangeName->UpdateInsertTab(aCxt);
512 pDBCollection->UpdateReference(
513 URM_INSDEL, 0,0,nPos, MaxCol(),MaxRow(),MAXTAB, 0,0,1 );
514 if (pDPCollection)
515 pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
516 if (pDetOpList)
517 pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,1 );
518 UpdateChartRef( URM_INSDEL, 0,0,nPos, MaxCol(),MaxRow(),MAXTAB, 0,0,1 );
519 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,1 );
520 if ( pUnoBroadcaster )
521 pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,1 ) );
522
523 for (const auto& a : maTabs)
524 {
525 if (a)
526 a->UpdateInsertTab(aCxt);
527 }
528 maTabs.emplace(maTabs.begin() + nPos, new ScTable(*this, nPos, rName));
529
530 // UpdateBroadcastAreas must be called between UpdateInsertTab,
531 // which ends listening, and StartAllListeners, to not modify
532 // areas that are to be inserted by starting listeners.
533 UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,1);
534 for (const auto& a : maTabs)
535 {
536 if (a)
537 a->UpdateCompile();
538 }
539
541
542 if (pValidationList)
543 {
545 pValidationList->UpdateInsertTab(aCxt);
546 }
547
548 bValid = true;
549 }
550 else
551 bValid = false;
552 }
553 }
554
555 if (bValid)
556 {
558 aCxt.mbClearTabDeletedFlag = bUndoDeleteTab;
559 aCxt.mnTabDeletedStart = nPos;
560 aCxt.mnTabDeletedEnd = nPos;
562
564 {
565 ScModelObj* pModel = comphelper::getFromUnoTunnel<ScModelObj>(this->GetDocumentShell()->GetModel());
567 }
568 }
569
570 return bValid;
571}
572
573bool ScDocument::InsertTabs( SCTAB nPos, const std::vector<OUString>& rNames,
574 bool bNamesValid )
575{
576 SCTAB nNewSheets = static_cast<SCTAB>(rNames.size());
577 SCTAB nTabCount = GetTableCount();
578 bool bValid = bNamesValid || ValidTab(nTabCount+nNewSheets);
579
580 if (bValid)
581 {
582 if (nPos == SC_TAB_APPEND || nPos >= nTabCount)
583 {
584 for ( SCTAB i = 0; i < nNewSheets; ++i )
585 {
586 maTabs.emplace_back( new ScTable(*this, nTabCount + i, rNames.at(i)) );
587 }
588 }
589 else
590 {
591 if (ValidTab(nPos) && (nPos < nTabCount))
592 {
593 sc::RefUpdateInsertTabContext aCxt( *this, nPos, nNewSheets);
594 ScRange aRange( 0,0,nPos, MaxCol(),MaxRow(),MAXTAB );
595 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,nNewSheets );
596 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,nNewSheets );
597 if (pRangeName)
598 pRangeName->UpdateInsertTab(aCxt);
599 pDBCollection->UpdateReference(
600 URM_INSDEL, 0,0,nPos, MaxCol(),MaxRow(),MAXTAB, 0,0,nNewSheets );
601 if (pDPCollection)
602 pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,nNewSheets );
603 if (pDetOpList)
604 pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,nNewSheets );
605 UpdateChartRef( URM_INSDEL, 0,0,nPos, MaxCol(),MaxRow(),MAXTAB, 0,0,nNewSheets );
606 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0, nNewSheets );
607 if ( pUnoBroadcaster )
608 pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,nNewSheets ) );
609
610 for (const auto& a : maTabs)
611 {
612 if (a)
613 a->UpdateInsertTab(aCxt);
614 }
615 for (SCTAB i = 0; i < nNewSheets; ++i)
616 {
617 maTabs.emplace(maTabs.begin() + nPos + i, new ScTable(*this, nPos + i, rNames.at(i)) );
618 }
619
620 // UpdateBroadcastAreas must be called between UpdateInsertTab,
621 // which ends listening, and StartAllListeners, to not modify
622 // areas that are to be inserted by starting listeners.
623 UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,nNewSheets);
624 for (const auto& a : maTabs)
625 {
626 if (a)
627 a->UpdateCompile();
628 }
629
631
632 if (pValidationList)
633 {
635 pValidationList->UpdateInsertTab(aCxt);
636 }
637
638 bValid = true;
639 }
640 else
641 bValid = false;
642 }
643 }
644
645 if (bValid)
646 {
649 }
650
651 return bValid;
652}
653
655{
656 bool bValid = false;
657 if (HasTable(nTab))
658 {
659 SCTAB nTabCount = GetTableCount();
660 if (nTabCount > 1)
661 {
662 sc::AutoCalcSwitch aACSwitch(*this, false);
663 sc::RefUpdateDeleteTabContext aCxt( *this, nTab, 1);
664 sc::DelayDeletingBroadcasters delayDeletingBroadcasters(*this);
665
666 ScRange aRange( 0, 0, nTab, MaxCol(), MaxRow(), nTab );
667 DelBroadcastAreasInRange( aRange );
668
669 // #i8180# remove database ranges etc. that are on the deleted tab
670 // (restored in undo with ScRefUndoData)
671
672 xColNameRanges->DeleteOnTab( nTab );
673 xRowNameRanges->DeleteOnTab( nTab );
674 pDBCollection->DeleteOnTab( nTab );
675 if (pDPCollection)
676 pDPCollection->DeleteOnTab( nTab );
677 if (pDetOpList)
678 pDetOpList->DeleteOnTab( nTab );
679 DeleteAreaLinksOnTab( nTab );
680
681 // normal reference update
682
683 aRange.aEnd.SetTab(GetTableCount() - 1);
684 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1 );
685 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1 );
686 if (pRangeName)
687 pRangeName->UpdateDeleteTab(aCxt);
688 pDBCollection->UpdateReference(
689 URM_INSDEL, 0,0,nTab, MaxCol(),MaxRow(),MAXTAB, 0,0,-1 );
690 if (pDPCollection)
691 pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,-1 );
692 if (pDetOpList)
693 pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,-1 );
694 UpdateChartRef( URM_INSDEL, 0,0,nTab, MaxCol(),MaxRow(),MAXTAB, 0,0,-1 );
695 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,-1 );
696 if (pValidationList)
697 {
699 pValidationList->UpdateDeleteTab(aCxt);
700 }
701 if ( pUnoBroadcaster )
702 pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,-1 ) );
703
704 for (auto & pTab : maTabs)
705 if (pTab)
706 pTab->UpdateDeleteTab(aCxt);
707
708 // tdf#149502 make sure ScTable destructor called after the erase is finished, when
709 // maTabs[x].nTab==x is true again, as it should be always true.
710 // In the end of maTabs.erase, maTabs indexes change, but nTab updated before erase.
711 // ~ScTable expect that maTabs[x].nTab==x so it shouldn't be called during erase.
712 ScTableUniquePtr pErasedTab = std::move(maTabs[nTab]);
713 maTabs.erase(maTabs.begin() + nTab);
714 delete pErasedTab.release();
715
716 // UpdateBroadcastAreas must be called between UpdateDeleteTab,
717 // which ends listening, and StartAllListeners, to not modify
718 // areas that are to be inserted by starting listeners.
719 UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,-1);
720 for (const auto& a : maTabs)
721 {
722 if (a)
723 a->UpdateCompile();
724 }
725 // Excel-Filter deletes some Tables while loading, Listeners will
726 // only be triggered after the loading is done.
728 {
730
731 sc::SetFormulaDirtyContext aFormulaDirtyCxt;
732 SetAllFormulasDirty(aFormulaDirtyCxt);
733 }
734
736 {
737 ScModelObj* pModel = comphelper::getFromUnoTunnel<ScModelObj>(this->GetDocumentShell()->GetModel());
739 }
740
741 bValid = true;
742 }
743 }
744 return bValid;
745}
746
747bool ScDocument::DeleteTabs( SCTAB nTab, SCTAB nSheets )
748{
749 bool bValid = false;
750 if (HasTable(nTab) && (nTab + nSheets) <= GetTableCount())
751 {
752 SCTAB nTabCount = GetTableCount();
753 if (nTabCount > nSheets)
754 {
755 sc::AutoCalcSwitch aACSwitch(*this, false);
756 sc::RefUpdateDeleteTabContext aCxt( *this, nTab, nSheets);
757 sc::DelayDeletingBroadcasters delayDeletingBroadcasters(*this);
758
759 for (SCTAB aTab = 0; aTab < nSheets; ++aTab)
760 {
761 ScRange aRange( 0, 0, nTab, MaxCol(), MaxRow(), nTab + aTab );
762 DelBroadcastAreasInRange( aRange );
763
764 // #i8180# remove database ranges etc. that are on the deleted tab
765 // (restored in undo with ScRefUndoData)
766
767 xColNameRanges->DeleteOnTab( nTab + aTab );
768 xRowNameRanges->DeleteOnTab( nTab + aTab );
769 pDBCollection->DeleteOnTab( nTab + aTab );
770 if (pDPCollection)
771 pDPCollection->DeleteOnTab( nTab + aTab );
772 if (pDetOpList)
773 pDetOpList->DeleteOnTab( nTab + aTab );
774 DeleteAreaLinksOnTab( nTab + aTab );
775 }
776
777 if (pRangeName)
778 pRangeName->UpdateDeleteTab(aCxt);
779
780 // normal reference update
781
782 ScRange aRange( 0, 0, nTab, MaxCol(), MaxRow(), nTabCount - 1 );
783 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1*nSheets );
784 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1*nSheets );
785 pDBCollection->UpdateReference(
786 URM_INSDEL, 0,0,nTab, MaxCol(),MaxRow(),MAXTAB, 0,0,-1*nSheets );
787 if (pDPCollection)
788 pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,-1*nSheets );
789 if (pDetOpList)
790 pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,-1*nSheets );
791 UpdateChartRef( URM_INSDEL, 0,0,nTab, MaxCol(),MaxRow(),MAXTAB, 0,0,-1*nSheets );
792 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,-1*nSheets );
793 if (pValidationList)
794 {
796 pValidationList->UpdateDeleteTab(aCxt);
797 }
798 if ( pUnoBroadcaster )
799 pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,-1*nSheets ) );
800
801 for (auto & pTab : maTabs)
802 if (pTab)
803 pTab->UpdateDeleteTab(aCxt);
804
805 maTabs.erase(maTabs.begin() + nTab, maTabs.begin() + nTab + nSheets);
806 // UpdateBroadcastAreas must be called between UpdateDeleteTab,
807 // which ends listening, and StartAllListeners, to not modify
808 // areas that are to be inserted by starting listeners.
809 UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,-1*nSheets);
810 for (const auto& a : maTabs)
811 {
812 if (a)
813 a->UpdateCompile();
814 }
815 // Excel-Filter deletes some Tables while loading, Listeners will
816 // only be triggered after the loading is done.
818 {
820
821 sc::SetFormulaDirtyContext aFormulaDirtyCxt;
822 SetAllFormulasDirty(aFormulaDirtyCxt);
823 }
824
826 {
827 ScModelObj* pModel = comphelper::getFromUnoTunnel<ScModelObj>(this->GetDocumentShell()->GetModel());
829 }
830
831 bValid = true;
832 }
833 }
834 return bValid;
835}
836
837bool ScDocument::RenameTab( SCTAB nTab, const OUString& rName, bool bExternalDocument )
838{
839 bool bValid = false;
840 SCTAB i;
841 if (HasTable(nTab))
842 {
843 if ( bExternalDocument )
844 bValid = true; // composed name
845 else
846 bValid = ValidTabName(rName);
847 for (i = 0; i < GetTableCount() && bValid; i++)
848 {
849 if (maTabs[i] && (i != nTab))
850 {
851 OUString aOldName = maTabs[i]->GetName();
852 bValid = !ScGlobal::GetTransliteration().isEqual( rName, aOldName );
853 }
854 }
855 if (bValid)
856 {
857 // #i75258# update charts before renaming, so they can get their live data objects.
858 // Once the charts are live, the sheet can be renamed without problems.
860 pChartListenerCollection->UpdateChartsContainingTab( nTab );
861 maTabs[nTab]->SetName(rName);
862
863 // If formulas refer to the renamed sheet, the TokenArray remains valid,
864 // but the XML stream must be re-generated.
865 for (const auto& pTable : maTabs)
866 {
867 if (pTable)
868 pTable->SetStreamValid( false );
869 }
870
872 {
873 ScModelObj* pModel = comphelper::getFromUnoTunnel<ScModelObj>(this->GetDocumentShell()->GetModel());
875 }
876 }
877 }
878
879 collectUIInformation({{"NewName", rName}}, "Rename_Sheet");
880
881 return bValid;
882}
883
884void ScDocument::SetVisible( SCTAB nTab, bool bVisible )
885{
886 if (ScTable* pTable = FetchTable(nTab))
887 pTable->SetVisible(bVisible);
888}
889
890bool ScDocument::IsVisible( SCTAB nTab ) const
891{
892 if (const ScTable* pTable = FetchTable(nTab))
893 return pTable->IsVisible();
894 return false;
895}
896
898{
899 if (const ScTable* pTable = FetchTable(nTab))
900 return pTable->IsStreamValid();
901 return false;
902}
903
904void ScDocument::SetStreamValid( SCTAB nTab, bool bSet, bool bIgnoreLock )
905{
906 if (ScTable* pTable = FetchTable(nTab))
907 pTable->SetStreamValid( bSet, bIgnoreLock );
908}
909
911{
912 mbStreamValidLocked = bLock;
913}
914
916{
917 if (const ScTable* pTable = FetchTable(nTab))
918 return pTable->IsPendingRowHeights();
919 return false;
920}
921
923{
924 if (ScTable* pTable = FetchTable(nTab))
925 pTable->SetPendingRowHeights(bSet);
926}
927
929{
930 const ScTable* pTab = FetchTable(nTab);
931 if (!pTab)
933
934 return pTab->GetOptimalMinRowHeight();
935}
936
937void ScDocument::SetLayoutRTL( SCTAB nTab, bool bRTL, ScObjectHandling eObjectHandling)
938{
939 ScTable* pTable = FetchTable(nTab);
940 if (!pTable)
941 return;
942
943 if ( bImportingXML )
944 {
945 // #i57869# only set the LoadingRTL flag, the real setting (including mirroring)
946 // is applied in SetImportingXML(false). This is so the shapes can be loaded in
947 // normal LTR mode.
948
949 pTable->SetLoadingRTL( bRTL );
950 return;
951 }
952
953 pTable->SetLayoutRTL( bRTL ); // only sets the flag
954 pTable->SetDrawPageSize(true, true, eObjectHandling);
955
956 // objects are already repositioned via SetDrawPageSize, only writing mode is missing
957 if (!mpDrawLayer)
958 return;
959
960 SdrPage* pPage = mpDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
961 OSL_ENSURE(pPage,"Page ?");
962 if (!pPage)
963 return;
964
965 SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups );
966 SdrObject* pObject = aIter.Next();
967 while (pObject)
968 {
969 pObject->SetContextWritingMode( bRTL ? WritingMode2::RL_TB : WritingMode2::LR_TB );
970 pObject = aIter.Next();
971 }
972}
973
975{
976 if (const ScTable* pTable = FetchTable(nTab))
977 return pTable->IsLayoutRTL();
978
979 return false;
980}
981
983{
984 // Negative page area is always used for RTL layout.
985 // The separate method is used to find all RTL handling of drawing objects.
986 return IsLayoutRTL( nTab );
987}
988
989/* ----------------------------------------------------------------------------
990 used search area:
991
992 GetCellArea - Only Data
993 GetTableArea - Data / Attributes
994 GetPrintArea - intended for character objects,
995 sweeps attributes all the way to bottom / right
996---------------------------------------------------------------------------- */
997
998bool ScDocument::GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const
999{
1000 if (HasTable(nTab))
1001 return maTabs[nTab]->GetCellArea(rEndCol, rEndRow);
1002
1003 rEndCol = 0;
1004 rEndRow = 0;
1005 return false;
1006}
1007
1008bool ScDocument::GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow, bool bCalcHiddens) const
1009{
1010 if (const ScTable* pTable = FetchTable(nTab))
1011 return pTable->GetTableArea(rEndCol, rEndRow, bCalcHiddens);
1012
1013 rEndCol = 0;
1014 rEndRow = 0;
1015 return false;
1016}
1017
1018bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const
1019{
1020 if (!HasTable(nTab))
1021 return false;
1022
1023 SCCOL nCol1, nCol2;
1024 SCROW nRow1, nRow2;
1025 maTabs[nTab]->GetFirstDataPos(nCol1, nRow1);
1026 maTabs[nTab]->GetLastDataPos(nCol2, nRow2);
1027
1028 if (nCol1 > nCol2 || nRow1 > nRow2)
1029 // invalid range.
1030 return false;
1031
1032 // Make sure the area only shrinks, and doesn't grow.
1033 if (rStartCol < nCol1)
1034 rStartCol = nCol1;
1035 if (nCol2 < rEndCol)
1036 rEndCol = nCol2;
1037 if (rStartRow < nRow1)
1038 rStartRow = nRow1;
1039 if (nRow2 < rEndRow)
1040 rEndRow = nRow2;
1041
1042 if (rStartCol > rEndCol || rStartRow > rEndRow)
1043 // invalid range.
1044 return false;
1045
1046 return true; // success!
1047}
1048
1049bool ScDocument::ShrinkToUsedDataArea( bool& o_bShrunk, SCTAB nTab, SCCOL& rStartCol,
1050 SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly,
1051 bool bStickyTopRow, bool bStickyLeftCol, ScDataAreaExtras* pDataAreaExtras ) const
1052{
1053 if (const ScTable* pTable = FetchTable(nTab))
1054 {
1055 return pTable->ShrinkToUsedDataArea(
1056 o_bShrunk, rStartCol, rStartRow, rEndCol, rEndRow, bColumnsOnly, bStickyTopRow,
1057 bStickyLeftCol, pDataAreaExtras);
1058 }
1059 o_bShrunk = false;
1060 return false;
1061}
1062
1063SCROW ScDocument::GetLastDataRow( SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCROW nLastRow ) const
1064{
1065 if (const ScTable* pTable = FetchTable(nTab))
1066 return pTable->GetLastDataRow(nCol1, nCol2, nLastRow);
1067 return -1;
1068}
1069
1070// connected area
1071
1072void ScDocument::GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
1073 SCCOL& rEndCol, SCROW& rEndRow, bool bIncludeOld, bool bOnlyDown ) const
1074{
1075 if (const ScTable* pTable = FetchTable(nTab))
1076 pTable->GetDataArea( rStartCol, rStartRow, rEndCol, rEndRow, bIncludeOld, bOnlyDown );
1077}
1078
1080{
1081 SCTAB nTab = rRange.aStart.Tab();
1082 if (nTab != rRange.aEnd.Tab())
1083 return true;
1084
1085 if (const ScTable* pTable = FetchTable(nTab))
1086 return pTable->GetDataAreaSubrange(rRange);
1087
1088 return true;
1089}
1090
1091void ScDocument::LimitChartArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
1092 SCCOL& rEndCol, SCROW& rEndRow )
1093{
1094 if (ScTable* pTable = FetchTable(nTab))
1095 pTable->LimitChartArea( rStartCol, rStartRow, rEndCol, rEndRow);
1096}
1097
1099{
1100 ScRangeListRef aNew = new ScRangeList;
1101 if (rRangeList.is())
1102 {
1103 for ( size_t i = 0, nCount = rRangeList->size(); i < nCount; i++ )
1104 {
1105 ScRange aRange( (*rRangeList)[i] );
1106 if ( ( aRange.aStart.Col() == 0 && aRange.aEnd.Col() == MaxCol() ) ||
1107 ( aRange.aStart.Row() == 0 && aRange.aEnd.Row() == MaxRow() ) )
1108 {
1109 SCCOL nStartCol = aRange.aStart.Col();
1110 SCROW nStartRow = aRange.aStart.Row();
1111 SCCOL nEndCol = aRange.aEnd.Col();
1112 SCROW nEndRow = aRange.aEnd.Row();
1113 SCTAB nTab = aRange.aStart.Tab();
1114 if (ScTable* pTable = FetchTable(nTab))
1115 pTable->LimitChartArea(nStartCol, nStartRow, nEndCol, nEndRow);
1116 aRange.aStart.SetCol( nStartCol );
1117 aRange.aStart.SetRow( nStartRow );
1118 aRange.aEnd.SetCol( nEndCol );
1119 aRange.aEnd.SetRow( nEndRow );
1120 }
1121 aNew->push_back(aRange);
1122 }
1123 }
1124 else
1125 {
1126 OSL_FAIL("LimitChartIfAll: Ref==0");
1127 }
1128 rRangeList = aNew;
1129}
1130
1131static void lcl_GetFirstTabRange( SCTAB& rTabRangeStart, SCTAB& rTabRangeEnd, const ScMarkData* pTabMark, SCTAB aMaxTab )
1132{
1133 // without ScMarkData, leave start/end unchanged
1134 if ( !pTabMark )
1135 return;
1136
1137 for (SCTAB nTab=0; nTab< aMaxTab; ++nTab)
1138 if (pTabMark->GetTableSelect(nTab))
1139 {
1140 // find first range of consecutive selected sheets
1141 rTabRangeStart = pTabMark->GetFirstSelected();
1142 while ( nTab+1 < aMaxTab && pTabMark->GetTableSelect(nTab+1) )
1143 ++nTab;
1144 rTabRangeEnd = nTab;
1145 return;
1146 }
1147}
1148
1149static bool lcl_GetNextTabRange( SCTAB& rTabRangeStart, SCTAB& rTabRangeEnd, const ScMarkData* pTabMark, SCTAB aMaxTab )
1150{
1151 if ( pTabMark )
1152 {
1153 // find next range of consecutive selected sheets after rTabRangeEnd
1154 for (SCTAB nTab=rTabRangeEnd+1; nTab< aMaxTab; ++nTab)
1155 if (pTabMark->GetTableSelect(nTab))
1156 {
1157 rTabRangeStart = nTab;
1158 while ( nTab+1 < aMaxTab && pTabMark->GetTableSelect(nTab+1) )
1159 ++nTab;
1160 rTabRangeEnd = nTab;
1161 return true;
1162 }
1163 }
1164 return false;
1165}
1166
1167bool ScDocument::CanInsertRow( const ScRange& rRange ) const
1168{
1169 SCCOL nStartCol = rRange.aStart.Col();
1170 SCROW nStartRow = rRange.aStart.Row();
1171 SCTAB nStartTab = rRange.aStart.Tab();
1172 SCCOL nEndCol = rRange.aEnd.Col();
1173 SCROW nEndRow = rRange.aEnd.Row();
1174 SCTAB nEndTab = rRange.aEnd.Tab();
1175 PutInOrder( nStartCol, nEndCol );
1176 PutInOrder( nStartRow, nEndRow );
1177 PutInOrder( nStartTab, nEndTab );
1178 SCSIZE nSize = static_cast<SCSIZE>(nEndRow - nStartRow + 1);
1179
1180 bool bTest = true;
1181 for (SCTAB i = nStartTab; i <= nEndTab && bTest && i < GetTableCount(); i++)
1182 if (maTabs[i])
1183 bTest &= maTabs[i]->TestInsertRow( nStartCol, nEndCol, nStartRow, nSize );
1184
1185 return bTest;
1186}
1187
1188namespace {
1189
1190struct SetDirtyIfPostponedHandler
1191{
1192 void operator() (const ScTableUniquePtr & p)
1193 {
1194 if (p)
1195 p->SetDirtyIfPostponed();
1196 }
1197};
1198
1199struct BroadcastRecalcOnRefMoveHandler
1200{
1201 void operator() (const ScTableUniquePtr & p)
1202 {
1203 if (p)
1204 p->BroadcastRecalcOnRefMove();
1205 }
1206};
1207
1208struct BroadcastRecalcOnRefMoveGuard
1209{
1210 explicit BroadcastRecalcOnRefMoveGuard( ScDocument* pDoc ) :
1211 aSwitch( *pDoc, false),
1212 aBulk( pDoc->GetBASM(), SfxHintId::ScDataChanged)
1213 {
1214 }
1215
1216private:
1217 sc::AutoCalcSwitch aSwitch; // first for ctor/dtor order, destroy second
1218 ScBulkBroadcast aBulk; // second for ctor/dtor order, destroy first
1219};
1220
1221}
1222
1223bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
1224 SCCOL nEndCol, SCTAB nEndTab,
1225 SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc,
1226 const ScMarkData* pTabMark )
1227{
1228 SCTAB i;
1229
1230 PutInOrder( nStartCol, nEndCol );
1231 PutInOrder( nStartTab, nEndTab );
1232 if ( pTabMark )
1233 {
1234 nStartTab = 0;
1235 nEndTab = GetTableCount() - 1;
1236 }
1237
1238 bool bTest = true;
1239 bool bRet = false;
1240 bool bOldAutoCalc = GetAutoCalc();
1241 SetAutoCalc( false ); // avoid multiple calculations
1242 bool oldDelayedDeleteBroadcasters = IsDelayedDeletingBroadcasters();
1244 for ( i = nStartTab; i <= nEndTab && bTest && i < GetTableCount(); i++)
1245 if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
1246 bTest &= maTabs[i]->TestInsertRow(nStartCol, nEndCol, nStartRow, nSize);
1247 if (bTest)
1248 {
1249 // UpdateBroadcastAreas have to be called before UpdateReference, so that entries
1250 // aren't shifted that would be rebuild at UpdateReference
1251
1252 // handle chunks of consecutive selected sheets together
1253 SCTAB nTabRangeStart = nStartTab;
1254 SCTAB nTabRangeEnd = nEndTab;
1255 lcl_GetFirstTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount());
1256 ScRange aShiftedRange(nStartCol, nStartRow, nTabRangeStart, nEndCol, MaxRow(), nTabRangeEnd);
1257 sc::EndListeningContext aEndListenCxt(*this);
1258
1259 std::vector<ScAddress> aGroupPos;
1260 do
1261 {
1262 aShiftedRange.aStart.SetTab(nTabRangeStart);
1263 aShiftedRange.aEnd.SetTab(nTabRangeEnd);
1264
1265 // Collect all formula groups that will get split by the shifting,
1266 // and end all their listening. Record the position of the top
1267 // cell of the topmost group, and the position of the bottom cell
1268 // of the bottommost group.
1269 EndListeningIntersectedGroups(aEndListenCxt, aShiftedRange, &aGroupPos);
1270
1271 UpdateBroadcastAreas(URM_INSDEL, aShiftedRange, 0, static_cast<SCROW>(nSize), 0);
1272 }
1273 while (lcl_GetNextTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount()));
1274
1275 lcl_GetFirstTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount());
1276
1277 sc::RefUpdateContext aCxt(*this);
1278 aCxt.meMode = URM_INSDEL;
1279 aCxt.maRange = aShiftedRange;
1280 aCxt.mnRowDelta = nSize;
1281 do
1282 {
1283 aCxt.maRange.aStart.SetTab(nTabRangeStart);
1284 aCxt.maRange.aEnd.SetTab(nTabRangeEnd);
1285 UpdateReference(aCxt, pRefUndoDoc, false); // without drawing objects
1286 }
1287 while (lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount()));
1288
1289 // UpdateReference should have set "needs listening" flags to those
1290 // whose references have been modified. We also need to set this flag
1291 // to those that were in the groups that got split by shifting.
1292 SetNeedsListeningGroups(aGroupPos);
1293
1294 for (i=nStartTab; i<=nEndTab && i < GetTableCount(); i++)
1295 if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
1296 maTabs[i]->InsertRow( nStartCol, nEndCol, nStartRow, nSize );
1297
1298 // UpdateRef for drawing layer must be after inserting,
1299 // when the new row heights are known.
1300 for (i=nStartTab; i<=nEndTab && i < GetTableCount(); i++)
1301 if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
1302 maTabs[i]->UpdateDrawRef( URM_INSDEL,
1303 nStartCol, nStartRow, nStartTab, nEndCol, MaxRow(), nEndTab,
1304 0, static_cast<SCROW>(nSize), 0 );
1305
1306 if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
1307 { // A new Listening is needed when references to deleted ranges are restored,
1308 // previous Listeners were removed in FormulaCell UpdateReference.
1310 }
1311 else
1312 { // Listeners have been removed in UpdateReference
1314
1315 // At least all cells using range names pointing relative to the
1316 // moved range must be recalculated, and all cells marked postponed
1317 // dirty.
1318 for (const auto& a : maTabs)
1319 {
1320 if (a)
1321 a->SetDirtyIfPostponed();
1322 }
1323
1324 {
1325 BroadcastRecalcOnRefMoveGuard g(this);
1326 std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler());
1327 }
1328 }
1329 bRet = true;
1330 }
1331 EnableDelayDeletingBroadcasters( oldDelayedDeleteBroadcasters );
1332 SetAutoCalc( bOldAutoCalc );
1333 if ( bRet && pChartListenerCollection )
1334 pChartListenerCollection->UpdateDirtyCharts();
1335 return bRet;
1336}
1337
1338bool ScDocument::InsertRow( const ScRange& rRange )
1339{
1340 return InsertRow( rRange.aStart.Col(), rRange.aStart.Tab(),
1341 rRange.aEnd.Col(), rRange.aEnd.Tab(),
1342 rRange.aStart.Row(), static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1) );
1343}
1344
1345void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
1346 SCCOL nEndCol, SCTAB nEndTab,
1347 SCROW nStartRow, SCSIZE nSize,
1348 ScDocument* pRefUndoDoc, bool* pUndoOutline,
1349 const ScMarkData* pTabMark )
1350{
1351 SCTAB i;
1352
1353 PutInOrder( nStartCol, nEndCol );
1354 PutInOrder( nStartTab, nEndTab );
1355 if ( pTabMark )
1356 {
1357 nStartTab = 0;
1358 nEndTab = GetTableCount() - 1;
1359 }
1360
1361 sc::AutoCalcSwitch aACSwitch(*this, false); // avoid multiple calculations
1362
1363 // handle chunks of consecutive selected sheets together
1364 SCTAB nTabRangeStart = nStartTab;
1365 SCTAB nTabRangeEnd = nEndTab;
1366 lcl_GetFirstTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount());
1367 do
1368 {
1369 if ( ValidRow(nStartRow+nSize) )
1370 {
1372 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
1373 ScAddress( nEndCol, nStartRow+nSize-1, nTabRangeEnd ) ) );
1375 ScAddress( nStartCol, nStartRow+nSize, nTabRangeStart ),
1376 ScAddress( nEndCol, MaxRow(), nTabRangeEnd )), 0, -static_cast<SCROW>(nSize), 0 );
1377 }
1378 else
1380 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
1381 ScAddress( nEndCol, MaxRow(), nTabRangeEnd ) ) );
1382 }
1383 while (lcl_GetNextTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount()));
1384
1385 sc::RefUpdateContext aCxt(*this);
1386 const bool bLastRowIncluded = (static_cast<SCROW>(nStartRow + nSize) == GetMaxRowCount() && ValidRow(nStartRow));
1387 if ( ValidRow(nStartRow+nSize) || bLastRowIncluded )
1388 {
1389 lcl_GetFirstTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount());
1390 aCxt.meMode = URM_INSDEL;
1391 aCxt.mnRowDelta = -static_cast<SCROW>(nSize);
1392 if (bLastRowIncluded)
1393 {
1394 // Last row is included, shift a virtually non-existent row in.
1395 aCxt.maRange = ScRange( nStartCol, GetMaxRowCount(), nTabRangeStart, nEndCol, GetMaxRowCount(), nTabRangeEnd);
1396 }
1397 else
1398 {
1399 aCxt.maRange = ScRange( nStartCol, nStartRow+nSize, nTabRangeStart, nEndCol, MaxRow(), nTabRangeEnd);
1400 }
1401 do
1402 {
1403 UpdateReference(aCxt, pRefUndoDoc, true, false);
1404 }
1405 while (lcl_GetNextTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount()));
1406 }
1407
1408 if (pUndoOutline)
1409 *pUndoOutline = false;
1410
1411 // Keep track of the positions of all formula groups that have been joined
1412 // during row deletion.
1413 std::vector<ScAddress> aGroupPos;
1414
1415 for ( i = nStartTab; i <= nEndTab && i < GetTableCount(); i++)
1416 if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
1417 maTabs[i]->DeleteRow(aCxt.maRegroupCols, nStartCol, nEndCol, nStartRow, nSize, pUndoOutline, &aGroupPos);
1418
1419 // Newly joined groups have some of their members still listening. We
1420 // need to make sure none of them are listening.
1421 EndListeningGroups(aGroupPos);
1422
1423 // Mark all joined groups for group listening.
1424 SetNeedsListeningGroups(aGroupPos);
1425
1426 if ( ValidRow(nStartRow+nSize) || bLastRowIncluded )
1427 {
1428 // Listeners have been removed in UpdateReference
1430
1431 // At least all cells using range names pointing relative to the moved
1432 // range must be recalculated, and all cells marked postponed dirty.
1433 for (const auto& a : maTabs)
1434 {
1435 if (a)
1436 a->SetDirtyIfPostponed();
1437 }
1438
1439 {
1440 BroadcastRecalcOnRefMoveGuard g(this);
1441 std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler());
1442 }
1443 }
1444
1446 pChartListenerCollection->UpdateDirtyCharts();
1447}
1448
1449void ScDocument::DeleteRow( const ScRange& rRange )
1450{
1451 DeleteRow( rRange.aStart.Col(), rRange.aStart.Tab(),
1452 rRange.aEnd.Col(), rRange.aEnd.Tab(),
1453 rRange.aStart.Row(), static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1) );
1454}
1455
1456bool ScDocument::CanInsertCol( const ScRange& rRange ) const
1457{
1458 SCCOL nStartCol = rRange.aStart.Col();
1459 SCROW nStartRow = rRange.aStart.Row();
1460 SCTAB nStartTab = rRange.aStart.Tab();
1461 SCCOL nEndCol = rRange.aEnd.Col();
1462 SCROW nEndRow = rRange.aEnd.Row();
1463 SCTAB nEndTab = rRange.aEnd.Tab();
1464 PutInOrder( nStartCol, nEndCol );
1465 PutInOrder( nStartRow, nEndRow );
1466 PutInOrder( nStartTab, nEndTab );
1467 SCSIZE nSize = static_cast<SCSIZE>(nEndCol - nStartCol + 1);
1468
1469 bool bTest = true;
1470 for (SCTAB i = nStartTab; i <= nEndTab && bTest && i < GetTableCount(); i++)
1471 if (maTabs[i])
1472 bTest &= maTabs[i]->TestInsertCol( nStartRow, nEndRow, nSize );
1473
1474 return bTest;
1475}
1476
1477bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
1478 SCROW nEndRow, SCTAB nEndTab,
1479 SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc,
1480 const ScMarkData* pTabMark )
1481{
1482 SCTAB i;
1483
1484 PutInOrder( nStartRow, nEndRow );
1485 PutInOrder( nStartTab, nEndTab );
1486 if ( pTabMark )
1487 {
1488 nStartTab = 0;
1489 nEndTab = GetTableCount() - 1;
1490 }
1491
1492 bool bTest = true;
1493 bool bRet = false;
1494 bool bOldAutoCalc = GetAutoCalc();
1495 SetAutoCalc( false ); // avoid multiple calculations
1496 bool oldDelayedDeleteBroadcasters = IsDelayedDeletingBroadcasters();
1498 for ( i = nStartTab; i <= nEndTab && bTest && i < GetTableCount(); i++)
1499 if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
1500 bTest &= maTabs[i]->TestInsertCol( nStartRow, nEndRow, nSize );
1501 if (bTest)
1502 {
1503 // handle chunks of consecutive selected sheets together
1504 SCTAB nTabRangeStart = nStartTab;
1505 SCTAB nTabRangeEnd = nEndTab;
1506 lcl_GetFirstTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount());
1507 do
1508 {
1510 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
1511 ScAddress( MaxCol(), nEndRow, nTabRangeEnd )), static_cast<SCCOL>(nSize), 0, 0 );
1512 }
1513 while (lcl_GetNextTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount()));
1514
1515 lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount());
1516
1517 sc::RefUpdateContext aCxt(*this);
1518 aCxt.meMode = URM_INSDEL;
1519 aCxt.maRange = ScRange(nStartCol, nStartRow, nTabRangeStart, MaxCol(), nEndRow, nTabRangeEnd);
1520 aCxt.mnColDelta = nSize;
1521 do
1522 {
1523 UpdateReference(aCxt, pRefUndoDoc, true, false);
1524 }
1525 while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount()));
1526
1527 for (i = nStartTab; i <= nEndTab && i < GetTableCount(); i++)
1528 if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
1529 maTabs[i]->InsertCol(aCxt.maRegroupCols, nStartCol, nStartRow, nEndRow, nSize);
1530
1531 if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
1532 { // A new Listening is needed when references to deleted ranges are restored,
1533 // previous Listeners were removed in FormulaCell UpdateReference.
1535 }
1536 else
1537 {
1538 // Listeners have been removed in UpdateReference
1540 // At least all cells using range names pointing relative to the
1541 // moved range must be recalculated, and all cells marked postponed
1542 // dirty.
1543 {
1544 ScBulkBroadcast aBulkBroadcast(GetBASM(), SfxHintId::ScDataChanged);
1545 std::for_each(maTabs.begin(), maTabs.end(), SetDirtyIfPostponedHandler());
1546 }
1547 // Cells containing functions such as CELL, COLUMN or ROW may have
1548 // changed their values on relocation. Broadcast them.
1549 {
1550 BroadcastRecalcOnRefMoveGuard g(this);
1551 std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler());
1552 }
1553 }
1554 bRet = true;
1555 }
1556 EnableDelayDeletingBroadcasters( oldDelayedDeleteBroadcasters );
1557 SetAutoCalc( bOldAutoCalc );
1558 if ( bRet && pChartListenerCollection )
1559 pChartListenerCollection->UpdateDirtyCharts();
1560 return bRet;
1561}
1562
1563bool ScDocument::InsertCol( const ScRange& rRange )
1564{
1565 return InsertCol( rRange.aStart.Row(), rRange.aStart.Tab(),
1566 rRange.aEnd.Row(), rRange.aEnd.Tab(),
1567 rRange.aStart.Col(), static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1) );
1568}
1569
1570void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab,
1571 SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc,
1572 bool* pUndoOutline, const ScMarkData* pTabMark )
1573{
1574 SCTAB i;
1575
1576 PutInOrder( nStartRow, nEndRow );
1577 PutInOrder( nStartTab, nEndTab );
1578 if ( pTabMark )
1579 {
1580 nStartTab = 0;
1581 nEndTab = GetTableCount() - 1;
1582 }
1583
1584 sc::AutoCalcSwitch aACSwitch(*this, false); // avoid multiple calculations
1585 ScBulkBroadcast aBulkBroadcast(GetBASM(), SfxHintId::ScDataChanged);
1586
1587 // handle chunks of consecutive selected sheets together
1588 SCTAB nTabRangeStart = nStartTab;
1589 SCTAB nTabRangeEnd = nEndTab;
1590 lcl_GetFirstTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount());
1591 do
1592 {
1593 if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
1594 {
1596 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
1597 ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize-1), nEndRow, nTabRangeEnd ) ) );
1599 ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart ),
1600 ScAddress( MaxCol(), nEndRow, nTabRangeEnd )), -static_cast<SCCOL>(nSize), 0, 0 );
1601 }
1602 else
1604 ScAddress( nStartCol, nStartRow, nTabRangeStart ),
1605 ScAddress( MaxCol(), nEndRow, nTabRangeEnd ) ) );
1606 }
1607 while (lcl_GetNextTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount()));
1608
1609 sc::RefUpdateContext aCxt(*this);
1610 const bool bLastColIncluded = (static_cast<SCCOL>(nStartCol + nSize) == GetMaxColCount() && ValidCol(nStartCol));
1611 if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) || bLastColIncluded )
1612 {
1613 lcl_GetFirstTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount());
1614 aCxt.meMode = URM_INSDEL;
1615 aCxt.mnColDelta = -static_cast<SCCOL>(nSize);
1616 if (bLastColIncluded)
1617 {
1618 // Last column is included, shift a virtually non-existent column in.
1619 aCxt.maRange = ScRange( GetMaxColCount(), nStartRow, nTabRangeStart, GetMaxColCount(), nEndRow, nTabRangeEnd);
1620 }
1621 else
1622 {
1623 aCxt.maRange = ScRange( sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart,
1624 MaxCol(), nEndRow, nTabRangeEnd);
1625 }
1626 do
1627 {
1628 UpdateReference(aCxt, pRefUndoDoc, true, false);
1629 }
1630 while (lcl_GetNextTabRange(nTabRangeStart, nTabRangeEnd, pTabMark, GetTableCount()));
1631 }
1632
1633 if (pUndoOutline)
1634 *pUndoOutline = false;
1635
1636 for (i = nStartTab; i <= nEndTab && i < GetTableCount(); ++i)
1637 {
1638 if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
1639 maTabs[i]->DeleteCol(aCxt.maRegroupCols, nStartCol, nStartRow, nEndRow, nSize, pUndoOutline);
1640 }
1641
1642 if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) || bLastColIncluded )
1643 {
1644 // Listeners have been removed in UpdateReference
1646
1647 // At least all cells using range names pointing relative to the moved
1648 // range must be recalculated, and all cells marked postponed dirty.
1649 for (const auto& a : maTabs)
1650 {
1651 if (a)
1652 a->SetDirtyIfPostponed();
1653 }
1654
1655 {
1656 BroadcastRecalcOnRefMoveGuard g(this);
1657 std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler());
1658 }
1659 }
1660
1662 pChartListenerCollection->UpdateDirtyCharts();
1663}
1664
1665void ScDocument::DeleteCol( const ScRange& rRange )
1666{
1667 DeleteCol( rRange.aStart.Row(), rRange.aStart.Tab(),
1668 rRange.aEnd.Row(), rRange.aEnd.Tab(),
1669 rRange.aStart.Col(), static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1) );
1670}
1671
1672// for Area-Links: Insert/delete cells, when the range is changed.
1673// (without Paint)
1674
1675static void lcl_GetInsDelRanges( const ScRange& rOld, const ScRange& rNew,
1676 ScRange& rColRange, bool& rInsCol, bool& rDelCol,
1677 ScRange& rRowRange, bool& rInsRow, bool& rDelRow )
1678{
1679 OSL_ENSURE( rOld.aStart == rNew.aStart, "FitBlock: Beginning is different" );
1680
1681 rInsCol = rDelCol = rInsRow = rDelRow = false;
1682
1683 SCCOL nStartX = rOld.aStart.Col();
1684 SCROW nStartY = rOld.aStart.Row();
1685 SCCOL nOldEndX = rOld.aEnd.Col();
1686 SCROW nOldEndY = rOld.aEnd.Row();
1687 SCCOL nNewEndX = rNew.aEnd.Col();
1688 SCROW nNewEndY = rNew.aEnd.Row();
1689 SCTAB nTab = rOld.aStart.Tab();
1690
1691 // if more rows, columns are inserted/deleted at the old height.
1692 bool bGrowY = ( nNewEndY > nOldEndY );
1693 SCROW nColEndY = bGrowY ? nOldEndY : nNewEndY;
1694 SCCOL nRowEndX = bGrowY ? nNewEndX : nOldEndX;
1695
1696 // Columns
1697
1698 if ( nNewEndX > nOldEndX ) // Insert columns
1699 {
1700 rColRange = ScRange( nOldEndX+1, nStartY, nTab, nNewEndX, nColEndY, nTab );
1701 rInsCol = true;
1702 }
1703 else if ( nNewEndX < nOldEndX ) // Delete columns
1704 {
1705 rColRange = ScRange( nNewEndX+1, nStartY, nTab, nOldEndX, nColEndY, nTab );
1706 rDelCol = true;
1707 }
1708
1709 // Rows
1710
1711 if ( nNewEndY > nOldEndY ) // Insert rows
1712 {
1713 rRowRange = ScRange( nStartX, nOldEndY+1, nTab, nRowEndX, nNewEndY, nTab );
1714 rInsRow = true;
1715 }
1716 else if ( nNewEndY < nOldEndY ) // Delete rows
1717 {
1718 rRowRange = ScRange( nStartX, nNewEndY+1, nTab, nRowEndX, nOldEndY, nTab );
1719 rDelRow = true;
1720 }
1721}
1722
1724{
1725 bool bPart = false;
1726 SCTAB nTab = rRange.aStart.Tab();
1727
1728 SCCOL nStartX = rRange.aStart.Col();
1729 SCROW nStartY = rRange.aStart.Row();
1730 SCCOL nEndX = rRange.aEnd.Col();
1731 SCROW nEndY = rRange.aEnd.Row();
1732
1733 if (HasAttrib( nStartX, nStartY, nTab, nEndX, nEndY, nTab,
1735 {
1736 ExtendMerge( nStartX, nStartY, nEndX, nEndY, nTab );
1737 ExtendOverlapped( nStartX, nStartY, nEndX, nEndY, nTab );
1738
1739 bPart = ( nStartX != rRange.aStart.Col() || nEndX != rRange.aEnd.Col() ||
1740 nStartY != rRange.aStart.Row() || nEndY != rRange.aEnd.Row() );
1741 }
1742 return bPart;
1743}
1744
1746{
1747 SCTAB nTab = rPos.Tab();
1748 if (ScTable* pTable = FetchTable(nTab))
1749 return pTable->ResolveStaticReference(rPos.Col(), rPos.Row());
1750 return formula::FormulaTokenRef();
1751}
1752
1754{
1755 SCTAB nTab = rRange.aStart.Tab();
1756 if (nTab != rRange.aEnd.Tab() || !HasTable(nTab))
1757 return formula::FormulaTokenRef();
1758
1759 return maTabs[nTab]->ResolveStaticReference(
1760 rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
1761}
1762
1764{
1765 SCTAB nTab = rPos.Tab();
1766 if (ScTable* pTable = FetchTable(nTab))
1767 return pTable->FetchVectorRefArray(rPos.Col(), rPos.Row(), rPos.Row()+nLength-1);
1768 return formula::VectorRefArray();
1769}
1770
1771#ifdef DBG_UTIL
1773{
1774 SCTAB nTab = rPos.Tab();
1775 assert(HasTable(nTab));
1776 if (ScTable* pTable = FetchTable(nTab))
1777 return pTable->AssertNoInterpretNeeded(rPos.Col(), rPos.Row(), rPos.Row()+nLength-1);
1778}
1779#endif
1780
1782{
1783 assert(nAdjustHeightLock > 0);
1784 if(nAdjustHeightLock > 0)
1786}
1787
1789{
1790 SCTAB nTab = rPos.Tab();
1791 if (ScTable* pTable = FetchTable(nTab))
1792 return pTable->HandleRefArrayForParallelism(rPos.Col(), rPos.Row(), rPos.Row()+nLength-1, mxGroup);
1793 return false;
1794}
1795
1796bool ScDocument::CanFitBlock( const ScRange& rOld, const ScRange& rNew )
1797{
1798 if ( rOld == rNew )
1799 return true;
1800
1801 bool bOk = true;
1802 bool bInsCol,bDelCol,bInsRow,bDelRow;
1803 ScRange aColRange,aRowRange;
1804 lcl_GetInsDelRanges( rOld, rNew, aColRange,bInsCol,bDelCol, aRowRange,bInsRow,bDelRow );
1805
1806 if ( bInsCol && !CanInsertCol( aColRange ) ) // Cells at the edge ?
1807 bOk = false;
1808 if ( bInsRow && !CanInsertRow( aRowRange ) ) // Cells at the edge ?
1809 bOk = false;
1810
1811 if ( bInsCol || bDelCol )
1812 {
1813 aColRange.aEnd.SetCol(MaxCol());
1814 if ( HasPartOfMerged(aColRange) )
1815 bOk = false;
1816 }
1817 if ( bInsRow || bDelRow )
1818 {
1819 aRowRange.aEnd.SetRow(MaxRow());
1820 if ( HasPartOfMerged(aRowRange) )
1821 bOk = false;
1822 }
1823
1824 return bOk;
1825}
1826
1827void ScDocument::FitBlock( const ScRange& rOld, const ScRange& rNew, bool bClear )
1828{
1829 if (bClear)
1831
1832 bool bInsCol,bDelCol,bInsRow,bDelRow;
1833 ScRange aColRange,aRowRange;
1834 lcl_GetInsDelRanges( rOld, rNew, aColRange,bInsCol,bDelCol, aRowRange,bInsRow,bDelRow );
1835
1836 if ( bInsCol )
1837 InsertCol( aColRange ); // First insert columns
1838 if ( bInsRow )
1839 InsertRow( aRowRange );
1840
1841 if ( bDelRow )
1842 DeleteRow( aRowRange ); // First delete rows
1843 if ( bDelCol )
1844 DeleteCol( aColRange );
1845
1846 // Expand references to inserted rows
1847
1848 if ( bInsCol || bInsRow )
1849 {
1850 ScRange aGrowSource = rOld;
1851 aGrowSource.aEnd.SetCol(std::min( rOld.aEnd.Col(), rNew.aEnd.Col() ));
1852 aGrowSource.aEnd.SetRow(std::min( rOld.aEnd.Row(), rNew.aEnd.Row() ));
1853 SCCOL nGrowX = bInsCol ? ( rNew.aEnd.Col() - rOld.aEnd.Col() ) : 0;
1854 SCROW nGrowY = bInsRow ? ( rNew.aEnd.Row() - rOld.aEnd.Row() ) : 0;
1855 UpdateGrow( aGrowSource, nGrowX, nGrowY );
1856 }
1857}
1858
1860 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
1861 InsertDeleteFlags nDelFlag, bool bBroadcast, sc::ColumnSpanSet* pBroadcastSpans )
1862{
1863 sc::AutoCalcSwitch aACSwitch(*this, false);
1864
1865 PutInOrder( nCol1, nCol2 );
1866 PutInOrder( nRow1, nRow2 );
1867
1868 std::vector<ScAddress> aGroupPos;
1869 // Destroy and reconstruct listeners only if content is affected.
1870 bool bDelContent = ((nDelFlag & ~InsertDeleteFlags::CONTENTS) != nDelFlag);
1871 if (bDelContent)
1872 {
1873 // Record the positions of top and/or bottom formula groups that intersect
1874 // the area borders.
1875 sc::EndListeningContext aCxt(*this);
1876 ScRange aRange(nCol1, nRow1, 0, nCol2, nRow2, 0);
1877 for (SCTAB i = 0; i < GetTableCount(); i++)
1878 {
1879 if (rMark.GetTableSelect(i))
1880 {
1881 aRange.aStart.SetTab(i);
1882 aRange.aEnd.SetTab(i);
1883
1884 EndListeningIntersectedGroups(aCxt, aRange, &aGroupPos);
1885 }
1886 }
1888 }
1889
1890 for (SCTAB i = 0; i < GetTableCount(); i++)
1891 if (maTabs[i])
1892 if ( rMark.GetTableSelect(i) || bIsUndo )
1893 maTabs[i]->DeleteArea(nCol1, nRow1, nCol2, nRow2, nDelFlag, bBroadcast, pBroadcastSpans);
1894
1895 if (!bDelContent)
1896 return;
1897
1898 // Re-start listeners on those top bottom groups that have been split.
1899 SetNeedsListeningGroups(aGroupPos);
1901
1902 // If formula groups were split their listeners were destroyed and may
1903 // need to be notified now that they're restored, ScTable::DeleteArea()
1904 // couldn't do that.
1905 if (aGroupPos.empty())
1906 return;
1907
1908 ScRange aRange(nCol1, nRow1, 0, nCol2, nRow2, 0);
1909 for (SCTAB i = 0; i < GetTableCount(); i++)
1910 {
1911 if (rMark.GetTableSelect(i))
1912 {
1913 aRange.aStart.SetTab(i);
1914 aRange.aEnd.SetTab(i);
1915 SetDirty( aRange, true);
1916 }
1917 }
1918}
1919
1921 SCCOL nCol2, SCROW nRow2,
1922 SCTAB nTab, InsertDeleteFlags nDelFlag)
1923{
1924 PutInOrder( nCol1, nCol2 );
1925 PutInOrder( nRow1, nRow2 );
1926 if (ScTable* pTable = FetchTable(nTab))
1927 {
1928 bool bOldAutoCalc = GetAutoCalc();
1929 SetAutoCalc( false ); // avoid multiple calculations
1930 pTable->DeleteArea(nCol1, nRow1, nCol2, nRow2, nDelFlag);
1931 SetAutoCalc( bOldAutoCalc );
1932 }
1933}
1934
1936{
1937 for ( SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); nTab++ )
1938 DeleteAreaTab( rRange.aStart.Col(), rRange.aStart.Row(),
1939 rRange.aEnd.Col(), rRange.aEnd.Row(),
1940 nTab, nDelFlag );
1941}
1942
1943void ScDocument::InitUndoSelected(const ScDocument& rSrcDoc, const ScMarkData& rTabSelection,
1944 bool bColInfo, bool bRowInfo )
1945{
1946 if (bIsUndo)
1947 {
1948 Clear();
1949
1950 SharePooledResources(&rSrcDoc);
1951
1952 for (SCTAB nTab = 0; nTab <= rTabSelection.GetLastSelected(); nTab++)
1953 if ( rTabSelection.GetTableSelect( nTab ) )
1954 {
1955 ScTableUniquePtr pTable(new ScTable(*this, nTab, OUString(), bColInfo, bRowInfo));
1956 if (nTab < GetTableCount())
1957 maTabs[nTab] = std::move(pTable);
1958 else
1959 maTabs.push_back(std::move(pTable));
1960 }
1961 else
1962 {
1963 if (nTab < GetTableCount())
1964 maTabs[nTab]=nullptr;
1965 else
1966 maTabs.push_back(nullptr);
1967 }
1968 }
1969 else
1970 {
1971 OSL_FAIL("InitUndo");
1972 }
1973}
1974
1975void ScDocument::InitUndo( const ScDocument& rSrcDoc, SCTAB nTab1, SCTAB nTab2,
1976 bool bColInfo, bool bRowInfo )
1977{
1978 if (!bIsUndo)
1979 {
1980 OSL_FAIL("InitUndo");
1981 return;
1982 }
1983
1984 Clear();
1985
1986 // Undo document shares its pooled resources with the source document.
1987 SharePooledResources(&rSrcDoc);
1988
1989 if (rSrcDoc.mpShell->GetMedium())
1991
1992 if (nTab2 >= GetTableCount())
1993 maTabs.resize(nTab2 + 1);
1994 for (SCTAB nTab = nTab1; nTab <= nTab2; nTab++)
1995 {
1996 maTabs[nTab].reset(new ScTable(*this, nTab, OUString(), bColInfo, bRowInfo));
1997 }
1998}
1999
2000void ScDocument::AddUndoTab( SCTAB nTab1, SCTAB nTab2, bool bColInfo, bool bRowInfo )
2001{
2002 if (!bIsUndo)
2003 {
2004 OSL_FAIL("AddUndoTab");
2005 return;
2006 }
2007
2008 if (nTab2 >= GetTableCount())
2009 {
2010 maTabs.resize(nTab2+1);
2011 }
2012
2013 for (SCTAB nTab = nTab1; nTab <= nTab2; nTab++)
2014 if (!maTabs[nTab])
2015 {
2016 maTabs[nTab].reset( new ScTable(*this, nTab, OUString(), bColInfo, bRowInfo) );
2017 }
2018}
2019
2020void ScDocument::SetCutMode( bool bVal )
2021{
2022 if (bIsClip)
2023 GetClipParam().mbCutMode = bVal;
2024 else
2025 {
2026 OSL_FAIL("SetCutMode without bIsClip");
2027 }
2028}
2029
2031{
2032 if (bIsClip)
2033 return GetClipParam().mbCutMode;
2034 else
2035 {
2036 OSL_FAIL("IsCutMode without bIsClip");
2037 return false;
2038 }
2039}
2040
2042 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
2043 InsertDeleteFlags nFlags, bool bOnlyMarked, ScDocument& rDestDoc,
2044 const ScMarkData* pMarks, bool bColRowFlags )
2045{
2046 if (ValidTab(nTab1) && ValidTab(nTab2))
2047 {
2048 ScRange aThisRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2049 CopyToDocument(aThisRange, nFlags, bOnlyMarked, rDestDoc, pMarks, bColRowFlags);
2050 }
2051}
2052
2054 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
2055 InsertDeleteFlags nFlags, bool bOnlyMarked, ScDocument& rDestDoc)
2056{
2057 PutInOrder( nCol1, nCol2 );
2058 PutInOrder( nRow1, nRow2 );
2059 PutInOrder( nTab1, nTab2 );
2060 if (!(ValidTab(nTab1) && ValidTab(nTab2)))
2061 return;
2062
2063 sc::AutoCalcSwitch aACSwitch(rDestDoc, false); // avoid multiple calculations
2064
2065 if (nTab1 > 0)
2066 CopyToDocument(0, 0, 0, MaxCol(), MaxRow(), nTab1-1, InsertDeleteFlags::FORMULA, false, rDestDoc);
2067
2068 sc::CopyToDocContext aCxt(rDestDoc);
2069 assert(nTab2 < GetTableCount() && nTab2 < rDestDoc.GetTableCount());
2070 for (SCTAB i = nTab1; i <= nTab2; i++)
2071 {
2072 if (maTabs[i] && rDestDoc.maTabs[i])
2073 maTabs[i]->UndoToTable(aCxt, nCol1, nRow1, nCol2, nRow2, nFlags,
2074 bOnlyMarked, rDestDoc.maTabs[i].get());
2075 }
2076
2077 if (nTab2 < MAXTAB)
2078 CopyToDocument(0, 0, nTab2+1, MaxCol(), MaxRow(), MAXTAB, InsertDeleteFlags::FORMULA, false, rDestDoc);
2079}
2080
2082 InsertDeleteFlags nFlags, bool bOnlyMarked, ScDocument& rDestDoc,
2083 const ScMarkData* pMarks, bool bColRowFlags)
2084{
2085 ScRange aNewRange = rRange;
2086 aNewRange.PutInOrder();
2087
2088 if (rDestDoc.aDocName.isEmpty())
2089 rDestDoc.aDocName = aDocName;
2090
2091 sc::AutoCalcSwitch aACSwitch(rDestDoc, false); // avoid multiple calculations
2092 ScBulkBroadcast aBulkBroadcast(rDestDoc.GetBASM(), SfxHintId::ScDataChanged);
2093 sc::DelayDeletingBroadcasters delayDeletingBroadcasters(*this);
2094
2095 sc::CopyToDocContext aCxt(rDestDoc);
2096 aCxt.setStartListening(false);
2097
2098 SCTAB nMinSizeBothTabs = std::min(GetTableCount(), rDestDoc.GetTableCount());
2099 for (SCTAB i = aNewRange.aStart.Tab(); i <= aNewRange.aEnd.Tab() && i < nMinSizeBothTabs; i++)
2100 {
2101 ScTable* pTab = FetchTable(i);
2102 ScTable* pDestTab = rDestDoc.FetchTable(i);
2103 if (!pTab || !pDestTab)
2104 continue;
2105
2106 pTab->CopyToTable(
2107 aCxt, aNewRange.aStart.Col(), aNewRange.aStart.Row(), aNewRange.aEnd.Col(), aNewRange.aEnd.Row(),
2108 nFlags, bOnlyMarked, pDestTab, pMarks, false, bColRowFlags,
2109 /*bGlobalNamesToLocal*/false, /*bCopyCaptions*/true);
2110 }
2111
2112 rDestDoc.StartAllListeners(aNewRange);
2113}
2114
2116 InsertDeleteFlags nFlags, bool bOnlyMarked, ScDocument& rDestDoc)
2117{
2118 sc::AutoCalcSwitch aAutoCalcSwitch(*this, false);
2119
2120 ScRange aNewRange = rRange;
2121 aNewRange.PutInOrder();
2122 SCTAB nTab1 = aNewRange.aStart.Tab();
2123 SCTAB nTab2 = aNewRange.aEnd.Tab();
2124
2125 sc::CopyToDocContext aCxt(rDestDoc);
2126 if (nTab1 > 0)
2127 CopyToDocument(0, 0, 0, MaxCol(), MaxRow(), nTab1-1, InsertDeleteFlags::FORMULA, false, rDestDoc);
2128
2129 SCTAB nMinSizeBothTabs = std::min(GetTableCount(), rDestDoc.GetTableCount());
2130 for (SCTAB i = nTab1; i <= nTab2 && i < nMinSizeBothTabs; i++)
2131 {
2132 if (maTabs[i] && rDestDoc.maTabs[i])
2133 maTabs[i]->UndoToTable(aCxt, aNewRange.aStart.Col(), aNewRange.aStart.Row(),
2134 aNewRange.aEnd.Col(), aNewRange.aEnd.Row(),
2135 nFlags, bOnlyMarked, rDestDoc.maTabs[i].get());
2136 }
2137
2138 if (nTab2 < GetTableCount())
2139 CopyToDocument(0, 0 , nTab2+1, MaxCol(), MaxRow(), GetTableCount(), InsertDeleteFlags::FORMULA, false, rDestDoc);
2140}
2141
2143 ScDocument* pClipDoc, const ScMarkData* pMarks,
2144 bool bKeepScenarioFlags, bool bIncludeObjects )
2145{
2146 OSL_ENSURE( pMarks, "CopyToClip: ScMarkData fails" );
2147
2148 if (bIsClip)
2149 return;
2150
2151 if (!pClipDoc)
2152 {
2153 SAL_WARN("sc", "CopyToClip: no ClipDoc");
2154 pClipDoc = ScModule::GetClipDoc();
2155 }
2156
2157 if (mpShell->GetMedium())
2158 {
2160 // for unsaved files use the title name and adjust during save of file
2161 if (pClipDoc->maFileURL.isEmpty())
2162 pClipDoc->maFileURL = mpShell->GetName();
2163 }
2164 else
2165 {
2166 pClipDoc->maFileURL = mpShell->GetName();
2167 }
2168
2169 //init maTabNames
2170 for (const auto& rxTab : maTabs)
2171 {
2172 if( rxTab )
2173 {
2174 OUString aTabName = rxTab->GetName();
2175 pClipDoc->maTabNames.push_back(aTabName);
2176 }
2177 else
2178 pClipDoc->maTabNames.emplace_back();
2179 }
2180
2181 pClipDoc->aDocName = aDocName;
2182 pClipDoc->SetClipParam(rClipParam);
2183 ScRange aClipRange = rClipParam.getWholeRange();
2184 SCTAB nEndTab = GetTableCount();
2185
2186 pClipDoc->ResetClip(this, pMarks);
2187
2188 sc::CopyToClipContext aCxt(*pClipDoc, bKeepScenarioFlags);
2189 CopyRangeNamesToClip(pClipDoc, aClipRange, pMarks);
2190
2191 for (SCTAB i = 0; i < nEndTab; ++i)
2192 {
2193 if (!maTabs[i] || i >= pClipDoc->GetTableCount() || !pClipDoc->maTabs[i])
2194 continue;
2195
2196 if ( pMarks && !pMarks->GetTableSelect(i) )
2197 continue;
2198
2199 maTabs[i]->CopyToClip(aCxt, rClipParam.maRanges, pClipDoc->maTabs[i].get());
2200
2201 if (mpDrawLayer && bIncludeObjects)
2202 {
2203 // also copy drawing objects
2204 tools::Rectangle aObjRect = GetMMRect(
2205 aClipRange.aStart.Col(), aClipRange.aStart.Row(), aClipRange.aEnd.Col(), aClipRange.aEnd.Row(), i);
2206 mpDrawLayer->CopyToClip(pClipDoc, i, aObjRect);
2207 }
2208 }
2209
2210 // Make sure to mark overlapped cells.
2211 pClipDoc->ExtendMerge(aClipRange, true);
2212}
2213
2214void ScDocument::CopyStaticToDocument(const ScRange& rSrcRange, SCTAB nDestTab, ScDocument& rDestDoc)
2215{
2216 ScTable* pSrcTab = rSrcRange.aStart.Tab() < GetTableCount() ? maTabs[rSrcRange.aStart.Tab()].get() : nullptr;
2217 ScTable* pDestTab = nDestTab < rDestDoc.GetTableCount() ? rDestDoc.maTabs[nDestTab].get() : nullptr;
2218
2219 if (!pSrcTab || !pDestTab)
2220 return;
2221
2224
2225 pSrcTab->CopyStaticToDocument(
2226 rSrcRange.aStart.Col(), rSrcRange.aStart.Row(), rSrcRange.aEnd.Col(), rSrcRange.aEnd.Row(),
2227 aMap, pDestTab);
2228}
2229
2230void ScDocument::CopyCellToDocument( const ScAddress& rSrcPos, const ScAddress& rDestPos, ScDocument& rDestDoc )
2231{
2232 if (!HasTable(rSrcPos.Tab()) || !rDestDoc.HasTable(rDestPos.Tab()))
2233 return;
2234
2235 ScTable& rSrcTab = *maTabs[rSrcPos.Tab()];
2236 ScTable& rDestTab = *rDestDoc.maTabs[rDestPos.Tab()];
2237
2238 rSrcTab.CopyCellToDocument(rSrcPos.Col(), rSrcPos.Row(), rDestPos.Col(), rDestPos.Row(), rDestTab);
2239}
2240
2242 SCCOL nCol2, SCROW nRow2,
2243 SCTAB nTab, ScDocument* pClipDoc)
2244{
2245 if (bIsClip)
2246 return;
2247
2248 if (!pClipDoc)
2249 {
2250 SAL_WARN("sc", "CopyTabToClip: no ClipDoc");
2251 pClipDoc = ScModule::GetClipDoc();
2252 }
2253
2254 if (mpShell->GetMedium())
2255 {
2257 // for unsaved files use the title name and adjust during save of file
2258 if (pClipDoc->maFileURL.isEmpty())
2259 pClipDoc->maFileURL = mpShell->GetName();
2260 }
2261 else
2262 {
2263 pClipDoc->maFileURL = mpShell->GetName();
2264 }
2265
2266 //init maTabNames
2267 for (const auto& rxTab : maTabs)
2268 {
2269 if( rxTab )
2270 {
2271 OUString aTabName = rxTab->GetName();
2272 pClipDoc->maTabNames.push_back(aTabName);
2273 }
2274 else
2275 pClipDoc->maTabNames.emplace_back();
2276 }
2277
2278 PutInOrder( nCol1, nCol2 );
2279 PutInOrder( nRow1, nRow2 );
2280
2281 ScClipParam& rClipParam = pClipDoc->GetClipParam();
2282 pClipDoc->aDocName = aDocName;
2283 rClipParam.maRanges.RemoveAll();
2284 rClipParam.maRanges.push_back(ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0));
2285 pClipDoc->ResetClip( this, nTab );
2286
2287 sc::CopyToClipContext aCxt(*pClipDoc, false);
2288 if (nTab < GetTableCount() && nTab < pClipDoc->GetTableCount())
2289 if (maTabs[nTab] && pClipDoc->maTabs[nTab])
2290 maTabs[nTab]->CopyToClip(aCxt, nCol1, nRow1, nCol2, nRow2, pClipDoc->maTabs[nTab].get());
2291
2292 pClipDoc->GetClipParam().mbCutMode = false;
2293}
2294
2295void ScDocument::TransposeClip(ScDocument* pTransClip, InsertDeleteFlags nFlags, bool bAsLink,
2296 bool bIncludeFiltered)
2297{
2298 OSL_ENSURE( bIsClip && pTransClip && pTransClip->bIsClip,
2299 "TransposeClip with wrong Document" );
2300
2301 // initialize
2302 // -> pTransClip has to be deleted before the original document!
2303
2304 pTransClip->ResetClip(this, nullptr); // all
2305
2306 // Take over range
2307
2308 if (pRangeName)
2309 {
2310 pTransClip->GetRangeName()->clear();
2311 for (const auto& rEntry : *pRangeName)
2312 {
2313 sal_uInt16 nIndex = rEntry.second->GetIndex();
2314 ScRangeData* pData = new ScRangeData(*rEntry.second);
2315 if (pTransClip->pRangeName->insert(pData))
2316 pData->SetIndex(nIndex);
2317 }
2318 }
2319
2320 ScRange aCombinedClipRange = GetClipParam().getWholeRange();
2321
2322 if (!ValidRow(aCombinedClipRange.aEnd.Row() - aCombinedClipRange.aStart.Row()))
2323 {
2324 SAL_WARN("sc", "TransposeClip: Too big");
2325 return;
2326 }
2327
2328 // Transpose of filtered multi range row selection is a special case since filtering
2329 // and selection are in the same dimension (i.e. row).
2330 // The filtered row status and the selection ranges are not available at the same time,
2331 // handle this case specially, do not use GetClipParam().getWholeRange(),
2332 // instead loop through the ranges, calculate the row offset and handle filtered rows and
2333 // create in ScClipParam::transpose() a unified range.
2334 const bool bIsMultiRangeRowFilteredTranspose
2335 = !bIncludeFiltered && GetClipParam().isMultiRange()
2336 && HasFilteredRows(aCombinedClipRange.aStart.Row(), aCombinedClipRange.aEnd.Row(),
2337 aCombinedClipRange.aStart.Tab())
2339
2340 ScRangeList aClipRanges;
2341 if (bIsMultiRangeRowFilteredTranspose)
2342 aClipRanges = GetClipParam().maRanges;
2343 else
2344 aClipRanges = ScRangeList(aCombinedClipRange);
2345
2346 // The data
2347 ScRange aClipRange;
2348 SCROW nRowCount = 0; // next consecutive row
2349 for (size_t j = 0, n = aClipRanges.size(); j < n; ++j)
2350 {
2351 aClipRange = aClipRanges[j];
2352
2353 SCROW nRowOffset = 0;
2354 if (bIsMultiRangeRowFilteredTranspose)
2355 {
2356 // adjust for the rows that are filtered
2357 nRowOffset = nRowCount;
2358
2359 // calculate filtered rows of current clip range
2360 SCROW nRowCountNonFiltered = CountNonFilteredRows(
2361 aClipRange.aStart.Row(), aClipRange.aEnd.Row(), aClipRange.aStart.Tab());
2362 assert(!bIncludeFiltered && "bIsMultiRangeRowFilteredTranspose can only be true if bIncludeFiltered is false");
2363 nRowCount += nRowCountNonFiltered; // for next iteration
2364 }
2365
2366 for (SCTAB i = 0; i < GetTableCount(); i++)
2367 {
2368 if (maTabs[i])
2369 {
2370 OSL_ENSURE(pTransClip->maTabs[i], "TransposeClip: Table not there");
2371 maTabs[i]->TransposeClip(
2372 aClipRange.aStart.Col(), aClipRange.aStart.Row(), aClipRange.aEnd.Col(),
2373 aClipRange.aEnd.Row(), aCombinedClipRange.aStart.Row(), nRowOffset,
2374 pTransClip->maTabs[i].get(), nFlags, bAsLink, bIncludeFiltered);
2375
2376 if ( mpDrawLayer && ( nFlags & InsertDeleteFlags::OBJECTS ) )
2377 {
2378 // Drawing objects are copied to the new area without transposing.
2379 // CopyFromClip is used to adjust the objects to the transposed block's
2380 // cell range area.
2381 // (mpDrawLayer in the original clipboard document is set only if there
2382 // are drawing objects to copy)
2383
2384 // ToDo: Loop over blocks of non-filtered rows in case of filtered rows exist.
2385 pTransClip->InitDrawLayer();
2386 ScAddress aTransposedEnd(
2387 static_cast<SCCOL>(aClipRange.aEnd.Row() - aClipRange.aStart.Row() + aClipRange.aStart.Col()),
2388 static_cast<SCROW>(aClipRange.aEnd.Col() - aClipRange.aStart.Col() + aClipRange.aStart.Row()), i);
2389 ScRange aDestRange(aClipRange.aStart, aTransposedEnd);
2390 ScAddress aDestStart = aClipRange.aStart;
2391 pTransClip->mpDrawLayer->CopyFromClip(mpDrawLayer.get(), i, aClipRange, aDestStart, aDestRange, true);
2392 }
2393 }
2394 }
2395 }
2396
2397 pTransClip->SetClipParam(GetClipParam());
2398 pTransClip->GetClipParam().transpose(*this, bIncludeFiltered,
2399 bIsMultiRangeRowFilteredTranspose);
2400
2401 // This happens only when inserting...
2402
2403 GetClipParam().mbCutMode = false;
2404}
2405
2406namespace {
2407
2408void copyUsedNamesToClip(ScRangeName* pClipRangeName, ScRangeName* pRangeName,
2410{
2411 pClipRangeName->clear();
2412 for (const auto& rEntry : *pRangeName) //TODO: also DB and Pivot regions!!!
2413 {
2414 sal_uInt16 nIndex = rEntry.second->GetIndex();
2415 bool bInUse = (rUsedNames.count(nIndex) > 0);
2416 if (!bInUse)
2417 continue;
2418
2419 ScRangeData* pData = new ScRangeData(*rEntry.second);
2420 if (pClipRangeName->insert(pData))
2421 pData->SetIndex(nIndex);
2422 }
2423}
2424
2425}
2426
2427void ScDocument::CopyRangeNamesToClip(ScDocument* pClipDoc, const ScRange& rClipRange, const ScMarkData* pMarks)
2428{
2429 if (!pRangeName || pRangeName->empty())
2430 return;
2431
2432 sc::UpdatedRangeNames aUsedNames; // indexes of named ranges that are used in the copied cells
2433 SCTAB nMinSizeBothTabs = std::min(GetTableCount(), pClipDoc->GetTableCount());
2434 for (SCTAB i = 0; i < nMinSizeBothTabs; ++i)
2435 if (maTabs[i] && pClipDoc->maTabs[i])
2436 if ( !pMarks || pMarks->GetTableSelect(i) )
2437 maTabs[i]->FindRangeNamesInUse(
2438 rClipRange.aStart.Col(), rClipRange.aStart.Row(),
2439 rClipRange.aEnd.Col(), rClipRange.aEnd.Row(), aUsedNames);
2440
2441 /* TODO: handle also sheet-local names */
2442 sc::UpdatedRangeNames::NameIndicesType aUsedGlobalNames( aUsedNames.getUpdatedNames(-1));
2443 copyUsedNamesToClip(pClipDoc->GetRangeName(), pRangeName.get(), aUsedGlobalNames);
2444}
2445
2447 : mrDoc(rDoc)
2448{
2449 mrDoc.MergeNumberFormatter(rSrcDoc);
2450}
2451
2453{
2455 mrDoc.pFormatExchangeList = nullptr;
2456}
2457
2459{
2461 mpFormulaGroupCxt.reset();
2462}
2463
2465{
2466 ScTable* pTab = FetchTable(rPos.Tab());
2467 if (!pTab)
2468 return nullptr;
2469
2470 return pTab->GetBroadcaster(rPos.Col(), rPos.Row());
2471}
2472
2474{
2475 const ScTable* pTab = FetchTable(rPos.Tab());
2476 if (!pTab)
2477 return nullptr;
2478
2479 return pTab->GetBroadcaster(rPos.Col(), rPos.Row());
2480}
2481
2483{
2484 ScTable* pTab = FetchTable(rTopPos.Tab());
2485 if (!pTab || nLength <= 0)
2486 return;
2487
2488 pTab->DeleteBroadcasters(rBlockPos, rTopPos.Col(), rTopPos.Row(), rTopPos.Row()+nLength-1);
2489}
2490
2491#if DUMP_COLUMN_STORAGE
2492void ScDocument::DumpColumnStorage( SCTAB nTab, SCCOL nCol ) const
2493{
2494 const ScTable* pTab = FetchTable(nTab);
2495 if (!pTab)
2496 return;
2497
2498 pTab->DumpColumnStorage(nCol);
2499}
2500#endif
2501
2503{
2504 return ValidTab(nTab)
2505 && nTab < GetTableCount()
2506 && maTabs[nTab];
2507}
2508
2510{
2511 if (!HasTable(nTab))
2512 return nullptr;
2513
2514 return maTabs[nTab].get();
2515}
2516
2518{
2519 if (!HasTable(nTab))
2520 return nullptr;
2521
2522 return maTabs[nTab].get();
2523}
2524
2526{
2527 if (ScTable* pTable = FetchTable(nTab))
2528 return pTable->GetWritableColumnsRange(nColBegin, nColEnd);
2529
2530 SAL_WARN("sc", "GetWritableColumnsRange() called for non-existent table");
2531 return ScColumnsRange(-1, -1);
2532}
2533
2535{
2536 if (const ScTable* pTable = FetchTable(nTab))
2537 return pTable->GetAllocatedColumnsRange(nColBegin, nColEnd);
2538 return ScColumnsRange(-1, -1);
2539}
2540
2542{
2543 if (const ScTable* pTable = FetchTable(nTab))
2544 return pTable->GetColumnsRange(nColBegin, nColEnd);
2545 return ScColumnsRange(-1, -1);
2546}
2547
2549{
2550 SvNumberFormatter* pThisFormatter = mxPoolHelper->GetFormTable();
2551 SvNumberFormatter* pOtherFormatter = rSrcDoc.mxPoolHelper->GetFormTable();
2552 if (pOtherFormatter && pOtherFormatter != pThisFormatter)
2553 {
2554 SvNumberFormatterIndexTable* pExchangeList =
2555 pThisFormatter->MergeFormatter(*pOtherFormatter);
2556 if (!pExchangeList->empty())
2557 {
2559 pFormatExchangeList = pExchangeList;
2560 }
2561 }
2562}
2563
2565{
2566 if (!mpClipParam)
2567 mpClipParam.reset(new ScClipParam);
2568
2569 return *mpClipParam;
2570}
2571
2573{
2574 mpClipParam.reset(new ScClipParam(rParam));
2575}
2576
2578{
2579 if (bIsClip || mpShell == nullptr || mpShell->IsLoading())
2580 return false;
2581
2582 ScDocument* pClipDoc = ScModule::GetClipDoc();
2583 return pClipDoc && pClipDoc->bIsClip && pClipDoc->mxPoolHelper.is() && mxPoolHelper.is() &&
2584 mxPoolHelper->GetDocPool() == pClipDoc->mxPoolHelper->GetDocPool();
2585}
2586
2589 SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2590{
2591 if (ScTable* pTable = FetchTable(nTab))
2592 pTable->StartListeningFormulaCells(rStartCxt, rEndCxt, nCol1, nRow1, nCol2, nRow2);
2593}
2594
2596 SCCOL nCol2, SCROW nRow2,
2597 const ScMarkData& rMark, InsertDeleteFlags nInsFlag )
2598{
2599 if (!(nInsFlag & InsertDeleteFlags::CONTENTS))
2600 return;
2601
2602 auto pSet = std::make_shared<sc::ColumnBlockPositionSet>(*this);
2603
2604 sc::StartListeningContext aStartCxt(*this, pSet);
2605 sc::EndListeningContext aEndCxt(*this, pSet, nullptr);
2606
2607 for (SCTAB nTab : rMark)
2608 StartListeningFromClip(aStartCxt, aEndCxt, nTab, nCol1, nRow1, nCol2, nRow2);
2609}
2610
2612 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
2613 InsertDeleteFlags nInsFlag, sc::ColumnSpanSet& rBroadcastSpans )
2614{
2615 if (nInsFlag & InsertDeleteFlags::CONTENTS)
2616 {
2617 SCTAB nMax = GetTableCount();
2618 for (const auto& rTab : rMark)
2619 {
2620 if (rTab >= nMax)
2621 break;
2622 if (maTabs[rTab])
2623 maTabs[rTab]->SetDirtyFromClip(nCol1, nRow1, nCol2, nRow2, rBroadcastSpans);
2624 }
2625 }
2626}
2627
2629{
2630 if (ScTable* pTable = FetchTable(nTab))
2631 return pTable->InitColumnBlockPosition(rBlockPos, nCol);
2632 return false;
2633}
2634
2636 sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
2637 const ScMarkData& rMark, SCCOL nDx, SCROW nDy )
2638{
2639 TableContainer& rClipTabs = rCxt.getClipDoc()->maTabs;
2640 SCTAB nTabEnd = rCxt.getTabEnd();
2641 SCTAB nClipTab = 0;
2642 for (SCTAB i = rCxt.getTabStart(); i <= nTabEnd && i < GetTableCount(); i++)
2643 {
2644 if (maTabs[i] && rMark.GetTableSelect(i) )
2645 {
2646 while (!rClipTabs[nClipTab]) nClipTab = (nClipTab+1) % static_cast<SCTAB>(rClipTabs.size());
2647
2648 maTabs[i]->CopyFromClip(
2649 rCxt, nCol1, nRow1, nCol2, nRow2, nDx, nDy, rClipTabs[nClipTab].get());
2650
2652 {
2653 // also copy drawing objects
2654
2655 // drawing layer must be created before calling CopyFromClip
2656 // (ScDocShell::MakeDrawLayer also does InitItems etc.)
2657 OSL_ENSURE( mpDrawLayer, "CopyBlockFromClip: No drawing layer" );
2658 if ( mpDrawLayer )
2659 {
2660 // For GetMMRect, the row heights in the target document must already be valid
2661 // (copied in an extra step before pasting, or updated after pasting cells, but
2662 // before pasting objects).
2663 ScRange aSourceRange(nCol1 - nDx, nRow1 - nDy, nClipTab, nCol2 - nDx, nRow2 - nDy, nClipTab);
2664 ScRange aDestRange(nCol1, nRow1, i, nCol2, nRow2, i);
2665 mpDrawLayer->CopyFromClip(rCxt.getClipDoc()->mpDrawLayer.get(), nClipTab, aSourceRange,
2666 ScAddress( nCol1, nRow1, i ), aDestRange);
2667 }
2668 }
2669
2670 nClipTab = (nClipTab+1) % static_cast<SCTAB>(rClipTabs.size());
2671 }
2672 }
2674 return;
2675
2676 nClipTab = 0;
2677 for (SCTAB i = rCxt.getTabStart(); i <= nTabEnd && i < GetTableCount(); i++)
2678 {
2679 if (maTabs[i] && rMark.GetTableSelect(i) )
2680 {
2681 while (!rClipTabs[nClipTab]) nClipTab = (nClipTab+1) % static_cast<SCTAB>(rClipTabs.size());
2682 SCTAB nDz = i - nClipTab;
2683
2684 // ranges of consecutive selected tables (in clipboard and dest. doc)
2685 // must be handled in one UpdateReference call
2686 SCTAB nFollow = 0;
2687 while ( i + nFollow < nTabEnd
2688 && rMark.GetTableSelect( i + nFollow + 1 )
2689 && nClipTab + nFollow < MAXTAB
2690 && rClipTabs[(nClipTab + nFollow + 1) % static_cast<SCTAB>(rClipTabs.size())] )
2691 ++nFollow;
2692
2693 sc::RefUpdateContext aRefCxt(*this, rCxt.getClipDoc());
2694 aRefCxt.maRange = ScRange(nCol1, nRow1, i, nCol2, nRow2, i+nFollow);
2695 aRefCxt.mnColDelta = nDx;
2696 aRefCxt.mnRowDelta = nDy;
2697 aRefCxt.mnTabDelta = nDz;
2698 aRefCxt.setBlockPositionReference(rCxt.getBlockPositionSet()); // share mdds position caching
2699 if (rCxt.getClipDoc()->GetClipParam().mbCutMode)
2700 {
2701 // Update references only if cut originates from the same
2702 // document we are pasting into.
2703 if (rCxt.getClipDoc()->GetPool() == GetPool())
2704 {
2705 bool bOldInserting = IsInsertingFromOtherDoc();
2707 aRefCxt.meMode = URM_MOVE;
2708 UpdateReference(aRefCxt, rCxt.getUndoDoc(), false);
2709
2710 // For URM_MOVE group listeners may have been removed,
2711 // re-establish them.
2712 if (!aRefCxt.maRegroupCols.empty())
2713 {
2714 /* TODO: holding the ColumnSet in a shared_ptr at
2715 * RefUpdateContext would eliminate the need of
2716 * copying it here. */
2717 auto pColSet = std::make_shared<sc::ColumnSet>( aRefCxt.maRegroupCols);
2718 StartNeededListeners( pColSet);
2719 }
2720
2721 SetInsertingFromOtherDoc( bOldInserting);
2722 }
2723 }
2724 else
2725 {
2726 aRefCxt.meMode = URM_COPY;
2727 UpdateReference(aRefCxt, rCxt.getUndoDoc(), false);
2728 }
2729
2730 nClipTab = (nClipTab+nFollow+1) % static_cast<SCTAB>(rClipTabs.size());
2731 i = sal::static_int_cast<SCTAB>( i + nFollow );
2732 }
2733 }
2734}
2735
2737 SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
2738 SCCOL nDx, SCROW& rClipStartRow, SCROW nClipEndRow)
2739{
2740 // call CopyBlockFromClip for ranges of consecutive non-filtered rows
2741 // nCol1/nRow1 etc. is in target doc
2742
2743 // filtered state is taken from first used table in clipboard (as in GetClipArea)
2744 SCTAB nFlagTab = 0;
2745 TableContainer& rClipTabs = rCxt.getClipDoc()->maTabs;
2746 while ( nFlagTab < static_cast<SCTAB>(rClipTabs.size()) && !rClipTabs[nFlagTab] )
2747 ++nFlagTab;
2748
2749 SCROW nSourceRow = rClipStartRow;
2750 SCROW nSourceEnd = nClipEndRow;
2751 SCROW nDestRow = nRow1;
2752 SCROW nFilteredRows = 0;
2753
2754 while ( nSourceRow <= nSourceEnd && nDestRow <= nRow2 )
2755 {
2756 // skip filtered rows
2757 SCROW nSourceRowOriginal = nSourceRow;
2758 nSourceRow = rCxt.getClipDoc()->FirstNonFilteredRow(nSourceRow, nSourceEnd, nFlagTab);
2759 nFilteredRows += nSourceRow - nSourceRowOriginal;
2760
2761 if ( nSourceRow <= nSourceEnd )
2762 {
2763 // look for more non-filtered rows following
2764 SCROW nLastRow = nSourceRow;
2765 (void)rCxt.getClipDoc()->RowFiltered(nSourceRow, nFlagTab, nullptr, &nLastRow);
2766 SCROW nFollow = nLastRow - nSourceRow;
2767
2768 if (nFollow > nSourceEnd - nSourceRow)
2769 nFollow = nSourceEnd - nSourceRow;
2770 if (nFollow > nRow2 - nDestRow)
2771 nFollow = nRow2 - nDestRow;
2772
2773 SCROW nNewDy = nDestRow - nSourceRow;
2775 rCxt, nCol1, nDestRow, nCol2, nDestRow + nFollow, rMark, nDx, nNewDy);
2776
2777 nSourceRow += nFollow + 1;
2778 nDestRow += nFollow + 1;
2779 }
2780 }
2781 rClipStartRow = nSourceRow;
2782 return nFilteredRows;
2783}
2784
2785namespace {
2786
2787class BroadcastAction : public sc::ColumnSpanSet::ColumnAction
2788{
2789 ScDocument& mrDoc;
2790 ScColumn* mpCol;
2791
2792public:
2793 explicit BroadcastAction( ScDocument& rDoc ) : mrDoc(rDoc), mpCol(nullptr) {}
2794
2795 virtual void startColumn( ScColumn* pCol ) override
2796 {
2797 mpCol = pCol;
2798 }
2799
2800 virtual void execute( SCROW nRow1, SCROW nRow2, bool bVal ) override
2801 {
2802 if (!bVal)
2803 return;
2804
2805 assert(mpCol);
2806 ScRange aRange(mpCol->GetCol(), nRow1, mpCol->GetTab());
2807 aRange.aEnd.SetRow(nRow2);
2808 mrDoc.BroadcastCells(aRange, SfxHintId::ScDataChanged);
2809 };
2810};
2811
2812}
2813
2815 const ScRange& rDestRange, const ScMarkData& rMark, InsertDeleteFlags nInsFlag,
2816 ScDocument* pRefUndoDoc, ScDocument* pClipDoc, bool bResetCut,
2817 bool bAsLink, bool bIncludeFiltered, bool bSkipEmptyCells,
2818 const ScRangeList * pDestRanges )
2819{
2820 if (bIsClip)
2821 return;
2822
2823 if (!pClipDoc)
2824 {
2825 OSL_FAIL("CopyFromClip: no ClipDoc");
2826 pClipDoc = ScModule::GetClipDoc();
2827 }
2828
2829 if (!pClipDoc->bIsClip || !pClipDoc->GetTableCount())
2830 return;
2831
2832 sc::AutoCalcSwitch aACSwitch(*this, false); // temporarily turn off auto calc.
2833
2834 NumFmtMergeHandler aNumFmtMergeHdl(*this, *pClipDoc);
2835
2836 SCCOL nAllCol1 = rDestRange.aStart.Col();
2837 SCROW nAllRow1 = rDestRange.aStart.Row();
2838 SCCOL nAllCol2 = rDestRange.aEnd.Col();
2839 SCROW nAllRow2 = rDestRange.aEnd.Row();
2840
2841 SCCOL nXw = 0;
2842 SCROW nYw = 0;
2843 ScRange aClipRange = pClipDoc->GetClipParam().getWholeRange();
2844 for (SCTAB nTab = 0; nTab < pClipDoc->GetTableCount(); nTab++) // find largest merge overlap
2845 if (pClipDoc->maTabs[nTab]) // all sheets of the clipboard content
2846 {
2847 SCCOL nThisEndX = aClipRange.aEnd.Col();
2848 SCROW nThisEndY = aClipRange.aEnd.Row();
2849 pClipDoc->ExtendMerge( aClipRange.aStart.Col(),
2850 aClipRange.aStart.Row(),
2851 nThisEndX, nThisEndY, nTab );
2852 // only extra value from ExtendMerge
2853 nThisEndX = sal::static_int_cast<SCCOL>( nThisEndX - aClipRange.aEnd.Col() );
2854 nThisEndY = sal::static_int_cast<SCROW>( nThisEndY - aClipRange.aEnd.Row() );
2855 if ( nThisEndX > nXw )
2856 nXw = nThisEndX;
2857 if ( nThisEndY > nYw )
2858 nYw = nThisEndY;
2859 }
2860
2861 SCCOL nDestAddX;
2862 SCROW nDestAddY;
2863 pClipDoc->GetClipArea( nDestAddX, nDestAddY, bIncludeFiltered );
2864 nXw = sal::static_int_cast<SCCOL>( nXw + nDestAddX );
2865 nYw = sal::static_int_cast<SCROW>( nYw + nDestAddY ); // ClipArea, plus ExtendMerge value
2866
2867 /* Decide which contents to delete before copying. Delete all
2868 contents if nInsFlag contains any real content flag.
2869 #i102056# Notes are pasted from clipboard in a second pass,
2870 together with the special flag InsertDeleteFlags::ADDNOTES that states to not
2871 overwrite/delete existing cells but to insert the notes into
2872 these cells. In this case, just delete old notes from the
2873 destination area. */
2876 nDelFlag |= InsertDeleteFlags::NOTE;
2877 // tdf#141440 - do not delete notes when pasting contents (see InsertDeleteFlags::CONTENTS)
2878 else if ( nInsFlag & (InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE) )
2880
2881 if (nInsFlag & InsertDeleteFlags::ATTRIB)
2882 nDelFlag |= InsertDeleteFlags::ATTRIB;
2883
2884 sc::CopyFromClipContext aCxt(*this, pRefUndoDoc, pClipDoc, nInsFlag, bAsLink, bSkipEmptyCells);
2885 std::pair<SCTAB,SCTAB> aTabRanges = getMarkedTableRange(maTabs, rMark);
2886 aCxt.setTabRange(aTabRanges.first, aTabRanges.second);
2887 aCxt.setDeleteFlag(nDelFlag);
2888
2889 ScRangeList aLocalRangeList;
2890 if (!pDestRanges)
2891 {
2892 aLocalRangeList.push_back( rDestRange);
2893 pDestRanges = &aLocalRangeList;
2894 }
2895
2896 bInsertingFromOtherDoc = true; // No Broadcast/Listener created at Insert
2897
2898 sc::ColumnSpanSet aBroadcastSpans;
2899
2900 SCCOL nClipStartCol = aClipRange.aStart.Col();
2901 SCROW nClipStartRow = aClipRange.aStart.Row();
2902 SCROW nClipEndRow = aClipRange.aEnd.Row();
2903 for ( size_t nRange = 0; nRange < pDestRanges->size(); ++nRange )
2904 {
2905 const ScRange & rRange = (*pDestRanges)[nRange];
2906 SCCOL nCol1 = rRange.aStart.Col();
2907 SCROW nRow1 = rRange.aStart.Row();
2908 SCCOL nCol2 = rRange.aEnd.Col();
2909 SCROW nRow2 = rRange.aEnd.Row();
2910
2911 aCxt.setDestRange(nCol1, nRow1, nCol2, nRow2);
2912 DeleteBeforeCopyFromClip(aCxt, rMark, aBroadcastSpans); // <- this removes existing formula listeners
2913
2914 if (CopyOneCellFromClip(aCxt, nCol1, nRow1, nCol2, nRow2))
2915 continue;
2916
2917 SCCOL nC1 = nCol1;
2918 SCROW nR1 = nRow1;
2919 SCCOL nC2 = nC1 + nXw;
2920 if (nC2 > nCol2)
2921 nC2 = nCol2;
2922 SCROW nR2 = nR1 + nYw;
2923 if (nR2 > nRow2)
2924 nR2 = nRow2;
2925
2926 const SCCOLROW nThreshold = 8192;
2927 bool bPreallocatePattern = ((nInsFlag & InsertDeleteFlags::ATTRIB) && (nRow2 - nRow1 > nThreshold));
2928 std::vector< SCTAB > vTables;
2929
2930 if (bPreallocatePattern)
2931 {
2932 for (SCTAB i = aCxt.getTabStart(); i <= aCxt.getTabEnd(); ++i)
2933 if (maTabs[i] && rMark.GetTableSelect( i ) )
2934 vTables.push_back( i );
2935 }
2936
2937 do
2938 {
2939 // Pasting is done column-wise, when pasting to a filtered
2940 // area this results in partitioning and we have to
2941 // remember and reset the start row for each column until
2942 // it can be advanced for the next chunk of unfiltered
2943 // rows.
2944 SCROW nSaveClipStartRow = nClipStartRow;
2945 do
2946 {
2947 nClipStartRow = nSaveClipStartRow;
2948 SCCOL nDx = nC1 - nClipStartCol;
2949 SCROW nDy = nR1 - nClipStartRow;
2950 if ( bIncludeFiltered )
2951 {
2953 aCxt, nC1, nR1, nC2, nR2, rMark, nDx, nDy);
2954 nClipStartRow += nR2 - nR1 + 1;
2955 }
2956 else
2957 {
2958 CopyNonFilteredFromClip(aCxt, nC1, nR1, nC2, nR2, rMark, nDx, nClipStartRow,
2959 nClipEndRow);
2960 }
2961 nC1 = nC2 + 1;
2962 nC2 = std::min(static_cast<SCCOL>(nC1 + nXw), nCol2);
2963 } while (nC1 <= nCol2);
2964 if (nClipStartRow > nClipEndRow)
2965 nClipStartRow = aClipRange.aStart.Row();
2966 nC1 = nCol1;
2967 nC2 = nC1 + nXw;
2968 if (nC2 > nCol2)
2969 nC2 = nCol2;
2970
2971 // Preallocate pattern memory once if further chunks are to be pasted.
2972 if (bPreallocatePattern && (nR2+1) <= nRow2)
2973 {
2974 SCROW nR3 = nR2 + 1;
2975 for (SCTAB nTab : vTables)
2976 {
2977 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
2978 {
2979 // Pattern count of the first chunk pasted.
2980 SCSIZE nChunk = GetPatternCount( nTab, nCol, nR1, nR2);
2981 // If it is only one pattern per chunk and chunks are
2982 // pasted consecutively then it will get its range
2983 // enlarged for each chunk and no further allocation
2984 // happens. For non-consecutive chunks we're out of
2985 // luck in this case.
2986 if (nChunk > 1)
2987 {
2988 SCSIZE nNeeded = nChunk * (nRow2 - nR3 + 1) / (nYw + 1);
2989 SCSIZE nRemain = GetPatternCount( nTab, nCol, nR3, nRow2);
2990 if (nNeeded > nRemain)
2991 {
2992 SCSIZE nCurr = GetPatternCount( nTab, nCol);
2993 ReservePatternCount( nTab, nCol, nCurr + nNeeded);
2994 }
2995 }
2996 }
2997 }
2998 bPreallocatePattern = false;
2999 }
3000
3001 nR1 = nR2 + 1;
3002 nR2 = std::min(static_cast<SCROW>(nR1 + nYw), nRow2);
3003 } while (nR1 <= nRow2);
3004 }
3005
3006 bInsertingFromOtherDoc = false;
3007
3008 if (nInsFlag & InsertDeleteFlags::CONTENTS)
3009 {
3010 for (SCTAB nTab : rMark)
3011 aCxt.setListeningFormulaSpans(nTab, nAllCol1, nAllRow1, nAllCol2, nAllRow2);
3012 }
3013
3014 // Create Listener after everything has been inserted
3016
3017 {
3018 ScBulkBroadcast aBulkBroadcast( GetBASM(), SfxHintId::ScDataChanged);
3019
3020 // Set all formula cells dirty, and collect non-empty non-formula cell
3021 // positions so that we can broadcast on them below.
3022 SetDirtyFromClip(nAllCol1, nAllRow1, nAllCol2, nAllRow2, rMark, nInsFlag, aBroadcastSpans);
3023
3024 BroadcastAction aAction(*this);
3025 aBroadcastSpans.executeColumnAction(*this, aAction);
3026 }
3027
3028 if (bResetCut)
3029 pClipDoc->GetClipParam().mbCutMode = false;
3030}
3031
3033 InsertDeleteFlags nInsFlag, ScDocument* pClipDoc,
3034 bool bResetCut, bool bAsLink, bool bIncludeFiltered,
3035 bool bSkipAttrForEmpty)
3036{
3037 if (bIsClip)
3038 return;
3039
3040 if (!pClipDoc->bIsClip || !pClipDoc->GetTableCount())
3041 // There is nothing in the clip doc to copy.
3042 return;
3043
3044 // Right now, we don't allow pasting into filtered rows, so we don't even handle it here.
3045
3046 sc::AutoCalcSwitch aACSwitch(*this, false); // turn of auto calc temporarily.
3047 NumFmtMergeHandler aNumFmtMergeHdl(*this, *pClipDoc);
3048
3049 const ScRange& aDestRange = rMark.GetMarkArea();
3050
3051 bInsertingFromOtherDoc = true; // No Broadcast/Listener created at Insert
3052
3053 SCCOL nCol1 = rDestPos.Col();
3054 SCROW nRow1 = rDestPos.Row();
3055 ScClipParam& rClipParam = pClipDoc->GetClipParam();
3056
3057 sc::ColumnSpanSet aBroadcastSpans;
3058
3059 if (!bSkipAttrForEmpty)
3060 {
3061 // Do the deletion first.
3062 SCCOL nColSize = rClipParam.getPasteColSize();
3063 SCROW nRowSize = rClipParam.getPasteRowSize(*pClipDoc, bIncludeFiltered);
3064
3065 DeleteArea(nCol1, nRow1, nCol1+nColSize-1, nRow1+nRowSize-1, rMark, InsertDeleteFlags::CONTENTS, false, &aBroadcastSpans);
3066 }
3067
3068 sc::CopyFromClipContext aCxt(*this, nullptr, pClipDoc, nInsFlag, bAsLink, bSkipAttrForEmpty);
3069 std::pair<SCTAB,SCTAB> aTabRanges = getMarkedTableRange(maTabs, rMark);
3070 aCxt.setTabRange(aTabRanges.first, aTabRanges.second);
3071
3072 for (size_t i = 0, n = rClipParam.maRanges.size(); i < n; ++i)
3073 {
3074 const ScRange & rRange = rClipParam.maRanges[i];
3075
3076 SCROW nRowCount = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
3077 SCCOL nDx = static_cast<SCCOL>(nCol1 - rRange.aStart.Col());
3078 SCROW nDy = static_cast<SCROW>(nRow1 - rRange.aStart.Row());
3079 SCCOL nCol2 = nCol1 + rRange.aEnd.Col() - rRange.aStart.Col();
3080 SCROW nEndRow = nRow1 + nRowCount - 1;
3081 SCROW nFilteredRows = 0;
3082
3083 if (bIncludeFiltered)
3084 {
3085 CopyBlockFromClip(aCxt, nCol1, nRow1, nCol2, nEndRow, rMark, nDx, nDy);
3086 }
3087 else
3088 {
3089 SCROW nClipStartRow = rRange.aStart.Row();
3090 SCROW nClipEndRow = rRange.aEnd.Row();
3091 nFilteredRows += CopyNonFilteredFromClip(aCxt, nCol1, nRow1, nCol2, nEndRow, rMark, nDx,
3092 nClipStartRow, nClipEndRow);
3093 nRowCount -= nFilteredRows;
3094 }
3095
3096 switch (rClipParam.meDirection)
3097 {
3098 case ScClipParam::Row:
3099 // Begin row for the next range being pasted.
3100 nRow1 += nRowCount;
3101 break;
3103 nCol1 += rRange.aEnd.Col() - rRange.aStart.Col() + 1;
3104 break;
3105 default:
3106 ;
3107 }
3108 }
3109
3110 bInsertingFromOtherDoc = false;
3111
3112 // Create Listener after everything has been inserted
3113 StartListeningFromClip(aDestRange.aStart.Col(), aDestRange.aStart.Row(),
3114 aDestRange.aEnd.Col(), aDestRange.aEnd.Row(), rMark, nInsFlag );
3115
3116 {
3117 ScBulkBroadcast aBulkBroadcast( GetBASM(), SfxHintId::ScDataChanged);
3118
3119 // Set formula cells dirty and collect non-formula cells.
3121 aDestRange.aStart.Col(), aDestRange.aStart.Row(), aDestRange.aEnd.Col(), aDestRange.aEnd.Row(),
3122 rMark, nInsFlag, aBroadcastSpans);
3123
3124 BroadcastAction aAction(*this);
3125 aBroadcastSpans.executeColumnAction(*this, aAction);
3126 }
3127
3128 if (bResetCut)
3129 pClipDoc->GetClipParam().mbCutMode = false;
3130}
3131
3132void ScDocument::SetClipArea( const ScRange& rArea, bool bCut )
3133{
3134 if (bIsClip)
3135 {
3136 ScClipParam& rClipParam = GetClipParam();
3137 rClipParam.maRanges.RemoveAll();
3138 rClipParam.maRanges.push_back(rArea);
3139 rClipParam.mbCutMode = bCut;
3140 }
3141 else
3142 {
3143 OSL_FAIL("SetClipArea: No Clip");
3144 }
3145}
3146
3147void ScDocument::GetClipArea(SCCOL& nClipX, SCROW& nClipY, bool bIncludeFiltered)
3148{
3149 if (!bIsClip)
3150 {
3151 OSL_FAIL("GetClipArea: No Clip");
3152 return;
3153 }
3154
3155 ScRangeList& rClipRanges = GetClipParam().maRanges;
3156 if (rClipRanges.empty())
3157 // No clip range. Bail out.
3158 return;
3159
3160 ScRange const & rRange = rClipRanges.front();
3161 SCCOL nStartCol = rRange.aStart.Col();
3162 SCCOL nEndCol = rRange.aEnd.Col();
3163 SCROW nStartRow = rRange.aStart.Row();
3164 SCROW nEndRow = rRange.aEnd.Row();
3165 for ( size_t i = 1, n = rClipRanges.size(); i < n; ++i )
3166 {
3167 ScRange const & rRange2 = rClipRanges[ i ];
3168 if (rRange2.aStart.Col() < nStartCol)
3169 nStartCol = rRange2.aStart.Col();
3170 if (rRange2.aStart.Row() < nStartRow)
3171 nStartRow = rRange2.aStart.Row();
3172 if (rRange2.aEnd.Col() > nEndCol)
3173 nEndCol = rRange2.aEnd.Col();
3174 if (rRange2.aEnd.Row() > nEndRow)
3175 nEndRow = rRange2.aEnd.Row();
3176 }
3177
3178 nClipX = nEndCol - nStartCol;
3179
3180 if ( bIncludeFiltered )
3181 nClipY = nEndRow - nStartRow;
3182 else
3183 {
3184 // count non-filtered rows
3185 // count on first used table in clipboard
3186 SCTAB nCountTab = 0;
3187 while (nCountTab < GetTableCount() && !maTabs[nCountTab])
3188 ++nCountTab;
3189
3190 SCROW nResult = CountNonFilteredRows(nStartRow, nEndRow, nCountTab);
3191
3192 if ( nResult > 0 )
3193 nClipY = nResult - 1;
3194 else
3195 nClipY = 0; // always return at least 1 row
3196 }
3197}
3198
3200{
3201 if (bIsClip)
3202 {
3203 ScRangeList& rClipRanges = GetClipParam().maRanges;
3204 if ( !rClipRanges.empty() )
3205 {
3206 nClipX = rClipRanges.front().aStart.Col();
3207 nClipY = rClipRanges.front().aStart.Row();
3208 }
3209 }
3210 else
3211 {
3212 OSL_FAIL("GetClipStart: No Clip");
3213 }
3214}
3215
3217{
3218 // count on first used table in clipboard
3219 SCTAB nCountTab = 0;
3220 while (nCountTab < GetTableCount() && !maTabs[nCountTab])
3221 ++nCountTab;
3222
3223 ScRangeList& rClipRanges = GetClipParam().maRanges;
3224 if ( rClipRanges.empty() )
3225 return false;
3226
3227 for ( size_t i = 0, n = rClipRanges.size(); i < n; ++i )
3228 {
3229 ScRange & rRange = rClipRanges[ i ];
3230 bool bAnswer = maTabs[nCountTab]->HasFilteredRows(rRange.aStart.Row(), rRange.aEnd.Row());
3231 if (bAnswer)
3232 return true;
3233 }
3234 return false;
3235}
3236
3237void ScDocument::MixDocument( const ScRange& rRange, ScPasteFunc nFunction, bool bSkipEmpty,
3238 ScDocument& rSrcDoc )
3239{
3240 SCTAB nTab1 = rRange.aStart.Tab();
3241 SCTAB nTab2 = rRange.aEnd.Tab();
3242 sc::MixDocContext aCxt(*this);
3243 SCTAB nMinSizeBothTabs = std::min(GetTableCount(), rSrcDoc.GetTableCount());
3244 for (SCTAB i = nTab1; i <= nTab2 && i < nMinSizeBothTabs; i++)
3245 {
3246 ScTable* pTab = FetchTable(i);
3247 const ScTable* pSrcTab = rSrcDoc.FetchTable(i);
3248 if (!pTab || !pSrcTab)
3249 continue;
3250
3251 pTab->MixData(
3252 aCxt, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(),
3253 nFunction, bSkipEmpty, pSrcTab);
3254 }
3255}
3256
3257void ScDocument::FillTab( const ScRange& rSrcArea, const ScMarkData& rMark,
3258 InsertDeleteFlags nFlags, ScPasteFunc nFunction,
3259 bool bSkipEmpty, bool bAsLink )
3260{
3261 InsertDeleteFlags nDelFlags = nFlags;
3262 if (nDelFlags & InsertDeleteFlags::CONTENTS)
3263 nDelFlags |= InsertDeleteFlags::CONTENTS; // Either all contents or delete nothing!
3264
3265 SCTAB nSrcTab = rSrcArea.aStart.Tab();
3266
3267 if (ScTable* pSourceTable = FetchTable(nSrcTab))
3268 {
3269 SCCOL nStartCol = rSrcArea.aStart.Col();
3270 SCROW nStartRow = rSrcArea.aStart.Row();
3271 SCCOL nEndCol = rSrcArea.aEnd.Col();
3272 SCROW nEndRow = rSrcArea.aEnd.Row();
3273 ScDocumentUniquePtr pMixDoc;
3274 bool bDoMix = ( bSkipEmpty || nFunction != ScPasteFunc::NONE ) && ( nFlags & InsertDeleteFlags::CONTENTS );
3275
3276 bool bOldAutoCalc = GetAutoCalc();
3277 SetAutoCalc( false ); // avoid multiple calculations
3278
3279 sc::CopyToDocContext aCxt(*this);
3280 sc::MixDocContext aMixDocCxt(*this);
3281
3283 for (const SCTAB& i : rMark)
3284 {
3285 if (i >= nCount)
3286 break;
3287 if (i != nSrcTab && maTabs[i])
3288 {
3289 if (bDoMix)
3290 {
3291 if (!pMixDoc)
3292 {
3293 pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
3294 pMixDoc->InitUndo( *this, i, i );
3295 }
3296 else
3297 pMixDoc->AddUndoTab( i, i );
3298
3299 // context used for copying content to the temporary mix document.
3300 sc::CopyToDocContext aMixCxt(*pMixDoc);
3301 maTabs[i]->CopyToTable(aMixCxt, nStartCol,nStartRow, nEndCol,nEndRow,
3302 InsertDeleteFlags::CONTENTS, false, pMixDoc->maTabs[i].get(),
3303 /*pMarkData*/nullptr, /*bAsLink*/false, /*bColRowFlags*/true,
3304 /*bGlobalNamesToLocal*/false, /*bCopyCaptions*/true );
3305 }
3306 maTabs[i]->DeleteArea( nStartCol,nStartRow, nEndCol,nEndRow, nDelFlags);
3307 pSourceTable->CopyToTable(aCxt, nStartCol,nStartRow, nEndCol,nEndRow,
3308 nFlags, false, maTabs[i].get(), nullptr, bAsLink,
3309 /*bColRowFlags*/true, /*bGlobalNamesToLocal*/false, /*bCopyCaptions*/true );
3310
3311 if (bDoMix)
3312 maTabs[i]->MixData(aMixDocCxt, nStartCol,nStartRow, nEndCol,nEndRow,
3313 nFunction, bSkipEmpty, pMixDoc->maTabs[i].get() );
3314 }
3315 }
3316
3317 SetAutoCalc( bOldAutoCalc );
3318 }
3319 else
3320 {
3321 OSL_FAIL("wrong table");
3322 }
3323}
3324
3325void ScDocument::FillTabMarked( SCTAB nSrcTab, const ScMarkData& rMark,
3326 InsertDeleteFlags nFlags, ScPasteFunc nFunction,
3327 bool bSkipEmpty, bool bAsLink )
3328{
3329 InsertDeleteFlags nDelFlags = nFlags;
3330 if (nDelFlags & InsertDeleteFlags::CONTENTS)
3331 nDelFlags |= InsertDeleteFlags::CONTENTS; // Either all contents or delete nothing!
3332
3333 if (ScTable* pSourceTable = FetchTable(nSrcTab))
3334 {
3335 ScDocumentUniquePtr pMixDoc;
3336 bool bDoMix = ( bSkipEmpty || nFunction != ScPasteFunc::NONE ) && ( nFlags & InsertDeleteFlags::CONTENTS );
3337
3338 bool bOldAutoCalc = GetAutoCalc();
3339 SetAutoCalc( false ); // avoid multiple calculations
3340
3341 const ScRange& aArea = rMark.GetMultiMarkArea();
3342 SCCOL nStartCol = aArea.aStart.Col();
3343 SCROW nStartRow = aArea.aStart.Row();
3344 SCCOL nEndCol = aArea.aEnd.Col();
3345 SCROW nEndRow = aArea.aEnd.Row();
3346
3347 sc::CopyToDocContext aCxt(*this);
3348 sc::MixDocContext aMixDocCxt(*this);
3350 for (const SCTAB& i : rMark)
3351 {
3352 if (i >= nCount)
3353 break;
3354 if ( i != nSrcTab && maTabs[i] )
3355 {
3356 if (bDoMix)
3357 {
3358 if (!pMixDoc)
3359 {
3360 pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
3361 pMixDoc->InitUndo( *this, i, i );
3362 }
3363 else
3364 pMixDoc->AddUndoTab( i, i );
3365
3366 sc::CopyToDocContext aMixCxt(*pMixDoc);
3367 maTabs[i]->CopyToTable(aMixCxt, nStartCol,nStartRow, nEndCol,nEndRow,
3368 InsertDeleteFlags::CONTENTS, true, pMixDoc->maTabs[i].get(), &rMark,
3369 /*bAsLink*/false, /*bColRowFlags*/true, /*bGlobalNamesToLocal*/false,
3370 /*bCopyCaptions*/true );
3371 }
3372
3373 maTabs[i]->DeleteSelection( nDelFlags, rMark );
3374 pSourceTable->CopyToTable(aCxt, nStartCol,nStartRow, nEndCol,nEndRow,
3375 nFlags, true, maTabs[i].get(), &rMark, bAsLink,
3376 /*bColRowFlags*/true, /*bGlobalNamesToLocal*/false, /*bCopyCaptions*/true );
3377
3378 if (bDoMix)
3379 maTabs[i]->MixMarked(aMixDocCxt, rMark, nFunction, bSkipEmpty, pMixDoc->maTabs[i].get());
3380 }
3381 }
3382
3383 SetAutoCalc( bOldAutoCalc );
3384 }
3385 else
3386 {
3387 OSL_FAIL("wrong table");
3388 }
3389}
3390
3391bool ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rString,
3392 const ScSetStringParam* pParam )
3393{
3394 ScTable* pTab = FetchTable(nTab);
3395 if (!pTab)
3396 return false;
3397
3398 const ScFormulaCell* pCurCellFormula = pTab->GetFormulaCell(nCol, nRow);
3399 if (pCurCellFormula && pCurCellFormula->IsShared())
3400 {
3401 // In case setting this string affects an existing formula group, end
3402 // its listening to purge then empty cell broadcasters. Affected
3403 // remaining split group listeners will be set up again via
3404 // ScColumn::DetachFormulaCell() and
3405 // ScColumn::StartListeningUnshared().
3406
3407 sc::EndListeningContext aCxt(*this);
3408 ScAddress aPos(nCol, nRow, nTab);
3409 EndListeningIntersectedGroup(aCxt, aPos, nullptr);
3411 }
3412
3413 return pTab->SetString(nCol, nRow, nTab, rString, pParam);
3414}
3415
3417 const ScAddress& rPos, const OUString& rString, const ScSetStringParam* pParam )
3418{
3419 return SetString(rPos.Col(), rPos.Row(), rPos.Tab(), rString, pParam);
3420}
3421
3422bool ScDocument::SetEditText( const ScAddress& rPos, std::unique_ptr<EditTextObject> pEditText )
3423{
3424 if (ScTable* pTable = FetchTable(rPos.Tab()))
3425 return pTable->SetEditText(rPos.Col(), rPos.Row(), std::move(pEditText));
3426 return false;
3427}
3428
3429void ScDocument::SetEditText( const ScAddress& rPos, const EditTextObject& rEditText, const SfxItemPool* pEditPool )
3430{
3431 if (ScTable* pTable = FetchTable(rPos.Tab()))
3432 pTable->SetEditText(rPos.Col(), rPos.Row(), rEditText, pEditPool);
3433}
3434
3435void ScDocument::SetEditText( const ScAddress& rPos, const OUString& rStr )
3436{
3437 if (ScTable* pTable = FetchTable(rPos.Tab()))
3438 {
3439 ScFieldEditEngine& rEngine = GetEditEngine();
3440 rEngine.SetTextCurrentDefaults(rStr);
3441 pTable->SetEditText(rPos.Col(), rPos.Row(), rEngine.CreateTextObject());
3442 }
3443}
3444
3446{
3447 if (const ScTable* pTable = FetchTable(rRange.aStart.Tab()))
3448 return pTable->GetFirstEditTextRow(rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
3449 return -1;
3450}
3451
3452void ScDocument::SetTextCell( const ScAddress& rPos, const OUString& rStr )
3453{
3454 if (ScTable* pTable = FetchTable(rPos.Tab()))
3455 {
3456 if (ScStringUtil::isMultiline(rStr))
3457 {
3458 ScFieldEditEngine& rEngine = GetEditEngine();
3459 rEngine.SetTextCurrentDefaults(rStr);
3460 pTable->SetEditText(rPos.Col(), rPos.Row(), rEngine.CreateTextObject());
3461 }
3462 else
3463 {
3464 ScSetStringParam aParam;
3465 aParam.setTextInput();
3466 pTable->SetString(rPos.Col(), rPos.Row(), rPos.Tab(), rStr, &aParam);
3467 }
3468 }
3469}
3470
3472{
3473 if (ScTable* pTable = FetchTable(rPos.Tab()))
3474 pTable->SetEmptyCell(rPos.Col(), rPos.Row());
3475}
3476
3477void ScDocument::SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal )
3478{
3479 SetValue(ScAddress(nCol, nRow, nTab), rVal);
3480}
3481
3482void ScDocument::SetValue( const ScAddress& rPos, double fVal )
3483{
3484 ScTable* pTab = FetchTable(rPos.Tab());
3485 if (!pTab)
3486 return;
3487
3488 const ScFormulaCell* pCurCellFormula = pTab->GetFormulaCell(rPos.Col(), rPos.Row());
3489 if (pCurCellFormula && pCurCellFormula->IsShared())
3490 {
3491 // In case setting this value affects an existing formula group, end
3492 // its listening to purge then empty cell broadcasters. Affected
3493 // remaining split group listeners will be set up again via
3494 // ScColumn::DetachFormulaCell() and
3495 // ScColumn::StartListeningUnshared().
3496
3497 sc::EndListeningContext aCxt(*this);
3498 EndListeningIntersectedGroup(aCxt, rPos, nullptr);
3500 }
3501
3502 pTab->SetValue(rPos.Col(), rPos.Row(), fVal);
3503}
3504
3505OUString ScDocument::GetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext* pContext ) const
3506{
3507 if (const ScTable* pTable = FetchTable(nTab))
3508 return pTable->GetString(nCol, nRow, pContext);
3509 return OUString();
3510}
3511
3512OUString ScDocument::GetString( const ScAddress& rPos, const ScInterpreterContext* pContext ) const
3513{
3514 if (const ScTable* pTable = FetchTable(rPos.Tab()))
3515 return pTable->GetString(rPos.Col(), rPos.Row(), pContext);
3516 return OUString();
3517}
3518
3520{
3521 if (ScTable* pTable = FetchTable(rPos.Tab()))
3522 return pTable->GetValueCell(rPos.Col(), rPos.Row());
3523 return nullptr;
3524}
3525
3527{
3528 if (const ScTable* pTable = FetchTable(rPos.Tab()))
3529 return pTable->GetSharedString(rPos.Col(), rPos.Row());
3530 return svl::SharedString();
3531}
3532
3533std::shared_ptr<sc::FormulaGroupContext>& ScDocument::GetFormulaGroupContext()
3534{
3536 if (!mpFormulaGroupCxt)
3537 mpFormulaGroupCxt = std::make_shared<sc::FormulaGroupContext>();
3538
3539 return mpFormulaGroupCxt;
3540}
3541
3543{
3546 mpFormulaGroupCxt.reset();
3547}
3548
3549OUString ScDocument::GetInputString(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bForceSystemLocale ) const
3550{
3551 if (const ScTable* pTable = FetchTable(nTab))
3552 return pTable->GetInputString(nCol, nRow, bForceSystemLocale);
3553 else
3554 return OUString();
3555}
3556
3558{
3559 // Used in formulas (add-in parameters etc), so it must use the same semantics as
3560 // ScInterpreter::GetCellString: always format values as numbers.
3561 // The return value is the error code.
3562
3563 ScRefCellValue aCell(*this, rPos);
3564 if (aCell.isEmpty())
3565 {
3566 rString.clear();
3567 return FormulaError::NONE;
3568 }
3569
3570 FormulaError nErr = FormulaError::NONE;
3571 OUString aStr;
3572 SvNumberFormatter* pFormatter = GetFormatTable();
3573 switch (aCell.getType())
3574 {
3575 case CELLTYPE_STRING:
3576 case CELLTYPE_EDIT:
3577 aStr = aCell.getString(this);
3578 break;
3579 case CELLTYPE_FORMULA:
3580 {
3581 ScFormulaCell* pFCell = aCell.getFormula();
3582 nErr = pFCell->GetErrCode();
3583 if (pFCell->IsValue())
3584 {
3585 double fVal = pFCell->GetValue();
3586 sal_uInt32 nIndex = pFormatter->GetStandardFormat(
3587 SvNumFormatType::NUMBER,
3589 pFormatter->GetInputLineString(fVal, nIndex, aStr);
3590 }
3591 else
3592 aStr = pFCell->GetString().getString();
3593 }
3594 break;
3595 case CELLTYPE_VALUE:
3596 {
3597 double fVal = aCell.getDouble();
3598 sal_uInt32 nIndex = pFormatter->GetStandardFormat(
3599 SvNumFormatType::NUMBER,
3601 pFormatter->GetInputLineString(fVal, nIndex, aStr);
3602 }
3603 break;
3604 default:
3605 ;
3606 }
3607
3608 rString = aStr;
3609 return nErr;
3610}
3611
3613{
3614 SCTAB nTab = rPos.Tab();
3615 if (const ScTable* pTable = FetchTable(nTab))
3616 return pTable->GetEditText(rPos.Col(), rPos.Row());
3617 return nullptr;
3618}
3619
3621{
3622 if (ScTable* pTable = FetchTable(rPos.Tab()))
3623 return pTable->RemoveEditTextCharAttribs(rPos.Col(), rPos.Row(), rAttr);
3624}
3625
3626double ScDocument::GetValue( const ScAddress& rPos ) const
3627{
3628 SCTAB nTab = rPos.Tab();
3629 if (const ScTable* pTable = FetchTable(nTab))
3630 return pTable->GetValue(rPos.Col(), rPos.Row());
3631 return 0.0;
3632}
3633
3634double ScDocument::GetValue( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
3635{
3636 ScAddress aAdr(nCol, nRow, nTab);
3637 return GetValue(aAdr);
3638}
3639
3640sal_uInt32 ScDocument::GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
3641{
3642 if (const ScTable* pTable = FetchTable(nTab))
3643 return pTable->GetNumberFormat(nCol, nRow);
3644 return 0;
3645}
3646
3647sal_uInt32 ScDocument::GetNumberFormat( const ScRange& rRange ) const
3648{
3649 SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = rRange.aEnd.Tab();
3650 SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col();
3651 SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row();
3652
3653 if (!HasTable(nTab1) || !HasTable(nTab2))
3654 return 0;
3655
3656 sal_uInt32 nFormat = 0;
3657 bool bFirstItem = true;
3658 for (SCTAB nTab = nTab1; nTab <= nTab2 && nTab < GetTableCount() ; ++nTab)
3659 for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
3660 {
3661 sal_uInt32 nThisFormat = maTabs[nTab]->GetNumberFormat(nCol, nRow1, nRow2);
3662 if (bFirstItem)
3663 {
3664 nFormat = nThisFormat;
3665 bFirstItem = false;
3666 }
3667 else if (nThisFormat != nFormat)
3668 return 0;
3669 }
3670
3671 return nFormat;
3672}
3673
3674sal_uInt32 ScDocument::GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& rPos ) const
3675{
3676 SCTAB nTab = rPos.Tab();
3677 if (const ScTable* pTable = FetchTable(nTab))
3678 return pTable->GetNumberFormat( rContext, rPos );
3679 return 0;
3680}
3681
3682void ScDocument::SetNumberFormat( const ScAddress& rPos, sal_uInt32 nNumberFormat )
3683{
3685 SCTAB nTab = rPos.Tab();
3686 if (ScTable* pTable = FetchTable(nTab))
3687 pTable->SetNumberFormat(rPos.Col(), rPos.Row(), nNumberFormat);
3688}
3689
3691 const ScAddress& rPos ) const
3692{
3693 SCTAB nTab = rPos.Tab();
3694 if (nTab < GetTableCount() && maTabs[nTab])
3695 {
3696 nIndex = maTabs[nTab]->GetNumberFormat( rContext, rPos );
3697 nType = rContext.GetNumberFormatType( nIndex );
3698 }
3699 else
3700 {
3701 nType = SvNumFormatType::UNDEFINED;
3702 nIndex = 0;
3703 }
3704}
3705
3706OUString ScDocument::GetFormula( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
3707{
3708 if (const ScTable* pTable = FetchTable(nTab))
3709 return pTable->GetFormula(nCol, nRow);
3710
3711 return OUString();
3712}
3713
3715{
3716 if (const ScTable* pTable = FetchTable(rPos.Tab()))
3717 return pTable->GetFormulaCell(rPos.Col(), rPos.Row());
3718 return nullptr;
3719}
3720
3722{
3723 if (ScTable* pTable = FetchTable(rPos.Tab()))
3724 return pTable->GetFormulaCell(rPos.Col(), rPos.Row());
3725 return nullptr;
3726}
3727
3729{
3730 SCTAB nTab = rPos.Tab();
3731 if (const ScTable* pTable = FetchTable(nTab))
3732 return pTable->GetCellType(rPos);
3733 return CELLTYPE_NONE;
3734}
3735
3737{
3738 if (const ScTable* pTable = FetchTable(nTab))
3739 return pTable->GetCellType( nCol, nRow );
3740 return CELLTYPE_NONE;
3741}
3742
3743bool ScDocument::HasStringData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
3744{
3745 if (const ScTable* pTable = FetchTable(nTab) ; pTable && nCol < pTable->GetAllocatedColumnsCount())
3746 return pTable->HasStringData(nCol, nRow);
3747 return false;
3748}
3749
3750bool ScDocument::HasValueData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
3751{
3752 if (const ScTable* pTable = FetchTable(nTab) ; pTable && nCol < pTable->GetAllocatedColumnsCount())
3753 return pTable->HasValueData( nCol, nRow );
3754 return false;
3755}
3756
3757bool ScDocument::HasValueData( const ScAddress& rPos ) const
3758{
3759 return HasValueData(rPos.Col(), rPos.Row(), rPos.Tab());
3760}
3761
3762bool ScDocument::HasStringCells( const ScRange& rRange ) const
3763{
3764 // true, if String- or Edit cells in range
3765
3766 SCCOL nStartCol = rRange.aStart.Col();
3767 SCROW nStartRow = rRange.aStart.Row();
3768 SCTAB nStartTab = rRange.aStart.Tab();
3769 SCCOL nEndCol = rRange.aEnd.Col();
3770 SCROW nEndRow = rRange.aEnd.Row();
3771 SCTAB nEndTab = rRange.aEnd.Tab();
3772
3773 for (SCTAB nTab = nStartTab; nTab <= nEndTab && nTab < GetTableCount(); nTab++)
3774 {
3775 if ( maTabs[nTab] && maTabs[nTab]->HasStringCells( nStartCol, nStartRow, nEndCol, nEndRow ) )
3776 return true;
3777 }
3778 return false;
3779}
3780
3781bool ScDocument::HasSelectionData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
3782{
3783 sal_uInt32 nValidation = GetAttr( nCol, nRow, nTab, ATTR_VALIDDATA )->GetValue();
3784 if( nValidation )
3785 {
3786 const ScValidationData* pData = GetValidationEntry( nValidation );
3787 if( pData && pData->HasSelectionList() )
3788 return true;
3789 }
3790 return HasStringCells( ScRange( nCol, 0, nTab, nCol, MaxRow(), nTab ) );
3791}
3792
3793bool ScDocument::HasValidationData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
3794{
3795 sal_uInt32 nValidation = GetAttr( nCol, nRow, nTab, ATTR_VALIDDATA )->GetValue();
3796 if( nValidation )
3797 {
3798 const ScValidationData* pData = GetValidationEntry( nValidation );
3799 if( pData && pData->GetDataMode() != ScValidationMode::SC_VALID_ANY )
3800 return true;
3801 }
3802 return false;
3803}
3804
3806{
3807 bool bOldAutoCalc = GetAutoCalc();
3808 bAutoCalc = false; // no multiple calculations
3809
3810 for (const auto& a : maTabs)
3811 {
3812 if (a)
3813 a->CheckVectorizationState();
3814 }
3815
3816 SetAutoCalc(bOldAutoCalc);
3817}
3818
3820{
3821 bool bOldAutoCalc = GetAutoCalc();
3822 bAutoCalc = false; // no multiple calculations
3823 { // scope for bulk broadcast
3824 ScBulkBroadcast aBulkBroadcast( GetBASM(), SfxHintId::ScDataChanged);
3825 for (const auto& a : maTabs)
3826 {
3827 if (a)
3828 a->SetAllFormulasDirty(rCxt);
3829 }
3830 }
3831
3832 // Although Charts are also set to dirty in Tracking without AutoCalc
3833 // if all formulas are dirty, the charts can no longer be caught
3834 // (#45205#) - that is why all Charts have to be explicitly handled again
3836 pChartListenerCollection->SetDirty();
3837
3838 SetAutoCalc( bOldAutoCalc );
3839}
3840
3841void ScDocument::SetDirty( const ScRange& rRange, bool bIncludeEmptyCells )
3842{
3843 bool bOldAutoCalc = GetAutoCalc();
3844 bAutoCalc = false; // no multiple calculations
3845 { // scope for bulk broadcast
3846 ScBulkBroadcast aBulkBroadcast( GetBASM(), SfxHintId::ScDataChanged);
3847 SCTAB nTab2 = rRange.aEnd.Tab();
3848 for (SCTAB i = rRange.aStart.Tab(); i <= nTab2 && i < GetTableCount(); i++)
3849 if (maTabs[i]) maTabs[i]->SetDirty( rRange,
3851
3852 /* TODO: this now also notifies conditional formatting and does a UNO
3853 * broadcast, which wasn't done here before. Is that an actually
3854 * desired side effect, or should we come up with a method that
3855 * doesn't? */
3856 if (bIncludeEmptyCells)
3857 BroadcastCells( rRange, SfxHintId::ScDataChanged, false);
3858 }
3859 SetAutoCalc( bOldAutoCalc );
3860}
3861
3863{
3864 bool bOldAutoCalc = GetAutoCalc();
3865 bAutoCalc = false; // no multiple recalculation
3866 SCTAB nTab2 = rRange.aEnd.Tab();
3867 for (SCTAB i = rRange.aStart.Tab(); i <= nTab2 && i < GetTableCount(); i++)
3868 if (maTabs[i]) maTabs[i]->SetTableOpDirty( rRange );
3869 SetAutoCalc( bOldAutoCalc );
3870}
3871
3873{
3874 if (!GetAutoCalc())
3875 return;
3876
3878
3879 for (size_t nPos=0, nRangeCount = rRanges.size(); nPos < nRangeCount; nPos++)
3880 {
3881 const ScRange& rRange = rRanges[nPos];
3882 for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
3883 {
3884 ScTable* pTab = FetchTable(nTab);
3885 if (!pTab)
3886 return;
3887
3888 pTab->InterpretDirtyCells(
3889 rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
3890 }
3891 }
3892
3894 mpFormulaGroupCxt.reset();
3895}
3896
3898{
3899 bool allInterpreted = true;
3900 for (size_t nPos=0, nRangeCount = rRanges.size(); nPos < nRangeCount; nPos++)
3901 {
3902 const ScRange& rRange = rRanges[nPos];
3903 for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
3904 {
3905 ScTable* pTab = FetchTable(nTab);
3906 if (!pTab)
3907 break;
3908
3909 if( !pTab->InterpretCellsIfNeeded(
3910 rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row()))
3911 {
3912 allInterpreted = false;
3913 }
3914 }
3915 }
3916 return allInterpreted;
3917}
3918
3920{
3921 if (m_TableOpList.empty())
3922 return;
3923
3925 if ( p->bCollectNotifications )
3926 {
3927 if ( p->bRefresh )
3928 { // refresh pointers only
3929 p->aNotifiedFormulaCells.push_back( pCell );
3930 }
3931 else
3932 { // init both, address and pointer
3933 p->aNotifiedFormulaCells.push_back( pCell );
3934 p->aNotifiedFormulaPos.push_back( pCell->aPos );
3935 }
3936 }
3937}
3938
3940{
3942 ClearLookupCaches(); // Ensure we don't deliver zombie data.
3943 sc::AutoCalcSwitch aSwitch(*this, true);
3944 for (const auto& a : maTabs)
3945 {
3946 if (a)
3947 a->SetDirtyVar();
3948 }
3949 for (const auto& a : maTabs)
3950 {
3951 if (a)
3952 a->CalcAll();
3953 }
3955
3956 // In eternal hard recalc state caches were not added as listeners,
3957 // invalidate them so the next non-CalcAll() normal lookup will not be
3958 // presented with outdated data.
3961}
3962
3964{
3965 sc::CompileFormulaContext aCxt(*this);
3966 for (const auto& a : maTabs)
3967 {
3968 if (a)
3969 a->CompileAll(aCxt);
3970 }
3971
3972 sc::SetFormulaDirtyContext aFormulaDirtyCxt;
3973 SetAllFormulasDirty(aFormulaDirtyCxt);
3974}
3975
3977{
3978 bool bOldAutoCalc = GetAutoCalc();
3979 SetAutoCalc( false );
3980 ScProgress aProgress( GetDocumentShell(), ScResId(
3981 STR_PROGRESS_CALCULATING ), GetXMLImportedFormulaCount(), true );
3982
3983 sc::CompileFormulaContext aCxt(*this);
3984
3985 // set AutoNameCache to speed up automatic name lookup
3986 OSL_ENSURE( !pAutoNameCache, "AutoNameCache already set" );
3987 pAutoNameCache.reset( new ScAutoNameCache( *this ) );
3988
3989 if (pRangeName)
3990 pRangeName->CompileUnresolvedXML(aCxt);
3991
3992 std::for_each(maTabs.begin(), maTabs.end(),
3993 [&](ScTableUniquePtr & pTab)
3994 {
3995 if (pTab)
3996 pTab->CompileXML(aCxt, aProgress);
3997 }
3998 );
4000
4001 pAutoNameCache.reset(); // valid only during CompileXML, where cell contents don't change
4002
4003 if ( pValidationList )
4004 {
4006 pValidationList->CompileXML();
4007 }
4008
4009 // Track all formula cells that were appended to the FormulaTrack during
4010 // import or CompileXML().
4011 TrackFormulas();
4012
4013 SetAutoCalc( bOldAutoCalc );
4014}
4015
4017{
4018 bool bCompiled = false;
4019 sc::CompileFormulaContext aCxt(*this);
4020 for (const auto& pTab : maTabs)
4021 {
4022 if (pTab && pTab->CompileErrorCells(aCxt, nErrCode))
4023 bCompiled = true;
4024 }
4025
4026 return bCompiled;
4027}
4028
4029void ScDocument::CalcAfterLoad( bool bStartListening )
4030{
4031 if (bIsClip) // Excel data is loaded from the Clipboard to a Clip-Doc
4032 return; // the calculation is then only performed when inserting into the real document
4033
4034 bCalcingAfterLoad = true;
4035 sc::CompileFormulaContext aCxt(*this);
4036 {
4037 for (const auto& pTable : maTabs)
4038 {
4039 if (pTable)
4040 pTable->CalcAfterLoad(aCxt, bStartListening);
4041 }
4042 for (const auto& pTable : maTabs)
4043 {
4044 if (pTable)
4045 pTable->SetDirtyAfterLoad();
4046 }
4047 }
4048 bCalcingAfterLoad = false;
4049
4050 SetDetectiveDirty(false); // No real changes yet
4051
4052 // #i112436# If formula cells are already dirty, they don't broadcast further changes.
4053 // So the source ranges of charts must be interpreted even if they are not visible,
4054 // similar to ScMyShapeResizer::CreateChartListener for loading own files (i104899).
4056 {
4057 const ScChartListenerCollection::ListenersType& rListeners = pChartListenerCollection->getListeners();
4058 for (auto const& it : rListeners)
4059 {
4060 const ScChartListener *const p = it.second.get();
4061 InterpretDirtyCells(*p->GetRangeList());
4062 }
4063 }
4064}
4065
4067{
4068 SCTAB nTab = rPos.Tab();
4069 if (const ScTable* pTable = FetchTable(nTab))
4070 return pTable->GetErrCode( rPos );
4071 return FormulaError::NONE;
4072}
4073
4075{
4077 SCTAB nTab1 = rRange.aStart.Tab();
4078 SCTAB nTab2 = rRange.aEnd.Tab();
4079 for (SCTAB nTab = nTab1; nTab1 <= nTab2 && nTab < nTabSize; ++nTab)
4080 if (maTabs[nTab])
4081 maTabs[nTab]->ResetChanged(rRange);
4082}
4083
4084// Column widths / Row heights --------------------------------------
4085
4086void ScDocument::SetColWidth( SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth )
4087{
4088 if (ScTable* pTable = FetchTable(nTab))
4089 pTable->SetColWidth(nCol, nNewWidth);
4090}
4091
4092void ScDocument::SetColWidthOnly( SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth )
4093{
4094 if (ScTable* pTable = FetchTable(nTab))
4095 pTable->SetColWidthOnly(nCol, nNewWidth);
4096}
4097
4098void ScDocument::SetRowHeight( SCROW nRow, SCTAB nTab, sal_uInt16 nNewHeight )
4099{
4100 if (ScTable* pTable = FetchTable(nTab))
4101 pTable->SetRowHeight(nRow, nNewHeight);
4102}
4103
4104void ScDocument::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_uInt16 nNewHeight )
4105{
4106 if (ScTable* pTable = FetchTable(nTab))
4107 pTable->SetRowHeightRange(nStartRow, nEndRow, nNewHeight, 1.0, true);
4108}
4109
4110void ScDocument::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_uInt16 nNewHeight )
4111{
4112 if (ScTable* pTable = FetchTable(nTab))
4113 pTable->SetRowHeightOnly( nStartRow, nEndRow, nNewHeight );
4114}
4115
4116void ScDocument::SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bManual )
4117{
4118 if (ScTable* pTable = FetchTable(nTab))
4119 pTable->SetManualHeight( nStartRow, nEndRow, bManual );
4120}
4121
4122sal_uInt16 ScDocument::GetColWidth( SCCOL nCol, SCTAB nTab, bool bHiddenAsZero ) const
4123{
4124 if (const ScTable* pTable = FetchTable(nTab))
4125 return pTable->GetColWidth( nCol, bHiddenAsZero );
4126 OSL_FAIL("wrong table number");
4127 return 0;
4128}
4129
4130tools::Long ScDocument::GetColWidth( SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab ) const
4131{
4132 if (const ScTable* pTable = FetchTable(nTab))
4133 return pTable->GetColWidth(nStartCol, nEndCol);
4134 return 0;
4135}
4136
4137sal_uInt16 ScDocument::GetOriginalWidth( SCCOL nCol, SCTAB nTab ) const
4138{
4139 if (const ScTable* pTable = FetchTable(nTab))
4140 return pTable->GetOriginalWidth( nCol );
4141 OSL_FAIL("wrong table number");
4142 return 0;
4143}
4144
4145sal_uInt16 ScDocument::GetCommonWidth( SCCOL nEndCol, SCTAB nTab ) const
4146{
4147 if (const ScTable* pTable = FetchTable(nTab))
4148 return pTable->GetCommonWidth( nEndCol );
4149 OSL_FAIL("Wrong table number");
4150 return 0;
4151}
4152
4153sal_uInt16 ScDocument::GetOriginalHeight( SCROW nRow, SCTAB nTab ) const
4154{
4155 if (const ScTable* pTable = FetchTable(nTab))
4156 return pTable->GetOriginalHeight( nRow );
4157 OSL_FAIL("Wrong table number");
4158 return 0;
4159}
4160
4161sal_uInt16 ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero ) const
4162{
4163 if (const ScTable* pTable = FetchTable(nTab))
4164 return pTable->GetRowHeight( nRow, nullptr, nullptr, bHiddenAsZero );
4165 OSL_FAIL("Wrong sheet number");
4166 return 0;
4167}
4168
4169sal_uInt16 ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) const
4170{
4171 if (const ScTable* pTable = FetchTable(nTab))
4172 return pTable->GetRowHeight( nRow, pStartRow, pEndRow, bHiddenAsZero );
4173 OSL_FAIL("Wrong sheet number");
4174 return 0;
4175}
4176
4177tools::Long ScDocument::GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero ) const
4178{
4179 if (nStartRow == nEndRow)
4180 return GetRowHeight( nStartRow, nTab, bHiddenAsZero ); // faster for a single row
4181
4182 // check bounds because this method replaces former for(i=start;i<=end;++i) loops
4183 if (nStartRow > nEndRow)
4184 return 0;
4185
4186 if (const ScTable* pTable = FetchTable(nTab))
4187 return pTable->GetRowHeight( nStartRow, nEndRow, bHiddenAsZero );
4188
4189 OSL_FAIL("wrong sheet number");
4190 return 0;
4191}
4192
4194{
4195 return maTabs[nTab]->GetRowForHeight(nHeight);
4196}
4197
4199 SCTAB nTab, double fScale ) const
4200{
4201 // faster for a single row
4202 if (nStartRow == nEndRow)
4203 return static_cast<tools::Long>(GetRowHeight( nStartRow, nTab) * fScale);
4204
4205 // check bounds because this method replaces former for(i=start;i<=end;++i) loops
4206 if (nStartRow > nEndRow)
4207 return 0;
4208
4209 if (const ScTable* pTable = FetchTable(nTab))
4210 return pTable->GetScaledRowHeight( nStartRow, nEndRow, fScale);
4211
4212 OSL_FAIL("wrong sheet number");
4213 return 0;
4214}
4215
4217{
4218 if (const ScTable* pTable = FetchTable(nTab))
4219 return pTable->GetHiddenRowCount( nRow );
4220 OSL_FAIL("wrong table number");
4221 return 0;
4222}
4223
4224tools::Long ScDocument::GetColOffset( SCCOL nCol, SCTAB nTab, bool bHiddenAsZero ) const
4225{
4226 if (const ScTable* pTable = FetchTable(nTab))
4227 return pTable->GetColOffset( nCol, bHiddenAsZero );
4228 OSL_FAIL("wrong table number");
4229 return 0;
4230}
4231
4232tools::Long ScDocument::GetRowOffset( SCROW nRow, SCTAB nTab, bool bHiddenAsZero ) const
4233{
4234 if (const ScTable* pTable = FetchTable(nTab))
4235 return pTable->GetRowOffset( nRow, bHiddenAsZero );
4236 OSL_FAIL("wrong table number");
4237 return 0;
4238}
4239
4241 double nPPTX, double nPPTY,
4242 const Fraction& rZoomX, const Fraction& rZoomY,
4243 bool bFormula, const ScMarkData* pMarkData,
4244 const ScColWidthParam* pParam )
4245{
4246 if (ScTable* pTable = FetchTable(nTab))
4247 return pTable->GetOptimalColWidth(nCol, pDev, nPPTX, nPPTY, rZoomX,
4248 rZoomY, bFormula, pMarkData, pParam);
4249 OSL_FAIL("wrong table number");
4250 return 0;
4251}
4252
4254 OutputDevice* pDev,
4255 double nPPTX, double nPPTY,
4256 const Fraction& rZoomX, const Fraction& rZoomY,
4257 bool bWidth, bool bTotalSize, bool bInPrintTwips )
4258{
4259 if (ScTable* pTable = FetchTable(nTab))
4260 return pTable->GetNeededSize(nCol, nRow, pDev, nPPTX, nPPTY,
4261 rZoomX, rZoomY, bWidth, bTotalSize,
4262 bInPrintTwips);
4263 OSL_FAIL("wrong table number");
4264 return 0;
4265}
4266
4267bool ScDocument::SetOptimalHeight( sc::RowHeightContext& rCxt, SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bApi )
4268{
4269 if (ScTable* pTable = FetchTable(nTab))
4270 return pTable->SetOptimalHeight(rCxt, nStartRow, nEndRow, bApi);
4271 return false;
4272}
4273
4275{
4276 // one progress across all (selected) sheets
4277
4278 sal_uInt64 nCellCount = 0;
4279 for (SCTAB nTab = 0; nTab < GetTableCount(); nTab++)
4280 if ( maTabs[nTab] && ( !pTabMark || pTabMark->GetTableSelect(nTab) ) )
4281 nCellCount += maTabs[nTab]->GetWeightedCount();
4282
4283 ScProgress aProgress( GetDocumentShell(), ScResId(STR_PROGRESS_HEIGHTING), nCellCount, true );
4284
4285 sal_uInt64 nProgressStart = 0;
4286 for (SCTAB nTab = 0; nTab < GetTableCount(); nTab++)
4287 if ( maTabs[nTab] && ( !pTabMark || pTabMark->GetTableSelect(nTab) ) )
4288 {
4289 maTabs[nTab]->SetOptimalHeightOnly(rCxt, 0, MaxRow(), &aProgress, nProgressStart);
4290 maTabs[nTab]->SetDrawPageSize();
4291 nProgressStart += maTabs[nTab]->GetWeightedCount();
4292 }
4293}
4294
4295// Column/Row - Flags ----------------------------------------------
4296
4297void ScDocument::ShowCol(SCCOL nCol, SCTAB nTab, bool bShow)
4298{
4299 if (ScTable* pTable = FetchTable(nTab))
4300 pTable->ShowCol(nCol, bShow);
4301}
4302
4303void ScDocument::ShowRow(SCROW nRow, SCTAB nTab, bool bShow)
4304{
4305 if (ScTable* pTable = FetchTable(nTab))
4306 pTable->ShowRow(nRow, bShow);
4307}
4308
4309void ScDocument::ShowRows(SCROW nRow1, SCROW nRow2, SCTAB nTab, bool bShow)
4310{
4311 if (ScTable* pTable = FetchTable(nTab))
4312 pTable->ShowRows( nRow1, nRow2, bShow );
4313}
4314
4315void ScDocument::SetRowFlags( SCROW nRow, SCTAB nTab, CRFlags nNewFlags )
4316{
4317 if (ScTable* pTable = FetchTable(nTab))
4318 pTable->SetRowFlags( nRow, nNewFlags );
4319}
4320
4321void ScDocument::SetRowFlags( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, CRFlags nNewFlags )
4322{
4323 if (ScTable* pTable = FetchTable(nTab))
4324 pTable->SetRowFlags( nStartRow, nEndRow, nNewFlags );
4325}
4326
4328{
4329 if (const ScTable* pTable = FetchTable(nTab))
4330 return pTable->GetColFlags( nCol );
4331 OSL_FAIL("wrong table number");
4332 return CRFlags::NONE;
4333}
4334
4336{
4337 if (const ScTable* pTable = FetchTable(nTab))
4338 return pTable->GetRowFlags( nRow );
4339 OSL_FAIL("wrong table number");
4340 return CRFlags::NONE;
4341}
4342
4343void ScDocument::GetAllRowBreaks(set<SCROW>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const
4344{
4345 if (const ScTable* pTable = FetchTable(nTab))
4346 pTable->GetAllRowBreaks(rBreaks, bPage, bManual);
4347}
4348
4349void ScDocument::GetAllColBreaks(set<SCCOL>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const
4350{
4351 if (const ScTable* pTable = FetchTable(nTab))
4352 pTable->GetAllColBreaks(rBreaks, bPage, bManual);
4353}
4354
4356{
4358 if (const ScTable* pTable = FetchTable(nTab); pTable && ValidRow(nRow))
4359 {
4360 if (pTable->HasRowPageBreak(nRow))
4362
4363 if (pTable->HasRowManualBreak(nRow))
4365 }
4366 return nType;
4367}
4368
4370{
4372
4373 if (const ScTable* pTable = FetchTable(nTab); pTable && ValidCol(nCol))
4374 {
4375 if (pTable->HasColPageBreak(nCol))
4377
4378 if (pTable->HasColManualBreak(nCol))
4380 }
4381 return nType;
4382}
4383
4384void ScDocument::SetRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
4385{
4386 if (ScTable* pTable = FetchTable(nTab); pTable && ValidRow(nRow))
4387 pTable->SetRowBreak(nRow, bPage, bManual);
4388}
4389
4390void ScDocument::SetColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
4391{
4392 if (ScTable* pTable = FetchTable(nTab); pTable && ValidCol(nCol))
4393 pTable->SetColBreak(nCol, bPage, bManual);
4394}
4395
4396void ScDocument::RemoveRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
4397{
4398 if (ScTable* pTable = FetchTable(nTab); pTable && ValidRow(nRow))
4399 pTable->RemoveRowBreak(nRow, bPage, bManual);
4400}
4401
4402void ScDocument::RemoveColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
4403{
4404 if (ScTable* pTable = FetchTable(nTab); pTable && ValidCol(nCol))
4405 pTable->RemoveColBreak(nCol, bPage, bManual);
4406}
4407
4408Sequence<TablePageBreakData> ScDocument::GetRowBreakData(SCTAB nTab) const
4409{
4410 if (const ScTable* pTable = FetchTable(nTab))
4411 return pTable->GetRowBreakData();
4412
4413 return Sequence<TablePageBreakData>();
4414}
4415
4416bool ScDocument::RowHidden(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow) const
4417{
4418 if (const ScTable* pTable = FetchTable(nTab))
4419 return pTable->RowHidden(nRow, pFirstRow, pLastRow);
4420 return false;
4421}
4422
4423bool ScDocument::HasHiddenRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
4424{
4425 if (const ScTable* pTable = FetchTable(nTab))
4426 return pTable->HasHiddenRows(nStartRow, nEndRow);
4427 return false;
4428}
4429
4430bool ScDocument::ColHidden(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol, SCCOL* pLastCol) const
4431{
4432 if (const ScTable* pTable = FetchTable(nTab))
4433 return pTable->ColHidden(nCol, pFirstCol, pLastCol);
4434
4435 if (pFirstCol)
4436 *pFirstCol = nCol;
4437 if (pLastCol)
4438 *pLastCol = nCol;
4439 return false;
4440}
4441
4442void ScDocument::SetRowHidden(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHidden)
4443{
4444 if (ScTable* pTable = FetchTable(nTab))
4445 pTable->SetRowHidden(nStartRow, nEndRow, bHidden);
4446}
4447
4448void ScDocument::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bHidden)
4449{
4450 if (ScTable* pTable = FetchTable(nTab))
4451 pTable->SetColHidden(nStartCol, nEndCol, bHidden);
4452}
4453
4454SCROW ScDocument::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
4455{
4456 if (const ScTable* pTable = FetchTable(nTab))
4457 return pTable->FirstVisibleRow(nStartRow, nEndRow);
4458 return 0;
4459}
4460
4461SCROW ScDocument::LastVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
4462{
4463 if (const ScTable* pTable = FetchTable(nTab))
4464 return pTable->LastVisibleRow(nStartRow, nEndRow);
4465 return ::std::numeric_limits<SCROW>::max();
4466}
4467
4468SCROW ScDocument::CountVisibleRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
4469{
4470 if (const ScTable* pTable = FetchTable(nTab))
4471 return pTable->CountVisibleRows(nStartRow, nEndRow);
4472 return 0;
4473}
4474
4475bool ScDocument::RowFiltered(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow) const
4476{
4477 if (const ScTable* pTable = FetchTable(nTab))
4478 return pTable->RowFiltered(nRow, pFirstRow, pLastRow);
4479 return false;
4480}
4481
4482bool ScDocument::HasFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
4483{
4484 if (const ScTable* pTable = FetchTable(nTab))
4485 return pTable->HasFilteredRows(nStartRow, nEndRow);
4486 return false;
4487}
4488
4490{
4491 if (const ScTable* pTable = FetchTable(nTab))
4492 return pTable->ColFiltered(nCol);
4493 return false;
4494}
4495
4496void ScDocument::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bFiltered)
4497{
4498 if (ScTable* pTable = FetchTable(nTab))
4499 pTable->SetRowFiltered(nStartRow, nEndRow, bFiltered);
4500}
4501
4503{
4504 if (const ScTable* pTable = FetchTable(nTab))
4505 return pTable->FirstNonFilteredRow(nStartRow, nEndRow);
4506 return std::numeric_limits<SCROW>::max();
4507}
4508
4510{
4511 if (const ScTable* pTable = FetchTable(nTab))
4512 return pTable->LastNonFilteredRow(nStartRow, nEndRow);
4513 return std::numeric_limits<SCROW>::max();
4514}
4515
4517{
4518 if (const ScTable* pTable = FetchTable(nTab))
4519 return pTable->CountNonFilteredRows(nStartRow, nEndRow);
4520 return 0;
4521}
4522
4524{
4525 if (const ScTable* pTable = FetchTable(nTab))
4526 return pTable->IsManualRowHeight(nRow);
4527 return false;
4528}
4529
4531{
4532 for (const auto& pTable : maTabs)
4533 {
4534 if (pTable)
4535 pTable->SyncColRowFlags();
4536 }
4537}
4538
4540{
4541 if (const ScTable* pTable = FetchTable(nTab))
4542 return pTable->GetLastFlaggedRow();
4543 return 0;
4544}
4545
4547{
4548 if (const ScTable* pTable = FetchTable(nTab))
4549 return pTable->GetLastChangedColFlagsWidth();
4550 return 0;
4551}
4552
4554{
4555 if (const ScTable* pTable = FetchTable(nTab))
4556 return pTable->GetLastChangedRowFlagsWidth();
4557 return 0;
4558}
4559
4561{
4562 if (const ScTable* pTable = FetchTable(nTab))
4563 {
4564 CRFlags nStartFlags = pTable->GetColFlags(nStart);
4565 sal_uInt16 nStartWidth = pTable->GetOriginalWidth(nStart);
4566 for (SCCOL nCol : pTable->GetColumnsRange( nStart + 1, MaxCol()))
4567 {
4568 if (((nStartFlags & CRFlags::ManualBreak) != (pTable->GetColFlags(nCol) & CRFlags::ManualBreak)) ||
4569 (nStartWidth != pTable->GetOriginalWidth(nCol)) ||
4570 ((nStartFlags & CRFlags::Hidden) != (pTable->GetColFlags(nCol) & CRFlags::Hidden)) )
4571 {
4572 return nCol;
4573 }
4574 }
4575 return MaxCol()+1;
4576 }
4577 return 0;
4578}
4579
4581{
4582 const ScTable* pTable = FetchTable(nTab);
4583 if (!pTable)
4584 return 0;
4585
4586 const ScBitMaskCompressedArray<SCROW, CRFlags>* pRowFlagsArray = pTable->GetRowFlagsArray();
4587 if (!pRowFlagsArray)
4588 return 0;
4589
4590 if (!pTable->mpRowHeights || !pTable->mpHiddenRows)
4591 return 0;
4592
4593 size_t nIndex; // ignored
4594 SCROW nFlagsEndRow;
4595 SCROW nHiddenEndRow;
4596 SCROW nHeightEndRow;
4597 CRFlags nFlags;
4598 bool bHidden;
4599 sal_uInt16 nHeight;
4600 CRFlags nStartFlags = nFlags = pRowFlagsArray->GetValue( nStart, nIndex, nFlagsEndRow);
4601 bool bStartHidden = bHidden = pTable->RowHidden( nStart, nullptr, &nHiddenEndRow);
4602 sal_uInt16 nStartHeight = nHeight = pTable->GetRowHeight( nStart, nullptr, &nHeightEndRow, false);
4603 SCROW nRow;
4604 while ((nRow = std::min( nHiddenEndRow, std::min( nFlagsEndRow, nHeightEndRow)) + 1) <= MaxRow())
4605 {
4606 if (nFlagsEndRow < nRow)
4607 nFlags = pRowFlagsArray->GetValue( nRow, nIndex, nFlagsEndRow);
4608 if (nHiddenEndRow < nRow)
4609 bHidden = pTable->RowHidden( nRow, nullptr, &nHiddenEndRow);
4610 if (nHeightEndRow < nRow)
4611 nHeight = pTable->GetRowHeight( nRow, nullptr, &nHeightEndRow, false);
4612
4613 if (((nStartFlags & CRFlags::ManualBreak) != (nFlags & CRFlags::ManualBreak)) ||
4614 ((nStartFlags & CRFlags::ManualSize) != (nFlags & CRFlags::ManualSize)) ||
4615 (bStartHidden != bHidden) ||
4616 (nStartHeight != nHeight))
4617 return nRow;
4618 }
4619
4620 return MaxRow()+1;
4621}
4622
4623void ScDocument::GetColDefault( SCTAB nTab, SCCOL nCol, SCROW nLastRow, SCROW& nDefault)
4624{
4625 nDefault = 0;
4626 ScDocAttrIterator aDocAttrItr(*this, nTab, nCol, 0, nCol, nLastRow);
4627 SCCOL nColumn;
4628 SCROW nStartRow;
4629 SCROW nEndRow;
4630 const ScPatternAttr* pAttr = aDocAttrItr.GetNext(nColumn, nStartRow, nEndRow);
4631 if (nEndRow >= nLastRow)
4632 return;
4633
4634 ScDefaultAttrSet aSet;
4635 ScDefaultAttrSet::iterator aItr = aSet.end();
4636 while (pAttr)
4637 {
4638 ScDefaultAttr aAttr(pAttr);
4639 aItr = aSet.find(aAttr);
4640 if (aItr == aSet.end())
4641 {
4642 aAttr.nCount = static_cast<SCSIZE>(nEndRow - nStartRow + 1);
4643 aAttr.nFirst = nStartRow;
4644 aSet.insert(aAttr);
4645 }
4646 else
4647 {
4648 aAttr.nCount = aItr->nCount + static_cast<SCSIZE>(nEndRow - nStartRow + 1);
4649 aAttr.nFirst = aItr->nFirst;
4650 aSet.erase(aItr);
4651 aSet.insert(aAttr);
4652 }
4653 pAttr = aDocAttrItr.GetNext(nColumn, nStartRow, nEndRow);
4654 }
4655 ScDefaultAttrSet::iterator aDefaultItr = aSet.begin();
4656 aItr = aDefaultItr;
4657 ++aItr;
4658 while (aItr != aSet.end())
4659 {
4660 // for entries with equal count, use the one with the lowest start row,
4661 // don't use the random order of pointer comparisons
4662 if ( aItr->nCount > aDefaultItr->nCount ||
4663 ( aItr->nCount == aDefaultItr->nCount && aItr->nFirst < aDefaultItr->nFirst ) )
4664 aDefaultItr = aItr;
4665 ++aItr;
4666 }
4667 nDefault = aDefaultItr->nFirst;
4668}
4669
4670void ScDocument::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, SCTAB nTab )
4671{
4672 if (ScTable* pTable = FetchTable(nTab))
4673 pTable->StripHidden( rX1, rY1, rX2, rY2 );
4674}
4675
4676void ScDocument::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, SCTAB nTab )
4677{
4678 if (ScTable* pTable = FetchTable(nTab))
4679 pTable->ExtendHidden( rX1, rY1, rX2, rY2 );
4680}
4681
4682// Attribute ----------------------------------------------------------
4683
4684const SfxPoolItem* ScDocument::GetAttr( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich ) const
4685{
4686 if (const ScTable* pTable = FetchTable(nTab))
4687 {
4688 const SfxPoolItem* pTemp = pTable->GetAttr( nCol, nRow, nWhich );
4689 if (pTemp)
4690 return pTemp;
4691 else
4692 {
4693 OSL_FAIL( "Attribute Null" );
4694 }
4695 }
4696 return &mxPoolHelper->GetDocPool()->GetDefaultItem( nWhich );
4697}
4698
4699const SfxPoolItem* ScDocument::GetAttr( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich, SCROW& nStartRow, SCROW& nEndRow ) const
4700{
4701 if (const ScTable* pTable = FetchTable(nTab))
4702 {
4703 const SfxPoolItem* pTemp = pTable->GetAttr( nCol, nRow, nWhich, nStartRow, nEndRow );
4704 if (pTemp)
4705 return pTemp;
4706 else
4707 {
4708 OSL_FAIL( "Attribute Null" );
4709 }
4710 }
4711 return &mxPoolHelper->GetDocPool()->GetDefaultItem( nWhich );
4712}
4713
4714const SfxPoolItem* ScDocument::GetAttr( const ScAddress& rPos, sal_uInt16 nWhich ) const
4715{
4716 return GetAttr(rPos.Col(), rPos.Row(), rPos.Tab(), nWhich);
4717}
4718
4719const ScPatternAttr* ScDocument::GetPattern( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
4720{
4721 if (const ScTable* pTable = FetchTable(nTab))
4722 return pTable->GetPattern( nCol, nRow );
4723 return nullptr;
4724}
4725
4727{
4728 if (const ScTable* pTable = FetchTable(rPos.Tab()))
4729 return pTable->GetPattern(rPos.Col(), rPos.Row());
4730
4731 return nullptr;
4732}
4733
4734const ScPatternAttr* ScDocument::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) const
4735{
4736 if (const ScTable* pTable = FetchTable(nTab))
4737 return pTable->GetMostUsedPattern(nCol, nStartRow, nEndRow);
4738 return nullptr;
4739}
4740
4741void ScDocument::ApplyAttr( SCCOL nCol, SCROW nRow, SCTAB nTab, const SfxPoolItem& rAttr )
4742{
4743 if (ScTable* pTable = FetchTable(nTab))
4744 pTable->ApplyAttr( nCol, nRow, rAttr );
4745}
4746
4747void ScDocument::ApplyPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr& rAttr )
4748{
4749 if (ScTable* pTable = FetchTable(nTab))
4750 pTable->ApplyPattern(nCol, nRow, rAttr);
4751}
4752
4753void ScDocument::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow,
4754 SCCOL nEndCol, SCROW nEndRow,
4755 const ScMarkData& rMark,
4756 const ScPatternAttr& rAttr,
4757 ScEditDataArray* pDataArray,
4758 bool* const pIsChanged )
4759{
4760 SCTAB nMax = GetTableCount();
4761 for (const auto& rTab : rMark)
4762 {
4763 if (rTab >= nMax)
4764 break;
4765 if (maTabs[rTab])
4766 maTabs[rTab]->ApplyPatternArea( nStartCol, nStartRow, nEndCol, nEndRow, rAttr, pDataArray, pIsChanged );
4767 }
4768}
4769
4771 SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScPatternAttr& rAttr )
4772{
4773 if (ScTable* pTable = FetchTable(nTab))
4774 pTable->ApplyPatternArea(nStartCol, nStartRow, nEndCol, nEndRow, rAttr);
4775}
4776
4778 const ScMarkData& rMark, const ScPatternAttr& rPattern, SvNumFormatType nNewType )
4779{
4780 SCTAB nMax = GetTableCount();
4781 for (const auto& rTab : rMark)
4782 {
4783 if (rTab >= nMax)
4784 break;
4785 if (maTabs[rTab])
4786 maTabs[rTab]->ApplyPatternIfNumberformatIncompatible( rRange, rPattern, nNewType );
4787 }
4788}
4789
4790void ScDocument::AddCondFormatData( const ScRangeList& rRange, SCTAB nTab, sal_uInt32 nIndex )
4791{
4792 if (ScTable* pTable = FetchTable(nTab))
4793 pTable->AddCondFormatData(rRange, nIndex);
4794}
4795
4796void ScDocument::RemoveCondFormatData( const ScRangeList& rRange, SCTAB nTab, sal_uInt32 nIndex )
4797{
4798 if (ScTable* pTable = FetchTable(nTab))
4799 pTable->RemoveCondFormatData(rRange, nIndex);
4800}
4801
4802void ScDocument::ApplyStyle( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScStyleSheet& rStyle)
4803{
4804 if (ScTable* pTable = FetchTable(nTab))
4805 pTable->ApplyStyle(nCol, nRow, &rStyle);
4806}
4807
4808void ScDocument::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow,
4809 SCCOL nEndCol, SCROW nEndRow,
4810 const ScMarkData& rMark,
4811 const ScStyleSheet& rStyle)
4812{
4813 SCTAB nMax = GetTableCount();
4814 for (const auto& rTab : rMark)
4815 {
4816 if (rTab >= nMax)
4817 break;
4818 if (maTabs[rTab])
4819 maTabs[rTab]->ApplyStyleArea( nStartCol, nStartRow, nEndCol, nEndRow, rStyle );
4820 }
4821}
4822
4823void ScDocument::ApplyStyleAreaTab( SCCOL nStartCol, SCROW nStartRow,
4824 SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScStyleSheet& rStyle)
4825{
4826 if (ScTable* pTable = FetchTable(nTab))
4827 pTable->ApplyStyleArea( nStartCol, nStartRow, nEndCol, nEndRow, rStyle );
4828}
4829
4831{
4832 // ApplySelectionStyle needs multi mark
4833 if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
4834 {
4835 const ScRange& aRange = rMark.GetMarkArea();
4836 ApplyStyleArea( aRange.aStart.Col(), aRange.aStart.Row(),
4837 aRange.aEnd.Col(), aRange.aEnd.Row(), rMark, rStyle );
4838 }
4839 else
4840 {
4841 SCTAB nMax = GetTableCount();
4842 for (const auto& rTab : rMark)
4843 {
4844 if (rTab >= nMax)
4845 break;
4846 if ( maTabs[rTab] )
4847 maTabs[rTab]->ApplySelectionStyle( rStyle, rMark );
4848 }
4849 }
4850}
4851
4853 const SvxBorderLine* pLine, bool bColorOnly )
4854{
4855 if ( bColorOnly && !pLine )
4856 return;
4857
4858 SCTAB nMax = GetTableCount();
4859 for (const auto& rTab : rMark)
4860 {
4861 if (rTab >= nMax)
4862 break;
4863 if (maTabs[rTab])
4864 maTabs[rTab]->ApplySelectionLineStyle( rMark, pLine, bColorOnly );
4865 }
4866}
4867
4868const ScStyleSheet* ScDocument::GetStyle( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
4869{
4870 if (const ScTable* pTable = FetchTable(nTab))
4871 return pTable->GetStyle(nCol, nRow);
4872 return nullptr;
4873}
4874
4876{
4877 bool bEqual = true;
4878 bool bFound;
4879
4880 const ScStyleSheet* pStyle = nullptr;
4881 const ScStyleSheet* pNewStyle;
4882
4883 if ( rMark.IsMultiMarked() )
4884 {
4885 SCTAB nMax = GetTableCount();
4886 for (const auto& rTab : rMark)
4887 {
4888 if (rTab >= nMax)
4889 break;
4890
4891 if (maTabs[rTab])
4892 {
4893 pNewStyle = maTabs[rTab]->GetSelectionStyle( rMark, bFound );
4894 if (bFound)
4895 {
4896 if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
4897 bEqual = false; // different
4898 pStyle = pNewStyle;
4899 }
4900 }
4901 }
4902 }
4903 if ( rMark.IsMarked() )
4904 {
4905 const ScRange& aRange = rMark.GetMarkArea();
4906 for (SCTAB i = aRange.aStart.Tab(); i <= aRange.aEnd.Tab() && bEqual && i < GetTableCount(); i++)
4907 if (maTabs[i] && rMark.GetTableSelect(i))
4908 {
4909 pNewStyle = maTabs[i]->GetAreaStyle( bFound,
4910 aRange.aStart.Col(), aRange.aStart.Row(),
4911 aRange.aEnd.Col(), aRange.aEnd.Row() );
4912 if (bFound)
4913 {
4914 if ( !pNewStyle || ( pStyle && pNewStyle != pStyle ) )
4915 bEqual = false; // different
4916 pStyle = pNewStyle;
4917 }
4918 }
4919 }
4920
4921 return bEqual ? pStyle : nullptr;
4922}
4923
4924void ScDocument::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, bool bRemoved,
4925 OutputDevice* pDev,
4926 double nPPTX, double nPPTY,
4927 const Fraction& rZoomX, const Fraction& rZoomY )
4928{
4929 for (const auto& rTab : maTabs)
4930 {
4931 if (rTab)
4932 {
4933 rTab->StyleSheetChanged(pStyleSheet, bRemoved, pDev, nPPTX, nPPTY, rZoomX, rZoomY);
4934 }
4935 }
4936}
4937
4939{
4941 {
4942 SfxStyleSheetIterator aIter( mxPoolHelper->GetStylePool(),
4943 SfxStyleFamily::Para );
4944 for ( const SfxStyleSheetBase* pStyle = aIter.First(); pStyle;
4945 pStyle = aIter.Next() )
4946 {
4947 if (pStyle->isScStyleSheet())
4948 {
4949 const ScStyleSheet* pScStyle = static_cast<const ScStyleSheet*>( pStyle );
4951 }
4952 }
4953
4954 bool bIsUsed = false;
4955
4956 for (const auto& pTable : maTabs)
4957 {
4958 if (pTable && pTable->IsStyleSheetUsed(rStyle))
4959 bIsUsed = true;
4960 }
4961
4963
4964 return bIsUsed;
4965 }
4966
4967 return rStyle.GetUsage() == ScStyleSheet::Usage::USED;
4968}
4969
4970bool ScDocument::ApplyFlagsTab( SCCOL nStartCol, SCROW nStartRow,
4971 SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, ScMF nFlags )
4972{
4973 if (ScTable* pTable = FetchTable(nTab))
4974 return pTable->ApplyFlags(nStartCol, nStartRow, nEndCol, nEndRow, nFlags);
4975
4976 OSL_FAIL("ApplyFlags: wrong table");
4977 return false;
4978}
4979
4980bool ScDocument::RemoveFlagsTab( SCCOL nStartCol, SCROW nStartRow,
4981 SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, ScMF nFlags )
4982{
4983 if (ScTable* pTable = FetchTable(nTab))
4984 return pTable->RemoveFlags(nStartCol, nStartRow, nEndCol, nEndRow, nFlags);
4985
4986 OSL_FAIL("RemoveFlags: wrong table");
4987 return false;
4988}
4989
4990const ScPatternAttr* ScDocument::SetPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, std::unique_ptr<ScPatternAttr> pAttr )
4991{
4992 if (ScTable* pTable = FetchTable(nTab))
4993 return pTable->SetPattern(nCol, nRow, std::move(pAttr));
4994 return nullptr;
4995}
4996
4997const ScPatternAttr* ScDocument::SetPattern( const ScAddress& rPos, std::unique_ptr<ScPatternAttr> pAttr )
4998{
4999 return SetPattern(rPos.Col(), rPos.Row(), rPos.Tab(), std::move(pAttr));
5000}
5001
5002void ScDocument::SetPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr& rAttr )
5003{
5004 if (ScTable* pTable = FetchTable(nTab))
5005 pTable->SetPattern(nCol, nRow, rAttr);
5006}
5007
5008void ScDocument::SetPattern( const ScAddress& rPos, const ScPatternAttr& rAttr )
5009{
5010 SCTAB nTab = rPos.Tab();
5011 if (ScTable* pTable = FetchTable(nTab))
5012 pTable->SetPattern(rPos, rAttr);
5013}
5014
5015std::unique_ptr<ScPatternAttr> ScDocument::CreateSelectionPattern( const ScMarkData& rMark, bool bDeep )
5016{
5017 ScMergePatternState aState;
5018
5019 if ( rMark.IsMultiMarked() ) // multi selection
5020 {
5021 SCTAB nMax = GetTableCount();
5022 for (const auto& rTab : rMark)
5023 {
5024 if (rTab >= nMax)
5025 break;
5026 if (maTabs[rTab])
5027 maTabs[rTab]->MergeSelectionPattern( aState, rMark, bDeep );
5028 }
5029 }
5030 if ( rMark.IsMarked() ) // single selection
5031 {
5032 const ScRange& aRange = rMark.GetMarkArea();
5033 SCTAB nMax = GetTableCount();
5034 for (const auto& rTab : rMark)
5035 {
5036 if (rTab >= nMax)
5037 break;
5038 if (maTabs[rTab])
5039 maTabs[rTab]->MergePatternArea( aState,
5040 aRange.aStart.Col(), aRange.aStart.Row(),
5041 aRange.aEnd.Col(), aRange.aEnd.Row(), bDeep );
5042 }
5043 }
5044
5045 OSL_ENSURE( aState.pItemSet, "SelectionPattern Null" );
5046 if (aState.pItemSet)
5047 {
5048 std::unique_ptr<ScPatternAttr> pPattern(new ScPatternAttr( std::move(*aState.pItemSet) ));
5049 if (aState.mbValidPatternId)
5050 pPattern->SetKey(aState.mnPatternId);
5051
5052 return pPattern;
5053 }
5054 else
5055 return std::unique_ptr<ScPatternAttr>(new ScPatternAttr( GetPool() )); // empty
5056}
5057
5059{
5061 return pSelectionAttr.get();
5062}
5063
5065 SvxBoxItem& rLineOuter,
5066 SvxBoxInfoItem& rLineInner )
5067{
5068 rLineOuter.SetLine(nullptr, SvxBoxItemLine::TOP);
5069 rLineOuter.SetLine(nullptr, SvxBoxItemLine::BOTTOM);
5070 rLineOuter.SetLine(nullptr, SvxBoxItemLine::LEFT);
5071 rLineOuter.SetLine(nullptr, SvxBoxItemLine::RIGHT);
5072 rLineOuter.SetAllDistances(0);
5073
5074 rLineInner.SetLine(nullptr, SvxBoxInfoItemLine::HORI);
5075 rLineInner.SetLine(nullptr, SvxBoxInfoItemLine::VERT);
5076 rLineInner.SetTable(true);
5077 rLineInner.SetDist(true);
5078 rLineInner.SetMinDist(false);
5079
5080 ScLineFlags aFlags;
5081
5082 if( rMark.IsMultiMarked() )
5083 {
5084 ScRangeList aRangeList;
5085 rMark.FillRangeListWithMarks( &aRangeList, false );
5086 size_t nRangeCount = aRangeList.size();
5087 bool bMultipleRows = false, bMultipleCols = false;
5088 for( size_t nRangeIdx = 0; nRangeIdx < nRangeCount; ++nRangeIdx )
5089 {
5090 const ScRange & rRange = aRangeList[ nRangeIdx ];
5091 bMultipleRows = ( bMultipleRows || ( rRange.aStart.Row() != rRange.aEnd.Row() ) );
5092 bMultipleCols = ( bMultipleCols || ( rRange.aStart.Col() != rRange.aEnd.Col() ) );
5093 SCTAB nMax = GetTableCount();
5094 for (const auto& rTab : rMark)
5095 {
5096 if (rTab >= nMax)
5097 break;
5098
5099 if (maTabs[rTab])
5100 maTabs[rTab]->MergeBlockFrame( &rLineOuter, &rLineInner, aFlags,
5101 rRange.aStart.Col(), rRange.aStart.Row(),
5102 rRange.aEnd.Col(), rRange.aEnd.Row() );
5103 }
5104 }
5105 rLineInner.EnableHor( bMultipleRows );
5106 rLineInner.EnableVer( bMultipleCols );
5107 }
5108 else if( rMark.IsMarked() )
5109 {
5110 const ScRange& aRange = rMark.GetMarkArea();
5111 rLineInner.EnableHor( aRange.aStart.Row() != aRange.aEnd.Row() );
5112 rLineInner.EnableVer( aRange.aStart.Col() != aRange.aEnd.Col() );
5113 SCTAB nMax = GetTableCount();
5114 for (const auto& rTab : rMark)
5115 {
5116 if (rTab >= nMax)
5117 break;
5118
5119 if (maTabs[rTab])
5120 maTabs[rTab]->MergeBlockFrame( &rLineOuter, &rLineInner, aFlags,
5121 aRange.aStart.Col(), aRange.aStart.Row(),
5122 aRange.aEnd.Col(), aRange.aEnd.Row() );
5123 }
5124 }
5125
5126 // Evaluate don't care Status
5127
5128 rLineInner.SetValid( SvxBoxInfoItemValidFlags::LEFT, ( aFlags.nLeft != SC_LINE_DONTCARE ) );
5129 rLineInner.SetValid( SvxBoxInfoItemValidFlags::RIGHT, ( aFlags.nRight != SC_LINE_DONTCARE ) );
5130 rLineInner.SetValid( SvxBoxInfoItemValidFlags::TOP, ( aFlags.nTop != SC_LINE_DONTCARE ) );
5131 rLineInner.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, ( aFlags.nBottom != SC_LINE_DONTCARE ) );
5132 rLineInner.SetValid( SvxBoxInfoItemValidFlags::HORI, ( aFlags.nHori != SC_LINE_DONTCARE ) );
5133 rLineInner.SetValid( SvxBoxInfoItemValidFlags::VERT, ( aFlags.nVert != SC_LINE_DONTCARE ) );
5134}
5135
5137{
5138 if ( nMask & HasAttrFlags::Rotate )
5139 {
5140 // Is attribute used in document?
5141 // (as in fillinfo)
5142
5143 bool bAnyItem = false;
5144 for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(ATTR_ROTATE_VALUE))
5145 {
5146 // 90 or 270 degrees is former SvxOrientationItem - only look for other values
5147 // (see ScPatternAttr::GetCellOrientation)
5148 Degree100 nAngle = static_cast<const ScRotateValueItem*>(pItem)->GetValue();
5149 if ( nAngle && nAngle != 9000_deg100 && nAngle != 27000_deg100 )
5150 {
5151 bAnyItem = true;
5152 break;
5153 }
5154 }
5155 if (!bAnyItem)
5156 nMask &= ~HasAttrFlags::Rotate;
5157 }
5158 return nMask;
5159}
5160
5161bool ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
5162 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, HasAttrFlags nMask ) const
5163{
5164 nMask = OptimizeHasAttrib( nMask, mxPoolHelper->GetDocPool());
5165
5166 if (nMask == HasAttrFlags::NONE)
5167 return false;
5168
5169 for (SCTAB i = nTab1; i <= nTab2 && i < GetTableCount(); i++)
5170 if (maTabs[i])
5171 {
5172 if ( nMask & HasAttrFlags::RightOrCenter )
5173 {
5174 // On a RTL sheet, don't start to look for the default left value
5175 // (which is then logically right), instead always assume true.
5176 // That way, ScAttrArray::HasAttrib doesn't have to handle RTL sheets.
5177
5178 if ( IsLayoutRTL(i) )
5179 return true;
5180 }
5181
5182 if( maTabs[i]->HasAttrib( nCol1, nRow1, nCol2, nRow2, nMask ))
5183 return true;
5184 }
5185
5186 return false;
5187}
5188
5189bool ScDocument::HasAttrib( SCCOL nCol, SCROW nRow, SCTAB nTab, HasAttrFlags nMask, SCROW* nStartRow, SCROW* nEndRow ) const
5190{
5191 nMask = OptimizeHasAttrib( nMask, mxPoolHelper->GetDocPool());
5192
5193 if (nMask == HasAttrFlags::NONE || nTab >= GetTableCount())
5194 {
5195 if( nStartRow )
5196 *nStartRow = 0;
5197 if( nEndRow )
5198 *nEndRow = MaxRow();
5199 return false;
5200 }
5201
5202 if ( nMask & HasAttrFlags::RightOrCenter )
5203 {
5204 // On a RTL sheet, don't start to look for the default left value
5205 // (which is then logically right), instead always assume true.
5206 // That way, ScAttrArray::HasAttrib doesn't have to handle RTL sheets.
5207
5208 if ( IsLayoutRTL(nTab) )
5209 {
5210 if( nStartRow )
5211 *nStartRow = 0;
5212 if( nEndRow )
5213 *nEndRow = MaxRow();
5214 return true;
5215 }
5216 }
5217
5218 return maTabs[nTab]->HasAttrib( nCol, nRow, nMask, nStartRow, nEndRow );
5219}
5220
5221bool ScDocument::HasAttrib( const ScRange& rRange, HasAttrFlags nMask ) const
5222{
5223 return HasAttrib( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
5224 rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(),
5225 nMask );
5226}
5227
5228void ScDocument::FindMaxRotCol( SCTAB nTab, RowInfo* pRowInfo, SCSIZE nArrCount,
5229 SCCOL nX1, SCCOL nX2 ) const
5230{
5231 if (HasTable(nTab))
5232 {
5233 maTabs[nTab]->FindMaxRotCol(pRowInfo, nArrCount, nX1, nX2);
5234 return;
5235 }
5236 OSL_FAIL("FindMaxRotCol: wrong table");
5237}
5238
5240 const SvxBorderLine** ppLeft, const SvxBorderLine** ppTop,
5241 const SvxBorderLine** ppRight, const SvxBorderLine** ppBottom ) const
5242{
5243 //TODO: consider page limits for printing !!!!!
5244
5245 const SvxBoxItem* pThisAttr = GetEffItem( nCol, nRow, nTab, ATTR_BORDER );
5246 OSL_ENSURE(pThisAttr,"where is the attribute?");
5247
5248 const SvxBorderLine* pLeftLine = pThisAttr->GetLeft();
5249 const SvxBorderLine* pTopLine = pThisAttr->GetTop();
5250 const SvxBorderLine* pRightLine = pThisAttr->GetRight();
5251 const SvxBorderLine* pBottomLine = pThisAttr->GetBottom();
5252
5253 if ( nCol > 0 )
5254 {
5255 const SvxBorderLine* pOther = GetEffItem( nCol-1, nRow, nTab, ATTR_BORDER )->GetRight();
5256 if ( ScHasPriority( pOther, pLeftLine ) )
5257 pLeftLine = pOther;
5258 }
5259 if ( nRow > 0 )
5260 {
5261 const SvxBorderLine* pOther = GetEffItem( nCol, nRow-1, nTab, ATTR_BORDER )->GetBottom();
5262 if ( ScHasPriority( pOther, pTopLine ) )
5263 pTopLine = pOther;
5264 }
5265 if ( nCol < MaxCol() )
5266 {
5267 const SvxBorderLine* pOther = GetEffItem( nCol+1, nRow, nTab, ATTR_BORDER )->GetLeft();
5268 if ( ScHasPriority( pOther, pRightLine ) )
5269 pRightLine = pOther;
5270 }
5271 if ( nRow < MaxRow() )
5272 {
5273 const SvxBorderLine* pOther = GetEffItem( nCol, nRow+1, nTab, ATTR_BORDER )->GetTop();
5274 if ( ScHasPriority( pOther, pBottomLine ) )
5275 pBottomLine = pOther;
5276 }
5277
5278 if (ppLeft)
5279 *ppLeft = pLeftLine;
5280 if (ppTop)
5281 *ppTop = pTopLine;
5282 if (ppRight)
5283 *ppRight = pRightLine;
5284 if (ppBottom)
5285 *ppBottom = pBottomLine;
5286}
5287
5288bool ScDocument::IsBlockEmpty(SCCOL nStartCol, SCROW nStartRow,
5289 SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
5290{
5291 if (HasTable(nTab))
5292 return maTabs[nTab]->IsBlockEmpty(nStartCol, nStartRow, nEndCol, nEndRow);
5293 OSL_FAIL("wrong table number");
5294 return false;
5295}
5296
5298{
5299 if (ScTable* pTable = FetchTable(nTab))
5300 pTable->LockTable();
5301 else
5302 {
5303 OSL_FAIL("wrong table number");
5304 }
5305}
5306
5308{
5309 if (ScTable* pTable = FetchTable(nTab))
5310 pTable->UnlockTable();
5311 else
5312 {
5313 OSL_FAIL("wrong table number");
5314 }
5315}
5316
5317bool ScDocument::IsBlockEditable( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
5318 SCCOL nEndCol, SCROW nEndRow,
5319 bool* pOnlyNotBecauseOfMatrix /* = NULL */,
5320 bool bNoMatrixAtAll ) const
5321{
5322 // import into read-only document is possible
5324 {
5325 if ( pOnlyNotBecauseOfMatrix )
5326 *pOnlyNotBecauseOfMatrix = false;
5327 return false;
5328 }
5329
5330 if (const ScTable* pTable = FetchTable(nTab))
5331 return pTable->IsBlockEditable(nStartCol, nStartRow, nEndCol, nEndRow,
5332 pOnlyNotBecauseOfMatrix, bNoMatrixAtAll);
5333
5334 OSL_FAIL("wrong table number");
5335 if ( pOnlyNotBecauseOfMatrix )
5336 *pOnlyNotBecauseOfMatrix = false;
5337 return false;
5338}
5339
5341 bool* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
5342{
5343 // import into read-only document is possible
5345 {
5346 if ( pOnlyNotBecauseOfMatrix )
5347 *pOnlyNotBecauseOfMatrix = false;
5348 return false;
5349 }
5350
5351 const ScRange& aRange = rMark.GetMarkArea();
5352
5353 bool bOk = true;
5354 bool bMatrix = ( pOnlyNotBecauseOfMatrix != nullptr );
5355 SCTAB nMax = GetTableCount();
5356 for (const auto& rTab : rMark)
5357 {
5358 if (rTab >= nMax)
5359 break;
5360
5361 if ( maTabs[rTab] )
5362 {
5363 if (rMark.IsMarked())
5364 {
5365 if ( !maTabs[rTab]->IsBlockEditable( aRange.aStart.Col(),
5366 aRange.aStart.Row(), aRange.aEnd.Col(),
5367 aRange.aEnd.Row(), pOnlyNotBecauseOfMatrix ) )
5368 {
5369 bOk = false;
5370 if ( pOnlyNotBecauseOfMatrix )
5371 bMatrix = *pOnlyNotBecauseOfMatrix;
5372 }
5373 }
5374 if (rMark.IsMultiMarked())
5375 {
5376 if ( !maTabs[rTab]->IsSelectionEditable( rMark, pOnlyNotBecauseOfMatrix ) )
5377 {
5378 bOk = false;
5379 if ( pOnlyNotBecauseOfMatrix )
5380 bMatrix = *pOnlyNotBecauseOfMatrix;
5381 }
5382 }
5383 }
5384
5385 if (!bOk && !bMatrix)
5386 break;
5387 }
5388
5389 if ( pOnlyNotBecauseOfMatrix )
5390 *pOnlyNotBecauseOfMatrix = ( !bOk && bMatrix );
5391
5392 return bOk;
5393}
5394
5396 SCCOL nEndCol, SCROW nEndRow,
5397 const ScMarkData& rMark ) const
5398{
5399 bool bOk = true;
5400 SCTAB nMax = GetTableCount();
5401 for (const auto& rTab : rMark)
5402 {
5403 if (rTab >= nMax)
5404 break;
5405
5406 if (maTabs[rTab] && maTabs[rTab]->HasBlockMatrixFragment( nStartCol, nStartRow, nEndCol, nEndRow ))
5407 bOk = false;
5408
5409 if (!bOk)
5410 break;
5411 }
5412
5413 return !bOk;
5414}
5415
5416bool ScDocument::GetMatrixFormulaRange( const ScAddress& rCellPos, ScRange& rMatrix )
5417{
5418 // if rCell is part of a matrix formula, return its complete range
5419
5420 ScFormulaCell* pFCell = GetFormulaCell(rCellPos);
5421 if (!pFCell)
5422 // not a formula cell. Bail out.
5423 return false;
5424
5425 ScAddress aOrigin = rCellPos;
5426 if (!pFCell->GetMatrixOrigin(*this, aOrigin))
5427 // Failed to get the address of the matrix origin.
5428 return false;
5429
5430 if (aOrigin != rCellPos)
5431 {
5432 pFCell = GetFormulaCell(aOrigin);
5433 if (!pFCell)
5434 // The matrix origin cell is not a formula cell !? Something is up...
5435 return false;
5436 }
5437
5438 SCCOL nSizeX;
5439 SCROW nSizeY;
5440 pFCell->GetMatColsRows(nSizeX, nSizeY);
5441 if (nSizeX <= 0 || nSizeY <= 0)
5442 {
5443 // GetMatrixEdge computes also dimensions of the matrix
5444 // if not already done (may occur if document is loaded
5445 // from old file format).
5446 // Needs an "invalid" initialized address.
5447 aOrigin.SetInvalid();
5448 pFCell->GetMatrixEdge(*this, aOrigin);
5449 pFCell->GetMatColsRows(nSizeX, nSizeY);
5450 }
5451
5452 if (nSizeX <= 0 || nSizeY <= 0)
5453 // Matrix size is still invalid. Give up.
5454 return false;
5455
5456 ScAddress aEnd( aOrigin.Col() + nSizeX - 1,
5457 aOrigin.Row() + nSizeY - 1,
5458 aOrigin.Tab() );
5459
5460 rMatrix.aStart = aOrigin;
5461 rMatrix.aEnd = aEnd;
5462
5463 return true;
5464}
5465
5466void ScDocument::ExtendOverlapped( SCCOL& rStartCol, SCROW& rStartRow,
5467 SCCOL nEndCol, SCROW nEndRow, SCTAB nTab ) const
5468{
5469 if ( ValidColRow(rStartCol,rStartRow) && ValidColRow(nEndCol,nEndRow) && ValidTab(nTab) )
5470 {
5471 if (const ScTable* pTable = FetchTable(nTab))
5472 {
5473 SCCOL nCol;
5474 SCCOL nOldCol = rStartCol;
5475 SCROW nOldRow = rStartRow;
5476 for (nCol=nOldCol; nCol<=nEndCol; nCol++)
5477 while (GetAttr(nCol,rStartRow,nTab,ATTR_MERGE_FLAG)->IsVerOverlapped())
5478 --rStartRow;
5479
5480 //TODO: pass on ?
5481
5482 const ScAttrArray& pAttrArray = pTable->ColumnData(nOldCol).AttrArray();
5483 SCSIZE nIndex;
5484 if ( pAttrArray.Count() )
5485 pAttrArray.Search( nOldRow, nIndex );
5486 else
5487 nIndex = 0;
5488 SCROW nAttrPos = nOldRow;
5489 while (nAttrPos<=nEndRow)
5490 {
5491 OSL_ENSURE( nIndex < pAttrArray.Count(), "Wrong index in AttrArray" );
5492
5493 bool bHorOverlapped;
5494 if ( pAttrArray.Count() )
5495 bHorOverlapped = pAttrArray.mvData[nIndex].pPattern->GetItem(ATTR_MERGE_FLAG).IsHorOverlapped();
5496 else
5497 bHorOverlapped = GetDefPattern()->GetItem(ATTR_MERGE_FLAG).IsHorOverlapped();
5498 if ( bHorOverlapped )
5499 {
5500 SCROW nEndRowSeg = (pAttrArray.Count()) ? pAttrArray.mvData[nIndex].nEndRow : MaxRow();
5501 SCROW nLoopEndRow = std::min( nEndRow, nEndRowSeg );
5502 for (SCROW nAttrRow = nAttrPos; nAttrRow <= nLoopEndRow; nAttrRow++)
5503 {
5504 SCCOL nTempCol = nOldCol;
5505 do
5506 --nTempCol;
5507 while (GetAttr(nTempCol,nAttrRow,nTab,ATTR_MERGE_FLAG)->IsHorOverlapped());
5508 if (nTempCol < rStartCol)
5509 rStartCol = nTempCol;
5510 }
5511 }
5512 if ( pAttrArray.Count() )
5513 {
5514 nAttrPos = pAttrArray.mvData[nIndex].nEndRow + 1;
5515 ++nIndex;
5516 }
5517 else
5518 nAttrPos = MaxRow() + 1;
5519 }
5520 }
5521 }
5522 else
5523 {
5524 OSL_FAIL("ExtendOverlapped: invalid range");
5525 }
5526}
5527
5528void ScDocument::ExtendMergeSel( SCCOL nStartCol, SCROW nStartRow,
5529 SCCOL& rEndCol, SCROW& rEndRow,
5530 const ScMarkData& rMark, bool bRefresh )
5531{
5532 // use all selected sheets from rMark
5533
5534 SCCOL nOldEndCol = rEndCol;
5535 SCROW nOldEndRow = rEndRow;
5536
5537 SCTAB nMax = GetTableCount();
5538 for (const auto& rTab : rMark)
5539 {
5540 if (rTab >= nMax)
5541 break;
5542
5543 if ( maTabs[rTab] )
5544 {
5545 SCCOL nThisEndCol = nOldEndCol;
5546 SCROW nThisEndRow = nOldEndRow;
5547 ExtendMerge( nStartCol, nStartRow, nThisEndCol, nThisEndRow, rTab, bRefresh );
5548 if ( nThisEndCol > rEndCol )
5549 rEndCol = nThisEndCol;
5550 if ( nThisEndRow > rEndRow )
5551 rEndRow = nThisEndRow;
5552 }
5553 }
5554}
5555
5556bool ScDocument::ExtendMerge( SCCOL nStartCol, SCROW nStartRow,
5557 SCCOL& rEndCol, SCROW& rEndRow,
5558 SCTAB nTab, bool bRefresh )
5559{
5560 bool bFound = false;
5561 if ( ValidColRow(nStartCol,nStartRow) && ValidColRow(rEndCol,rEndRow) && ValidTab(nTab) )
5562 {
5563 if (ScTable* pTable = FetchTable(nTab))
5564 bFound = pTable->ExtendMerge( nStartCol, nStartRow, rEndCol, rEndRow, bRefresh );
5565
5566 if (bRefresh)
5567 RefreshAutoFilter( nStartCol, nStartRow, rEndCol, rEndRow, nTab );
5568 }
5569 else
5570 {
5571 OSL_FAIL("ExtendMerge: invalid range");
5572 }
5573
5574 return bFound;
5575}
5576
5577bool ScDocument::ExtendMerge( ScRange& rRange, bool bRefresh )
5578{
5579 bool bFound = false;
5580 SCTAB nStartTab = rRange.aStart.Tab();
5581 SCTAB nEndTab = rRange.aEnd.Tab();
5582 SCCOL nEndCol = rRange.aEnd.Col();
5583 SCROW nEndRow = rRange.aEnd.Row();
5584
5585 PutInOrder( nStartTab, nEndTab );
5586 for (SCTAB nTab = nStartTab; nTab <= nEndTab && nTab < GetTableCount(); nTab++ )
5587 {
5588 SCCOL nExtendCol = rRange.aEnd.Col();
5589 SCROW nExtendRow = rRange.aEnd.Row();
5590 if (ExtendMerge( rRange.aStart.Col(), rRange.aStart.Row(),
5591 nExtendCol, nExtendRow,
5592 nTab, bRefresh ) )
5593 {
5594 bFound = true;
5595 if (nExtendCol > nEndCol) nEndCol = nExtendCol;
5596 if (nExtendRow > nEndRow) nEndRow = nExtendRow;
5597 }
5598 }
5599
5600 rRange.aEnd.SetCol(nEndCol);
5601 rRange.aEnd.SetRow(nEndRow);
5602
5603 return bFound;
5604}
5605
5607{
5608 // Extend range to merged cells without including any new non-overlapped cells
5609 ScRange aExt = rRange;
5610 // ExtendMerge() is non-const, but called without refresh.
5611 if (!const_cast<ScDocument*>(this)->ExtendMerge( aExt ))
5612 return;
5613
5614 if ( aExt.aEnd.Row() > rRange.aEnd.Row() )
5615 {
5616 ScRange aTest = aExt;
5617 aTest.aStart.SetRow( rRange.aEnd.Row() + 1 );
5618 if ( HasAttrib( aTest, HasAttrFlags::NotOverlapped ) )
5619 aExt.aEnd.SetRow(rRange.aEnd.Row());
5620 }
5621 if ( aExt.aEnd.Col() > rRange.aEnd.Col() )
5622 {
5623 ScRange aTest = aExt;
5624 aTest.aStart.SetCol( rRange.aEnd.Col() + 1 );
5625 if ( HasAttrib( aTest, HasAttrFlags::NotOverlapped ) )
5626 aExt.aEnd.SetCol(rRange.aEnd.Col());
5627 }
5628
5629 rRange = aExt;
5630}
5631
5633{
5634 SCTAB nStartTab = rRange.aStart.Tab();
5635 SCTAB nEndTab = rRange.aEnd.Tab();
5636 SCCOL nStartCol = rRange.aStart.Col();
5637 SCROW nStartRow = rRange.aStart.Row();
5638
5639 PutInOrder( nStartTab, nEndTab );
5640 for (SCTAB nTab = nStartTab; nTab <= nEndTab && nTab < GetTableCount(); nTab++ )
5641 {
5642 SCCOL nExtendCol = rRange.aStart.Col();
5643 SCROW nExtendRow = rRange.aStart.Row();
5644 ExtendOverlapped( nExtendCol, nExtendRow,
5645 rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
5646 if (nExtendCol < nStartCol)
5647 {
5648 nStartCol = nExtendCol;
5649 }
5650 if (nExtendRow < nStartRow)
5651 {
5652 nStartRow = nExtendRow;
5653 }
5654 }
5655
5656 rRange.aStart.SetCol(nStartCol);
5657 rRange.aStart.SetRow(nStartRow);
5658}
5659
5660bool ScDocument::RefreshAutoFilter( SCCOL nStartCol, SCROW nStartRow,
5661 SCCOL nEndCol, SCROW nEndRow, SCTAB nTab )
5662{
5663 SCTAB nDBTab;
5664 SCCOL nDBStartCol;
5665 SCROW nDBStartRow;
5666 SCCOL nDBEndCol;
5667 SCROW nDBEndRow;
5668
5669 // Delete Autofilter
5670
5671 bool bChange = RemoveFlagsTab( nStartCol,nStartRow, nEndCol,nEndRow, nTab, ScMF::Auto );
5672
5673 // Set Autofilter
5674
5675 const ScDBData* pData = nullptr;
5676 ScDBCollection::NamedDBs& rDBs = pDBCollection->getNamedDBs();
5677 for (const auto& rxDB : rDBs)
5678 {
5679 if (rxDB->HasAutoFilter())
5680 {
5681 rxDB->GetArea(nDBTab, nDBStartCol,nDBStartRow, nDBEndCol,nDBEndRow);
5682 if ( nDBTab==nTab && nDBStartRow<=nEndRow && nDBEndRow>=nStartRow &&
5683 nDBStartCol<=nEndCol && nDBEndCol>=nStartCol )
5684 {
5685 if (ApplyFlagsTab( nDBStartCol,nDBStartRow, nDBEndCol,nDBStartRow,
5686 nDBTab, ScMF::Auto ))
5687 bChange = true;
5688 }
5689 }
5690 }
5691 if (ScTable* pTable = FetchTable(nTab))
5692 pData = pTable->GetAnonymousDBData();
5693 else
5694 pData = nullptr;
5695 if (pData && pData->HasAutoFilter())
5696 {
5697 pData->GetArea( nDBTab, nDBStartCol,nDBStartRow, nDBEndCol,nDBEndRow );
5698 if ( nDBTab==nTab && nDBStartRow<=nEndRow && nDBEndRow>=nStartRow &&
5699 nDBStartCol<=nEndCol && nDBEndCol>=nStartCol )
5700 {
5701 if (ApplyFlagsTab( nDBStartCol,nDBStartRow, nDBEndCol,nDBStartRow,
5702 nDBTab, ScMF::Auto ))
5703 bChange = true;
5704 }
5705 }
5706 return bChange;
5707}
5708
5709void ScDocument::SkipOverlapped( SCCOL& rCol, SCROW& rRow, SCTAB nTab ) const
5710{
5711 while (IsHorOverlapped(rCol, rRow, nTab))
5712 --rCol;
5713 while (IsVerOverlapped(rCol, rRow, nTab))
5714 --rRow;
5715}
5716
5717bool ScDocument::IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
5718{
5719 const ScMergeFlagAttr* pAttr = GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG );
5720 if (pAttr)
5721 return pAttr->IsHorOverlapped();
5722 else
5723 {
5724 OSL_FAIL("Overlapped: Attr==0");
5725 return false;
5726 }
5727}
5728
5729bool ScDocument::IsVerOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab, SCROW* nStartRow, SCROW* nEndRow ) const
5730{
5731 SCROW dummy;
5732 const ScMergeFlagAttr* pAttr = GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG,
5733 nStartRow ? *nStartRow : dummy, nEndRow ? *nEndRow : dummy );
5734 if (pAttr)
5735 return pAttr->IsVerOverlapped();
5736 else
5737 {
5738 OSL_FAIL("Overlapped: Attr==0");
5739 return false;
5740 }
5741}
5742
5744 const SvxBoxItem& rLineOuter,
5745 const SvxBoxInfoItem* pLineInner )
5746{
5747 ScRangeList aRangeList;
5748 rMark.FillRangeListWithMarks( &aRangeList, false );
5749 size_t nRangeCount = aRangeList.size();
5750 SCTAB nMax = GetTableCount();
5751 for (const auto& rTab : rMark)
5752 {
5753 if (rTab >= nMax)
5754 break;
5755
5756 if (maTabs[rTab])
5757 {
5758 for ( size_t j=0; j < nRangeCount; j++ )
5759 {
5760 const ScRange & rRange = aRangeList[ j ];
5761 maTabs[rTab]->ApplyBlockFrame( rLineOuter, pLineInner,
5762 rRange.aStart.Col(), rRange.aStart.Row(),
5763 rRange.aEnd.Col(), rRange.aEnd.Row() );
5764 }
5765 }
5766 }
5767 if (!rLineOuter.IsRemoveAdjacentCellBorder())
5768 return;
5769
5770 SvxBoxItem aTmp0(rLineOuter);
5771 aTmp0.SetLine( nullptr, SvxBoxItemLine::TOP );
5772 aTmp0.SetLine( nullptr, SvxBoxItemLine::BOTTOM );
5773 aTmp0.SetLine( nullptr, SvxBoxItemLine::LEFT );
5774 aTmp0.SetLine( nullptr, SvxBoxItemLine::RIGHT );
5775 SvxBoxItem aLeft( aTmp0 );
5776 SvxBoxItem aRight( aTmp0 );
5777 SvxBoxItem aTop( aTmp0 );
5778 SvxBoxItem aBottom( aTmp0 );
5779
5780 SvxBoxInfoItem aTmp1( *pLineInner );
5781 aTmp1.SetTable( false );
5782 aTmp1.SetLine( nullptr, SvxBoxInfoItemLine::HORI );
5783 aTmp1.SetLine( nullptr, SvxBoxInfoItemLine::VERT );
5784 aTmp1.SetValid( SvxBoxInfoItemValidFlags::ALL, false );
5785 aTmp1.SetValid( SvxBoxInfoItemValidFlags::DISTANCE );
5786 SvxBoxInfoItem aLeftInfo( aTmp1 );
5787 SvxBoxInfoItem aRightInfo( aTmp1 );
5788 SvxBoxInfoItem aTopInfo( aTmp1 );
5789 SvxBoxInfoItem aBottomInfo( aTmp1 );
5790
5791 if (pLineInner->IsValid( SvxBoxInfoItemValidFlags::TOP ) && !rLineOuter.GetTop())
5792 aTopInfo.SetValid( SvxBoxInfoItemValidFlags::BOTTOM );
5793
5794 if (pLineInner->IsValid( SvxBoxInfoItemValidFlags::BOTTOM ) && !rLineOuter.GetBottom())
5795 aBottomInfo.SetValid( SvxBoxInfoItemValidFlags::TOP );
5796
5797 if (pLineInner->IsValid( SvxBoxInfoItemValidFlags::LEFT ) && !rLineOuter.GetLeft())
5798 aLeftInfo.SetValid( SvxBoxInfoItemValidFlags::RIGHT );
5799
5800 if (pLineInner->IsValid( SvxBoxInfoItemValidFlags::RIGHT ) && !rLineOuter.GetRight())
5801 aRightInfo.SetValid( SvxBoxInfoItemValidFlags::LEFT );
5802
5803 const ScRangeList& rRangeListTopEnvelope = rMark.GetTopEnvelope();
5804 const ScRangeList& rRangeListBottomEnvelope = rMark.GetBottomEnvelope();
5805 const ScRangeList& rRangeListLeftEnvelope = rMark.GetLeftEnvelope();
5806 const ScRangeList& rRangeListRightEnvelope = rMark.GetRightEnvelope();
5807
5808 for (const auto& rTab : rMark)
5809 {
5810 if (rTab >= nMax)
5811 break;
5812
5813 if ( maTabs[rTab] )
5814 {
5815 size_t nEnvelopeRangeCount = rRangeListTopEnvelope.size();
5816 for ( size_t j=0; j < nEnvelopeRangeCount; j++ )
5817 {
5818 const ScRange & rRange = rRangeListTopEnvelope[ j ];
5819 maTabs[rTab]->ApplyBlockFrame( aTop, &aTopInfo,
5820 rRange.aStart.Col(), rRange.aStart.Row(),
5821 rRange.aEnd.Col(), rRange.aEnd.Row() );
5822 }
5823 nEnvelopeRangeCount = rRangeListBottomEnvelope.size();
5824 for ( size_t j=0; j < nEnvelopeRangeCount; j++ )
5825 {
5826 const ScRange & rRange = rRangeListBottomEnvelope[ j ];
5827 maTabs[rTab]->ApplyBlockFrame( aBottom, &aBottomInfo,
5828 rRange.aStart.Col(), rRange.aStart.Row(),
5829 rRange.aEnd.Col(), rRange.aEnd.Row() );
5830 }
5831 nEnvelopeRangeCount = rRangeListLeftEnvelope.size();
5832 for ( size_t j=0; j < nEnvelopeRangeCount; j++ )
5833 {
5834 const ScRange & rRange = rRangeListLeftEnvelope[ j ];
5835 maTabs[rTab]->ApplyBlockFrame( aLeft, &aLeftInfo,
5836 rRange.aStart.Col(), rRange.aStart.Row(),
5837 rRange.aEnd.Col(), rRange.aEnd.Row() );
5838 }
5839 nEnvelopeRangeCount = rRangeListRightEnvelope.size();
5840 for ( size_t j=0; j < nEnvelopeRangeCount; j++ )
5841 {
5842 const ScRange & rRange = rRangeListRightEnvelope[ j ];
5843 maTabs[rTab]->ApplyBlockFrame( aRight, &aRightInfo,
5844 rRange.aStart.Col(), rRange.aStart.Row(),
5845 rRange.aEnd.Col(), rRange.aEnd.Row() );
5846 }
5847 }
5848 }
5849}
5850
5852 const SvxBoxItem& rLineOuter,
5853 const SvxBoxInfoItem& rLineInner)
5854{
5855 SCTAB nStartTab = rRange.aStart.Tab();
5856 SCTAB nEndTab = rRange.aStart.Tab();
5857 for (SCTAB nTab = nStartTab; nTab <= nEndTab && nTab < GetTableCount(); nTab++)
5858 if (maTabs[nTab])
5859 maTabs[nTab]->ApplyBlockFrame(rLineOuter, &rLineInner,
5860 rRange.aStart.Col(), rRange.aStart.Row(),
5861 rRange.aEnd.Col(), rRange.aEnd.Row());
5862}
5863
5864void ScDocument::ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged )
5865{
5866 const SfxItemSet* pSet = &rAttr.GetItemSet();
5867 bool bSet = false;
5868 sal_uInt16 i;
5869 for (i=ATTR_PATTERN_START; i<=ATTR_PATTERN_END && !bSet; i++)
5870 if (pSet->GetItemState(i) == SfxItemState::SET)
5871 bSet = true;
5872
5873 if (!bSet)
5874 return;
5875
5876 // ApplySelectionCache needs multi mark
5877 if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
5878 {
5879 const ScRange& aRange = rMark.GetMarkArea();
5880 ApplyPatternArea( aRange.aStart.Col(), aRange.aStart.Row(),
5881 aRange.aEnd.Col(), aRange.aEnd.Row(), rMark, rAttr, pDataArray, pIsChanged );
5882 }
5883 else
5884 {
5885 SfxItemPoolCache aCache( mxPoolHelper->GetDocPool(), pSet );
5886 SCTAB nMax = GetTableCount();
5887 for (const auto& rTab : rMark)
5888 {
5889 if (rTab >= nMax)
5890 break;
5891 if (maTabs[rTab])
5892 maTabs[rTab]->ApplySelectionCache( &aCache, rMark, pDataArray, pIsChanged );
5893 }
5894 }
5895}
5896
5897void ScDocument::ChangeSelectionIndent( bool bIncrement, const ScMarkData& rMark )
5898{
5899 SCTAB nMax = GetTableCount();
5900 for (const auto& rTab : rMark)
5901 {
5902 if (rTab >= nMax)
5903 break;
5904 if (maTabs[rTab])
5905 maTabs[rTab]->ChangeSelectionIndent( bIncrement, rMark );
5906 }
5907}
5908
5909void ScDocument::ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData& rMark )
5910{
5911 SCTAB nMax = GetTableCount();
5912 for (const auto& rTab : rMark)
5913 {
5914 if (rTab >= nMax)
5915 break;
5916 if (maTabs[rTab])
5917 maTabs[rTab]->ClearSelectionItems( pWhich, rMark );
5918 }
5919}
5920
5921void ScDocument::DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast )
5922{
5923 sc::AutoCalcSwitch aACSwitch(*this, false);
5924
5925 std::vector<ScAddress> aGroupPos;
5926 // Destroy and reconstruct listeners only if content is affected.
5927 bool bDelContent = ((nDelFlag & ~InsertDeleteFlags::CONTENTS) != nDelFlag);
5928 if (bDelContent)
5929 {
5930 // Record the positions of top and/or bottom formula groups that
5931 // intersect the area borders.
5932 sc::EndListeningContext aCxt(*this);
5933 ScRangeList aRangeList;
5934 rMark.FillRangeListWithMarks( &aRangeList, false);
5935 for (size_t i = 0; i < aRangeList.size(); ++i)
5936 {
5937 const ScRange & rRange = aRangeList[i];
5938 EndListeningIntersectedGroups( aCxt, rRange, &aGroupPos);
5939 }
5941 }
5942
5943 SCTAB nMax = GetTableCount();
5944 for (const auto& rTab : rMark)
5945 {
5946 if (rTab >= nMax)
5947 break;
5948 if (maTabs[rTab])
5949 maTabs[rTab]->DeleteSelection(nDelFlag, rMark, bBroadcast);
5950 }
5951
5952 if (!bDelContent)
5953 return;
5954
5955 // Re-start listeners on those top bottom groups that have been split.
5956 SetNeedsListeningGroups(aGroupPos);
5958
5959 // If formula groups were split their listeners were destroyed and may
5960 // need to be notified now that they're restored,
5961 // ScTable::DeleteSelection() couldn't do that.
5962 if (aGroupPos.empty())
5963 return;
5964
5965 ScRangeList aRangeList;
5966 rMark.FillRangeListWithMarks( &aRangeList, false);
5967 for (size_t i = 0; i < aRangeList.size(); ++i)
5968 {
5969 SetDirty( aRangeList[i], true);
5970 }
5971 //Notify listeners on top and bottom of the group that has been split
5972 for (size_t i = 0; i < aGroupPos.size(); ++i) {
5973 ScFormulaCell *pFormulaCell = GetFormulaCell(aGroupPos[i]);
5974 if (pFormulaCell)
5975 pFormulaCell->SetDirty(true);
5976 }
5977}
5978
5980 SCTAB nTab, InsertDeleteFlags nDelFlag, const ScMarkData& rMark )
5981{
5982 if (ScTable* pTable = FetchTable(nTab))
5983 {
5984 sc::AutoCalcSwitch aACSwitch(*this, false);
5985
5986 std::vector<ScAddress> aGroupPos;
5987 // Destroy and reconstruct listeners only if content is affected.
5988 bool bDelContent = ((nDelFlag & ~InsertDeleteFlags::CONTENTS) != nDelFlag);
5989 if (bDelContent)
5990 {
5991 // Record the positions of top and/or bottom formula groups that
5992 // intersect the area borders.
5993 sc::EndListeningContext aCxt(*this);
5994 ScRangeList aRangeList;
5995 rMark.FillRangeListWithMarks( &aRangeList, false);
5996 for (size_t i = 0; i < aRangeList.size(); ++i)
5997 {
5998 const ScRange & rRange = aRangeList[i];
5999 if (rRange.aStart.Tab() <= nTab && nTab <= rRange.aEnd.Tab())
6000 {
6001 ScRange aRange( rRange);
6002 aRange.aStart.SetTab( nTab);
6003 aRange.aEnd.SetTab( nTab);
6004 EndListeningIntersectedGroups( aCxt, aRange, &aGroupPos);
6005 }
6006 }
6008 }
6009
6010 pTable->DeleteSelection(nDelFlag, rMark);
6011
6012 if (bDelContent)
6013 {
6014 // Re-start listeners on those top bottom groups that have been split.
6015 SetNeedsListeningGroups(aGroupPos);
6017
6018 // If formula groups were split their listeners were destroyed and may
6019 // need to be notified now that they're restored,
6020 // ScTable::DeleteSelection() couldn't do that.
6021 if (!aGroupPos.empty())
6022 {
6023 ScRangeList aRangeList;
6024 rMark.FillRangeListWithMarks( &aRangeList, false);
6025 for (size_t i = 0; i < aRangeList.size(); ++i)
6026 {
6027 const ScRange & rRange = aRangeList[i];
6028 if (rRange.aStart.Tab() <= nTab && nTab <= rRange.aEnd.Tab())
6029 {
6030 ScRange aRange( rRange);
6031 aRange.aStart.SetTab( nTab);
6032 aRange.aEnd.SetTab( nTab);
6033 SetDirty( aRange, true);
6034 }
6035 }
6036 }
6037 }
6038 }
6039 else
6040 {
6041 OSL_FAIL("wrong table");
6042 }
6043}
6044
6046{
6047 return const_cast<ScPatternAttr*>(&mxPoolHelper->GetDocPool()->GetDefaultItem(ATTR_PATTERN));
6048}
6049
6051{
6052 return mxPoolHelper ? mxPoolHelper->GetDocPool() : nullptr;
6053}
6054
6056{
6057 return mxPoolHelper ? mxPoolHelper->GetStylePool() : nullptr;
6058}
6059
6060bool ScDocument::IsEmptyData(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
6061{
6062 if (const ScTable* pTable = FetchTable(nTab))
6063 return pTable->IsEmptyData(nStartCol, nStartRow, nEndCol, nEndRow);
6064 return true;
6065}
6066
6068 SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, ScDirection eDir )
6069{
6070 PutInOrder(nStartCol, nEndCol);
6071 PutInOrder(nStartRow, nEndRow);
6072 PutInOrder(nStartTab, nEndTab);
6073 if (ScTable* pTable = FetchTable(nStartTab))
6074 return pTable->GetEmptyLinesInBlock(nStartCol, nStartRow, nEndCol, nEndRow, eDir);
6075 return 0;
6076}
6077
6078void ScDocument::FindAreaPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, ScMoveDirection eDirection ) const
6079{
6080 if (const ScTable* pTable = FetchTable(nTab))
6081 pTable->FindAreaPos(rCol, rRow, eDirection);
6082}
6083
6084void ScDocument::GetNextPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, SCCOL nMovX, SCROW nMovY,
6085 bool bMarked, bool bUnprotected, const ScMarkData& rMark, SCCOL nTabStartCol ) const
6086{
6087 OSL_ENSURE( !nMovX || !nMovY, "GetNextPos: only X or Y" );
6088
6089 ScMarkData aCopyMark = rMark;
6090 aCopyMark.SetMarking(false);
6091 aCopyMark.MarkToMulti();
6092
6093 if (const ScTable* pTable = FetchTable(nTab))
6094 pTable->GetNextPos(rCol, rRow, nMovX, nMovY, bMarked, bUnprotected, aCopyMark, nTabStartCol);
6095}
6096
6097// Data operations
6098
6100{
6101 ScDocumentPool* pPool = mxPoolHelper->GetDocPool();
6102
6103 for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(ATTR_PATTERN))
6104 {
6105 auto pPattern = const_cast<ScPatternAttr*>(dynamic_cast<const ScPatternAttr*>(pItem));
6106 if (pPattern)
6107 pPattern->UpdateStyleSheet(*this);
6108 }
6109 const_cast<ScPatternAttr&>(pPool->GetDefaultItem(ATTR_PATTERN)).UpdateStyleSheet(*this);
6110}
6111
6113{
6114 ScDocumentPool* pPool = mxPoolHelper->GetDocPool();
6115
6116 for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(ATTR_PATTERN))
6117 {
6118 auto pPattern = const_cast<ScPatternAttr*>(dynamic_cast<const ScPatternAttr*>(pItem));
6119 if (pPattern)
6120 pPattern->StyleToName();
6121 }
6122 const_cast<ScPatternAttr&>(pPool->GetDefaultItem(ATTR_PATTERN)).StyleToName();
6123}
6124
6126{
6127 sal_uInt64 nCellCount = 0;
6128
6129 for (const auto& a : maTabs)
6130 {
6131 if (a)
6132 nCellCount += a->GetCellCount();
6133 }
6134
6135 return nCellCount;
6136}
6137
6139{
6140 sal_uInt64 nFormulaGroupCount = 0;
6141
6142 ScFormulaGroupIterator aIter( *const_cast<ScDocument*>(this) );
6143 for ( sc::FormulaGroupEntry* ptr = aIter.first(); ptr; ptr = aIter.next())
6144 {
6145 nFormulaGroupCount++;
6146 }
6147
6148 return nFormulaGroupCount;
6149}
6150
6152{
6153 sal_uInt64 nCodeCount = 0;
6154
6155 for (const auto& a : maTabs)
6156 {
6157 if (a)
6158 nCodeCount += a->GetCodeCount();
6159 }
6160
6161 return nCodeCount;
6162}
6163
6164void ScDocument::PageStyleModified( SCTAB nTab, const OUString& rNewName )
6165{
6166 if (ScTable* pTable = FetchTable(nTab))
6167 pTable->PageStyleModified( rNewName );
6168}
6169
6170void ScDocument::SetPageStyle( SCTAB nTab, const OUString& rName )
6171{
6172 if (ScTable* pTable = FetchTable(nTab))
6173 pTable->SetPageStyle( rName );
6174}
6175
6176OUString ScDocument::GetPageStyle( SCTAB nTab ) const
6177{
6178 if (const ScTable* pTable = FetchTable(nTab))
6179 return pTable->GetPageStyle();
6180 return OUString();
6181}
6182
6183void ScDocument::SetPageSize( SCTAB nTab, const Size& rSize )
6184{
6185 if (ScTable* pTable = FetchTable(nTab))
6186 pTable->SetPageSize( rSize );
6187}
6188
6190{
6191 if (const ScTable* pTable = FetchTable(nTab))
6192 return pTable->GetPageSize();
6193
6194 OSL_FAIL("invalid tab");
6195 return Size();
6196}
6197
6198void ScDocument::SetRepeatArea( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow )
6199{
6200 if (ScTable* pTable = FetchTable(nTab))
6201 pTable->SetRepeatArea( nStartCol, nEndCol, nStartRow, nEndRow );
6202}
6203
6205{
6206 if (ScTable* pTable = FetchTable(nTab))
6207 pTable->InvalidatePageBreaks();
6208}
6209
6210void ScDocument::UpdatePageBreaks( SCTAB nTab, const ScRange* pUserArea )
6211{
6212 if (ScTable* pTable = FetchTable(nTab))
6213 pTable->UpdatePageBreaks( pUserArea );
6214}
6215
6217{
6218 if (ScTable* pTable = FetchTable(nTab))
6219 pTable->RemoveManualBreaks();
6220}
6221
6223{
6224 if (const ScTable* pTable = FetchTable(nTab))
6225 return pTable->HasManualBreaks();
6226
6227 OSL_FAIL("invalid tab");
6228 return false;
6229}
6230
6232{
6233 rDocStat.nTableCount = GetTableCount();
6234 rDocStat.aDocName = aDocName;
6236 rDocStat.nCellCount = GetCellCount();
6237}
6238
6240{
6241 bool bResult = false;
6242
6243 for (const auto& a : maTabs)
6244 {
6245 if (!a)
6246 continue;
6247 bResult = a->IsPrintEntireSheet() || (a->GetPrintRangeCount() > 0);
6248 if (bResult)
6249 break;
6250 }
6251
6252 return bResult;
6253}
6254
6256{
6257 const ScTable* pTable = FetchTable(nTab);
6258 return (pTable && pTable->IsPrintEntireSheet());
6259}
6260
6262{
6263 if (ScTable* pTable = FetchTable(nTab))
6264 return pTable->GetPrintRangeCount();
6265 return 0;
6266}
6267
6268const ScRange* ScDocument::GetPrintRange( SCTAB nTab, sal_uInt16 nPos )
6269{
6270 if (ScTable* pTable = FetchTable(nTab))
6271 return pTable->GetPrintRange(nPos);
6272
6273 return nullptr;
6274}
6275
6276std::optional<ScRange> ScDocument::GetRepeatColRange( SCTAB nTab )
6277{
6278 if (ScTable* pTable = FetchTable(nTab))
6279 return pTable->GetRepeatColRange();
6280
6281 return std::nullopt;
6282}
6283
6284std::optional<ScRange> ScDocument::GetRepeatRowRange( SCTAB nTab )
6285{
6286 if (ScTable* pTable = FetchTable(nTab))
6287 return pTable->GetRepeatRowRange();
6288 return std::nullopt;
6289}
6290
6292{
6293 if (ScTable* pTable = FetchTable(nTab))
6294 pTable->ClearPrintRanges();
6295}
6296
6297void ScDocument::AddPrintRange( SCTAB nTab, const ScRange& rNew )
6298{
6299 if (ScTable* pTable = FetchTable(nTab))
6300 pTable->AddPrintRange(rNew);
6301}
6302
6304{
6305 if (ScTable* pTable = FetchTable(nTab))
6306 pTable->SetPrintEntireSheet();
6307}
6308
6309void ScDocument::SetRepeatColRange( SCTAB nTab, std::optional<ScRange> oNew )
6310{
6311 if (ScTable* pTable = FetchTable(nTab))
6312 pTable->SetRepeatColRange(std::move(oNew));
6313}
6314
6315void ScDocument::SetRepeatRowRange( SCTAB nTab, std::optional<ScRange> oNew )
6316{
6317 if (ScTable* pTable = FetchTable(nTab))
6318 pTable->SetRepeatRowRange(std::move(oNew));
6319}
6320
6321std::unique_ptr<ScPrintRangeSaver> ScDocument::CreatePrintRangeSaver() const
6322{
6323 const SCTAB nCount = GetTableCount();
6324 std::unique_ptr<ScPrintRangeSaver> pNew(new ScPrintRangeSaver( nCount ));
6325 for (SCTAB i=0; i<nCount; i++)
6326 if (maTabs[i])
6327 maTabs[i]->FillPrintSaver( pNew->GetTabData(i) );
6328 return pNew;
6329}
6330
6332{
6333 const SCTAB nCount = rSaver.GetTabCount();
6334 const SCTAB maxIndex = std::min(nCount, GetTableCount());
6335 for (SCTAB i=0; i<maxIndex; i++)
6336 if (maTabs[i])
6337 maTabs[i]->RestorePrintRanges( rSaver.GetTabData(i) );
6338}
6339
6341{
6342 // The page number count restarts at a sheet, if another template is set at
6343 // the preceding one (only compare names) and if a pagenumber is specified (not 0)
6344
6345 if (nTab + 1 < GetTableCount() && maTabs[nTab] && maTabs[nTab+1])
6346 {
6347 const OUString & rNew = maTabs[nTab+1]->GetPageStyle();
6348 if ( rNew != maTabs[nTab]->GetPageStyle() )
6349 {
6350 SfxStyleSheetBase* pStyle = mxPoolHelper->GetStylePool()->Find( rNew, SfxStyleFamily::Page );
6351 if ( pStyle )
6352 {
6353 const SfxItemSet& rSet = pStyle->GetItemSet();
6354 sal_uInt16 nFirst = rSet.Get(ATTR_PAGE_FIRSTPAGENO).GetValue();
6355 if ( nFirst != 0 )
6356 return true; // Specify page number in new template
6357 }
6358 }
6359 }
6360
6361 return false; // otherwise not
6362}
6363
6365{
6366 if (!mpUndoManager)
6367 {
6368 // to support enhanced text edit for draw objects, use an SdrUndoManager
6370
6371 ScUndoManager* pUndoManager = new ScUndoManager;
6372 pUndoManager->SetDocShell(GetDocumentShell());
6373 mpUndoManager = pUndoManager;
6374 }
6375
6376 return mpUndoManager;
6377}
6378
6380{
6381 if (HasTable(nTab))
6382 return new ScRowBreakIterator(maTabs[nTab]->maRowPageBreaks);
6383 return nullptr;
6384}
6385
6387{
6388 maSubTotalCells.insert(pCell);
6389}
6390
6392{
6393 maSubTotalCells.erase(pCell);
6394}
6395
6396namespace {
6397
6398bool lcl_hasDirtyRange(const ScDocument& rDoc, ScFormulaCell* pCell, const ScRange& rDirtyRange)
6399{
6400 ScDetectiveRefIter aRefIter(rDoc, pCell);
6401 ScRange aRange;
6402 while (aRefIter.GetNextRef(aRange))
6403 {
6404 if (aRange.Intersects(rDirtyRange))
6405 return true;
6406 }
6407 return false;
6408}
6409
6410}
6411
6413{
6414 // to update the list by skipping cells that no longer contain subtotal function.
6415 set<ScFormulaCell*> aNewSet;
6416
6417 bool bOldRecalc = GetAutoCalc();
6418 SetAutoCalc(false);
6419 for (ScFormulaCell* pCell : maSubTotalCells)
6420 {
6421 if (pCell->IsSubTotal())
6422 {
6423 aNewSet.insert(pCell);
6424 if (lcl_hasDirtyRange(*this, pCell, rDirtyRange))
6425 pCell->SetDirty();
6426 }
6427 }
6428
6429 SetAutoCalc(bOldRecalc);
6430 maSubTotalCells.swap(aNewSet); // update the list.
6431}
6432
6433sal_uInt16 ScDocument::GetTextWidth( const ScAddress& rPos ) const
6434{
6435 SCTAB nTab = rPos.Tab();
6436 if (const ScTable* pTable = FetchTable(nTab))
6437 return pTable->GetTextWidth(rPos.Col(), rPos.Row());
6438 return 0;
6439}
6440
6442{
6443 SCTAB nTab = rPos.Tab();
6444 if (const ScTable* pTable = FetchTable(nTab))
6445 return pTable->GetScriptType(rPos.Col(), rPos.Row());
6446 return SvtScriptType::NONE;
6447}
6448
6450{
6451 SCTAB nTab = rPos.Tab();
6452 if (ScTable* pTable = FetchTable(nTab))
6453 pTable->SetScriptType(rPos.Col(), rPos.Row(), nType);
6454}
6455
6456void ScDocument::EnableUndo( bool bVal )
6457{
6458 // The undo manager increases lock count every time undo is disabled.
6459 // Because of this, we shouldn't disable undo unless it's currently
6460 // enabled, or else re-enabling it may not actually re-enable undo unless
6461 // the lock count becomes zero.
6462
6463 if (bVal != GetUndoManager()->IsUndoEnabled())
6464 {
6465 GetUndoManager()->EnableUndo(bVal);
6466 if( mpDrawLayer ) mpDrawLayer->EnableUndo(bVal);
6467 }
6468
6469 mbUndoEnabled = bVal;
6470}
6471
6473{
6475}
6476
6478{
6479 if (!mpShell)
6480 return false;
6481
6482 try
6483 {
6484 uno::Reference<script::vba::XVBACompatibility> xVBA(
6485 mpShell->GetBasicContainer(), uno::UNO_QUERY);
6486
6487 return xVBA.is() && xVBA->getVBACompatibilityMode();
6488 }
6489 catch (const lang::NotInitializedException&) {}
6490
6491 return false;
6492}
6493
6494// Sparklines
6495std::shared_ptr<sc::Sparkline> ScDocument::GetSparkline(ScAddress const& rPosition)
6496{
6497 SCTAB nTab = rPosition.Tab();
6498 if (ScTable* pTable = FetchTable(nTab))
6499 return pTable->GetSparkline(rPosition.Col(), rPosition.Row());
6500 return std::shared_ptr<sc::Sparkline>();
6501}
6502
6504{
6505 return bool(GetSparkline(rPosition));
6506}
6507
6508sc::Sparkline* ScDocument::CreateSparkline(ScAddress const& rPosition, std::shared_ptr<sc::SparklineGroup> const& pSparklineGroup)
6509{
6510 SCTAB nTab = rPosition.Tab();
6511 if (ScTable* pTable = FetchTable(nTab))
6512 return pTable->CreateSparkline(rPosition.Col(), rPosition.Row(), pSparklineGroup);
6513 return nullptr;
6514}
6515
6517{
6518 SCTAB nTab = rPosition.Tab();
6519 if (ScTable* pTable = FetchTable(nTab))
6520 return pTable->DeleteSparkline(rPosition.Col(), rPosition.Row());
6521 return false;
6522}
6523
6525{
6526 if (ScTable* pTable = FetchTable(nTab))
6527 return &pTable->GetSparklineList();
6528 return nullptr;
6529}
6530
6532{
6533 std::shared_ptr<sc::SparklineGroup> pSparklineGroup;
6534 return GetSparklineGroupInRange(rRange, pSparklineGroup);
6535}
6536
6537bool ScDocument::GetSparklineGroupInRange(ScRange const& rRange, std::shared_ptr<sc::SparklineGroup>& rGroup)
6538{
6539 std::shared_ptr<sc::SparklineGroup> pFoundGroup;
6540 SCTAB nTab = rRange.aStart.Tab();
6541
6542 for (SCCOL nX = rRange.aStart.Col(); nX <= rRange.aEnd.Col(); nX++)
6543 {
6544 for (SCROW nY = rRange.aStart.Row(); nY <= rRange.aEnd.Row(); nY++)
6545 {
6546 auto pSparkline = GetSparkline(ScAddress(nX, nY, nTab));
6547 if (!pSparkline)
6548 {
6549 return false;
6550 }
6551 else if (!pFoundGroup)
6552 {
6553 pFoundGroup = pSparkline->getSparklineGroup();
6554 }
6555 else if (pFoundGroup != pSparkline->getSparklineGroup())
6556 {
6557 return false;
6558 }
6559 }
6560 }
6561
6562 rGroup = pFoundGroup;
6563 return true;
6564}
6565
6566std::shared_ptr<sc::SparklineGroup> ScDocument::SearchSparklineGroup(tools::Guid const& rGuid)
6567{
6568 for (auto const& rTable : maTabs)
6569 {
6570 if (!rTable)
6571 continue;
6572
6573 auto& rSparklineList = rTable->GetSparklineList();
6574
6575 for (auto const& pSparklineGroup : rSparklineList.getSparklineGroups())
6576 {
6577 if (pSparklineGroup->getID() == rGuid)
6578 return pSparklineGroup;
6579 }
6580 }
6581
6582 return std::shared_ptr<sc::SparklineGroup>();
6583}
6584
6585// Notes
6586
6588{
6589 return GetNote(rPos.Col(), rPos.Row(), rPos.Tab());
6590}
6591
6593{
6594 if (ScTable* pTable = FetchTable(nTab))
6595 return pTable->GetNote(nCol, nRow);
6596 return nullptr;
6597}
6598
6599void ScDocument::SetNote(const ScAddress& rPos, std::unique_ptr<ScPostIt> pNote)
6600{
6601 return SetNote(rPos.Col(), rPos.Row(), rPos.Tab(), std::move(pNote));
6602}
6603
6604void ScDocument::SetNote(SCCOL nCol, SCROW nRow, SCTAB nTab, std::unique_ptr<ScPostIt> pNote)
6605{
6606 if (ScTable* pTable = FetchTable(nTab))
6607 {
6608 pTable->SetNote(nCol, nRow, std::move(pNote));
6609
6610 if (ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(GetDocumentShell()))
6611 {
6613 *pDocSh, ScRange(nCol, nRow, nTab), "note");
6614 }
6615 }
6616}
6617
6618bool ScDocument::HasNote(const ScAddress& rPos) const
6619{
6620 return HasNote(rPos.Col(), rPos.Row(), rPos.Tab());
6621}
6622
6623bool ScDocument::HasNote(SCCOL nCol, SCROW nRow, SCTAB nTab) const
6624{
6625 if (!ValidColRow(nCol, nRow))
6626 return false;
6627
6628 const ScTable* pTab = FetchTable(nTab);
6629 if (!pTab)
6630 return false;
6631
6632 if (nCol >= pTab->GetAllocatedColumnsCount())
6633 return false;
6634
6635 const ScPostIt* pNote = pTab->aCol[nCol].GetCellNote(nRow);
6636 return pNote != nullptr;
6637}
6638
6639bool ScDocument::HasNote(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow) const
6640{
6641 if (const ScTable* pTable = FetchTable(nTab))
6642 {
6643 nStartCol = pTable->ClampToAllocatedColumns(nStartCol);
6644 nEndCol = pTable->ClampToAllocatedColumns(nEndCol);
6645 for (SCCOL nCol = nStartCol; nCol < nEndCol; ++nCol)
6646 if (pTable->aCol[nCol].HasCellNote(nStartRow, nEndRow))
6647 return true;
6648 }
6649 return false;
6650}
6651
6653{
6654 if (!ValidCol(nCol))
6655 return false;
6656
6657 if (const ScTable* pTable = FetchTable(nTab))
6658 {
6659 if (nCol >= pTable->GetAllocatedColumnsCount())
6660 return false;
6661
6662 return pTable->aCol[nCol].HasCellNotes();
6663 }
6664
6665 return false;
6666}
6667
6669{
6670 if (const ScTable* pTable = FetchTable(nTab))
6671 {
6672 for (SCCOL nCol=0, nColSize = pTable->aCol.size(); nCol < nColSize; ++nCol)
6673 if ( HasColNotes(nCol, nTab) )
6674 return true;
6675 }
6676 return false;
6677}
6678
6680{
6681 for (SCTAB i = 0; i <= MAXTAB; ++i)
6682 {
6683 if (HasTabNotes(i))
6684 return true;
6685 }
6686 return false;
6687}
6688
6689std::unique_ptr<ScPostIt> ScDocument::ReleaseNote(const ScAddress& rPos)
6690{
6691 if (ScTable* pTable = FetchTable(rPos.Tab()))
6692 return pTable->ReleaseNote(rPos.Col(), rPos.Row());
6693 return nullptr;
6694}
6695
6697{
6698 if (HasNote(rPos))
6699 return GetNote(rPos);
6700 else
6701 return CreateNote(rPos);
6702}
6703
6705{
6706 ScPostIt* pPostIt = new ScPostIt(*this, rPos);
6707 SetNote(rPos, std::unique_ptr<ScPostIt>(pPostIt));
6708 return pPostIt;
6709}
6710
6711size_t ScDocument::GetNoteCount( SCTAB nTab, SCCOL nCol ) const
6712{
6713 if (const ScTable* pTable = FetchTable(nTab))
6714 return pTable->GetNoteCount(nCol);
6715 return 0;
6716}
6717
6719{
6720 for (const auto& pTable : maTabs)
6721 {
6722 if (pTable)
6723 pTable->CreateAllNoteCaptions();
6724 }
6725}
6726
6727void ScDocument::ForgetNoteCaptions( const ScRangeList& rRanges, bool bPreserveData )
6728{
6729 for (size_t i = 0, n = rRanges.size(); i < n; ++i)
6730 {
6731 const ScRange & rRange = rRanges[i];
6732 const ScAddress& s = rRange.aStart;
6733 const ScAddress& e = rRange.aEnd;
6734 for (SCTAB nTab = s.Tab(); nTab <= e.Tab(); ++nTab)
6735 {
6736 if (ScTable* pTable = FetchTable(nTab))
6737 pTable->ForgetNoteCaptions(s.Col(), s.Row(), e.Col(), e.Row(), bPreserveData);
6738 }
6739 }
6740}
6741
6743{
6746 bool bFirstControl = true;
6747 std::vector<sc::NoteEntry> aNotes;
6748
6749 for (size_t i = 0, n = rRanges.size(); i < n; ++i)
6750 {
6751 const ScRange & rRange = rRanges[i];
6752
6753 for( SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab )
6754 {
6755 aState = maTabs[nTab]->GetAllNoteCaptionsState( rRange, aNotes );
6756
6757 if (aState == CommentCaptionState::MIXED)
6758 return aState;
6759
6760 if (bFirstControl) // it is possible that a range is ALLSHOWN, another range is ALLHIDDEN,
6761 { // we have to detect that situation as mixed.
6762 aTmpState = aState;
6763 bFirstControl = false;
6764 }
6765 else if(aTmpState != aState)
6766 {
6768 return aState;
6769 }
6770 }
6771 }
6772 return aState;
6773}
6774
6776{
6777 for (size_t nTab = 0; nTab < maTabs.size(); ++nTab)
6778 {
6779 for (SCCOL nCol : GetAllocatedColumnsRange(nTab, 0, MaxCol()))
6780 {
6781 size_t nColNoteCount = GetNoteCount(nTab, nCol);
6782 if (!nColNoteCount)
6783 continue;
6784
6785 if (nIndex >= nColNoteCount)
6786 {
6787 nIndex -= nColNoteCount;
6788 continue;
6789 }
6790
6791 SCROW nRow = GetNotePosition(nTab, nCol, nIndex);
6792 if (nRow >= 0)
6793 return ScAddress(nCol, nRow, nTab);
6794
6795 OSL_FAIL("note not found");
6797 }
6798 }
6799
6800 OSL_FAIL("note not found");
6802}
6803
6804ScAddress ScDocument::GetNotePosition( size_t nIndex, SCTAB nTab ) const
6805{
6806 for (SCCOL nCol : GetAllocatedColumnsRange(nTab, 0, MaxCol()))
6807 {
6808 size_t nColNoteCount = GetNoteCount(nTab, nCol);
6809 if (!nColNoteCount)
6810 continue;
6811
6812 if (nIndex >= nColNoteCount)
6813 {
6814 nIndex -= nColNoteCount;
6815 continue;
6816 }
6817
6818 SCROW nRow = GetNotePosition(nTab, nCol, nIndex);
6819 if (nRow >= 0)
6820 return ScAddress(nCol, nRow, nTab);
6821
6822 OSL_FAIL("note not found");
6824 }
6825
6826 OSL_FAIL("note not found");
6828}
6829
6830SCROW ScDocument::GetNotePosition( SCTAB nTab, SCCOL nCol, size_t nIndex ) const
6831{
6832 if (const ScTable* pTable = FetchTable(nTab))
6833 return pTable->GetNotePosition(nCol, nIndex);
6834 return -1;
6835}
6836
6837void ScDocument::GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const
6838{
6839 for (const auto & pTable : maTabs)
6840 {
6841 if (pTable)
6842 pTable->GetAllNoteEntries(rNotes);
6843 }
6844}
6845
6846void ScDocument::GetAllNoteEntries( SCTAB nTab, std::vector<sc::NoteEntry>& rNotes ) const
6847{
6848 if (const ScTable* pTable = FetchTable(nTab))
6849 pTable->GetAllNoteEntries(rNotes);
6850}
6851
6852void ScDocument::GetNotesInRange( const ScRangeList& rRangeList, std::vector<sc::NoteEntry>& rNotes ) const
6853{
6854 for( size_t i = 0; i < rRangeList.size(); ++i)
6855 {
6856 const ScRange & rRange = rRangeList[i];
6857 for( SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab )
6858 {
6859 maTabs[nTab]->GetNotesInRange( rRange, rNotes );
6860 }
6861 }
6862}
6863
6865{
6866 if (const ScTable* pTable = FetchTable(nTab))
6867 pTable->GetUnprotectedCells(rRangeList);
6868}
6869
6870bool ScDocument::ContainsNotesInRange( const ScRangeList& rRangeList ) const
6871{
6872 for( size_t i = 0; i < rRangeList.size(); ++i)
6873 {
6874 const ScRange & rRange = rRangeList[i];
6875 for( SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab )
6876 {
6877 bool bContainsNote = maTabs[nTab]->ContainsNotesInRange( rRange );
6878 if(bContainsNote)
6879 return true;
6880 }
6881 }
6882
6883 return false;
6884}
6885
6886void ScDocument::SetAutoNameCache( std::unique_ptr<ScAutoNameCache> pCache )
6887{
6888 pAutoNameCache = std::move(pCache);
6889}
6890
6892
6894{
6896 {
6898 maNonThreaded.xRecursionHelper = std::make_unique<ScRecursionHelper>();
6900 }
6901 else
6902 {
6904 maThreadSpecific.xRecursionHelper = std::make_unique<ScRecursionHelper>();
6906 }
6907}
6908
6909void ScDocument::SetupContextFromNonThreadedContext(ScInterpreterContext& /*threadedContext*/, int /*threadNumber*/)
6910{
6911 (void)this;
6912 // lookup cache is now only in pooled ScInterpreterContext's
6913}
6914
6916{
6917 // Move data from a context used by a calculation thread to the main thread's context.
6918 // Called from the main thread after the calculation thread has already finished.
6922 std::make_move_iterator(threadedContext.maDelayedSetNumberFormat.begin()),
6923 std::make_move_iterator(threadedContext.maDelayedSetNumberFormat.end()));
6924 // lookup cache is now only in pooled ScInterpreterContext's
6925}
6926
6927/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool ValidTab(SCTAB nTab)
Definition: address.hxx:111
const SCTAB MAXTAB
Definition: address.hxx:70
const SCTAB SC_TAB_APPEND
Definition: address.hxx:90
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:150
#define SC_LINE_DONTCARE
Definition: attarray.hxx:48
bool ScHasPriority(const ::editeng::SvxBorderLine *pThis, const ::editeng::SvxBorderLine *pOther)
General Help Function.
Definition: attrib.cxx:49
ScMF
Definition: attrib.hxx:34
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
std::unique_ptr< EditTextObject > CreateTextObject()
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
SCTAB Tab() const
Definition: address.hxx:283
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SCROW Row() const
Definition: address.hxx:274
void SetInvalid()
Definition: address.hxx:299
void SetRow(SCROW nRowP)
Definition: address.hxx:287
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
@ INITIALIZE_INVALID
Definition: address.hxx:221
SCCOL Col() const
Definition: address.hxx:279
bool Search(SCROW nRow, SCSIZE &nIndex) const
Definition: attarray.cxx:194
SCSIZE Count() const
Definition: attarray.hxx:226
std::vector< ScAttrEntry > mvData
Definition: attarray.hxx:98
Cache for faster lookup of automatic names during CompileXML (during CompileXML, no document content ...
The data type represents bits, manageable by bitwise operations.
std::map< OUString, std::unique_ptr< ScChartListener > > ListenersType
Definition: chartlis.hxx:125
SCTAB GetTab() const
Definition: column.hxx:255
@ BROADCAST_DATA_POSITIONS
broadcast existing cells with position => does AreaBroadcast
Definition: column.hxx:245
@ BROADCAST_BROADCASTERS
broadcast only existing cell broadcasters => no AreaBroadcast of range!
Definition: column.hxx:246
SCCOL GetCol() const
Definition: column.hxx:256
const D & GetValue(A nPos) const
Stores global named database ranges.
Definition: dbdata.hxx:243
const OUString & GetInitTabPrefix() const
Iterator for references in a formula cell.
Definition: formulaiter.hxx:32
const ScPatternAttr * GetNext(SCCOL &rCol, SCROW &rRow1, SCROW &rRow2)
Definition: dociter.cxx:1588
Use this class as a locale variable to merge number formatter from another document,...
Definition: document.hxx:2661
NumFmtMergeHandler(ScDocument &rDoc, const ScDocument &rSrcDoc)
Definition: document.cxx:2446
SC_DLLPUBLIC bool InsertTab(SCTAB nPos, const OUString &rName, bool bExternalDocument=false, bool bUndoDeleteTab=false)
Definition: document.cxx:485
void StartAllListeners()
Definition: documen7.cxx:582
void ResetChanged(const ScRange &rRange)
Definition: document.cxx:4074
SCROW CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4516
void SetEmptyCell(const ScAddress &rPos)
Definition: document.cxx:3471
void TrackFormulas(SfxHintId nHintId=SfxHintId::ScDataChanged)
Definition: documen7.cxx:524
void CompileAll()
Definition: document.cxx:3963
SCROW CountVisibleRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4468
SC_DLLPUBLIC bool SetEditText(const ScAddress &rPos, std::unique_ptr< EditTextObject > pEditText)
This method manages the lifecycle of the passed edit text object.
Definition: document.cxx:3422
SC_DLLPUBLIC bool RemoveFlagsTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, ScMF nFlags)
Definition: document.cxx:4980
const ScStyleSheet * GetSelectionStyle(const ScMarkData &rMark) const
Definition: document.cxx:4875
SC_DLLPUBLIC ScColumnsRange GetWritableColumnsRange(SCTAB nTab, SCCOL nColBegin, SCCOL nColEnd)
Definition: document.cxx:2525
bool bAutoCalc
Definition: document.hxx:487
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4161
void UpdateGrow(const ScRange &rArea, SCCOL nGrowX, SCROW nGrowY)
Definition: documen3.cxx:1143
SC_DLLPUBLIC std::shared_ptr< sc::Sparkline > GetSparkline(ScAddress const &rPosition)
Returns sparkline at the address if it exists.
Definition: document.cxx:6495
SC_DLLPUBLIC void CopyFromClip(const ScRange &rDestRange, const ScMarkData &rMark, InsertDeleteFlags nInsFlag, ScDocument *pRefUndoDoc, ScDocument *pClipDoc, bool bResetCut=true, bool bAsLink=false, bool bIncludeFiltered=true, bool bSkipEmptyCells=false, const ScRangeList *pDestRanges=nullptr)
Paste data from a clipboard document into this document.
Definition: document.cxx:2814
SCROW FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4502
SC_DLLPUBLIC sal_uInt32 GetNumberFormat(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3640
friend class ScTable
Definition: document.hxx:339
SC_DLLPUBLIC void DumpColumnStorage(SCTAB nTab, SCCOL nCol) const
OUString maFileURL
Definition: document.hxx:419
bool IsHorOverlapped(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:5717
SC_DLLPUBLIC bool GetMatrixFormulaRange(const ScAddress &rCellPos, ScRange &rMatrix)
Definition: document.cxx:5416
void UndoToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, InsertDeleteFlags nFlags, bool bMarked, ScDocument &rDestDoc)
Definition: document.cxx:2053
bool RefreshAutoFilter(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab)
Definition: document.cxx:5660
SC_DLLPUBLIC void CreateValidTabNames(std::vector< OUString > &aNames, SCTAB nCount) const
Definition: document.cxx:420
SvtBroadcaster * GetBroadcaster(const ScAddress &rPos)
Definition: document.cxx:2464
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4122
SC_DLLPUBLIC sal_uInt64 GetCellCount() const
Definition: document.cxx:6125
SC_DLLPUBLIC ScPatternAttr * GetDefPattern() const
Definition: document.cxx:6045
SC_DLLPUBLIC double * GetValueCell(const ScAddress &rPos)
Return a pointer to the double value stored in value cell.
Definition: document.cxx:3519
void DeleteBroadcasters(sc::ColumnBlockPosition &rBlockPos, const ScAddress &rTopPos, SCROW nLength)
Definition: document.cxx:2482
bool ValidRow(SCROW nRow) const
Definition: document.hxx:900
void UpdateRefAreaLinks(UpdateRefMode eUpdateRefMode, const ScRange &r, SCCOL nDx, SCROW nDy, SCTAB nDz)
Definition: documen8.cxx:1078
void Clear(bool bFromDestructor=false)
Definition: documen9.cxx:489
CommentCaptionState GetAllNoteCaptionsState(const ScRangeList &rRanges)
Definition: document.cxx:6742
SC_DLLPUBLIC void EnableUserInteraction(bool bVal)
Definition: document.cxx:6472
SC_DLLPUBLIC void SetLayoutRTL(SCTAB nTab, bool bRTL, ScObjectHandling eObjectHandling=ScObjectHandling::RecalcPosMode)
Definition: document.cxx:937
bool HasPartOfMerged(const ScRange &rRange)
Definition: document.cxx:1723
void UpdatePageBreaks(SCTAB nTab, const ScRange *pUserArea=nullptr)
Definition: document.cxx:6210
void ApplyFrameAreaTab(const ScRange &rRange, const SvxBoxItem &rLineOuter, const SvxBoxInfoItem &rLineInner)
Definition: document.cxx:5851
void GetColDefault(SCTAB nTab, SCCOL nCol, SCROW nLastRow, SCROW &nDefault)
Definition: document.cxx:4623
bool CanInsertCol(const ScRange &rRange) const
Definition: document.cxx:1456
SC_DLLPUBLIC ScTable * FetchTable(SCTAB nTab)
Definition: document.cxx:2509
bool HasSelectionData(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Returns true, if there is any data to create a selection list for rPos.
Definition: document.cxx:3781
svl::SharedString GetSharedString(const ScAddress &rPos) const
Definition: document.cxx:3526
SC_DLLPUBLIC bool ExtendMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, SCTAB nTab, bool bRefresh=false)
Definition: document.cxx:5556
void SetNote(const ScAddress &rPos, std::unique_ptr< ScPostIt > pNote)
Definition: document.cxx:6599
void CopyBlockFromClip(sc::CopyFromClipContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rMark, SCCOL nDx, SCROW nDy)
Definition: document.cxx:2635
ScClipParam & GetClipParam()
Definition: document.cxx:2564
SC_DLLPUBLIC tools::Long GetColOffset(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4224
SCROW CopyNonFilteredFromClip(sc::CopyFromClipContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rMark, SCCOL nDx, SCROW &rClipStartRow, SCROW nClipEndRow)
Definition: document.cxx:2736
SC_DLLPUBLIC bool InsertTabs(SCTAB nPos, const std::vector< OUString > &rNames, bool bNamesValid=false)
Definition: document.cxx:573
SC_DLLPUBLIC bool GetTable(const OUString &rName, SCTAB &rTab) const
Definition: document.cxx:244
SC_DLLPUBLIC ScColumnsRange GetAllocatedColumnsRange(SCTAB nTab, SCCOL nColBegin, SCCOL nColEnd) const
Definition: document.cxx:2534
tools::Long GetScaledRowHeight(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, double fScale) const
Definition: document.cxx:4198
std::unique_ptr< ScDBData > mpAnonymousDBData
Definition: document.hxx:402
bool CompileErrorCells(FormulaError nErrCode)
Re-compile formula cells with error.
Definition: document.cxx:4016
SC_DLLPUBLIC void InitDrawLayer(SfxObjectShell *pDocShell=nullptr)
Definition: documen9.cxx:105
SC_DLLPUBLIC bool HasColNotes(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:6652
void SetDetectiveDirty(bool bSet)
Definition: document.hxx:2211
void GetUnprotectedCells(ScRangeList &rRange, SCTAB nTab) const
Definition: document.cxx:6864
SC_DLLPUBLIC bool ValidNewTabName(const OUString &rName) const
Definition: document.cxx:357
SC_DLLPUBLIC void SetColHidden(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bHidden)
Definition: document.cxx:4448
bool ShrinkToDataArea(SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow) const
Shrink a range to only include data area.
Definition: document.cxx:1018
void EnableDelayDeletingBroadcasters(bool set)
If set, cells will not delete their empty broadcasters, avoiding possible extensive mdds vector chang...
Definition: document10.cxx:449
void InvalidatePageBreaks(SCTAB nTab)
Definition: document.cxx:6204
bool IsSelectionEditable(const ScMarkData &rMark, bool *pOnlyNotBecauseOfMatrix=nullptr) const
Definition: document.cxx:5340
ScDocumentThreadSpecific maNonThreaded
Definition: document.hxx:467
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:892
std::unique_ptr< ScDPCollection > pDPCollection
Definition: document.hxx:383
void SetNeedsListeningGroups(const std::vector< ScAddress > &rPosArray)
Definition: document10.cxx:520
SC_DLLPUBLIC const ScValidationData * GetValidationEntry(sal_uInt32 nIndex) const
Definition: documen4.cxx:873
std::vector< ScTableUniquePtr > TableContainer
Definition: document.hxx:347
size_t GetNoteCount(SCTAB nTab, SCCOL nCol) const
Definition: document.cxx:6711
void SharePooledResources(const ScDocument *pSrcDoc)
Definition: document10.cxx:330
SC_DLLPUBLIC SCROW GetLastFlaggedRow(SCTAB nTab) const
Definition: document.cxx:4539
bool HasManualBreaks(SCTAB nTab) const
Definition: document.cxx:6222
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:837
SC_DLLPUBLIC SCROW GetMaxRowCount() const
Definition: document.hxx:895
void AppendTabOnLoad(const OUString &rName)
Definition: document.cxx:453
HardRecalcState GetHardRecalcState() const
Definition: document.hxx:2402
bool HasFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4482
SC_DLLPUBLIC bool RowFiltered(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4475
formula::VectorRefArray FetchVectorRefArray(const ScAddress &rPos, SCROW nLength)
Definition: document.cxx:1763
SC_DLLPUBLIC bool SetOptimalHeight(sc::RowHeightContext &rCxt, SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bApi)
Definition: document.cxx:4267
rtl::Reference< ScPoolHelper > mxPoolHelper
Definition: document.hxx:358
void DiscardFormulaGroupContext()
Definition: document.cxx:3542
SC_DLLPUBLIC void CopyStaticToDocument(const ScRange &rSrcRange, SCTAB nDestTab, ScDocument &rDestDoc)
Copy only raw cell values to another document.
Definition: document.cxx:2214
SC_DLLPUBLIC void AddPrintRange(SCTAB nTab, const ScRange &rNew)
Adds a new print ranges.
Definition: document.cxx:6297
SCROW GetRowForHeight(SCTAB nTab, tools::Long nHeight) const
Given the height i.e.
Definition: document.cxx:4193
void FillTabMarked(SCTAB nSrcTab, const ScMarkData &rMark, InsertDeleteFlags nFlags, ScPasteFunc nFunction, bool bSkipEmpty, bool bAsLink)
Definition: document.cxx:3325
SC_DLLPUBLIC void SetTextCell(const ScAddress &rPos, const OUString &rStr)
Call this if you are not sure whether to put this as an edit text or a simple text.
Definition: document.cxx:3452
ScInterpreterContext maInterpreterContext
Definition: document.hxx:473
static SC_DLLPUBLIC bool ValidTabName(const OUString &rName)
Definition: document.cxx:318
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6050
bool IsCutMode()
Definition: document.cxx:2030
SC_DLLPUBLIC void ApplyPatternAreaTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScPatternAttr &rAttr)
Definition: document.cxx:4770
const SfxPoolItem * GetEffItem(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: documen4.cxx:751
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
const ScStyleSheet * GetStyle(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4868
bool ColFiltered(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:4489
SC_DLLPUBLIC void ClearPrintRanges(SCTAB nTab)
Removes all print ranges.
Definition: document.cxx:6291
SC_DLLPUBLIC void ShowRow(SCROW nRow, SCTAB nTab, bool bShow)
Definition: document.cxx:4303
SC_DLLPUBLIC ScDocument(ScDocumentMode eMode=SCDOCMODE_DOCUMENT, SfxObjectShell *pDocShell=nullptr)
Definition: documen2.cxx:114
SC_DLLPUBLIC ScDBData * GetAnonymousDBData()
Definition: document.cxx:313
std::shared_ptr< sc::FormulaGroupContext > & GetFormulaGroupContext()
Definition: document.cxx:3533
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:483
css::uno::Sequence< css::sheet::TablePageBreakData > GetRowBreakData(SCTAB nTab) const
Definition: document.cxx:4408
SCROW GetLastChangedRowFlagsWidth(SCTAB nTab) const
Definition: document.cxx:4553
void SetTableOpDirty(const ScRange &)
Definition: document.cxx:3862
SC_DLLPUBLIC void CalcAfterLoad(bool bStartListening=true)
Definition: document.cxx:4029
std::vector< ScInterpreterTableOpParams * > m_TableOpList
list of ScInterpreterTableOpParams currently in use
Definition: document.hxx:447
SC_DLLPUBLIC double GetValue(const ScAddress &rPos) const
Definition: document.cxx:3626
SC_DLLPUBLIC std::vector< OUString > GetAllTableNames() const
Definition: document.cxx:270
bool ContainsNotesInRange(const ScRangeList &rRange) const
Definition: document.cxx:6870
void UpdateReference(sc::RefUpdateContext &rCxt, ScDocument *pUndoDoc=nullptr, bool bIncludeDraw=true, bool bUpdateNoteCaptionPos=true)
Definition: documen3.cxx:1008
void BroadcastCells(const ScRange &rRange, SfxHintId nHint, bool bBroadcastSingleBroadcasters=true)
Definition: documen7.cxx:158
SC_DLLPUBLIC ScPostIt * GetNote(const ScAddress &rPos)
Definition: document.cxx:6587
bool mbFormulaGroupCxtBlockDiscard
Definition: document.hxx:364
SC_DLLPUBLIC sc::Sparkline * CreateSparkline(ScAddress const &rPosition, std::shared_ptr< sc::SparklineGroup > const &pSparklineGroup)
Definition: document.cxx:6508
void CompileXML()
Definition: document.cxx:3976
std::unique_ptr< ScAutoNameCache > pAutoNameCache
Definition: document.hxx:429
bool HasClipFilteredRows()
Definition: document.cxx:3216
SCROW GetNextDifferentChangedRowFlagsWidth(SCTAB nTab, SCROW nStart) const
Definition: document.cxx:4580
SC_DLLPUBLIC void TransposeClip(ScDocument *pTransClip, InsertDeleteFlags nFlags, bool bAsLink, bool bIncludeFiltered)
Definition: document.cxx:2295
SC_DLLPUBLIC void SetPrintEntireSheet(SCTAB nTab)
Marks the specified sheet to be printed completely.
Definition: document.cxx:6303
SC_DLLPUBLIC const ScRange * GetPrintRange(SCTAB nTab, sal_uInt16 nPos)
Definition: document.cxx:6268
SC_DLLPUBLIC bool InitColumnBlockPosition(sc::ColumnBlockPosition &rBlockPos, SCTAB nTab, SCCOL nCol)
Definition: document.cxx:2628
SC_DLLPUBLIC void EnableUndo(bool bVal)
Definition: document.cxx:6456
std::unique_ptr< ScPatternAttr > pSelectionAttr
Definition: document.hxx:385
std::unique_ptr< SfxBroadcaster > pUnoBroadcaster
Definition: document.hxx:395
bool IsDelayedDeletingBroadcasters() const
Definition: document.hxx:1439
void PrepareFormulaCalc()
Call this before any operations that might trigger one or more formula cells to get calculated.
Definition: document.cxx:2458
void MergeContextBackIntoNonThreadedContext(ScInterpreterContext &threadedContext, int threadNumber)
Definition: document.cxx:6915
SC_DLLPUBLIC void DeleteSelection(InsertDeleteFlags nDelFlag, const ScMarkData &rMark, bool bBroadcast=true)
Definition: document.cxx:5921
sal_uInt16 GetSheetOptimalMinRowHeight(SCTAB nTab) const
Definition: document.cxx:928
void PageStyleModified(SCTAB nTab, const OUString &rNewName)
Definition: document.cxx:6164
SC_DLLPUBLIC void SetColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
Definition: document.cxx:4390
void AddTableOpFormulaCell(ScFormulaCell *)
Definition: document.cxx:3919
SC_DLLPUBLIC bool IsNegativePage(SCTAB nTab) const
Definition: document.cxx:982
SC_DLLPUBLIC void ApplySelectionStyle(const ScStyleSheet &rStyle, const ScMarkData &rMark)
Definition: document.cxx:4830
SC_DLLPUBLIC bool ApplyFlagsTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, ScMF nFlags)
Definition: document.cxx:4970
SC_DLLPUBLIC SCROW GetLastDataRow(SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCROW nLastRow) const
Return the last non-empty row position in given columns that's no greater than the initial last row p...
Definition: document.cxx:1063
void SetClipArea(const ScRange &rArea, bool bCut=false)
Definition: document.cxx:3132
std::unique_ptr< ScValidationDataList > pValidationList
Definition: document.hxx:376
bool ShrinkToUsedDataArea(bool &o_bShrunk, SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow, bool bColumnsOnly, bool bStickyTopRow=false, bool bStickyLeftCol=false, ScDataAreaExtras *pDataAreaExtras=nullptr) const
Shrink a range to only include used data area.
Definition: document.cxx:1049
SC_DLLPUBLIC ScBreakType HasRowBreak(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4355
ScRangePairListRef xRowNameRanges
Definition: document.hxx:421
ScRowBreakIterator * GetRowBreakIterator(SCTAB nTab) const
Definition: document.cxx:6379
void SetSubTotalCellsDirty(const ScRange &rDirtyRange)
Definition: document.cxx:6412
bool bImportingXML
Definition: document.hxx:505
SC_DLLPUBLIC sal_uInt16 GetOriginalHeight(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4153
void SetTabNameOnLoad(SCTAB nTab, const OUString &rName)
Definition: document.cxx:465
SC_DLLPUBLIC bool DeleteSparkline(ScAddress const &rPosition)
Definition: document.cxx:6516
SC_DLLPUBLIC void SetAutoNameCache(std::unique_ptr< ScAutoNameCache > pCache)
Definition: document.cxx:6886
sal_uInt32 nAdjustHeightLock
Definition: document.hxx:544
void LimitChartArea(SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow)
Definition: document.cxx:1091
void EndListeningGroups(const std::vector< ScAddress > &rPosArray)
Definition: document10.cxx:505
SCROW GetHiddenRowCount(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4216
void SetStreamValid(SCTAB nTab, bool bSet, bool bIgnoreLock=false)
Definition: document.cxx:904
OUString GetCopyTabName(SCTAB nTab) const
Definition: document.cxx:215
void StylesToNames()
Definition: document.cxx:6112
void ReservePatternCount(SCTAB nTab, SCCOL nCol, SCSIZE nReserve)
Definition: documen3.cxx:2118
void FillTab(const ScRange &rSrcArea, const ScMarkData &rMark, InsertDeleteFlags nFlags, ScPasteFunc nFunction, bool bSkipEmpty, bool bAsLink)
Definition: document.cxx:3257
SC_DLLPUBLIC void CopyToClip(const ScClipParam &rClipParam, ScDocument *pClipDoc, const ScMarkData *pMarks, bool bKeepScenarioFlags, bool bIncludeObjects)
Definition: document.cxx:2142
SC_DLLPUBLIC void SetRowHeightRange(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_uInt16 nNewHeight)
Definition: document.cxx:4104
void UpdStlShtPtrsFrmNms()
Definition: document.cxx:6099
void AddSubTotalCell(ScFormulaCell *pCell)
Definition: document.cxx:6386
ScRecursionHelper & GetRecursionHelper()
Definition: document.cxx:6893
bool mbUserInteractionEnabled
Definition: document.hxx:553
SC_DLLPUBLIC void ApplyPattern(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr &rAttr)
Definition: document.cxx:4747
std::unique_ptr< ScDetOpList > pDetOpList
Definition: document.hxx:393
SC_DLLPUBLIC void ShowCol(SCCOL nCol, SCTAB nTab, bool bShow)
Definition: document.cxx:4297
SC_DLLPUBLIC bool GetAutoCalc() const
Definition: document.hxx:1413
SCCOL GetLastChangedColFlagsWidth(SCTAB nTab) const
Definition: document.cxx:4546
SC_DLLPUBLIC bool HasStringData(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3743
void SetCodeName(const OUString &r)
Definition: document.hxx:610
SC_DLLPUBLIC void GetAllNoteEntries(std::vector< sc::NoteEntry > &rNotes) const
Definition: document.cxx:6837
bool IsInVBAMode() const
Definition: document.cxx:6477
SC_DLLPUBLIC const ScPatternAttr * GetMostUsedPattern(SCCOL nCol, SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4734
std::unique_ptr< ScPatternAttr > CreateSelectionPattern(const ScMarkData &rMark, bool bDeep=true)
Definition: document.cxx:5015
SC_DLLPUBLIC void InitUndoSelected(const ScDocument &rSrcDoc, const ScMarkData &rTabSelection, bool bColInfo=false, bool bRowInfo=false)
Definition: document.cxx:1943
bool IsStyleSheetUsed(const ScStyleSheet &rStyle) const
Definition: document.cxx:4938
bool bLoadingMedium
Definition: document.hxx:504
SC_DLLPUBLIC std::unique_ptr< ScPostIt > ReleaseNote(const ScAddress &rPos)
Definition: document.cxx:6689
SC_DLLPUBLIC void SetNumberFormat(const ScAddress &rPos, sal_uInt32 nNumberFormat)
Definition: document.cxx:3682
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: document.cxx:3391
void RestorePrintRanges(const ScPrintRangeSaver &rSaver)
Definition: document.cxx:6331
void ApplySelectionLineStyle(const ScMarkData &rMark, const ::editeng::SvxBorderLine *pLine, bool bColorOnly)
Definition: document.cxx:4852
TableContainer maTabs
Definition: document.hxx:378
SC_DLLPUBLIC bool HasSparkline(ScAddress const &rPosition)
Definition: document.cxx:6503
void EndListeningIntersectedGroups(sc::EndListeningContext &rCxt, const ScRange &rRange, std::vector< ScAddress > *pGroupPos)
Definition: document10.cxx:490
SC_DLLPUBLIC OUString GetPageStyle(SCTAB nTab) const
Definition: document.cxx:6176
bool bIsClip
Definition: document.hxx:494
bool IsStreamValid(SCTAB nTab) const
Definition: document.cxx:897
void LimitChartIfAll(ScRangeListRef &rRangeList)
Definition: document.cxx:1098
SC_DLLPUBLIC void InitUndo(const ScDocument &rSrcDoc, SCTAB nTab1, SCTAB nTab2, bool bColInfo=false, bool bRowInfo=false)
Definition: document.cxx:1975
SC_DLLPUBLIC bool CopyOneCellFromClip(sc::CopyFromClipContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: document10.cxx:83
void CopyRangeNamesToClip(ScDocument *pClipDoc, const ScRange &rClipRange, const ScMarkData *pMarks)
Definition: document.cxx:2427
SC_DLLPUBLIC bool HasPrintRange()
Definition: document.cxx:6239
void DeleteSelectionTab(SCTAB nTab, InsertDeleteFlags nDelFlag, const ScMarkData &rMark)
Definition: document.cxx:5979
SC_DLLPUBLIC void DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rMark, InsertDeleteFlags nDelFlag, bool bBroadcast=true, sc::ColumnSpanSet *pBroadcastSpans=nullptr)
Definition: document.cxx:1859
void SetAllFormulasDirty(const sc::SetFormulaDirtyContext &rCxt)
Definition: document.cxx:3819
void DeleteRow(SCCOL nStartCol, SCTAB nStartTab, SCCOL nEndCol, SCTAB nEndTab, SCROW nStartRow, SCSIZE nSize, ScDocument *pRefUndoDoc=nullptr, bool *pUndoOutline=nullptr, const ScMarkData *pTabMark=nullptr)
Definition: document.cxx:1345
SC_DLLPUBLIC void ExtendTotalMerge(ScRange &rRange) const
Definition: document.cxx:5606
void DelBroadcastAreasInRange(const ScRange &rRange)
Definition: documen7.cxx:215
sal_uInt16 GetCommonWidth(SCCOL nEndCol, SCTAB nTab) const
Definition: document.cxx:4145
FormulaError GetErrCode(const ScAddress &) const
Definition: document.cxx:4066
ScBroadcastAreaSlotMachine * GetBASM() const
Definition: document.hxx:2231
void GetSelectionFrame(const ScMarkData &rMark, SvxBoxItem &rLineOuter, SvxBoxInfoItem &rLineInner)
Definition: document.cxx:5064
SC_DLLPUBLIC ScBreakType HasColBreak(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:4369
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1084
SC_DLLPUBLIC void ApplySelectionPattern(const ScPatternAttr &rAttr, const ScMarkData &rMark, ScEditDataArray *pDataArray=nullptr, bool *pIsChanged=nullptr)
Definition: document.cxx:5864
SC_DLLPUBLIC bool GetHashCode(SCTAB nTab, sal_Int64 &rHashCode) const
Definition: document.cxx:194
SC_DLLPUBLIC void ShowRows(SCROW nRow1, SCROW nRow2, SCTAB nTab, bool bShow)
Definition: document.cxx:4309
SCROW LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4509
bool IsPendingRowHeights(SCTAB nTab) const
Definition: document.cxx:915
sal_uInt16 GetOptimalColWidth(SCCOL nCol, SCTAB nTab, OutputDevice *pDev, double nPPTX, double nPPTY, const Fraction &rZoomX, const Fraction &rZoomY, bool bFormula, const ScMarkData *pMarkData=nullptr, const ScColWidthParam *pParam=nullptr)
Definition: document.cxx:4240
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4416
void ExtendMergeSel(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, const ScMarkData &rMark, bool bRefresh=false)
Definition: document.cxx:5528
SC_DLLPUBLIC void CreateValidTabName(OUString &rName) const
Definition: document.cxx:375
void ExtendHidden(SCCOL &rX1, SCROW &rY1, SCCOL &rX2, SCROW &rY2, SCTAB nTab)
Definition: document.cxx:4676
SC_DLLPUBLIC CRFlags GetRowFlags(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4335
std::unique_ptr< ScChangeTrack > pChangeTrack
Definition: document.hxx:394
SC_DLLPUBLIC std::shared_ptr< sc::SparklineGroup > SearchSparklineGroup(tools::Guid const &rGuid)
Definition: document.cxx:6566
ScAddress GetNotePosition(size_t nIndex) const
Definition: document.cxx:6775
SC_DLLPUBLIC bool HasNote(const ScAddress &rPos) const
Definition: document.cxx:6618
SvNumberFormatterIndexTable * pFormatExchangeList
Definition: document.hxx:377
ScUndoManager * mpUndoManager
Definition: document.hxx:368
SC_DLLPUBLIC void GetAllColBreaks(std::set< SCCOL > &rBreaks, SCTAB nTab, bool bPage, bool bManual) const
Definition: document.cxx:4349
SC_DLLPUBLIC void SetRepeatRowRange(SCTAB nTab, std::optional< ScRange > oNew)
Definition: document.cxx:6315
SC_DLLPUBLIC void SetRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
Definition: document.cxx:4384
void GetNumberFormatInfo(const ScInterpreterContext &rContext, SvNumFormatType &nType, sal_uInt32 &nIndex, const ScAddress &rPos) const
Definition: document.cxx:3690
SC_DLLPUBLIC bool HasAttrib(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, HasAttrFlags nMask) const
Definition: document.cxx:5161
void AddUndoTab(SCTAB nTab1, SCTAB nTab2, bool bColInfo=false, bool bRowInfo=false)
Definition: document.cxx:2000
SC_DLLPUBLIC CRFlags GetColFlags(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:4327
void InvalidateStreamOnSave()
Definition: document.cxx:476
bool IsBlockEditable(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool *pOnlyNotBecauseOfMatrix=nullptr, bool bNoMatrixAtAll=false) const
Definition: document.cxx:5317
@ ETERNAL
CalcAll() without broadcast/notify but setting up new listeners.
static thread_local ScDocumentThreadSpecific maThreadSpecific
Definition: document.hxx:471
void SetDirtyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rMark, InsertDeleteFlags nInsFlag, sc::ColumnSpanSet &rBroadcastSpans)
Definition: document.cxx:2611
SC_DLLPUBLIC bool GetTableArea(SCTAB nTab, SCCOL &rEndCol, SCROW &rEndRow, bool bCalcHiddens=false) const
Definition: document.cxx:1008
SC_DLLPUBLIC OUString GetInputString(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bForceSystemLocale=false) const
Definition: document.cxx:3549
void CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, InsertDeleteFlags nFlags, bool bMarked, ScDocument &rDestDoc, const ScMarkData *pMarks=nullptr, bool bColRowFlags=true)
Definition: document.cxx:2041
SC_DLLPUBLIC void ApplyPatternIfNumberformatIncompatible(const ScRange &rRange, const ScMarkData &rMark, const ScPatternAttr &rPattern, SvNumFormatType nNewType)
Definition: document.cxx:4777
SCSIZE GetPatternCount(SCTAB nTab, SCCOL nCol) const
Definition: documen3.cxx:2103
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3477
void FindAreaPos(SCCOL &rCol, SCROW &rRow, SCTAB nTab, ScMoveDirection eDirection) const
Definition: document.cxx:6078
sal_uInt64 GetXMLImportedFormulaCount() const
Definition: document.hxx:2459
bool bIsUndo
Definition: document.hxx:495
void ApplyStyle(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScStyleSheet &rStyle)
Definition: document.cxx:4802
const OUString & GetCodeName() const
Definition: document.hxx:609
SC_DLLPUBLIC void ApplyPatternArea(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScMarkData &rMark, const ScPatternAttr &rAttr, ScEditDataArray *pDataArray=nullptr, bool *const pIsChanged=nullptr)
Definition: document.cxx:4753
void GetDocStat(ScDocStat &rDocStat)
Definition: document.cxx:6231
void MergeNumberFormatter(const ScDocument &rSrcDoc)
Definition: document.cxx:2548
void ClearSelectionItems(const sal_uInt16 *pWhich, const ScMarkData &rMark)
Definition: document.cxx:5909
bool CanInsertRow(const ScRange &rRange) const
Definition: document.cxx:1167
void SetupContextFromNonThreadedContext(ScInterpreterContext &threadedContext, int threadNumber)
Definition: document.cxx:6909
void ApplySelectionFrame(const ScMarkData &rMark, const SvxBoxItem &rLineOuter, const SvxBoxInfoItem *pLineInner)
Definition: document.cxx:5743
SC_DLLPUBLIC void MakeTable(SCTAB nTab, bool _bNeedsNameCheck=true)
Definition: document.cxx:171
SC_DLLPUBLIC void SetColWidthOnly(SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth)
Definition: document.cxx:4092
bool IsInsertingFromOtherDoc() const
Definition: document.hxx:2224
void FitBlock(const ScRange &rOld, const ScRange &rNew, bool bClear=true)
Definition: document.cxx:1827
void SetPageSize(SCTAB nTab, const Size &rSize)
Definition: document.cxx:6183
void UpdateBroadcastAreas(UpdateRefMode eUpdateRefMode, const ScRange &rRange, SCCOL nDx, SCROW nDy, SCTAB nDz)
Definition: documen7.cxx:590
SC_DLLPUBLIC void ApplyAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, const SfxPoolItem &rAttr)
Definition: document.cxx:4741
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1083
std::vector< OUString > maTabNames
Definition: document.hxx:380
SC_DLLPUBLIC std::optional< ScRange > GetRepeatColRange(SCTAB nTab)
Definition: document.cxx:6276
bool InterpretCellsIfNeeded(const ScRangeList &rRanges)
Definition: document.cxx:3897
SC_DLLPUBLIC bool HasTabNotes(SCTAB nTab) const
Definition: document.cxx:6668
SC_DLLPUBLIC bool HasOneSparklineGroup(ScRange const &rRange)
Definition: document.cxx:6531
std::unique_ptr< ScClipParam > mpClipParam
Definition: document.hxx:408
void ChangeSelectionIndent(bool bIncrement, const ScMarkData &rMark)
Definition: document.cxx:5897
SC_DLLPUBLIC ScStyleSheetPool * GetStyleSheetPool() const
Definition: document.cxx:6055
void GetClipArea(SCCOL &nClipX, SCROW &nClipY, bool bIncludeFiltered)
Definition: document.cxx:3147
void StyleSheetChanged(const SfxStyleSheetBase *pStyleSheet, bool bRemoved, OutputDevice *pDev, double nPPTX, double nPPTY, const Fraction &rZoomX, const Fraction &rZoomY)
Definition: document.cxx:4924
SC_DLLPUBLIC void SetPattern(const ScAddress &, const ScPatternAttr &rAttr)
Definition: document.cxx:5008
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:899
bool GetDataAreaSubrange(ScRange &rRange) const
Returns true if there is a non-empty subrange in the range given as input.
Definition: document.cxx:1079
SC_DLLPUBLIC void ResetClip(ScDocument *pSourceDoc, const ScMarkData *pMarks)
Definition: documen2.cxx:525
SC_DLLPUBLIC void SetRowHeightOnly(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_uInt16 nNewHeight)
Definition: document.cxx:4110
void RemoveEditTextCharAttribs(const ScAddress &rPos, const ScPatternAttr &rAttr)
Definition: document.cxx:3620
SC_DLLPUBLIC void SetRowHidden(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHidden)
Definition: document.cxx:4442
SC_DLLPUBLIC void AddCondFormatData(const ScRangeList &rRange, SCTAB nTab, sal_uInt32 nIndex)
Definition: document.cxx:4790
SC_DLLPUBLIC bool HasValueData(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3750
SC_DLLPUBLIC void GetNextPos(SCCOL &rCol, SCROW &rRow, SCTAB nTab, SCCOL nMovX, SCROW nMovY, bool bMarked, bool bUnprotected, const ScMarkData &rMark, SCCOL nTabStartCol=SC_TABSTART_NONE) const
Definition: document.cxx:6084
SC_DLLPUBLIC const EditTextObject * GetEditText(const ScAddress &rPos) const
Definition: document.cxx:3612
void DeleteBeforeCopyFromClip(sc::CopyFromClipContext &rCxt, const ScMarkData &rMark, sc::ColumnSpanSet &rBroadcastSpans)
Definition: document10.cxx:58
SC_DLLPUBLIC bool NeedPageResetAfterTab(SCTAB nTab) const
Definition: document.cxx:6340
SC_DLLPUBLIC void ExtendOverlapped(SCCOL &rStartCol, SCROW &rStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5466
SC_DLLPUBLIC bool IsManualRowHeight(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4523
bool HasValidationData(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3793
void RemoveSubTotalCell(ScFormulaCell *pCell)
Definition: document.cxx:6391
SC_DLLPUBLIC void GetBorderLines(SCCOL nCol, SCROW nRow, SCTAB nTab, const ::editeng::SvxBorderLine **ppLeft, const ::editeng::SvxBorderLine **ppTop, const ::editeng::SvxBorderLine **ppRight, const ::editeng::SvxBorderLine **ppBottom) const
Definition: document.cxx:5239
sal_uInt16 GetTextWidth(const ScAddress &rPos) const
Definition: document.cxx:6433
bool IsVerOverlapped(SCCOL nCol, SCROW nRow, SCTAB nTab, SCROW *nStartRow=nullptr, SCROW *nEndRow=nullptr) const
Definition: document.cxx:5729
SC_DLLPUBLIC void SetPageStyle(SCTAB nTab, const OUString &rName)
Definition: document.cxx:6170
void DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab, SCCOL nStartCol, SCSIZE nSize, ScDocument *pRefUndoDoc=nullptr, bool *pUndoOutline=nullptr, const ScMarkData *pTabMark=nullptr)
Definition: document.cxx:1570
SC_DLLPUBLIC bool GetCellArea(SCTAB nTab, SCCOL &rEndCol, SCROW &rEndRow) const
Definition: document.cxx:998
SC_DLLPUBLIC OUString GetFormula(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3706
SCCOL GetNextDifferentChangedColFlagsWidth(SCTAB nTab, SCCOL nStart) const
Definition: document.cxx:4560
void SetCutMode(bool bCut)
Definition: document.cxx:2020
SC_DLLPUBLIC void SetRowFlags(SCROW nRow, SCTAB nTab, CRFlags nNewFlags)
Definition: document.cxx:4315
void DeleteAreaLinksOnTab(SCTAB nTab)
Definition: documen8.cxx:1059
SC_DLLPUBLIC SvtScriptType GetScriptType(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScRefCellValue *pCell=nullptr)
Definition: documen6.cxx:132
void SetInsertingFromOtherDoc(bool bVal)
Definition: document.hxx:2223
SC_DLLPUBLIC sc::SparklineList * GetSparklineList(SCTAB nTab)
Definition: document.cxx:6524
bool IsThreadedGroupCalcInProgress() const
Definition: document.hxx:630
SC_DLLPUBLIC std::optional< ScRange > GetRepeatRowRange(SCTAB nTab)
Definition: document.cxx:6284
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:467
bool HasStringCells(const ScRange &rRange) const
Definition: document.cxx:3762
std::unique_ptr< ScDBCollection > pDBCollection
Definition: document.hxx:382
SC_DLLPUBLIC SCROW GetFirstEditTextRow(const ScRange &rRange) const
Definition: document.cxx:3445
void ClearFormulaTree()
Definition: documen7.cxx:440
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:171
SC_DLLPUBLIC ScPostIt * GetOrCreateNote(const ScAddress &rPos)
Definition: document.cxx:6696
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4430
void SkipOverlapped(SCCOL &rCol, SCROW &rRow, SCTAB nTab) const
Definition: document.cxx:5709
void LockStreamValid(bool bLock)
Definition: document.cxx:910
bool mbStreamValidLocked
Definition: document.hxx:552
SC_DLLPUBLIC void SetAutoCalc(bool bNewAutoCalc)
Definition: documen7.cxx:602
void CopyTabToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScDocument *pClipDoc)
Definition: document.cxx:2241
bool bStyleSheetUsageInvalid
Definition: document.hxx:547
bool bCalcingAfterLoad
Definition: document.hxx:506
SC_DLLPUBLIC bool HasHiddenRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4423
void CopyCellToDocument(const ScAddress &rSrcPos, const ScAddress &rDestPos, ScDocument &rDestDoc)
Copy only cell, nothing but cell to another document.
Definition: document.cxx:2230
SC_DLLPUBLIC ScUndoManager * GetUndoManager()
Definition: document.cxx:6364
SC_DLLPUBLIC ScPostIt * CreateNote(const ScAddress &rPos)
Definition: document.cxx:6704
SC_DLLPUBLIC void SetRowHeight(SCROW nRow, SCTAB nTab, sal_uInt16 nNewHeight)
Definition: document.cxx:4098
void ApplyStyleArea(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScMarkData &rMark, const ScStyleSheet &rStyle)
Definition: document.cxx:4808
std::unique_ptr< ScPrintRangeSaver > CreatePrintRangeSaver() const
Definition: document.cxx:6321
SC_DLLPUBLIC bool IsEmptyData(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:6060
SC_DLLPUBLIC SCROW LastVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4461
SC_DLLPUBLIC void DeleteAreaTab(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, InsertDeleteFlags nDelFlag)
Definition: document.cxx:1920
SC_DLLPUBLIC void CalcAll()
Definition: document.cxx:3939
SC_DLLPUBLIC void GetAllRowBreaks(std::set< SCROW > &rBreaks, SCTAB nTab, bool bPage, bool bManual) const
Definition: document.cxx:4343
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
Definition: document.cxx:3505
SC_DLLPUBLIC bool IsVisible(SCTAB nTab) const
Definition: document.cxx:890
SC_DLLPUBLIC bool GetSparklineGroupInRange(ScRange const &rRange, std::shared_ptr< sc::SparklineGroup > &rGroup)
Returns true if the whole range covers one and the same sparkline group and returns the group via out...
Definition: document.cxx:6537
void LockTable(SCTAB nTab)
Definition: document.cxx:5297
void SetPendingRowHeights(SCTAB nTab, bool bSet)
Definition: document.cxx:922
SC_DLLPUBLIC sal_uInt16 GetOriginalWidth(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:4137
void UpdateChartRef(UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCCOL nDx, SCROW nDy, SCTAB nDz)
Definition: documen5.cxx:394
bool bInsertingFromOtherDoc
Definition: document.hxx:503
bool HandleRefArrayForParallelism(const ScAddress &rPos, SCROW nLength, const ScFormulaCellGroupRef &mxGroup)
Definition: document.cxx:1788
void RemoveCondFormatData(const ScRangeList &rRange, SCTAB nTab, sal_uInt32 nIndex)
Definition: document.cxx:4796
SC_DLLPUBLIC void SetManualHeight(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bManual)
Definition: document.cxx:4116
SC_DLLPUBLIC void SetColWidth(SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth)
Definition: document.cxx:4086
SC_DLLPUBLIC const ScFormulaCell * GetFormulaCell(const ScAddress &rPos) const
Definition: document.cxx:3714
void SyncColRowFlags()
Write all column row flags to table's flag data, because not all column row attributes are stored in ...
Definition: document.cxx:4530
SC_DLLPUBLIC CellType GetCellType(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3736
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:974
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
Definition: document.cxx:2502
bool IsBlockEmpty(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5288
void GetNotesInRange(const ScRangeList &rRange, std::vector< sc::NoteEntry > &rNotes) const
Definition: document.cxx:6852
SC_DLLPUBLIC bool DeleteTab(SCTAB nTab)
Definition: document.cxx:654
SC_DLLPUBLIC void SetRepeatColRange(SCTAB nTab, std::optional< ScRange > oNew)
Definition: document.cxx:6309
void ForgetNoteCaptions(const ScRangeList &rRanges, bool bPreserveData)
Definition: document.cxx:6727
SC_DLLPUBLIC void ApplyStyleAreaTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScStyleSheet &rStyle)
Definition: document.cxx:4823
SC_DLLPUBLIC bool DeleteTabs(SCTAB nTab, SCTAB nSheets)
Definition: document.cxx:747
bool IsUndoEnabled() const
Definition: document.hxx:1595
std::unique_ptr< ScDrawLayer > mpDrawLayer
Definition: document.hxx:374
void CopyMultiRangeFromClip(const ScAddress &rDestPos, const ScMarkData &rMark, InsertDeleteFlags nInsFlag, ScDocument *pClipDoc, bool bResetCut=true, bool bAsLink=false, bool bIncludeFiltered=true, bool bSkipAttrForEmpty=false)
Definition: document.cxx:3032
SfxObjectShell * mpShell
Definition: document.hxx:371
SC_DLLPUBLIC sal_uInt16 GetPrintRangeCount(SCTAB nTab)
Definition: document.cxx:6261
bool IsPrintEntireSheet(SCTAB nTab) const
Returns true, if the specified sheet is always printed.
Definition: document.cxx:6255
void SetDirty(const ScRange &, bool bIncludeEmptyCells)
Definition: document.cxx:3841
void ClearLookupCaches()
Zap all caches.
Definition: documen2.cxx:1308
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:204
void SetScriptType(const ScAddress &rPos, SvtScriptType nType)
Definition: document.cxx:6449
const ScPatternAttr * GetSelectionPattern(const ScMarkData &rMark)
Definition: document.cxx:5058
bool HasSelectedBlockMatrixFragment(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScMarkData &rMark) const
Definition: document.cxx:5395
sal_uInt64 GetCodeCount() const
Definition: document.cxx:6151
void SetClipParam(const ScClipParam &rParam)
Definition: document.cxx:2572
SC_DLLPUBLIC void GetDataArea(SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow, bool bIncludeOld, bool bOnlyDown) const
Return the smallest area containing at least all contiguous cells having data.
Definition: document.cxx:1072
bool IsClipboardSource() const
Definition: document.cxx:2577
void StartListeningFromClip(sc::StartListeningContext &rStartCxt, sc::EndListeningContext &rEndCxt, SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: document.cxx:2587
void SetRepeatArea(SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow)
Definition: document.cxx:6198
SC_DLLPUBLIC void SetRowFiltered(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bFiltered)
Definition: document.cxx:4496
void UnlockTable(SCTAB nTab)
Definition: document.cxx:5307
bool mbChangeReadOnlyEnabled
Definition: document.hxx:551
void MixDocument(const ScRange &rRange, ScPasteFunc nFunction, bool bSkipEmpty, ScDocument &rSrcDoc)
Definition: document.cxx:3237
void CheckVectorizationState()
Definition: document.cxx:3805
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4684
ScRangePairListRef xColNameRanges
Definition: document.hxx:420
SC_DLLPUBLIC ScColumnsRange GetColumnsRange(SCTAB nTab, SCCOL nColBegin, SCCOL nColEnd) const
Definition: document.cxx:2541
SC_DLLPUBLIC SCSIZE GetEmptyLinesInBlock(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, ScDirection eDir)
Definition: document.cxx:6067
void CreateAllNoteCaptions()
Ensure that all note objects have an associated sdr object.
Definition: document.cxx:6718
tools::Long GetNeededSize(SCCOL nCol, SCROW nRow, SCTAB nTab, OutputDevice *pDev, double nPPTX, double nPPTY, const Fraction &rZoomX, const Fraction &rZoomY, bool bWidth, bool bTotalSize=false, bool bInPrintTwips=false)
Definition: document.cxx:4253
void UpdateAllRowHeights(sc::RowHeightContext &rCxt, const ScMarkData *pTabMark)
Definition: document.cxx:4274
void InterpretDirtyCells(const ScRangeList &rRanges)
Definition: document.cxx:3872
void StartNeededListeners()
Definition: document10.cxx:554
void RemoveManualBreaks(SCTAB nTab)
Definition: document.cxx:6216
SC_DLLPUBLIC void UnlockAdjustHeight()
Definition: document.cxx:1781
void FindMaxRotCol(SCTAB nTab, RowInfo *pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2) const
Definition: document.cxx:5228
formula::FormulaTokenRef ResolveStaticReference(const ScAddress &rPos)
Definition: document.cxx:1745
bool CanFitBlock(const ScRange &rOld, const ScRange &rNew)
Definition: document.cxx:1796
std::shared_ptr< sc::FormulaGroupContext > mpFormulaGroupCxt
Definition: document.hxx:363
bool mbUndoEnabled
Definition: document.hxx:549
SC_DLLPUBLIC const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4719
SC_DLLPUBLIC SCCOL GetMaxColCount() const
Definition: document.hxx:894
bool InsertCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab, SCCOL nStartCol, SCSIZE nSize, ScDocument *pRefUndoDoc=nullptr, const ScMarkData *pTabMark=nullptr)
Definition: document.cxx:1477
Size GetPageSize(SCTAB nTab) const
Definition: document.cxx:6189
bool InsertRow(SCCOL nStartCol, SCTAB nStartTab, SCCOL nEndCol, SCTAB nEndTab, SCROW nStartRow, SCSIZE nSize, ScDocument *pRefUndoDoc=nullptr, const ScMarkData *pTabMark=nullptr)
Definition: document.cxx:1223
bool HasNotes() const
Definition: document.cxx:6679
void GetClipStart(SCCOL &nClipX, SCROW &nClipY)
Definition: document.cxx:3199
SC_DLLPUBLIC sal_uInt64 GetFormulaGroupCount() const
Definition: document.cxx:6138
void AssertNoInterpretNeeded(const ScAddress &rPos, SCROW nLength)
Definition: document.cxx:1772
std::unique_ptr< ScRangeName > pRangeName
Definition: document.hxx:381
SC_DLLPUBLIC void SetVisible(SCTAB nTab, bool bVisible)
Definition: document.cxx:884
void EndListeningIntersectedGroup(sc::EndListeningContext &rCxt, const ScAddress &rPos, std::vector< ScAddress > *pGroupPos)
Definition: document10.cxx:480
OUString aDocName
Pool for all external formula parsers used by this document.
Definition: document.hxx:417
FormulaError GetStringForFormula(const ScAddress &rPos, OUString &rString)
Definition: document.cxx:3557
void RemoveRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
Definition: document.cxx:4396
SC_DLLPUBLIC SCROW FirstVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4454
SC_DLLPUBLIC tools::Rectangle GetMMRect(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: documen3.cxx:1986
SC_DLLPUBLIC tools::Long GetRowOffset(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4232
SC_DLLPUBLIC void SetAnonymousDBData(SCTAB nTab, std::unique_ptr< ScDBData > pDBData)
Definition: document.cxx:302
void StripHidden(SCCOL &rX1, SCROW &rY1, SCCOL &rX2, SCROW &rY2, SCTAB nTab)
Definition: document.cxx:4670
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:297
std::unique_ptr< ScChartListenerCollection > pChartListenerCollection
Definition: document.hxx:391
std::set< ScFormulaCell * > maSubTotalCells
Definition: document.hxx:557
void RemoveColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
Definition: document.cxx:4402
bool ValidColRow(SCCOL nCol, SCROW nRow) const
Definition: document.hxx:901
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:619
void GetMatColsRows(SCCOL &nCols, SCROW &nRows) const
bool IsShared() const
bool IsSubTotal() const
sc::MatrixEdge GetMatrixEdge(const ScDocument &rDoc, ScAddress &rOrgPos) const
double GetValue()
bool GetMatrixOrigin(const ScDocument &rDoc, ScAddress &rPos) const
const svl::SharedString & GetString()
FormulaError GetErrCode()
void SetDirty(bool bDirtyFlag=true)
ScAddress aPos
sc::FormulaGroupEntry * first()
Definition: dociter.cxx:784
sc::FormulaGroupEntry * next()
Definition: dociter.cxx:789
static SC_DLLPUBLIC sal_uInt16 nStdRowHeight
Definition: global.hxx:596
static SC_DLLPUBLIC ::utl::TransliterationWrapper & GetTransliteration()
Definition: global.cxx:1026
static SC_DLLPUBLIC LanguageType eLnge
Definition: global.hxx:560
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 & GetMultiMarkArea() const
Definition: markdata.hxx:84
const ScRange & GetMarkArea() const
Definition: markdata.hxx:83
SCTAB GetFirstSelected() const
Definition: markdata.cxx:185
bool IsMultiMarked() const
Definition: markdata.hxx:81
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
Definition: markdata.cxx:372
SCTAB GetLastSelected() const
Definition: markdata.cxx:194
void SetMarking(bool bFlag)
Definition: markdata.hxx:102
bool GetTableSelect(SCTAB nTab) const
Definition: markdata.cxx:169
const ScRangeList & GetLeftEnvelope() const
Definition: markdata.hxx:157
void MarkToMulti()
Definition: markdata.cxx:209
const ScRangeList & GetBottomEnvelope() const
Definition: markdata.hxx:156
bool IsMarked() const
Definition: markdata.hxx:80
const ScRangeList & GetTopEnvelope() const
Definition: markdata.hxx:155
const ScRangeList & GetRightEnvelope() const
Definition: markdata.hxx:158
bool IsHorOverlapped() const
Definition: attrib.hxx:102
bool IsVerOverlapped() const
Definition: attrib.hxx:103
static ScDocument * GetClipDoc()
Definition: scmod.cxx:688
void UpdateStyleSheet(const ScDocument &rDoc)
Definition: patattr.cxx:1335
void StyleToName()
Definition: patattr.cxx:1362
SfxItemSet & GetItemSet()
Definition: patattr.hxx:192
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:73
Additional class containing cell annotation data.
Definition: postit.hxx:58
ScPrintSaverTab & GetTabData(SCTAB nTab)
Definition: prnsave.cxx:71
SCTAB GetTabCount() const
Definition: prnsave.hxx:62
ScRange & front()
Definition: rangelst.hxx:92
void RemoveAll()
Definition: rangelst.cxx:1101
bool empty() const
Definition: rangelst.hxx:88
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1137
size_t size() const
Definition: rangelst.hxx:89
void clear()
Definition: rangenam.cxx:869
SC_DLLPUBLIC bool insert(ScRangeData *p, bool bReuseFreeIndex=true)
Insert object into set.
Definition: rangenam.cxx:802
void PutInOrder()
Definition: address.hxx:622
ScAddress aEnd
Definition: address.hxx:498
bool Intersects(const ScRange &rRange) const
Definition: address.hxx:734
ScAddress aStart
Definition: address.hxx:497
static bool SC_DLLPUBLIC isMultiline(std::u16string_view rStr)
Definition: stringutil.cxx:425
ScStyleSheet::Usage GetUsage() const
Definition: stlsheet.hxx:53
void SetUsage(ScStyleSheet::Usage eUse) const
Definition: stlsheet.hxx:52
void CopyStaticToDocument(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const SvNumberFormatterMergeMap &rMap, ScTable *pDestTab)
Definition: table2.cxx:551
void CopyCellToDocument(SCCOL nSrcCol, SCROW nSrcRow, SCCOL nDestCol, SCROW nDestRow, ScTable &rDestTab)
Definition: table2.cxx:589
void SetDrawPageSize(bool bResetStreamValid=true, bool bUpdateNoteCaptionPos=true, const ScObjectHandling eObjectHandling=ScObjectHandling::RecalcPosMode)
Definition: table2.cxx:4221
bool InterpretCellsIfNeeded(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: table1.cxx:2624
sal_uInt16 GetRowHeight(SCROW nRow, SCROW *pStartRow, SCROW *pEndRow, bool bHiddenAsZero=true) const
Definition: table2.cxx:3553
ScColContainer aCol
Definition: table.hxx:162
void MixData(sc::MixDocContext &rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScPasteFunc nFunction, bool bSkipEmpty, const ScTable *pSrcTab)
Definition: table2.cxx:785
void SetLoadingRTL(bool bSet)
Definition: table1.cxx:400
const ScFormulaCell * GetFormulaCell(SCCOL nCol, SCROW nRow) const
Definition: table2.cxx:1830
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
bool CompileErrorCells(sc::CompileFormulaContext &rCxt, FormulaError nErrCode)
Definition: table2.cxx:2209
void SetValue(SCCOL nCol, SCROW nRow, const double &rVal)
Definition: table2.cxx:1763
void DumpColumnStorage(SCCOL nCol) const
void InterpretDirtyCells(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: table1.cxx:2617
bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: table2.cxx:1652
bool RowHidden(SCROW nRow, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: table5.cxx:487
const ScBitMaskCompressedArray< SCROW, CRFlags > * GetRowFlagsArray() const
Definition: table.hxx:935
sal_uInt16 GetOptimalMinRowHeight() const
Definition: table.hxx:879
SCCOL GetAllocatedColumnsCount() const
Definition: table.hxx:1164
void SetLayoutRTL(bool bSet)
Definition: table1.cxx:395
std::unique_ptr< ScFlatBoolRowSegments > mpHiddenRows
Definition: table.hxx:200
std::unique_ptr< ScFlatUInt16RowSegments > mpRowHeights
Definition: table.hxx:195
SvtBroadcaster * GetBroadcaster(SCCOL nCol, SCROW nRow)
Definition: table1.cxx:2586
bool IsPrintEntireSheet() const
Returns true, if the sheet is always printed.
Definition: table.hxx:830
void DeleteBroadcasters(sc::ColumnBlockPosition &rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2)
Definition: table1.cxx:2594
const OUString & GetName() const
Definition: table.hxx:397
SdrObject * Next()
void SetDocShell(SfxObjectShell *pDocShell)
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
static void notifyDocumentSizeChangedAllViews(vcl::ITiledRenderable *pDoc, bool bInvalidateAll=true)
const INetURLObject & GetURLObject() const
css::uno::Reference< css::script::XLibraryContainer > GetBasicContainer()
bool IsReadOnly() const
bool IsLoading() const
SfxMedium * GetMedium() const
const OUString & GetName() const
virtual SfxItemSet & GetItemSet()
virtual SfxStyleSheetBase * Next()
virtual SfxStyleSheetBase * First()
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
void GetInputLineString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &rOutString, bool bFiltering=false, bool bForceSystemLocale=false)
SvNumberFormatterMergeMap ConvertMergeTableToMap()
SvNumberFormatterIndexTable * MergeFormatter(SvNumberFormatter &rNewTable)
void SetTable(bool bNew)
bool IsValid(SvxBoxInfoItemValidFlags nValid) const
void EnableVer(bool bEnable)
void SetDist(bool bNew)
void SetMinDist(bool bNew)
void EnableHor(bool bEnable)
void SetValid(SvxBoxInfoItemValidFlags nValid, bool bValid=true)
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxInfoItemLine nLine)
const editeng::SvxBorderLine * GetTop() const
bool IsRemoveAdjacentCellBorder() const
const editeng::SvxBorderLine * GetRight() const
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxItemLine nLine)
const editeng::SvxBorderLine * GetLeft() const
const editeng::SvxBorderLine * GetBottom() const
void SetAllDistances(sal_Int16 nNew)
static UITestLogger & getInstance()
void logEvent(const EventDescription &rDescription)
Temporarily switch on/off auto calculation mode.
Definition: scopetools.hxx:27
ColumnBlockPositionSet * getBlockPositionSet()
Definition: clipcontext.hxx:44
bool empty() const
Definition: columnset.cxx:60
Structure that stores segments of boolean flags per column, and perform custom action on those segmen...
void executeColumnAction(ScDocument &rDoc, ColumnAction &ac) const
void setDeleteFlag(InsertDeleteFlags nFlag)
void startListeningFormulas()
Have the formula cells in the recorded ranges start listening.
void setDestRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: clipcontext.cxx:74
void setListeningFormulaSpans(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Record a range of formula cells that need to start listening after the copy-from-clip is complete.
InsertDeleteFlags getInsertFlag() const
void setTabRange(SCTAB nStart, SCTAB nEnd)
Definition: clipcontext.cxx:58
SCTAB getTabStart() const
Definition: clipcontext.cxx:64
ScDocument * getUndoDoc()
Definition: clipcontext.cxx:92
SCTAB getTabEnd() const
Definition: clipcontext.cxx:69
ScDocument * getClipDoc()
Definition: clipcontext.cxx:97
void setStartListening(bool b)
Wrapper for ScDocument::EnableDelayDeletingBroadcasters()
Definition: scopetools.hxx:99
Tracks and gathers all created sparklines and sparkline groups.
Sparkline data, used for rendering the content of a cell.
Definition: Sparkline.hxx:29
Keep track of all named expressions that have been updated during reference update.
std::unordered_set< sal_uInt16 > NameIndicesType
NameIndicesType getUpdatedNames(SCTAB nTab) const
const OUString & getString() const
bool is() const
bool isEqual(const OUString &rStr1, const OUString &rStr2) const
int nCount
constexpr double nPPTX
constexpr double nPPTY
static void lcl_GetFirstTabRange(SCTAB &rTabRangeStart, SCTAB &rTabRangeEnd, const ScMarkData *pTabMark, SCTAB aMaxTab)
Definition: document.cxx:1131
static bool lcl_GetNextTabRange(SCTAB &rTabRangeStart, SCTAB &rTabRangeEnd, const ScMarkData *pTabMark, SCTAB aMaxTab)
Definition: document.cxx:1149
std::set< ScDefaultAttr, ScLessDefaultAttr > ScDefaultAttrSet
Definition: document.cxx:169
static HasAttrFlags OptimizeHasAttrib(HasAttrFlags nMask, const ScDocumentPool *pPool)
Definition: document.cxx:5136
static void lcl_GetInsDelRanges(const ScRange &rOld, const ScRange &rNew, ScRange &rColRange, bool &rInsCol, bool &rDelCol, ScRange &rRowRange, bool &rInsRow, bool &rDelRow)
Definition: document.cxx:1675
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2720
std::unique_ptr< ScTable, o3tl::default_delete< ScTable > > ScTableUniquePtr
Definition: document.hxx:320
@ SCDOCMODE_UNDO
Definition: document.hxx:258
CommentCaptionState
Definition: document.hxx:263
@ MIXED
Definition: document.hxx:266
@ ALLHIDDEN
Definition: document.hxx:265
@ CORE
Definition: document.hxx:317
ScObjectHandling
Definition: drwlayer.hxx:91
EmbeddedObjectRef * pObject
FormulaError
ScBreakType
Definition: global.hxx:139
ScMoveDirection
Definition: global.hxx:326
CellType
Definition: global.hxx:272
@ CELLTYPE_EDIT
Definition: global.hxx:277
@ CELLTYPE_STRING
Definition: global.hxx:275
@ CELLTYPE_FORMULA
Definition: global.hxx:276
@ CELLTYPE_NONE
Definition: global.hxx:273
@ CELLTYPE_VALUE
Definition: global.hxx:274
@ URM_COPY
Definition: global.hxx:303
@ URM_MOVE
Definition: global.hxx:304
@ URM_INSDEL
Definition: global.hxx:302
ScPasteFunc
Definition: global.hxx:181
InsertDeleteFlags
Definition: global.hxx:149
@ NOTE
Strings (and string results if InsertDeleteFlags::FORMULA is not set).
@ OBJECTS
Cell styles.
@ 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
ScDirection
Definition: global.hxx:343
CRFlags
Definition: global.hxx:125
SfxHintId
sal_Int32 nIndex
OUString aName
void * p
sal_Int64 n
uno_Any a
SvtScriptType
sal_uInt16 nPos
#define SAL_WARN(area, stream)
aStr
std::unique_ptr< sal_Int32[]> pData
void NotifyIfChangesListeners(const ScDocShell &rDocShell, const ScRange &rRange, const OUString &rType=OUString("cell-change"))
Definition: docsh.hxx:506
::boost::intrusive_ptr< FormulaToken > FormulaTokenRef
int i
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
long Long
HashMap_OWString_Interface aMap
const size_t nTabSize
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
constexpr TypedWhichId< ScPatternAttr > ATTR_PATTERN(156)
constexpr TypedWhichId< SfxUInt16Item > ATTR_PAGE_FIRSTPAGENO(177)
constexpr TypedWhichId< ScRotateValueItem > ATTR_ROTATE_VALUE(135)
constexpr sal_uInt16 ATTR_PATTERN_START(100)
constexpr TypedWhichId< SvxBoxItem > ATTR_BORDER(150)
constexpr sal_uInt16 ATTR_PATTERN_END(155)
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALIDDATA(153)
#define SC_MOD()
Definition: scmod.hxx:247
static SfxItemSet & rSet
std::map< OUString, OUString > aParameters
This struct stores general clipboard parameters associated with a ScDocument instance created in clip...
Definition: clipparam.hxx:31
bool isMultiRange() const
Definition: clipparam.cxx:38
SCCOL getPasteColSize()
Get the column size of a pasted range.
Definition: clipparam.cxx:43
SCROW getPasteRowSize(const ScDocument &rSrcDoc, bool bIncludeFiltered)
Same as the above method, but returns the row size of the compressed range.
Definition: clipparam.cxx:73
void transpose(const ScDocument &rSrcDoc, bool bIncludeFiltered, bool bIsMultiRangeRowFilteredTranspose)
Transpose the clip parameters.
Definition: clipparam.cxx:114
Direction meDirection
Definition: clipparam.hxx:35
ScRangeList maRanges
Definition: clipparam.hxx:34
bool mbCutMode
Definition: clipparam.hxx:36
ScRange getWholeRange() const
Return a single range that encompasses all individual ranges.
Definition: clipparam.cxx:109
Struct to hold non-data extended area, used with ScDocument::ShrinkToUsedDataArea().
Definition: sortparam.hxx:53
OUString aDocName
Definition: document.hxx:286
sal_uInt64 nFormulaCount
Definition: document.hxx:289
sal_uInt64 nCellCount
Definition: document.hxx:288
SCTAB nTableCount
Definition: document.hxx:287
For usage in FindDdeLink() only!
Definition: document.hxx:308
std::unique_ptr< ScRecursionHelper > xRecursionHelper
Definition: document.hxx:309
SvNumFormatType GetNumberFormatType(sal_uInt32 nFIndex) const
std::vector< DelayedSetNumberFormat > maDelayedSetNumberFormat
sal_uInt8 nHori
Definition: attarray.hxx:60
sal_uInt8 nVert
Definition: attarray.hxx:61
sal_uInt8 nLeft
Definition: attarray.hxx:56
sal_uInt8 nBottom
Definition: attarray.hxx:59
sal_uInt8 nRight
Definition: attarray.hxx:57
sal_uInt8 nTop
Definition: attarray.hxx:58
std::optional< SfxItemSet > pItemSet
Definition: attarray.hxx:69
sal_uInt64 mnPatternId
Definition: attarray.hxx:74
A pretty assertion that checks that the relevant bits in the @nFlags are not set on the document at e...
Definition: document.hxx:2761
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
double getDouble() const
Definition: cellvalue.hxx:134
bool isEmpty() const
Definition: cellvalue.cxx:667
OUString getString(const ScDocument *pDoc) const
Retrieve string value.
Definition: cellvalue.cxx:657
CellType getType() const
Definition: cellvalue.hxx:133
Store parameters used in the ScDocument::SetString() method.
Definition: stringutil.hxx:35
void setTextInput()
Call this whenever you need to unconditionally set input as text, no matter what the input is.
Definition: stringutil.cxx:39
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.
void setBlockPositionReference(ColumnBlockPositionSet *blockPos)
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.
bool mbClearTabDeletedFlag
When true, go through all reference tokens and clears "sheet deleted" flag if its corresponding index...
bool bVisible
sal_uInt16 sal_Unicode
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:23
sal_Int16 SCTAB
Definition: types.hxx:22
::boost::intrusive_ptr< ScFormulaCellGroup > ScFormulaCellGroupRef
Definition: types.hxx:43
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
@ SC_VALID_ANY
Definition: validat.hxx:42
sal_Int32 nLength
std::unordered_map< sal_uInt16, sal_uInt32 > SvNumberFormatterIndexTable
SvNumFormatType
std::unordered_map< sal_uInt32, sal_uInt32 > SvNumberFormatterMergeMap