cid#1607171 Data race condition
[LibreOffice.git] / sc / source / ui / undo / undotab.cxx
blob52d1a18ff62d20f65c04ad7de3c4d351e2d02440
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sfx2/app.hxx>
21 #include <sfx2/bindings.hxx>
22 #include <sfx2/dispatch.hxx>
23 #include <svl/hint.hxx>
24 #include <osl/diagnose.h>
26 #include <undotab.hxx>
27 #include <document.hxx>
28 #include <docsh.hxx>
29 #include <tabvwsh.hxx>
30 #include <globstr.hrc>
31 #include <global.hxx>
32 #include <sc.hrc>
33 #include <strings.hrc>
34 #include <undoolk.hxx>
35 #include <target.hxx>
36 #include <uiitems.hxx>
37 #include <prnsave.hxx>
38 #include <printfun.hxx>
39 #include <chgtrack.hxx>
40 #include <tabprotection.hxx>
41 #include <utility>
42 #include <viewdata.hxx>
43 #include <progress.hxx>
44 #include <markdata.hxx>
45 #include <refundo.hxx>
47 // for ScUndoRenameObject - might me moved to another file later
48 #include <svx/svditer.hxx>
49 #include <svx/svdoole2.hxx>
50 #include <drwlayer.hxx>
51 #include <scresid.hxx>
52 #include <sheetevents.hxx>
53 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
54 #include <comphelper/lok.hxx>
55 #include <tools/json_writer.hxx>
57 #include <memory>
58 #include <vector>
60 using namespace com::sun::star;
61 using ::std::unique_ptr;
62 using ::std::vector;
64 namespace
66 void lcl_OnTabsChanged(const ScTabViewShell& rViewShell, const ScDocument& rDoc, SCTAB nTab, bool bInvalidateTiles = false)
68 for (SCTAB nTabIndex = nTab; nTabIndex < rDoc.GetTableCount(); ++nTabIndex)
70 if (!rDoc.IsVisible(nTabIndex))
71 continue;
72 if (bInvalidateTiles)
73 rViewShell.libreOfficeKitViewInvalidateTilesCallback(nullptr, nTabIndex, 0);
74 ScTabViewShell::notifyAllViewsSheetGeomInvalidation(
75 &rViewShell,
76 true /* bColsAffected */, true /* bRowsAffected */,
77 true /* bSizes*/, true /* bHidden */, true /* bFiltered */,
78 true /* bGroups */, nTabIndex);
82 template<typename T>
83 void lcl_MakeJsonArray(tools::JsonWriter& rJson, const std::vector<T>& v, const char *pArrayName)
85 if (!v.empty())
87 auto jsonArray = rJson.startArray(pArrayName);
88 std::stringstream ss;
89 for (std::size_t i = 0; i < v.size(); ++i)
91 SCTAB tabIndex = v[i];
92 ss << tabIndex;
93 if (i < v.size() - 1)
94 ss << ",";
95 ss << " ";
97 if (!ss.str().empty())
98 rJson.putRaw(ss.str());
102 void lcl_UndoCommandResult(const ScTabViewShell& rViewShell,
103 const char *pCmdName, const char *pCmdType,
104 const std::vector<SCTAB>* pNewTabs,
105 const std::vector<SCTAB>* pOldTabs = nullptr)
107 tools::JsonWriter aJson;
108 aJson.put("commandName", pCmdName);
109 aJson.put("success", true);
111 auto result = aJson.startNode("result");
112 aJson.put("type", pCmdType);
113 if (pNewTabs)
114 lcl_MakeJsonArray(aJson, *pNewTabs, "newTabs");
115 if (pOldTabs)
116 lcl_MakeJsonArray(aJson, *pOldTabs, "oldTabs");
119 rViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
123 ScUndoInsertTab::ScUndoInsertTab( ScDocShell* pNewDocShell,
124 SCTAB nTabNum,
125 bool bApp,
126 OUString aNewName) :
127 ScSimpleUndo( pNewDocShell ),
128 sNewName(std::move( aNewName )),
129 nTab( nTabNum ),
130 bAppend( bApp )
132 pDrawUndo = GetSdrUndoAction( &pDocShell->GetDocument() );
133 SetChangeTrack();
136 ScUndoInsertTab::~ScUndoInsertTab()
138 pDrawUndo.reset();
141 OUString ScUndoInsertTab::GetComment() const
143 if (bAppend)
144 return ScResId( STR_UNDO_APPEND_TAB );
145 else
146 return ScResId( STR_UNDO_INSERT_TAB );
149 void ScUndoInsertTab::SetChangeTrack()
151 ScDocument& rDoc = pDocShell->GetDocument();
152 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
153 if ( pChangeTrack )
155 ScRange aRange( 0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab );
156 pChangeTrack->AppendInsert( aRange );
157 nEndChangeAction = pChangeTrack->GetActionMax();
159 else
160 nEndChangeAction = 0;
163 void ScUndoInsertTab::Undo()
165 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
166 if (!pViewShell)
167 return;
169 pViewShell->SetTabNo(nTab);
171 pDocShell->SetInUndo( true ); //! BeginUndo
172 bDrawIsInUndo = true;
173 pViewShell->DeleteTable( nTab, false );
174 bDrawIsInUndo = false;
175 pDocShell->SetInUndo( false ); //! EndUndo
177 DoSdrUndoAction( pDrawUndo.get(), &pDocShell->GetDocument() );
179 ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
180 if ( pChangeTrack )
181 pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
183 if (comphelper::LibreOfficeKit::isActive())
185 ScDocument& rDoc = pDocShell->GetDocument();
186 lcl_OnTabsChanged(*pViewShell, rDoc, nTab);
187 std::vector<SCTAB> aTabs{nTab};
188 lcl_UndoCommandResult(*pViewShell, ".uno:Undo", "ScUndoInsertTab", &aTabs);
192 // SetTabNo(...,sal_True) for all views to sync with drawing layer pages
193 pDocShell->Broadcast( SfxHint( SfxHintId::ScForceSetTab ) );
196 void ScUndoInsertTab::Redo()
198 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
199 if (!pViewShell)
200 return;
202 RedoSdrUndoAction( pDrawUndo.get() ); // Draw Redo first
204 pDocShell->SetInUndo( true ); //! BeginRedo
205 bDrawIsInUndo = true;
206 if (bAppend)
207 pViewShell->AppendTable( sNewName, false );
208 else
210 pViewShell->SetTabNo(nTab);
211 pViewShell->InsertTable( sNewName, nTab, false );
213 bDrawIsInUndo = false;
214 pDocShell->SetInUndo( false ); //! EndRedo
216 SetChangeTrack();
218 if (comphelper::LibreOfficeKit::isActive())
220 ScDocument& rDoc = pDocShell->GetDocument();
221 lcl_OnTabsChanged(*pViewShell, rDoc, nTab);
222 std::vector<SCTAB> aTabs{nTab};
223 lcl_UndoCommandResult(*pViewShell, ".uno:Redo", "ScUndoInsertTab", &aTabs);
227 void ScUndoInsertTab::Repeat(SfxRepeatTarget& rTarget)
229 if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
230 pViewTarget->GetViewShell()->GetViewData().GetDispatcher().
231 Execute(FID_INS_TABLE, SfxCallMode::SLOT | SfxCallMode::RECORD);
234 bool ScUndoInsertTab::CanRepeat(SfxRepeatTarget& rTarget) const
236 return dynamic_cast<const ScTabViewTarget*>( &rTarget) != nullptr;
239 ScUndoInsertTables::ScUndoInsertTables( ScDocShell* pNewDocShell,
240 SCTAB nTabNum,
241 std::vector<OUString>&& newNameList) :
242 ScSimpleUndo( pNewDocShell ),
243 aNameList( std::move(newNameList) ),
244 nTab( nTabNum )
246 pDrawUndo = GetSdrUndoAction( &pDocShell->GetDocument() );
248 SetChangeTrack();
251 ScUndoInsertTables::~ScUndoInsertTables()
253 pDrawUndo.reset();
256 OUString ScUndoInsertTables::GetComment() const
258 return ScResId( STR_UNDO_INSERT_TAB );
261 void ScUndoInsertTables::SetChangeTrack()
263 ScDocument& rDoc = pDocShell->GetDocument();
264 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
265 if ( pChangeTrack )
267 nStartChangeAction = pChangeTrack->GetActionMax() + 1;
268 nEndChangeAction = 0;
269 ScRange aRange( 0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab );
270 for( size_t i = 0; i < aNameList.size(); i++ )
272 aRange.aStart.SetTab( sal::static_int_cast<SCTAB>( nTab + i ) );
273 aRange.aEnd.SetTab( sal::static_int_cast<SCTAB>( nTab + i ) );
274 pChangeTrack->AppendInsert( aRange );
275 nEndChangeAction = pChangeTrack->GetActionMax();
278 else
279 nStartChangeAction = nEndChangeAction = 0;
282 void ScUndoInsertTables::Undo()
284 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
285 if (!pViewShell)
286 return;
288 pViewShell->SetTabNo(nTab);
290 pDocShell->SetInUndo( true ); //! BeginUndo
291 bDrawIsInUndo = true;
293 pViewShell->DeleteTables( nTab, static_cast<SCTAB>(aNameList.size()) );
295 bDrawIsInUndo = false;
296 pDocShell->SetInUndo( false ); //! EndUndo
298 DoSdrUndoAction( pDrawUndo.get(), &pDocShell->GetDocument() );
300 ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
301 if ( pChangeTrack )
302 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
304 // SetTabNo(...,sal_True) for all views to sync with drawing layer pages
305 pDocShell->Broadcast( SfxHint( SfxHintId::ScForceSetTab ) );
308 void ScUndoInsertTables::Redo()
310 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
311 if (!pViewShell)
312 return;
314 RedoSdrUndoAction( pDrawUndo.get() ); // Draw Redo first
316 pDocShell->SetInUndo( true ); //! BeginRedo
317 bDrawIsInUndo = true;
318 pViewShell->InsertTables( aNameList, nTab, static_cast<SCTAB>(aNameList.size()),false );
320 bDrawIsInUndo = false;
321 pDocShell->SetInUndo( false ); //! EndRedo
323 SetChangeTrack();
326 void ScUndoInsertTables::Repeat(SfxRepeatTarget& rTarget)
328 if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
329 pViewTarget->GetViewShell()->GetViewData().GetDispatcher().
330 Execute(FID_INS_TABLE, SfxCallMode::SLOT | SfxCallMode::RECORD);
333 bool ScUndoInsertTables::CanRepeat(SfxRepeatTarget& rTarget) const
335 return dynamic_cast<const ScTabViewTarget*>( &rTarget) != nullptr;
338 ScUndoDeleteTab::ScUndoDeleteTab( ScDocShell* pNewDocShell, const vector<SCTAB> &aTab,
339 ScDocumentUniquePtr pUndoDocument, std::unique_ptr<ScRefUndoData> pRefData ) :
340 ScMoveUndo( pNewDocShell, std::move(pUndoDocument), std::move(pRefData) )
342 theTabs.insert(theTabs.end(), aTab.begin(), aTab.end() );
343 SetChangeTrack();
346 ScUndoDeleteTab::~ScUndoDeleteTab()
348 theTabs.clear();
351 OUString ScUndoDeleteTab::GetComment() const
353 return ScResId( STR_UNDO_DELETE_TAB );
356 void ScUndoDeleteTab::SetChangeTrack()
358 ScDocument& rDoc = pDocShell->GetDocument();
359 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
360 if ( pChangeTrack )
362 sal_uLong nTmpChangeAction;
363 nStartChangeAction = pChangeTrack->GetActionMax() + 1;
364 nEndChangeAction = 0;
365 ScRange aRange( 0, 0, 0, rDoc.MaxCol(), rDoc.MaxRow(), 0 );
366 for ( size_t i = 0; i < theTabs.size(); ++i )
368 aRange.aStart.SetTab( theTabs[i] );
369 aRange.aEnd.SetTab( theTabs[i] );
370 pChangeTrack->AppendDeleteRange( aRange, pRefUndoDoc.get(),
371 nTmpChangeAction, nEndChangeAction, static_cast<short>(i) );
374 else
375 nStartChangeAction = nEndChangeAction = 0;
378 static SCTAB lcl_GetVisibleTabBefore( const ScDocument& rDoc, SCTAB nTab )
380 while ( nTab > 0 && !rDoc.IsVisible( nTab ) )
381 --nTab;
383 return nTab;
386 void ScUndoDeleteTab::Undo()
388 BeginUndo();
389 ScDocument& rDoc = pDocShell->GetDocument();
391 bool bLink = false;
392 OUString aName;
394 for(SCTAB nTab: theTabs)
396 pRefUndoDoc->GetName( nTab, aName );
398 bDrawIsInUndo = true;
399 bool bOk = rDoc.InsertTab(nTab, aName, false, true);
400 bDrawIsInUndo = false;
401 if (bOk)
403 pRefUndoDoc->CopyToDocument(0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, InsertDeleteFlags::ALL,false, rDoc);
405 OUString aOldName;
406 pRefUndoDoc->GetName( nTab, aOldName );
407 rDoc.RenameTab( nTab, aOldName );
408 if (pRefUndoDoc->IsLinked(nTab))
410 rDoc.SetLink( nTab, pRefUndoDoc->GetLinkMode(nTab), pRefUndoDoc->GetLinkDoc(nTab),
411 pRefUndoDoc->GetLinkFlt(nTab), pRefUndoDoc->GetLinkOpt(nTab),
412 pRefUndoDoc->GetLinkTab(nTab), pRefUndoDoc->GetLinkRefreshDelay(nTab) );
413 bLink = true;
416 if ( pRefUndoDoc->IsScenario(nTab) )
418 rDoc.SetScenario( nTab, true );
419 OUString aComment;
420 Color aColor;
421 ScScenarioFlags nScenFlags;
422 pRefUndoDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
423 rDoc.SetScenarioData( nTab, aComment, aColor, nScenFlags );
424 bool bActive = pRefUndoDoc->IsActiveScenario( nTab );
425 rDoc.SetActiveScenario( nTab, bActive );
427 rDoc.SetVisible( nTab, pRefUndoDoc->IsVisible( nTab ) );
428 rDoc.SetTabBgColor( nTab, pRefUndoDoc->GetTabBgColor(nTab) );
429 auto pSheetEvents = pRefUndoDoc->GetSheetEvents( nTab );
430 rDoc.SetSheetEvents( nTab, std::unique_ptr<ScSheetEvents>(pSheetEvents ? new ScSheetEvents(*pSheetEvents) : nullptr) );
431 rDoc.SetLayoutRTL( nTab, pRefUndoDoc->IsLayoutRTL( nTab ) );
433 if ( pRefUndoDoc->IsTabProtected( nTab ) )
434 rDoc.SetTabProtection(nTab, pRefUndoDoc->GetTabProtection(nTab));
437 if (bLink)
439 pDocShell->UpdateLinks(); // update Link Manager
442 EndUndo(); // Draw-Undo has to be called before Broadcast!
444 ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
445 if ( pChangeTrack )
446 pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
448 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
449 if (comphelper::LibreOfficeKit::isActive() && !theTabs.empty())
451 if (pViewShell)
453 lcl_OnTabsChanged(*pViewShell, rDoc, theTabs[0]);
454 lcl_UndoCommandResult(*pViewShell, ".uno:Undo", "ScUndoDeleteTab", &theTabs);
458 for(SCTAB nTab: theTabs)
460 pDocShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab) );
462 SfxApplication* pSfxApp = SfxGetpApp(); // Navigator
463 pSfxApp->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
464 pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
465 pSfxApp->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
466 pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
468 pDocShell->PostPaint(0,0,0, rDoc.MaxCol(),rDoc.MaxRow(),MAXTAB, PaintPartFlags::All ); // incl. extras
470 // not ShowTable due to SetTabNo(..., sal_True):
471 if (pViewShell)
472 pViewShell->SetTabNo( lcl_GetVisibleTabBefore( rDoc, theTabs[0] ), true );
475 void ScUndoDeleteTab::Redo()
477 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
478 if (!pViewShell)
479 return;
481 pViewShell->SetTabNo( lcl_GetVisibleTabBefore( pDocShell->GetDocument(), theTabs.front() ) );
483 RedoSdrUndoAction( pDrawUndo.get() ); // Draw Redo first
485 pDocShell->SetInUndo( true ); //! BeginRedo
486 bDrawIsInUndo = true;
487 pViewShell->DeleteTables( theTabs, false );
488 bDrawIsInUndo = false;
489 pDocShell->SetInUndo( true ); //! EndRedo
491 SetChangeTrack();
493 if (comphelper::LibreOfficeKit::isActive() && !theTabs.empty())
495 ScDocument& rDoc = pDocShell->GetDocument();
496 lcl_OnTabsChanged(*pViewShell, rDoc, theTabs[0]);
497 lcl_UndoCommandResult(*pViewShell, ".uno:Redo", "ScUndoDeleteTab", &theTabs);
500 // SetTabNo(...,sal_True) for all views to sync with drawing layer pages
501 pDocShell->Broadcast( SfxHint( SfxHintId::ScForceSetTab ) );
504 void ScUndoDeleteTab::Repeat(SfxRepeatTarget& rTarget)
506 if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
508 ScTabViewShell* pViewShell = pViewTarget->GetViewShell();
509 pViewShell->DeleteTable( pViewShell->GetViewData().GetTabNo() );
513 bool ScUndoDeleteTab::CanRepeat(SfxRepeatTarget& rTarget) const
515 return dynamic_cast<const ScTabViewTarget*>( &rTarget) != nullptr;
518 ScUndoRenameTab::ScUndoRenameTab( ScDocShell* pNewDocShell,
519 SCTAB nT,
520 const OUString& rOldName,
521 const OUString& rNewName) :
522 ScSimpleUndo( pNewDocShell ),
523 nTab ( nT )
525 sOldName = rOldName;
526 sNewName = rNewName;
529 ScUndoRenameTab::~ScUndoRenameTab()
533 OUString ScUndoRenameTab::GetComment() const
535 return ScResId( STR_UNDO_RENAME_TAB );
538 void ScUndoRenameTab::DoChange( SCTAB nTabP, const OUString& rName ) const
540 ScDocument& rDoc = pDocShell->GetDocument();
541 rDoc.RenameTab( nTabP, rName );
543 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) ); // Navigator
544 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) ); // Also Name Box
546 pDocShell->PostPaintGridAll();
547 pDocShell->PostPaintExtras();
548 pDocShell->PostDataChanged();
550 // The sheet name might be used in a formula ...
551 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
552 if (pViewShell)
553 pViewShell->UpdateInputHandler();
556 void ScUndoRenameTab::Undo()
558 DoChange(nTab, sOldName);
561 void ScUndoRenameTab::Redo()
563 DoChange(nTab, sNewName);
566 void ScUndoRenameTab::Repeat(SfxRepeatTarget& /* rTarget */)
568 // makes no sense
571 bool ScUndoRenameTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
573 return false;
576 ScUndoMoveTab::ScUndoMoveTab(
577 ScDocShell* pNewDocShell, std::unique_ptr<vector<SCTAB>> pOldTabs, std::unique_ptr<vector<SCTAB>> pNewTabs,
578 std::unique_ptr<vector<OUString>> pOldNames, std::unique_ptr<vector<OUString>> pNewNames) :
579 ScSimpleUndo( pNewDocShell ),
580 mpOldTabs(std::move(pOldTabs)), mpNewTabs(std::move(pNewTabs)),
581 mpOldNames(std::move(pOldNames)), mpNewNames(std::move(pNewNames))
583 // The sizes differ. Something is wrong.
584 assert(!mpOldNames || mpOldTabs->size() == mpOldNames->size());
585 // The sizes differ. Something is wrong.
586 assert(!mpNewNames || mpNewTabs->size() == mpNewNames->size());
589 ScUndoMoveTab::~ScUndoMoveTab()
593 OUString ScUndoMoveTab::GetComment() const
595 return ScResId( STR_UNDO_MOVE_TAB );
598 void ScUndoMoveTab::DoChange( bool bUndo ) const
600 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
601 if (!pViewShell)
602 return;
604 ScDocument& rDoc = pDocShell->GetDocument();
605 if (bUndo) // UnDo
607 size_t i = mpNewTabs->size();
608 ScProgress aProgress(pDocShell, ScResId(STR_UNDO_MOVE_TAB),
609 i * rDoc.GetCodeCount(), true);
610 for (; i > 0; --i)
612 SCTAB nDestTab = (*mpNewTabs)[i-1];
613 SCTAB nOldTab = (*mpOldTabs)[i-1];
614 if (nDestTab > MAXTAB) // appended ?
615 nDestTab = rDoc.GetTableCount() - 1;
617 rDoc.MoveTab( nDestTab, nOldTab, &aProgress );
618 pViewShell->GetViewData().MoveTab( nDestTab, nOldTab );
619 pViewShell->SetTabNo( nOldTab, true );
620 if (mpOldNames)
622 const OUString& rOldName = (*mpOldNames)[i-1];
623 rDoc.RenameTab(nOldTab, rOldName);
627 else
629 size_t n = mpNewTabs->size();
630 ScProgress aProgress(pDocShell, ScResId(STR_UNDO_MOVE_TAB),
631 n * rDoc.GetCodeCount(), true);
632 for (size_t i = 0; i < n; ++i)
634 SCTAB nDestTab = (*mpNewTabs)[i];
635 SCTAB nNewTab = nDestTab;
636 SCTAB nOldTab = (*mpOldTabs)[i];
637 if (nDestTab > MAXTAB) // appended ?
638 nDestTab = rDoc.GetTableCount() - 1;
640 rDoc.MoveTab( nOldTab, nNewTab, &aProgress );
641 pViewShell->GetViewData().MoveTab( nOldTab, nNewTab );
642 pViewShell->SetTabNo( nDestTab, true );
643 if (mpNewNames)
645 const OUString& rNewName = (*mpNewNames)[i];
646 rDoc.RenameTab(nNewTab, rNewName);
651 if (comphelper::LibreOfficeKit::isActive() && !mpNewTabs->empty())
653 const auto newTabsMinIt = std::min_element(mpNewTabs->begin(), mpNewTabs->end());
654 const auto oldTabsMinIt = std::min_element(mpOldTabs->begin(), mpOldTabs->end());
655 SCTAB nTab = std::min(*newTabsMinIt, *oldTabsMinIt);
656 lcl_OnTabsChanged(*pViewShell, rDoc, nTab, true /* bInvalidateTiles */);
657 lcl_UndoCommandResult(*pViewShell, bUndo ? ".uno:Undo" : ".uno:Redo", "ScUndoMoveTab", mpOldTabs.get(), mpNewTabs.get());
660 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) ); // Navigator
662 pDocShell->PostPaintGridAll();
663 pDocShell->PostPaintExtras();
664 pDocShell->PostDataChanged();
667 void ScUndoMoveTab::Undo()
669 DoChange( true );
672 void ScUndoMoveTab::Redo()
674 DoChange( false );
677 void ScUndoMoveTab::Repeat(SfxRepeatTarget& /* rTarget */)
679 // No Repeat ! ? !
682 bool ScUndoMoveTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
684 return false;
687 ScUndoCopyTab::ScUndoCopyTab(
688 ScDocShell* pNewDocShell,
689 std::unique_ptr<vector<SCTAB>> pOldTabs, std::unique_ptr<vector<SCTAB>> pNewTabs,
690 std::unique_ptr<vector<OUString>> pNewNames) :
691 ScSimpleUndo( pNewDocShell ),
692 mpOldTabs(std::move(pOldTabs)),
693 mpNewTabs(std::move(pNewTabs)),
694 mpNewNames(std::move(pNewNames))
696 pDrawUndo = GetSdrUndoAction( &pDocShell->GetDocument() );
698 // The sizes differ. Something is wrong.
699 assert(!mpNewNames || mpNewTabs->size() == mpNewNames->size());
702 ScUndoCopyTab::~ScUndoCopyTab()
704 pDrawUndo.reset();
707 OUString ScUndoCopyTab::GetComment() const
709 return ScResId( STR_UNDO_COPY_TAB );
712 void ScUndoCopyTab::DoChange() const
714 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
716 if (pViewShell)
717 pViewShell->SetTabNo((*mpOldTabs)[0],true);
719 SfxApplication* pSfxApp = SfxGetpApp(); // Navigator
720 pSfxApp->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
721 pSfxApp->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
723 pDocShell->PostPaintGridAll();
724 pDocShell->PostPaintExtras();
725 pDocShell->PostDataChanged();
728 void ScUndoCopyTab::Undo()
730 ScDocument& rDoc = pDocShell->GetDocument();
732 DoSdrUndoAction( pDrawUndo.get(), &rDoc ); // before the sheets are deleted
734 vector<SCTAB>::const_reverse_iterator itr, itrEnd = mpNewTabs->rend();
735 for (itr = mpNewTabs->rbegin(); itr != itrEnd; ++itr)
737 SCTAB nDestTab = *itr;
738 if (nDestTab > MAXTAB) // append?
739 nDestTab = rDoc.GetTableCount() - 1;
741 bDrawIsInUndo = true;
742 rDoc.DeleteTab(nDestTab);
743 bDrawIsInUndo = false;
746 // ScTablesHint broadcasts after all sheets have been deleted,
747 // so sheets and draw pages are in sync!
749 for (itr = mpNewTabs->rbegin(); itr != itrEnd; ++itr)
751 SCTAB nDestTab = *itr;
752 if (nDestTab > MAXTAB) // append?
753 nDestTab = rDoc.GetTableCount() - 1;
755 pDocShell->Broadcast( ScTablesHint( SC_TAB_DELETED, nDestTab ) );
758 DoChange();
761 void ScUndoCopyTab::Redo()
763 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
764 if (!pViewShell)
765 return;
767 ScDocument& rDoc = pDocShell->GetDocument();
769 SCTAB nDestTab = 0;
770 for (size_t i = 0, n = mpNewTabs->size(); i < n; ++i)
772 nDestTab = (*mpNewTabs)[i];
773 SCTAB nNewTab = nDestTab;
774 SCTAB nOldTab = (*mpOldTabs)[i];
775 if (nDestTab > MAXTAB) // appended ?
776 nDestTab = rDoc.GetTableCount() - 1;
778 bDrawIsInUndo = true;
779 rDoc.CopyTab( nOldTab, nNewTab );
780 bDrawIsInUndo = false;
782 pViewShell->GetViewData().MoveTab( nOldTab, nNewTab );
784 SCTAB nAdjSource = nOldTab;
785 if ( nNewTab <= nOldTab )
786 ++nAdjSource; // new position of source table after CopyTab
788 if ( rDoc.IsScenario(nAdjSource) )
790 rDoc.SetScenario(nNewTab, true );
791 OUString aComment;
792 Color aColor;
793 ScScenarioFlags nScenFlags;
794 rDoc.GetScenarioData(nAdjSource, aComment, aColor, nScenFlags );
795 rDoc.SetScenarioData(nNewTab, aComment, aColor, nScenFlags );
796 bool bActive = rDoc.IsActiveScenario(nAdjSource);
797 rDoc.SetActiveScenario(nNewTab, bActive );
798 bool bVisible = rDoc.IsVisible(nAdjSource);
799 rDoc.SetVisible(nNewTab,bVisible );
802 if ( rDoc.IsTabProtected( nAdjSource ) )
803 rDoc.CopyTabProtection(nAdjSource, nNewTab);
805 if (mpNewNames)
807 const OUString& rName = (*mpNewNames)[i];
808 rDoc.RenameTab(nNewTab, rName);
812 RedoSdrUndoAction( pDrawUndo.get() ); // after the sheets are inserted
814 pViewShell->SetTabNo( nDestTab, true ); // after draw-undo
816 DoChange();
820 void ScUndoCopyTab::Repeat(SfxRepeatTarget& /* rTarget */)
822 // no Repeat ! ? !
825 bool ScUndoCopyTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
827 return false;
830 ScUndoTabColor::ScUndoTabColor(
831 ScDocShell* pNewDocShell, SCTAB nT, const Color& aOTabBgColor, const Color& aNTabBgColor) :
832 ScSimpleUndo( pNewDocShell )
834 ScUndoTabColorInfo aInfo(nT);
835 aInfo.maOldTabBgColor = aOTabBgColor;
836 aInfo.maNewTabBgColor = aNTabBgColor;
837 aTabColorList.push_back(aInfo);
840 ScUndoTabColor::ScUndoTabColor(
841 ScDocShell* pNewDocShell,
842 ScUndoTabColorInfo::List&& rUndoTabColorList) :
843 ScSimpleUndo(pNewDocShell),
844 aTabColorList(std::move(rUndoTabColorList))
848 ScUndoTabColor::~ScUndoTabColor()
852 OUString ScUndoTabColor::GetComment() const
854 if (aTabColorList.size() > 1)
855 return ScResId(STR_UNDO_SET_MULTI_TAB_BG_COLOR);
856 return ScResId(STR_UNDO_SET_TAB_BG_COLOR);
859 void ScUndoTabColor::DoChange(bool bUndoType) const
861 ScDocument& rDoc = pDocShell->GetDocument();
863 size_t nTabColorCount = aTabColorList.size();
864 for (size_t i = 0; i < nTabColorCount; ++i)
866 const ScUndoTabColorInfo& rTabColor = aTabColorList[i];
867 rDoc.SetTabBgColor(rTabColor.mnTabId,
868 bUndoType ? rTabColor.maOldTabBgColor : rTabColor.maNewTabBgColor);
871 pDocShell->PostPaintExtras();
872 ScDocShellModificator aModificator( *pDocShell );
873 aModificator.SetDocumentModified();
876 void ScUndoTabColor::Undo()
878 DoChange(true);
881 void ScUndoTabColor::Redo()
883 DoChange(false);
886 void ScUndoTabColor::Repeat(SfxRepeatTarget& /* rTarget */)
888 // makes no sense
891 bool ScUndoTabColor::CanRepeat(SfxRepeatTarget& /* rTarget */) const
893 return false;
896 ScUndoMakeScenario::ScUndoMakeScenario( ScDocShell* pNewDocShell,
897 SCTAB nSrc, SCTAB nDest,
898 OUString aN, OUString aC,
899 const Color& rCol, ScScenarioFlags nF,
900 const ScMarkData& rMark ) :
901 ScSimpleUndo( pNewDocShell ),
902 mpMarkData(new ScMarkData(rMark)),
903 nSrcTab( nSrc ),
904 nDestTab( nDest ),
905 aName(std::move( aN )),
906 aComment(std::move( aC )),
907 aColor( rCol ),
908 nFlags( nF )
910 pDrawUndo = GetSdrUndoAction( &pDocShell->GetDocument() );
913 ScUndoMakeScenario::~ScUndoMakeScenario()
915 pDrawUndo.reset();
918 OUString ScUndoMakeScenario::GetComment() const
920 return ScResId( STR_UNDO_MAKESCENARIO );
923 void ScUndoMakeScenario::Undo()
925 ScDocument& rDoc = pDocShell->GetDocument();
927 pDocShell->SetInUndo( true );
928 bDrawIsInUndo = true;
929 rDoc.DeleteTab( nDestTab );
930 bDrawIsInUndo = false;
931 pDocShell->SetInUndo( false );
933 DoSdrUndoAction( pDrawUndo.get(), &rDoc );
935 pDocShell->PostPaint(0,0,nDestTab,rDoc.MaxCol(),rDoc.MaxRow(),MAXTAB, PaintPartFlags::All);
936 pDocShell->PostDataChanged();
938 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
939 if (pViewShell)
940 pViewShell->SetTabNo( nSrcTab, true );
942 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
944 // SetTabNo(...,sal_True) for all views to sync with drawing layer pages
945 pDocShell->Broadcast( SfxHint( SfxHintId::ScForceSetTab ) );
948 void ScUndoMakeScenario::Redo()
950 SetViewMarkData(*mpMarkData);
952 RedoSdrUndoAction( pDrawUndo.get() ); // Draw Redo first
954 pDocShell->SetInUndo( true );
955 bDrawIsInUndo = true;
957 pDocShell->MakeScenario( nSrcTab, aName, aComment, aColor, nFlags, *mpMarkData, false );
959 bDrawIsInUndo = false;
960 pDocShell->SetInUndo( false );
962 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
963 if (pViewShell)
964 pViewShell->SetTabNo( nDestTab, true );
966 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
969 void ScUndoMakeScenario::Repeat(SfxRepeatTarget& rTarget)
971 if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
973 pViewTarget->GetViewShell()->MakeScenario( aName, aComment, aColor, nFlags );
977 bool ScUndoMakeScenario::CanRepeat(SfxRepeatTarget& rTarget) const
979 return dynamic_cast<const ScTabViewTarget*>( &rTarget) != nullptr;
982 ScUndoImportTab::ScUndoImportTab(ScDocShell* pShell,
983 SCTAB nNewTab, SCTAB nNewCount)
984 : ScSimpleUndo(pShell)
985 , nTab(nNewTab)
986 , nCount(nNewCount)
988 pDrawUndo = GetSdrUndoAction( &pDocShell->GetDocument() );
991 ScUndoImportTab::~ScUndoImportTab()
993 pDrawUndo.reset();
996 OUString ScUndoImportTab::GetComment() const
998 return ScResId( STR_UNDO_INSERT_TAB );
1001 void ScUndoImportTab::DoChange() const
1003 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1004 if (!pViewShell)
1005 return;
1007 ScDocument& rDoc = pDocShell->GetDocument();
1008 SCTAB nTabCount = rDoc.GetTableCount();
1009 if(nTab<nTabCount)
1011 pViewShell->SetTabNo(nTab,true);
1013 else
1015 pViewShell->SetTabNo(nTab-1,true);
1018 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) ); // Navigator
1019 pDocShell->PostPaint( 0,0,0, rDoc.MaxCol(),rDoc.MaxRow(),MAXTAB,
1020 PaintPartFlags::Grid | PaintPartFlags::Top | PaintPartFlags::Left | PaintPartFlags::Extras );
1023 void ScUndoImportTab::Undo()
1025 // Inserted range names, etc.
1027 SCTAB i;
1028 ScDocument& rDoc = pDocShell->GetDocument();
1029 bool bMakeRedo = !xRedoDoc;
1030 if (bMakeRedo)
1032 xRedoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1033 xRedoDoc->InitUndo(rDoc, nTab,nTab+nCount-1, true, true);
1035 OUString aOldName;
1036 for (i=0; i<nCount; i++)
1038 SCTAB nTabPos=nTab+i;
1040 rDoc.CopyToDocument(0,0,nTabPos, rDoc.MaxCol(),rDoc.MaxRow(),nTabPos, InsertDeleteFlags::ALL,false, *xRedoDoc);
1041 rDoc.GetName( nTabPos, aOldName );
1042 xRedoDoc->RenameTab(nTabPos, aOldName);
1043 xRedoDoc->SetTabBgColor(nTabPos, rDoc.GetTabBgColor(nTabPos));
1045 if ( rDoc.IsScenario(nTabPos) )
1047 xRedoDoc->SetScenario(nTabPos, true);
1048 OUString aComment;
1049 Color aColor;
1050 ScScenarioFlags nScenFlags;
1051 rDoc.GetScenarioData(nTabPos, aComment, aColor, nScenFlags );
1052 xRedoDoc->SetScenarioData(nTabPos, aComment, aColor, nScenFlags);
1053 bool bActive = rDoc.IsActiveScenario(nTabPos);
1054 xRedoDoc->SetActiveScenario(nTabPos, bActive);
1055 bool bVisible = rDoc.IsVisible(nTabPos);
1056 xRedoDoc->SetVisible(nTabPos, bVisible);
1059 if ( rDoc.IsTabProtected( nTabPos ) )
1060 xRedoDoc->SetTabProtection(nTabPos, rDoc.GetTabProtection(nTabPos));
1065 DoSdrUndoAction( pDrawUndo.get(), &rDoc ); // before the sheets are deleted
1067 bDrawIsInUndo = true;
1068 for (i=0; i<nCount; i++)
1069 rDoc.DeleteTab( nTab );
1070 bDrawIsInUndo = false;
1072 DoChange();
1075 void ScUndoImportTab::Redo()
1077 if (!xRedoDoc)
1079 OSL_FAIL("Where is my Redo Document?");
1080 return;
1083 ScDocument& rDoc = pDocShell->GetDocument();
1084 OUString aName;
1085 SCTAB i;
1086 for (i=0; i<nCount; i++) // first insert all sheets (#63304#)
1088 SCTAB nTabPos=nTab+i;
1089 xRedoDoc->GetName(nTabPos, aName);
1090 bDrawIsInUndo = true;
1091 rDoc.InsertTab(nTabPos,aName);
1092 bDrawIsInUndo = false;
1094 for (i=0; i<nCount; i++) // then copy into inserted sheets
1096 SCTAB nTabPos=nTab+i;
1097 xRedoDoc->CopyToDocument(0,0,nTabPos, rDoc.MaxCol(),rDoc.MaxRow(),nTabPos, InsertDeleteFlags::ALL,false, rDoc);
1098 rDoc.SetTabBgColor(nTabPos, xRedoDoc->GetTabBgColor(nTabPos));
1100 if (xRedoDoc->IsScenario(nTabPos))
1102 rDoc.SetScenario(nTabPos, true );
1103 OUString aComment;
1104 Color aColor;
1105 ScScenarioFlags nScenFlags;
1106 xRedoDoc->GetScenarioData(nTabPos, aComment, aColor, nScenFlags );
1107 rDoc.SetScenarioData(nTabPos, aComment, aColor, nScenFlags );
1108 bool bActive = xRedoDoc->IsActiveScenario(nTabPos);
1109 rDoc.SetActiveScenario(nTabPos, bActive );
1110 bool bVisible = xRedoDoc->IsVisible(nTabPos);
1111 rDoc.SetVisible(nTabPos,bVisible );
1114 if (xRedoDoc->IsTabProtected(nTabPos))
1115 rDoc.SetTabProtection(nTabPos, xRedoDoc->GetTabProtection(nTabPos));
1118 RedoSdrUndoAction( pDrawUndo.get() ); // after the sheets are inserted
1120 DoChange();
1123 void ScUndoImportTab::Repeat(SfxRepeatTarget& rTarget)
1125 if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
1126 pViewTarget->GetViewShell()->GetViewData().GetDispatcher().
1127 Execute(FID_INS_TABLE, SfxCallMode::SLOT | SfxCallMode::RECORD);
1130 bool ScUndoImportTab::CanRepeat(SfxRepeatTarget& rTarget) const
1132 return dynamic_cast<const ScTabViewTarget*>( &rTarget) != nullptr;
1135 ScUndoRemoveLink::ScUndoRemoveLink( ScDocShell* pShell, OUString _aDocName ) :
1136 ScSimpleUndo( pShell ),
1137 aDocName(std::move( _aDocName )),
1138 nRefreshDelay( 0 ),
1139 nCount( 0 )
1141 ScDocument& rDoc = pDocShell->GetDocument();
1142 SCTAB nTabCount = rDoc.GetTableCount();
1143 pTabs.reset( new SCTAB[nTabCount] );
1144 pModes.reset( new ScLinkMode[nTabCount] );
1145 pTabNames.reset( new OUString[nTabCount] );
1147 for (SCTAB i=0; i<nTabCount; i++)
1149 ScLinkMode nMode = rDoc.GetLinkMode(i);
1150 if (nMode != ScLinkMode::NONE)
1151 if (rDoc.GetLinkDoc(i) == aDocName)
1153 if (!nCount)
1155 aFltName = rDoc.GetLinkFlt(i);
1156 aOptions = rDoc.GetLinkOpt(i);
1157 nRefreshDelay = rDoc.GetLinkRefreshDelay(i);
1159 else
1161 OSL_ENSURE(aFltName == rDoc.GetLinkFlt(i) &&
1162 aOptions == rDoc.GetLinkOpt(i),
1163 "different Filter for a Document?");
1165 pTabs[nCount] = i;
1166 pModes[nCount] = nMode;
1167 pTabNames[nCount] = rDoc.GetLinkTab(i);
1168 ++nCount;
1173 ScUndoRemoveLink::~ScUndoRemoveLink()
1177 OUString ScUndoRemoveLink::GetComment() const
1179 return ScResId( STR_UNDO_REMOVELINK );
1182 void ScUndoRemoveLink::DoChange( bool bLink ) const
1184 ScDocument& rDoc = pDocShell->GetDocument();
1185 for (sal_uInt16 i=0; i<nCount; i++)
1186 if (bLink) // establish link
1187 rDoc.SetLink( pTabs[i], pModes[i], aDocName, aFltName, aOptions, pTabNames[i], nRefreshDelay );
1188 else // remove link
1189 rDoc.SetLink( pTabs[i], ScLinkMode::NONE, u""_ustr, u""_ustr, u""_ustr, u""_ustr, 0 );
1190 pDocShell->UpdateLinks();
1193 void ScUndoRemoveLink::Undo()
1195 DoChange( true );
1198 void ScUndoRemoveLink::Redo()
1200 DoChange( false );
1203 void ScUndoRemoveLink::Repeat(SfxRepeatTarget& /* rTarget */)
1205 // makes no sense
1208 bool ScUndoRemoveLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1210 return false;
1213 ScUndoShowHideTab::ScUndoShowHideTab( ScDocShell* pShell, std::vector<SCTAB>&& newUndoTabs, bool bNewShow ) :
1214 ScSimpleUndo( pShell ),
1215 undoTabs( std::move(newUndoTabs) ),
1216 bShow( bNewShow )
1220 ScUndoShowHideTab::~ScUndoShowHideTab()
1224 void ScUndoShowHideTab::DoChange( bool bShowP ) const
1226 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1227 if (!pViewShell)
1228 return;
1230 ScDocument& rDoc = pDocShell->GetDocument();
1231 for(const SCTAB& nTab : undoTabs)
1233 rDoc.SetVisible( nTab, bShowP );
1234 pViewShell->SetTabNo(nTab,true);
1237 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
1238 pDocShell->SetDocumentModified();
1241 void ScUndoShowHideTab::Undo()
1243 DoChange(!bShow);
1246 void ScUndoShowHideTab::Redo()
1248 DoChange(bShow);
1251 void ScUndoShowHideTab::Repeat(SfxRepeatTarget& rTarget)
1253 if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
1254 pViewTarget->GetViewShell()->GetViewData().GetDispatcher().
1255 Execute( bShow ? FID_TABLE_SHOW : FID_TABLE_HIDE,
1256 SfxCallMode::SLOT | SfxCallMode::RECORD);
1259 bool ScUndoShowHideTab::CanRepeat(SfxRepeatTarget& rTarget) const
1261 return dynamic_cast<const ScTabViewTarget*>( &rTarget) != nullptr;
1264 OUString ScUndoShowHideTab::GetComment() const
1266 TranslateId pId;
1267 if (undoTabs.size() > 1)
1269 pId = bShow ? STR_UNDO_SHOWTABS : STR_UNDO_HIDETABS;
1271 else
1273 pId = bShow ? STR_UNDO_SHOWTAB : STR_UNDO_HIDETAB;
1276 return ScResId(pId);
1279 ScUndoDocProtect::ScUndoDocProtect(ScDocShell* pShell, unique_ptr<ScDocProtection> && pProtectSettings) :
1280 ScSimpleUndo(pShell),
1281 mpProtectSettings(std::move(pProtectSettings))
1285 ScUndoDocProtect::~ScUndoDocProtect()
1289 void ScUndoDocProtect::DoProtect(bool bProtect)
1291 ScDocument& rDoc = pDocShell->GetDocument();
1293 if (bProtect)
1295 // set protection.
1296 unique_ptr<ScDocProtection> pCopy(new ScDocProtection(*mpProtectSettings));
1297 pCopy->setProtected(true);
1298 rDoc.SetDocProtection(pCopy.get());
1300 else
1302 // remove protection.
1303 rDoc.SetDocProtection(nullptr);
1306 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1307 if (pViewShell)
1309 pViewShell->UpdateLayerLocks();
1310 pViewShell->UpdateInputHandler(true); // so that input can be immediately entered again
1313 pDocShell->PostPaintGridAll();
1316 void ScUndoDocProtect::Undo()
1318 BeginUndo();
1319 DoProtect(!mpProtectSettings->isProtected());
1320 EndUndo();
1323 void ScUndoDocProtect::Redo()
1325 BeginRedo();
1326 DoProtect(mpProtectSettings->isProtected());
1327 EndRedo();
1330 void ScUndoDocProtect::Repeat(SfxRepeatTarget& /* rTarget */)
1332 // makes no sense
1335 bool ScUndoDocProtect::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1337 return false; // makes no sense
1340 OUString ScUndoDocProtect::GetComment() const
1342 TranslateId pId = mpProtectSettings->isProtected() ? STR_UNDO_PROTECT_DOC : STR_UNDO_UNPROTECT_DOC;
1343 return ScResId(pId);
1346 ScUndoTabProtect::ScUndoTabProtect(ScDocShell* pShell, SCTAB nTab, unique_ptr<ScTableProtection> && pProtectSettings) :
1347 ScSimpleUndo(pShell),
1348 mnTab(nTab),
1349 mpProtectSettings(std::move(pProtectSettings))
1353 ScUndoTabProtect::~ScUndoTabProtect()
1357 void ScUndoTabProtect::DoProtect(bool bProtect)
1359 ScDocument& rDoc = pDocShell->GetDocument();
1361 if (bProtect)
1363 // set protection.
1364 unique_ptr<ScTableProtection> pCopy(new ScTableProtection(*mpProtectSettings));
1365 pCopy->setProtected(true);
1366 rDoc.SetTabProtection(mnTab, pCopy.get());
1368 else
1370 // remove protection.
1371 rDoc.SetTabProtection(mnTab, nullptr);
1374 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1375 if (pViewShell)
1377 if (ScTabView* pTabView = pViewShell->GetViewData().GetView())
1378 pTabView->SetTabProtectionSymbol( mnTab, bProtect);
1379 pViewShell->UpdateLayerLocks();
1380 pViewShell->UpdateInputHandler(true); // so that input can be immediately entered again
1383 pDocShell->PostPaintGridAll();
1386 void ScUndoTabProtect::Undo()
1388 BeginUndo();
1389 DoProtect(!mpProtectSettings->isProtected());
1390 EndUndo();
1393 void ScUndoTabProtect::Redo()
1395 BeginRedo();
1396 DoProtect(mpProtectSettings->isProtected());
1397 EndRedo();
1400 void ScUndoTabProtect::Repeat(SfxRepeatTarget& /* rTarget */)
1402 // makes no sense
1405 bool ScUndoTabProtect::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1407 return false; // makes no sense
1410 OUString ScUndoTabProtect::GetComment() const
1412 TranslateId pId = mpProtectSettings->isProtected() ? STR_UNDO_PROTECT_TAB : STR_UNDO_UNPROTECT_TAB;
1413 return ScResId(pId);
1416 ScUndoPrintRange::ScUndoPrintRange( ScDocShell* pShell, SCTAB nNewTab,
1417 std::unique_ptr<ScPrintRangeSaver> pOld, std::unique_ptr<ScPrintRangeSaver> pNew ) :
1418 ScSimpleUndo( pShell ),
1419 nTab( nNewTab ),
1420 pOldRanges( std::move(pOld) ),
1421 pNewRanges( std::move(pNew) )
1425 ScUndoPrintRange::~ScUndoPrintRange()
1427 pOldRanges.reset();
1428 pNewRanges.reset();
1431 void ScUndoPrintRange::DoChange(bool bUndo)
1433 ScDocument& rDoc = pDocShell->GetDocument();
1434 if (bUndo)
1435 rDoc.RestorePrintRanges( *pOldRanges );
1436 else
1437 rDoc.RestorePrintRanges( *pNewRanges );
1439 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1440 if (pViewShell)
1441 pViewShell->SetTabNo( nTab );
1443 ScPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab ).UpdatePages();
1445 if (pViewShell && comphelper::LibreOfficeKit::isActive())
1447 tools::JsonWriter aJsonWriter;
1448 if (bUndo)
1449 pOldRanges->GetPrintRangesInfo(aJsonWriter);
1450 else
1451 pNewRanges->GetPrintRangesInfo(aJsonWriter);
1453 const OString message = aJsonWriter.finishAndGetAsOString();
1454 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_PRINT_RANGES, message);
1457 pDocShell->PostPaint( ScRange(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab), PaintPartFlags::Grid );
1460 void ScUndoPrintRange::Undo()
1462 BeginUndo();
1463 DoChange( true );
1464 EndUndo();
1467 void ScUndoPrintRange::Redo()
1469 BeginRedo();
1470 DoChange( false );
1471 EndRedo();
1474 void ScUndoPrintRange::Repeat(SfxRepeatTarget& /* rTarget */)
1476 // makes no sense
1479 bool ScUndoPrintRange::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1481 return false; // makes no sense
1484 OUString ScUndoPrintRange::GetComment() const
1486 return ScResId( STR_UNDO_PRINTRANGES );
1489 ScUndoScenarioFlags::ScUndoScenarioFlags(ScDocShell* pNewDocShell, SCTAB nT,
1490 OUString aON, OUString aNN, OUString aOC, OUString aNC,
1491 const Color& rOCol, const Color& rNCol, ScScenarioFlags nOF, ScScenarioFlags nNF) :
1492 ScSimpleUndo( pNewDocShell ),
1493 nTab ( nT ),
1494 aOldName (std::move( aON )),
1495 aNewName (std::move( aNN )),
1496 aOldComment (std::move( aOC )),
1497 aNewComment (std::move( aNC )),
1498 aOldColor ( rOCol ),
1499 aNewColor ( rNCol ),
1500 nOldFlags (nOF),
1501 nNewFlags (nNF)
1505 ScUndoScenarioFlags::~ScUndoScenarioFlags()
1509 OUString ScUndoScenarioFlags::GetComment() const
1511 return ScResId( STR_UNDO_EDITSCENARIO );
1514 void ScUndoScenarioFlags::Undo()
1516 ScDocument& rDoc = pDocShell->GetDocument();
1518 rDoc.RenameTab( nTab, aOldName );
1519 rDoc.SetScenarioData( nTab, aOldComment, aOldColor, nOldFlags );
1521 pDocShell->PostPaintGridAll();
1522 // The sheet name might be used in a formula ...
1523 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1524 if (pViewShell)
1525 pViewShell->UpdateInputHandler();
1527 if ( aOldName != aNewName )
1528 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
1531 void ScUndoScenarioFlags::Redo()
1533 ScDocument& rDoc = pDocShell->GetDocument();
1535 rDoc.RenameTab( nTab, aNewName );
1536 rDoc.SetScenarioData( nTab, aNewComment, aNewColor, nNewFlags );
1538 pDocShell->PostPaintGridAll();
1539 // The sheet name might be used in a formula ...
1540 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1541 if (pViewShell)
1542 pViewShell->UpdateInputHandler();
1544 if ( aOldName != aNewName )
1545 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScTablesChanged ) );
1548 void ScUndoScenarioFlags::Repeat(SfxRepeatTarget& /* rTarget */)
1550 // Repeat makes no sense
1553 bool ScUndoScenarioFlags::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1555 return false;
1558 // (move to different file?)
1559 ScUndoRenameObject::ScUndoRenameObject( ScDocShell* pNewDocShell, OUString aPN,
1560 OUString aON, OUString aNN ) :
1561 ScSimpleUndo( pNewDocShell ),
1562 aPersistName(std::move( aPN )),
1563 aOldName (std::move( aON )),
1564 aNewName (std::move( aNN ))
1568 ScUndoRenameObject::~ScUndoRenameObject()
1572 OUString ScUndoRenameObject::GetComment() const
1574 // string resource shared with title for dialog
1575 return ScResId(SCSTR_RENAMEOBJECT);
1578 SdrObject* ScUndoRenameObject::GetObject()
1580 ScDocument& rDoc = pDocShell->GetDocument();
1581 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
1582 if ( pDrawLayer )
1584 sal_uInt16 nCount = pDrawLayer->GetPageCount();
1585 for (sal_uInt16 nTab=0; nTab<nCount; nTab++)
1587 SdrPage* pPage = pDrawLayer->GetPage(nTab);
1588 assert(pPage && "Page ?");
1590 SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups );
1591 SdrObject* pObject = aIter.Next();
1592 while (pObject)
1594 if ( pObject->GetObjIdentifier() == SdrObjKind::OLE2 &&
1595 static_cast<SdrOle2Obj*>(pObject)->GetPersistName() == aPersistName )
1597 return pObject;
1600 pObject = aIter.Next();
1604 OSL_FAIL("Object not found");
1605 return nullptr;
1608 void ScUndoRenameObject::Undo()
1610 BeginUndo();
1611 SdrObject* pObj = GetObject();
1612 if ( pObj )
1613 pObj->SetName( aOldName );
1614 EndUndo();
1617 void ScUndoRenameObject::Redo()
1619 BeginRedo();
1620 SdrObject* pObj = GetObject();
1621 if ( pObj )
1622 pObj->SetName( aNewName );
1623 EndRedo();
1626 void ScUndoRenameObject::Repeat(SfxRepeatTarget& /* rTarget */)
1630 bool ScUndoRenameObject::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1632 return false;
1635 ScUndoLayoutRTL::ScUndoLayoutRTL( ScDocShell* pShell, SCTAB nNewTab, bool bNewRTL ) :
1636 ScSimpleUndo( pShell ),
1637 nTab( nNewTab ),
1638 bRTL( bNewRTL )
1642 ScUndoLayoutRTL::~ScUndoLayoutRTL()
1646 void ScUndoLayoutRTL::DoChange( bool bNew )
1648 pDocShell->SetInUndo( true );
1650 ScDocument& rDoc = pDocShell->GetDocument();
1651 rDoc.SetLayoutRTL(nTab, bNew, ScObjectHandling::MirrorRTLMode);
1653 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1654 if (pViewShell)
1655 pViewShell->SetTabNo(nTab,true);
1657 pDocShell->SetDocumentModified();
1659 pDocShell->SetInUndo( false );
1662 void ScUndoLayoutRTL::Undo()
1664 DoChange(!bRTL);
1667 void ScUndoLayoutRTL::Redo()
1669 DoChange(bRTL);
1672 void ScUndoLayoutRTL::Repeat(SfxRepeatTarget& rTarget)
1674 if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
1675 pViewTarget->GetViewShell()->GetViewData().GetDispatcher().
1676 Execute( FID_TAB_RTL, SfxCallMode::SLOT | SfxCallMode::RECORD);
1679 bool ScUndoLayoutRTL::CanRepeat(SfxRepeatTarget& rTarget) const
1681 return dynamic_cast<const ScTabViewTarget*>( &rTarget) != nullptr;
1684 OUString ScUndoLayoutRTL::GetComment() const
1686 return ScResId( STR_UNDO_TAB_RTL );
1689 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */