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 <com/sun/star/drawing/FillStyle.hpp>
21
22 #include <svl/lstner.hxx>
23
24 #include <svx/svdundo.hxx>
25 #include <svx/svdotext.hxx>
26 #include <svx/svdobj.hxx>
27 #include <svx/svdpage.hxx>
28 #include <svx/svdlayer.hxx>
29 #include <svx/svdmodel.hxx>
30 #include <svx/svdview.hxx>
31 #include <svx/xfillit0.hxx>
32 #include <svx/strings.hrc>
33 #include <svx/dialmgr.hxx>
34 #include <svx/scene3d.hxx>
35 #include <editeng/editdata.hxx>
36 #include <editeng/outlobj.hxx>
37 #include <svx/svdogrp.hxx>
38 #include <sdr/properties/itemsettools.hxx>
39 #include <svx/sdr/properties/properties.hxx>
40 #include <svx/svdocapt.hxx>
41 #include <svl/whiter.hxx>
42 #include <svx/e3dsceneupdater.hxx>
43 #include <svx/svdviter.hxx>
44 #include <svx/svdograf.hxx>
45 #include <sdr/contact/viewcontactofgraphic.hxx>
46 #include <svx/svdotable.hxx> // #i124389#
47 #include <vcl/svapp.hxx>
48 #include <sfx2/viewsh.hxx>
49 #include <svx/svdoashp.hxx>
50
51
52 // iterates over all views and unmarks this SdrObject if it is marked
ImplUnmarkObject(SdrObject * pObj)53 static void ImplUnmarkObject( SdrObject* pObj )
54 {
55 SdrViewIter aIter( pObj );
56 for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() )
57 {
58 pView->MarkObj( pObj, pView->GetSdrPageView(), true );
59 }
60 }
61
SdrUndoAction(SdrModel & rNewMod)62 SdrUndoAction::SdrUndoAction(SdrModel& rNewMod)
63 : rMod(rNewMod), m_nViewShellId(-1)
64 {
65 if (SfxViewShell* pViewShell = SfxViewShell::Current())
66 m_nViewShellId = pViewShell->GetViewShellId();
67 }
68
~SdrUndoAction()69 SdrUndoAction::~SdrUndoAction() {}
70
CanRepeat(SfxRepeatTarget & rView) const71 bool SdrUndoAction::CanRepeat(SfxRepeatTarget& rView) const
72 {
73 SdrView* pV=dynamic_cast<SdrView*>( &rView );
74 if (pV!=nullptr) return CanSdrRepeat(*pV);
75 return false;
76 }
77
Repeat(SfxRepeatTarget & rView)78 void SdrUndoAction::Repeat(SfxRepeatTarget& rView)
79 {
80 SdrView* pV=dynamic_cast<SdrView*>( &rView );
81 if (pV!=nullptr) SdrRepeat(*pV);
82 DBG_ASSERT(pV!=nullptr,"Repeat: SfxRepeatTarget that was handed over is not a SdrView");
83 }
84
GetRepeatComment(SfxRepeatTarget & rView) const85 OUString SdrUndoAction::GetRepeatComment(SfxRepeatTarget& rView) const
86 {
87 SdrView* pV=dynamic_cast<SdrView*>( &rView );
88 if (pV!=nullptr) return GetSdrRepeatComment();
89 return OUString();
90 }
91
CanSdrRepeat(SdrView &) const92 bool SdrUndoAction::CanSdrRepeat(SdrView& /*rView*/) const
93 {
94 return false;
95 }
96
SdrRepeat(SdrView &)97 void SdrUndoAction::SdrRepeat(SdrView& /*rView*/)
98 {
99 }
100
GetSdrRepeatComment() const101 OUString SdrUndoAction::GetSdrRepeatComment() const
102 {
103 return OUString();
104 }
105
GetViewShellId() const106 ViewShellId SdrUndoAction::GetViewShellId() const
107 {
108 return m_nViewShellId;
109 }
110
SdrUndoGroup(SdrModel & rNewMod)111 SdrUndoGroup::SdrUndoGroup(SdrModel& rNewMod)
112 : SdrUndoAction(rNewMod),
113 eFunction(SdrRepeatFunc::NONE)
114 {}
115
~SdrUndoGroup()116 SdrUndoGroup::~SdrUndoGroup()
117 {
118 }
119
AddAction(std::unique_ptr<SdrUndoAction> pAct)120 void SdrUndoGroup::AddAction(std::unique_ptr<SdrUndoAction> pAct)
121 {
122 maActions.push_back(std::move(pAct));
123 }
124
Undo()125 void SdrUndoGroup::Undo()
126 {
127 for (auto it = maActions.rbegin(); it != maActions.rend(); ++it)
128 (*it)->Undo();
129 }
130
Redo()131 void SdrUndoGroup::Redo()
132 {
133 for (std::unique_ptr<SdrUndoAction> & pAction : maActions)
134 pAction->Redo();
135 }
136
GetComment() const137 OUString SdrUndoGroup::GetComment() const
138 {
139 return aComment.replaceAll("%1", aObjDescription);
140 }
141
CanSdrRepeat(SdrView & rView) const142 bool SdrUndoGroup::CanSdrRepeat(SdrView& rView) const
143 {
144 switch (eFunction)
145 {
146 case SdrRepeatFunc::NONE : return false;
147 case SdrRepeatFunc::Delete : return rView.AreObjectsMarked();
148 case SdrRepeatFunc::CombinePolyPoly: return rView.IsCombinePossible();
149 case SdrRepeatFunc::CombineOnePoly : return rView.IsCombinePossible(true);
150 case SdrRepeatFunc::DismantlePolys : return rView.IsDismantlePossible();
151 case SdrRepeatFunc::DismantleLines : return rView.IsDismantlePossible(true);
152 case SdrRepeatFunc::ConvertToPoly : return rView.IsConvertToPolyObjPossible();
153 case SdrRepeatFunc::ConvertToPath : return rView.IsConvertToPathObjPossible();
154 case SdrRepeatFunc::Group : return rView.IsGroupPossible();
155 case SdrRepeatFunc::Ungroup : return rView.IsUnGroupPossible();
156 case SdrRepeatFunc::PutToTop : return rView.IsToTopPossible();
157 case SdrRepeatFunc::PutToBottom : return rView.IsToBtmPossible();
158 case SdrRepeatFunc::MoveToTop : return rView.IsToTopPossible();
159 case SdrRepeatFunc::MoveToBottom : return rView.IsToBtmPossible();
160 case SdrRepeatFunc::ReverseOrder : return rView.IsReverseOrderPossible();
161 case SdrRepeatFunc::ImportMtf : return rView.IsImportMtfPossible();
162 default: break;
163 } // switch
164 return false;
165 }
166
SdrRepeat(SdrView & rView)167 void SdrUndoGroup::SdrRepeat(SdrView& rView)
168 {
169 switch (eFunction)
170 {
171 case SdrRepeatFunc::NONE : break;
172 case SdrRepeatFunc::Delete : rView.DeleteMarked(); break;
173 case SdrRepeatFunc::CombinePolyPoly : rView.CombineMarkedObjects(false); break;
174 case SdrRepeatFunc::CombineOnePoly : rView.CombineMarkedObjects(); break;
175 case SdrRepeatFunc::DismantlePolys : rView.DismantleMarkedObjects(); break;
176 case SdrRepeatFunc::DismantleLines : rView.DismantleMarkedObjects(true); break;
177 case SdrRepeatFunc::ConvertToPoly : rView.ConvertMarkedToPolyObj(); break;
178 case SdrRepeatFunc::ConvertToPath : rView.ConvertMarkedToPathObj(false); break;
179 case SdrRepeatFunc::Group : rView.GroupMarked(); break;
180 case SdrRepeatFunc::Ungroup : rView.UnGroupMarked(); break;
181 case SdrRepeatFunc::PutToTop : rView.PutMarkedToTop(); break;
182 case SdrRepeatFunc::PutToBottom : rView.PutMarkedToBtm(); break;
183 case SdrRepeatFunc::MoveToTop : rView.MovMarkedToTop(); break;
184 case SdrRepeatFunc::MoveToBottom : rView.MovMarkedToBtm(); break;
185 case SdrRepeatFunc::ReverseOrder : rView.ReverseOrderOfMarked(); break;
186 case SdrRepeatFunc::ImportMtf : rView.DoImportMarkedMtf(); break;
187 default: break;
188 } // switch
189 }
190
GetSdrRepeatComment() const191 OUString SdrUndoGroup::GetSdrRepeatComment() const
192 {
193 return aComment.replaceAll("%1", SvxResId(STR_ObjNameSingulPlural));
194 }
195
SdrUndoObj(SdrObject & rNewObj)196 SdrUndoObj::SdrUndoObj(SdrObject& rNewObj)
197 : SdrUndoAction(rNewObj.getSdrModelFromSdrObject())
198 ,pObj(&rNewObj)
199 {
200 }
201
GetDescriptionStringForObject(const SdrObject & _rForObject,const char * pStrCacheID,bool bRepeat)202 OUString SdrUndoObj::GetDescriptionStringForObject( const SdrObject& _rForObject, const char* pStrCacheID, bool bRepeat )
203 {
204 const OUString rStr {SvxResId(pStrCacheID)};
205
206 const sal_Int32 nPos = rStr.indexOf("%1");
207 if (nPos < 0)
208 return rStr;
209
210 if (bRepeat)
211 return rStr.replaceAt(nPos, 2, SvxResId(STR_ObjNameSingulPlural));
212
213 return rStr.replaceAt(nPos, 2, _rForObject.TakeObjNameSingul());
214 }
215
ImpGetDescriptionStr(const char * pStrCacheID,bool bRepeat) const216 OUString SdrUndoObj::ImpGetDescriptionStr(const char* pStrCacheID, bool bRepeat) const
217 {
218 if ( pObj )
219 return GetDescriptionStringForObject( *pObj, pStrCacheID, bRepeat );
220 return OUString();
221 }
222
223 // common call method for possible change of the page when UNDO/REDO is triggered
ImpShowPageOfThisObject()224 void SdrUndoObj::ImpShowPageOfThisObject()
225 {
226 if(pObj && pObj->IsInserted() && pObj->getSdrPageFromSdrObject())
227 {
228 SdrHint aHint(SdrHintKind::SwitchToPage, *pObj, pObj->getSdrPageFromSdrObject());
229 pObj->getSdrModelFromSdrObject().Broadcast(aHint);
230 }
231 }
232
ensureStyleSheetInStyleSheetPool(SfxStyleSheetBasePool & rStyleSheetPool,SfxStyleSheet & rSheet)233 void SdrUndoAttrObj::ensureStyleSheetInStyleSheetPool(SfxStyleSheetBasePool& rStyleSheetPool, SfxStyleSheet& rSheet)
234 {
235 SfxStyleSheetBase* pThere = rStyleSheetPool.Find(rSheet.GetName(), rSheet.GetFamily());
236
237 if(!pThere)
238 {
239 // re-insert remembered style which was removed in the meantime. To do this
240 // without assertion, do it without parent and set parent after insertion
241 const OUString aParent(rSheet.GetParent());
242
243 rSheet.SetParent(OUString());
244 rStyleSheetPool.Insert(&rSheet);
245 rSheet.SetParent(aParent);
246 }
247 }
248
SdrUndoAttrObj(SdrObject & rNewObj,bool bStyleSheet1,bool bSaveText)249 SdrUndoAttrObj::SdrUndoAttrObj(SdrObject& rNewObj, bool bStyleSheet1, bool bSaveText)
250 : SdrUndoObj(rNewObj)
251 , mxUndoStyleSheet()
252 , mxRedoStyleSheet()
253 , bHaveToTakeRedoSet(true)
254 {
255 bStyleSheet = bStyleSheet1;
256
257 SdrObjList* pOL = rNewObj.GetSubList();
258 bool bIsGroup(pOL!=nullptr && pOL->GetObjCount());
259 bool bIs3DScene(bIsGroup && dynamic_cast< E3dScene* >(pObj) != nullptr);
260
261 if(bIsGroup)
262 {
263 // it's a group object!
264 pUndoGroup.reset(new SdrUndoGroup(pObj->getSdrModelFromSdrObject()));
265 const size_t nObjCount(pOL->GetObjCount());
266
267 for(size_t nObjNum = 0; nObjNum < nObjCount; ++nObjNum)
268 {
269 pUndoGroup->AddAction(
270 std::make_unique<SdrUndoAttrObj>(*pOL->GetObj(nObjNum), bStyleSheet1));
271 }
272 }
273
274 if(!bIsGroup || bIs3DScene)
275 {
276 pUndoSet.reset( new SfxItemSet(pObj->GetMergedItemSet()) );
277
278 if(bStyleSheet)
279 mxUndoStyleSheet = pObj->GetStyleSheet();
280
281 if(bSaveText)
282 {
283 auto p = pObj->GetOutlinerParaObject();
284 if(p)
285 pTextUndo.reset( new OutlinerParaObject(*p) );
286 }
287 }
288 }
289
~SdrUndoAttrObj()290 SdrUndoAttrObj::~SdrUndoAttrObj()
291 {
292 pUndoSet.reset();
293 pRedoSet.reset();
294 pUndoGroup.reset();
295 pTextUndo.reset();
296 pTextRedo.reset();
297 }
298
Undo()299 void SdrUndoAttrObj::Undo()
300 {
301 E3DModifySceneSnapRectUpdater aUpdater(pObj);
302 bool bIs3DScene(dynamic_cast< E3dScene* >(pObj) != nullptr);
303
304 // Trigger PageChangeCall
305 ImpShowPageOfThisObject();
306
307 if(!pUndoGroup || bIs3DScene)
308 {
309 if(bHaveToTakeRedoSet)
310 {
311 bHaveToTakeRedoSet = false;
312
313 pRedoSet.reset( new SfxItemSet(pObj->GetMergedItemSet()) );
314
315 if(bStyleSheet)
316 mxRedoStyleSheet = pObj->GetStyleSheet();
317
318 if(pTextUndo)
319 {
320 // #i8508#
321 auto p = pObj->GetOutlinerParaObject();
322 if(p)
323 pTextRedo.reset( new OutlinerParaObject(*p) );
324 }
325 }
326
327 if(bStyleSheet)
328 {
329 mxRedoStyleSheet = pObj->GetStyleSheet();
330 SfxStyleSheet* pSheet = dynamic_cast< SfxStyleSheet* >(mxUndoStyleSheet.get());
331
332 if(pSheet && pObj->getSdrModelFromSdrObject().GetStyleSheetPool())
333 {
334 ensureStyleSheetInStyleSheetPool(*pObj->getSdrModelFromSdrObject().GetStyleSheetPool(), *pSheet);
335 pObj->SetStyleSheet(pSheet, true);
336 }
337 else
338 {
339 OSL_ENSURE(false, "OOps, something went wrong in SdrUndoAttrObj (!)");
340 }
341 }
342
343 sdr::properties::ItemChangeBroadcaster aItemChange(*pObj);
344
345 // Since ClearItem sets back everything to normal
346 // it also sets fit-to-size text to non-fit-to-size text and
347 // switches on autogrowheight (the default). That may lead to
348 // losing the geometry size info for the object when it is
349 // laid out again from AdjustTextFrameWidthAndHeight(). This makes
350 // rescuing the size of the object necessary.
351 const tools::Rectangle aSnapRect = pObj->GetSnapRect();
352 // SdrObjCustomShape::NbcSetSnapRect needs logic instead of snap rect
353 const tools::Rectangle aLogicRect = pObj->GetLogicRect();
354
355 if(pUndoSet)
356 {
357 if(dynamic_cast<const SdrCaptionObj*>( pObj) != nullptr)
358 {
359 // do a more smooth item deletion here, else the text
360 // rect will be reformatted, especially when information regarding
361 // vertical text is changed. When clearing only set items it's
362 // slower, but safer regarding such information (it's not changed
363 // usually)
364 SfxWhichIter aIter(*pUndoSet);
365 sal_uInt16 nWhich(aIter.FirstWhich());
366
367 while(nWhich)
368 {
369 if(SfxItemState::SET != pUndoSet->GetItemState(nWhich, false))
370 {
371 pObj->ClearMergedItem(nWhich);
372 }
373
374 nWhich = aIter.NextWhich();
375 }
376 }
377 else
378 {
379 pObj->ClearMergedItem();
380 }
381
382 pObj->SetMergedItemSet(*pUndoSet);
383 }
384
385 // Restore previous size here when it was changed.
386 if(aSnapRect != pObj->GetSnapRect())
387 {
388 if(dynamic_cast<const SdrObjCustomShape*>(pObj))
389 pObj->NbcSetSnapRect(aLogicRect);
390 else
391 pObj->NbcSetSnapRect(aSnapRect);
392 }
393
394 pObj->GetProperties().BroadcastItemChange(aItemChange);
395
396 if(pTextUndo)
397 {
398 pObj->SetOutlinerParaObject(std::make_unique<OutlinerParaObject>(*pTextUndo));
399 }
400 }
401
402 if(pUndoGroup)
403 {
404 pUndoGroup->Undo();
405 }
406 }
407
Redo()408 void SdrUndoAttrObj::Redo()
409 {
410 E3DModifySceneSnapRectUpdater aUpdater(pObj);
411 bool bIs3DScene(dynamic_cast< E3dScene* >(pObj) != nullptr);
412
413 if(!pUndoGroup || bIs3DScene)
414 {
415 if(bStyleSheet)
416 {
417 mxUndoStyleSheet = pObj->GetStyleSheet();
418 SfxStyleSheet* pSheet = dynamic_cast< SfxStyleSheet* >(mxRedoStyleSheet.get());
419
420 if(pSheet && pObj->getSdrModelFromSdrObject().GetStyleSheetPool())
421 {
422 ensureStyleSheetInStyleSheetPool(*pObj->getSdrModelFromSdrObject().GetStyleSheetPool(), *pSheet);
423 pObj->SetStyleSheet(pSheet, true);
424 }
425 else
426 {
427 OSL_ENSURE(false, "OOps, something went wrong in SdrUndoAttrObj (!)");
428 }
429 }
430
431 sdr::properties::ItemChangeBroadcaster aItemChange(*pObj);
432
433 const tools::Rectangle aSnapRect = pObj->GetSnapRect();
434 const tools::Rectangle aLogicRect = pObj->GetLogicRect();
435
436 if(pRedoSet)
437 {
438 if(dynamic_cast<const SdrCaptionObj*>( pObj) != nullptr)
439 {
440 // do a more smooth item deletion here, else the text
441 // rect will be reformatted, especially when information regarding
442 // vertical text is changed. When clearing only set items it's
443 // slower, but safer regarding such information (it's not changed
444 // usually)
445 SfxWhichIter aIter(*pRedoSet);
446 sal_uInt16 nWhich(aIter.FirstWhich());
447
448 while(nWhich)
449 {
450 if(SfxItemState::SET != pRedoSet->GetItemState(nWhich, false))
451 {
452 pObj->ClearMergedItem(nWhich);
453 }
454
455 nWhich = aIter.NextWhich();
456 }
457 }
458 else
459 {
460 pObj->ClearMergedItem();
461 }
462
463 pObj->SetMergedItemSet(*pRedoSet);
464 }
465
466 // Restore previous size here when it was changed.
467 if(aSnapRect != pObj->GetSnapRect())
468 {
469 if(dynamic_cast<const SdrObjCustomShape*>(pObj))
470 pObj->NbcSetSnapRect(aLogicRect);
471 else
472 pObj->NbcSetSnapRect(aSnapRect);
473 }
474
475 pObj->GetProperties().BroadcastItemChange(aItemChange);
476
477 // #i8508#
478 if(pTextRedo)
479 {
480 pObj->SetOutlinerParaObject(std::make_unique<OutlinerParaObject>(*pTextRedo));
481 }
482 }
483
484 if(pUndoGroup)
485 {
486 pUndoGroup->Redo();
487 }
488
489 // Trigger PageChangeCall
490 ImpShowPageOfThisObject();
491 }
492
GetComment() const493 OUString SdrUndoAttrObj::GetComment() const
494 {
495 if(bStyleSheet)
496 {
497 return ImpGetDescriptionStr(STR_EditSetStylesheet);
498 }
499 else
500 {
501 return ImpGetDescriptionStr(STR_EditSetAttributes);
502 }
503 }
504
GetSdrRepeatComment() const505 OUString SdrUndoAttrObj::GetSdrRepeatComment() const
506 {
507 if(bStyleSheet)
508 {
509 return ImpGetDescriptionStr(STR_EditSetStylesheet, true);
510 }
511 else
512 {
513 return ImpGetDescriptionStr(STR_EditSetAttributes, true);
514 }
515 }
516
517
~SdrUndoMoveObj()518 SdrUndoMoveObj::~SdrUndoMoveObj() {}
519
Undo()520 void SdrUndoMoveObj::Undo()
521 {
522 // Trigger PageChangeCall
523 ImpShowPageOfThisObject();
524
525 pObj->Move(Size(-aDistance.Width(),-aDistance.Height()));
526 }
527
Redo()528 void SdrUndoMoveObj::Redo()
529 {
530 pObj->Move(Size(aDistance.Width(),aDistance.Height()));
531
532 // Trigger PageChangeCall
533 ImpShowPageOfThisObject();
534 }
535
GetComment() const536 OUString SdrUndoMoveObj::GetComment() const
537 {
538 return ImpGetDescriptionStr(STR_EditMove);
539 }
540
SdrRepeat(SdrView & rView)541 void SdrUndoMoveObj::SdrRepeat(SdrView& rView)
542 {
543 rView.MoveMarkedObj(aDistance);
544 }
545
CanSdrRepeat(SdrView & rView) const546 bool SdrUndoMoveObj::CanSdrRepeat(SdrView& rView) const
547 {
548 return rView.AreObjectsMarked();
549 }
550
GetSdrRepeatComment() const551 OUString SdrUndoMoveObj::GetSdrRepeatComment() const
552 {
553 return ImpGetDescriptionStr(STR_EditMove,true);
554 }
555
556
SdrUndoGeoObj(SdrObject & rNewObj)557 SdrUndoGeoObj::SdrUndoGeoObj(SdrObject& rNewObj)
558 : SdrUndoObj(rNewObj)
559 , mbSkipChangeLayout(false)
560 {
561 SdrObjList* pOL=rNewObj.GetSubList();
562 if (pOL!=nullptr && pOL->GetObjCount() && dynamic_cast<const E3dScene* >( &rNewObj) == nullptr)
563 {
564 // this is a group object!
565 // If this were 3D scene, we'd only add an Undo for the scene itself
566 // (which we do elsewhere).
567 pUndoGroup.reset(new SdrUndoGroup(pObj->getSdrModelFromSdrObject()));
568 const size_t nObjCount = pOL->GetObjCount();
569 for (size_t nObjNum = 0; nObjNum<nObjCount; ++nObjNum) {
570 pUndoGroup->AddAction(std::make_unique<SdrUndoGeoObj>(*pOL->GetObj(nObjNum)));
571 }
572 }
573 else
574 {
575 pUndoGeo.reset(pObj->GetGeoData());
576 }
577 }
578
~SdrUndoGeoObj()579 SdrUndoGeoObj::~SdrUndoGeoObj()
580 {
581 pUndoGeo.reset();
582 pRedoGeo.reset();
583 pUndoGroup.reset();
584 }
585
Undo()586 void SdrUndoGeoObj::Undo()
587 {
588 // Trigger PageChangeCall
589 ImpShowPageOfThisObject();
590
591 if(pUndoGroup)
592 {
593 pUndoGroup->Undo();
594
595 // only repaint, no objectchange
596 pObj->ActionChanged();
597 }
598 else
599 {
600 pRedoGeo.reset(pObj->GetGeoData());
601
602 auto pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pObj);
603 if (pTableObj && mbSkipChangeLayout)
604 pTableObj->SetSkipChangeLayout(true);
605 pObj->SetGeoData(*pUndoGeo);
606 if (pTableObj && mbSkipChangeLayout)
607 pTableObj->SetSkipChangeLayout(false);
608 }
609 }
610
Redo()611 void SdrUndoGeoObj::Redo()
612 {
613 if(pUndoGroup)
614 {
615 pUndoGroup->Redo();
616
617 // only repaint, no objectchange
618 pObj->ActionChanged();
619 }
620 else
621 {
622 pUndoGeo.reset(pObj->GetGeoData());
623 pObj->SetGeoData(*pRedoGeo);
624 }
625
626 // Trigger PageChangeCall
627 ImpShowPageOfThisObject();
628 }
629
GetComment() const630 OUString SdrUndoGeoObj::GetComment() const
631 {
632 return ImpGetDescriptionStr(STR_DragMethObjOwn);
633 }
634
635
SdrUndoObjList(SdrObject & rNewObj,bool bOrdNumDirect)636 SdrUndoObjList::SdrUndoObjList(SdrObject& rNewObj, bool bOrdNumDirect)
637 : SdrUndoObj(rNewObj)
638 , bOwner(false)
639 {
640 pObjList=pObj->getParentSdrObjListFromSdrObject();
641 if (bOrdNumDirect)
642 {
643 nOrdNum=pObj->GetOrdNumDirect();
644 }
645 else
646 {
647 nOrdNum=pObj->GetOrdNum();
648 }
649 }
650
~SdrUndoObjList()651 SdrUndoObjList::~SdrUndoObjList()
652 {
653 SolarMutexGuard aGuard;
654
655 if (pObj!=nullptr && IsOwner())
656 {
657 // Attribute have to go back to the regular Pool
658 SetOwner(false);
659
660 // now delete
661 SdrObject::Free( pObj );
662 }
663 }
664
SetOwner(bool bNew)665 void SdrUndoObjList::SetOwner(bool bNew)
666 {
667 bOwner = bNew;
668 }
669
670
Undo()671 void SdrUndoRemoveObj::Undo()
672 {
673 // Trigger PageChangeCall
674 ImpShowPageOfThisObject();
675
676 DBG_ASSERT(!pObj->IsInserted(),"UndoRemoveObj: pObj has already been inserted.");
677 if (!pObj->IsInserted())
678 {
679 // #i11426#
680 // For UNDOs in Calc/Writer it is necessary to adapt the anchor
681 // position of the target object.
682 Point aOwnerAnchorPos(0, 0);
683
684 if (dynamic_cast< const SdrObjGroup* >(pObjList->getSdrObjectFromSdrObjList()) != nullptr)
685 {
686 aOwnerAnchorPos = pObjList->getSdrObjectFromSdrObjList()->GetAnchorPos();
687 }
688
689 E3DModifySceneSnapRectUpdater aUpdater(pObjList->getSdrObjectFromSdrObjList());
690 pObjList->InsertObject(pObj,nOrdNum);
691
692 // #i11426#
693 if(aOwnerAnchorPos.X() || aOwnerAnchorPos.Y())
694 {
695 pObj->NbcSetAnchorPos(aOwnerAnchorPos);
696 }
697 }
698 }
699
Redo()700 void SdrUndoRemoveObj::Redo()
701 {
702 DBG_ASSERT(pObj->IsInserted(),"RedoRemoveObj: pObj is not inserted.");
703 if (pObj->IsInserted())
704 {
705 ImplUnmarkObject( pObj );
706 E3DModifySceneSnapRectUpdater aUpdater(pObj);
707 pObjList->RemoveObject(pObj->GetOrdNum());
708 }
709
710 // Trigger PageChangeCall
711 ImpShowPageOfThisObject();
712 }
713
~SdrUndoRemoveObj()714 SdrUndoRemoveObj::~SdrUndoRemoveObj()
715 {
716 }
717
718
Undo()719 void SdrUndoInsertObj::Undo()
720 {
721 // Trigger PageChangeCall
722 ImpShowPageOfThisObject();
723
724 DBG_ASSERT(pObj->IsInserted(),"UndoInsertObj: pObj is not inserted.");
725 if (pObj->IsInserted())
726 {
727 ImplUnmarkObject( pObj );
728
729 SdrObject* pChkObj= pObjList->RemoveObject(pObj->GetOrdNum());
730 DBG_ASSERT(pChkObj==pObj,"UndoInsertObj: RemoveObjNum!=pObj");
731 }
732 }
733
Redo()734 void SdrUndoInsertObj::Redo()
735 {
736 DBG_ASSERT(!pObj->IsInserted(),"RedoInsertObj: pObj is already inserted");
737 if (!pObj->IsInserted())
738 {
739 // Restore anchor position of an object,
740 // which becomes a member of a group, because its cleared in method
741 // <InsertObject(..)>. Needed for correct Redo in Writer. (#i45952#)
742 Point aAnchorPos( 0, 0 );
743
744 if (dynamic_cast<const SdrObjGroup*>(pObjList->getSdrObjectFromSdrObjList()) != nullptr)
745 {
746 aAnchorPos = pObj->GetAnchorPos();
747 }
748
749 pObjList->InsertObject(pObj,nOrdNum);
750
751 // Arcs lose position when grouped (#i45952#)
752 if ( aAnchorPos.X() || aAnchorPos.Y() )
753 {
754 pObj->NbcSetAnchorPos( aAnchorPos );
755 }
756 }
757
758 // Trigger PageChangeCall
759 ImpShowPageOfThisObject();
760 }
761
SdrUndoDelObj(SdrObject & rNewObj,bool bOrdNumDirect)762 SdrUndoDelObj::SdrUndoDelObj(SdrObject& rNewObj, bool bOrdNumDirect)
763 : SdrUndoRemoveObj(rNewObj,bOrdNumDirect)
764 {
765 SetOwner(true);
766 }
767
Undo()768 void SdrUndoDelObj::Undo()
769 {
770 SdrUndoRemoveObj::Undo();
771 DBG_ASSERT(IsOwner(),"UndoDeleteObj: pObj does not belong to UndoAction");
772 SetOwner(false);
773 }
774
Redo()775 void SdrUndoDelObj::Redo()
776 {
777 SdrUndoRemoveObj::Redo();
778 DBG_ASSERT(!IsOwner(),"RedoDeleteObj: pObj already belongs to UndoAction");
779 SetOwner(true);
780 }
781
GetComment() const782 OUString SdrUndoDelObj::GetComment() const
783 {
784 return ImpGetDescriptionStr(STR_EditDelete);
785 }
786
SdrRepeat(SdrView & rView)787 void SdrUndoDelObj::SdrRepeat(SdrView& rView)
788 {
789 rView.DeleteMarked();
790 }
791
CanSdrRepeat(SdrView & rView) const792 bool SdrUndoDelObj::CanSdrRepeat(SdrView& rView) const
793 {
794 return rView.AreObjectsMarked();
795 }
796
GetSdrRepeatComment() const797 OUString SdrUndoDelObj::GetSdrRepeatComment() const
798 {
799 return ImpGetDescriptionStr(STR_EditDelete,true);
800 }
801
802
Undo()803 void SdrUndoNewObj::Undo()
804 {
805 SdrUndoInsertObj::Undo();
806 DBG_ASSERT(!IsOwner(),"RedoNewObj: pObj already belongs to UndoAction");
807 SetOwner(true);
808 }
809
Redo()810 void SdrUndoNewObj::Redo()
811 {
812 SdrUndoInsertObj::Redo();
813 DBG_ASSERT(IsOwner(),"RedoNewObj: pObj does not belong to UndoAction");
814 SetOwner(false);
815 }
816
GetComment(const SdrObject & _rForObject)817 OUString SdrUndoNewObj::GetComment( const SdrObject& _rForObject )
818 {
819 return GetDescriptionStringForObject( _rForObject, STR_UndoInsertObj );
820 }
821
GetComment() const822 OUString SdrUndoNewObj::GetComment() const
823 {
824 return ImpGetDescriptionStr(STR_UndoInsertObj);
825 }
826
SdrUndoReplaceObj(SdrObject & rOldObj1,SdrObject & rNewObj1)827 SdrUndoReplaceObj::SdrUndoReplaceObj(SdrObject& rOldObj1, SdrObject& rNewObj1)
828 : SdrUndoObj(rOldObj1)
829 , bOldOwner(false)
830 , bNewOwner(false)
831 , pNewObj(&rNewObj1)
832 {
833 SetOldOwner(true);
834 pObjList=pObj->getParentSdrObjListFromSdrObject();
835 }
836
~SdrUndoReplaceObj()837 SdrUndoReplaceObj::~SdrUndoReplaceObj()
838 {
839 if (pObj!=nullptr && IsOldOwner())
840 {
841 // Attribute have to go back into the Pool
842 SetOldOwner(false);
843
844 // now delete
845 SdrObject::Free( pObj );
846 }
847 if (pNewObj!=nullptr && IsNewOwner())
848 {
849 // Attribute have to go back into the Pool
850 SetNewOwner(false);
851
852 // now delete
853 SdrObject::Free( pNewObj );
854 }
855 }
856
Undo()857 void SdrUndoReplaceObj::Undo()
858 {
859 // Trigger PageChangeCall
860 ImpShowPageOfThisObject();
861
862 if (IsOldOwner() && !IsNewOwner())
863 {
864 DBG_ASSERT(!pObj->IsInserted(),"SdrUndoReplaceObj::Undo(): Old object is already inserted!");
865 DBG_ASSERT(pNewObj->IsInserted(),"SdrUndoReplaceObj::Undo(): New object is not inserted!");
866 SetOldOwner(false);
867 SetNewOwner(true);
868
869 ImplUnmarkObject( pNewObj );
870 pObjList->ReplaceObject(pObj,pNewObj->GetOrdNum());
871 }
872 else
873 {
874 OSL_FAIL("SdrUndoReplaceObj::Undo(): Wrong IsMine flags. Did you call Undo twice?");
875 }
876 }
877
Redo()878 void SdrUndoReplaceObj::Redo()
879 {
880 if (!IsOldOwner() && IsNewOwner())
881 {
882 DBG_ASSERT(!pNewObj->IsInserted(),"SdrUndoReplaceObj::Redo(): New object is already inserted!!");
883 DBG_ASSERT(pObj->IsInserted(),"SdrUndoReplaceObj::Redo(): Old object is not inserted!!");
884 SetOldOwner(true);
885 SetNewOwner(false);
886
887 ImplUnmarkObject( pObj );
888 pObjList->ReplaceObject(pNewObj,pObj->GetOrdNum());
889
890 }
891 else
892 {
893 OSL_FAIL("SdrUndoReplaceObj::Redo(): Wrong IsMine flags. Did you call Redo twice?");
894 }
895
896 // Trigger PageChangeCall
897 ImpShowPageOfThisObject();
898 }
899
SetNewOwner(bool bNew)900 void SdrUndoReplaceObj::SetNewOwner(bool bNew)
901 {
902 bNewOwner = bNew;
903 }
904
SetOldOwner(bool bNew)905 void SdrUndoReplaceObj::SetOldOwner(bool bNew)
906 {
907 bOldOwner = bNew;
908 }
909
910
GetComment() const911 OUString SdrUndoCopyObj::GetComment() const
912 {
913 return ImpGetDescriptionStr(STR_UndoCopyObj);
914 }
915
916
917 // #i11702#
918
SdrUndoObjectLayerChange(SdrObject & rObj,SdrLayerID aOldLayer,SdrLayerID aNewLayer)919 SdrUndoObjectLayerChange::SdrUndoObjectLayerChange(SdrObject& rObj, SdrLayerID aOldLayer, SdrLayerID aNewLayer)
920 : SdrUndoObj(rObj)
921 , maOldLayer(aOldLayer)
922 , maNewLayer(aNewLayer)
923 {
924 }
925
Undo()926 void SdrUndoObjectLayerChange::Undo()
927 {
928 ImpShowPageOfThisObject();
929 pObj->SetLayer(maOldLayer);
930 }
931
Redo()932 void SdrUndoObjectLayerChange::Redo()
933 {
934 pObj->SetLayer(maNewLayer);
935 ImpShowPageOfThisObject();
936 }
937
938
SdrUndoObjOrdNum(SdrObject & rNewObj,sal_uInt32 nOldOrdNum1,sal_uInt32 nNewOrdNum1)939 SdrUndoObjOrdNum::SdrUndoObjOrdNum(SdrObject& rNewObj, sal_uInt32 nOldOrdNum1, sal_uInt32 nNewOrdNum1)
940 : SdrUndoObj(rNewObj)
941 , nOldOrdNum(nOldOrdNum1)
942 , nNewOrdNum(nNewOrdNum1)
943 {
944 }
945
Undo()946 void SdrUndoObjOrdNum::Undo()
947 {
948 // Trigger PageChangeCall
949 ImpShowPageOfThisObject();
950
951 SdrObjList* pOL=pObj->getParentSdrObjListFromSdrObject();
952 if (pOL==nullptr)
953 {
954 OSL_FAIL("UndoObjOrdNum: pObj does not have an ObjList.");
955 return;
956 }
957 pOL->SetObjectOrdNum(nNewOrdNum,nOldOrdNum);
958 }
959
Redo()960 void SdrUndoObjOrdNum::Redo()
961 {
962 SdrObjList* pOL=pObj->getParentSdrObjListFromSdrObject();
963 if (pOL==nullptr)
964 {
965 OSL_FAIL("RedoObjOrdNum: pObj does not have an ObjList.");
966 return;
967 }
968 pOL->SetObjectOrdNum(nOldOrdNum,nNewOrdNum);
969
970 // Trigger PageChangeCall
971 ImpShowPageOfThisObject();
972 }
973
GetComment() const974 OUString SdrUndoObjOrdNum::GetComment() const
975 {
976 return ImpGetDescriptionStr(STR_UndoObjOrdNum);
977 }
978
979
SdrUndoObjSetText(SdrObject & rNewObj,sal_Int32 nText)980 SdrUndoObjSetText::SdrUndoObjSetText(SdrObject& rNewObj, sal_Int32 nText)
981 : SdrUndoObj(rNewObj)
982 , bNewTextAvailable(false)
983 , bEmptyPresObj(false)
984 , mnText(nText)
985 {
986 SdrText* pText = static_cast< SdrTextObj*>( &rNewObj )->getText(mnText);
987 if( pText && pText->GetOutlinerParaObject() )
988 pOldText.reset( new OutlinerParaObject(*pText->GetOutlinerParaObject()) );
989
990 bEmptyPresObj = rNewObj.IsEmptyPresObj();
991 }
992
~SdrUndoObjSetText()993 SdrUndoObjSetText::~SdrUndoObjSetText()
994 {
995 pOldText.reset();
996 pNewText.reset();
997 }
998
AfterSetText()999 void SdrUndoObjSetText::AfterSetText()
1000 {
1001 if (!bNewTextAvailable)
1002 {
1003 SdrText* pText = static_cast< SdrTextObj*>( pObj )->getText(mnText);
1004 if( pText && pText->GetOutlinerParaObject() )
1005 pNewText.reset( new OutlinerParaObject(*pText->GetOutlinerParaObject()) );
1006 bNewTextAvailable=true;
1007 }
1008 }
1009
Undo()1010 void SdrUndoObjSetText::Undo()
1011 {
1012 // only works with SdrTextObj
1013 SdrTextObj* pTarget = dynamic_cast< SdrTextObj* >(pObj);
1014
1015 if(!pTarget)
1016 {
1017 OSL_ENSURE(false, "SdrUndoObjSetText::Undo with SdrObject not based on SdrTextObj (!)");
1018 return;
1019 }
1020
1021 // Trigger PageChangeCall
1022 ImpShowPageOfThisObject();
1023
1024 // save old text for Redo
1025 if(!bNewTextAvailable)
1026 {
1027 AfterSetText();
1028 }
1029
1030 SdrText* pText = pTarget->getText(mnText);
1031 if (pText)
1032 {
1033 // copy text for Undo, because the original now belongs to SetOutlinerParaObject()
1034 std::unique_ptr<OutlinerParaObject> pText1( pOldText ? new OutlinerParaObject(*pOldText) : nullptr );
1035 pTarget->NbcSetOutlinerParaObjectForText(std::move(pText1), pText);
1036 }
1037
1038 pTarget->SetEmptyPresObj(bEmptyPresObj);
1039 pTarget->ActionChanged();
1040
1041 // #i124389# if it's a table, also need to relayout TextFrame
1042 if(dynamic_cast< sdr::table::SdrTableObj* >(pTarget) != nullptr)
1043 {
1044 pTarget->NbcAdjustTextFrameWidthAndHeight();
1045 }
1046
1047 // #i122410# SetOutlinerParaObject at SdrText does not trigger a
1048 // BroadcastObjectChange, but it is needed to make evtl. SlideSorters
1049 // update their preview.
1050 pTarget->BroadcastObjectChange();
1051 }
1052
Redo()1053 void SdrUndoObjSetText::Redo()
1054 {
1055 // only works with SdrTextObj
1056 SdrTextObj* pTarget = dynamic_cast< SdrTextObj* >(pObj);
1057
1058 if(!pTarget)
1059 {
1060 OSL_ENSURE(false, "SdrUndoObjSetText::Redo with SdrObject not based on SdrTextObj (!)");
1061 return;
1062 }
1063
1064 SdrText* pText = pTarget->getText(mnText);
1065 if (pText)
1066 {
1067 // copy text for Undo, because the original now belongs to SetOutlinerParaObject()
1068 std::unique_ptr<OutlinerParaObject> pText1( pNewText ? new OutlinerParaObject(*pNewText) : nullptr );
1069 pTarget->NbcSetOutlinerParaObjectForText( std::move(pText1), pText );
1070 }
1071
1072 pTarget->ActionChanged();
1073
1074 // #i124389# if it's a table, also need to relayout TextFrame
1075 if(dynamic_cast< sdr::table::SdrTableObj* >(pTarget) != nullptr)
1076 {
1077 pTarget->NbcAdjustTextFrameWidthAndHeight();
1078 }
1079
1080 // #i122410# NbcSetOutlinerParaObjectForText at SdrTextObj does not trigger a
1081 // BroadcastObjectChange, but it is needed to make evtl. SlideSorters
1082 // update their preview.
1083 pTarget->BroadcastObjectChange();
1084
1085 // Trigger PageChangeCall
1086 ImpShowPageOfThisObject();
1087 }
1088
GetComment() const1089 OUString SdrUndoObjSetText::GetComment() const
1090 {
1091 return ImpGetDescriptionStr(STR_UndoObjSetText);
1092 }
1093
GetSdrRepeatComment() const1094 OUString SdrUndoObjSetText::GetSdrRepeatComment() const
1095 {
1096 return ImpGetDescriptionStr(STR_UndoObjSetText);
1097 }
1098
SdrRepeat(SdrView & rView)1099 void SdrUndoObjSetText::SdrRepeat(SdrView& rView)
1100 {
1101 if (bNewTextAvailable && rView.AreObjectsMarked())
1102 {
1103 const SdrMarkList& rML=rView.GetMarkedObjectList();
1104
1105 const bool bUndo = rView.IsUndoEnabled();
1106 if( bUndo )
1107 {
1108 OUString aStr = ImpGetDescriptionStr(STR_UndoObjSetText);
1109 rView.BegUndo(aStr);
1110 }
1111
1112 const size_t nCount=rML.GetMarkCount();
1113 for (size_t nm=0; nm<nCount; ++nm)
1114 {
1115 SdrObject* pObj2=rML.GetMark(nm)->GetMarkedSdrObj();
1116 SdrTextObj* pTextObj=dynamic_cast<SdrTextObj*>( pObj2 );
1117 if (pTextObj!=nullptr)
1118 {
1119 if( bUndo )
1120 rView.AddUndo(std::make_unique<SdrUndoObjSetText>(*pTextObj,0));
1121
1122 std::unique_ptr<OutlinerParaObject> pText1;
1123 if (pNewText)
1124 pText1.reset(new OutlinerParaObject(*pNewText));
1125 pTextObj->SetOutlinerParaObject(std::move(pText1));
1126 }
1127 }
1128
1129 if( bUndo )
1130 rView.EndUndo();
1131 }
1132 }
1133
CanSdrRepeat(SdrView & rView) const1134 bool SdrUndoObjSetText::CanSdrRepeat(SdrView& rView) const
1135 {
1136 bool bOk = false;
1137 if (bNewTextAvailable && rView.AreObjectsMarked()) {
1138 bOk=true;
1139 }
1140 return bOk;
1141 }
1142
1143 // Undo/Redo for setting object's name (#i73249#)
SdrUndoObjStrAttr(SdrObject & rNewObj,const ObjStrAttrType eObjStrAttr,const OUString & sOldStr,const OUString & sNewStr)1144 SdrUndoObjStrAttr::SdrUndoObjStrAttr( SdrObject& rNewObj,
1145 const ObjStrAttrType eObjStrAttr,
1146 const OUString& sOldStr,
1147 const OUString& sNewStr)
1148 : SdrUndoObj( rNewObj )
1149 , meObjStrAttr( eObjStrAttr )
1150 , msOldStr( sOldStr )
1151 , msNewStr( sNewStr )
1152 {
1153 }
1154
Undo()1155 void SdrUndoObjStrAttr::Undo()
1156 {
1157 ImpShowPageOfThisObject();
1158
1159 switch ( meObjStrAttr )
1160 {
1161 case ObjStrAttrType::Name:
1162 pObj->SetName( msOldStr );
1163 break;
1164 case ObjStrAttrType::Title:
1165 pObj->SetTitle( msOldStr );
1166 break;
1167 case ObjStrAttrType::Description:
1168 pObj->SetDescription( msOldStr );
1169 break;
1170 }
1171 }
1172
Redo()1173 void SdrUndoObjStrAttr::Redo()
1174 {
1175 switch ( meObjStrAttr )
1176 {
1177 case ObjStrAttrType::Name:
1178 pObj->SetName( msNewStr );
1179 break;
1180 case ObjStrAttrType::Title:
1181 pObj->SetTitle( msNewStr );
1182 break;
1183 case ObjStrAttrType::Description:
1184 pObj->SetDescription( msNewStr );
1185 break;
1186 }
1187
1188 ImpShowPageOfThisObject();
1189 }
1190
GetComment() const1191 OUString SdrUndoObjStrAttr::GetComment() const
1192 {
1193 OUString aStr;
1194 switch ( meObjStrAttr )
1195 {
1196 case ObjStrAttrType::Name:
1197 aStr = ImpGetDescriptionStr( STR_UndoObjName) +
1198 " '" + msNewStr + "'";
1199 break;
1200 case ObjStrAttrType::Title:
1201 aStr = ImpGetDescriptionStr( STR_UndoObjTitle );
1202 break;
1203 case ObjStrAttrType::Description:
1204 aStr = ImpGetDescriptionStr( STR_UndoObjDescription );
1205 break;
1206 }
1207
1208 return aStr;
1209 }
1210
1211
SdrUndoLayer(sal_uInt16 nLayerNum,SdrLayerAdmin & rNewLayerAdmin,SdrModel & rNewModel)1212 SdrUndoLayer::SdrUndoLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel)
1213 : SdrUndoAction(rNewModel)
1214 , pLayer(rNewLayerAdmin.GetLayer(nLayerNum))
1215 , pLayerAdmin(&rNewLayerAdmin)
1216 , nNum(nLayerNum)
1217 , bItsMine(false)
1218 {
1219 }
1220
~SdrUndoLayer()1221 SdrUndoLayer::~SdrUndoLayer()
1222 {
1223 if (bItsMine)
1224 {
1225 delete pLayer;
1226 }
1227 }
1228
1229
Undo()1230 void SdrUndoNewLayer::Undo()
1231 {
1232 DBG_ASSERT(!bItsMine,"SdrUndoNewLayer::Undo(): Layer already belongs to UndoAction.");
1233 bItsMine=true;
1234 SdrLayer* pCmpLayer= pLayerAdmin->RemoveLayer(nNum).release();
1235 DBG_ASSERT(pCmpLayer==pLayer,"SdrUndoNewLayer::Undo(): Removed layer is != pLayer.");
1236 }
1237
Redo()1238 void SdrUndoNewLayer::Redo()
1239 {
1240 DBG_ASSERT(bItsMine,"SdrUndoNewLayer::Undo(): Layer does not belong to UndoAction.");
1241 bItsMine=false;
1242 pLayerAdmin->InsertLayer(std::unique_ptr<SdrLayer>(pLayer),nNum);
1243 }
1244
GetComment() const1245 OUString SdrUndoNewLayer::GetComment() const
1246 {
1247 return SvxResId(STR_UndoNewLayer);
1248 }
1249
1250
Undo()1251 void SdrUndoDelLayer::Undo()
1252 {
1253 DBG_ASSERT(bItsMine,"SdrUndoDelLayer::Undo(): Layer does not belong to UndoAction.");
1254 bItsMine=false;
1255 pLayerAdmin->InsertLayer(std::unique_ptr<SdrLayer>(pLayer),nNum);
1256 }
1257
Redo()1258 void SdrUndoDelLayer::Redo()
1259 {
1260 DBG_ASSERT(!bItsMine,"SdrUndoDelLayer::Undo(): Layer already belongs to UndoAction.");
1261 bItsMine=true;
1262 SdrLayer* pCmpLayer= pLayerAdmin->RemoveLayer(nNum).release();
1263 DBG_ASSERT(pCmpLayer==pLayer,"SdrUndoDelLayer::Redo(): Removed layer is != pLayer.");
1264 }
1265
GetComment() const1266 OUString SdrUndoDelLayer::GetComment() const
1267 {
1268 return SvxResId(STR_UndoDelLayer);
1269 }
1270
1271
SdrUndoPage(SdrPage & rNewPg)1272 SdrUndoPage::SdrUndoPage(SdrPage& rNewPg)
1273 : SdrUndoAction(rNewPg.getSdrModelFromSdrPage())
1274 ,mrPage(rNewPg)
1275 {
1276 }
1277
ImpInsertPage(sal_uInt16 nNum)1278 void SdrUndoPage::ImpInsertPage(sal_uInt16 nNum)
1279 {
1280 DBG_ASSERT(!mrPage.IsInserted(),"SdrUndoPage::ImpInsertPage(): mrPage is already inserted.");
1281 if (!mrPage.IsInserted())
1282 {
1283 if (mrPage.IsMasterPage())
1284 {
1285 rMod.InsertMasterPage(&mrPage,nNum);
1286 }
1287 else
1288 {
1289 rMod.InsertPage(&mrPage,nNum);
1290 }
1291 }
1292 }
1293
ImpRemovePage(sal_uInt16 nNum)1294 void SdrUndoPage::ImpRemovePage(sal_uInt16 nNum)
1295 {
1296 DBG_ASSERT(mrPage.IsInserted(),"SdrUndoPage::ImpRemovePage(): mrPage is not inserted.");
1297 if (mrPage.IsInserted())
1298 {
1299 SdrPage* pChkPg=nullptr;
1300 if (mrPage.IsMasterPage())
1301 {
1302 pChkPg=rMod.RemoveMasterPage(nNum);
1303 }
1304 else
1305 {
1306 pChkPg=rMod.RemovePage(nNum);
1307 }
1308 DBG_ASSERT(pChkPg==&mrPage,"SdrUndoPage::ImpRemovePage(): RemovePage!=&mrPage");
1309 }
1310 }
1311
ImpMovePage(sal_uInt16 nOldNum,sal_uInt16 nNewNum)1312 void SdrUndoPage::ImpMovePage(sal_uInt16 nOldNum, sal_uInt16 nNewNum)
1313 {
1314 DBG_ASSERT(mrPage.IsInserted(),"SdrUndoPage::ImpMovePage(): mrPage is not inserted.");
1315 if (mrPage.IsInserted())
1316 {
1317 if (mrPage.IsMasterPage())
1318 {
1319 rMod.MoveMasterPage(nOldNum,nNewNum);
1320 }
1321 else
1322 {
1323 rMod.MovePage(nOldNum,nNewNum);
1324 }
1325 }
1326 }
1327
ImpGetDescriptionStr(const char * pStrCacheID)1328 OUString SdrUndoPage::ImpGetDescriptionStr(const char* pStrCacheID)
1329 {
1330 return SvxResId(pStrCacheID);
1331 }
1332
1333
SdrUndoPageList(SdrPage & rNewPg)1334 SdrUndoPageList::SdrUndoPageList(SdrPage& rNewPg)
1335 : SdrUndoPage(rNewPg)
1336 , bItsMine(false)
1337 {
1338 nPageNum=rNewPg.GetPageNum();
1339 }
1340
~SdrUndoPageList()1341 SdrUndoPageList::~SdrUndoPageList()
1342 {
1343 if(bItsMine)
1344 {
1345 delete &mrPage;
1346 }
1347 }
1348
1349
SdrUndoDelPage(SdrPage & rNewPg)1350 SdrUndoDelPage::SdrUndoDelPage(SdrPage& rNewPg)
1351 : SdrUndoPageList(rNewPg)
1352 , mbHasFillBitmap(false)
1353 {
1354 bItsMine = true;
1355
1356 // keep fill bitmap separately to remove it from pool if not used elsewhere
1357 if (mrPage.IsMasterPage())
1358 {
1359 SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet();
1360 if (pStyleSheet)
1361 queryFillBitmap(pStyleSheet->GetItemSet());
1362 }
1363 else
1364 {
1365 queryFillBitmap(mrPage.getSdrPageProperties().GetItemSet());
1366 }
1367 if (bool(mpFillBitmapItem))
1368 clearFillBitmap();
1369
1370 // now remember the master page relationships
1371 if(mrPage.IsMasterPage())
1372 {
1373 sal_uInt16 nPageCnt(rMod.GetPageCount());
1374
1375 for(sal_uInt16 nPageNum2(0); nPageNum2 < nPageCnt; nPageNum2++)
1376 {
1377 SdrPage* pDrawPage = rMod.GetPage(nPageNum2);
1378
1379 if(pDrawPage->TRG_HasMasterPage())
1380 {
1381 SdrPage& rMasterPage = pDrawPage->TRG_GetMasterPage();
1382
1383 if(&mrPage == &rMasterPage)
1384 {
1385 if(!pUndoGroup)
1386 {
1387 pUndoGroup.reset( new SdrUndoGroup(rMod) );
1388 }
1389
1390 pUndoGroup->AddAction(rMod.GetSdrUndoFactory().CreateUndoPageRemoveMasterPage(*pDrawPage));
1391 }
1392 }
1393 }
1394 }
1395 }
1396
~SdrUndoDelPage()1397 SdrUndoDelPage::~SdrUndoDelPage()
1398 {
1399 }
1400
Undo()1401 void SdrUndoDelPage::Undo()
1402 {
1403 if (bool(mpFillBitmapItem))
1404 restoreFillBitmap();
1405 ImpInsertPage(nPageNum);
1406 if (pUndoGroup!=nullptr)
1407 {
1408 // recover master page relationships
1409 pUndoGroup->Undo();
1410 }
1411 DBG_ASSERT(bItsMine,"UndoDeletePage: mrPage does not belong to UndoAction.");
1412 bItsMine=false;
1413 }
1414
Redo()1415 void SdrUndoDelPage::Redo()
1416 {
1417 ImpRemovePage(nPageNum);
1418 if (bool(mpFillBitmapItem))
1419 clearFillBitmap();
1420 // master page relations are dissolved automatically
1421 DBG_ASSERT(!bItsMine,"RedoDeletePage: mrPage already belongs to UndoAction.");
1422 bItsMine=true;
1423 }
1424
GetComment() const1425 OUString SdrUndoDelPage::GetComment() const
1426 {
1427 return ImpGetDescriptionStr(STR_UndoDelPage);
1428 }
1429
GetSdrRepeatComment() const1430 OUString SdrUndoDelPage::GetSdrRepeatComment() const
1431 {
1432 return ImpGetDescriptionStr(STR_UndoDelPage);
1433 }
1434
SdrRepeat(SdrView &)1435 void SdrUndoDelPage::SdrRepeat(SdrView& /*rView*/)
1436 {
1437 }
1438
CanSdrRepeat(SdrView &) const1439 bool SdrUndoDelPage::CanSdrRepeat(SdrView& /*rView*/) const
1440 {
1441 return false;
1442 }
1443
queryFillBitmap(const SfxItemSet & rItemSet)1444 void SdrUndoDelPage::queryFillBitmap(const SfxItemSet& rItemSet)
1445 {
1446 const SfxPoolItem *pItem = nullptr;
1447 if (rItemSet.GetItemState(XATTR_FILLBITMAP, false, &pItem) == SfxItemState::SET)
1448 mpFillBitmapItem.reset(pItem->Clone());
1449 if (rItemSet.GetItemState(XATTR_FILLSTYLE, false, &pItem) == SfxItemState::SET)
1450 mbHasFillBitmap = static_cast<const XFillStyleItem*>(pItem)->GetValue() == css::drawing::FillStyle_BITMAP;
1451 }
1452
clearFillBitmap()1453 void SdrUndoDelPage::clearFillBitmap()
1454 {
1455 if (mrPage.IsMasterPage())
1456 {
1457 SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet();
1458 assert(bool(pStyleSheet)); // who took away my stylesheet?
1459 if (pStyleSheet->GetListenerCount() == 1)
1460 {
1461 SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
1462 rItemSet.ClearItem(XATTR_FILLBITMAP);
1463 if (mbHasFillBitmap)
1464 rItemSet.ClearItem(XATTR_FILLSTYLE);
1465 }
1466 }
1467 else
1468 {
1469 SdrPageProperties &rPageProps = mrPage.getSdrPageProperties();
1470 rPageProps.ClearItem(XATTR_FILLBITMAP);
1471 if (mbHasFillBitmap)
1472 rPageProps.ClearItem(XATTR_FILLSTYLE);
1473 }
1474 }
1475
restoreFillBitmap()1476 void SdrUndoDelPage::restoreFillBitmap()
1477 {
1478 if (mrPage.IsMasterPage())
1479 {
1480 SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet();
1481 assert(bool(pStyleSheet)); // who took away my stylesheet?
1482 if (pStyleSheet->GetListenerCount() == 1)
1483 {
1484 SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
1485 rItemSet.Put(*mpFillBitmapItem);
1486 if (mbHasFillBitmap)
1487 rItemSet.Put(XFillStyleItem(css::drawing::FillStyle_BITMAP));
1488 }
1489 }
1490 else
1491 {
1492 SdrPageProperties &rPageProps = mrPage.getSdrPageProperties();
1493 rPageProps.PutItem(*mpFillBitmapItem);
1494 if (mbHasFillBitmap)
1495 rPageProps.PutItem(XFillStyleItem(css::drawing::FillStyle_BITMAP));
1496 }
1497 }
1498
1499
Undo()1500 void SdrUndoNewPage::Undo()
1501 {
1502 ImpRemovePage(nPageNum);
1503 DBG_ASSERT(!bItsMine,"UndoNewPage: mrPage already belongs to UndoAction.");
1504 bItsMine=true;
1505 }
1506
Redo()1507 void SdrUndoNewPage::Redo()
1508 {
1509 ImpInsertPage(nPageNum);
1510 DBG_ASSERT(bItsMine,"RedoNewPage: mrPage does not belong to UndoAction.");
1511 bItsMine=false;
1512 }
1513
GetComment() const1514 OUString SdrUndoNewPage::GetComment() const
1515 {
1516 return ImpGetDescriptionStr(STR_UndoNewPage);
1517 }
1518
1519
GetComment() const1520 OUString SdrUndoCopyPage::GetComment() const
1521 {
1522 return ImpGetDescriptionStr(STR_UndoCopPage);
1523 }
1524
GetSdrRepeatComment() const1525 OUString SdrUndoCopyPage::GetSdrRepeatComment() const
1526 {
1527 return ImpGetDescriptionStr(STR_UndoCopPage);
1528 }
1529
SdrRepeat(SdrView &)1530 void SdrUndoCopyPage::SdrRepeat(SdrView& /*rView*/)
1531 {
1532
1533 }
1534
CanSdrRepeat(SdrView &) const1535 bool SdrUndoCopyPage::CanSdrRepeat(SdrView& /*rView*/) const
1536 {
1537 return false;
1538 }
1539
1540
Undo()1541 void SdrUndoSetPageNum::Undo()
1542 {
1543 ImpMovePage(nNewPageNum,nOldPageNum);
1544 }
1545
Redo()1546 void SdrUndoSetPageNum::Redo()
1547 {
1548 ImpMovePage(nOldPageNum,nNewPageNum);
1549 }
1550
GetComment() const1551 OUString SdrUndoSetPageNum::GetComment() const
1552 {
1553 return ImpGetDescriptionStr(STR_UndoMovPage);
1554 }
1555
SdrUndoPageMasterPage(SdrPage & rChangedPage)1556 SdrUndoPageMasterPage::SdrUndoPageMasterPage(SdrPage& rChangedPage)
1557 : SdrUndoPage(rChangedPage)
1558 , mbOldHadMasterPage(mrPage.TRG_HasMasterPage())
1559 , maOldMasterPageNumber(0)
1560 {
1561 // get current state from page
1562 if(mbOldHadMasterPage)
1563 {
1564 maOldSet = mrPage.TRG_GetMasterPageVisibleLayers();
1565 maOldMasterPageNumber = mrPage.TRG_GetMasterPage().GetPageNum();
1566 }
1567 }
1568
~SdrUndoPageMasterPage()1569 SdrUndoPageMasterPage::~SdrUndoPageMasterPage()
1570 {
1571 }
1572
SdrUndoPageRemoveMasterPage(SdrPage & rChangedPage)1573 SdrUndoPageRemoveMasterPage::SdrUndoPageRemoveMasterPage(SdrPage& rChangedPage)
1574 : SdrUndoPageMasterPage(rChangedPage)
1575 {
1576 }
1577
Undo()1578 void SdrUndoPageRemoveMasterPage::Undo()
1579 {
1580 if(mbOldHadMasterPage)
1581 {
1582 mrPage.TRG_SetMasterPage(*mrPage.getSdrModelFromSdrPage().GetMasterPage(maOldMasterPageNumber));
1583 mrPage.TRG_SetMasterPageVisibleLayers(maOldSet);
1584 }
1585 }
1586
Redo()1587 void SdrUndoPageRemoveMasterPage::Redo()
1588 {
1589 mrPage.TRG_ClearMasterPage();
1590 }
1591
GetComment() const1592 OUString SdrUndoPageRemoveMasterPage::GetComment() const
1593 {
1594 return ImpGetDescriptionStr(STR_UndoDelPageMasterDscr);
1595 }
1596
SdrUndoPageChangeMasterPage(SdrPage & rChangedPage)1597 SdrUndoPageChangeMasterPage::SdrUndoPageChangeMasterPage(SdrPage& rChangedPage)
1598 : SdrUndoPageMasterPage(rChangedPage)
1599 , mbNewHadMasterPage(false)
1600 , maNewMasterPageNumber(0)
1601 {
1602 }
1603
Undo()1604 void SdrUndoPageChangeMasterPage::Undo()
1605 {
1606 // remember values from new page
1607 if(mrPage.TRG_HasMasterPage())
1608 {
1609 mbNewHadMasterPage = true;
1610 maNewSet = mrPage.TRG_GetMasterPageVisibleLayers();
1611 maNewMasterPageNumber = mrPage.TRG_GetMasterPage().GetPageNum();
1612 }
1613
1614 // restore old values
1615 if(mbOldHadMasterPage)
1616 {
1617 mrPage.TRG_ClearMasterPage();
1618 mrPage.TRG_SetMasterPage(*mrPage.getSdrModelFromSdrPage().GetMasterPage(maOldMasterPageNumber));
1619 mrPage.TRG_SetMasterPageVisibleLayers(maOldSet);
1620 }
1621 }
1622
Redo()1623 void SdrUndoPageChangeMasterPage::Redo()
1624 {
1625 // restore new values
1626 if(mbNewHadMasterPage)
1627 {
1628 mrPage.TRG_ClearMasterPage();
1629 mrPage.TRG_SetMasterPage(*mrPage.getSdrModelFromSdrPage().GetMasterPage(maNewMasterPageNumber));
1630 mrPage.TRG_SetMasterPageVisibleLayers(maNewSet);
1631 }
1632 }
1633
GetComment() const1634 OUString SdrUndoPageChangeMasterPage::GetComment() const
1635 {
1636 return ImpGetDescriptionStr(STR_UndoChgPageMasterDscr);
1637 }
1638
1639
~SdrUndoFactory()1640 SdrUndoFactory::~SdrUndoFactory(){}
1641
1642 // shapes
1643
CreateUndoMoveObject(SdrObject & rObject,const Size & rDist)1644 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoMoveObject( SdrObject& rObject, const Size& rDist )
1645 {
1646 return std::make_unique<SdrUndoMoveObj>( rObject, rDist );
1647 }
1648
CreateUndoGeoObject(SdrObject & rObject)1649 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoGeoObject( SdrObject& rObject )
1650 {
1651 return std::make_unique<SdrUndoGeoObj>( rObject );
1652 }
1653
CreateUndoAttrObject(SdrObject & rObject,bool bStyleSheet1,bool bSaveText)1654 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoAttrObject( SdrObject& rObject, bool bStyleSheet1, bool bSaveText )
1655 {
1656 return std::make_unique<SdrUndoAttrObj>( rObject, bStyleSheet1, bSaveText );
1657 }
1658
CreateUndoRemoveObject(SdrObject & rObject)1659 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoRemoveObject(SdrObject& rObject)
1660 {
1661 return std::make_unique<SdrUndoRemoveObj>(rObject);
1662 }
1663
CreateUndoInsertObject(SdrObject & rObject,bool bOrdNumDirect)1664 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoInsertObject( SdrObject& rObject, bool bOrdNumDirect )
1665 {
1666 return std::make_unique<SdrUndoInsertObj>( rObject, bOrdNumDirect );
1667 }
1668
CreateUndoDeleteObject(SdrObject & rObject,bool bOrdNumDirect)1669 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoDeleteObject( SdrObject& rObject, bool bOrdNumDirect )
1670 {
1671 return std::make_unique<SdrUndoDelObj>( rObject, bOrdNumDirect );
1672 }
1673
CreateUndoNewObject(SdrObject & rObject,bool bOrdNumDirect)1674 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoNewObject( SdrObject& rObject, bool bOrdNumDirect )
1675 {
1676 return std::make_unique<SdrUndoNewObj>( rObject, bOrdNumDirect );
1677 }
1678
CreateUndoCopyObject(SdrObject & rObject,bool bOrdNumDirect)1679 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoCopyObject( SdrObject& rObject, bool bOrdNumDirect )
1680 {
1681 return std::make_unique<SdrUndoCopyObj>( rObject, bOrdNumDirect );
1682 }
1683
CreateUndoObjectOrdNum(SdrObject & rObject,sal_uInt32 nOldOrdNum1,sal_uInt32 nNewOrdNum1)1684 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoObjectOrdNum( SdrObject& rObject, sal_uInt32 nOldOrdNum1, sal_uInt32 nNewOrdNum1)
1685 {
1686 return std::make_unique<SdrUndoObjOrdNum>( rObject, nOldOrdNum1, nNewOrdNum1 );
1687 }
1688
CreateUndoReplaceObject(SdrObject & rOldObject,SdrObject & rNewObject)1689 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoReplaceObject( SdrObject& rOldObject, SdrObject& rNewObject )
1690 {
1691 return std::make_unique<SdrUndoReplaceObj>( rOldObject, rNewObject );
1692 }
1693
CreateUndoObjectLayerChange(SdrObject & rObject,SdrLayerID aOldLayer,SdrLayerID aNewLayer)1694 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoObjectLayerChange( SdrObject& rObject, SdrLayerID aOldLayer, SdrLayerID aNewLayer )
1695 {
1696 return std::make_unique<SdrUndoObjectLayerChange>( rObject, aOldLayer, aNewLayer );
1697 }
1698
CreateUndoObjectSetText(SdrObject & rNewObj,sal_Int32 nText)1699 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoObjectSetText( SdrObject& rNewObj, sal_Int32 nText )
1700 {
1701 return std::make_unique<SdrUndoObjSetText>( rNewObj, nText );
1702 }
1703
CreateUndoObjectStrAttr(SdrObject & rObject,SdrUndoObjStrAttr::ObjStrAttrType eObjStrAttrType,const OUString & sOldStr,const OUString & sNewStr)1704 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoObjectStrAttr( SdrObject& rObject,
1705 SdrUndoObjStrAttr::ObjStrAttrType eObjStrAttrType,
1706 const OUString& sOldStr,
1707 const OUString& sNewStr )
1708 {
1709 return std::make_unique<SdrUndoObjStrAttr>( rObject, eObjStrAttrType, sOldStr, sNewStr );
1710 }
1711
1712
1713 // layer
CreateUndoNewLayer(sal_uInt16 nLayerNum,SdrLayerAdmin & rNewLayerAdmin,SdrModel & rNewModel)1714 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoNewLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel)
1715 {
1716 return std::make_unique<SdrUndoNewLayer>( nLayerNum, rNewLayerAdmin, rNewModel );
1717 }
1718
CreateUndoDeleteLayer(sal_uInt16 nLayerNum,SdrLayerAdmin & rNewLayerAdmin,SdrModel & rNewModel)1719 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoDeleteLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel)
1720 {
1721 return std::make_unique<SdrUndoDelLayer>( nLayerNum, rNewLayerAdmin, rNewModel );
1722 }
1723
1724 // page
CreateUndoDeletePage(SdrPage & rPage)1725 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoDeletePage(SdrPage& rPage)
1726 {
1727 return std::make_unique<SdrUndoDelPage>(rPage);
1728 }
1729
CreateUndoNewPage(SdrPage & rPage)1730 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoNewPage(SdrPage& rPage)
1731 {
1732 return std::make_unique<SdrUndoNewPage>( rPage );
1733 }
1734
CreateUndoCopyPage(SdrPage & rPage)1735 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoCopyPage(SdrPage& rPage)
1736 {
1737 return std::make_unique<SdrUndoCopyPage>( rPage );
1738 }
1739
CreateUndoSetPageNum(SdrPage & rNewPg,sal_uInt16 nOldPageNum1,sal_uInt16 nNewPageNum1)1740 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoSetPageNum(SdrPage& rNewPg, sal_uInt16 nOldPageNum1, sal_uInt16 nNewPageNum1)
1741 {
1742 return std::make_unique<SdrUndoSetPageNum>( rNewPg, nOldPageNum1, nNewPageNum1 );
1743 }
1744 // master page
CreateUndoPageRemoveMasterPage(SdrPage & rChangedPage)1745 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoPageRemoveMasterPage(SdrPage& rChangedPage)
1746 {
1747 return std::make_unique<SdrUndoPageRemoveMasterPage>( rChangedPage );
1748 }
1749
CreateUndoPageChangeMasterPage(SdrPage & rChangedPage)1750 std::unique_ptr<SdrUndoAction> SdrUndoFactory::CreateUndoPageChangeMasterPage(SdrPage& rChangedPage)
1751 {
1752 return std::make_unique<SdrUndoPageChangeMasterPage>(rChangedPage);
1753 }
1754
1755
1756 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1757