LibreOffice Module sc (master) 1
docfunc.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 <comphelper/lok.hxx>
23#include <o3tl/safeint.hxx>
24#include <o3tl/string_view.hxx>
25#include <sfx2/app.hxx>
26#include <editeng/editobj.hxx>
28#include <sfx2/linkmgr.hxx>
29#include <sfx2/bindings.hxx>
30#include <utility>
31#include <vcl/weld.hxx>
32#include <vcl/stdtext.hxx>
33#include <vcl/svapp.hxx>
34#include <svx/svdocapt.hxx>
35#include <sal/log.hxx>
37#include <osl/diagnose.h>
38
39#include <com/sun/star/container/XNameContainer.hpp>
40#include <com/sun/star/script/ModuleType.hpp>
41#include <com/sun/star/script/XLibraryContainer.hpp>
42#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
43
44#include <docfunc.hxx>
45
46#include <sc.hrc>
47#include <strings.hrc>
48
49#include <arealink.hxx>
50#include <attrib.hxx>
51#include <dociter.hxx>
52#include <autoform.hxx>
53#include <formulacell.hxx>
54#include <cellmergeoption.hxx>
55#include <detdata.hxx>
56#include <detfunc.hxx>
57#include <docpool.hxx>
58#include <docsh.hxx>
59#include <drwlayer.hxx>
60#include <editutil.hxx>
61#include <globstr.hrc>
62#include <olinetab.hxx>
63#include <patattr.hxx>
64#include <rangenam.hxx>
65#include <refundo.hxx>
66#include <scresid.hxx>
67#include <stlpool.hxx>
68#include <stlsheet.hxx>
69#include <tablink.hxx>
70#include <tabvwsh.hxx>
71#include <uiitems.hxx>
72#include <undoblk.hxx>
73#include <undocell.hxx>
74#include <undodraw.hxx>
75#include <undotab.hxx>
76#include <sizedev.hxx>
77#include <scmod.hxx>
78#include <inputhdl.hxx>
79#include <editable.hxx>
80#include <compiler.hxx>
81#include <scui_def.hxx>
82#include <tabprotection.hxx>
83#include <clipparam.hxx>
84#include <externalrefmgr.hxx>
85#include <undorangename.hxx>
86#include <progress.hxx>
87#include <dpobject.hxx>
88#include <stringutil.hxx>
89#include <cellvalue.hxx>
90#include <tokenarray.hxx>
91#include <rowheightcontext.hxx>
92#include <cellvalues.hxx>
93#include <undoconvert.hxx>
94#include <docfuncutil.hxx>
95#include <sheetevents.hxx>
96#include <conditio.hxx>
97#include <columnspanset.hxx>
98#include <validat.hxx>
99#include <SparklineGroup.hxx>
101#include <SparklineData.hxx>
109#include <config_features.h>
110
111#include <memory>
112#include <basic/basmgr.hxx>
113#include <set>
114#include <vector>
115#include <sfx2/viewfrm.hxx>
116
117using namespace com::sun::star;
118using ::std::vector;
119
120void ScDocFunc::NotifyDrawUndo( std::unique_ptr<SdrUndoAction> pUndoAction)
121{
122 // #i101118# if drawing layer collects the undo actions, add it there
124 if( pDrawLayer && pDrawLayer->IsRecording() )
125 pDrawLayer->AddCalcUndo( std::move(pUndoAction) );
126 else
127 rDocShell.GetUndoManager()->AddUndoAction( std::make_unique<ScUndoDraw>( std::move(pUndoAction), &rDocShell ) );
129
130 // the affected sheet isn't known, so all stream positions are invalidated
132 SCTAB nTabCount = rDoc.GetTableCount();
133 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
134 rDoc.SetStreamValid(nTab, false);
135}
136
137// paint row above the range (because of lines after AdjustRowHeight)
138
139static void lcl_PaintAbove( ScDocShell& rDocShell, const ScRange& rRange )
140{
141 SCROW nRow = rRange.aStart.Row();
142 if ( nRow > 0 )
143 {
144 SCTAB nTab = rRange.aStart.Tab();
145 --nRow;
146 ScDocument& rDoc = rDocShell.GetDocument();
147 rDocShell.PostPaint( ScRange(0,nRow,nTab,rDoc.MaxCol(),nRow,nTab), PaintPartFlags::Grid );
148 }
149}
150
151bool ScDocFunc::AdjustRowHeight( const ScRange& rRange, bool bPaint, bool bApi )
152{
154 SfxViewShell* pSomeViewForThisDoc = rDocShell.GetBestViewShell(false);
155 if ( rDoc.IsImportingXML() )
156 {
157 // for XML import, all row heights are updated together after importing
158 return false;
159 }
160 if ( rDoc.IsAdjustHeightLocked() )
161 {
162 return false;
163 }
164
165 SCTAB nTab = rRange.aStart.Tab();
166 SCROW nStartRow = rRange.aStart.Row();
167 SCROW nEndRow = rRange.aEnd.Row();
168
170 Fraction aOne(1,1);
171
172 sc::RowHeightContext aCxt(rDoc.MaxRow(), aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, aProv.GetDevice());
173 bool bChanged = rDoc.SetOptimalHeight(aCxt, nStartRow, nEndRow, nTab, bApi);
174 // tdf#76183: recalculate objects' positions
175 if (bChanged)
176 {
178 {
179 SfxViewShell* pViewShell = SfxViewShell::GetFirst();
180 while (pViewShell)
181 {
182 ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
183 if (pTabViewShell && pTabViewShell->GetDocId() == pSomeViewForThisDoc->GetDocId())
184 {
185 if (ScPositionHelper* pPosHelper = pTabViewShell->GetViewData().GetLOKHeightHelper(nTab))
186 pPosHelper->invalidateByIndex(nStartRow);
187 }
188 pViewShell = SfxViewShell::GetNext(*pViewShell);
189 }
190 }
191 rDoc.SetDrawPageSize(nTab);
192 }
193
194 if ( bPaint && bChanged )
195 rDocShell.PostPaint(ScRange(0, nStartRow, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab),
197
199 {
202 pSomeViewForThisDoc, false /* bColumns */, true /* bRows */, true /* bSizes*/,
203 false /* bHidden */, false /* bFiltered */, false /* bGroups */, nTab);
204 }
205
206 return bChanged;
207}
208
210{
211 ScDocShellModificator aModificator( rDocShell );
212
215 bool bUndo (rDoc.IsUndoEnabled());
216 ScDrawLayer* pModel = rDoc.GetDrawLayer();
217 SCCOL nCol = rPos.Col();
218 SCROW nRow = rPos.Row();
219 SCTAB nTab = rPos.Tab();
220
221 if (bUndo)
222 pModel->BeginCalcUndo(false);
223 bool bDone = ScDetectiveFunc(rDoc, nTab).ShowPred( nCol, nRow );
224 std::unique_ptr<SdrUndoGroup> pUndo;
225 if (bUndo)
226 pUndo = pModel->GetCalcUndo();
227 if (bDone)
228 {
229 ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDPRED );
230 rDoc.AddDetectiveOperation( aOperation );
231 if (bUndo)
232 {
234 std::make_unique<ScUndoDetective>( &rDocShell, std::move(pUndo), &aOperation ) );
235 }
236 aModificator.SetDocumentModified();
238 if (pBindings)
239 pBindings->Invalidate( SID_DETECTIVE_REFRESH );
240 }
241
242 return bDone;
243}
244
246{
248
249 bool bUndo(rDoc.IsUndoEnabled());
250 ScDrawLayer* pModel = rDoc.GetDrawLayer();
251 if (!pModel)
252 return false;
253
254 ScDocShellModificator aModificator( rDocShell );
255
256 SCCOL nCol = rPos.Col();
257 SCROW nRow = rPos.Row();
258 SCTAB nTab = rPos.Tab();
259
260 if (bUndo)
261 pModel->BeginCalcUndo(false);
262 bool bDone = ScDetectiveFunc(rDoc, nTab).DeletePred( nCol, nRow );
263 std::unique_ptr<SdrUndoGroup> pUndo;
264 if (bUndo)
265 pUndo = pModel->GetCalcUndo();
266 if (bDone)
267 {
268 ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELPRED );
269 rDoc.AddDetectiveOperation( aOperation );
270 if (bUndo)
271 {
273 std::make_unique<ScUndoDetective>( &rDocShell, std::move(pUndo), &aOperation ) );
274 }
275 aModificator.SetDocumentModified();
277 if (pBindings)
278 pBindings->Invalidate( SID_DETECTIVE_REFRESH );
279 }
280
281 return bDone;
282}
283
285{
286 ScDocShellModificator aModificator( rDocShell );
287
290
291 bool bUndo(rDoc.IsUndoEnabled());
292 ScDrawLayer* pModel = rDoc.GetDrawLayer();
293 SCCOL nCol = rPos.Col();
294 SCROW nRow = rPos.Row();
295 SCTAB nTab = rPos.Tab();
296
297 if (bUndo)
298 pModel->BeginCalcUndo(false);
299 bool bDone = ScDetectiveFunc(rDoc, nTab).ShowSucc( nCol, nRow );
300 std::unique_ptr<SdrUndoGroup> pUndo;
301 if (bUndo)
302 pUndo = pModel->GetCalcUndo();
303 if (bDone)
304 {
305 ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDSUCC );
306 rDoc.AddDetectiveOperation( aOperation );
307 if (bUndo)
308 {
310 std::make_unique<ScUndoDetective>( &rDocShell, std::move(pUndo), &aOperation ) );
311 }
312 aModificator.SetDocumentModified();
314 if (pBindings)
315 pBindings->Invalidate( SID_DETECTIVE_REFRESH );
316 }
317
318 return bDone;
319}
320
322{
324
325 bool bUndo (rDoc.IsUndoEnabled());
326 ScDrawLayer* pModel = rDoc.GetDrawLayer();
327 if (!pModel)
328 return false;
329
330 ScDocShellModificator aModificator( rDocShell );
331
332 SCCOL nCol = rPos.Col();
333 SCROW nRow = rPos.Row();
334 SCTAB nTab = rPos.Tab();
335
336 if (bUndo)
337 pModel->BeginCalcUndo(false);
338 bool bDone = ScDetectiveFunc(rDoc, nTab).DeleteSucc( nCol, nRow );
339 std::unique_ptr<SdrUndoGroup> pUndo;
340 if (bUndo)
341 pUndo = pModel->GetCalcUndo();
342 if (bDone)
343 {
344 ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELSUCC );
345 rDoc.AddDetectiveOperation( aOperation );
346 if (bUndo)
347 {
349 std::make_unique<ScUndoDetective>( &rDocShell, std::move(pUndo), &aOperation ) );
350 }
351 aModificator.SetDocumentModified();
353 if (pBindings)
354 pBindings->Invalidate( SID_DETECTIVE_REFRESH );
355 }
356
357 return bDone;
358}
359
361{
362 ScDocShellModificator aModificator( rDocShell );
363
366
367 bool bUndo (rDoc.IsUndoEnabled());
368 ScDrawLayer* pModel = rDoc.GetDrawLayer();
369 SCCOL nCol = rPos.Col();
370 SCROW nRow = rPos.Row();
371 SCTAB nTab = rPos.Tab();
372
373 if (bUndo)
374 pModel->BeginCalcUndo(false);
375 bool bDone = ScDetectiveFunc(rDoc, nTab).ShowError( nCol, nRow );
376 std::unique_ptr<SdrUndoGroup> pUndo;
377 if (bUndo)
378 pUndo = pModel->GetCalcUndo();
379 if (bDone)
380 {
381 ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDERROR );
382 rDoc.AddDetectiveOperation( aOperation );
383 if (bUndo)
384 {
386 std::make_unique<ScUndoDetective>( &rDocShell, std::move(pUndo), &aOperation ) );
387 }
388 aModificator.SetDocumentModified();
390 if (pBindings)
391 pBindings->Invalidate( SID_DETECTIVE_REFRESH );
392 }
393
394 return bDone;
395}
396
398{
399 ScDocShellModificator aModificator( rDocShell );
400
403
404 bool bUndo (rDoc.IsUndoEnabled());
405 ScDrawLayer* pModel = rDoc.GetDrawLayer();
406
407 std::unique_ptr<weld::WaitObject> xWaitWin(new weld::WaitObject(ScDocShell::GetActiveDialogParent()));
408 if (bUndo)
409 pModel->BeginCalcUndo(false);
410 bool bOverflow;
411 bool bDone = ScDetectiveFunc(rDoc, nTab).MarkInvalid( bOverflow );
412 std::unique_ptr<SdrUndoGroup> pUndo;
413 if (bUndo)
414 pUndo = pModel->GetCalcUndo();
415 xWaitWin.reset();
416 if (bDone)
417 {
418 if (pUndo && bUndo)
419 {
420 pUndo->SetComment( ScResId( STR_UNDO_DETINVALID ) );
421 rDocShell.GetUndoManager()->AddUndoAction( std::move(pUndo) );
422 }
423 aModificator.SetDocumentModified();
424 if ( bOverflow )
425 {
426 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr,
427 VclMessageType::Info, VclButtonsType::Ok,
428 ScResId(STR_DETINVALID_OVERFLOW)));
429 xInfoBox->run();
430 }
431 }
432
433 return bDone;
434}
435
437{
439
440 bool bUndo (rDoc.IsUndoEnabled());
441 ScDrawLayer* pModel = rDoc.GetDrawLayer();
442 if (!pModel)
443 return false;
444
445 ScDocShellModificator aModificator( rDocShell );
446
447 if (bUndo)
448 pModel->BeginCalcUndo(false);
449 bool bDone = ScDetectiveFunc(rDoc, nTab).DeleteAll( ScDetectiveDelete::Detective );
450 std::unique_ptr<SdrUndoGroup> pUndo;
451 if (bUndo)
452 pUndo = pModel->GetCalcUndo();
453 if (bDone)
454 {
455 ScDetOpList* pOldList = rDoc.GetDetOpList();
456 std::unique_ptr<ScDetOpList> pUndoList;
457 if (bUndo && pOldList)
458 pUndoList.reset(new ScDetOpList(*pOldList));
459
461
462 if (bUndo)
463 {
465 std::make_unique<ScUndoDetective>( &rDocShell, std::move(pUndo), nullptr, std::move(pUndoList) ) );
466 }
467 aModificator.SetDocumentModified();
469 if (pBindings)
470 pBindings->Invalidate( SID_DETECTIVE_REFRESH );
471 }
472
473 return bDone;
474}
475
476bool ScDocFunc::DetectiveRefresh( bool bAutomatic )
477{
478 bool bDone = false;
480
481 ScDetOpList* pList = rDoc.GetDetOpList();
482 if ( pList && pList->Count() )
483 {
485 ScDrawLayer* pModel = rDoc.GetDrawLayer();
486 const bool bUndo (rDoc.IsUndoEnabled());
487 if (bUndo)
488 pModel->BeginCalcUndo(false);
489
490 // Delete in all sheets
491
492 SCTAB nTabCount = rDoc.GetTableCount();
493 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
494 ScDetectiveFunc( rDoc,nTab ).DeleteAll( ScDetectiveDelete::Arrows ); // don't remove circles
495
496 // repeat
497
498 size_t nCount = pList->Count();
499 for (size_t i=0; i < nCount; ++i)
500 {
501 const ScDetOpData& rData = pList->GetObject(i);
502 const ScAddress& aPos = rData.GetPos();
503 ScDetectiveFunc aFunc( rDoc, aPos.Tab() );
504 SCCOL nCol = aPos.Col();
505 SCROW nRow = aPos.Row();
506 switch (rData.GetOperation())
507 {
508 case SCDETOP_ADDSUCC:
509 aFunc.ShowSucc( nCol, nRow );
510 break;
511 case SCDETOP_DELSUCC:
512 aFunc.DeleteSucc( nCol, nRow );
513 break;
514 case SCDETOP_ADDPRED:
515 aFunc.ShowPred( nCol, nRow );
516 break;
517 case SCDETOP_DELPRED:
518 aFunc.DeletePred( nCol, nRow );
519 break;
520 case SCDETOP_ADDERROR:
521 aFunc.ShowError( nCol, nRow );
522 break;
523 default:
524 OSL_FAIL("wrong operation in DetectiveRefresh");
525 }
526 }
527
528 if (bUndo)
529 {
530 std::unique_ptr<SdrUndoGroup> pUndo = pModel->GetCalcUndo();
531 if (pUndo)
532 {
533 pUndo->SetComment( ScResId( STR_UNDO_DETREFRESH ) );
534 // associate with the last action
536 std::make_unique<ScUndoDraw>( std::move(pUndo), &rDocShell ),
537 bAutomatic );
538 }
539 }
541 bDone = true;
542 }
543 return bDone;
544}
545
547 const ScRangeList& rSrcRanges, vector<ScTokenRef>& rRefTokens, ScDocShell& rDocShell,
548 bool bPred)
549{
550 ScDocument& rDoc = rDocShell.GetDocument();
551 vector<ScTokenRef> aRefTokens;
552 if (rSrcRanges.empty())
553 return;
554 ScRange const & rFrontRange = rSrcRanges.front();
555 ScDetectiveFunc aDetFunc(rDoc, rFrontRange.aStart.Tab());
556 for (size_t i = 0, n = rSrcRanges.size(); i < n; ++i)
557 {
558 ScRange const & r = rSrcRanges[i];
559 if (bPred)
560 {
561 aDetFunc.GetAllPreds(
562 r.aStart.Col(), r.aStart.Row(), r.aEnd.Col(), r.aEnd.Row(), aRefTokens);
563 }
564 else
565 {
566 aDetFunc.GetAllSuccs(
567 r.aStart.Col(), r.aStart.Row(), r.aEnd.Col(), r.aEnd.Row(), aRefTokens);
568 }
569 }
570 rRefTokens.swap(aRefTokens);
571}
572
573void ScDocFunc::DetectiveCollectAllPreds(const ScRangeList& rSrcRanges, vector<ScTokenRef>& rRefTokens)
574{
575 lcl_collectAllPredOrSuccRanges(rSrcRanges, rRefTokens, rDocShell, true);
576}
577
578void ScDocFunc::DetectiveCollectAllSuccs(const ScRangeList& rSrcRanges, vector<ScTokenRef>& rRefTokens)
579{
580 lcl_collectAllPredOrSuccRanges(rSrcRanges, rRefTokens, rDocShell, false);
581}
582
584 const ScMarkData& rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi )
585{
586 ScDocShellModificator aModificator( rDocShell );
587
588 if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
589 {
590 OSL_FAIL("ScDocFunc::DeleteContents without markings");
591 return false;
592 }
593
595
596 if (bRecord && !rDoc.IsUndoEnabled())
597 bRecord = false;
598
599 ScEditableTester aTester( rDoc, rMark );
600 if (!aTester.IsEditable())
601 {
602 if (!bApi)
604 return false;
605 }
606
607 ScMarkData aMultiMark = rMark;
608 aMultiMark.SetMarking(false); // for MarkToMulti
609
610 ScDocumentUniquePtr pUndoDoc;
611 bool bMulti = aMultiMark.IsMultiMarked();
612 aMultiMark.MarkToMulti();
613 const ScRange& aMarkRange = aMultiMark.GetMultiMarkArea();
614 ScRange aExtendedRange(aMarkRange);
615 if ( rDoc.ExtendMerge( aExtendedRange, true ) )
616 bMulti = false;
617
618 // no objects on protected tabs
619 bool bObjects = (nFlags & InsertDeleteFlags::OBJECTS) && !sc::DocFuncUtil::hasProtectedTab(rDoc, rMark);
620
621 sal_uInt16 nExtFlags = 0; // extra flags are needed only if attributes are deleted
622 if ( nFlags & InsertDeleteFlags::ATTRIB )
623 rDocShell.UpdatePaintExt( nExtFlags, aMarkRange );
624
625 // order of operations:
626 // 1) BeginDrawUndo
627 // 2) Delete objects (DrawUndo will be filled)
628 // 3) Copy content for undo and set up undo actions
629 // 4) Delete content
630
631 bool bDrawUndo = bObjects || (nFlags & InsertDeleteFlags::NOTE);
632 if (bRecord && bDrawUndo)
633 rDoc.BeginDrawUndo();
634
635 if (bObjects)
636 {
637 if (bMulti)
638 rDoc.DeleteObjectsInSelection( aMultiMark );
639 else
640 rDoc.DeleteObjectsInArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
641 aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),
642 aMultiMark );
643 }
644
645 // To keep track of all non-empty cells within the deleted area.
646 std::shared_ptr<ScSimpleUndo::DataSpansType> pDataSpans;
647
648 if ( bRecord )
649 {
650 pUndoDoc = sc::DocFuncUtil::createDeleteContentsUndoDoc(rDoc, aMultiMark, aMarkRange, nFlags, bMulti);
651 pDataSpans = sc::DocFuncUtil::getNonEmptyCellSpans(rDoc, aMultiMark, aMarkRange);
652 }
653
654 rDoc.DeleteSelection( nFlags, aMultiMark );
655
656 // add undo action after drawing undo is complete (objects and note captions)
657 if( bRecord )
658 {
660 rDocShell.GetUndoManager(), &rDocShell, aMultiMark, aExtendedRange,
661 std::move(pUndoDoc), nFlags, pDataSpans, bMulti, bDrawUndo);
662 }
663
664 if (!AdjustRowHeight( aExtendedRange, true, bApi ))
665 rDocShell.PostPaint( aExtendedRange, PaintPartFlags::Grid, nExtFlags );
666 else if (nExtFlags & SC_PF_LINES)
667 lcl_PaintAbove( rDocShell, aExtendedRange ); // for lines above the range
668
669 aModificator.SetDocumentModified();
670
671 return true;
672}
673
675 const ScAddress& rPos, const ScMarkData& rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi )
676{
677 ScDocShellModificator aModificator(rDocShell);
678
680
681 if (bRecord && !rDoc.IsUndoEnabled())
682 bRecord = false;
683
684 ScEditableTester aTester(rDoc, rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark);
685 if (!aTester.IsEditable())
686 {
688 return false;
689 }
690
691 // no objects on protected tabs
692 bool bObjects = (nFlags & InsertDeleteFlags::OBJECTS) && !sc::DocFuncUtil::hasProtectedTab(rDoc, rMark);
693
694 sal_uInt16 nExtFlags = 0; // extra flags are needed only if attributes are deleted
695 if (nFlags & InsertDeleteFlags::ATTRIB)
696 rDocShell.UpdatePaintExt(nExtFlags, rPos);
697
698 // order of operations:
699 // 1) BeginDrawUndo
700 // 2) delete objects (DrawUndo is filled)
701 // 3) copy contents for undo
702 // 4) delete contents
703 // 5) add undo-action
704
705 bool bDrawUndo = bObjects || (nFlags & InsertDeleteFlags::NOTE); // needed for shown notes
706 if (bDrawUndo && bRecord)
707 rDoc.BeginDrawUndo();
708
709 if (bObjects)
710 rDoc.DeleteObjectsInArea(rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark);
711
712 // To keep track of all non-empty cells within the deleted area.
713 std::shared_ptr<ScSimpleUndo::DataSpansType> pDataSpans;
714
715 ScDocumentUniquePtr pUndoDoc;
716 if (bRecord)
717 {
718 pUndoDoc = sc::DocFuncUtil::createDeleteContentsUndoDoc(rDoc, rMark, rPos, nFlags, false);
719 pDataSpans = sc::DocFuncUtil::getNonEmptyCellSpans(rDoc, rMark, rPos);
720 }
721
722 rDoc.DeleteArea(rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark, nFlags);
723
724 if (bRecord)
725 {
727 rDocShell.GetUndoManager(), &rDocShell, rMark, rPos, std::move(pUndoDoc),
728 nFlags, pDataSpans, false, bDrawUndo);
729 }
730
731 if (!AdjustRowHeight(rPos, true, bApi))
733 rPos.Col(), rPos.Row(), rPos.Tab(), rPos.Col(), rPos.Row(), rPos.Tab(),
734 PaintPartFlags::Grid, nExtFlags);
735
736 aModificator.SetDocumentModified();
737
738 return true;
739}
740
742 bool bApi )
743{
744 ScDocShellModificator aModificator( rDocShell );
745
747 bool bRecord = true;
748 if (!rDoc.IsUndoEnabled())
749 bRecord = false;
750
751 ScEditableTester aTester( rDoc, rMark );
752 if (!aTester.IsEditable())
753 {
754 if (!bApi)
756 return false;
757 }
758
759 ScMarkData aMultiMark = rMark;
760 aMultiMark.SetMarking(false); // for MarkToMulti
761 aMultiMark.MarkToMulti();
762 const ScRange& aMarkRange = aMultiMark.GetMultiMarkArea();
763
764 if (bRecord)
765 {
766 SCTAB nStartTab = aMarkRange.aStart.Tab();
767 SCTAB nTabCount = rDoc.GetTableCount();
768
770 pUndoDoc->InitUndo( rDoc, nStartTab, nStartTab );
771 for (const auto& rTab : rMark)
772 {
773 if (rTab >= nTabCount)
774 break;
775
776 if (rTab != nStartTab)
777 pUndoDoc->AddUndoTab( rTab, rTab );
778 }
779
780 ScRange aCopyRange = aMarkRange;
781 aCopyRange.aStart.SetTab(0);
782 aCopyRange.aEnd.SetTab(nTabCount-1);
783 rDoc.CopyToDocument(aCopyRange, InsertDeleteFlags::CONTENTS, true, *pUndoDoc, &aMultiMark);
784
786 std::make_unique<ScUndoTransliterate>( &rDocShell, aMultiMark, std::move(pUndoDoc), nType ) );
787 }
788
789 rDoc.TransliterateText( aMultiMark, nType );
790
791 if (!AdjustRowHeight( aMarkRange, true, true ))
793
794 aModificator.SetDocumentModified();
795
796 return true;
797}
798
799bool ScDocFunc::SetNormalString( bool& o_rbNumFmtSet, const ScAddress& rPos, const OUString& rText, bool bApi )
800{
801 ScDocShellModificator aModificator( rDocShell );
803
804 bool bUndo(rDoc.IsUndoEnabled());
805 ScEditableTester aTester( rDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
806 if (!aTester.IsEditable())
807 {
808 if (!bApi)
810 return false;
811 }
812
813 bool bEditDeleted = (rDoc.GetCellType(rPos) == CELLTYPE_EDIT);
815
816 if (bUndo)
817 {
818 ScUndoEnterData::Value aOldValue;
819
820 aOldValue.mnTab = rPos.Tab();
821 aOldValue.maCell.assign(rDoc, rPos);
822
823 const ScPatternAttr* pPattern = rDoc.GetPattern( rPos.Col(),rPos.Row(),rPos.Tab() );
824 if ( const SfxUInt32Item* pItem = pPattern->GetItemSet().GetItemIfSet(
825 ATTR_VALUE_FORMAT,false) )
826 {
827 aOldValue.mbHasFormat = true;
828 aOldValue.mnFormat = pItem->GetValue();
829 }
830 else
831 aOldValue.mbHasFormat = false;
832
833 aOldValues.push_back(aOldValue);
834 }
835
836 o_rbNumFmtSet = rDoc.SetString( rPos.Col(), rPos.Row(), rPos.Tab(), rText );
837
838 if (bUndo)
839 {
840 // because of ChangeTracking, UndoAction can be created only after SetString was called
842 std::make_unique<ScUndoEnterData>(&rDocShell, rPos, aOldValues, rText, nullptr));
843 }
844
845 if ( bEditDeleted || rDoc.HasAttrib( ScRange(rPos), HasAttrFlags::NeedHeight ) )
846 AdjustRowHeight( ScRange(rPos), true, bApi );
847
848 rDocShell.PostPaintCell( rPos );
849 aModificator.SetDocumentModified();
850
851 // notify input handler here the same way as in PutCell
852 if (bApi)
853 NotifyInputHandler( rPos );
854
855 const SfxUInt32Item* pItem = rDoc.GetAttr(rPos, ATTR_VALIDDATA);
856 const ScValidationData* pData = rDoc.GetValidationEntry(pItem->GetValue());
857 if (pData)
858 {
859 ScRefCellValue aCell(rDoc, rPos);
860 if (pData->IsDataValid(aCell, rPos))
861 ScDetectiveFunc(rDoc, rPos.Tab()).DeleteCirclesAt(rPos.Col(), rPos.Row());
862 }
863
864 return true;
865}
866
867bool ScDocFunc::SetValueCell( const ScAddress& rPos, double fVal, bool bInteraction )
868{
869 ScDocShellModificator aModificator( rDocShell );
871 bool bUndo = rDoc.IsUndoEnabled();
872
873 bool bHeight = rDoc.HasAttrib(rPos, HasAttrFlags::NeedHeight);
874
875 ScCellValue aOldVal;
876 if (bUndo)
877 aOldVal.assign(rDoc, rPos);
878
879 rDoc.SetValue(rPos, fVal);
880
881 if (bUndo)
882 {
884 ScCellValue aNewVal;
885 aNewVal.assign(rDoc, rPos);
886 pUndoMgr->AddUndoAction(std::make_unique<ScUndoSetCell>(&rDocShell, rPos, aOldVal, aNewVal));
887 }
888
889 if (bHeight)
890 AdjustRowHeight(rPos, true, !bInteraction);
891
892 rDocShell.PostPaintCell( rPos );
893 aModificator.SetDocumentModified();
894
895 // #103934#; notify editline and cell in edit mode
896 if (!bInteraction)
897 NotifyInputHandler( rPos );
898
899 return true;
900}
901
902void ScDocFunc::SetValueCells( const ScAddress& rPos, const std::vector<double>& aVals, bool bInteraction )
903{
905
906 // Check for invalid range.
907 SCROW nLastRow = rPos.Row() + aVals.size() - 1;
908 if (nLastRow > rDoc.MaxRow())
909 // out of bound.
910 return;
911
912 ScRange aRange(rPos);
913 aRange.aEnd.SetRow(nLastRow);
914
915 ScDocShellModificator aModificator(rDocShell);
916
917 if (rDoc.IsUndoEnabled())
918 {
919 std::unique_ptr<sc::UndoSetCells> pUndoObj(new sc::UndoSetCells(&rDocShell, rPos));
920 rDoc.TransferCellValuesTo(rPos, aVals.size(), pUndoObj->GetOldValues());
921 pUndoObj->SetNewValues(aVals);
923 pUndoMgr->AddUndoAction(std::move(pUndoObj));
924 }
925
926 rDoc.SetValues(rPos, aVals);
927
929 aModificator.SetDocumentModified();
930
931 // #103934#; notify editline and cell in edit mode
932 if (!bInteraction)
933 NotifyInputHandler(rPos);
934}
935
936bool ScDocFunc::SetStringCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction )
937{
938 ScDocShellModificator aModificator( rDocShell );
940 bool bUndo = rDoc.IsUndoEnabled();
941
942 bool bHeight = rDoc.HasAttrib(rPos, HasAttrFlags::NeedHeight);
943
944 ScCellValue aOldVal;
945 if (bUndo)
946 aOldVal.assign(rDoc, rPos);
947
948 ScSetStringParam aParam;
949 aParam.setTextInput();
950 rDoc.SetString(rPos, rStr, &aParam);
951
952 if (bUndo)
953 {
955 ScCellValue aNewVal;
956 aNewVal.assign(rDoc, rPos);
957 pUndoMgr->AddUndoAction(std::make_unique<ScUndoSetCell>(&rDocShell, rPos, aOldVal, aNewVal));
958 }
959
960 if (bHeight)
961 AdjustRowHeight(rPos, true, !bInteraction);
962
963 rDocShell.PostPaintCell( rPos );
964 aModificator.SetDocumentModified();
965
966 // #103934#; notify editline and cell in edit mode
967 if (!bInteraction)
968 NotifyInputHandler( rPos );
969
970 return true;
971}
972
973bool ScDocFunc::SetEditCell( const ScAddress& rPos, const EditTextObject& rStr, bool bInteraction )
974{
975 ScDocShellModificator aModificator( rDocShell );
977 bool bUndo = rDoc.IsUndoEnabled();
978
979 bool bHeight = rDoc.HasAttrib(rPos, HasAttrFlags::NeedHeight);
980
981 ScCellValue aOldVal;
982 if (bUndo)
983 aOldVal.assign(rDoc, rPos);
984
985 rDoc.SetEditText(rPos, rStr.Clone());
986
987 if (bUndo)
988 {
990 ScCellValue aNewVal;
991 aNewVal.assign(rDoc, rPos);
992 pUndoMgr->AddUndoAction(std::make_unique<ScUndoSetCell>(&rDocShell, rPos, aOldVal, aNewVal));
993 }
994
995 if (bHeight)
996 AdjustRowHeight(rPos, true, !bInteraction);
997
998 rDocShell.PostPaintCell( rPos );
999 aModificator.SetDocumentModified();
1000
1001 // #103934#; notify editline and cell in edit mode
1002 if (!bInteraction)
1003 NotifyInputHandler( rPos );
1004
1005 return true;
1006}
1007
1008bool ScDocFunc::SetStringOrEditCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction )
1009{
1011
1012 if (ScStringUtil::isMultiline(rStr))
1013 {
1014 ScFieldEditEngine& rEngine = rDoc.GetEditEngine();
1015 rEngine.SetTextCurrentDefaults(rStr);
1016 std::unique_ptr<EditTextObject> pEditText(rEngine.CreateTextObject());
1017 return SetEditCell(rPos, *pEditText, bInteraction);
1018 }
1019 else
1020 return SetStringCell(rPos, rStr, bInteraction);
1021}
1022
1023bool ScDocFunc::SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, bool bInteraction )
1024{
1025 std::unique_ptr<ScFormulaCell> xCell(pCell);
1026
1027 ScDocShellModificator aModificator( rDocShell );
1029 bool bUndo = rDoc.IsUndoEnabled();
1030
1031 bool bHeight = rDoc.HasAttrib(rPos, HasAttrFlags::NeedHeight);
1032
1033 ScCellValue aOldVal;
1034 if (bUndo)
1035 aOldVal.assign(rDoc, rPos);
1036
1037 pCell = rDoc.SetFormulaCell(rPos, xCell.release());
1038
1039 // For performance reasons API calls may disable calculation while
1040 // operating and recalculate once when done. If through user interaction
1041 // and AutoCalc is disabled, calculate the formula (without its
1042 // dependencies) once so the result matches the current document's content.
1043 if (bInteraction && !rDoc.GetAutoCalc() && pCell)
1044 {
1045 // calculate just the cell once and set Dirty again
1046 pCell->Interpret();
1047 pCell->SetDirtyVar();
1048 rDoc.PutInFormulaTree( pCell);
1049 }
1050
1051 if (bUndo)
1052 {
1054 ScCellValue aNewVal;
1055 aNewVal.assign(rDoc, rPos);
1056 pUndoMgr->AddUndoAction(std::make_unique<ScUndoSetCell>(&rDocShell, rPos, aOldVal, aNewVal));
1057 }
1058
1059 if (bHeight)
1060 AdjustRowHeight(rPos, true, !bInteraction);
1061
1062 rDocShell.PostPaintCell( rPos );
1063 aModificator.SetDocumentModified();
1064
1065 // #103934#; notify editline and cell in edit mode
1066 if (!bInteraction)
1067 NotifyInputHandler( rPos );
1068
1069 return true;
1070}
1071
1072bool ScDocFunc::SetFormulaCells( const ScAddress& rPos, std::vector<ScFormulaCell*>& rCells, bool bInteraction )
1073{
1075
1076 const size_t nLength = rCells.size();
1077 if (rPos.Row() + nLength - 1 > o3tl::make_unsigned(rDoc.MaxRow()))
1078 // out of bound
1079 return false;
1080
1081 ScRange aRange(rPos);
1082 aRange.aEnd.IncRow(nLength - 1);
1083
1084 ScDocShellModificator aModificator( rDocShell );
1085 bool bUndo = rDoc.IsUndoEnabled();
1086
1087 std::unique_ptr<sc::UndoSetCells> pUndoObj;
1088 if (bUndo)
1089 {
1090 pUndoObj.reset(new sc::UndoSetCells(&rDocShell, rPos));
1091 rDoc.TransferCellValuesTo(rPos, nLength, pUndoObj->GetOldValues());
1092 }
1093
1094 rDoc.SetFormulaCells(rPos, rCells);
1095
1096 // For performance reasons API calls may disable calculation while
1097 // operating and recalculate once when done. If through user interaction
1098 // and AutoCalc is disabled, calculate the formula (without its
1099 // dependencies) once so the result matches the current document's content.
1100 if (bInteraction && !rDoc.GetAutoCalc())
1101 {
1102 for (auto* pCell : rCells)
1103 {
1104 // calculate just the cell once and set Dirty again
1105 pCell->Interpret();
1106 pCell->SetDirtyVar();
1107 rDoc.PutInFormulaTree( pCell);
1108 }
1109 }
1110
1111 if (bUndo)
1112 {
1113 pUndoObj->SetNewValues(rCells);
1115 pUndoMgr->AddUndoAction(std::move(pUndoObj));
1116 }
1117
1119 aModificator.SetDocumentModified();
1120
1121 // #103934#; notify editline and cell in edit mode
1122 if (!bInteraction)
1123 NotifyInputHandler( rPos );
1124
1125 return true;
1126}
1127
1129{
1131 if ( !(pViewSh && pViewSh->GetViewData().GetDocShell() == &rDocShell) )
1132 return;
1133
1134 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
1135 if ( pInputHdl && pInputHdl->GetCursorPos() == rPos )
1136 {
1137 bool bIsEditMode(pInputHdl->IsEditMode());
1138
1139 // set modified if in editmode, because so the string is not set in the InputWindow like in the cell
1140 // (the cell shows the same like the InputWindow)
1141 if (bIsEditMode)
1142 pInputHdl->SetModified();
1143 pViewSh->UpdateInputHandler(false, !bIsEditMode);
1144 }
1145}
1146
1147namespace {
1148
1149 struct ScMyRememberItem
1150 {
1151 sal_Int32 nIndex;
1152 SfxItemSet aItemSet;
1153
1154 ScMyRememberItem(SfxItemSet _aItemSet, sal_Int32 nTempIndex) :
1155 nIndex(nTempIndex), aItemSet(std::move(_aItemSet)) {}
1156 };
1157
1158}
1159
1160void ScDocFunc::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine, bool bApi )
1161{
1162 // PutData calls PutCell or SetNormalString
1163
1164 bool bRet = false;
1166 ScEditAttrTester aTester( &rEngine );
1167 bool bEditCell = aTester.NeedsObject();
1168 if ( bEditCell )
1169 {
1170 // #i61702# With bLoseContent set, the content of rEngine isn't restored
1171 // (used in loading XML, where after the removeActionLock call the API object's
1172 // EditEngine isn't accessed again.
1173 bool bLoseContent = rDoc.IsImportingXML();
1174
1175 const bool bUpdateMode = rEngine.SetUpdateLayout(false);
1176
1177 std::vector<std::unique_ptr<ScMyRememberItem>> aRememberItems;
1178
1179 // All paragraph attributes must be removed before calling CreateTextObject,
1180 // not only alignment, so the object doesn't contain the cell attributes as
1181 // paragraph attributes. Before removing the attributes store them in a vector to
1182 // set them back to the EditEngine.
1183 sal_Int32 nCount = rEngine.GetParagraphCount();
1184 for (sal_Int32 i=0; i<nCount; i++)
1185 {
1186 const SfxItemSet& rOld = rEngine.GetParaAttribs( i );
1187 if ( rOld.Count() )
1188 {
1189 if ( !bLoseContent )
1190 {
1191 aRememberItems.push_back(std::make_unique<ScMyRememberItem>(rEngine.GetParaAttribs(i), i));
1192 }
1193 rEngine.SetParaAttribs( i, SfxItemSet( *rOld.GetPool(), rOld.GetRanges() ) );
1194 }
1195 }
1196
1197 // A copy of pNewData will be stored in the cell.
1198 std::unique_ptr<EditTextObject> pNewData(rEngine.CreateTextObject());
1199 bRet = SetEditCell(rPos, *pNewData, !bApi);
1200
1201 // Set the paragraph attributes back to the EditEngine.
1202 for (const auto& rxItem : aRememberItems)
1203 {
1204 rEngine.SetParaAttribs(rxItem->nIndex, rxItem->aItemSet);
1205 }
1206
1207 // #i61702# if the content isn't accessed, there's no need to set the UpdateMode again
1208 if ( bUpdateMode && !bLoseContent )
1209 rEngine.SetUpdateLayout(true);
1210 }
1211 else
1212 {
1213 OUString aText = rEngine.GetText();
1214 if (aText.isEmpty())
1215 {
1216 bool bNumFmtSet = false;
1217 bRet = SetNormalString( bNumFmtSet, rPos, aText, bApi );
1218 }
1219 else
1220 bRet = SetStringCell(rPos, aText, !bApi);
1221 }
1222
1223 if ( !(bRet && aTester.NeedsCellAttr()) )
1224 return;
1225
1226 const SfxItemSet& rEditAttr = aTester.GetAttribs();
1227 ScPatternAttr aPattern( rDoc.GetPool() );
1228 aPattern.GetFromEditItemSet( &rEditAttr );
1229 aPattern.DeleteUnchanged( rDoc.GetPattern( rPos.Col(), rPos.Row(), rPos.Tab() ) );
1230 aPattern.GetItemSet().ClearItem( ATTR_HOR_JUSTIFY ); // wasn't removed above if no edit object
1231 if ( aPattern.GetItemSet().Count() > 0 )
1232 {
1233 ScMarkData aMark(rDoc.GetSheetLimits());
1234 aMark.SelectTable( rPos.Tab(), true );
1235 aMark.SetMarkArea( ScRange( rPos ) );
1236 ApplyAttributes( aMark, aPattern, bApi );
1237 }
1238}
1239
1241 const ScAddress& rPos, const OUString& rText, bool bInterpret, bool bEnglish, bool bApi,
1242 const formula::FormulaGrammar::Grammar eGrammar )
1243{
1244 bool bSet = false;
1245 if ( bInterpret )
1246 {
1247 if ( bEnglish )
1248 {
1250
1251 ::std::optional<ScExternalRefManager::ApiGuard> pExtRefGuard;
1252 if (bApi)
1253 pExtRefGuard.emplace(rDoc);
1254
1255 ScInputStringType aRes =
1257
1258 switch (aRes.meType)
1259 {
1261 bSet = SetFormulaCell(rPos, new ScFormulaCell(rDoc, rPos, aRes.maText, eGrammar), !bApi);
1262 break;
1264 bSet = SetValueCell(rPos, aRes.mfValue, !bApi);
1265 break;
1267 bSet = SetStringOrEditCell(rPos, aRes.maText, !bApi);
1268 break;
1269 default:
1270 ;
1271 }
1272 }
1273 // otherwise keep Null -> SetString with local formulas/number formats
1274 }
1275 else if (!rText.isEmpty())
1276 {
1277 bSet = SetStringOrEditCell(rPos, rText, !bApi);
1278 }
1279
1280 if (!bSet)
1281 {
1282 bool bNumFmtSet = false;
1283 bSet = SetNormalString( bNumFmtSet, rPos, rText, bApi );
1284 }
1285 return bSet;
1286}
1287
1288bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow )
1289{
1291 ScPostIt* pNote = rDoc.GetNote( rPos );
1292 if( !pNote || (bShow == pNote->IsCaptionShown()) ||
1294 return false;
1295
1296 // move the caption to internal or hidden layer and create undo action
1297 pNote->ShowCaption( rPos, bShow );
1298 if( rDoc.IsUndoEnabled() )
1299 rDocShell.GetUndoManager()->AddUndoAction( std::make_unique<ScUndoShowHideNote>( rDocShell, rPos, bShow ) );
1300
1301 rDoc.SetStreamValid(rPos.Tab(), false);
1302
1304
1305 if (ScViewData* pViewData = ScDocShell::GetViewData())
1306 {
1307 if (ScDrawView* pDrawView = pViewData->GetScDrawView())
1308 pDrawView->SyncForGrid( pNote->GetCaption());
1309 }
1310
1312
1313 return true;
1314}
1315
1316void ScDocFunc::SetNoteText( const ScAddress& rPos, const OUString& rText, bool bApi )
1317{
1318 ScDocShellModificator aModificator( rDocShell );
1319
1321 ScEditableTester aTester( rDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
1322 if (!aTester.IsEditable())
1323 {
1324 if (!bApi)
1326 return;
1327 }
1328
1329 OUString aNewText = convertLineEnd(rText, GetSystemLineEnd());
1330
1331 if( ScPostIt* pNote = (!aNewText.isEmpty()) ? rDoc.GetOrCreateNote( rPos ) : rDoc.GetNote(rPos) )
1332 pNote->SetText( rPos, aNewText );
1333
1335
1336 rDoc.SetStreamValid(rPos.Tab(), false);
1337
1338 rDocShell.PostPaintCell( rPos );
1339 aModificator.SetDocumentModified();
1340}
1341
1342void ScDocFunc::ReplaceNote( const ScAddress& rPos, const OUString& rNoteText, const OUString* pAuthor, const OUString* pDate, bool bApi )
1343{
1344 ScDocShellModificator aModificator( rDocShell );
1346 ScEditableTester aTester( rDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
1347 if (aTester.IsEditable())
1348 {
1349 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
1350 SfxUndoManager* pUndoMgr = (pDrawLayer && rDoc.IsUndoEnabled()) ? rDocShell.GetUndoManager() : nullptr;
1351
1352 ScNoteData aOldData;
1353 std::unique_ptr<ScPostIt> pOldNote = rDoc.ReleaseNote( rPos );
1354 sal_uInt32 nNoteId = 0;
1355 if( pOldNote )
1356 {
1357 nNoteId = pOldNote->GetId();
1358 // ensure existing caption object before draw undo tracking starts
1359 pOldNote->GetOrCreateCaption( rPos );
1360 // rescue note data for undo
1361 aOldData = pOldNote->GetNoteData();
1362 }
1363
1364 // collect drawing undo actions for deleting/inserting caption objects
1365 if( pUndoMgr )
1366 pDrawLayer->BeginCalcUndo(false);
1367
1368 // delete the note (creates drawing undo action for the caption object)
1369 bool hadOldNote(pOldNote);
1370 pOldNote.reset();
1371
1372 // create new note (creates drawing undo action for the new caption object)
1373 ScNoteData aNewData;
1374 ScPostIt* pNewNote = nullptr;
1375 if( (pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false, true, nNoteId )) )
1376 {
1377 if( pAuthor ) pNewNote->SetAuthor( *pAuthor );
1378 if( pDate ) pNewNote->SetDate( *pDate );
1379
1380 // rescue note data for undo
1381 aNewData = pNewNote->GetNoteData();
1382 }
1383
1384 // create the undo action
1385 if( pUndoMgr && (aOldData.mxCaption || aNewData.mxCaption) )
1386 pUndoMgr->AddUndoAction( std::make_unique<ScUndoReplaceNote>( rDocShell, rPos, aOldData, aNewData, pDrawLayer->GetCalcUndo() ) );
1387
1388 // repaint cell (to make note marker visible)
1389 rDocShell.PostPaintCell( rPos );
1390
1391 rDoc.SetStreamValid(rPos.Tab(), false);
1392
1393 aModificator.SetDocumentModified();
1394
1395 // Let our LOK clients know about the new/modified note
1396 if (pNewNote)
1397 {
1399 &rDoc, rPos, pNewNote);
1400 }
1401 }
1402 else if (!bApi)
1403 {
1405 }
1406}
1407
1408ScPostIt* ScDocFunc::ImportNote( const ScAddress& rPos, const OUString& rNoteText )
1409{
1410 ScDocShellModificator aModificator( rDocShell );
1412
1413 std::unique_ptr<ScPostIt> pOldNote = rDoc.ReleaseNote( rPos );
1414 SAL_WARN_IF(pOldNote, "sc.ui", "imported data has >1 notes on same cell? at pos " << rPos);
1415
1416 // create new note
1417 ScPostIt* pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false, true, /*nNoteId*/0 );
1418
1419 rDoc.SetStreamValid(rPos.Tab(), false);
1420
1421 aModificator.SetDocumentModified();
1422
1423 return pNewNote;
1424}
1425
1426bool ScDocFunc::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
1427 bool bApi )
1428{
1430 bool bRecord = true;
1431 if ( !rDoc.IsUndoEnabled() )
1432 bRecord = false;
1433
1434 bool bImportingXML = rDoc.IsImportingXML();
1435 // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1436 // #i62483# When loading XML, the check can be skipped altogether.
1437 bool bOnlyNotBecauseOfMatrix;
1438 if ( !bImportingXML && !rDoc.IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
1439 && !bOnlyNotBecauseOfMatrix )
1440 {
1441 if (!bApi)
1442 rDocShell.ErrorMessage(STR_PROTECTIONERR);
1443 return false;
1444 }
1445
1446 ScDocShellModificator aModificator( rDocShell );
1447
1449
1450 ScRange aMultiRange;
1451 bool bMulti = rMark.IsMultiMarked();
1452 if ( bMulti )
1453 aMultiRange = rMark.GetMultiMarkArea();
1454 else
1455 aMultiRange = rMark.GetMarkArea();
1456
1457 if ( bRecord )
1458 {
1460 pUndoDoc->InitUndo( rDoc, aMultiRange.aStart.Tab(), aMultiRange.aEnd.Tab() );
1461 rDoc.CopyToDocument(aMultiRange, InsertDeleteFlags::ATTRIB, bMulti, *pUndoDoc, &rMark);
1462
1464 std::make_unique<ScUndoSelectionAttr>(
1465 &rDocShell, rMark,
1466 aMultiRange.aStart.Col(), aMultiRange.aStart.Row(), aMultiRange.aStart.Tab(),
1467 aMultiRange.aEnd.Col(), aMultiRange.aEnd.Row(), aMultiRange.aEnd.Tab(),
1468 std::move(pUndoDoc), bMulti, &rPattern ) );
1469 }
1470
1471 // While loading XML it is not necessary to ask HasAttrib. It needs too much time.
1472 sal_uInt16 nExtFlags = 0;
1473 if ( !bImportingXML )
1474 rDocShell.UpdatePaintExt( nExtFlags, aMultiRange ); // content before the change
1475
1476 bool bChanged = false;
1477 rDoc.ApplySelectionPattern( rPattern, rMark, nullptr, &bChanged );
1478
1479 if(bChanged)
1480 {
1481 if ( !bImportingXML )
1482 rDocShell.UpdatePaintExt( nExtFlags, aMultiRange ); // content after the change
1483
1484 if (!AdjustRowHeight( aMultiRange, true, bApi ))
1485 rDocShell.PostPaint( aMultiRange, PaintPartFlags::Grid, nExtFlags );
1486 else if (nExtFlags & SC_PF_LINES)
1487 lcl_PaintAbove( rDocShell, aMultiRange ); // because of lines above the range
1488
1489 aModificator.SetDocumentModified();
1490 }
1491
1492 return true;
1493}
1494
1495bool ScDocFunc::ApplyStyle( const ScMarkData& rMark, const OUString& rStyleName,
1496 bool bApi )
1497{
1499 bool bRecord = true;
1500 if ( !rDoc.IsUndoEnabled() )
1501 bRecord = false;
1502
1503 bool bImportingXML = rDoc.IsImportingXML();
1504 // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1505 // #i62483# When loading XML, the check can be skipped altogether.
1506 bool bOnlyNotBecauseOfMatrix;
1507 if ( !bImportingXML && !rDoc.IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
1508 && !bOnlyNotBecauseOfMatrix )
1509 {
1510 if (!bApi)
1511 rDocShell.ErrorMessage(STR_PROTECTIONERR);
1512 return false;
1513 }
1514
1515 ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>( rDoc.GetStyleSheetPool()->Find(
1516 rStyleName, SfxStyleFamily::Para ));
1517 if (!pStyleSheet)
1518 return false;
1519
1520 ScDocShellModificator aModificator( rDocShell );
1521
1522 ScRange aMultiRange;
1523 bool bMulti = rMark.IsMultiMarked();
1524 if ( bMulti )
1525 aMultiRange = rMark.GetMultiMarkArea();
1526 else
1527 aMultiRange = rMark.GetMarkArea();
1528
1529 if ( bRecord )
1530 {
1532 SCTAB nStartTab = aMultiRange.aStart.Tab();
1533 SCTAB nTabCount = rDoc.GetTableCount();
1534 pUndoDoc->InitUndo( rDoc, nStartTab, nStartTab );
1535 for (const auto& rTab : rMark)
1536 {
1537 if (rTab >= nTabCount)
1538 break;
1539
1540 if (rTab != nStartTab)
1541 pUndoDoc->AddUndoTab( rTab, rTab );
1542 }
1543
1544 ScRange aCopyRange = aMultiRange;
1545 aCopyRange.aStart.SetTab(0);
1546 aCopyRange.aEnd.SetTab(nTabCount-1);
1547 rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, bMulti, *pUndoDoc, &rMark );
1548
1550 std::make_unique<ScUndoSelectionStyle>(
1551 &rDocShell, rMark, aMultiRange, rStyleName, std::move(pUndoDoc) ) );
1552
1553 }
1554
1555 rDoc.ApplySelectionStyle( *pStyleSheet, rMark );
1556
1557 if (!AdjustRowHeight( aMultiRange, true, bApi ))
1559
1560 aModificator.SetDocumentModified();
1561
1562 return true;
1563}
1564
1565namespace {
1566
1574bool canInsertCellsByPivot(const ScRange& rRange, const ScMarkData& rMarkData, InsCellCmd eCmd, const ScDocument& rDoc)
1575{
1576 if (!rDoc.HasPivotTable())
1577 // This document has no pivot tables.
1578 return true;
1579
1580 const ScDPCollection* pDPs = rDoc.GetDPCollection();
1581
1582 ScRange aRange(rRange); // local copy
1583 switch (eCmd)
1584 {
1585 case INS_INSROWS_BEFORE:
1586 {
1587 aRange.aStart.SetCol(0);
1588 aRange.aEnd.SetCol(rDoc.MaxCol());
1589 [[fallthrough]];
1590 }
1591 case INS_CELLSDOWN:
1592 {
1593 auto bIntersects = std::any_of(rMarkData.begin(), rMarkData.end(), [&pDPs, &aRange](const SCTAB& rTab) {
1594 return pDPs->IntersectsTableByColumns(aRange.aStart.Col(), aRange.aEnd.Col(), aRange.aStart.Row(), rTab); });
1595 if (bIntersects)
1596 // This column range cuts through at least one pivot table. Not good.
1597 return false;
1598
1599 // Start row must be either at the top or above any pivot tables.
1600 if (aRange.aStart.Row() < 0)
1601 // I don't know how to handle this case.
1602 return false;
1603
1604 if (aRange.aStart.Row() == 0)
1605 // First row is always allowed.
1606 return true;
1607
1608 ScRange aTest(aRange);
1609 aTest.aStart.IncRow(-1); // Test one row up.
1610 aTest.aEnd.SetRow(aTest.aStart.Row());
1611 for (const auto& rTab : rMarkData)
1612 {
1613 aTest.aStart.SetTab(rTab);
1614 aTest.aEnd.SetTab(rTab);
1615 if (pDPs->HasTable(aTest))
1616 return false;
1617 }
1618 }
1619 break;
1620 case INS_INSCOLS_BEFORE:
1621 {
1622 aRange.aStart.SetRow(0);
1623 aRange.aEnd.SetRow(rDoc.MaxRow());
1624 [[fallthrough]];
1625 }
1626 case INS_CELLSRIGHT:
1627 {
1628 auto bIntersects = std::any_of(rMarkData.begin(), rMarkData.end(), [&pDPs, &aRange](const SCTAB& rTab) {
1629 return pDPs->IntersectsTableByRows(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Row(), rTab); });
1630 if (bIntersects)
1631 // This column range cuts through at least one pivot table. Not good.
1632 return false;
1633
1634 // Start row must be either at the top or above any pivot tables.
1635 if (aRange.aStart.Col() < 0)
1636 // I don't know how to handle this case.
1637 return false;
1638
1639 if (aRange.aStart.Col() == 0)
1640 // First row is always allowed.
1641 return true;
1642
1643 ScRange aTest(aRange);
1644 aTest.aStart.IncCol(-1); // Test one column to the left.
1645 aTest.aEnd.SetCol(aTest.aStart.Col());
1646 for (const auto& rTab : rMarkData)
1647 {
1648 aTest.aStart.SetTab(rTab);
1649 aTest.aEnd.SetTab(rTab);
1650 if (pDPs->HasTable(aTest))
1651 return false;
1652 }
1653 }
1654 break;
1655 default:
1656 ;
1657 }
1658 return true;
1659}
1660
1668bool canDeleteCellsByPivot(const ScRange& rRange, const ScMarkData& rMarkData, DelCellCmd eCmd, const ScDocument& rDoc)
1669{
1670 if (!rDoc.HasPivotTable())
1671 // This document has no pivot tables.
1672 return true;
1673
1674 const ScDPCollection* pDPs = rDoc.GetDPCollection();
1675
1676 ScRange aRange(rRange); // local copy
1677
1678 switch (eCmd)
1679 {
1680 case DelCellCmd::Rows:
1681 {
1682 aRange.aStart.SetCol(0);
1683 aRange.aEnd.SetCol(rDoc.MaxCol());
1684 [[fallthrough]];
1685 }
1687 {
1688 auto bIntersects = std::any_of(rMarkData.begin(), rMarkData.end(), [&pDPs, &aRange](const SCTAB& rTab) {
1689 return pDPs->IntersectsTableByColumns(aRange.aStart.Col(), aRange.aEnd.Col(), aRange.aStart.Row(), rTab); });
1690 if (bIntersects)
1691 // This column range cuts through at least one pivot table. Not good.
1692 return false;
1693
1694 ScRange aTest(aRange);
1695 for (const auto& rTab : rMarkData)
1696 {
1697 aTest.aStart.SetTab(rTab);
1698 aTest.aEnd.SetTab(rTab);
1699 if (pDPs->HasTable(aTest))
1700 return false;
1701 }
1702 }
1703 break;
1704 case DelCellCmd::Cols:
1705 {
1706 aRange.aStart.SetRow(0);
1707 aRange.aEnd.SetRow(rDoc.MaxRow());
1708 [[fallthrough]];
1709 }
1711 {
1712 auto bIntersects = std::any_of(rMarkData.begin(), rMarkData.end(), [&pDPs, &aRange](const SCTAB& rTab) {
1713 return pDPs->IntersectsTableByRows(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Row(), rTab); });
1714 if (bIntersects)
1715 // This column range cuts through at least one pivot table. Not good.
1716 return false;
1717
1718 ScRange aTest(aRange);
1719 for (const auto& rTab : rMarkData)
1720 {
1721 aTest.aStart.SetTab(rTab);
1722 aTest.aEnd.SetTab(rTab);
1723 if (pDPs->HasTable(aTest))
1724 return false;
1725 }
1726 }
1727 break;
1728 default:
1729 ;
1730 }
1731 return true;
1732}
1733
1734}
1735
1736bool ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark, InsCellCmd eCmd,
1737 bool bRecord, bool bApi, bool bPartOfPaste )
1738{
1739 ScDocShellModificator aModificator( rDocShell );
1741
1743 ((eCmd == INS_CELLSDOWN && (rRange.aStart.Col() != 0 || rRange.aEnd.Col() != rDoc.MaxCol())) ||
1744 (eCmd == INS_CELLSRIGHT && (rRange.aStart.Row() != 0 || rRange.aEnd.Row() != rDoc.MaxRow()))))
1745 {
1746 // We should not reach this via UI disabled slots.
1747 assert(bApi);
1748 SAL_WARN("sc.ui","ScDocFunc::InsertCells - no change-tracking of partial cell shift");
1749 return false;
1750 }
1751
1752 ScRange aTargetRange( rRange );
1753
1754 // If insertion is for full cols/rows and after the current
1755 // selection, then shift the range accordingly
1756 if ( eCmd == INS_INSROWS_AFTER )
1757 {
1758 ScRange aErrorRange( ScAddress::UNINITIALIZED );
1759 if (!aTargetRange.Move(0, rRange.aEnd.Row() - rRange.aStart.Row() + 1, 0, aErrorRange, rDoc))
1760 {
1761 return false;
1762 }
1763 }
1764 if ( eCmd == INS_INSCOLS_AFTER )
1765 {
1766 ScRange aErrorRange( ScAddress::UNINITIALIZED );
1767 if (!aTargetRange.Move(rRange.aEnd.Col() - rRange.aStart.Col() + 1, 0, 0, aErrorRange, rDoc))
1768 {
1769 return false;
1770 }
1771 }
1772
1773 SCCOL nStartCol = aTargetRange.aStart.Col();
1774 SCROW nStartRow = aTargetRange.aStart.Row();
1775 SCTAB nStartTab = aTargetRange.aStart.Tab();
1776 SCCOL nEndCol = aTargetRange.aEnd.Col();
1777 SCROW nEndRow = aTargetRange.aEnd.Row();
1778 SCTAB nEndTab = aTargetRange.aEnd.Tab();
1779
1780 if ( !rDoc.ValidRow(nStartRow) || !rDoc.ValidRow(nEndRow) )
1781 {
1782 OSL_FAIL("invalid row in InsertCells");
1783 return false;
1784 }
1785
1786 SCTAB nTabCount = rDoc.GetTableCount();
1787 SCCOL nPaintStartCol = nStartCol;
1788 SCROW nPaintStartRow = nStartRow;
1789 SCCOL nPaintEndCol = nEndCol;
1790 SCROW nPaintEndRow = nEndRow;
1792 bool bSuccess;
1793
1794 ScTabViewShell* pViewSh = rDocShell.GetBestViewShell(); //preserve current cursor position
1795 SCCOL nCursorCol = 0;
1796 SCROW nCursorRow = 0;
1797 if( pViewSh )
1798 {
1799 nCursorCol = pViewSh->GetViewData().GetCurX();
1800 nCursorRow = pViewSh->GetViewData().GetCurY();
1801 }
1802
1803 if (bRecord && !rDoc.IsUndoEnabled())
1804 bRecord = false;
1805
1806 ScMarkData aMark(rDoc.GetSheetLimits());
1807 if (pTabMark)
1808 aMark = *pTabMark;
1809 else
1810 {
1811 SCTAB nCount = 0;
1812 for( SCTAB i=0; i<nTabCount; i++ )
1813 {
1814 if( !rDoc.IsScenario(i) )
1815 {
1816 nCount++;
1817 if( nCount == nEndTab+1 )
1818 {
1819 aMark.SelectTable( i, true );
1820 break;
1821 }
1822 }
1823 }
1824 }
1825
1826 ScMarkData aFullMark( aMark ); // including scenario sheets
1827 for (const auto& rTab : aMark)
1828 {
1829 if (rTab >= nTabCount)
1830 break;
1831
1832 for( SCTAB j = rTab+1; j<nTabCount && rDoc.IsScenario(j); j++ )
1833 aFullMark.SelectTable( j, true );
1834 }
1835
1836 SCTAB nSelCount = aMark.GetSelectCount();
1837
1838 // Adjust also related scenarios
1839
1840 SCCOL nMergeTestStartCol = nStartCol;
1841 SCROW nMergeTestStartRow = nStartRow;
1842 SCCOL nMergeTestEndCol = nEndCol;
1843 SCROW nMergeTestEndRow = nEndRow;
1844
1845 ScRange aExtendMergeRange( aTargetRange );
1846
1847 if( aTargetRange.aStart == aTargetRange.aEnd && rDoc.HasAttrib(aTargetRange, HasAttrFlags::Merged) )
1848 {
1849 rDoc.ExtendMerge( aExtendMergeRange );
1850 rDoc.ExtendOverlapped( aExtendMergeRange );
1851 nMergeTestEndCol = aExtendMergeRange.aEnd.Col();
1852 nMergeTestEndRow = aExtendMergeRange.aEnd.Row();
1853 nPaintEndCol = nMergeTestEndCol;
1854 nPaintEndRow = nMergeTestEndRow;
1855 }
1856
1857 if ( eCmd == INS_INSROWS_BEFORE || eCmd == INS_INSROWS_AFTER )
1858 {
1859 nMergeTestStartCol = 0;
1860 nMergeTestEndCol = rDoc.MaxCol();
1861 }
1862 if ( eCmd == INS_INSCOLS_BEFORE || eCmd == INS_INSCOLS_AFTER )
1863 {
1864 nMergeTestStartRow = 0;
1865 nMergeTestEndRow = rDoc.MaxRow();
1866 }
1867 if ( eCmd == INS_CELLSDOWN )
1868 nMergeTestEndRow = rDoc.MaxRow();
1869 if ( eCmd == INS_CELLSRIGHT )
1870 nMergeTestEndCol = rDoc.MaxCol();
1871
1872 bool bNeedRefresh = false;
1873
1874 SCCOL nEditTestEndCol = (eCmd==INS_INSCOLS_BEFORE || eCmd==INS_INSCOLS_AFTER) ? rDoc.MaxCol() : nMergeTestEndCol;
1875 SCROW nEditTestEndRow = (eCmd==INS_INSROWS_BEFORE || eCmd==INS_INSROWS_AFTER) ? rDoc.MaxRow() : nMergeTestEndRow;
1876
1877 ScEditableTester aTester;
1878
1879 switch (eCmd)
1880 {
1881 case INS_INSCOLS_BEFORE:
1882 aTester = ScEditableTester(
1883 rDoc, sc::ColRowEditAction::InsertColumnsBefore, nMergeTestStartCol, nMergeTestEndCol, aMark);
1884 break;
1885 case INS_INSCOLS_AFTER:
1886 aTester = ScEditableTester(
1887 rDoc, sc::ColRowEditAction::InsertColumnsAfter, nMergeTestStartCol, nMergeTestEndCol, aMark);
1888 break;
1889 case INS_INSROWS_BEFORE:
1890 aTester = ScEditableTester(
1891 rDoc, sc::ColRowEditAction::InsertRowsBefore, nMergeTestStartRow, nMergeTestEndRow, aMark);
1892 break;
1893 case INS_INSROWS_AFTER:
1894 aTester = ScEditableTester(
1895 rDoc, sc::ColRowEditAction::InsertRowsAfter, nMergeTestStartRow, nMergeTestEndRow, aMark);
1896 break;
1897 default:
1898 aTester = ScEditableTester(
1899 rDoc, nMergeTestStartCol, nMergeTestStartRow, nEditTestEndCol, nEditTestEndRow, aMark);
1900 }
1901
1902 if (!aTester.IsEditable())
1903 {
1904 if (!bApi)
1906 return false;
1907 }
1908
1909 // Check if this insertion is allowed with respect to pivot table.
1910 if (!canInsertCellsByPivot(aTargetRange, aMark, eCmd, rDoc))
1911 {
1912 if (!bApi)
1913 rDocShell.ErrorMessage(STR_NO_INSERT_DELETE_OVER_PIVOT_TABLE);
1914 return false;
1915 }
1916
1917 weld::WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important due to TrackFormulas at UpdateReference
1918
1919 ScDocumentUniquePtr pRefUndoDoc;
1920 std::unique_ptr<ScRefUndoData> pUndoData;
1921 if ( bRecord )
1922 {
1923 pRefUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1924 pRefUndoDoc->InitUndo( rDoc, 0, nTabCount-1 );
1925
1926 // pRefUndoDoc is filled in InsertCol / InsertRow
1927
1928 pUndoData.reset(new ScRefUndoData( &rDoc ));
1929
1930 rDoc.BeginDrawUndo();
1931 }
1932
1933 // #i8302 : we unmerge overwhelming ranges, before insertion all the actions are put in the same ListAction
1934 // the patch comes from mloiseleur and maoyg
1935 bool bInsertMerge = false;
1936 std::vector<ScRange> qIncreaseRange;
1937 OUString aUndo = ScResId( STR_UNDO_INSERTCELLS );
1938 if (bRecord)
1939 {
1940 ViewShellId nViewShellId(-1);
1941 if (pViewSh)
1942 nViewShellId = pViewSh->GetViewShellId();
1943 rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo, 0, nViewShellId );
1944 }
1945 std::unique_ptr<ScUndoRemoveMerge> pUndoRemoveMerge;
1946
1947 for (const SCTAB i : aMark)
1948 {
1949 if (i >= nTabCount)
1950 break;
1951
1952 if( rDoc.HasAttrib( nMergeTestStartCol, nMergeTestStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i, HasAttrFlags::Merged | HasAttrFlags::Overlapped ) )
1953 {
1954 if (eCmd==INS_CELLSRIGHT)
1955 bNeedRefresh = true;
1956
1957 SCCOL nMergeStartCol = nMergeTestStartCol;
1958 SCROW nMergeStartRow = nMergeTestStartRow;
1959 SCCOL nMergeEndCol = nMergeTestEndCol;
1960 SCROW nMergeEndRow = nMergeTestEndRow;
1961
1962 rDoc.ExtendMerge( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
1963 rDoc.ExtendOverlapped( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
1964
1965 if(( eCmd == INS_CELLSDOWN && ( nMergeStartCol != nMergeTestStartCol || nMergeEndCol != nMergeTestEndCol )) ||
1966 (eCmd == INS_CELLSRIGHT && ( nMergeStartRow != nMergeTestStartRow || nMergeEndRow != nMergeTestEndRow )) )
1967 {
1968 if (!bApi)
1969 rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
1971 return false;
1972 }
1973
1974 SCCOL nTestCol = -1;
1975 SCROW nTestRow1 = -1;
1976 SCROW nTestRow2 = -1;
1977
1978 ScDocAttrIterator aTestIter( rDoc, i, nMergeTestStartCol, nMergeTestStartRow, nMergeTestEndCol, nMergeTestEndRow );
1979 ScRange aExtendRange( nMergeTestStartCol, nMergeTestStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i );
1980 const ScPatternAttr* pPattern = nullptr;
1981 while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != nullptr )
1982 {
1983 const ScMergeAttr& rMergeFlag = pPattern->GetItem(ATTR_MERGE);
1984 const ScMergeFlagAttr& rMergeFlagAttr = pPattern->GetItem(ATTR_MERGE_FLAG);
1985 ScMF nNewFlags = rMergeFlagAttr.GetValue() & (ScMF::Hor | ScMF::Ver);
1986 if (rMergeFlag.IsMerged() || nNewFlags == ScMF::Hor || nNewFlags == ScMF::Ver)
1987 {
1988 ScRange aRange( nTestCol, nTestRow1, i );
1989 rDoc.ExtendOverlapped(aRange);
1990 rDoc.ExtendMerge(aRange, true);
1991
1992 if( nTestRow1 < nTestRow2 && nNewFlags == ScMF::Hor )
1993 {
1994 for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
1995 {
1996 ScRange aTestRange( nTestCol, nTestRow, i );
1997 rDoc.ExtendOverlapped( aTestRange );
1998 rDoc.ExtendMerge( aTestRange, true);
1999 ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
2000 if( !aExtendRange.Contains( aMergeRange ) )
2001 {
2002 qIncreaseRange.push_back( aTestRange );
2003 bInsertMerge = true;
2004 }
2005 }
2006 }
2007 else
2008 {
2009 ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
2010 if( !aExtendRange.Contains( aMergeRange ) )
2011 {
2012 qIncreaseRange.push_back( aRange );
2013 }
2014 bInsertMerge = true;
2015 }
2016 }
2017 }
2018
2019 if( bInsertMerge )
2020 {
2021 if( eCmd == INS_INSROWS_BEFORE || eCmd == INS_INSROWS_AFTER || eCmd == INS_CELLSDOWN )
2022 {
2023 nStartRow = aExtendMergeRange.aStart.Row();
2024 nEndRow = aExtendMergeRange.aEnd.Row();
2025
2026 if( eCmd == INS_CELLSDOWN )
2027 nEndCol = nMergeTestEndCol;
2028 else
2029 {
2030 nStartCol = 0;
2031 nEndCol = rDoc.MaxCol();
2032 }
2033 }
2034 else if( eCmd == INS_CELLSRIGHT || eCmd == INS_INSCOLS_BEFORE || eCmd == INS_INSCOLS_AFTER )
2035 {
2036
2037 nStartCol = aExtendMergeRange.aStart.Col();
2038 nEndCol = aExtendMergeRange.aEnd.Col();
2039 if( eCmd == INS_CELLSRIGHT )
2040 {
2041 nEndRow = nMergeTestEndRow;
2042 }
2043 else
2044 {
2045 nStartRow = 0;
2046 nEndRow = rDoc.MaxRow();
2047 }
2048 }
2049
2050 if( !qIncreaseRange.empty() )
2051 {
2052 if (bRecord && !pUndoRemoveMerge)
2053 {
2055 pUndoDoc->InitUndo( rDoc, *aMark.begin(), *aMark.rbegin());
2056 pUndoRemoveMerge.reset( new ScUndoRemoveMerge( &rDocShell, rRange, std::move(pUndoDoc) ));
2057 }
2058
2059 for( const ScRange& aRange : qIncreaseRange )
2060 {
2062 {
2063 UnmergeCells( aRange, bRecord, pUndoRemoveMerge.get() );
2064 }
2065 }
2066 }
2067 }
2068 else
2069 {
2070 if (!bApi)
2071 rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
2073 return false;
2074 }
2075 }
2076 }
2077
2078 if (bRecord && pUndoRemoveMerge)
2079 {
2080 rDocShell.GetUndoManager()->AddUndoAction( std::move(pUndoRemoveMerge));
2081 }
2082
2083 switch (eCmd)
2084 {
2085 case INS_CELLSDOWN:
2086 bSuccess = rDoc.InsertRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc.get(), &aFullMark );
2087 nPaintEndRow = rDoc.MaxRow();
2088 break;
2089 case INS_INSROWS_BEFORE:
2090 case INS_INSROWS_AFTER:
2091 bSuccess = rDoc.InsertRow( 0, 0, rDoc.MaxCol(), MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc.get(), &aFullMark );
2092 nPaintStartCol = 0;
2093 nPaintEndCol = rDoc.MaxCol();
2094 nPaintEndRow = rDoc.MaxRow();
2095 nPaintFlags |= PaintPartFlags::Left;
2096 break;
2097 case INS_CELLSRIGHT:
2098 bSuccess = rDoc.InsertCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc.get(), &aFullMark );
2099 nPaintEndCol = rDoc.MaxCol();
2100 break;
2101 case INS_INSCOLS_BEFORE:
2102 case INS_INSCOLS_AFTER:
2103 bSuccess = rDoc.InsertCol( 0, 0, rDoc.MaxRow(), MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc.get(), &aFullMark );
2104 nPaintStartRow = 0;
2105 nPaintEndRow = rDoc.MaxRow();
2106 nPaintEndCol = rDoc.MaxCol();
2107 nPaintFlags |= PaintPartFlags::Top;
2108 break;
2109 default:
2110 OSL_FAIL("Wrong code at inserting");
2111 bSuccess = false;
2112 break;
2113 }
2114
2115 if ( bSuccess )
2116 {
2117 SCTAB nUndoPos = 0;
2118
2119 if ( bRecord )
2120 {
2121 std::unique_ptr<SCTAB[]> pTabs(new SCTAB[nSelCount]);
2122 std::unique_ptr<SCTAB[]> pScenarios(new SCTAB[nSelCount]);
2123 nUndoPos = 0;
2124 for (const auto& rTab : aMark)
2125 {
2126 if (rTab >= nTabCount)
2127 break;
2128
2129 SCTAB nCount = 0;
2130 for( SCTAB j=rTab+1; j<nTabCount && rDoc.IsScenario(j); j++ )
2131 nCount ++;
2132
2133 pScenarios[nUndoPos] = nCount;
2134 pTabs[nUndoPos] = rTab;
2135 nUndoPos ++;
2136 }
2137
2138 if( !bInsertMerge )
2139 {
2141 }
2142
2143 rDocShell.GetUndoManager()->AddUndoAction( std::make_unique<ScUndoInsertCells>(
2144 &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),
2145 nUndoPos, std::move(pTabs), std::move(pScenarios), eCmd, std::move(pRefUndoDoc), std::move(pUndoData), bPartOfPaste ) );
2146 }
2147
2148 // #i8302 : we remerge growing ranges, with the new part inserted
2149
2150 while( !qIncreaseRange.empty() )
2151 {
2152 ScRange aRange = qIncreaseRange.back();
2154 {
2155 switch (eCmd)
2156 {
2157 case INS_CELLSDOWN:
2158 case INS_INSROWS_BEFORE:
2159 case INS_INSROWS_AFTER:
2160 aRange.aEnd.IncRow(static_cast<SCCOL>(nEndRow-nStartRow+1));
2161 break;
2162 case INS_CELLSRIGHT:
2163 case INS_INSCOLS_BEFORE:
2164 case INS_INSCOLS_AFTER:
2165 aRange.aEnd.IncCol(static_cast<SCCOL>(nEndCol-nStartCol+1));
2166 break;
2167 default:
2168 break;
2169 }
2170 ScCellMergeOption aMergeOption(
2171 aRange.aStart.Col(), aRange.aStart.Row(),
2172 aRange.aEnd.Col(), aRange.aEnd.Row() );
2173 aMergeOption.maTabs.insert(aRange.aStart.Tab());
2174 MergeCells(aMergeOption, false, true, true);
2175 }
2176 qIncreaseRange.pop_back();
2177 }
2178
2179 if( bInsertMerge )
2181
2182 for (const SCTAB i : aMark)
2183 {
2184 if (i >= nTabCount)
2185 break;
2186
2187 rDoc.SetDrawPageSize(i);
2188
2189 if (bNeedRefresh)
2190 rDoc.ExtendMerge( nMergeTestStartCol, nMergeTestStartRow, nMergeTestEndCol, nMergeTestEndRow, i, true );
2191 else
2192 rDoc.RefreshAutoFilter( nMergeTestStartCol, nMergeTestStartRow, nMergeTestEndCol, nMergeTestEndRow, i );
2193
2194 if ( eCmd == INS_INSROWS_BEFORE ||eCmd == INS_INSCOLS_BEFORE || eCmd == INS_INSROWS_AFTER ||eCmd == INS_INSCOLS_AFTER )
2195 rDoc.UpdatePageBreaks( i );
2196
2197 sal_uInt16 nExtFlags = 0;
2198 rDocShell.UpdatePaintExt( nExtFlags, nPaintStartCol, nPaintStartRow, i, nPaintEndCol, nPaintEndRow, i );
2199
2200 SCTAB nScenarioCount = 0;
2201
2202 for( SCTAB j = i+1; j<nTabCount && rDoc.IsScenario(j); j++ )
2203 nScenarioCount ++;
2204
2205 bool bAdjusted = ( eCmd == INS_INSROWS_BEFORE || eCmd == INS_INSROWS_AFTER ) ?
2206 AdjustRowHeight(ScRange(0, nStartRow, i, rDoc.MaxCol(), nEndRow, i+nScenarioCount ), true, bApi) :
2207 AdjustRowHeight(ScRange(0, nPaintStartRow, i, rDoc.MaxCol(), nPaintEndRow, i+nScenarioCount ), true, bApi);
2208 if (bAdjusted)
2209 {
2210 // paint only what is not done by AdjustRowHeight
2211 if (nPaintFlags & PaintPartFlags::Top)
2212 rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, i, nPaintEndCol, nPaintEndRow, i+nScenarioCount, PaintPartFlags::Top );
2213 }
2214 else
2215 rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, i, nPaintEndCol, nPaintEndRow, i+nScenarioCount, nPaintFlags, nExtFlags );
2216 }
2217 }
2218 else
2219 {
2220 if( bInsertMerge )
2221 {
2222 while( !qIncreaseRange.empty() )
2223 {
2224 ScRange aRange = qIncreaseRange.back();
2225 ScCellMergeOption aMergeOption(
2226 aRange.aStart.Col(), aRange.aStart.Row(),
2227 aRange.aEnd.Col(), aRange.aEnd.Row() );
2228 MergeCells(aMergeOption, false, true, true);
2229 qIncreaseRange.pop_back();
2230 }
2231
2232 if( pViewSh )
2233 {
2234 pViewSh->MarkRange( aTargetRange, false );
2235 pViewSh->SetCursor( nCursorCol, nCursorRow );
2236 }
2237 }
2238
2241
2242 pRefUndoDoc.reset();
2243 if (!bApi)
2244 rDocShell.ErrorMessage(STR_INSERT_FULL); // column/row full
2245 }
2246
2247 // The cursor position needs to be modified earlier than updating
2248 // any enabled edit view which is triggered by SetDocumentModified below.
2249 if (bSuccess)
2250 {
2251 bool bInsertCols = ( eCmd == INS_INSCOLS_BEFORE || eCmd == INS_INSCOLS_AFTER);
2252 bool bInsertRows = ( eCmd == INS_INSROWS_BEFORE || eCmd == INS_INSROWS_AFTER );
2253
2254 if (bInsertCols)
2255 {
2256 pViewSh->OnLOKInsertDeleteColumn(rRange.aStart.Col(), 1);
2257 }
2258
2259 if (bInsertRows)
2260 {
2261 pViewSh->OnLOKInsertDeleteRow(rRange.aStart.Row(), 1);
2262 }
2263 }
2264
2265 aModificator.SetDocumentModified();
2266
2267 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
2268 return bSuccess;
2269}
2270
2271bool ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, DelCellCmd eCmd,
2272 bool bApi )
2273{
2274 ScDocShellModificator aModificator( rDocShell );
2276
2278 ((eCmd == DelCellCmd::CellsUp && (rRange.aStart.Col() != 0 || rRange.aEnd.Col() != rDoc.MaxCol())) ||
2279 (eCmd == DelCellCmd::CellsLeft && (rRange.aStart.Row() != 0 || rRange.aEnd.Row() != rDoc.MaxRow()))))
2280 {
2281 // We should not reach this via UI disabled slots.
2282 assert(bApi);
2283 SAL_WARN("sc.ui","ScDocFunc::DeleteCells - no change-tracking of partial cell shift");
2284 return false;
2285 }
2286
2287 SCCOL nStartCol = rRange.aStart.Col();
2288 SCROW nStartRow = rRange.aStart.Row();
2289 SCTAB nStartTab = rRange.aStart.Tab();
2290 SCCOL nEndCol = rRange.aEnd.Col();
2291 SCROW nEndRow = rRange.aEnd.Row();
2292 SCTAB nEndTab = rRange.aEnd.Tab();
2293
2294 if ( !rDoc.ValidRow(nStartRow) || !rDoc.ValidRow(nEndRow) )
2295 {
2296 OSL_FAIL("invalid row in DeleteCells");
2297 return false;
2298 }
2299
2300 SCTAB nTabCount = rDoc.GetTableCount();
2301 SCCOL nPaintStartCol = nStartCol;
2302 SCROW nPaintStartRow = nStartRow;
2303 SCCOL nPaintEndCol = nEndCol;
2304 SCROW nPaintEndRow = nEndRow;
2306
2307 bool bRecord = true;
2308 if (!rDoc.IsUndoEnabled())
2309 bRecord = false;
2310
2311 ScMarkData aMark(rDoc.GetSheetLimits());
2312 if (pTabMark)
2313 aMark = *pTabMark;
2314 else
2315 {
2316 SCTAB nCount = 0;
2317 for(SCTAB i=0; i<nTabCount; i++ )
2318 {
2319 if( !rDoc.IsScenario(i) )
2320 {
2321 nCount++;
2322 if( nCount == nEndTab+1 )
2323 {
2324 aMark.SelectTable(i, true);
2325 break;
2326 }
2327 }
2328 }
2329 }
2330
2331 ScMarkData aFullMark( aMark ); // including scenario sheets
2332 for (const auto& rTab : aMark)
2333 {
2334 if (rTab >= nTabCount)
2335 break;
2336
2337 for( SCTAB j = rTab+1; j<nTabCount && rDoc.IsScenario(j); j++ )
2338 aFullMark.SelectTable( j, true );
2339 }
2340
2341 SCTAB nSelCount = aMark.GetSelectCount();
2342
2343 SCCOL nUndoStartCol = nStartCol;
2344 SCROW nUndoStartRow = nStartRow;
2345 SCCOL nUndoEndCol = nEndCol;
2346 SCROW nUndoEndRow = nEndRow;
2347
2348 ScRange aExtendMergeRange( rRange );
2349
2350 if( rRange.aStart == rRange.aEnd && rDoc.HasAttrib(rRange, HasAttrFlags::Merged) )
2351 {
2352 rDoc.ExtendMerge( aExtendMergeRange );
2353 rDoc.ExtendOverlapped( aExtendMergeRange );
2354 nUndoEndCol = aExtendMergeRange.aEnd.Col();
2355 nUndoEndRow = aExtendMergeRange.aEnd.Row();
2356 nPaintEndCol = nUndoEndCol;
2357 nPaintEndRow = nUndoEndRow;
2358 }
2359
2360 if (eCmd==DelCellCmd::Rows)
2361 {
2362 nUndoStartCol = 0;
2363 nUndoEndCol = rDoc.MaxCol();
2364 }
2365 if (eCmd==DelCellCmd::Cols)
2366 {
2367 nUndoStartRow = 0;
2368 nUndoEndRow = rDoc.MaxRow();
2369 }
2370 // Test for cell protection
2371
2372 SCCOL nEditTestEndX = nUndoEndCol;
2373 if ( eCmd==DelCellCmd::Cols || eCmd==DelCellCmd::CellsLeft )
2374 nEditTestEndX = rDoc.MaxCol();
2375 SCROW nEditTestEndY = nUndoEndRow;
2376 if ( eCmd==DelCellCmd::Rows || eCmd==DelCellCmd::CellsUp )
2377 nEditTestEndY = rDoc.MaxRow();
2378
2379 ScEditableTester aTester;
2380
2381 switch (eCmd)
2382 {
2383 case DelCellCmd::Cols:
2384 aTester = ScEditableTester(
2385 rDoc, sc::ColRowEditAction::DeleteColumns, nUndoStartCol, nUndoEndCol, aMark);
2386 break;
2387 case DelCellCmd::Rows:
2388 aTester = ScEditableTester(
2389 rDoc, sc::ColRowEditAction::DeleteRows, nUndoStartRow, nUndoEndRow, aMark);
2390 break;
2391 default:
2392 aTester = ScEditableTester(
2393 rDoc, nUndoStartCol, nUndoStartRow, nEditTestEndX, nEditTestEndY, aMark);
2394 }
2395
2396 if (!aTester.IsEditable())
2397 {
2398 if (!bApi)
2400 return false;
2401 }
2402
2403 if (!canDeleteCellsByPivot(rRange, aMark, eCmd, rDoc))
2404 {
2405 if (!bApi)
2406 rDocShell.ErrorMessage(STR_NO_INSERT_DELETE_OVER_PIVOT_TABLE);
2407 return false;
2408 }
2409 // Test for merged cells
2410
2411 SCCOL nMergeTestEndCol = (eCmd==DelCellCmd::CellsLeft) ? rDoc.MaxCol() : nUndoEndCol;
2412 SCROW nMergeTestEndRow = (eCmd==DelCellCmd::CellsUp) ? rDoc.MaxRow() : nUndoEndRow;
2413 SCCOL nExtendStartCol = nUndoStartCol;
2414 SCROW nExtendStartRow = nUndoStartRow;
2415 bool bNeedRefresh = false;
2416
2417 //Issue 8302 want to be able to insert into the middle of merged cells
2418 //the patch comes from maoyg
2419 ::std::vector<ScRange> qDecreaseRange;
2420 bool bDeletingMerge = false;
2421 OUString aUndo = ScResId( STR_UNDO_DELETECELLS );
2422 if (bRecord)
2423 {
2424 ViewShellId nViewShellId(-1);
2426 nViewShellId = pViewSh->GetViewShellId();
2427 rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo, 0, nViewShellId );
2428 }
2429 std::unique_ptr<ScUndoRemoveMerge> pUndoRemoveMerge;
2430
2431 for (const SCTAB i : aMark)
2432 {
2433 if (i >= nTabCount)
2434 break;
2435
2436 if ( rDoc.HasAttrib( nUndoStartCol, nUndoStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i, HasAttrFlags::Merged | HasAttrFlags::Overlapped ))
2437 {
2438 SCCOL nMergeStartCol = nUndoStartCol;
2439 SCROW nMergeStartRow = nUndoStartRow;
2440 SCCOL nMergeEndCol = nMergeTestEndCol;
2441 SCROW nMergeEndRow = nMergeTestEndRow;
2442
2443 rDoc.ExtendMerge( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
2444 rDoc.ExtendOverlapped( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
2445 if( ( eCmd == DelCellCmd::CellsUp && ( nMergeStartCol != nUndoStartCol || nMergeEndCol != nMergeTestEndCol))||
2446 ( eCmd == DelCellCmd::CellsLeft && ( nMergeStartRow != nUndoStartRow || nMergeEndRow != nMergeTestEndRow)))
2447 {
2448 if (!bApi)
2449 rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
2451 return false;
2452 }
2453
2454 nExtendStartCol = nMergeStartCol;
2455 nExtendStartRow = nMergeStartRow;
2456 SCCOL nTestCol = -1;
2457 SCROW nTestRow1 = -1;
2458 SCROW nTestRow2 = -1;
2459
2460 ScDocAttrIterator aTestIter( rDoc, i, nUndoStartCol, nUndoStartRow, nMergeTestEndCol, nMergeTestEndRow );
2461 ScRange aExtendRange( nUndoStartCol, nUndoStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i );
2462 const ScPatternAttr* pPattern = nullptr;
2463 while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != nullptr )
2464 {
2465 const ScMergeAttr& rMergeFlag = pPattern->GetItem(ATTR_MERGE);
2466 const ScMergeFlagAttr& rMergeFlagAttr = pPattern->GetItem(ATTR_MERGE_FLAG);
2467 ScMF nNewFlags = rMergeFlagAttr.GetValue() & (ScMF::Hor | ScMF::Ver);
2468 if (rMergeFlag.IsMerged() || nNewFlags == ScMF::Hor || nNewFlags == ScMF::Ver)
2469 {
2470 ScRange aRange( nTestCol, nTestRow1, i );
2471 rDoc.ExtendOverlapped( aRange );
2472 rDoc.ExtendMerge( aRange, true );
2473
2474 if( nTestRow1 < nTestRow2 && nNewFlags == ScMF::Hor )
2475 {
2476 for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
2477 {
2478 ScRange aTestRange( nTestCol, nTestRow, i );
2479 rDoc.ExtendOverlapped( aTestRange );
2480 rDoc.ExtendMerge( aTestRange, true );
2481 ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
2482 if( !aExtendRange.Contains( aMergeRange ) )
2483 {
2484 qDecreaseRange.push_back( aTestRange );
2485 bDeletingMerge = true;
2486 }
2487 }
2488 }
2489 else
2490 {
2491 ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
2492 if( !aExtendRange.Contains( aMergeRange ) )
2493 {
2494 qDecreaseRange.push_back( aRange );
2495 }
2496 bDeletingMerge = true;
2497 }
2498 }
2499 }
2500
2501 if( bDeletingMerge )
2502 {
2503
2504 if( eCmd == DelCellCmd::Rows || eCmd == DelCellCmd::CellsUp )
2505 {
2506 nStartRow = aExtendMergeRange.aStart.Row();
2507 nEndRow = aExtendMergeRange.aEnd.Row();
2508 bNeedRefresh = true;
2509
2510 if( eCmd == DelCellCmd::CellsUp )
2511 {
2512 nEndCol = aExtendMergeRange.aEnd.Col();
2513 }
2514 else
2515 {
2516 nStartCol = 0;
2517 nEndCol = rDoc.MaxCol();
2518 }
2519 }
2520 else if( eCmd == DelCellCmd::CellsLeft || eCmd == DelCellCmd::Cols )
2521 {
2522
2523 nStartCol = aExtendMergeRange.aStart.Col();
2524 nEndCol = aExtendMergeRange.aEnd.Col();
2525 if( eCmd == DelCellCmd::CellsLeft )
2526 {
2527 nEndRow = aExtendMergeRange.aEnd.Row();
2528 bNeedRefresh = true;
2529 }
2530 else
2531 {
2532 nStartRow = 0;
2533 nEndRow = rDoc.MaxRow();
2534 }
2535 }
2536
2537 if( !qDecreaseRange.empty() )
2538 {
2539 if (bRecord && !pUndoRemoveMerge)
2540 {
2542 pUndoDoc->InitUndo( rDoc, *aMark.begin(), *aMark.rbegin());
2543 pUndoRemoveMerge.reset( new ScUndoRemoveMerge( &rDocShell, rRange, std::move(pUndoDoc) ));
2544 }
2545
2546 for( const ScRange& aRange : qDecreaseRange )
2547 {
2549 {
2550 UnmergeCells( aRange, bRecord, pUndoRemoveMerge.get() );
2551 }
2552 }
2553 }
2554 }
2555 else
2556 {
2557 if (!bApi)
2558 rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
2560 return false;
2561 }
2562 }
2563 }
2564
2565 if (bRecord && pUndoRemoveMerge)
2566 {
2567 rDocShell.GetUndoManager()->AddUndoAction( std::move(pUndoRemoveMerge));
2568 }
2569
2570 // do it
2571
2572 weld::WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
2573
2574 ScDocumentUniquePtr pUndoDoc;
2575 std::unique_ptr<ScDocument> pRefUndoDoc;
2576 std::unique_ptr<ScRefUndoData> pUndoData;
2577 if ( bRecord )
2578 {
2579 // With the fix for #101329#, UpdateRef always puts cells into pRefUndoDoc at their old position,
2580 // so it's no longer necessary to copy more than the deleted range into pUndoDoc.
2581
2582 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
2583 pUndoDoc->InitUndo( rDoc, 0, nTabCount-1, (eCmd==DelCellCmd::Cols), (eCmd==DelCellCmd::Rows) );
2584 for (const auto& rTab : aMark)
2585 {
2586 if (rTab >= nTabCount)
2587 break;
2588
2589 SCTAB nScenarioCount = 0;
2590
2591 for( SCTAB j = rTab+1; j<nTabCount && rDoc.IsScenario(j); j++ )
2592 nScenarioCount ++;
2593
2594 rDoc.CopyToDocument( nUndoStartCol, nUndoStartRow, rTab, nUndoEndCol, nUndoEndRow, rTab+nScenarioCount,
2596 }
2597
2598 pRefUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
2599 pRefUndoDoc->InitUndo( rDoc, 0, nTabCount-1 );
2600
2601 pUndoData.reset(new ScRefUndoData( &rDoc ));
2602
2603 rDoc.BeginDrawUndo();
2604 }
2605
2606 sal_uInt16 nExtFlags = 0;
2607 for (const auto& rTab : aMark)
2608 {
2609 if (rTab >= nTabCount)
2610 break;
2611
2612 rDocShell.UpdatePaintExt( nExtFlags, nStartCol, nStartRow, rTab, nEndCol, nEndRow, rTab );
2613 }
2614
2615 switch (eCmd)
2616 {
2619 rDoc.DeleteObjectsInArea(nStartCol, nStartRow, nEndCol, nEndRow, aMark, true);
2620 break;
2621 case DelCellCmd::Rows:
2622 rDoc.DeleteObjectsInArea(0, nStartRow, rDoc.MaxCol(), nEndRow, aMark, true);
2623 break;
2624 case DelCellCmd::Cols:
2625 rDoc.DeleteObjectsInArea(nStartCol, 0, nEndCol, rDoc.MaxRow(), aMark, true);
2626 break;
2627 default:
2628 break;
2629 }
2630
2631
2632 bool bUndoOutline = false;
2633 switch (eCmd)
2634 {
2636 rDoc.DeleteRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc.get(), nullptr, &aFullMark );
2637 nPaintEndRow = rDoc.MaxRow();
2638 break;
2639 case DelCellCmd::Rows:
2640 rDoc.DeleteRow( 0, 0, rDoc.MaxCol(), MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc.get(), &bUndoOutline, &aFullMark );
2641 nPaintStartCol = 0;
2642 nPaintEndCol = rDoc.MaxCol();
2643 nPaintEndRow = rDoc.MaxRow();
2644 nPaintFlags |= PaintPartFlags::Left;
2645 break;
2647 rDoc.DeleteCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc.get(), nullptr, &aFullMark );
2648 nPaintEndCol = rDoc.MaxCol();
2649 break;
2650 case DelCellCmd::Cols:
2651 rDoc.DeleteCol( 0, 0, rDoc.MaxRow(), MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc.get(), &bUndoOutline, &aFullMark );
2652 nPaintStartRow = 0;
2653 nPaintEndRow = rDoc.MaxRow();
2654 nPaintEndCol = rDoc.MaxCol();
2655 nPaintFlags |= PaintPartFlags::Top;
2656 break;
2657 default:
2658 OSL_FAIL("Wrong code at deleting");
2659 break;
2660 }
2661
2663
2664 if ( bRecord )
2665 {
2666 for (const auto& rTab : aFullMark)
2667 {
2668 if (rTab >= nTabCount)
2669 break;
2670
2671 pRefUndoDoc->DeleteAreaTab(nUndoStartCol,nUndoStartRow,nUndoEndCol,nUndoEndRow, rTab, InsertDeleteFlags::ALL);
2672 }
2673
2674 // for all sheets, so that formulas can be copied
2675 pUndoDoc->AddUndoTab( 0, nTabCount-1 );
2676
2677 // copy with bColRowFlags=false (#54194#)
2678 pRefUndoDoc->CopyToDocument(0,0,0,rDoc.MaxCol(),rDoc.MaxRow(),MAXTAB,InsertDeleteFlags::FORMULA,false,*pUndoDoc,nullptr,false);
2679 pRefUndoDoc.reset();
2680
2681 std::unique_ptr<SCTAB[]> pTabs( new SCTAB[nSelCount]);
2682 std::unique_ptr<SCTAB[]> pScenarios( new SCTAB[nSelCount]);
2683 SCTAB nUndoPos = 0;
2684
2685 for (const auto& rTab : aMark)
2686 {
2687 if (rTab >= nTabCount)
2688 break;
2689
2690 SCTAB nCount = 0;
2691 for( SCTAB j=rTab+1; j<nTabCount && rDoc.IsScenario(j); j++ )
2692 nCount ++;
2693
2694 pScenarios[nUndoPos] = nCount;
2695 pTabs[nUndoPos] = rTab;
2696 nUndoPos ++;
2697 }
2698
2699 if( !bDeletingMerge )
2700 {
2702 }
2703
2704 rDocShell.GetUndoManager()->AddUndoAction( std::make_unique<ScUndoDeleteCells>(
2705 &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),
2706 nUndoPos, std::move(pTabs), std::move(pScenarios),
2707 eCmd, std::move(pUndoDoc), std::move(pUndoData) ) );
2708 }
2709
2710 // #i8302 want to be able to insert into the middle of merged cells
2711 // the patch comes from maoyg
2712
2713 while( !qDecreaseRange.empty() )
2714 {
2715 ScRange aRange = qDecreaseRange.back();
2716
2717 sal_Int32 nDecreaseRowCount = 0;
2718 sal_Int32 nDecreaseColCount = 0;
2719 if( eCmd == DelCellCmd::CellsUp || eCmd == DelCellCmd::Rows )
2720 {
2721 if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
2722 nDecreaseRowCount = nEndRow-nStartRow+1;
2723 else if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow >= aRange.aStart.Row() && nEndRow >= aRange.aEnd.Row() )
2724 nDecreaseRowCount = aRange.aEnd.Row()-nStartRow+1;
2725 else if( nStartRow >= aRange.aStart.Row() && nStartRow >= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
2726 nDecreaseRowCount = aRange.aEnd.Row()-nEndRow+1;
2727 }
2728 else if( eCmd == DelCellCmd::CellsLeft || eCmd == DelCellCmd::Cols )
2729 {
2730 if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
2731 nDecreaseColCount = nEndCol-nStartCol+1;
2732 else if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol >= aRange.aStart.Col() && nEndCol >= aRange.aEnd.Col() )
2733 nDecreaseColCount = aRange.aEnd.Col()-nStartCol+1;
2734 else if( nStartCol >= aRange.aStart.Col() && nStartCol >= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
2735 nDecreaseColCount = aRange.aEnd.Col()-nEndCol+1;
2736 }
2737
2738 switch (eCmd)
2739 {
2741 case DelCellCmd::Rows:
2742 aRange.aEnd.SetRow(static_cast<SCCOL>( aRange.aEnd.Row()-nDecreaseRowCount));
2743 break;
2745 case DelCellCmd::Cols:
2746 aRange.aEnd.SetCol(static_cast<SCCOL>( aRange.aEnd.Col()-nDecreaseColCount));
2747 break;
2748 default:
2749 break;
2750 }
2751
2753 {
2754 ScCellMergeOption aMergeOption(aRange);
2755 MergeCells( aMergeOption, false, true, true );
2756 }
2757 qDecreaseRange.pop_back();
2758 }
2759
2760 if( bDeletingMerge )
2762
2763 if ( eCmd==DelCellCmd::Cols || eCmd==DelCellCmd::CellsLeft )
2764 nMergeTestEndCol = rDoc.MaxCol();
2765 if ( eCmd==DelCellCmd::Rows || eCmd==DelCellCmd::CellsUp )
2766 nMergeTestEndRow = rDoc.MaxRow();
2767 if ( bNeedRefresh )
2768 {
2769 // #i51445# old merge flag attributes must be deleted also for single cells,
2770 // not only for whole columns/rows
2771
2772 ScPatternAttr aPattern( rDoc.GetPool() );
2773 aPattern.GetItemSet().Put( ScMergeFlagAttr() );
2774
2775 rDoc.ApplyPatternArea( nExtendStartCol, nExtendStartRow, nMergeTestEndCol, nMergeTestEndRow, aMark, aPattern );
2776
2777 for (const auto& rTab : aMark)
2778 {
2779 if (rTab >= nTabCount)
2780 break;
2781
2782 SCTAB nScenarioCount = 0;
2783
2784 for( SCTAB j = rTab+1; j<nTabCount && rDoc.IsScenario(j); j++ )
2785 nScenarioCount ++;
2786
2787 ScRange aMergedRange( nExtendStartCol, nExtendStartRow, rTab, nMergeTestEndCol, nMergeTestEndRow, rTab+nScenarioCount );
2788 rDoc.ExtendMerge( aMergedRange, true );
2789 }
2790 }
2791
2792 for (const auto& rTab : aMark)
2793 {
2794 if (rTab >= nTabCount)
2795 break;
2796
2797 rDoc.RefreshAutoFilter( nExtendStartCol, nExtendStartRow, nMergeTestEndCol, nMergeTestEndRow, rTab );
2798 }
2799
2800 for (const auto& rTab : aMark)
2801 {
2802 if (rTab >= nTabCount)
2803 break;
2804
2805 rDoc.SetDrawPageSize(rTab);
2806
2807 if ( eCmd == DelCellCmd::Cols || eCmd == DelCellCmd::Rows )
2808 rDoc.UpdatePageBreaks( rTab );
2809
2810 rDocShell.UpdatePaintExt( nExtFlags, nPaintStartCol, nPaintStartRow, rTab, nPaintEndCol, nPaintEndRow, rTab );
2811
2812 SCTAB nScenarioCount = 0;
2813
2814 for( SCTAB j = rTab+1; j<nTabCount && rDoc.IsScenario(j); j++ )
2815 nScenarioCount ++;
2816
2817 // delete entire rows: do not adjust
2818 if ( eCmd == DelCellCmd::Rows || !AdjustRowHeight(ScRange( 0, nPaintStartRow, rTab, rDoc.MaxCol(), nPaintEndRow, rTab+nScenarioCount ), true, bApi) )
2819 rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, rTab, nPaintEndCol, nPaintEndRow, rTab+nScenarioCount, nPaintFlags, nExtFlags );
2820 else
2821 {
2822 // paint only what is not done by AdjustRowHeight
2823 if (nExtFlags & SC_PF_LINES)
2824 lcl_PaintAbove( rDocShell, ScRange( nPaintStartCol, nPaintStartRow, rTab, nPaintEndCol, nPaintEndRow, rTab+nScenarioCount) );
2825 if (nPaintFlags & PaintPartFlags::Top)
2826 rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, rTab, nPaintEndCol, nPaintEndRow, rTab+nScenarioCount, PaintPartFlags::Top );
2827 }
2828 }
2829
2830 // The cursor position needs to be modified earlier than updating
2831 // any enabled edit view which is triggered by SetDocumentModified below.
2833 if (pViewSh)
2834 {
2835 if (eCmd == DelCellCmd::Cols)
2836 {
2837 pViewSh->OnLOKInsertDeleteColumn(rRange.aStart.Col(), -1);
2838 }
2839 if (eCmd == DelCellCmd::Rows)
2840 {
2841 pViewSh->OnLOKInsertDeleteRow(rRange.aStart.Row(), -1);
2842 }
2843 }
2844
2845 aModificator.SetDocumentModified();
2846
2847 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
2848
2849 return true;
2850}
2851
2852bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
2853 bool bCut, bool bRecord, bool bPaint, bool bApi )
2854{
2855 ScDocShellModificator aModificator( rDocShell );
2856
2857 SCCOL nStartCol = rSource.aStart.Col();
2858 SCROW nStartRow = rSource.aStart.Row();
2859 SCTAB nStartTab = rSource.aStart.Tab();
2860 SCCOL nEndCol = rSource.aEnd.Col();
2861 SCROW nEndRow = rSource.aEnd.Row();
2862 SCTAB nEndTab = rSource.aEnd.Tab();
2863 SCCOL nDestCol = rDestPos.Col();
2864 SCROW nDestRow = rDestPos.Row();
2865 SCTAB nDestTab = rDestPos.Tab();
2866
2868 if ( !rDoc.ValidRow(nStartRow) || !rDoc.ValidRow(nEndRow) || !rDoc.ValidRow(nDestRow) )
2869 {
2870 OSL_FAIL("invalid row in MoveBlock");
2871 return false;
2872 }
2873
2874 // adjust related scenarios too - but only when moved within one sheet
2875 bool bScenariosAdded = false;
2876 if (bRecord && !rDoc.IsUndoEnabled())
2877 bRecord = false;
2878
2879 SCTAB nTabCount = rDoc.GetTableCount();
2880 if ( nDestTab == nStartTab && !rDoc.IsScenario(nEndTab) )
2881 while ( nEndTab+1 < nTabCount && rDoc.IsScenario(nEndTab+1) )
2882 {
2883 ++nEndTab;
2884 bScenariosAdded = true;
2885 }
2886
2887 SCTAB nSrcTabCount = nEndTab-nStartTab+1;
2888 SCTAB nDestEndTab = nDestTab+nSrcTabCount-1;
2889 SCTAB nTab;
2890
2892
2893 ScMarkData aSourceMark(rDoc.GetSheetLimits());
2894 for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2895 aSourceMark.SelectTable( nTab, true ); // select source
2896 aSourceMark.SetMarkArea( rSource );
2897
2898 ScDocShellRef aDragShellRef;
2899 if ( rDoc.HasOLEObjectsInArea( rSource ) )
2900 {
2901 aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
2902 aDragShellRef->DoInitNew();
2903 }
2904 ScDrawLayer::SetGlobalDrawPersist( aDragShellRef.get() );
2905
2906 ScClipParam aClipParam(ScRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nStartTab), bCut);
2907 rDoc.CopyToClip(aClipParam, pClipDoc.get(), &aSourceMark, bScenariosAdded, true);
2908
2910
2911 SCCOL nOldEndCol = nEndCol;
2912 SCROW nOldEndRow = nEndRow;
2913 bool bClipOver = false;
2914 for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2915 {
2916 SCCOL nTmpEndCol = nOldEndCol;
2917 SCROW nTmpEndRow = nOldEndRow;
2918 if (rDoc.ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab ))
2919 bClipOver = true;
2920 if ( nTmpEndCol > nEndCol ) nEndCol = nTmpEndCol;
2921 if ( nTmpEndRow > nEndRow ) nEndRow = nTmpEndRow;
2922 }
2923
2924 SCCOL nDestEndCol = nDestCol + ( nOldEndCol-nStartCol );
2925 SCROW nDestEndRow = nDestRow + ( nOldEndRow-nStartRow );
2926
2927 SCCOL nUndoEndCol = nDestCol + ( nEndCol-nStartCol ); // extended in destination block
2928 SCROW nUndoEndRow = nDestRow + ( nEndRow-nStartRow );
2929
2930 bool bIncludeFiltered = bCut;
2931 if ( !bIncludeFiltered )
2932 {
2933 // adjust sizes to include only non-filtered rows
2934
2935 SCCOL nClipX;
2936 SCROW nClipY;
2937 pClipDoc->GetClipArea( nClipX, nClipY, false );
2938 SCROW nUndoAdd = nUndoEndRow - nDestEndRow;
2939 nDestEndRow = nDestRow + nClipY;
2940 nUndoEndRow = nDestEndRow + nUndoAdd;
2941 }
2942
2943 if (!rDoc.ValidCol(nUndoEndCol) || !rDoc.ValidRow(nUndoEndRow))
2944 {
2945 if (!bApi)
2946 rDocShell.ErrorMessage(STR_PASTE_FULL);
2947 return false;
2948 }
2949
2950 // Test for cell protection
2951
2952 ScEditableTester aTester;
2953 for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
2954 aTester.TestBlock( rDoc, nTab, nDestCol,nDestRow, nUndoEndCol,nUndoEndRow );
2955 if (bCut)
2956 for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2957 aTester.TestBlock( rDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
2958
2959 if (!aTester.IsEditable())
2960 {
2961 if (!bApi)
2963 return false;
2964 }
2965
2966 // Test for merged cells- when moving after delete
2967
2968 if (bClipOver && !bCut)
2969 if (rDoc.HasAttrib( nDestCol,nDestRow,nDestTab, nUndoEndCol,nUndoEndRow,nDestEndTab,
2971 { // "Merge of already merged cells not possible"
2972 if (!bApi)
2973 rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
2974 return false;
2975 }
2976
2977 // Are there borders in the cells? (for painting)
2978
2979 sal_uInt16 nSourceExt = 0;
2980 rDocShell.UpdatePaintExt( nSourceExt, nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab );
2981 sal_uInt16 nDestExt = 0;
2982 rDocShell.UpdatePaintExt( nDestExt, nDestCol,nDestRow,nDestTab, nDestEndCol,nDestEndRow,nDestEndTab );
2983
2984 // do it
2985
2986 ScDocumentUniquePtr pUndoDoc;
2987
2988 if (bRecord)
2989 {
2990 bool bWholeCols = ( nStartRow == 0 && nEndRow == rDoc.MaxRow() );
2991 bool bWholeRows = ( nStartCol == 0 && nEndCol == rDoc.MaxCol() );
2993
2994 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
2995 pUndoDoc->InitUndo( rDoc, nStartTab, nEndTab, bWholeCols, bWholeRows );
2996
2997 if (bCut)
2998 {
2999 rDoc.CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
3000 nUndoFlags, false, *pUndoDoc );
3001 }
3002
3003 if ( nDestTab != nStartTab )
3004 pUndoDoc->AddUndoTab( nDestTab, nDestEndTab, bWholeCols, bWholeRows );
3005 rDoc.CopyToDocument( nDestCol, nDestRow, nDestTab,
3006 nDestEndCol, nDestEndRow, nDestEndTab,
3007 nUndoFlags, false, *pUndoDoc );
3008 rDoc.BeginDrawUndo();
3009 }
3010
3011 bool bSourceHeight = false; // adjust heights?
3012 if (bCut)
3013 {
3014 ScMarkData aDelMark(rDoc.GetSheetLimits()); // only for tables
3015 for (nTab=nStartTab; nTab<=nEndTab; nTab++)
3016 {
3017 rDoc.DeleteAreaTab( nStartCol,nStartRow, nOldEndCol,nOldEndRow, nTab, InsertDeleteFlags::ALL );
3018 aDelMark.SelectTable( nTab, true );
3019 }
3020 rDoc.DeleteObjectsInArea( nStartCol,nStartRow, nOldEndCol,nOldEndRow, aDelMark );
3021
3022 // Test for merged cells
3023
3024 if (bClipOver)
3025 if (rDoc.HasAttrib( nDestCol,nDestRow,nDestTab,
3026 nUndoEndCol,nUndoEndRow,nDestEndTab,
3028 {
3029 rDoc.CopyFromClip( rSource, aSourceMark, InsertDeleteFlags::ALL, nullptr, pClipDoc.get() );
3030 for (nTab=nStartTab; nTab<=nEndTab; nTab++)
3031 {
3032 SCCOL nTmpEndCol = nEndCol;
3033 SCROW nTmpEndRow = nEndRow;
3034 rDoc.ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab, true );
3035 }
3036
3037 // Report error only after restoring content
3038 if (!bApi) // "Merge of already merged cells not possible"
3039 rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
3040
3041 return false;
3042 }
3043
3044 bSourceHeight = AdjustRowHeight( rSource, false, bApi );
3045 }
3046
3047 ScRange aPasteDest( nDestCol, nDestRow, nDestTab, nDestEndCol, nDestEndRow, nDestEndTab );
3048
3049 ScMarkData aDestMark(rDoc.GetSheetLimits());
3050 for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
3051 aDestMark.SelectTable( nTab, true ); // select destination
3052 aDestMark.SetMarkArea( aPasteDest );
3053
3054 /* Do not copy drawing objects here. While pasting, the
3055 function ScDocument::UpdateReference() is called which calls
3056 ScDrawLayer::MoveCells() which may move away inserted objects to wrong
3057 positions (e.g. if source and destination range overlaps).*/
3058
3059 rDoc.CopyFromClip(
3060 aPasteDest, aDestMark, InsertDeleteFlags::ALL & ~InsertDeleteFlags::OBJECTS,
3061 pUndoDoc.get(), pClipDoc.get(), true, false, bIncludeFiltered);
3062
3063 // skipped rows and merged cells don't mix
3064 if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
3065 UnmergeCells( aPasteDest, false, nullptr );
3066
3067 bool bDestHeight = AdjustRowHeight(
3068 ScRange( 0,nDestRow,nDestTab, rDoc.MaxCol(),nDestEndRow,nDestEndTab ),
3069 false, bApi );
3070
3071 /* Paste drawing objects after adjusting formula references
3072 and row heights. There are no cell notes or drawing objects, if the
3073 clipdoc does not contain a drawing layer.*/
3074 if ( pClipDoc->GetDrawLayer() )
3075 rDoc.CopyFromClip( aPasteDest, aDestMark, InsertDeleteFlags::OBJECTS,
3076 nullptr, pClipDoc.get(), true, false, bIncludeFiltered );
3077
3078 if (bRecord)
3079 {
3080 ScRange aUndoRange(nStartCol, nStartRow, nStartTab, nOldEndCol, nOldEndRow, nEndTab);
3081 ScAddress aDestPos(nDestCol, nDestRow, nDestTab);
3082
3084 std::make_unique<ScUndoDragDrop>(
3085 &rDocShell, aUndoRange, aDestPos, bCut, std::move(pUndoDoc), bScenariosAdded));
3086 }
3087
3088 SCCOL nDestPaintEndCol = nDestEndCol;
3089 SCROW nDestPaintEndRow = nDestEndRow;
3090 for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
3091 {
3092 SCCOL nTmpEndCol = nDestEndCol;
3093 SCROW nTmpEndRow = nDestEndRow;
3094 rDoc.ExtendMerge( nDestCol, nDestRow, nTmpEndCol, nTmpEndRow, nTab, true );
3095 if (nTmpEndCol > nDestPaintEndCol) nDestPaintEndCol = nTmpEndCol;
3096 if (nTmpEndRow > nDestPaintEndRow) nDestPaintEndRow = nTmpEndRow;
3097 }
3098
3099 if (bCut)
3100 for (nTab=nStartTab; nTab<=nEndTab; nTab++)
3101 rDoc.RefreshAutoFilter( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
3102
3103 if (bPaint)
3104 {
3105 // destination range:
3106
3107 SCCOL nPaintStartX = nDestCol;
3108 SCROW nPaintStartY = nDestRow;
3109 SCCOL nPaintEndX = nDestPaintEndCol;
3110 SCROW nPaintEndY = nDestPaintEndRow;
3112
3113 if ( nStartRow==0 && nEndRow==rDoc.MaxRow() ) // copy widths too?
3114 {
3115 nPaintEndX = rDoc.MaxCol();
3116 nPaintStartY = 0;
3117 nPaintEndY = rDoc.MaxRow();
3118 nFlags |= PaintPartFlags::Top;
3119 }
3120 if ( bDestHeight || ( nStartCol == 0 && nEndCol == rDoc.MaxCol() ) )
3121 {
3122 nPaintEndY = rDoc.MaxRow();
3123 nPaintStartX = 0;
3124 nPaintEndX = rDoc.MaxCol();
3125 nFlags |= PaintPartFlags::Left;
3126 }
3127 if ( bScenariosAdded )
3128 {
3129 nPaintStartX = 0;
3130 nPaintStartY = 0;
3131 nPaintEndX = rDoc.MaxCol();
3132 nPaintEndY = rDoc.MaxRow();
3133 }
3134
3135 rDocShell.PostPaint( nPaintStartX,nPaintStartY,nDestTab,
3136 nPaintEndX,nPaintEndY,nDestEndTab, nFlags, nSourceExt | nDestExt );
3137
3138 if ( bCut )
3139 {
3140 // source range:
3141
3142 nPaintStartX = nStartCol;
3143 nPaintStartY = nStartRow;
3144 nPaintEndX = nEndCol;
3145 nPaintEndY = nEndRow;
3146 nFlags = PaintPartFlags::Grid;
3147
3148 if ( bSourceHeight )
3149 {
3150 nPaintEndY = rDoc.MaxRow();
3151 nPaintStartX = 0;
3152 nPaintEndX = rDoc.MaxCol();
3153 nFlags |= PaintPartFlags::Left;
3154 }
3155 if ( bScenariosAdded )
3156 {
3157 nPaintStartX = 0;
3158 nPaintStartY = 0;
3159 nPaintEndX = rDoc.MaxCol();
3160 nPaintEndY = rDoc.MaxRow();
3161 }
3162
3163 rDocShell.PostPaint( nPaintStartX,nPaintStartY,nStartTab,
3164 nPaintEndX,nPaintEndY,nEndTab, nFlags, nSourceExt );
3165 }
3166 }
3167
3168 aModificator.SetDocumentModified();
3169
3170 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
3171
3172 return true;
3173}
3174
3175static uno::Reference< uno::XInterface > GetDocModuleObject( const SfxObjectShell& rDocSh, const OUString& sCodeName )
3176{
3177 uno::Reference< lang::XMultiServiceFactory> xSF(rDocSh.GetModel(), uno::UNO_QUERY);
3178 uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess;
3179 uno::Reference< uno::XInterface > xDocModuleApiObject;
3180 if ( xSF.is() )
3181 {
3182 xVBACodeNamedObjectAccess.set( xSF->createInstance("ooo.vba.VBAObjectModuleObjectProvider"), uno::UNO_QUERY );
3183 xDocModuleApiObject.set( xVBACodeNamedObjectAccess->getByName( sCodeName ), uno::UNO_QUERY );
3184 }
3185 return xDocModuleApiObject;
3186
3187}
3188
3189static script::ModuleInfo lcl_InitModuleInfo( const SfxObjectShell& rDocSh, const OUString& sModule )
3190{
3191 script::ModuleInfo sModuleInfo;
3192 sModuleInfo.ModuleType = script::ModuleType::DOCUMENT;
3193 sModuleInfo.ModuleObject = GetDocModuleObject( rDocSh, sModule );
3194 return sModuleInfo;
3195}
3196
3197void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, const OUString& sSource )
3198{
3199 SfxObjectShell& rDocSh = *rDoc.GetDocumentShell();
3200 uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
3201 OSL_ENSURE( xLibContainer.is(), "No BasicContainer!" );
3202
3203 uno::Reference< container::XNameContainer > xLib;
3204 if( xLibContainer.is() )
3205 {
3206 OUString aLibName( "Standard" );
3207#if HAVE_FEATURE_SCRIPTING
3208 if ( rDocSh.GetBasicManager() && !rDocSh.GetBasicManager()->GetName().isEmpty() )
3209 {
3210 aLibName = rDocSh.GetBasicManager()->GetName();
3211 }
3212#endif
3213 uno::Any aLibAny = xLibContainer->getByName( aLibName );
3214 aLibAny >>= xLib;
3215 }
3216 if( !xLib.is() )
3217 return;
3218
3219 // if the Module with codename exists then find a new name
3220 sal_Int32 nNum = 1;
3221 OUString genModuleName = "Sheet1";
3222 while( xLib->hasByName( genModuleName ) )
3223 genModuleName = "Sheet" + OUString::number( ++nNum );
3224
3225 uno::Any aSourceAny;
3226 OUString sTmpSource = sSource;
3227 if ( sTmpSource.isEmpty() )
3228 sTmpSource = "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n";
3229 aSourceAny <<= sTmpSource;
3230 uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
3231 if ( xVBAModuleInfo.is() )
3232 {
3233 rDoc.SetCodeName( nTab, genModuleName );
3234 script::ModuleInfo sModuleInfo = lcl_InitModuleInfo( rDocSh, genModuleName );
3235 xVBAModuleInfo->insertModuleInfo( genModuleName, sModuleInfo );
3236 xLib->insertByName( genModuleName, aSourceAny );
3237 }
3238}
3239
3240void VBA_DeleteModule( ScDocShell& rDocSh, const OUString& sModuleName )
3241{
3242 uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
3243 OSL_ENSURE( xLibContainer.is(), "No BasicContainer!" );
3244
3245 uno::Reference< container::XNameContainer > xLib;
3246 if( xLibContainer.is() )
3247 {
3248 OUString aLibName( "Standard" );
3249#if HAVE_FEATURE_SCRIPTING
3250 if ( rDocSh.GetBasicManager() && !rDocSh.GetBasicManager()->GetName().isEmpty() )
3251 {
3252 aLibName = rDocSh.GetBasicManager()->GetName();
3253 }
3254#endif
3255 uno::Any aLibAny = xLibContainer->getByName( aLibName );
3256 aLibAny >>= xLib;
3257 }
3258 if( xLib.is() )
3259 {
3260 uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
3261 if( xLib->hasByName( sModuleName ) )
3262 xLib->removeByName( sModuleName );
3263 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo(sModuleName) )
3264 xVBAModuleInfo->removeModuleInfo( sModuleName );
3265
3266 }
3267}
3268
3269bool ScDocFunc::InsertTable( SCTAB nTab, const OUString& rName, bool bRecord, bool bApi )
3270{
3271 bool bSuccess = false;
3273
3274 ScDocShellModificator aModificator( rDocShell );
3275
3277
3278 // Strange loop, also basic is loaded too early ( InsertTable )
3279 // is called via the xml import for sheets in described in ODF
3280 bool bInsertDocModule = false;
3281
3283 {
3284 bInsertDocModule = rDoc.IsInVBAMode();
3285 }
3286 if ( bInsertDocModule || ( bRecord && !rDoc.IsUndoEnabled() ) )
3287 bRecord = false;
3288
3289 if (bRecord)
3290 rDoc.BeginDrawUndo(); // InsertTab generates SdrUndoNewPage
3291
3292 SCTAB nTabCount = rDoc.GetTableCount();
3293 bool bAppend = ( nTab >= nTabCount );
3294 if ( bAppend )
3295 nTab = nTabCount; // important for Undo
3296
3297 if (rDoc.InsertTab( nTab, rName ))
3298 {
3299 if (bRecord)
3301 std::make_unique<ScUndoInsertTab>( &rDocShell, nTab, bAppend, rName));
3302 // Update views:
3303 // Only insert vba modules if vba mode ( and not currently importing XML )
3304 if( bInsertDocModule )
3305 {
3306 VBA_InsertModule( rDoc, nTab, OUString() );
3307 }
3308 rDocShell.Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab ) );
3309
3311 aModificator.SetDocumentModified();
3312 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
3313 bSuccess = true;
3314 }
3315 else if (!bApi)
3316 rDocShell.ErrorMessage(STR_TABINSERT_ERROR);
3317
3318 return bSuccess;
3319}
3320
3321bool ScDocFunc::DeleteTable( SCTAB nTab, bool bRecord )
3322{
3324
3325 ScDocShellModificator aModificator( rDocShell );
3326
3327 bool bSuccess = false;
3329 bool bVbaEnabled = rDoc.IsInVBAMode();
3330 if (bRecord && !rDoc.IsUndoEnabled())
3331 bRecord = false;
3332 if ( bVbaEnabled )
3333 bRecord = false;
3334 bool bWasLinked = rDoc.IsLinked(nTab);
3335 ScDocumentUniquePtr pUndoDoc;
3336 std::unique_ptr<ScRefUndoData> pUndoData;
3337 if (bRecord)
3338 {
3339 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
3340 SCTAB nCount = rDoc.GetTableCount();
3341
3342 pUndoDoc->InitUndo( rDoc, nTab, nTab, true, true ); // only nTab with Flags
3343 pUndoDoc->AddUndoTab( 0, nCount-1 ); // all sheets for references
3344
3345 rDoc.CopyToDocument(0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, InsertDeleteFlags::ALL,false, *pUndoDoc );
3346 OUString aOldName;
3347 rDoc.GetName( nTab, aOldName );
3348 pUndoDoc->RenameTab( nTab, aOldName );
3349 if (bWasLinked)
3350 pUndoDoc->SetLink( nTab, rDoc.GetLinkMode(nTab), rDoc.GetLinkDoc(nTab),
3351 rDoc.GetLinkFlt(nTab), rDoc.GetLinkOpt(nTab),
3352 rDoc.GetLinkTab(nTab),
3353 rDoc.GetLinkRefreshDelay(nTab) );
3354
3355 if ( rDoc.IsScenario(nTab) )
3356 {
3357 pUndoDoc->SetScenario( nTab, true );
3358 OUString aComment;
3359 Color aColor;
3360 ScScenarioFlags nScenFlags;
3361 rDoc.GetScenarioData( nTab, aComment, aColor, nScenFlags );
3362 pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
3363 bool bActive = rDoc.IsActiveScenario( nTab );
3364 pUndoDoc->SetActiveScenario( nTab, bActive );
3365 }
3366 pUndoDoc->SetVisible( nTab, rDoc.IsVisible( nTab ) );
3367 pUndoDoc->SetTabBgColor( nTab, rDoc.GetTabBgColor(nTab) );
3368 auto pSheetEvents = rDoc.GetSheetEvents( nTab );
3369 pUndoDoc->SetSheetEvents( nTab, std::unique_ptr<ScSheetEvents>(pSheetEvents ? new ScSheetEvents(*pSheetEvents) : nullptr) );
3370
3371 // Drawing-Layer has to take care of its own undo!!!
3372 rDoc.BeginDrawUndo(); // DeleteTab generates SdrUndoDelPage
3373
3374 pUndoData.reset(new ScRefUndoData( &rDoc ));
3375 }
3376
3377 if (rDoc.DeleteTab(nTab))
3378 {
3379 if (bRecord)
3380 {
3381 vector<SCTAB> theTabs;
3382 theTabs.push_back(nTab);
3384 std::make_unique<ScUndoDeleteTab>( &rDocShell, theTabs, std::move(pUndoDoc), std::move(pUndoData) ));
3385 }
3386 // Update views:
3387 if( bVbaEnabled )
3388 {
3389 OUString sCodeName;
3390 if( rDoc.GetCodeName( nTab, sCodeName ) )
3391 {
3392 VBA_DeleteModule( rDocShell, sCodeName );
3393 }
3394 }
3395 rDocShell.Broadcast( ScTablesHint( SC_TAB_DELETED, nTab ) );
3396
3397 if (bWasLinked)
3398 {
3399 rDocShell.UpdateLinks(); // update Link-Manager
3400 SfxBindings* pBindings = rDocShell.GetViewBindings();
3401 if (pBindings)
3402 pBindings->Invalidate(SID_LINKS);
3403 }
3404
3406 aModificator.SetDocumentModified();
3407
3408 SfxApplication* pSfxApp = SfxGetpApp(); // Navigator
3409 pSfxApp->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
3410 pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
3411 pSfxApp->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
3412 pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
3413
3414 bSuccess = true;
3415 }
3416 return bSuccess;
3417}
3418
3419void ScDocFunc::SetTableVisible( SCTAB nTab, bool bVisible, bool bApi )
3420{
3422 bool bUndo(rDoc.IsUndoEnabled());
3423 if ( rDoc.IsVisible( nTab ) == bVisible )
3424 return; // nothing to do - ok
3425
3426 if ( !rDoc.IsDocEditable() )
3427 {
3428 if (!bApi)
3429 rDocShell.ErrorMessage(STR_PROTECTIONERR);
3430 return;
3431 }
3432
3433 ScDocShellModificator aModificator( rDocShell );
3434
3435 if ( !bVisible && !rDoc.IsImportingXML() ) // #i57869# allow hiding in any order for loading
3436 {
3437 // do not disable all sheets
3438
3439 sal_uInt16 nVisCount = 0;
3440 SCTAB nCount = rDoc.GetTableCount();
3441 for (SCTAB i=0; i<nCount && nVisCount<2; i++)
3442 if (rDoc.IsVisible(i))
3443 ++nVisCount;
3444
3445 if (nVisCount <= 1)
3446 {
3447 if (!bApi)
3448 rDocShell.ErrorMessage(STR_PROTECTIONERR);
3449 return;
3450 }
3451 }
3452
3453 rDoc.SetVisible( nTab, bVisible );
3454 if (bUndo)
3455 {
3456 std::vector<SCTAB> undoTabs { nTab };
3457 rDocShell.GetUndoManager()->AddUndoAction( std::make_unique<ScUndoShowHideTab>( &rDocShell, std::move(undoTabs), bVisible ) );
3458 }
3459
3460 // update views
3461 if (!bVisible)
3462 rDocShell.Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
3463
3464 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
3466 aModificator.SetDocumentModified();
3467}
3468
3469bool ScDocFunc::SetLayoutRTL( SCTAB nTab, bool bRTL )
3470{
3472 bool bUndo(rDoc.IsUndoEnabled());
3473 if ( rDoc.IsLayoutRTL( nTab ) == bRTL )
3474 return true; // nothing to do - ok
3475
3477
3478 ScDocShellModificator aModificator( rDocShell );
3479
3481
3482 if (bUndo)
3483 {
3484 rDocShell.GetUndoManager()->AddUndoAction( std::make_unique<ScUndoLayoutRTL>( &rDocShell, nTab, bRTL ) );
3485 }
3486
3488 aModificator.SetDocumentModified();
3489
3490 SfxBindings* pBindings = rDocShell.GetViewBindings();
3491 if (pBindings)
3492 {
3493 pBindings->Invalidate( FID_TAB_RTL );
3494 pBindings->Invalidate( SID_ATTR_SIZE );
3495 }
3496
3497 return true;
3498}
3499
3500bool ScDocFunc::RenameTable( SCTAB nTab, const OUString& rName, bool bRecord, bool bApi )
3501{
3503 if (bRecord && !rDoc.IsUndoEnabled())
3504 bRecord = false;
3505 if ( !rDoc.IsDocEditable() )
3506 {
3507 if (!bApi)
3508 rDocShell.ErrorMessage(STR_PROTECTIONERR);
3509 return false;
3510 }
3511
3512 ScDocShellModificator aModificator( rDocShell );
3513
3514 bool bSuccess = false;
3515 OUString sOldName;
3516 rDoc.GetName(nTab, sOldName);
3517 if (rDoc.RenameTab( nTab, rName ))
3518 {
3519 if (bRecord)
3520 {
3522 std::make_unique<ScUndoRenameTab>( &rDocShell, nTab, sOldName, rName));
3523 }
3525 aModificator.SetDocumentModified();
3526 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
3527 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
3528
3529 bSuccess = true;
3530 }
3531 return bSuccess;
3532}
3533
3534bool ScDocFunc::SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi )
3535{
3536
3538 if (bRecord && !rDoc.IsUndoEnabled())
3539 bRecord = false;
3540 if ( !rDoc.IsDocEditable() || rDoc.IsTabProtected(nTab) )
3541 {
3542 if (!bApi)
3543 rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Check to see what this string is...
3544 return false;
3545 }
3546
3547 Color aOldTabBgColor = rDoc.GetTabBgColor(nTab);
3548
3549 bool bSuccess = false;
3550 rDoc.SetTabBgColor(nTab, rColor);
3551 if ( rDoc.GetTabBgColor(nTab) == rColor)
3552 bSuccess = true;
3553 if (bSuccess)
3554 {
3555 if (bRecord)
3556 {
3558 std::make_unique<ScUndoTabColor>( &rDocShell, nTab, aOldTabBgColor, rColor));
3559 }
3561 ScDocShellModificator aModificator( rDocShell );
3562 aModificator.SetDocumentModified();
3563 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
3564
3565 bSuccess = true;
3566 }
3567 return bSuccess;
3568}
3569
3571 ScUndoTabColorInfo::List& rUndoTabColorList, bool bApi )
3572{
3574 bool bRecord = true;
3575 if (!rDoc.IsUndoEnabled())
3576 bRecord = false;
3577
3578 if ( !rDoc.IsDocEditable() )
3579 {
3580 if (!bApi)
3581 rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
3582 return false;
3583 }
3584
3585 sal_uInt16 nTab;
3586 Color aNewTabBgColor;
3587 bool bSuccess = true;
3588 size_t nTabProtectCount = 0;
3589 size_t nTabListCount = rUndoTabColorList.size();
3590 for ( size_t i = 0; i < nTabListCount; ++i )
3591 {
3592 ScUndoTabColorInfo& rInfo = rUndoTabColorList[i];
3593 nTab = rInfo.mnTabId;
3594 if ( !rDoc.IsTabProtected(nTab) )
3595 {
3596 aNewTabBgColor = rInfo.maNewTabBgColor;
3597 rInfo.maOldTabBgColor = rDoc.GetTabBgColor(nTab);
3598 rDoc.SetTabBgColor(nTab, aNewTabBgColor);
3599 if ( rDoc.GetTabBgColor(nTab) != aNewTabBgColor)
3600 {
3601 bSuccess = false;
3602 break;
3603 }
3604 }
3605 else
3606 {
3607 nTabProtectCount++;
3608 }
3609 }
3610
3611 if ( nTabProtectCount == nTabListCount )
3612 {
3613 if (!bApi)
3614 rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
3615 return false;
3616 }
3617
3618 if (bSuccess)
3619 {
3620 if (bRecord)
3621 {
3623 std::make_unique<ScUndoTabColor>( &rDocShell, std::vector(rUndoTabColorList)));
3624 }
3626 ScDocShellModificator aModificator( rDocShell );
3627 aModificator.SetDocumentModified();
3628 }
3629 return bSuccess;
3630}
3631
3636
3637static sal_uInt16 lcl_GetOptimalColWidth( ScDocShell& rDocShell, SCCOL nCol, SCTAB nTab )
3638{
3639 ScSizeDeviceProvider aProv(&rDocShell);
3640 OutputDevice* pDev = aProv.GetDevice(); // has pixel MapMode
3641 double nPPTX = aProv.GetPPTX();
3642 double nPPTY = aProv.GetPPTY();
3643
3644 ScDocument& rDoc = rDocShell.GetDocument();
3645 Fraction aOne(1,1);
3646 sal_uInt16 nTwips = rDoc.GetOptimalColWidth( nCol, nTab, pDev, nPPTX, nPPTY, aOne, aOne,
3647 false/*bFormula*/ );
3648
3649 return nTwips;
3650}
3651
3653 bool bWidth, const std::vector<sc::ColRowSpan>& rRanges, SCTAB nTab,
3654 ScSizeMode eMode, sal_uInt16 nSizeTwips, bool bRecord, bool bApi )
3655{
3656 ScDocShellModificator aModificator( rDocShell );
3657
3658 if (rRanges.empty())
3659 return true;
3660
3662 if ( bRecord && !rDoc.IsUndoEnabled() )
3663 bRecord = false;
3664
3665 // import into read-only document is possible
3666 if ( !rDoc.IsChangeReadOnlyEnabled() && !rDocShell.IsEditable() )
3667 {
3668 if (!bApi)
3669 rDocShell.ErrorMessage(STR_PROTECTIONERR);
3670 return false;
3671 }
3672
3673 SCCOLROW nStart = rRanges[0].mnStart;
3674 SCCOLROW nEnd = rRanges[0].mnEnd;
3675
3676 if ( eMode == SC_SIZE_OPTIMAL )
3677 {
3679 }
3680
3681 ScDocumentUniquePtr pUndoDoc;
3682 std::unique_ptr<ScOutlineTable> pUndoTab;
3683 std::vector<sc::ColRowSpan> aUndoRanges;
3684
3685 if ( bRecord )
3686 {
3687 rDoc.BeginDrawUndo(); // Drawing Updates
3688
3689 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
3690 if (bWidth)
3691 {
3692 pUndoDoc->InitUndo( rDoc, nTab, nTab, true );
3693 rDoc.CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab, static_cast<SCCOL>(nEnd), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, *pUndoDoc );
3694 }
3695 else
3696 {
3697 pUndoDoc->InitUndo( rDoc, nTab, nTab, false, true );
3698 rDoc.CopyToDocument( 0, static_cast<SCROW>(nStart), nTab, rDoc.MaxCol(), static_cast<SCROW>(nEnd), nTab, InsertDeleteFlags::NONE, false, *pUndoDoc );
3699 }
3700
3701 aUndoRanges = rRanges;
3702
3703 ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
3704 if (pTable)
3705 pUndoTab.reset(new ScOutlineTable( *pTable ));
3706 }
3707
3708 bool bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT;
3709 bool bOutline = false;
3710
3711 for (const sc::ColRowSpan& rRange : rRanges)
3712 {
3713 SCCOLROW nStartNo = rRange.mnStart;
3714 SCCOLROW nEndNo = rRange.mnEnd;
3715
3716 if ( !bWidth ) // deal with heights always in blocks
3717 {
3719 {
3720 bool bAll = ( eMode==SC_SIZE_OPTIMAL );
3721 if (!bAll)
3722 {
3723 // delete for all that have CRFlags::ManualSize enabled
3724 // then SetOptimalHeight with bShrink = FALSE
3725 for (SCROW nRow=nStartNo; nRow<=nEndNo; nRow++)
3726 {
3727 CRFlags nOld = rDoc.GetRowFlags(nRow,nTab);
3728 SCROW nLastRow = -1;
3729 bool bHidden = rDoc.RowHidden(nRow, nTab, nullptr, &nLastRow);
3730 if ( !bHidden && ( nOld & CRFlags::ManualSize ) )
3731 rDoc.SetRowFlags( nRow, nTab, nOld & ~CRFlags::ManualSize );
3732 }
3733 }
3734
3736 Fraction aOne(1,1);
3737 sc::RowHeightContext aCxt(rDoc.MaxRow(), aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, aProv.GetDevice());
3738 aCxt.setForceAutoSize(bAll);
3739 rDoc.SetOptimalHeight(aCxt, nStartNo, nEndNo, nTab, bApi);
3740
3741 if (bAll)
3742 rDoc.ShowRows( nStartNo, nEndNo, nTab, true );
3743
3744 // Manual flag will be set already in SetOptimalHeight if bAll=true
3745 // (it is on when Extra-Height, otherwise off).
3746 }
3748 {
3749 if (nSizeTwips)
3750 {
3751 rDoc.SetRowHeightRange( nStartNo, nEndNo, nTab, nSizeTwips );
3752 rDoc.SetManualHeight( nStartNo, nEndNo, nTab, true ); // height was set manually
3753 }
3754 if ( eMode != SC_SIZE_ORIGINAL )
3755 rDoc.ShowRows( nStartNo, nEndNo, nTab, nSizeTwips != 0 );
3756 }
3757 else if ( eMode==SC_SIZE_SHOW )
3758 {
3759 rDoc.ShowRows( nStartNo, nEndNo, nTab, true );
3760 }
3761 }
3762 else // Column widths
3763 {
3764 for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++)
3765 {
3766 if ( eMode != SC_SIZE_VISOPT || !rDoc.ColHidden(nCol, nTab) )
3767 {
3768 sal_uInt16 nThisSize = nSizeTwips;
3769
3771 nThisSize = nSizeTwips +
3772 lcl_GetOptimalColWidth( rDocShell, nCol, nTab );
3773 if ( nThisSize )
3774 rDoc.SetColWidth( nCol, nTab, nThisSize );
3775
3776 if ( eMode != SC_SIZE_ORIGINAL )
3777 rDoc.ShowCol( nCol, nTab, bShow );
3778 }
3779 }
3780 }
3781
3782 // adjust outlines
3783
3784 if ( eMode != SC_SIZE_ORIGINAL )
3785 {
3786 if (bWidth)
3787 bOutline = bOutline || rDoc.UpdateOutlineCol(
3788 static_cast<SCCOL>(nStartNo),
3789 static_cast<SCCOL>(nEndNo), nTab, bShow );
3790 else
3791 bOutline = bOutline || rDoc.UpdateOutlineRow(
3792 static_cast<SCROW>(nStartNo),
3793 static_cast<SCROW>(nEndNo), nTab, bShow );
3794 }
3795 }
3796 rDoc.SetDrawPageSize(nTab);
3797
3798 if (!bOutline)
3799 pUndoTab.reset();
3800
3801 if (bRecord)
3802 {
3803 ScMarkData aMark(rDoc.GetSheetLimits());
3804 aMark.SelectOneTable( nTab );
3806 std::make_unique<ScUndoWidthOrHeight>(
3807 &rDocShell, aMark, nStart, nTab, nEnd, nTab, std::move(pUndoDoc),
3808 std::move(aUndoRanges), std::move(pUndoTab), eMode, nSizeTwips, bWidth));
3809 }
3810
3811 rDoc.UpdatePageBreaks( nTab );
3812
3814 if (pViewSh)
3815 pViewSh->OnLOKSetWidthOrHeight(nStart, bWidth);
3816
3817 rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::All);
3818 aModificator.SetDocumentModified();
3819
3820 return false;
3821}
3822
3823bool ScDocFunc::InsertPageBreak( bool bColumn, const ScAddress& rPos,
3824 bool bRecord, bool bSetModified )
3825{
3826 ScDocShellModificator aModificator( rDocShell );
3827
3829 if (bRecord && !rDoc.IsUndoEnabled())
3830 bRecord = false;
3831 SCTAB nTab = rPos.Tab();
3832 SfxBindings* pBindings = rDocShell.GetViewBindings();
3833
3834 SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
3835 static_cast<SCCOLROW>(rPos.Row());
3836 if (nPos == 0)
3837 return false; // first column / row
3838
3839 ScBreakType nBreak = bColumn ?
3840 rDoc.HasColBreak(static_cast<SCCOL>(nPos), nTab) :
3841 rDoc.HasRowBreak(static_cast<SCROW>(nPos), nTab);
3842 if (nBreak & ScBreakType::Manual)
3843 return true;
3844
3845 if (bRecord)
3847 std::make_unique<ScUndoPageBreak>( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, true ) );
3848
3849 if (bColumn)
3850 rDoc.SetColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
3851 else
3852 rDoc.SetRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
3853
3854 rDoc.InvalidatePageBreaks(nTab);
3855 rDoc.UpdatePageBreaks( nTab );
3856
3857 rDoc.SetStreamValid(nTab, false);
3858
3859 if (bColumn)
3860 {
3861 rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab, PaintPartFlags::Grid );
3862 if (pBindings)
3863 {
3864 pBindings->Invalidate( FID_INS_COLBRK );
3865 pBindings->Invalidate( FID_DEL_COLBRK );
3866 }
3867 }
3868 else
3869 {
3870 rDocShell.PostPaint( 0, static_cast<SCROW>(nPos)-1, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab, PaintPartFlags::Grid );
3871 if (pBindings)
3872 {
3873 pBindings->Invalidate( FID_INS_ROWBRK );
3874 pBindings->Invalidate( FID_DEL_ROWBRK );
3875 }
3876 }
3877 if (pBindings)
3878 pBindings->Invalidate( FID_DEL_MANUALBREAKS );
3879
3880 if (bSetModified)
3881 aModificator.SetDocumentModified();
3882
3883 return true;
3884}
3885
3886bool ScDocFunc::RemovePageBreak( bool bColumn, const ScAddress& rPos,
3887 bool bRecord, bool bSetModified )
3888{
3889 ScDocShellModificator aModificator( rDocShell );
3890
3892 if (bRecord && !rDoc.IsUndoEnabled())
3893 bRecord = false;
3894 SCTAB nTab = rPos.Tab();
3895 SfxBindings* pBindings = rDocShell.GetViewBindings();
3896
3897 SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
3898 static_cast<SCCOLROW>(rPos.Row());
3899
3900 ScBreakType nBreak;
3901 if (bColumn)
3902 nBreak = rDoc.HasColBreak(static_cast<SCCOL>(nPos), nTab);
3903 else
3904 nBreak = rDoc.HasRowBreak(static_cast<SCROW>(nPos), nTab);
3905 if (!(nBreak & ScBreakType::Manual))
3906 // There is no manual break.
3907 return false;
3908
3909 if (bRecord)
3911 std::make_unique<ScUndoPageBreak>( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, false ) );
3912
3913 if (bColumn)
3914 rDoc.RemoveColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
3915 else
3916 rDoc.RemoveRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
3917
3918 rDoc.UpdatePageBreaks( nTab );
3919
3920 rDoc.SetStreamValid(nTab, false);
3921
3922 if (bColumn)
3923 {
3924 rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab, PaintPartFlags::Grid );
3925 if (pBindings)
3926 {
3927 pBindings->Invalidate( FID_INS_COLBRK );
3928 pBindings->Invalidate( FID_DEL_COLBRK );
3929 }
3930 }
3931 else
3932 {
3933 rDocShell.PostPaint( 0, nPos-1, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab, PaintPartFlags::Grid );
3934 if (pBindings)
3935 {
3936 pBindings->Invalidate( FID_INS_ROWBRK );
3937 pBindings->Invalidate( FID_DEL_ROWBRK );
3938 }
3939 }
3940 if (pBindings)
3941 pBindings->Invalidate( FID_DEL_MANUALBREAKS );
3942
3943 if (bSetModified)
3944 aModificator.SetDocumentModified();
3945
3946 return true;
3947}
3948
3950{
3952
3953 std::unique_ptr<ScTableProtection> p;
3954 if (!rProtect.isProtected() && rDoc.IsUndoEnabled())
3955 {
3956 // In case of unprotecting, use a copy of passed ScTableProtection object for undo
3957 p = std::make_unique<ScTableProtection>(rProtect);
3958 }
3959 rDoc.SetTabProtection(nTab, &rProtect);
3960 if (rDoc.IsUndoEnabled())
3961 {
3962 if (!p)
3963 {
3964 // For protection case, use a copy of resulting ScTableProtection for undo
3965 const ScTableProtection* pProtect = rDoc.GetTabProtection(nTab);
3966 p = std::make_unique<ScTableProtection>(*pProtect);
3967 }
3969 std::make_unique<ScUndoTabProtect>(&rDocShell, nTab, std::move(p)));
3970 // ownership of unique_ptr now transferred to ScUndoTabProtect.
3971 }
3973 fr = SfxViewFrame::GetNext(*fr, &rDocShell))
3974 if (ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(fr->GetViewShell()))
3975 pTabViewShell->SetTabProtectionSymbol(nTab, rProtect.isProtected());
3977 ScDocShellModificator aModificator(rDocShell);
3978 aModificator.SetDocumentModified();
3979}
3980
3982{
3984
3985 std::unique_ptr<ScDocProtection> p;
3986 if (!rProtect.isProtected() && rDoc.IsUndoEnabled())
3987 {
3988 // In case of unprotecting, use a copy of passed ScTableProtection object for undo
3989 p = std::make_unique<ScDocProtection>(rProtect);
3990 }
3991 rDoc.SetDocProtection(&rProtect);
3992 if (rDoc.IsUndoEnabled())
3993 {
3994 if (!p)
3995 {
3996 // For protection case, use a copy of resulting ScTableProtection for undo
3997 ScDocProtection* pProtect = rDoc.GetDocProtection();
3998 p = std::make_unique<ScDocProtection>(*pProtect);
3999 }
4001 std::make_unique<ScUndoDocProtect>(&rDocShell, std::move(p)));
4002 // ownership of unique_ptr now transferred to ScUndoTabProtect.
4003 }
4004
4006 ScDocShellModificator aModificator(rDocShell);
4007 aModificator.SetDocumentModified();
4008}
4009
4010bool ScDocFunc::Protect( SCTAB nTab, const OUString& rPassword )
4011{
4012 if (nTab == TABLEID_DOC)
4013 {
4014 // document protection
4015 ScDocProtection aProtection;
4016 aProtection.setProtected(true);
4017 aProtection.setPassword(rPassword);
4018 ProtectDocument(aProtection);
4019
4020 }
4021 else
4022 {
4023 // sheet protection
4024
4025 const ScTableProtection* pOldProtection = rDocShell.GetDocument().GetTabProtection(nTab);
4026 ::std::unique_ptr<ScTableProtection> pNewProtection(pOldProtection ? new ScTableProtection(*pOldProtection) : new ScTableProtection());
4027 pNewProtection->setProtected(true);
4028 pNewProtection->setPassword(rPassword);
4029 ProtectSheet(nTab, *pNewProtection);
4030 }
4031 return true;
4032}
4033
4034bool ScDocFunc::Unprotect( SCTAB nTab, const OUString& rPassword, bool bApi )
4035{
4037
4038 if (nTab == TABLEID_DOC)
4039 {
4040 // document protection
4041
4042 ScDocProtection* pDocProtect = rDoc.GetDocProtection();
4043 if (!pDocProtect || !pDocProtect->isProtected())
4044 // already unprotected (should not happen)!
4045 return true;
4046
4047 if (!pDocProtect->verifyPassword(rPassword))
4048 {
4049 if (!bApi)
4050 {
4051 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
4052 VclMessageType::Info, VclButtonsType::Ok,
4053 ScResId(SCSTR_WRONGPASSWORD)));
4054 xInfoBox->run();
4055 }
4056 return false;
4057 }
4058
4059 ScDocProtection aNewProtection(*pDocProtect);
4060 aNewProtection.setProtected(false);
4061 ProtectDocument(aNewProtection);
4062
4063 }
4064 else
4065 {
4066 // sheet protection
4067
4068 const ScTableProtection* pTabProtect = rDoc.GetTabProtection(nTab);
4069 if (!pTabProtect || !pTabProtect->isProtected())
4070 // already unprotected (should not happen)!
4071 return true;
4072 if (!pTabProtect->verifyPassword(rPassword))
4073 {
4074 if (!bApi)
4075 {
4076 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
4077 VclMessageType::Info, VclButtonsType::Ok,
4078 ScResId(SCSTR_WRONGPASSWORD)));
4079 xInfoBox->run();
4080 }
4081 return false;
4082 }
4083
4084 ScTableProtection aNewProtection(*pTabProtect);
4085 aNewProtection.setProtected(false);
4086 ProtectSheet(nTab, aNewProtection);
4087 }
4088
4089 return true;
4090}
4091
4092void ScDocFunc::ClearItems( const ScMarkData& rMark, const sal_uInt16* pWhich, bool bApi )
4093{
4094 ScDocShellModificator aModificator( rDocShell );
4095
4097 bool bUndo (rDoc.IsUndoEnabled());
4098 ScEditableTester aTester( rDoc, rMark );
4099 if (!aTester.IsEditable())
4100 {
4101 if (!bApi)
4103 return;
4104 }
4105
4106 // #i12940# ClearItems is called (from setPropertyToDefault) directly with uno object's cached
4107 // MarkData (GetMarkData), so rMark must be changed to multi selection for ClearSelectionItems
4108 // here.
4109
4110 ScMarkData aMultiMark = rMark;
4111 aMultiMark.SetMarking(false); // for MarkToMulti
4112 aMultiMark.MarkToMulti();
4113 const ScRange& aMarkRange = aMultiMark.GetMultiMarkArea();
4114
4115 if (bUndo)
4116 {
4117 SCTAB nStartTab = aMarkRange.aStart.Tab();
4118 SCTAB nEndTab = aMarkRange.aEnd.Tab();
4119
4121 pUndoDoc->InitUndo( rDoc, nStartTab, nEndTab );
4122 rDoc.CopyToDocument( aMarkRange, InsertDeleteFlags::ATTRIB, true, *pUndoDoc, &aMultiMark );
4123
4125 std::make_unique<ScUndoClearItems>( &rDocShell, aMultiMark, std::move(pUndoDoc), pWhich ) );
4126 }
4127
4128 rDoc.ClearSelectionItems( pWhich, aMultiMark );
4129
4131 aModificator.SetDocumentModified();
4132
4134}
4135
4136bool ScDocFunc::ChangeIndent( const ScMarkData& rMark, bool bIncrement, bool bApi )
4137{
4138 ScDocShellModificator aModificator( rDocShell );
4139
4141 bool bUndo(rDoc.IsUndoEnabled());
4142 ScEditableTester aTester( rDoc, rMark );
4143 if (!aTester.IsEditable())
4144 {
4145 if (!bApi)
4147 return false;
4148 }
4149
4150 const ScRange& aMarkRange = rMark.GetMultiMarkArea();
4151
4152 if (bUndo)
4153 {
4154 SCTAB nStartTab = aMarkRange.aStart.Tab();
4155 SCTAB nTabCount = rDoc.GetTableCount();
4156
4158 pUndoDoc->InitUndo( rDoc, nStartTab, nStartTab );
4159 for (const auto& rTab : rMark)
4160 {
4161 if (rTab >= nTabCount)
4162 break;
4163
4164 if (rTab != nStartTab)
4165 pUndoDoc->AddUndoTab( rTab, rTab );
4166 }
4167
4168 ScRange aCopyRange = aMarkRange;
4169 aCopyRange.aStart.SetTab(0);
4170 aCopyRange.aEnd.SetTab(nTabCount-1);
4171 rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, true, *pUndoDoc, &rMark );
4172
4174 std::make_unique<ScUndoIndent>( &rDocShell, rMark, std::move(pUndoDoc), bIncrement ) );
4175 }
4176
4177 rDoc.ChangeSelectionIndent( bIncrement, rMark );
4178
4180 aModificator.SetDocumentModified();
4181
4182 SfxBindings* pBindings = rDocShell.GetViewBindings();
4183 if (pBindings)
4184 {
4185 pBindings->Invalidate( SID_ALIGNLEFT ); // ChangeIndent aligns left
4186 pBindings->Invalidate( SID_ALIGNRIGHT );
4187 pBindings->Invalidate( SID_ALIGNBLOCK );
4188 pBindings->Invalidate( SID_ALIGNCENTERHOR );
4189 pBindings->Invalidate( SID_ATTR_LRSPACE );
4190 pBindings->Invalidate( SID_ATTR_PARA_ADJUST_LEFT );
4191 pBindings->Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
4192 pBindings->Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
4193 pBindings->Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
4194 // pseudo slots for Format menu
4195 pBindings->Invalidate( SID_ALIGN_ANY_HDEFAULT );
4196 pBindings->Invalidate( SID_ALIGN_ANY_LEFT );
4197 pBindings->Invalidate( SID_ALIGN_ANY_HCENTER );
4198 pBindings->Invalidate( SID_ALIGN_ANY_RIGHT );
4199 pBindings->Invalidate( SID_ALIGN_ANY_JUSTIFIED );
4200 }
4201
4202 return true;
4203}
4204
4205bool ScDocFunc::AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
4206 sal_uInt16 nFormatNo, bool bApi )
4207{
4208 ScDocShellModificator aModificator( rDocShell );
4209
4211 SCCOL nStartCol = rRange.aStart.Col();
4212 SCROW nStartRow = rRange.aStart.Row();
4213 SCTAB nStartTab = rRange.aStart.Tab();
4214 SCCOL nEndCol = rRange.aEnd.Col();
4215 SCROW nEndRow = rRange.aEnd.Row();
4216 SCTAB nEndTab = rRange.aEnd.Tab();
4217
4218 bool bRecord = true;
4219 if (!rDoc.IsUndoEnabled())
4220 bRecord = false;
4221 ScMarkData aMark(rDoc.GetSheetLimits());
4222 if (pTabMark)
4223 aMark = *pTabMark;
4224 else
4225 {
4226 for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4227 aMark.SelectTable( nTab, true );
4228 }
4229
4231 ScEditableTester aTester( rDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
4232 if ( nFormatNo < pAutoFormat->size() && aTester.IsEditable() )
4233 {
4235
4236 bool bSize = pAutoFormat->findByIndex(nFormatNo)->GetIncludeWidthHeight();
4237
4238 SCTAB nTabCount = rDoc.GetTableCount();
4239 ScDocumentUniquePtr pUndoDoc;
4240 if ( bRecord )
4241 {
4242 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
4243 pUndoDoc->InitUndo( rDoc, nStartTab, nStartTab, bSize, bSize );
4244 for (const auto& rTab : aMark)
4245 {
4246 if (rTab >= nTabCount)
4247 break;
4248
4249 if (rTab != nStartTab)
4250 pUndoDoc->AddUndoTab( rTab, rTab, bSize, bSize );
4251 }
4252
4253 ScRange aCopyRange = rRange;
4254 aCopyRange.aStart.SetTab(0);
4255 aCopyRange.aStart.SetTab(nTabCount-1);
4256 rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, false, *pUndoDoc, &aMark );
4257 if (bSize)
4258 {
4259 rDoc.CopyToDocument( nStartCol,0,0, nEndCol,rDoc.MaxRow(),nTabCount-1,
4260 InsertDeleteFlags::NONE, false, *pUndoDoc, &aMark );
4261 rDoc.CopyToDocument( 0,nStartRow,0, rDoc.MaxCol(),nEndRow,nTabCount-1,
4262 InsertDeleteFlags::NONE, false, *pUndoDoc, &aMark );
4263 }
4264 rDoc.BeginDrawUndo();
4265 }
4266
4267 rDoc.AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, aMark );
4268
4269 if (bSize)
4270 {
4271 std::vector<sc::ColRowSpan> aCols(1, sc::ColRowSpan(nStartCol,nEndCol));
4272 std::vector<sc::ColRowSpan> aRows(1, sc::ColRowSpan(nStartRow,nEndRow));
4273
4274 for (const auto& rTab : aMark)
4275 {
4276 if (rTab >= nTabCount)
4277 break;
4278
4279 SetWidthOrHeight(true, aCols, rTab, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, false, true);
4280 SetWidthOrHeight(false, aRows, rTab, SC_SIZE_VISOPT, 0, false, false);
4281 rDocShell.PostPaint( 0,0,rTab, rDoc.MaxCol(),rDoc.MaxRow(),rTab,
4283 }
4284 }
4285 else
4286 {
4287 for (const auto& rTab : aMark)
4288 {
4289 if (rTab >= nTabCount)
4290 break;
4291
4292 bool bAdj = AdjustRowHeight( ScRange(nStartCol, nStartRow, rTab,
4293 nEndCol, nEndRow, rTab), false, bApi );
4294 if (bAdj)
4295 rDocShell.PostPaint( 0,nStartRow,rTab, rDoc.MaxCol(),rDoc.MaxRow(),rTab,
4297 else
4298 rDocShell.PostPaint( nStartCol, nStartRow, rTab,
4299 nEndCol, nEndRow, rTab, PaintPartFlags::Grid );
4300 }
4301 }
4302
4303 if ( bRecord ) // only now is Draw-Undo available
4304 {
4306 std::make_unique<ScUndoAutoFormat>( &rDocShell, rRange, std::move(pUndoDoc), aMark, bSize, nFormatNo ) );
4307 }
4308
4309 aModificator.SetDocumentModified();
4310 }
4311 else if (!bApi)
4313
4314 return false;
4315}
4316
4317bool ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
4318 const ScTokenArray* pTokenArray, const OUString& rString, bool bApi, bool bEnglish,
4319 const OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
4320{
4321 if (ScViewData::SelectionFillDOOM( rRange ))
4322 return false;
4323
4324 ScDocShellModificator aModificator( rDocShell );
4325
4326 bool bSuccess = false;
4328 SCCOL nStartCol = rRange.aStart.Col();
4329 SCROW nStartRow = rRange.aStart.Row();
4330 SCTAB nStartTab = rRange.aStart.Tab();
4331 SCCOL nEndCol = rRange.aEnd.Col();
4332 SCROW nEndRow = rRange.aEnd.Row();
4333 SCTAB nEndTab = rRange.aEnd.Tab();
4334
4335 ScMarkData aMark(rDoc.GetSheetLimits());
4336 if (pTabMark)
4337 aMark = *pTabMark;
4338 else
4339 {
4340 for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4341 aMark.SelectTable( nTab, true );
4342 }
4343
4344 ScEditableTester aTester( rDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
4345 if ( aTester.IsEditable() )
4346 {
4348
4349 ScDocumentUniquePtr pUndoDoc;
4350
4351 const bool bUndo(rDoc.IsUndoEnabled());
4352 if (bUndo)
4353 {
4355 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
4356 pUndoDoc->InitUndo( rDoc, nStartTab, nEndTab );
4357 rDoc.CopyToDocument( rRange, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE, false, *pUndoDoc );
4358 }
4359
4360 // use TokenArray if given, string (and flags) otherwise
4361 if ( pTokenArray )
4362 {
4363 rDoc.InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
4364 aMark, OUString(), pTokenArray, eGrammar);
4365 }
4366 else if ( rDoc.IsImportingXML() )
4367 {
4368 ScTokenArray aCode(rDoc);
4369 aCode.AssignXMLString( rString,
4370 ((eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) ? rFormulaNmsp : OUString()));
4371 rDoc.InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
4372 aMark, OUString(), &aCode, eGrammar);
4373 rDoc.IncXMLImportedFormulaCount( rString.getLength() );
4374 }
4375 else if (bEnglish)
4376 {
4377 ScCompiler aComp( rDoc, rRange.aStart, eGrammar);
4378 std::unique_ptr<ScTokenArray> pCode = aComp.CompileString( rString );
4379 rDoc.InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
4380 aMark, OUString(), pCode.get(), eGrammar);
4381 }
4382 else
4383 rDoc.InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
4384 aMark, rString, nullptr, eGrammar);
4385
4386 if (bUndo)
4387 {
4390 std::make_unique<ScUndoEnterMatrix>( &rDocShell, rRange, std::move(pUndoDoc), rString ) );
4391 }
4392
4393 // Err522 painting of DDE-Formulas will be intercepted during interpreting
4394 rDocShell.PostPaint( nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab, PaintPartFlags::Grid );
4395 aModificator.SetDocumentModified();
4396
4397 bSuccess = true;
4398 }
4399 else if (!bApi)
4401
4402 return bSuccess;
4403}
4404
4405bool ScDocFunc::TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
4406 const ScTabOpParam& rParam, bool bRecord, bool bApi )
4407{
4408 ScDocShellModificator aModificator( rDocShell );
4409
4410 bool bSuccess = false;
4412 SCCOL nStartCol = rRange.aStart.Col();
4413 SCROW nStartRow = rRange.aStart.Row();
4414 SCTAB nStartTab = rRange.aStart.Tab();
4415 SCCOL nEndCol = rRange.aEnd.Col();
4416 SCROW nEndRow = rRange.aEnd.Row();
4417 SCTAB nEndTab = rRange.aEnd.Tab();
4418
4419 if (bRecord && !rDoc.IsUndoEnabled())
4420 bRecord = false;
4421
4422 ScMarkData aMark(rDoc.GetSheetLimits());
4423 if (pTabMark)
4424 aMark = *pTabMark;
4425 else
4426 {
4427 for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4428 aMark.SelectTable( nTab, true );
4429 }
4430
4431 ScEditableTester aTester( rDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
4432 if ( aTester.IsEditable() )
4433 {
4435 rDoc.SetDirty( rRange, false );
4436 if ( bRecord )
4437 {
4440 pUndoDoc->InitUndo( rDoc, nStartTab, nEndTab );
4441 rDoc.CopyToDocument( rRange, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE, false, *pUndoDoc );
4442
4444 std::make_unique<ScUndoTabOp>( &rDocShell,
4445 nStartCol, nStartRow, nStartTab,
4446 nEndCol, nEndRow, nEndTab, std::move(pUndoDoc),
4447 rParam.aRefFormulaCell,
4448 rParam.aRefFormulaEnd,
4449 rParam.aRefRowCell,
4450 rParam.aRefColCell,
4451 rParam.meMode) );
4452 }
4453 rDoc.InsertTableOp(rParam, nStartCol, nStartRow, nEndCol, nEndRow, aMark);
4455 aModificator.SetDocumentModified();
4456 bSuccess = true;
4457 }
4458 else if (!bApi)
4460
4461 return bSuccess;
4462}
4463
4465{
4466 if (eDir==FILL_TO_BOTTOM)
4467 return DIR_BOTTOM;
4468 else if (eDir==FILL_TO_RIGHT)
4469 return DIR_RIGHT;
4470 else if (eDir==FILL_TO_TOP)
4471 return DIR_TOP;
4472 else // if (eDir==FILL_TO_LEFT)
4473 return DIR_LEFT;
4474}
4475
4476namespace {
4477
4482void adjustFillRangeForAdjacentCopy(const ScDocument &rDoc, ScRange& rRange, FillDir eDir)
4483{
4484 switch (eDir)
4485 {
4486 case FILL_TO_BOTTOM:
4487 {
4488 if (rRange.aStart.Row() == 0)
4489 return;
4490
4491 if (rRange.aStart.Row() != rRange.aEnd.Row())
4492 return;
4493
4494 // Include the above row.
4495 ScAddress& s = rRange.aStart;
4496 s.SetRow(s.Row()-1);
4497 }
4498 break;
4499 case FILL_TO_TOP:
4500 {
4501 if (rRange.aStart.Row() == rDoc.MaxRow())
4502 return;
4503
4504 if (rRange.aStart.Row() != rRange.aEnd.Row())
4505 return;
4506
4507 // Include the row below.
4508 ScAddress& e = rRange.aEnd;
4509 e.SetRow(e.Row()+1);
4510 }
4511 break;
4512 case FILL_TO_LEFT:
4513 {
4514 if (rRange.aStart.Col() == rDoc.MaxCol())
4515 return;
4516
4517 if (rRange.aStart.Col() != rRange.aEnd.Col())
4518 return;
4519
4520 // Include the column to the right.
4521 ScAddress& e = rRange.aEnd;
4522 e.SetCol(e.Col()+1);
4523 }
4524 break;
4525 case FILL_TO_RIGHT:
4526 {
4527 if (rRange.aStart.Col() == 0)
4528 return;
4529
4530 if (rRange.aStart.Col() != rRange.aEnd.Col())
4531 return;
4532
4533 // Include the column to the left.
4534 ScAddress& s = rRange.aStart;
4535 s.SetCol(s.Col()-1);
4536 }
4537 break;
4538 default:
4539 ;
4540 }
4541}
4542
4543}
4544
4545bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
4546 FillDir eDir, bool bApi )
4547{
4548 ScDocShellModificator aModificator( rDocShell );
4550
4551 bool bSuccess = false;
4552 ScRange aRange = rRange;
4553 adjustFillRangeForAdjacentCopy(rDoc, aRange, eDir);
4554
4555 SCCOL nStartCol = aRange.aStart.Col();
4556 SCROW nStartRow = aRange.aStart.Row();
4557 SCTAB nStartTab = aRange.aStart.Tab();
4558 SCCOL nEndCol = aRange.aEnd.Col();
4559 SCROW nEndRow = aRange.aEnd.Row();
4560 SCTAB nEndTab = aRange.aEnd.Tab();
4561
4562 bool bRecord = true;
4563 if (!rDoc.IsUndoEnabled())
4564 bRecord = false;
4565
4566 ScMarkData aMark(rDoc.GetSheetLimits());
4567 if (pTabMark)
4568 aMark = *pTabMark;
4569 else
4570 {
4571 for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4572 aMark.SelectTable( nTab, true );
4573 }
4574
4575 ScEditableTester aTester( rDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
4576 if ( aTester.IsEditable() )
4577 {
4579
4580 ScRange aSourceArea = aRange;
4581 ScRange aDestArea = aRange;
4582
4583 SCCOLROW nCount = 0;
4584 switch (eDir)
4585 {
4586 case FILL_TO_BOTTOM:
4587 nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
4588 aSourceArea.aEnd.SetRow( aSourceArea.aStart.Row() );
4589 break;
4590 case FILL_TO_RIGHT:
4591 nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
4592 aSourceArea.aEnd.SetCol( aSourceArea.aStart.Col() );
4593 break;
4594 case FILL_TO_TOP:
4595 nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
4596 aSourceArea.aStart.SetRow( aSourceArea.aEnd.Row() );
4597 break;
4598 case FILL_TO_LEFT:
4599 nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
4600 aSourceArea.aStart.SetCol( aSourceArea.aEnd.Col() );
4601 break;
4602 }
4603
4604 ScDocumentUniquePtr pUndoDoc;
4605 if ( bRecord )
4606 {
4607 SCTAB nTabCount = rDoc.GetTableCount();
4608 SCTAB nDestStartTab = aDestArea.aStart.Tab();
4609
4610 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
4611 pUndoDoc->InitUndo( rDoc, nDestStartTab, nDestStartTab );
4612 for (const auto& rTab : aMark)
4613 {
4614 if (rTab >= nTabCount)
4615 break;
4616
4617 if (rTab != nDestStartTab)
4618 pUndoDoc->AddUndoTab( rTab, rTab );
4619 }
4620
4621 ScRange aCopyRange = aDestArea;
4622 aCopyRange.aStart.SetTab(0);
4623 aCopyRange.aEnd.SetTab(nTabCount-1);
4624 rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::AUTOFILL, false, *pUndoDoc, &aMark );
4625 }
4626
4627 sal_uLong nProgCount;
4628 if (eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP)
4629 nProgCount = aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1;
4630 else
4631 nProgCount = aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1;
4632 nProgCount *= nCount;
4633 ScProgress aProgress( rDoc.GetDocumentShell(),
4634 ScResId(STR_FILL_SERIES_PROGRESS), nProgCount, true );
4635
4636 rDoc.Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4637 aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), &aProgress,
4638 aMark, nCount, eDir, FILL_SIMPLE );
4639 AdjustRowHeight(aRange, true, bApi);
4640
4641 if ( bRecord ) // only now is Draw-Undo available
4642 {
4644 std::make_unique<ScUndoAutoFill>( &rDocShell, aDestArea, aSourceArea, std::move(pUndoDoc), aMark,
4645 eDir, FILL_SIMPLE, FILL_DAY, MAXDOUBLE, 1.0, 1e307) );
4646 }
4647
4649 aModificator.SetDocumentModified();
4650
4651 bSuccess = true;
4652 }
4653 else if (!bApi)
4655
4656 return bSuccess;
4657}
4658
4659bool ScDocFunc::FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
4660 FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
4661 double fStart, double fStep, double fMax,
4662 bool bApi )
4663{
4664 ScDocShellModificator aModificator( rDocShell );
4665
4666 bool bSuccess = false;
4668 SCCOL nStartCol = rRange.aStart.Col();
4669 SCROW nStartRow = rRange.aStart.Row();
4670 SCTAB nStartTab = rRange.aStart.Tab();
4671 SCCOL nEndCol = rRange.aEnd.Col();
4672 SCROW nEndRow = rRange.aEnd.Row();
4673 SCTAB nEndTab = rRange.aEnd.Tab();
4674
4675 bool bRecord = true;
4676 if (!rDoc.IsUndoEnabled())
4677 bRecord = false;
4678
4679 ScMarkData aMark(rDoc.GetSheetLimits());
4680 if (pTabMark)
4681 aMark = *pTabMark;
4682 else
4683 {
4684 for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4685 aMark.SelectTable( nTab, true );
4686 }
4687
4688 ScEditableTester aTester( rDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
4689 if ( aTester.IsEditable() )
4690 {
4692
4693 ScRange aSourceArea = rRange;
4694 ScRange aDestArea = rRange;
4695
4697 aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), aSourceArea.aStart.Tab(),
4698 aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aSourceArea.aEnd.Tab(),
4699 DirFromFillDir(eDir) );
4700
4701 // keep at least one row/column as source range
4702 SCSIZE nTotLines = ( eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP ) ?
4703 static_cast<SCSIZE>( aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1 ) :
4704 static_cast<SCSIZE>( aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1 );
4705 if ( nCount >= nTotLines )
4706 nCount = nTotLines - 1;
4707
4708 switch (eDir)
4709 {
4710 case FILL_TO_BOTTOM:
4711 aSourceArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() - nCount ) );
4712 break;
4713 case FILL_TO_RIGHT:
4714 aSourceArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() - nCount ) );
4715 break;
4716 case FILL_TO_TOP:
4717 aSourceArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() + nCount ) );
4718 break;
4719 case FILL_TO_LEFT:
4720 aSourceArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() + nCount ) );
4721 break;
4722 }
4723
4724 ScDocumentUniquePtr pUndoDoc;
4725 if ( bRecord )
4726 {
4727 SCTAB nTabCount = rDoc.GetTableCount();
4728 SCTAB nDestStartTab = aDestArea.aStart.Tab();
4729
4730 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
4731 pUndoDoc->InitUndo( rDoc, nDestStartTab, nDestStartTab );
4732 for (const auto& rTab : aMark)
4733 {
4734 if (rTab >= nTabCount)
4735 break;
4736
4737 if (rTab != nDestStartTab)
4738 pUndoDoc->AddUndoTab( rTab, rTab );
4739 }
4740
4741 rDoc.CopyToDocument(
4742 aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
4743 aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
4744 InsertDeleteFlags::AUTOFILL, false, *pUndoDoc, &aMark );
4745 }
4746
4747 if (aDestArea.aStart.Col() <= aDestArea.aEnd.Col() &&
4748 aDestArea.aStart.Row() <= aDestArea.aEnd.Row())
4749 {
4750 if ( fStart != MAXDOUBLE )
4751 {
4752 SCCOL nValX = (eDir == FILL_TO_LEFT) ? aDestArea.aEnd.Col() : aDestArea.aStart.Col();
4753 SCROW nValY = (eDir == FILL_TO_TOP ) ? aDestArea.aEnd.Row() : aDestArea.aStart.Row();
4754 SCTAB nTab = aDestArea.aStart.Tab();
4755 rDoc.SetValue( nValX, nValY, nTab, fStart );
4756 }
4757
4758 sal_uLong nProgCount;
4759 if (eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP)
4760 nProgCount = aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1;
4761 else
4762 nProgCount = aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1;
4763 nProgCount *= nCount;
4764 ScProgress aProgress( rDoc.GetDocumentShell(),
4765 ScResId(STR_FILL_SERIES_PROGRESS), nProgCount, true );
4766
4767 rDoc.Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4768 aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), &aProgress,
4769 aMark, nCount, eDir, eCmd, eDateCmd, fStep, fMax );
4770 AdjustRowHeight(rRange, true, bApi);
4771
4773 aModificator.SetDocumentModified();
4774 }
4775
4776 if ( bRecord ) // only now is Draw-Undo available
4777 {
4779 std::make_unique<ScUndoAutoFill>( &rDocShell, aDestArea, aSourceArea, std::move(pUndoDoc), aMark,
4780 eDir, eCmd, eDateCmd, fStart, fStep, fMax) );
4781 }
4782
4783 bSuccess = true;
4784 }
4785 else if (!bApi)
4787
4788 return bSuccess;
4789}
4790
4791bool ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
4792 FillDir eDir, sal_uLong nCount, bool bApi )
4793{
4794 return FillAuto( rRange, pTabMark, eDir, FILL_AUTO, FILL_DAY, nCount, 1.0/*fStep*/, MAXDOUBLE/*fMax*/, true/*bRecord*/, bApi );
4795}
4796
4797bool ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark, FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd, sal_uLong nCount, double fStep, double fMax, bool bRecord, bool bApi )
4798{
4799 ScDocShellModificator aModificator( rDocShell );
4800
4802 SCCOL nStartCol = rRange.aStart.Col();
4803 SCROW nStartRow = rRange.aStart.Row();
4804 SCTAB nStartTab = rRange.aStart.Tab();
4805 SCCOL nEndCol = rRange.aEnd.Col();
4806 SCROW nEndRow = rRange.aEnd.Row();
4807 SCTAB nEndTab = rRange.aEnd.Tab();
4808
4809 if (bRecord && !rDoc.IsUndoEnabled())
4810 bRecord = false;
4811
4812 ScMarkData aMark(rDoc.GetSheetLimits());
4813 if (pTabMark)
4814 aMark = *pTabMark;
4815 else
4816 {
4817 for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4818 aMark.SelectTable( nTab, true );
4819 }
4820
4821 ScRange aSourceArea = rRange;
4822 ScRange aDestArea = rRange;
4823
4824 switch (eDir)
4825 {
4826 case FILL_TO_BOTTOM:
4827 aDestArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() + nCount ) );
4828 break;
4829 case FILL_TO_TOP:
4830 if (nCount > sal::static_int_cast<sal_uLong>( aSourceArea.aStart.Row() ))
4831 {
4832 OSL_FAIL("FillAuto: Row < 0");
4833 nCount = aSourceArea.aStart.Row();
4834 }
4835 aDestArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() - nCount ) );
4836 break;
4837 case FILL_TO_RIGHT:
4838 aDestArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() + nCount ) );
4839 break;
4840 case FILL_TO_LEFT:
4841 if (nCount > sal::static_int_cast<sal_uLong>( aSourceArea.aStart.Col() ))
4842 {
4843 OSL_FAIL("FillAuto: Col < 0");
4844 nCount = aSourceArea.aStart.Col();
4845 }
4846 aDestArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() - nCount ) );
4847 break;
4848 default:
4849 OSL_FAIL("Wrong direction with FillAuto");
4850 break;
4851 }
4852
4853 // Test for cell protection
4856
4857 ScEditableTester aTester( rDoc, aDestArea );
4858 if ( !aTester.IsEditable() )
4859 {
4860 if (!bApi)
4862 return false;
4863 }
4864
4865 if ( rDoc.HasSelectedBlockMatrixFragment( nStartCol, nStartRow,
4866 nEndCol, nEndRow, aMark ) )
4867 {
4868 if (!bApi)
4869 rDocShell.ErrorMessage(STR_MATRIXFRAGMENTERR);
4870 return false;
4871 }
4872
4873 // FID_FILL_... slots should already had been disabled, check here for API
4874 // calls, no message.
4875 if (ScViewData::SelectionFillDOOM( aDestArea))
4876 return false;
4877
4879
4880 ScDocumentUniquePtr pUndoDoc;
4881 if ( bRecord )
4882 {
4883 SCTAB nTabCount = rDoc.GetTableCount();
4884 SCTAB nDestStartTab = aDestArea.aStart.Tab();
4885
4886 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
4887 pUndoDoc->InitUndo( rDoc, nDestStartTab, nDestStartTab );
4888 for (const auto& rTab : aMark)
4889 {
4890 if (rTab >= nTabCount)
4891 break;
4892
4893 if (rTab != nDestStartTab)
4894 pUndoDoc->AddUndoTab( rTab, rTab );
4895 }
4896
4897 // do not clone note captions in undo document
4898 rDoc.CopyToDocument(
4899 aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
4900 aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
4901 InsertDeleteFlags::AUTOFILL, false, *pUndoDoc, &aMark );
4902 }
4903
4904 sal_uLong nProgCount;
4905 if (eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP)
4906 nProgCount = aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1;
4907 else
4908 nProgCount = aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1;
4909 nProgCount *= nCount;
4910 ScProgress aProgress( rDoc.GetDocumentShell(),
4911 ScResId(STR_FILL_SERIES_PROGRESS), nProgCount, true );
4912
4913 rDoc.Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4914 aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), &aProgress,
4915 aMark, nCount, eDir, eCmd, eDateCmd, fStep, fMax );
4916
4917 AdjustRowHeight(aDestArea, true, bApi);
4918
4919 if ( bRecord ) // only now is Draw-Undo available
4920 {
4922 std::make_unique<ScUndoAutoFill>( &rDocShell, aDestArea, aSourceArea, std::move(pUndoDoc), aMark,
4923 eDir, eCmd, eDateCmd, MAXDOUBLE, fStep, fMax) );
4924 }
4925
4927 aModificator.SetDocumentModified();
4928
4929 rRange = aDestArea; // return destination range (for marking)
4930 return true;
4931}
4932
4933bool ScDocFunc::MergeCells( const ScCellMergeOption& rOption, bool bContents, bool bRecord, bool bApi, bool bEmptyMergedCells /*=false*/ )
4934{
4935 using ::std::set;
4936
4937 ScDocShellModificator aModificator( rDocShell );
4938
4939 SCCOL nStartCol = rOption.mnStartCol;
4940 SCROW nStartRow = rOption.mnStartRow;
4941 SCCOL nEndCol = rOption.mnEndCol;
4942 SCROW nEndRow = rOption.mnEndRow;
4943 if ((nStartCol == nEndCol && nStartRow == nEndRow) || rOption.maTabs.empty())
4944 {
4945 // Nothing to do. Bail out quickly
4946 return true;
4947 }
4948
4950 SCTAB nTab1 = *rOption.maTabs.begin(), nTab2 = *rOption.maTabs.rbegin();
4951
4952 if (bRecord && !rDoc.IsUndoEnabled())
4953 bRecord = false;
4954
4955 for (const auto& rTab : rOption.maTabs)
4956 {
4957 ScEditableTester aTester( rDoc, rTab, nStartCol, nStartRow, nEndCol, nEndRow );
4958 if (!aTester.IsEditable())
4959 {
4960 if (!bApi)
4962 return false;
4963 }
4964
4965 if ( rDoc.HasAttrib( nStartCol, nStartRow, rTab, nEndCol, nEndRow, rTab,
4967 {
4968 // "Merge of already merged cells not possible"
4969 if (!bApi)
4970 rDocShell.ErrorMessage(STR_MSSG_MERGECELLS_0);
4971 return false;
4972 }
4973 }
4974
4975 ScDocumentUniquePtr pUndoDoc;
4976 bool bNeedContentsUndo = false;
4977 for (const SCTAB nTab : rOption.maTabs)
4978 {
4979 bool bIsBlockEmpty = ( nStartRow == nEndRow )
4980 ? rDoc.IsEmptyData( nStartCol+1,nStartRow, nEndCol,nEndRow, nTab )
4981 : rDoc.IsEmptyData( nStartCol,nStartRow+1, nStartCol,nEndRow, nTab ) &&
4982 rDoc.IsEmptyData( nStartCol+1,nStartRow, nEndCol,nEndRow, nTab );
4983 bool bNeedContents = bContents && !bIsBlockEmpty;
4984 bool bNeedEmpty = bEmptyMergedCells && !bIsBlockEmpty && !bNeedContents; // if DoMergeContents then cells are emptied
4985
4986 if (bRecord)
4987 {
4988 // test if the range contains other notes which also implies that we need an undo document
4989 bool bHasNotes = rDoc.HasNote(nTab, nStartCol, nStartRow, nEndCol, nEndRow);
4990 if (!pUndoDoc)
4991 {
4992 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
4993 pUndoDoc->InitUndo(rDoc, nTab1, nTab2);
4994 }
4995 // note captions are collected by drawing undo
4996 rDoc.CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
4998 if( bHasNotes )
4999 rDoc.BeginDrawUndo();
5000 }
5001
5002 if (bNeedContents)
5003 rDoc.DoMergeContents( nStartCol,nStartRow, nEndCol,nEndRow, nTab );
5004 else if ( bNeedEmpty )
5005 rDoc.DoEmptyBlock( nStartCol,nStartRow, nEndCol,nEndRow, nTab );
5006 rDoc.DoMerge( nStartCol,nStartRow, nEndCol,nEndRow, nTab );
5007
5008 if (rOption.mbCenter)
5009 {
5010 rDoc.ApplyAttr( nStartCol, nStartRow, nTab, SvxHorJustifyItem( SvxCellHorJustify::Center, ATTR_HOR_JUSTIFY ) );
5011 rDoc.ApplyAttr( nStartCol, nStartRow, nTab, SvxVerJustifyItem( SvxCellVerJustify::Center, ATTR_VER_JUSTIFY ) );
5012 }
5013
5014 if ( !AdjustRowHeight( ScRange( 0,nStartRow,nTab, rDoc.MaxCol(),nEndRow,nTab ), true, bApi ) )
5015 rDocShell.PostPaint( nStartCol, nStartRow, nTab,
5016 nEndCol, nEndRow, nTab, PaintPartFlags::Grid );
5017 if (bNeedContents || rOption.mbCenter)
5018 {
5019 ScRange aRange(nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab);
5020 rDoc.SetDirty(aRange, true);
5021 }
5022
5023 bool bDone = ScDetectiveFunc(rDoc, nTab).DeleteAll( ScDetectiveDelete::Circles );
5024 if(bDone)
5026
5027 bNeedContentsUndo |= bNeedContents;
5028 }
5029
5030 if (pUndoDoc)
5031 {
5032 std::unique_ptr<SdrUndoGroup> pDrawUndo = rDoc.GetDrawLayer() ? rDoc.GetDrawLayer()->GetCalcUndo() : nullptr;
5034 std::make_unique<ScUndoMerge>(&rDocShell, rOption, bNeedContentsUndo, std::move(pUndoDoc), std::move(pDrawUndo)) );
5035 }
5036
5037 aModificator.SetDocumentModified();
5038
5039 SfxBindings* pBindings = rDocShell.GetViewBindings();
5040 if (pBindings)
5041 {
5042 pBindings->Invalidate( FID_MERGE_ON );
5043 pBindings->Invalidate( FID_MERGE_OFF );
5044 pBindings->Invalidate( FID_MERGE_TOGGLE );
5045 }
5046
5047 return true;
5048}
5049
5050bool ScDocFunc::UnmergeCells( const ScRange& rRange, bool bRecord, ScUndoRemoveMerge* pUndoRemoveMerge )
5051{
5052 ScCellMergeOption aOption(rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
5053 SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = rRange.aEnd.Tab();
5054 for (SCTAB i = nTab1; i <= nTab2; ++i)
5055 aOption.maTabs.insert(i);
5056
5057 return UnmergeCells(aOption, bRecord, pUndoRemoveMerge);
5058}
5059
5060bool ScDocFunc::UnmergeCells( const ScCellMergeOption& rOption, bool bRecord, ScUndoRemoveMerge* pUndoRemoveMerge )
5061{
5062 using ::std::set;
5063
5064 if (rOption.maTabs.empty())
5065 // Nothing to unmerge.
5066 return true;
5067
5068 ScDocShellModificator aModificator( rDocShell );
5070
5071 if (bRecord && !rDoc.IsUndoEnabled())
5072 bRecord = false;
5073
5074 ScDocument* pUndoDoc = (pUndoRemoveMerge ? pUndoRemoveMerge->GetUndoDoc() : nullptr);
5075 assert( pUndoDoc || !pUndoRemoveMerge );
5076 for (const SCTAB nTab : rOption.maTabs)
5077 {
5078 ScRange aRange = rOption.getSingleRange(nTab);
5079 if ( !rDoc.HasAttrib(aRange, HasAttrFlags::Merged) )
5080 continue;
5081
5082 ScRange aExtended = aRange;
5083 rDoc.ExtendMerge(aExtended);
5084 ScRange aRefresh = aExtended;
5085 rDoc.ExtendOverlapped(aRefresh);
5086
5087 if (bRecord)
5088 {
5089 if (!pUndoDoc)
5090 {
5091 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
5092 pUndoDoc->InitUndo(rDoc, *rOption.maTabs.begin(), *rOption.maTabs.rbegin());
5093 }
5094 rDoc.CopyToDocument(aExtended, InsertDeleteFlags::ATTRIB, false, *pUndoDoc);
5095 }
5096
5097 const SfxPoolItem& rDefAttr = rDoc.GetPool()->GetDefaultItem( ATTR_MERGE );
5098 ScPatternAttr aPattern( rDoc.GetPool() );
5099 aPattern.GetItemSet().Put( rDefAttr );
5100 rDoc.ApplyPatternAreaTab( aRange.aStart.Col(), aRange.aStart.Row(),
5101 aRange.aEnd.Col(), aRange.aEnd.Row(), nTab,
5102 aPattern );
5103
5104 rDoc.RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
5105 aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
5106 ScMF::Hor | ScMF::Ver );
5107
5108 rDoc.ExtendMerge( aRefresh, true );
5109
5110 if ( !AdjustRowHeight( aExtended, true, true ) )
5112
5113 bool bDone = ScDetectiveFunc(rDoc, nTab).DeleteAll( ScDetectiveDelete::Circles );
5114 if(bDone)
5116 }
5117
5118 if (bRecord)
5119 {
5120 if (pUndoRemoveMerge)
5121 {
5122 // If pUndoRemoveMerge was passed, the caller is responsible for
5123 // adding it to Undo. Just add the current option.
5124 pUndoRemoveMerge->AddCellMergeOption( rOption);
5125 }
5126 else
5127 {
5129 std::make_unique<ScUndoRemoveMerge>( &rDocShell, rOption, ScDocumentUniquePtr(pUndoDoc) ) );
5130 }
5131 }
5132 aModificator.SetDocumentModified();
5133
5134 return true;
5135}
5136
5137void ScDocFunc::ModifyRangeNames( const ScRangeName& rNewRanges, SCTAB nTab )
5138{
5139 SetNewRangeNames( std::unique_ptr<ScRangeName>(new ScRangeName(rNewRanges)), true, nTab );
5140}
5141
5142void ScDocFunc::SetNewRangeNames( std::unique_ptr<ScRangeName> pNewRanges, bool bModifyDoc, SCTAB nTab ) // takes ownership of pNewRanges
5143{
5144 ScDocShellModificator aModificator( rDocShell );
5145
5146 OSL_ENSURE( pNewRanges, "pNewRanges is 0" );
5148 bool bUndo(rDoc.IsUndoEnabled());
5149
5150 if (bUndo)
5151 {
5152 ScRangeName* pOld;
5153 if (nTab >=0)
5154 {
5155 pOld = rDoc.GetRangeName(nTab);
5156 }
5157 else
5158 {
5159 pOld = rDoc.GetRangeName();
5160 }
5161 std::unique_ptr<ScRangeName> pUndoRanges(new ScRangeName(*pOld));
5162 std::unique_ptr<ScRangeName> pRedoRanges(new ScRangeName(*pNewRanges));
5164 std::make_unique<ScUndoRangeNames>( &rDocShell, std::move(pUndoRanges), std::move(pRedoRanges), nTab ) );
5165 }
5166
5167 // #i55926# While loading XML, formula cells only have a single string token,
5168 // so CompileNameFormula would never find any name (index) tokens, and would
5169 // unnecessarily loop through all cells.
5170 bool bCompile = ( !rDoc.IsImportingXML() && rDoc.GetNamedRangesLockCount() == 0 );
5171
5172 if ( bCompile )
5174 if (nTab >= 0)
5175 rDoc.SetRangeName( nTab, std::move(pNewRanges) ); // takes ownership
5176 else
5177 rDoc.SetRangeName( std::move(pNewRanges) ); // takes ownership
5178 if ( bCompile )
5179 rDoc.CompileHybridFormula();
5180
5181 if (bModifyDoc)
5182 {
5183 aModificator.SetDocumentModified();
5184 SfxGetpApp()->Broadcast( SfxHint(SfxHintId::ScAreasChanged) );
5185 }
5186}
5187
5188void ScDocFunc::ModifyAllRangeNames(const std::map<OUString, ScRangeName>& rRangeMap)
5189{
5190 ScDocShellModificator aModificator(rDocShell);
5192
5193 if (rDoc.IsUndoEnabled())
5194 {
5195 std::map<OUString, ScRangeName*> aOldRangeMap;
5196 rDoc.GetRangeNameMap(aOldRangeMap);
5198 std::make_unique<ScUndoAllRangeNames>(&rDocShell, aOldRangeMap, rRangeMap));
5199 }
5200
5201 rDoc.PreprocessAllRangeNamesUpdate(rRangeMap);
5202 rDoc.SetAllRangeNames(rRangeMap);
5203 rDoc.CompileHybridFormula();
5204
5205 aModificator.SetDocumentModified();
5206 SfxGetpApp()->Broadcast(SfxHint(SfxHintId::ScAreasChanged));
5207}
5208
5210 SCCOL nPosX, SCROW nPosY, SCTAB nTab,
5211 SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
5212 bool& rCancel, bool bApi )
5213{
5214 if (rCancel)
5215 return;
5216
5218 if (rDoc.HasValueData( nPosX, nPosY, nTab ))
5219 return;
5220
5221 OUString aName = rDoc.GetString(nPosX, nPosY, nTab);
5223 if (aName.isEmpty())
5224 return;
5225
5226 OUString aContent( ScRange( nX1, nY1, nTab, nX2, nY2, nTab ).Format(
5228
5229 bool bInsert = false;
5230 ScRangeData* pOld = rList.findByUpperName(ScGlobal::getCharClass().uppercase(aName));
5231 if (pOld)
5232 {
5233 OUString aOldStr = pOld->GetSymbol();
5234 if (aOldStr != aContent)
5235 {
5236 if (bApi)
5237 bInsert = true; // don't check via API
5238 else
5239 {
5240 OUString aTemplate = ScResId( STR_CREATENAME_REPLACE );
5241 OUString aMessage = o3tl::getToken(aTemplate, 0, '#' ) + aName + o3tl::getToken(aTemplate, 1, '#' );
5242
5243 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
5244 VclMessageType::Question, VclButtonsType::YesNo,
5245 aMessage));
5246 xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
5247 xQueryBox->set_default_response(RET_YES);
5248
5249 short nResult = xQueryBox->run();
5250 if ( nResult == RET_YES )
5251 {
5252 rList.erase(*pOld);
5253 bInsert = true;
5254 }
5255 else if ( nResult == RET_CANCEL )
5256 rCancel = true;
5257 }
5258 }
5259 }
5260 else
5261 bInsert = true;
5262
5263 if (bInsert)
5264 {
5265 ScRangeData* pData = new ScRangeData( rDoc, aName, aContent,
5266 ScAddress( nPosX, nPosY, nTab));
5267 if (!rList.insert(pData))
5268 {
5269 OSL_FAIL("nanu?");
5270 }
5271 }
5272}
5273
5274bool ScDocFunc::CreateNames( const ScRange& rRange, CreateNameFlags nFlags, bool bApi, SCTAB aTab )
5275{
5276 if (nFlags == CreateNameFlags::NONE)
5277 return false; // was nothing
5278
5279 ScDocShellModificator aModificator( rDocShell );
5280
5281 bool bDone = false;
5282 SCCOL nStartCol = rRange.aStart.Col();
5283 SCROW nStartRow = rRange.aStart.Row();
5284 SCCOL nEndCol = rRange.aEnd.Col();
5285 SCROW nEndRow = rRange.aEnd.Row();
5286 SCTAB nTab = rRange.aStart.Tab();
5287 OSL_ENSURE(rRange.aEnd.Tab() == nTab, "CreateNames: multiple tables not possible");
5288
5289 bool bValid = true;
5290 if ( nFlags & ( CreateNameFlags::Top | CreateNameFlags::Bottom ) )
5291 if ( nStartRow == nEndRow )
5292 bValid = false;
5293 if ( nFlags & ( CreateNameFlags::Left | CreateNameFlags::Right ) )
5294 if ( nStartCol == nEndCol )
5295 bValid = false;
5296
5297 if (bValid)
5298 {
5300 ScRangeName* pNames;
5301 if (aTab >=0)
5302 pNames = rDoc.GetRangeName(nTab);
5303 else
5304 pNames = rDoc.GetRangeName();
5305
5306 if (!pNames)
5307 return false; // shouldn't happen
5308 ScRangeName aNewRanges( *pNames );
5309
5310 bool bTop ( nFlags & CreateNameFlags::Top );
5311 bool bLeft ( nFlags & CreateNameFlags::Left );
5312 bool bBottom( nFlags & CreateNameFlags::Bottom );
5313 bool bRight ( nFlags & CreateNameFlags::Right );
5314
5315 SCCOL nContX1 = nStartCol;
5316 SCROW nContY1 = nStartRow;
5317 SCCOL nContX2 = nEndCol;
5318 SCROW nContY2 = nEndRow;
5319
5320 if ( bTop )
5321 ++nContY1;
5322 if ( bLeft )
5323 ++nContX1;
5324 if ( bBottom )
5325 --nContY2;
5326 if ( bRight )
5327 --nContX2;
5328
5329 bool bCancel = false;
5330 SCCOL i;
5331 SCROW j;
5332
5333 if ( bTop )
5334 for (i=nContX1; i<=nContX2; i++)
5335 CreateOneName( aNewRanges, i,nStartRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
5336 if ( bLeft )
5337 for (j=nContY1; j<=nContY2; j++)
5338 CreateOneName( aNewRanges, nStartCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
5339 if ( bBottom )
5340 for (i=nContX1; i<=nContX2; i++)
5341 CreateOneName( aNewRanges, i,nEndRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
5342 if ( bRight )
5343 for (j=nContY1; j<=nContY2; j++)
5344 CreateOneName( aNewRanges, nEndCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
5345
5346 if ( bTop && bLeft )
5347 CreateOneName( aNewRanges, nStartCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
5348 if ( bTop && bRight )
5349 CreateOneName( aNewRanges, nEndCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
5350 if ( bBottom && bLeft )
5351 CreateOneName( aNewRanges, nStartCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
5352 if ( bBottom && bRight )
5353 CreateOneName( aNewRanges, nEndCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
5354
5355 ModifyRangeNames( aNewRanges, aTab );
5356 bDone = true;
5357
5358 }
5359
5360 return bDone;
5361}
5362
5363bool ScDocFunc::InsertNameList( const ScAddress& rStartPos, bool bApi )
5364{
5365 ScDocShellModificator aModificator( rDocShell );
5366
5367 bool bDone = false;
5369 const bool bRecord = rDoc.IsUndoEnabled();
5370 SCTAB nTab = rStartPos.Tab();
5371
5372 //local names have higher priority than global names
5373 ScRangeName* pLocalList = rDoc.GetRangeName(nTab);
5374 sal_uInt16 nValidCount = 0;
5375 for (const auto& rEntry : *pLocalList)
5376 {
5377 const ScRangeData& r = *rEntry.second;
5379 ++nValidCount;
5380 }
5381 ScRangeName* pList = rDoc.GetRangeName();
5382 for (const auto& rEntry : *pList)
5383 {
5384 const ScRangeData& r = *rEntry.second;
5386 ++nValidCount;
5387 }
5388
5389 if (nValidCount)
5390 {
5391 SCCOL nStartCol = rStartPos.Col();
5392 SCROW nStartRow = rStartPos.Row();
5393 SCCOL nEndCol = nStartCol + 1;
5394 SCROW nEndRow = nStartRow + static_cast<SCROW>(nValidCount) - 1;
5395
5396 ScEditableTester aTester( rDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
5397 if (aTester.IsEditable())
5398 {
5399 ScDocumentUniquePtr pUndoDoc;
5400
5401 if (bRecord)
5402 {
5403 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
5404 pUndoDoc->InitUndo( rDoc, nTab, nTab );
5405 rDoc.CopyToDocument(nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
5406 InsertDeleteFlags::ALL, false, *pUndoDoc);
5407
5408 rDoc.BeginDrawUndo(); // because of adjusting heights
5409 }
5410
5411 std::unique_ptr<ScRangeData*[]> ppSortArray(new ScRangeData* [ nValidCount ]);
5412 sal_uInt16 j = 0;
5413 for (const auto& rEntry : *pLocalList)
5414 {
5415 ScRangeData& r = *rEntry.second;
5417 ppSortArray[j++] = &r;
5418 }
5419 for (const auto& [rName, rxData] : *pList)
5420 {
5421 ScRangeData& r = *rxData;
5422 if (!r.HasType(ScRangeData::Type::Database) && !pLocalList->findByUpperName(rName))
5423 ppSortArray[j++] = &r;
5424 }
5425 qsort( static_cast<void*>(ppSortArray.get()), nValidCount, sizeof(ScRangeData*),
5427 OUString aName;
5428 OUStringBuffer aContent;
5429 OUString aFormula;
5430 SCROW nOutRow = nStartRow;
5431 for (j=0; j<nValidCount; j++)
5432 {
5433 ScRangeData* pData = ppSortArray[j];
5434 pData->GetName(aName);
5435 // adjust relative references to the left column in Excel-compliant way:
5436 pData->UpdateSymbol(aContent, ScAddress( nStartCol, nOutRow, nTab ));
5437 aFormula = "=" + aContent;
5438 ScSetStringParam aParam;
5439 aParam.setTextInput();
5440 rDoc.SetString(ScAddress(nStartCol,nOutRow,nTab), aName, &aParam);
5441 rDoc.SetString(ScAddress(nEndCol,nOutRow,nTab), aFormula, &aParam);
5442 ++nOutRow;
5443 }
5444
5445 ppSortArray.reset();
5446
5447 if (bRecord)
5448 {
5450 pRedoDoc->InitUndo( rDoc, nTab, nTab );
5451 rDoc.CopyToDocument(nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
5452 InsertDeleteFlags::ALL, false, *pRedoDoc);
5453
5455 std::make_unique<ScUndoListNames>( &rDocShell,
5456 ScRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab ),
5457 std::move(pUndoDoc), std::move(pRedoDoc) ) );
5458 }
5459
5460 if (!AdjustRowHeight(ScRange(0,nStartRow,nTab,rDoc.MaxCol(),nEndRow,nTab), true, true))
5461 rDocShell.PostPaint( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, PaintPartFlags::Grid );
5462
5463 aModificator.SetDocumentModified();
5464 bDone = true;
5465 }
5466 else if (!bApi)
5467 rDocShell.ErrorMessage(aTester.GetMessageId());
5468 }
5469 return bDone;
5470}
5471
5472void ScDocFunc::ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd )
5473{
5475 SCCOL nStartCol = rOldRange.aStart.Col();
5476 SCROW nStartRow = rOldRange.aStart.Row();
5477 SCTAB nTab = rOldRange.aStart.Tab();
5478
5479 OUString aFormula = rDoc.GetFormula( nStartCol, nStartRow, nTab );
5480 if ( !(aFormula.startsWith("{") && aFormula.endsWith("}")) )
5481 return;
5482
5483 OUString aUndo = ScResId( STR_UNDO_RESIZEMATRIX );
5484 bool bUndo(rDoc.IsUndoEnabled());
5485 if (bUndo)
5486 {
5487 ViewShellId nViewShellId(1);
5489 nViewShellId = pViewSh->GetViewShellId();
5490 rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo, 0, nViewShellId );
5491 }
5492
5493 aFormula = aFormula.copy(1, aFormula.getLength()-2);
5494
5495 ScMarkData aMark(rDoc.GetSheetLimits());
5496 aMark.SetMarkArea( rOldRange );
5497 aMark.SelectTable( nTab, true );
5498 ScRange aNewRange( rOldRange.aStart, rNewEnd );
5499
5500 if ( DeleteContents( aMark, InsertDeleteFlags::CONTENTS, true, false/*bApi*/ ) )
5501 {
5502 // GRAM_API for API compatibility.
5503 if (!EnterMatrix( aNewRange, &aMark, nullptr, aFormula, false/*bApi*/, false, OUString(), formula::FormulaGrammar::GRAM_API ))
5504 {
5505 // try to restore the previous state
5506 EnterMatrix( rOldRange, &aMark, nullptr, aFormula, false/*bApi*/, false, OUString(), formula::FormulaGrammar::GRAM_API );
5507 }
5508 }
5509
5510 if (bUndo)
5512}
5513
5514void ScDocFunc::InsertAreaLink( const OUString& rFile, const OUString& rFilter,
5515 const OUString& rOptions, const OUString& rSource,
5516 const ScRange& rDestRange, sal_Int32 nRefreshDelaySeconds,
5517 bool bFitBlock, bool bApi )
5518{
5520 bool bUndo (rDoc.IsUndoEnabled());
5521
5522 sfx2::LinkManager* pLinkManager = rDoc.GetLinkManager();
5523
5524 // #i52120# if other area links exist at the same start position,
5525 // remove them first (file format specifies only one link definition
5526 // for a cell)
5527
5528 sal_uInt16 nLinkCount = pLinkManager->GetLinks().size();
5529 sal_uInt16 nRemoved = 0;
5530 sal_uInt16 nLinkPos = 0;
5531 while (nLinkPos<nLinkCount)
5532 {
5533 ::sfx2::SvBaseLink* pBase = pLinkManager->GetLinks()[nLinkPos].get();
5534 ScAreaLink* pLink = dynamic_cast<ScAreaLink*>(pBase);
5535 if (pLink && pLink->GetDestArea().aStart == rDestRange.aStart)
5536 {
5537 if ( bUndo )
5538 {
5539 if ( !nRemoved )
5540 {
5541 // group all remove and the insert action
5542 OUString aUndo = ScResId( STR_UNDO_INSERTAREALINK );
5543 ViewShellId nViewShellId(-1);
5545 nViewShellId = pViewSh->GetViewShellId();
5546 rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo, 0, nViewShellId );
5547 }
5548
5549 ScAreaLink* pOldArea = static_cast<ScAreaLink*>(pBase);
5551 std::make_unique<ScUndoRemoveAreaLink>( &rDocShell,
5552 pOldArea->GetFile(), pOldArea->GetFilter(), pOldArea->GetOptions(),
5553 pOldArea->GetSource(), pOldArea->GetDestArea(), pOldArea->GetRefreshDelaySeconds() ) );
5554 }
5555 pLinkManager->Remove( pBase );
5556 nLinkCount = pLinkManager->GetLinks().size();
5557 ++nRemoved;
5558 }
5559 else
5560 ++nLinkPos;
5561 }
5562
5563 OUString aFilterName = rFilter;
5564 OUString aNewOptions = rOptions;
5565 if (aFilterName.isEmpty())
5566 ScDocumentLoader::GetFilterName( rFile, aFilterName, aNewOptions, true, !bApi );
5567
5568 // remove application prefix from filter name here, so the filter options
5569 // aren't reset when the filter name is changed in ScAreaLink::DataChanged
5570 ScDocumentLoader::RemoveAppPrefix( aFilterName );
5571
5572 ScAreaLink* pLink = new ScAreaLink( &rDocShell, rFile, aFilterName,
5573 aNewOptions, rSource, rDestRange, nRefreshDelaySeconds );
5574 OUString aTmp = aFilterName;
5575 pLinkManager->InsertFileLink( *pLink, sfx2::SvBaseLinkObjectType::ClientFile, rFile, &aTmp, &rSource );
5576
5577 // Undo for an empty link
5578
5579 if (bUndo)
5580 {
5581 rDocShell.GetUndoManager()->AddUndoAction( std::make_unique<ScUndoInsertAreaLink>( &rDocShell,
5582 rFile, aFilterName, aNewOptions,
5583 rSource, rDestRange, nRefreshDelaySeconds ) );
5584 if ( nRemoved )
5585 rDocShell.GetUndoManager()->LeaveListAction(); // undo for link update is still separate
5586 }
5587
5588 // Update has its own undo
5589 if (rDoc.IsExecuteLinkEnabled())
5590 {
5591 pLink->SetDoInsert(bFitBlock); // if applicable, don't insert anything on first update
5592 pLink->Update(); // no SetInCreate -> carry out update
5593 }
5594 pLink->SetDoInsert(true); // Default = true
5595
5596 SfxBindings* pBindings = rDocShell.GetViewBindings();
5597 if (pBindings)
5598 pBindings->Invalidate( SID_LINKS );
5599
5600 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) ); // Navigator
5601}
5602
5603void ScDocFunc::ReplaceConditionalFormat( sal_uLong nOldFormat, std::unique_ptr<ScConditionalFormat> pFormat, SCTAB nTab, const ScRangeList& rRanges )
5604{
5605 ScDocShellModificator aModificator(rDocShell);
5607 if(rDoc.IsTabProtected(nTab))
5608 return;
5609
5610 bool bUndo = rDoc.IsUndoEnabled();
5611 ScDocumentUniquePtr pUndoDoc;
5612 ScRange aCombinedRange = rRanges.Combine();
5613 ScRange aCompleteRange;
5614 if(bUndo)
5615 {
5616 pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
5617 pUndoDoc->InitUndo( rDoc, nTab, nTab );
5618
5619 if(pFormat)
5620 {
5621 aCompleteRange = aCombinedRange;
5622 }
5623 if(nOldFormat)
5624 {
5625 ScConditionalFormat* pOldFormat = rDoc.GetCondFormList(nTab)->GetFormat(nOldFormat);
5626 if(pOldFormat)
5627 aCompleteRange.ExtendTo(pOldFormat->GetRange().Combine());
5628 }
5629
5630 rDoc.CopyToDocument(aCompleteRange.aStart.Col(),aCompleteRange.aStart.Row(),nTab,
5631 aCompleteRange.aEnd.Col(),aCompleteRange.aEnd.Row(),nTab,
5632 InsertDeleteFlags::ALL, false, *pUndoDoc);
5633 }
5634
5635 std::unique_ptr<ScRange> pRepaintRange;
5636 if(nOldFormat)
5637 {
5638 ScConditionalFormat* pOldFormat = rDoc.GetCondFormList(nTab)->GetFormat(nOldFormat);
5639 if(pOldFormat)
5640 {
5641 pRepaintRange.reset(new ScRange( pOldFormat->GetRange().Combine() ));
5642 rDoc.RemoveCondFormatData(pOldFormat->GetRange(), nTab, pOldFormat->GetKey());
5643 }
5644
5645 rDoc.DeleteConditionalFormat(nOldFormat, nTab);
5646 rDoc.SetStreamValid(nTab, false);
5647 }
5648 if(pFormat)
5649 {
5650 if(pRepaintRange)
5651 pRepaintRange->ExtendTo(aCombinedRange);
5652 else
5653 pRepaintRange.reset(new ScRange(aCombinedRange));
5654
5655 sal_uLong nIndex = rDoc.AddCondFormat(std::move(pFormat), nTab);
5656
5657 rDoc.AddCondFormatData(rRanges, nTab, nIndex);
5658 rDoc.SetStreamValid(nTab, false);
5659 }
5660
5661 if(bUndo)
5662 {
5664 pRedoDoc->InitUndo( rDoc, nTab, nTab );
5665 rDoc.CopyToDocument(aCompleteRange.aStart.Col(),aCompleteRange.aStart.Row(),nTab,
5666 aCompleteRange.aEnd.Col(),aCompleteRange.aEnd.Row(),nTab,
5667 InsertDeleteFlags::ALL, false, *pRedoDoc);
5669 std::make_unique<ScUndoConditionalFormat>(&rDocShell, std::move(pUndoDoc), std::move(pRedoDoc), aCompleteRange));
5670 }
5671
5672 if(pRepaintRange)
5674
5675 aModificator.SetDocumentModified();
5676 SfxGetpApp()->Broadcast(SfxHint(SfxHintId::ScAreasChanged));
5677}
5678
5680{
5681 ScDocShellModificator aModificator(rDocShell);
5683 if(rDoc.IsTabProtected(nTab))
5684 return;
5685
5686 bool bUndo = rDoc.IsUndoEnabled();
5687 ScDocumentUniquePtr pUndoDoc;
5688 if (bUndo)
5689 {
5690 pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
5691 pUndoDoc->InitUndo( rDoc, nTab, nTab );
5692
5693 ScConditionalFormatList* pOld = rDoc.GetCondFormList(nTab);
5694
5695 if (pOld)
5696 pUndoDoc->SetCondFormList(new ScConditionalFormatList(*pUndoDoc, *pOld), nTab);
5697 else
5698 pUndoDoc->SetCondFormList(nullptr, nTab);
5699
5700 }
5701
5702 // first remove all old entries
5703 ScConditionalFormatList* pOldList = rDoc.GetCondFormList(nTab);
5704 pOldList->RemoveFromDocument(rDoc);
5705
5706 // then set new entries
5707 pList->AddToDocument(rDoc);
5708
5709 rDoc.SetCondFormList(pList, nTab);
5711
5712 if(bUndo)
5713 {
5715 pRedoDoc->InitUndo( rDoc, nTab, nTab );
5716 pRedoDoc->SetCondFormList(new ScConditionalFormatList(*pRedoDoc, *pList), nTab);
5717
5719 std::make_unique<ScUndoConditionalFormatList>(&rDocShell, std::move(pUndoDoc), std::move(pRedoDoc), nTab));
5720 }
5721
5722 rDoc.SetStreamValid(nTab, false);
5723 aModificator.SetDocumentModified();
5724 SfxGetpApp()->Broadcast(SfxHint(SfxHintId::ScAreasChanged));
5725}
5726
5727void ScDocFunc::ConvertFormulaToValue( const ScRange& rRange, bool bInteraction )
5728{
5729 ScDocShellModificator aModificator(rDocShell);
5731 bool bRecord = true;
5732 if (!rDoc.IsUndoEnabled())
5733 bRecord = false;
5734
5735 ScEditableTester aTester(rDoc, rRange);
5736 if (!aTester.IsEditable())
5737 {
5738 if (bInteraction)
5740 return;
5741 }
5742
5743 sc::TableValues aUndoVals(rRange);
5744 sc::TableValues* pUndoVals = bRecord ? &aUndoVals : nullptr;
5745
5746 rDoc.ConvertFormulaToValue(rRange, pUndoVals);
5747
5748 if (bRecord && pUndoVals)
5749 {
5751 std::make_unique<sc::UndoFormulaToValue>(&rDocShell, *pUndoVals));
5752 }
5753
5756 rDoc.BroadcastCells(rRange, SfxHintId::ScDataChanged);
5757 aModificator.SetDocumentModified();
5758}
5759
5761{
5762 OUString aUndo(ScResId(pNameResId));
5763 ViewShellId nViewShellId(-1);
5765 nViewShellId = pViewSh->GetViewShellId();
5766 rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo, 0, nViewShellId );
5767}
5768
5770{
5772}
5773
5774bool ScDocFunc::InsertSparklines(ScRange const& rDataRange, ScRange const& rSparklineRange,
5775 std::shared_ptr<sc::SparklineGroup> pSparklineGroup)
5776{
5777 std::vector<sc::SparklineData> aSparklineDataVector;
5778
5779 if (rSparklineRange.aStart.Col() == rSparklineRange.aEnd.Col())
5780 {
5781 sal_Int32 nOutputRowSize = rSparklineRange.aEnd.Row() - rSparklineRange.aStart.Row();
5782
5783 auto eInputOrientation = sc::calculateOrientation(nOutputRowSize, rDataRange);
5784
5785 if (eInputOrientation == sc::RangeOrientation::Unknown)
5786 return false;
5787
5788 sal_Int32 nIndex = 0;
5789
5790 for (ScAddress aAddress = rSparklineRange.aStart; aAddress.Row() <= rSparklineRange.aEnd.Row();
5791 aAddress.IncRow())
5792 {
5793 ScRange aInputRangeSlice = rDataRange;
5794 if (eInputOrientation == sc::RangeOrientation::Row)
5795 {
5796 aInputRangeSlice.aStart.SetRow(rDataRange.aStart.Row() + nIndex);
5797 aInputRangeSlice.aEnd.SetRow(rDataRange.aStart.Row() + nIndex);
5798 }
5799 else
5800 {
5801 aInputRangeSlice.aStart.SetCol(rDataRange.aStart.Col() + nIndex);
5802 aInputRangeSlice.aEnd.SetCol(rDataRange.aStart.Col() + nIndex);
5803 }
5804
5805 aSparklineDataVector.emplace_back(aAddress, aInputRangeSlice);
5806
5807 nIndex++;
5808 }
5809 }
5810 else if (rSparklineRange.aStart.Row() == rSparklineRange.aEnd.Row())
5811 {
5812 sal_Int32 nOutputColSize = rSparklineRange.aEnd.Col() - rSparklineRange.aStart.Col();
5813
5814 auto eInputOrientation = sc::calculateOrientation(nOutputColSize, rDataRange);
5815
5816 if (eInputOrientation == sc::RangeOrientation::Unknown)
5817 return false;
5818
5819 sal_Int32 nIndex = 0;
5820
5821 for (ScAddress aAddress = rSparklineRange.aStart; aAddress.Col() <= rSparklineRange.aEnd.Col();
5822 aAddress.IncCol())
5823 {
5824 ScRange aInputRangeSlice = rDataRange;
5825 if (eInputOrientation == sc::RangeOrientation::Row)
5826 {
5827 aInputRangeSlice.aStart.SetRow(rDataRange.aStart.Row() + nIndex);
5828 aInputRangeSlice.aEnd.SetRow(rDataRange.aStart.Row() + nIndex);
5829 }
5830 else
5831 {
5832 aInputRangeSlice.aStart.SetCol(rDataRange.aStart.Col() + nIndex);
5833 aInputRangeSlice.aEnd.SetCol(rDataRange.aStart.Col() + nIndex);
5834 }
5835
5836 aSparklineDataVector.emplace_back(aAddress, aInputRangeSlice);
5837
5838 nIndex++;
5839 }
5840 }
5841
5842 if (aSparklineDataVector.empty())
5843 return false;
5844
5845 auto pUndoInsertSparkline = std::make_unique<sc::UndoInsertSparkline>(rDocShell, aSparklineDataVector, pSparklineGroup);
5846 // insert the sparkline by "redoing"
5847 pUndoInsertSparkline->Redo();
5848 rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndoInsertSparkline));
5849
5850 return true;
5851}
5852
5854{
5855 auto& rDocument = rDocShell.GetDocument();
5856
5857 if (!rDocument.HasSparkline(rAddress))
5858 return false;
5859
5860 auto pUndoDeleteSparkline = std::make_unique<sc::UndoDeleteSparkline>(rDocShell, rAddress);
5861 // delete sparkline by "redoing"
5862 pUndoDeleteSparkline->Redo();
5863 rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndoDeleteSparkline));
5864
5865 return true;
5866}
5867
5868bool ScDocFunc::DeleteSparklineGroup(std::shared_ptr<sc::SparklineGroup> const& pSparklineGroup, SCTAB nTab)
5869{
5870 if (!pSparklineGroup)
5871 return false;
5872
5873 auto& rDocument = rDocShell.GetDocument();
5874
5875 if (!rDocument.HasTable(nTab))
5876 return false;
5877
5878 auto pUndo = std::make_unique<sc::UndoDeleteSparklineGroup>(rDocShell, pSparklineGroup, nTab);
5879 // delete sparkline group by "redoing"
5880 pUndo->Redo();
5881 rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndo));
5882 return true;
5883}
5884
5885bool ScDocFunc::ChangeSparklineGroupAttributes(std::shared_ptr<sc::SparklineGroup> const& pExistingSparklineGroup,
5886 sc::SparklineAttributes const& rNewAttributes)
5887{
5888 auto pUndo = std::make_unique<sc::UndoEditSparklneGroup>(rDocShell, pExistingSparklineGroup, rNewAttributes);
5889 // change sparkline group attributes by "redoing"
5890 pUndo->Redo();
5891 rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndo));
5892 return true;
5893}
5894
5895bool ScDocFunc::GroupSparklines(ScRange const& rRange, std::shared_ptr<sc::SparklineGroup> const& rpGroup)
5896{
5897 auto pUndo = std::make_unique<sc::UndoGroupSparklines>(rDocShell, rRange, rpGroup);
5898 // group sparklines by "redoing"
5899 pUndo->Redo();
5900 rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndo));
5901 return true;
5902}
5903
5905{
5906 auto pUndo = std::make_unique<sc::UndoUngroupSparklines>(rDocShell, rRange);
5907 // ungroup sparklines by "redoing"
5908 pUndo->Redo();
5909 rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndo));
5910 return true;
5911}
5912
5913bool ScDocFunc::ChangeSparkline(std::shared_ptr<sc::Sparkline> const& rpSparkline, SCTAB nTab, ScRangeList const& rDataRange)
5914{
5915 auto pUndo = std::make_unique<sc::UndoEditSparkline>(rDocShell, rpSparkline, nTab, rDataRange);
5916 // change sparkline by "redoing"
5917 pUndo->Redo();
5918 rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndo));
5919 return true;
5920}
5921
5922/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SCTAB MAXTAB
Definition: address.hxx:70
const SCTAB TABLEID_DOC
Definition: address.hxx:91
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
SfxApplication * SfxGetpApp()
ScMF
Definition: attrib.hxx:34
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
const OUString & GetName() const
sal_uInt32 GetValue() const
OUString GetText(LineEnd eEnd=LINEEND_LF) const
std::unique_ptr< EditTextObject > CreateTextObject()
bool SetUpdateLayout(bool bUpdate, bool bRestoring=false)
sal_Int32 GetParagraphCount() const
virtual void SetParaAttribs(sal_Int32 nPara, const SfxItemSet &rSet)
const SfxItemSet & GetParaAttribs(sal_Int32 nPara) const
virtual std::unique_ptr< EditTextObject > Clone() const=0
@ UNINITIALIZED
Definition: address.hxx:220
SCTAB Tab() const
Definition: address.hxx:283
void SetCol(SCCOL nColP)
Definition: address.hxx:291
void IncCol(SCCOL nDelta=1)
Definition: address.hxx:316
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
void IncRow(SCROW nDelta=1)
Definition: address.hxx:312
SCCOL Col() const
Definition: address.hxx:279
bool GetIncludeWidthHeight() const
Definition: autoform.hxx:148
const ScAutoFormatData * findByIndex(size_t nIndex) const
Definition: autoform.cxx:762
std::unique_ptr< ScTokenArray > CompileString(const OUString &rFormula)
Tokenize formula expression string into an array of tokens.
Definition: compiler.cxx:4691
void RemoveFromDocument(ScDocument &rDoc) const
Definition: conditio.cxx:2260
void AddToDocument(ScDocument &rDoc) const
Definition: conditio.cxx:2269
ScConditionalFormat * GetFormat(sal_uInt32 nKey)
Definition: conditio.cxx:2098
const ScRangeList & GetRange() const
Definition: conditio.hxx:559
sal_uInt32 GetKey() const
Definition: conditio.hxx:591
SC_DLLPUBLIC bool HasTable(const ScDPObject *pDPObj) const
Definition: dpobject.cxx:3782
ScDetOpType GetOperation() const
Definition: detdata.hxx:45
const ScAddress & GetPos() const
Definition: detdata.hxx:44
size_t Count() const
Definition: detdata.hxx:78
const ScDetOpData & GetObject(size_t nPos) const
Definition: detdata.cxx:83
bool DeleteSucc(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1122
bool ShowError(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1103
bool ShowPred(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1063
bool DeletePred(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1135
bool DeleteAll(ScDetectiveDelete eWhat)
Definition: detfunc.cxx:1203
void GetAllSuccs(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ::std::vector< ScTokenRef > &rRefTokens)
Definition: detfunc.cxx:1349
bool MarkInvalid(bool &rOverflow)
Definition: detfunc.cxx:1260
bool ShowSucc(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1083
void GetAllPreds(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ::std::vector< ScTokenRef > &rRefTokens)
Definition: detfunc.cxx:1330
bool DeleteCirclesAt(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1148
const ScPatternAttr * GetNext(SCCOL &rCol, SCROW &rRow1, SCROW &rRow2)
Definition: dociter.cxx:1588
void ModifyRangeNames(const ScRangeName &rNewRanges, SCTAB nTab=-1)
Definition: docfunc.cxx:5137
void EndListAction()
Definition: docfunc.cxx:5769
SC_DLLPUBLIC bool DeleteSparkline(ScAddress const &rAddress)
Definition: docfunc.cxx:5853
bool DetectiveAddError(const ScAddress &rPos)
Definition: docfunc.cxx:360
bool MoveBlock(const ScRange &rSource, const ScAddress &rDestPos, bool bCut, bool bRecord, bool bPaint, bool bApi)
Definition: docfunc.cxx:2852
bool AutoFormat(const ScRange &rRange, const ScMarkData *pTabMark, sal_uInt16 nFormatNo, bool bApi)
Definition: docfunc.cxx:4205
bool SetStringOrEditCell(const ScAddress &rPos, const OUString &rStr, bool bInteraction)
Definition: docfunc.cxx:1008
ScDocShell & rDocShell
Definition: docfunc.hxx:64
SC_DLLPUBLIC bool ChangeSparkline(std::shared_ptr< sc::Sparkline > const &rpSparkline, SCTAB nTab, ScRangeList const &rDataRange)
Definition: docfunc.cxx:5913
bool AdjustRowHeight(const ScRange &rRange, bool bPaint, bool bApi)
Definition: docfunc.cxx:151
bool Protect(SCTAB nTab, const OUString &rPassword)
Definition: docfunc.cxx:4010
bool SetNormalString(bool &o_rbNumFmtSet, const ScAddress &rPos, const OUString &rText, bool bApi)
Definition: docfunc.cxx:799
bool UnmergeCells(const ScRange &rRange, bool bRecord, ScUndoRemoveMerge *pUndoRemoveMerge)
Definition: docfunc.cxx:5050
bool SetTabBgColor(SCTAB nTab, const Color &rColor, bool bRecord, bool bApi)
Definition: docfunc.cxx:3534
void ResizeMatrix(const ScRange &rOldRange, const ScAddress &rNewEnd)
Definition: docfunc.cxx:5472
bool DetectiveAddPred(const ScAddress &rPos)
Definition: docfunc.cxx:209
void ProtectDocument(const ScDocProtection &rProtect)
Definition: docfunc.cxx:3981
void SetConditionalFormatList(ScConditionalFormatList *pList, SCTAB nTab)
Sets or replaces the conditional format list of a table.
Definition: docfunc.cxx:5679
bool SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell, bool bInteraction)
Below two methods take ownership of the formula cell instance(s).
Definition: docfunc.cxx:1023
void ModifyAllRangeNames(const std::map< OUString, ScRangeName > &rRangeMap)
Modify all range names, global scope names as well as sheet local ones, in one go.
Definition: docfunc.cxx:5188
bool ChangeIndent(const ScMarkData &rMark, bool bIncrement, bool bApi)
Definition: docfunc.cxx:4136
bool SetValueCell(const ScAddress &rPos, double fVal, bool bInteraction)
Definition: docfunc.cxx:867
bool CreateNames(const ScRange &rRange, CreateNameFlags nFlags, bool bApi, SCTAB nTab=-1)
Definition: docfunc.cxx:5274
bool RenameTable(SCTAB nTab, const OUString &rName, bool bRecord, bool bApi)
Definition: docfunc.cxx:3500
SC_DLLPUBLIC bool FillAuto(ScRange &rRange, const ScMarkData *pTabMark, FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd, sal_uLong nCount, double fStep, double fMax, bool bRecord, bool bApi)
Definition: docfunc.cxx:4797
bool InsertCells(const ScRange &rRange, const ScMarkData *pTabMark, InsCellCmd eCmd, bool bRecord, bool bApi, bool bPartOfPaste=false)
Definition: docfunc.cxx:1736
bool RemovePageBreak(bool bColumn, const ScAddress &rPos, bool bRecord, bool bSetModified)
Definition: docfunc.cxx:3886
bool SetCellText(const ScAddress &rPos, const OUString &rText, bool bInterpret, bool bEnglish, bool bApi, const formula::FormulaGrammar::Grammar eGrammar)
Definition: docfunc.cxx:1240
void ProtectSheet(SCTAB nTab, const ScTableProtection &rProtect)
Definition: docfunc.cxx:3949
bool SetStringCell(const ScAddress &rPos, const OUString &rStr, bool bInteraction)
Definition: docfunc.cxx:936
SC_DLLPUBLIC bool ShowNote(const ScAddress &rPos, bool bShow)
Definition: docfunc.cxx:1288
bool TabOp(const ScRange &rRange, const ScMarkData *pTabMark, const ScTabOpParam &rParam, bool bRecord, bool bApi)
Definition: docfunc.cxx:4405
SC_DLLPUBLIC bool MergeCells(const ScCellMergeOption &rOption, bool bContents, bool bRecord, bool bApi, bool bEmptyMergedCells=false)
Definition: docfunc.cxx:4933
void SetNewRangeNames(std::unique_ptr< ScRangeName > pNewRanges, bool bModifyDoc, SCTAB nTab)
Definition: docfunc.cxx:5142
bool DeleteCells(const ScRange &rRange, const ScMarkData *pTabMark, DelCellCmd eCmd, bool bApi)
Definition: docfunc.cxx:2271
bool SetFormulaCells(const ScAddress &rPos, std::vector< ScFormulaCell * > &rCells, bool bInteraction)
Definition: docfunc.cxx:1072
bool DetectiveMarkInvalid(SCTAB nTab)
Definition: docfunc.cxx:397
bool InsertPageBreak(bool bColumn, const ScAddress &rPos, bool bRecord, bool bSetModified)
Definition: docfunc.cxx:3823
bool FillSeries(const ScRange &rRange, const ScMarkData *pTabMark, FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd, double fStart, double fStep, double fMax, bool bApi)
Definition: docfunc.cxx:4659
SC_DLLPUBLIC bool InsertTable(SCTAB nTab, const OUString &rName, bool bRecord, bool bApi)
Definition: docfunc.cxx:3269
void ReplaceConditionalFormat(sal_uLong nOldIndex, std::unique_ptr< ScConditionalFormat > pFormat, SCTAB nTab, const ScRangeList &rRanges)
Definition: docfunc.cxx:5603
void NotifyDrawUndo(std::unique_ptr< SdrUndoAction >)
Definition: docfunc.cxx:120
void EnterListAction(TranslateId pNameResId)
Definition: docfunc.cxx:5760
SC_DLLPUBLIC bool DeleteContents(const ScMarkData &rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi)
Definition: docfunc.cxx:583
void InsertAreaLink(const OUString &rFile, const OUString &rFilter, const OUString &rOptions, const OUString &rSource, const ScRange &rDestRange, sal_Int32 nRefreshDelaySeconds, bool bFitBlock, bool bApi)
Definition: docfunc.cxx:5514
void SetTableVisible(SCTAB nTab, bool bVisible, bool bApi)
Definition: docfunc.cxx:3419
bool ApplyStyle(const ScMarkData &rMark, const OUString &rStyleName, bool bApi)
Definition: docfunc.cxx:1495
SC_DLLPUBLIC bool UngroupSparklines(ScRange const &rRange)
Definition: docfunc.cxx:5904
SC_DLLPUBLIC bool InsertSparklines(ScRange const &rDataRange, ScRange const &rSparklineRange, std::shared_ptr< sc::SparklineGroup > pSparklineGroup)
Definition: docfunc.cxx:5774
void SetNoteText(const ScAddress &rPos, const OUString &rNoteText, bool bApi)
Definition: docfunc.cxx:1316
void SetValueCells(const ScAddress &rPos, const std::vector< double > &aVals, bool bInteraction)
Definition: docfunc.cxx:902
SC_DLLPUBLIC bool SetWidthOrHeight(bool bWidth, const std::vector< sc::ColRowSpan > &rRanges, SCTAB nTab, ScSizeMode eMode, sal_uInt16 nSizeTwips, bool bRecord, bool bApi)
Definition: docfunc.cxx:3652
bool DetectiveDelPred(const ScAddress &rPos)
Definition: docfunc.cxx:245
void CreateOneName(ScRangeName &rList, SCCOL nPosX, SCROW nPosY, SCTAB nTab, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, bool &rCancel, bool bApi)
Definition: docfunc.cxx:5209
bool DetectiveDelSucc(const ScAddress &rPos)
Definition: docfunc.cxx:321
SC_DLLPUBLIC bool ChangeSparklineGroupAttributes(std::shared_ptr< sc::SparklineGroup > const &pExistingSparklineGroup, sc::SparklineAttributes const &rNewAttributes)
Definition: docfunc.cxx:5885
bool ApplyAttributes(const ScMarkData &rMark, const ScPatternAttr &rPattern, bool bApi)
Definition: docfunc.cxx:1426
void ConvertFormulaToValue(const ScRange &rRange, bool bInteraction)
Definition: docfunc.cxx:5727
bool SetEditCell(const ScAddress &rPos, const EditTextObject &rStr, bool bInteraction)
Definition: docfunc.cxx:973
bool DeleteTable(SCTAB nTab, bool bRecord)
Definition: docfunc.cxx:3321
bool DetectiveDelAll(SCTAB nTab)
Definition: docfunc.cxx:436
void NotifyInputHandler(const ScAddress &rPos)
Definition: docfunc.cxx:1128
SC_DLLPUBLIC bool DeleteSparklineGroup(std::shared_ptr< sc::SparklineGroup > const &pSparklineGroup, SCTAB nTab)
Definition: docfunc.cxx:5868
bool FillSimple(const ScRange &rRange, const ScMarkData *pTabMark, FillDir eDir, bool bApi)
Definition: docfunc.cxx:4545
bool InsertNameList(const ScAddress &rStartPos, bool bApi)
Definition: docfunc.cxx:5363
void PutData(const ScAddress &rPos, ScEditEngineDefaulter &rEngine, bool bApi)
Definition: docfunc.cxx:1160
bool DeleteCell(const ScAddress &rPos, const ScMarkData &rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi)
Definition: docfunc.cxx:674
bool DetectiveRefresh(bool bAutomatic=false)
Definition: docfunc.cxx:476
SC_DLLPUBLIC bool EnterMatrix(const ScRange &rRange, const ScMarkData *pTabMark, const ScTokenArray *pTokenArray, const OUString &rString, bool bApi, bool bEnglish, const OUString &rFormulaNmsp, const formula::FormulaGrammar::Grammar)
Definition: docfunc.cxx:4317
void ClearItems(const ScMarkData &rMark, const sal_uInt16 *pWhich, bool bApi)
Definition: docfunc.cxx:4092
void DetectiveCollectAllPreds(const ScRangeList &rSrcRanges, ::std::vector< ScTokenRef > &rRefTokens)
Definition: docfunc.cxx:573
SC_DLLPUBLIC bool GroupSparklines(ScRange const &rRange, std::shared_ptr< sc::SparklineGroup > const &rpGroup)
Definition: docfunc.cxx:5895
bool TransliterateText(const ScMarkData &rMark, TransliterationFlags nType, bool bApi)
Definition: docfunc.cxx:741
bool SetLayoutRTL(SCTAB nTab, bool bRTL)
Definition: docfunc.cxx:3469
SC_DLLPUBLIC ScPostIt * ImportNote(const ScAddress &rPos, const OUString &rNoteText)
Definition: docfunc.cxx:1408
bool DetectiveAddSucc(const ScAddress &rPos)
Definition: docfunc.cxx:284
bool Unprotect(SCTAB nTab, const OUString &rPassword, bool bApi)
Definition: docfunc.cxx:4034
void DetectiveCollectAllSuccs(const ScRangeList &rSrcRanges, ::std::vector< ScTokenRef > &rRefTokens)
Definition: docfunc.cxx:578
void ReplaceNote(const ScAddress &rPos, const OUString &rNoteText, const OUString *pAuthor, const OUString *pDate, bool bApi)
Definition: docfunc.cxx:1342
virtual bool verifyPassword(const OUString &aPassText) const override
virtual void setPassword(const OUString &aPassText) override
virtual bool isProtected() const override
virtual void setProtected(bool bProtected) override
Create before modifications of the document and destroy thereafter.
Definition: docsh.hxx:455
void SetDocumentModified()
Definition: docsh.cxx:3315
void PostPaintCell(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: docsh3.cxx:188
static weld::Window * GetActiveDialogParent()
Definition: docsh.cxx:3112
void PostPaintGridAll()
Definition: docsh3.cxx:183
void SetDocumentModified()
Definition: docsh.cxx:2982
SfxBindings * GetViewBindings()
Definition: docsh4.cxx:2642
void ErrorMessage(TranslateId pGlobStrId)
Definition: docsh5.cxx:71
const ScDocument & GetDocument() const
Definition: docsh.hxx:219
void UpdatePaintExt(sal_uInt16 &rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab)
Definition: docsh3.cxx:228
void PostDataChanged()
Definition: docsh3.cxx:93
ScDrawLayer * MakeDrawLayer()
Definition: docsh2.cxx:169
ScTabViewShell * GetBestViewShell(bool bOnlyVisible=true)
Definition: docsh4.cxx:2623
void PostPaintExtras()
Definition: docsh3.cxx:198
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:101
void SetDrawModified()
SetDrawModified - without Formula update.
Definition: docsh.cxx:3046
static ScViewData * GetViewData()
Definition: docsh4.cxx:2607
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2968
bool IsEditable() const
Definition: docsh5.cxx:96
void UpdateLinks() override
Definition: docsh6.cxx:318
static void LOKCommentNotify(LOKCommentNotificationType nType, const ScDocument *pDocument, const ScAddress &rPos, const ScPostIt *pNote)
Definition: docsh4.cxx:2539
static void RemoveAppPrefix(OUString &rFilterName)
Definition: tablink.cxx:485
static bool GetFilterName(const OUString &rFileName, OUString &rFilter, OUString &rOptions, bool bWithContent, bool bWithInteraction)
Returns the filter name and options from a file name.
Definition: tablink.cxx:431
SC_DLLPUBLIC bool InsertTab(SCTAB nPos, const OUString &rName, bool bExternalDocument=false, bool bUndoDeleteTab=false)
Definition: document.cxx:485
SC_DLLPUBLIC bool IsScenario(SCTAB nTab) const
Definition: documen3.cxx:432
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
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:898
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
SC_DLLPUBLIC void GetRangeNameMap(std::map< OUString, ScRangeName * > &rRangeName)
Definition: documen3.cxx:149
bool UpdateOutlineCol(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bShow)
Adapt Outline.
Definition: documen3.cxx:1415
bool RefreshAutoFilter(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab)
Definition: document.cxx:5660
SC_DLLPUBLIC ScFormulaCell * SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell)
Set formula cell, and transfer its ownership to the document.
Definition: documen2.cxx:1149
void SetValues(const ScAddress &rPos, const std::vector< double > &rVals)
Definition: document10.cxx:160
SC_DLLPUBLIC void SetAllRangeNames(const std::map< OUString, ScRangeName > &rRangeMap)
Definition: documen3.cxx:126
SC_DLLPUBLIC OUString GetLinkTab(SCTAB nTab) const
Definition: documen3.cxx:530
bool ValidRow(SCROW nRow) const
Definition: document.hxx:900
SC_DLLPUBLIC const ScTableProtection * GetTabProtection(SCTAB nTab) const
Definition: documen3.cxx:1914
SC_DLLPUBLIC void SetLayoutRTL(SCTAB nTab, bool bRTL, ScObjectHandling eObjectHandling=ScObjectHandling::RecalcPosMode)
Definition: document.cxx:937
void UpdatePageBreaks(SCTAB nTab, const ScRange *pUserArea=nullptr)
Definition: document.cxx:6210
void SetRangeName(SCTAB nTab, std::unique_ptr< ScRangeName > pNew)
Definition: documen3.cxx:185
SC_DLLPUBLIC void Fill(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScProgress *pProgress, const ScMarkData &rMark, sal_uInt64 nFillCount, FillDir eFillDir=FILL_TO_BOTTOM, FillCmd eFillCmd=FILL_LINEAR, FillDateCmd eFillDateCmd=FILL_DAY, double nStepValue=1.0, double nMaxValue=1E307)
Definition: documen3.cxx:1156
SC_DLLPUBLIC bool ExtendMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, SCTAB nTab, bool bRefresh=false)
Definition: document.cxx:5556
SC_DLLPUBLIC void InsertMatrixFormula(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rMark, const OUString &rFormula, const ScTokenArray *p=nullptr, const formula::FormulaGrammar::Grammar=formula::FormulaGrammar::GRAM_DEFAULT)
Definition: documen4.cxx:259
void TransliterateText(const ScMarkData &rMultiMark, TransliterationFlags nType)
Definition: documen8.cxx:1205
SC_DLLPUBLIC Color GetTabBgColor(SCTAB nTab) const
Definition: documen3.cxx:449
SC_DLLPUBLIC void InsertTableOp(const ScTabOpParam &rParam, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rMark)
Definition: documen4.cxx:356
void BeginDrawUndo()
Definition: documen9.cxx:61
SC_DLLPUBLIC void CompileHybridFormula()
Call this immediately after updating named ranges.
Definition: document10.cxx:319
SC_DLLPUBLIC bool IsTabProtected(SCTAB nTab) const
Definition: documen3.cxx:1905
void InvalidatePageBreaks(SCTAB nTab)
Definition: document.cxx:6204
bool SetFormulaCells(const ScAddress &rPos, std::vector< ScFormulaCell * > &rCells)
Definition: documen2.cxx:1158
bool IsSelectionEditable(const ScMarkData &rMark, bool *pOnlyNotBecauseOfMatrix=nullptr) const
Definition: document.cxx:5340
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:892
SC_DLLPUBLIC const ScValidationData * GetValidationEntry(sal_uInt32 nIndex) const
Definition: documen4.cxx:873
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:837
const ScSheetEvents * GetSheetEvents(SCTAB nTab) const
Definition: documen3.cxx:661
SC_DLLPUBLIC void DoMergeContents(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab)
Definition: documen3.cxx:2026
OUString GetLinkOpt(SCTAB nTab) const
Definition: documen3.cxx:523
SC_DLLPUBLIC bool SetOptimalHeight(sc::RowHeightContext &rCxt, SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bApi)
Definition: document.cxx:4267
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6050
SC_DLLPUBLIC void ApplyPatternAreaTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScPatternAttr &rAttr)
Definition: document.cxx:4770
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:492
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
bool IsAdjustHeightLocked() const
Definition: document.hxx:1599
SC_DLLPUBLIC bool HasPivotTable() const
Definition: documen3.cxx:360
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:483
ScDetOpList * GetDetOpList() const
Definition: document.hxx:1852
SC_DLLPUBLIC void DoMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, bool bDeleteCaptions=true)
Definition: documen3.cxx:2063
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
void AddDetectiveOperation(const ScDetOpData &rData)
Definition: documen4.cxx:892
void DeleteConditionalFormat(sal_uLong nIndex, SCTAB nTab)
Definition: documen4.cxx:881
SC_DLLPUBLIC sal_Int16 GetNamedRangesLockCount() const
Definition: document.hxx:1608
SC_DLLPUBLIC void DeleteSelection(InsertDeleteFlags nDelFlag, const ScMarkData &rMark, bool bBroadcast=true)
Definition: document.cxx:5921
SC_DLLPUBLIC void SetColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
Definition: document.cxx:4390
SC_DLLPUBLIC void ApplySelectionStyle(const ScStyleSheet &rStyle, const ScMarkData &rMark)
Definition: document.cxx:4830
SC_DLLPUBLIC void PreprocessRangeNameUpdate()
Definition: document10.cxx:295
bool IsDocEditable() const
Definition: documen3.cxx:1899
SC_DLLPUBLIC ScBreakType HasRowBreak(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4355
SC_DLLPUBLIC void GetScenarioData(SCTAB nTab, OUString &rComment, Color &rColor, ScScenarioFlags &rFlags) const
Definition: documen3.cxx:469
bool HasOLEObjectsInArea(const ScRange &rRange, const ScMarkData *pTabMark=nullptr)
Definition: documen9.cxx:264
void SetStreamValid(SCTAB nTab, bool bSet, bool bIgnoreLock=false)
Definition: document.cxx:904
SC_DLLPUBLIC void CopyToClip(const ScClipParam &rClipParam, ScDocument *pClipDoc, const ScMarkData *pMarks, bool bKeepScenarioFlags, bool bIncludeObjects)
Definition: document.cxx:2142
SC_DLLPUBLIC void DoEmptyBlock(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab)
Definition: documen3.cxx:2050
SC_DLLPUBLIC void SetRowHeightRange(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_uInt16 nNewHeight)
Definition: document.cxx:4104
void SetCondFormList(ScConditionalFormatList *pList, SCTAB nTab)
Definition: documen4.cxx:867
SC_DLLPUBLIC void ShowCol(SCCOL nCol, SCTAB nTab, bool bShow)
Definition: document.cxx:4297
SC_DLLPUBLIC bool GetAutoCalc() const
Definition: document.hxx:1413
void SetCodeName(const OUString &r)
Definition: document.hxx:610
bool IsInVBAMode() const
Definition: document.cxx:6477
SC_DLLPUBLIC std::unique_ptr< ScPostIt > ReleaseNote(const ScAddress &rPos)
Definition: document.cxx:6689
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: document.cxx:3391
SC_DLLPUBLIC void InitUndo(const ScDocument &rSrcDoc, SCTAB nTab1, SCTAB nTab2, bool bColInfo=false, bool bRowInfo=false)
Definition: document.cxx:1975
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
bool UpdateOutlineRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bShow)
Definition: documen3.cxx:1424
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 ScBreakType HasColBreak(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:4369
SC_DLLPUBLIC void SetDrawPageSize(SCTAB nTab)
Definition: documen9.cxx:203
void DeleteObjectsInSelection(const ScMarkData &rMark)
Definition: documen9.cxx:256
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 void ShowRows(SCROW nRow1, SCROW nRow2, SCTAB nTab, bool bShow)
Definition: document.cxx:4309
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
SC_DLLPUBLIC CRFlags GetRowFlags(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4335
SC_DLLPUBLIC bool HasNote(const ScAddress &rPos) const
Definition: document.cxx:6618
SC_DLLPUBLIC void SetRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
Definition: document.cxx:4384
bool IsExecuteLinkEnabled() const
Definition: document.hxx:1602
SC_DLLPUBLIC ScLinkMode GetLinkMode(SCTAB nTab) const
Definition: documen3.cxx:502
SC_DLLPUBLIC bool HasAttrib(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, HasAttrFlags nMask) const
Definition: document.cxx:5161
void DeleteObjectsInArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rMark, bool bAnchored=false)
Definition: documen9.cxx:240
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 SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3477
bool IsChangeReadOnlyEnabled() const
Definition: document.hxx:1604
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 ClearSelectionItems(const sal_uInt16 *pWhich, const ScMarkData &rMark)
Definition: document.cxx:5909
void ConvertFormulaToValue(const ScRange &rRange, sc::TableValues *pUndo)
Definition: document10.cxx:211
SC_DLLPUBLIC void ApplyAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, const SfxPoolItem &rAttr)
Definition: document.cxx:4741
SC_DLLPUBLIC ScDocProtection * GetDocProtection() const
Definition: documen3.cxx:1881
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1083
void ChangeSelectionIndent(bool bIncrement, const ScMarkData &rMark)
Definition: document.cxx:5897
SC_DLLPUBLIC ScStyleSheetPool * GetStyleSheetPool() const
Definition: document.cxx:6055
SC_DLLPUBLIC ScOutlineTable * GetOutlineTable(SCTAB nTab, bool bCreate=false)
Definition: documen3.cxx:737
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:899
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 ExtendOverlapped(SCCOL &rStartCol, SCROW &rStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5466
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 OUString GetFormula(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3706
SC_DLLPUBLIC void PreprocessAllRangeNamesUpdate(const std::map< OUString, ScRangeName > &rRangeMap)
Call this immediately before updating all named ranges.
Definition: document10.cxx:251
sal_uLong GetLinkRefreshDelay(SCTAB nTab) const
Definition: documen3.cxx:537
SC_DLLPUBLIC void SetRowFlags(SCROW nRow, SCTAB nTab, CRFlags nNewFlags)
Definition: document.cxx:4315
SC_DLLPUBLIC ScConditionalFormatList * GetCondFormList(SCTAB nTab) const
Definition: documen4.cxx:860
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:467
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
SC_DLLPUBLIC void SetDocProtection(const ScDocProtection *pProtect)
Definition: documen3.cxx:1886
void AutoFormat(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, sal_uInt16 nFormatNo, const ScMarkData &rMark)
Definition: documen3.cxx:1187
SC_DLLPUBLIC bool IsEmptyData(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:6060
SC_DLLPUBLIC void DeleteAreaTab(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, InsertDeleteFlags nDelFlag)
Definition: document.cxx:1920
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
void ClearDetectiveOperations()
Definition: documen4.cxx:900
SC_DLLPUBLIC OUString GetLinkDoc(SCTAB nTab) const
Definition: documen3.cxx:509
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 SetTabProtection(SCTAB nTab, const ScTableProtection *pProtect)
Definition: documen3.cxx:1922
bool IsLinked(SCTAB nTab) const
Definition: documen3.cxx:486
SC_DLLPUBLIC void SetColWidth(SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth)
Definition: document.cxx:4086
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx:2494
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 DeleteTab(SCTAB nTab)
Definition: document.cxx:654
SC_DLLPUBLIC sfx2::LinkManager * GetLinkManager()
Definition: documen2.cxx:231
bool IsUndoEnabled() const
Definition: document.hxx:1595
void SetDirty(const ScRange &, bool bIncludeEmptyCells)
Definition: document.cxx:3841
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:204
SC_DLLPUBLIC void SetTabBgColor(SCTAB nTab, const Color &rColor)
Definition: documen3.cxx:456
bool HasSelectedBlockMatrixFragment(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScMarkData &rMark) const
Definition: document.cxx:5395
OUString GetLinkFlt(SCTAB nTab) const
Definition: documen3.cxx:516
SC_DLLPUBLIC sal_uLong AddCondFormat(std::unique_ptr< ScConditionalFormat > pNew, SCTAB nTab)
Definition: documen4.cxx:708
void PutInFormulaTree(ScFormulaCell *pCell)
Definition: documen7.cxx:265
void TransferCellValuesTo(const ScAddress &rTopPos, size_t nLen, sc::CellValues &rDest)
Transfer a series of contiguous cell values from specified position to the passed container.
Definition: document10.cxx:169
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4684
SC_DLLPUBLIC SCSIZE GetEmptyLinesInBlock(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, ScDirection eDir)
Definition: document.cxx:6067
SC_DLLPUBLIC const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4719
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
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
SC_DLLPUBLIC ScDPCollection * GetDPCollection()
Definition: documen3.cxx:365
SC_DLLPUBLIC void SetVisible(SCTAB nTab, bool bVisible)
Definition: document.cxx:884
SC_DLLPUBLIC bool IsActiveScenario(SCTAB nTab) const
Definition: documen3.cxx:880
void RemoveRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
Definition: document.cxx:4396
void IncXMLImportedFormulaCount(sal_uInt64 nVal)
Definition: document.hxx:2460
bool IsImportingXML() const
Definition: document.hxx:2227
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:297
void RemoveColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
Definition: document.cxx:4402
bool IsRecording() const
Definition: drwlayer.hxx:143
void BeginCalcUndo(bool bDisableTextEditUsesCommonUndoManager)
Definition: drwlayer.cxx:1514
std::unique_ptr< SdrUndoGroup > GetCalcUndo()
Definition: drwlayer.cxx:1521
void AddCalcUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: drwlayer.cxx:1503
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2927
const SfxItemSet & GetAttribs() const
Definition: editutil.hxx:104
bool NeedsObject() const
Definition: editutil.hxx:102
bool NeedsCellAttr() const
Definition: editutil.hxx:103
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:619
bool IsEditable() const
Definition: editable.hxx:84
TranslateId GetMessageId() const
Definition: editable.cxx:152
void TestBlock(const ScDocument &rDoc, SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool bNoMatrixAtAll=false)
Definition: editable.cxx:82
bool Interpret(SCROW nStartOffset=-1, SCROW nEndOffset=-1)
static SC_DLLPUBLIC ScAutoFormat * GetOrCreateAutoFormat()
Definition: global.cxx:266
static SC_DLLPUBLIC const CharClass & getCharClass()
Definition: global.cxx:1064
void SetModified()
Definition: inputhdl.hxx:246
bool IsEditMode() const
Definition: inputhdl.hxx:187
const ScAddress & GetCursorPos() const
Definition: inputhdl.hxx:194
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
const_iterator end() const
Definition: markdata.hxx:164
const ScRange & GetMultiMarkArea() const
Definition: markdata.hxx:84
void SelectTable(SCTAB nTab, bool bNew)
Definition: markdata.cxx:157
const ScRange & GetMarkArea() const
Definition: markdata.hxx:83
void SelectOneTable(SCTAB nTab)
Definition: markdata.cxx:174
bool IsMultiMarked() const
Definition: markdata.hxx:81
void SetMarking(bool bFlag)
Definition: markdata.hxx:102
SCTAB GetSelectCount() const
Definition: markdata.cxx:180
void MarkToMulti()
Definition: markdata.cxx:209
bool IsMarked() const
Definition: markdata.hxx:80
void SetMarkArea(const ScRange &rRange)
Definition: markdata.cxx:92
const_iterator begin() const
Definition: markdata.hxx:163
const_reverse_iterator rbegin() const
Definition: markdata.hxx:165
bool IsMerged() const
Definition: attrib.hxx:74
ScMF GetValue() const
Definition: attrib.hxx:100
static ScPostIt * CreateNoteFromString(ScDocument &rDoc, const ScAddress &rPos, const OUString &rNoteText, bool bShown, bool bAlwaysCreateCaption, sal_uInt32 nPostItId=0)
Creates a cell note based on the passed string and inserts it into the document.
Definition: postit.cxx:965
void DeleteUnchanged(const ScPatternAttr *pOldAttrs)
Definition: patattr.cxx:1013
SfxItemSet & GetItemSet()
Definition: patattr.hxx:192
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:73
static void GetFromEditItemSet(SfxItemSet &rDestSet, const SfxItemSet &rEditSet)
Converts all edit engine items contained in rEditSet to Calc items and puts them into rDestSet.
Definition: patattr.cxx:874
Additional class containing cell annotation data.
Definition: postit.hxx:58
const ScNoteData & GetNoteData() const
Returns the data struct containing all note settings.
Definition: postit.hxx:103
void SetAuthor(const OUString &rAuthor)
Sets a new author date for this note.
Definition: postit.cxx:499
void ShowCaption(const ScAddress &rPos, bool bShow)
Shows or hides the note caption object.
Definition: postit.cxx:589
void SetDate(const OUString &rDate)
Sets a new creation date for this note.
Definition: postit.cxx:494
bool IsCaptionShown() const
Returns true, if the caption object is visible.
Definition: postit.hxx:150
SdrCaptionObj * GetCaption() const
Returns an existing note caption object.
Definition: postit.hxx:132
bool HasType(Type nType) const
Definition: rangenam.hxx:178
static void MakeValidName(const ScDocument &rDoc, OUString &rName)
Definition: rangenam.cxx:423
SC_DLLPUBLIC OUString GetSymbol(const formula::FormulaGrammar::Grammar eGrammar=formula::FormulaGrammar::GRAM_DEFAULT) const
Definition: rangenam.cxx:244
const OUString & GetUpperName() const
Definition: rangenam.hxx:112
ScRange & front()
Definition: rangelst.hxx:92
ScRange Combine() const
Definition: rangelst.cxx:1107
bool empty() const
Definition: rangelst.hxx:88
size_t size() const
Definition: rangelst.hxx:89
SC_DLLPUBLIC ScRangeData * findByUpperName(const OUString &rName)
Definition: rangenam.cxx:704
void erase(const ScRangeData &r)
Definition: rangenam.cxx:846
SC_DLLPUBLIC bool insert(ScRangeData *p, bool bReuseFreeIndex=true)
Insert object into set.
Definition: rangenam.cxx:802
bool Move(SCCOL aDeltaX, SCROW aDeltaY, SCTAB aDeltaZ, ScRange &rErrorRange, const ScDocument &rDoc)
Definition: address.cxx:2328
ScAddress aEnd
Definition: address.hxx:498
void ExtendTo(const ScRange &rRange)
Definition: address.cxx:1562
bool Contains(const ScAddress &) const
is Address& fully in Range?
Definition: address.hxx:718
ScAddress aStart
Definition: address.hxx:497
sal_Int32 GetRefreshDelaySeconds() const
OutputDevice * GetDevice() const
Definition: sizedev.hxx:40
double GetPPTY() const
Definition: sizedev.hxx:42
double GetPPTX() const
Definition: sizedev.hxx:41
static ScInputStringType parseInputString(SvNumberFormatter &rFormatter, const OUString &rStr, LanguageType eLang)
Definition: stringutil.cxx:430
static bool SC_DLLPUBLIC isMultiline(std::u16string_view rStr)
Definition: stringutil.cxx:425
static void notifyAllViewsSheetGeomInvalidation(const SfxViewShell *pForViewShell, bool bColumns, bool bRows, bool bSizes, bool bHidden, bool bFiltered, bool bGroups, SCTAB nCurrentTabIndex)
Emits a LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY for all views whose current tab is equal to nCurrentTa...
Definition: tabvwshc.cxx:593
static void notifyAllViewsHeaderInvalidation(const SfxViewShell *pForViewShell, HeaderType eHeaderType, SCTAB nCurrentTabIndex)
Emits a LOK_CALLBACK_INVALIDATE_HEADER for all views whose current tab is equal to nCurrentTabIndex.
Definition: tabvwshc.cxx:535
void UpdateInputHandler(bool bForce=false, bool bStopEditing=true)
Definition: tabvwsha.cxx:690
static ScTabViewShell * GetActiveViewShell()
Definition: tabvwsh4.cxx:1076
static void OnLOKNoteStateChanged(const ScPostIt *pNote)
Definition: tabview5.cxx:660
void MarkRange(const ScRange &rRange, bool bSetCursor=true, bool bContinue=false)
Definition: tabview3.cxx:1708
ScViewData & GetViewData()
Definition: tabview.hxx:344
SC_DLLPUBLIC void SetCursor(SCCOL nPosX, SCROW nPosY, bool bNew=false)
Definition: tabview3.cxx:363
sheet protection state container
virtual bool verifyPassword(const OUString &aPassText) const override
virtual bool isProtected() const override
virtual void setProtected(bool bProtected) override
void AssignXMLString(const OUString &rText, const OUString &rFormulaNmsp)
Assign XML string placeholder to the array.
Definition: token.cxx:2324
std::vector< Value > ValuesType
Definition: undocell.hxx:84
void AddCellMergeOption(const ScCellMergeOption &rOption)
Definition: undoblk.cxx:2250
ScDocument * GetUndoDoc()
Definition: undoblk.cxx:2245
ScPositionHelper & GetLOKHeightHelper()
Definition: viewdata.hxx:411
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
static bool SelectionFillDOOM(const ScRange &rRange)
Determine DOOM condition, i.e. from selected range.
Definition: viewdata.cxx:1328
SCROW GetCurY() const
Definition: viewdata.hxx:402
SCCOL GetCurX() const
Definition: viewdata.hxx:401
void OnLOKInsertDeleteColumn(SCCOL nStartCol, tools::Long nOffset)
Definition: viewfunc.cxx:1583
void OnLOKInsertDeleteRow(SCROW nStartRow, tools::Long nOffset)
Definition: viewfunc.cxx:1640
void OnLOKSetWidthOrHeight(SCCOLROW nStart, bool bWidth)
Definition: viewfunc.cxx:1697
void Invalidate(sal_uInt16 nId)
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
const WhichRangesContainer & GetRanges() const
SfxItemPool * GetPool() const
sal_uInt16 Count() const
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
css::uno::Reference< css::script::XLibraryContainer > GetBasicContainer()
BasicManager * GetBasicManager() const
css::uno::Reference< css::frame::XModel3 > GetModel() const
virtual SfxStyleSheetBase * Find(const OUString &, SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All)
size_t LeaveListAction()
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
void RemoveLastUndoAction()
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetNext(const SfxViewFrame &rPrev, const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetFirst(const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
ViewShellDocId GetDocId() const override
ViewShellId GetViewShellId() const override
static SAL_WARN_UNUSED_RESULT SfxViewShell * GetNext(const SfxViewShell &rPrev, bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
static SAL_WARN_UNUSED_RESULT SfxViewShell * GetFirst(bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
static void addDeleteContentsUndo(SfxUndoManager *pUndoMgr, ScDocShell *pDocSh, const ScMarkData &rMark, const ScRange &rRange, ScDocumentUniquePtr &&pUndoDoc, InsertDeleteFlags nFlags, const std::shared_ptr< ScSimpleUndo::DataSpansType > &pSpans, bool bMulti, bool bDrawUndo)
Definition: docfuncutil.cxx:78
static ScDocumentUniquePtr createDeleteContentsUndoDoc(ScDocument &rDoc, const ScMarkData &rMark, const ScRange &rRange, InsertDeleteFlags nFlags, bool bOnlyMarked)
Definition: docfuncutil.cxx:47
static std::shared_ptr< ScSimpleUndo::DataSpansType > getNonEmptyCellSpans(const ScDocument &rDoc, const ScMarkData &rMark, const ScRange &rRange)
Definition: docfuncutil.cxx:92
static bool hasProtectedTab(const ScDocument &rDoc, const ScMarkData &rMark)
Definition: docfuncutil.cxx:32
void setForceAutoSize(bool b)
Common properties for a group of sparklines.
Stores cell values for multiple tables.
Definition: cellvalues.hxx:89
void InsertFileLink(sfx2::SvBaseLink &, SvBaseLinkObjectType nFileType, std::u16string_view rFileNm, const OUString *pFilterNm=nullptr, const OUString *pRange=nullptr)
void Remove(SvBaseLink const *pLink)
const SvBaseLinks & GetLinks() const
T * get() const
int nCount
constexpr double nPPTX
constexpr double nPPTY
@ SCDETOP_DELPRED
Definition: detdata.hxx:31
@ SCDETOP_DELSUCC
Definition: detdata.hxx:29
@ SCDETOP_ADDPRED
Definition: detdata.hxx:30
@ SCDETOP_ADDSUCC
Definition: detdata.hxx:28
@ SCDETOP_ADDERROR
Definition: detdata.hxx:32
void VBA_InsertModule(ScDocument &rDoc, SCTAB nTab, const OUString &sSource)
Definition: docfunc.cxx:3197
static void lcl_PaintAbove(ScDocShell &rDocShell, const ScRange &rRange)
Definition: docfunc.cxx:139
static ScDirection DirFromFillDir(FillDir eDir)
Definition: docfunc.cxx:4464
static void lcl_collectAllPredOrSuccRanges(const ScRangeList &rSrcRanges, vector< ScTokenRef > &rRefTokens, ScDocShell &rDocShell, bool bPred)
Definition: docfunc.cxx:546
static sal_uInt16 lcl_GetOptimalColWidth(ScDocShell &rDocShell, SCCOL nCol, SCTAB nTab)
SetWidthOrHeight - duplicated in ViewFunc !!!!!! Problems:
Definition: docfunc.cxx:3637
static uno::Reference< uno::XInterface > GetDocModuleObject(const SfxObjectShell &rDocSh, const OUString &sCodeName)
Definition: docfunc.cxx:3175
void VBA_DeleteModule(ScDocShell &rDocSh, const OUString &sModuleName)
Definition: docfunc.cxx:3240
static script::ModuleInfo lcl_InitModuleInfo(const SfxObjectShell &rDocSh, const OUString &sModule)
Definition: docfunc.cxx:3189
#define SC_PF_TESTMERGE
Definition: docsh.hxx:77
#define SC_PF_LINES
Definition: docsh.hxx:76
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2720
@ SCDOCMODE_CLIP
Definition: document.hxx:257
@ SCDOCMODE_UNDO
Definition: document.hxx:258
ScBreakType
Definition: global.hxx:139
@ CELLTYPE_EDIT
Definition: global.hxx:277
DelCellCmd
Definition: global.hxx:281
InsCellCmd
Definition: global.hxx:290
@ INS_INSROWS_AFTER
Definition: global.hxx:296
@ INS_INSCOLS_AFTER
Definition: global.hxx:297
@ INS_CELLSDOWN
Definition: global.hxx:291
@ INS_INSCOLS_BEFORE
Definition: global.hxx:294
@ INS_CELLSRIGHT
Definition: global.hxx:292
@ INS_INSROWS_BEFORE
Definition: global.hxx:293
InsertDeleteFlags
Definition: global.hxx:149
@ NOTE
Strings (and string results if InsertDeleteFlags::FORMULA is not set).
@ NOCAPTIONS
Sparklines in a cell.
@ AUTOFILL
Copy flags for auto/series fill functions: do not touch notes and drawing objects.
@ OBJECTS
Cell styles.
@ ATTRIB
Internal use only (d&d undo): do not delete caption objects of cell notes.
@ FORMULA
Cell notes.
ScSizeMode
Definition: global.hxx:351
@ SC_SIZE_DIRECT
Definition: global.hxx:352
@ SC_SIZE_OPTIMAL
Definition: global.hxx:353
@ SC_SIZE_VISOPT
Definition: global.hxx:355
@ SC_SIZE_ORIGINAL
Definition: global.hxx:356
@ SC_SIZE_SHOW
Definition: global.hxx:354
FillDateCmd
Definition: global.hxx:334
@ FILL_DAY
Definition: global.hxx:335
PaintPartFlags
Definition: global.hxx:109
ScScenarioFlags
Definition: global.hxx:226
ScDirection
Definition: global.hxx:343
@ DIR_LEFT
Definition: global.hxx:347
@ DIR_TOP
Definition: global.hxx:346
@ DIR_RIGHT
Definition: global.hxx:345
@ DIR_BOTTOM
Definition: global.hxx:344
constexpr sal_Int32 STD_EXTRA_WIDTH
Definition: global.hxx:88
#define MAXDOUBLE
Definition: global.hxx:77
CRFlags
Definition: global.hxx:125
FillCmd
Definition: global.hxx:317
@ FILL_AUTO
Definition: global.hxx:322
@ FILL_SIMPLE
Definition: global.hxx:318
FillDir
Definition: global.hxx:309
@ FILL_TO_TOP
Definition: global.hxx:312
@ FILL_TO_RIGHT
Definition: global.hxx:311
@ FILL_TO_LEFT
Definition: global.hxx:313
@ FILL_TO_BOTTOM
Definition: global.hxx:310
sal_Int32 nIndex
OUString aName
Mode eMode
void * p
sal_Int64 n
#define LANGUAGE_ENGLISH_US
LineEnd GetSystemLineEnd()
TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
sal_uInt16 nPos
SvBaseLink * pLink
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
std::unique_ptr< sal_Int32[]> pData
size
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
RangeOrientation calculateOrientation(sal_Int32 nOutputSize, ScRange const &rInputRange)
Determine the sparkline group orientation for the input data the output size.
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
int ScRangeData_QsortNameCompare(const void *p1, const void *p2)
Definition: rangenam.cxx:644
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
constexpr TypedWhichId< SvxHorJustifyItem > ATTR_HOR_JUSTIFY(129)
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALUE_FORMAT(146)
constexpr TypedWhichId< SvxVerJustifyItem > ATTR_VER_JUSTIFY(132)
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALIDDATA(153)
#define SC_MOD()
Definition: scmod.hxx:247
CreateNameFlags
Definition: scui_def.hxx:50
sal_uIntPtr sal_uLong
OUString VCL_DLLPUBLIC GetStandardText(StandardButtonType eButton)
ScRange getSingleRange(SCTAB nTab) const
::std::set< SCTAB > maTabs
Store arbitrary cell value of any kind.
Definition: cellvalue.hxx:32
void assign(const ScDocument &rDoc, const ScAddress &rPos)
Take cell value from specified position in specified document.
Definition: cellvalue.cxx:359
This struct stores general clipboard parameters associated with a ScDocument instance created in clip...
Definition: clipparam.hxx:31
StringType meType
Definition: stringutil.hxx:124
Internal data for a cell annotation.
Definition: postit.hxx:42
rtl::Reference< SdrCaptionObj > mxCaption
Initial data for invisible notes without SdrObject.
Definition: postit.hxx:48
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:108
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
Parameter for data table aka multiple operations.
Definition: paramisc.hxx:46
ScRefAddress aRefFormulaEnd
Definition: paramisc.hxx:50
ScRefAddress aRefColCell
Definition: paramisc.hxx:52
ScRefAddress aRefFormulaCell
Definition: paramisc.hxx:49
ScRefAddress aRefRowCell
Definition: paramisc.hxx:51
ScCellValue maCell
Definition: undocell.hxx:79
::std::vector< ScUndoTabColorInfo > List
Definition: tabbgcolor.hxx:36
@ ROW_HEADER
Definition: tabview.hxx:60
bool bVisible
TransliterationFlags
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:23
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
#define SC_TAB_INSERTED
Definition: uiitems.hxx:75
#define SC_TAB_HIDDEN
Definition: uiitems.hxx:79
#define SC_TAB_DELETED
Definition: uiitems.hxx:76
RET_CANCEL
RET_YES
sal_Int32 nLength