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