File: | home/maarten/src/libreoffice/core/sd/source/core/drawdoc3.cxx |
Warning: | line 741, column 57 Use of memory after it is freed |
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 | ||||
21 | #include <memory> | |||
22 | ||||
23 | #include <sfx2/docfile.hxx> | |||
24 | #include <sfx2/docfilt.hxx> | |||
25 | #include <sfx2/app.hxx> | |||
26 | #include <svl/itemset.hxx> | |||
27 | #include <tools/debug.hxx> | |||
28 | ||||
29 | #include <sfx2/fcontnr.hxx> | |||
30 | #include <svl/style.hxx> | |||
31 | #include <svx/svdpagv.hxx> | |||
32 | #include <svx/svdundo.hxx> | |||
33 | #include <vcl/stdtext.hxx> | |||
34 | #include <vcl/svapp.hxx> | |||
35 | #include <vcl/weld.hxx> | |||
36 | #include <xmloff/autolayout.hxx> | |||
37 | ||||
38 | #include <strings.hrc> | |||
39 | #include <drawdoc.hxx> | |||
40 | #include <sdmod.hxx> | |||
41 | #include <sdpage.hxx> | |||
42 | #include <stlpool.hxx> | |||
43 | #include <sdresid.hxx> | |||
44 | #include <customshowlist.hxx> | |||
45 | #include <sdxfer.hxx> | |||
46 | ||||
47 | #include <unmovss.hxx> | |||
48 | #include <unchss.hxx> | |||
49 | #include <unprlout.hxx> | |||
50 | #include <DrawDocShell.hxx> | |||
51 | #include <GraphicDocShell.hxx> | |||
52 | #include <ViewShell.hxx> | |||
53 | #include <View.hxx> | |||
54 | #include <ViewShellBase.hxx> | |||
55 | #include <strings.hxx> | |||
56 | ||||
57 | using namespace ::com::sun::star; | |||
58 | ||||
59 | /** Concrete incarnations get called by lcl_IterateBookmarkPages, for | |||
60 | every page in the bookmark document/list | |||
61 | */ | |||
62 | ||||
63 | namespace { | |||
64 | ||||
65 | class InsertBookmarkAsPage_FindDuplicateLayouts | |||
66 | { | |||
67 | public: | |||
68 | explicit InsertBookmarkAsPage_FindDuplicateLayouts( std::vector<OUString> &rLayoutsToTransfer ) | |||
69 | : mrLayoutsToTransfer(rLayoutsToTransfer) {} | |||
70 | void operator()( SdDrawDocument&, SdPage const *, bool, SdDrawDocument* ); | |||
71 | private: | |||
72 | std::vector<OUString> &mrLayoutsToTransfer; | |||
73 | }; | |||
74 | ||||
75 | } | |||
76 | ||||
77 | void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc, SdPage const * pBMMPage, bool bRenameDuplicates, SdDrawDocument* pBookmarkDoc ) | |||
78 | { | |||
79 | // now check for duplicate masterpage and layout names | |||
80 | ||||
81 | OUString aLayout( pBMMPage->GetLayoutName() ); | |||
82 | sal_Int32 nIndex = aLayout.indexOf( SD_LT_SEPARATOR"~LT~" ); | |||
83 | if( nIndex != -1 ) | |||
84 | aLayout = aLayout.copy(0, nIndex); | |||
85 | ||||
86 | std::vector<OUString>::const_iterator pIter = | |||
87 | find(mrLayoutsToTransfer.begin(),mrLayoutsToTransfer.end(),aLayout); | |||
88 | ||||
89 | bool bFound = pIter != mrLayoutsToTransfer.end(); | |||
90 | ||||
91 | const sal_uInt16 nMPageCount = rDoc.GetMasterPageCount(); | |||
92 | for (sal_uInt16 nMPage = 0; nMPage < nMPageCount && !bFound; nMPage++) | |||
93 | { | |||
94 | // Do the layouts already exist within the document? | |||
95 | SdPage* pTestPage = static_cast<SdPage*>( rDoc.GetMasterPage(nMPage) ); | |||
96 | OUString aTest(pTestPage->GetLayoutName()); | |||
97 | sal_Int32 nIndex2 = aTest.indexOf( SD_LT_SEPARATOR"~LT~" ); | |||
98 | if( nIndex2 != -1 ) | |||
99 | aTest = aTest.copy(0, nIndex2); | |||
100 | ||||
101 | if (aTest == aLayout && pBMMPage->GetPageKind() == pTestPage->GetPageKind()) | |||
102 | { | |||
103 | // Ignore Layouts with "Default" these seem to be special - in the sense that there are lot of assumption all over Impress | |||
104 | // about this | |||
105 | if( bRenameDuplicates && aTest != SdResId( STR_LAYOUT_DEFAULT_NAMEreinterpret_cast<char const *>("STR_LAYOUT_DEFAULT_NAME" "\004" u8"Default") ) && !(pTestPage->Equals(*pBMMPage)) ) | |||
106 | { | |||
107 | pBookmarkDoc->RenameLayoutTemplate( | |||
108 | pBMMPage->GetLayoutName(), pBMMPage->GetName() + "_"); | |||
109 | aLayout = pBMMPage->GetName(); | |||
110 | ||||
111 | break; | |||
112 | } | |||
113 | else | |||
114 | bFound = true; | |||
115 | } | |||
116 | } | |||
117 | ||||
118 | if (!bFound) | |||
119 | mrLayoutsToTransfer.push_back(aLayout); | |||
120 | } | |||
121 | ||||
122 | // Inserts a bookmark as a page | |||
123 | static void lcl_IterateBookmarkPages( SdDrawDocument &rDoc, SdDrawDocument* pBookmarkDoc, | |||
124 | const std::vector<OUString> &rBookmarkList, sal_uInt16 nBMSdPageCount, | |||
125 | InsertBookmarkAsPage_FindDuplicateLayouts& rPageIterator, bool bRenameDuplicates ) | |||
126 | { | |||
127 | ||||
128 | // Refactored copy'n'pasted layout name collection from InsertBookmarkAsPage | |||
129 | ||||
130 | int nPos, nEndPos; | |||
131 | ||||
132 | if( rBookmarkList.empty() ) | |||
133 | { | |||
134 | // no list? whole source document | |||
135 | nEndPos = nBMSdPageCount; | |||
136 | } | |||
137 | else | |||
138 | { | |||
139 | // bookmark list? number of entries | |||
140 | nEndPos = rBookmarkList.size(); | |||
141 | } | |||
142 | ||||
143 | SdPage* pBMPage; | |||
144 | ||||
145 | // iterate over number of pages to insert | |||
146 | for (nPos = 0; nPos < nEndPos; ++nPos) | |||
147 | { | |||
148 | // the master page associated to the nPos'th page to insert | |||
149 | SdPage* pBMMPage = nullptr; | |||
150 | ||||
151 | if( rBookmarkList.empty() ) | |||
152 | { | |||
153 | // simply take master page of nPos'th page in source document | |||
154 | pBMMPage = static_cast<SdPage*>(&(pBookmarkDoc->GetSdPage(static_cast<sal_uInt16>(nPos), PageKind::Standard)->TRG_GetMasterPage())); | |||
155 | } | |||
156 | else | |||
157 | { | |||
158 | // fetch nPos'th entry from bookmark list, and determine master page | |||
159 | OUString aBMPgName(rBookmarkList[nPos]); | |||
160 | bool bIsMasterPage; | |||
161 | ||||
162 | sal_uInt16 nBMPage = pBookmarkDoc->GetPageByName( aBMPgName, bIsMasterPage ); | |||
163 | ||||
164 | if (nBMPage != SDRPAGE_NOTFOUND0xFFFF) | |||
165 | { | |||
166 | pBMPage = static_cast<SdPage*>( pBookmarkDoc->GetPage(nBMPage) ); | |||
167 | } | |||
168 | else | |||
169 | { | |||
170 | pBMPage = nullptr; | |||
171 | } | |||
172 | ||||
173 | // enforce that bookmarked page is a standard page and not already a master page | |||
174 | if (pBMPage && pBMPage->GetPageKind()==PageKind::Standard && !pBMPage->IsMasterPage()) | |||
175 | { | |||
176 | const sal_uInt16 nBMSdPage = (nBMPage - 1) / 2; | |||
177 | pBMMPage = static_cast<SdPage*> (&(pBookmarkDoc->GetSdPage(nBMSdPage, PageKind::Standard)->TRG_GetMasterPage())); | |||
178 | } | |||
179 | } | |||
180 | ||||
181 | // successfully determined valid (bookmarked) page? | |||
182 | if( pBMMPage ) | |||
183 | { | |||
184 | // yes, call functor | |||
185 | rPageIterator( rDoc, pBMMPage, bRenameDuplicates, pBookmarkDoc ); | |||
186 | } | |||
187 | } | |||
188 | } | |||
189 | ||||
190 | // Opens a bookmark document | |||
191 | SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(SfxMedium* pMedium) | |||
192 | { | |||
193 | bool bOK = true; | |||
194 | SdDrawDocument* pBookmarkDoc = nullptr; | |||
195 | OUString aBookmarkName = pMedium->GetName(); | |||
196 | std::shared_ptr<const SfxFilter> pFilter = pMedium->GetFilter(); | |||
197 | if ( !pFilter ) | |||
198 | { | |||
199 | pMedium->UseInteractionHandler( true ); | |||
200 | SfxGetpApp()->GetFilterMatcher().GuessFilter(*pMedium, pFilter); | |||
201 | } | |||
202 | ||||
203 | if ( !pFilter ) | |||
204 | { | |||
205 | bOK = false; | |||
206 | } | |||
207 | else if ( !aBookmarkName.isEmpty() && maBookmarkFile != aBookmarkName ) | |||
208 | { | |||
209 | bool bCreateGraphicShell = pFilter->GetServiceName() == "com.sun.star.drawing.DrawingDocument"; | |||
210 | bool bCreateImpressShell = pFilter->GetServiceName() == "com.sun.star.presentation.PresentationDocument"; | |||
211 | if ( bCreateGraphicShell || bCreateImpressShell ) | |||
212 | { | |||
213 | CloseBookmarkDoc(); | |||
214 | ||||
215 | // Create a DocShell, as OLE objects might be contained in the | |||
216 | // document. (Persist) | |||
217 | // If that wasn't the case, we could load the model directly. | |||
218 | if ( bCreateGraphicShell ) | |||
219 | // Draw | |||
220 | mxBookmarkDocShRef = new ::sd::GraphicDocShell(SfxObjectCreateMode::STANDARD); | |||
221 | else | |||
222 | // Impress | |||
223 | mxBookmarkDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::STANDARD, true, DocumentType::Impress); | |||
224 | ||||
225 | bOK = mxBookmarkDocShRef->DoLoad(pMedium); | |||
226 | if( bOK ) | |||
227 | { | |||
228 | maBookmarkFile = aBookmarkName; | |||
229 | pBookmarkDoc = mxBookmarkDocShRef->GetDoc(); | |||
230 | } | |||
231 | } | |||
232 | } | |||
233 | ||||
234 | DBG_ASSERT(!aBookmarkName.isEmpty(), "Empty document name!")do { if (true && (!(!aBookmarkName.isEmpty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/core/drawdoc3.cxx" ":" "234" ": "), "%s", "Empty document name!"); } } while (false ); | |||
235 | ||||
236 | if (!bOK) | |||
237 | { | |||
238 | std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(nullptr, | |||
239 | VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERRORreinterpret_cast<char const *>("STR_READ_DATA_ERROR" "\004" u8"The file could not be loaded!")))); | |||
240 | xErrorBox->run(); | |||
241 | ||||
242 | CloseBookmarkDoc(); | |||
243 | pBookmarkDoc = nullptr; | |||
244 | } | |||
245 | else if (mxBookmarkDocShRef.is()) | |||
246 | { | |||
247 | pBookmarkDoc = mxBookmarkDocShRef->GetDoc(); | |||
248 | } | |||
249 | ||||
250 | return pBookmarkDoc; | |||
251 | } | |||
252 | ||||
253 | // Opens a bookmark document | |||
254 | SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(const OUString& rBookmarkFile) | |||
255 | { | |||
256 | SdDrawDocument* pBookmarkDoc = nullptr; | |||
257 | ||||
258 | if (!rBookmarkFile.isEmpty() && maBookmarkFile != rBookmarkFile) | |||
259 | { | |||
260 | std::unique_ptr<SfxMedium> xMedium(new SfxMedium(rBookmarkFile, StreamMode::READ)); | |||
261 | pBookmarkDoc = OpenBookmarkDoc(xMedium.release()); | |||
262 | } | |||
263 | else if (mxBookmarkDocShRef.is()) | |||
264 | { | |||
265 | pBookmarkDoc = mxBookmarkDocShRef->GetDoc(); | |||
266 | } | |||
267 | ||||
268 | return pBookmarkDoc; | |||
269 | } | |||
270 | ||||
271 | // Inserts a bookmark (page or object) | |||
272 | void SdDrawDocument::InsertBookmark( | |||
273 | const std::vector<OUString> &rBookmarkList, // List of names of the bookmarks to be inserted | |||
274 | std::vector<OUString> &rExchangeList, // List of the names to be used | |||
275 | bool bLink, // Insert bookmarks as links? | |||
276 | sal_uInt16 nInsertPos, // Insertion position of pages | |||
277 | ::sd::DrawDocShell* pBookmarkDocSh, // If set, this is the source document | |||
278 | Point const * pObjPos) // Insertion position of objects | |||
279 | { | |||
280 | bool bOK = true; | |||
281 | bool bInsertPages = false; | |||
282 | ||||
283 | if (rBookmarkList.empty()) | |||
284 | { | |||
285 | // Insert all pages | |||
286 | bInsertPages = true; | |||
287 | } | |||
288 | else | |||
289 | { | |||
290 | SdDrawDocument* pBookmarkDoc = nullptr; | |||
291 | ||||
292 | if (pBookmarkDocSh) | |||
293 | { | |||
294 | pBookmarkDoc = pBookmarkDocSh->GetDoc(); | |||
295 | } | |||
296 | else if ( mxBookmarkDocShRef.is() ) | |||
297 | { | |||
298 | pBookmarkDoc = mxBookmarkDocShRef->GetDoc(); | |||
299 | } | |||
300 | else | |||
301 | bOK = false; | |||
302 | ||||
303 | bInsertPages = bOK && std::any_of(rBookmarkList.begin(), rBookmarkList.end(), | |||
304 | [&pBookmarkDoc](const OUString& rBookmark) { | |||
305 | // Is there a page name in the bookmark list? | |||
306 | bool bIsMasterPage; | |||
307 | return pBookmarkDoc->GetPageByName(rBookmark, bIsMasterPage) != SDRPAGE_NOTFOUND0xFFFF; | |||
308 | }); | |||
309 | } | |||
310 | ||||
311 | bool bCalcObjCount = !rExchangeList.empty(); | |||
312 | ||||
313 | if ( bOK && bInsertPages ) | |||
314 | { | |||
315 | // Insert all page bookmarks | |||
316 | bOK = InsertBookmarkAsPage(rBookmarkList, &rExchangeList, bLink, false/*bReplace*/, | |||
317 | nInsertPos, false/*bNoDialogs*/, pBookmarkDocSh, true/*bCopy*/, true, false); | |||
318 | } | |||
319 | ||||
320 | if ( bOK && !rBookmarkList.empty() ) | |||
321 | { | |||
322 | // Insert all object bookmarks | |||
323 | InsertBookmarkAsObject(rBookmarkList, rExchangeList, | |||
324 | pBookmarkDocSh, pObjPos, bCalcObjCount); | |||
325 | } | |||
326 | } | |||
327 | ||||
328 | namespace | |||
329 | { | |||
330 | ||||
331 | void | |||
332 | lcl_removeUnusedStyles(SfxStyleSheetBasePool* const pStyleSheetPool, StyleSheetCopyResultVector& rStyles) | |||
333 | { | |||
334 | StyleSheetCopyResultVector aUsedStyles; | |||
335 | aUsedStyles.reserve(rStyles.size()); | |||
336 | for (const auto& a : rStyles) | |||
337 | { | |||
338 | if (a.m_xStyleSheet->IsUsed()) | |||
339 | aUsedStyles.push_back(a); | |||
340 | else | |||
341 | pStyleSheetPool->Remove(a.m_xStyleSheet.get()); | |||
342 | } | |||
343 | rStyles = aUsedStyles; | |||
344 | } | |||
345 | ||||
346 | SfxStyleSheet *lcl_findStyle(StyleSheetCopyResultVector& rStyles, const OUString& aStyleName) | |||
347 | { | |||
348 | for (const auto& a : rStyles) | |||
349 | { | |||
350 | if (a.m_xStyleSheet->GetName().startsWith(aStyleName)) | |||
351 | return a.m_xStyleSheet.get(); | |||
352 | } | |||
353 | return nullptr; | |||
354 | } | |||
355 | ||||
356 | } | |||
357 | ||||
358 | bool SdDrawDocument::InsertBookmarkAsPage( | |||
359 | const std::vector<OUString> &rBookmarkList, | |||
360 | std::vector<OUString> *pExchangeList, // List of names to be used | |||
361 | bool bLink, | |||
362 | bool bReplace, | |||
363 | sal_uInt16 nInsertPos, | |||
364 | bool bNoDialogs, | |||
365 | ::sd::DrawDocShell* pBookmarkDocSh, | |||
366 | bool bCopy, | |||
367 | bool bMergeMasterPages, | |||
368 | bool bPreservePageNames) | |||
369 | { | |||
370 | bool bContinue = true; | |||
371 | bool bScaleObjects = false; | |||
372 | sal_uInt16 nReplacedStandardPages = 0; | |||
373 | ||||
374 | SdDrawDocument* pBookmarkDoc = nullptr; | |||
375 | OUString aBookmarkName; | |||
376 | ||||
377 | if (pBookmarkDocSh) | |||
| ||||
378 | { | |||
379 | pBookmarkDoc = pBookmarkDocSh->GetDoc(); | |||
380 | ||||
381 | if (pBookmarkDocSh->GetMedium()) | |||
382 | { | |||
383 | aBookmarkName = pBookmarkDocSh->GetMedium()->GetName(); | |||
384 | } | |||
385 | } | |||
386 | else if ( mxBookmarkDocShRef.is() ) | |||
387 | { | |||
388 | pBookmarkDoc = mxBookmarkDocShRef->GetDoc(); | |||
389 | aBookmarkName = maBookmarkFile; | |||
390 | } | |||
391 | else | |||
392 | { | |||
393 | return false; | |||
394 | } | |||
395 | ||||
396 | const sal_uInt16 nSdPageCount = GetSdPageCount(PageKind::Standard); | |||
397 | const sal_uInt16 nBMSdPageCount = pBookmarkDoc->GetSdPageCount(PageKind::Standard); | |||
398 | const sal_uInt16 nMPageCount = GetMasterPageCount(); | |||
399 | ||||
400 | if (nSdPageCount==0 || nBMSdPageCount==0 || nMPageCount==0) | |||
401 | { | |||
402 | return false; | |||
403 | } | |||
404 | ||||
405 | // Store the size and some other properties of the first page and notes | |||
406 | // page so that inserted pages can be properly scaled even when inserted | |||
407 | // before the first page. | |||
408 | // Note that the pointers are used later on as general page pointers. | |||
409 | SdPage* pRefPage = GetSdPage(0, PageKind::Standard); | |||
410 | Size aSize(pRefPage->GetSize()); | |||
411 | sal_Int32 nLeft = pRefPage->GetLeftBorder(); | |||
412 | sal_Int32 nRight = pRefPage->GetRightBorder(); | |||
413 | sal_Int32 nUpper = pRefPage->GetUpperBorder(); | |||
414 | sal_Int32 nLower = pRefPage->GetLowerBorder(); | |||
415 | Orientation eOrient = pRefPage->GetOrientation(); | |||
416 | ||||
417 | SdPage* pNPage = GetSdPage(0, PageKind::Notes); | |||
418 | Size aNSize(pNPage->GetSize()); | |||
419 | sal_Int32 nNLeft = pNPage->GetLeftBorder(); | |||
420 | sal_Int32 nNRight = pNPage->GetRightBorder(); | |||
421 | sal_Int32 nNUpper = pNPage->GetUpperBorder(); | |||
422 | sal_Int32 nNLower = pNPage->GetLowerBorder(); | |||
423 | Orientation eNOrient = pNPage->GetOrientation(); | |||
424 | ||||
425 | // Adapt page size and margins to those of the later pages? | |||
426 | pRefPage = GetSdPage(nSdPageCount - 1, PageKind::Standard); | |||
427 | ||||
428 | if( bNoDialogs ) | |||
429 | { | |||
430 | // If this is clipboard, then no need to scale objects: | |||
431 | // this will make copied masters to differ from the originals, | |||
432 | // and thus InsertBookmarkAsPage_FindDuplicateLayouts will | |||
433 | // duplicate masters on insert to same document | |||
434 | m_bTransportContainer = (SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->pTransferClip && | |||
435 | SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->pTransferClip->GetWorkDocument() == this); | |||
436 | if (!m_bTransportContainer) | |||
437 | { | |||
438 | if (rBookmarkList.empty()) | |||
439 | bScaleObjects = pRefPage->IsScaleObjects(); | |||
440 | else | |||
441 | bScaleObjects = true; | |||
442 | } | |||
443 | } | |||
444 | else | |||
445 | { | |||
446 | SdPage* pBMPage = pBookmarkDoc->GetSdPage(0,PageKind::Standard); | |||
447 | ||||
448 | if (pBMPage->GetSize() != pRefPage->GetSize() || | |||
449 | pBMPage->GetLeftBorder() != pRefPage->GetLeftBorder() || | |||
450 | pBMPage->GetRightBorder() != pRefPage->GetRightBorder() || | |||
451 | pBMPage->GetUpperBorder() != pRefPage->GetUpperBorder() || | |||
452 | pBMPage->GetLowerBorder() != pRefPage->GetLowerBorder()) | |||
453 | { | |||
454 | OUString aStr(SdResId(STR_SCALE_OBJECTSreinterpret_cast<char const *>("STR_SCALE_OBJECTS" "\004" u8"The page size of the target document is different than the source document.\n\nDo you want to scale the copied objects to fit the new page size?" ))); | |||
455 | std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(nullptr, | |||
456 | VclMessageType::Question, VclButtonsType::YesNo, | |||
457 | aStr)); | |||
458 | xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL); | |||
459 | sal_uInt16 nBut = xQueryBox->run(); | |||
460 | ||||
461 | bScaleObjects = nBut == RET_YES; | |||
462 | bContinue = nBut != RET_CANCEL; | |||
463 | ||||
464 | if (!bContinue
| |||
465 | { | |||
466 | return bContinue; | |||
467 | } | |||
468 | } | |||
469 | } | |||
470 | ||||
471 | // Get the necessary presentation stylesheets and transfer them before | |||
472 | // the pages, else, the text objects won't reference their styles anymore. | |||
473 | SfxUndoManager* pUndoMgr = nullptr; | |||
474 | if( mpDocSh ) | |||
475 | { | |||
476 | pUndoMgr = mpDocSh->GetUndoManager(); | |||
477 | ViewShellId nViewShellId(-1); | |||
478 | if (sd::ViewShell* pViewShell = mpDocSh->GetViewShell()) | |||
479 | nViewShellId = pViewShell->GetViewShellBase().GetViewShellId(); | |||
480 | pUndoMgr->EnterListAction(SdResId(STR_UNDO_INSERTPAGESreinterpret_cast<char const *>("STR_UNDO_INSERTPAGES" "\004" u8"Insert slides")), "", 0, nViewShellId); | |||
481 | } | |||
482 | ||||
483 | // Refactored copy'n'pasted layout name collection into IterateBookmarkPages | |||
484 | ||||
485 | std::vector<OUString> aLayoutsToTransfer; | |||
486 | InsertBookmarkAsPage_FindDuplicateLayouts aSearchFunctor( aLayoutsToTransfer ); | |||
487 | lcl_IterateBookmarkPages( *this, pBookmarkDoc, rBookmarkList, nBMSdPageCount, aSearchFunctor, ( rBookmarkList.empty() && pBookmarkDoc != this ) ); | |||
488 | ||||
489 | // Copy the style that we actually need. | |||
490 | SdStyleSheetPool& rBookmarkStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*pBookmarkDoc->GetStyleSheetPool()); | |||
491 | SdStyleSheetPool& rStyleSheetPool = dynamic_cast<SdStyleSheetPool&>(*GetStyleSheetPool()); | |||
492 | ||||
493 | // When copying styles, also copy the master pages! | |||
494 | if( !aLayoutsToTransfer.empty() ) | |||
495 | bMergeMasterPages = true; | |||
496 | ||||
497 | for ( const OUString& layoutName : aLayoutsToTransfer ) | |||
498 | { | |||
499 | StyleSheetCopyResultVector aCreatedStyles; | |||
500 | ||||
501 | rStyleSheetPool.CopyLayoutSheets(layoutName, rBookmarkStyleSheetPool,aCreatedStyles); | |||
502 | ||||
503 | if(!aCreatedStyles.empty()) | |||
504 | { | |||
505 | if( pUndoMgr ) | |||
506 | { | |||
507 | pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aCreatedStyles, true)); | |||
508 | } | |||
509 | } | |||
510 | } | |||
511 | ||||
512 | // Copy styles. This unconditionally copies all styles, even those | |||
513 | // that are not used in any of the inserted pages. The unused styles | |||
514 | // are then removed at the end of the function, where we also create | |||
515 | // undo records for the inserted styles. | |||
516 | StyleSheetCopyResultVector aNewGraphicStyles; | |||
517 | OUString aRenameStr; | |||
518 | if(!bReplace && !bNoDialogs) | |||
519 | aRenameStr = "_"; | |||
520 | rStyleSheetPool.RenameAndCopyGraphicSheets(rBookmarkStyleSheetPool, aNewGraphicStyles, aRenameStr); | |||
521 | StyleSheetCopyResultVector aNewCellStyles; | |||
522 | rStyleSheetPool.CopyCellSheets(rBookmarkStyleSheetPool, aNewCellStyles); | |||
523 | ||||
524 | // TODO handle undo of table styles too | |||
525 | rStyleSheetPool.CopyTableStyles(rBookmarkStyleSheetPool); | |||
526 | ||||
527 | // Insert document | |||
528 | ||||
529 | const bool bUndo = IsUndoEnabled(); | |||
530 | ||||
531 | if( bUndo ) | |||
532 | BegUndo(SdResId(STR_UNDO_INSERTPAGESreinterpret_cast<char const *>("STR_UNDO_INSERTPAGES" "\004" u8"Insert slides"))); | |||
533 | ||||
534 | if (rBookmarkList.empty()) | |||
535 | { | |||
536 | if (nInsertPos >= GetPageCount()) | |||
537 | { | |||
538 | // Add pages to the end | |||
539 | nInsertPos = GetPageCount(); | |||
540 | } | |||
541 | ||||
542 | sal_uInt16 nActualInsertPos = nInsertPos; | |||
543 | ||||
544 | sal_uInt16 nBMSdPage; | |||
545 | std::set<sal_uInt16> aRenameSet; | |||
546 | std::map<sal_uInt16,OUString> aNameMap; | |||
547 | ||||
548 | for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++) | |||
549 | { | |||
550 | SdPage* pBMPage = pBookmarkDoc->GetSdPage(nBMSdPage, PageKind::Standard); | |||
551 | OUString sName(pBMPage->GetName()); | |||
552 | bool bIsMasterPage; | |||
553 | ||||
554 | if (bLink) | |||
555 | { | |||
556 | // Remember the names of all pages | |||
557 | aNameMap.insert(std::make_pair(nBMSdPage,sName)); | |||
558 | } | |||
559 | ||||
560 | // Have to check for duplicate names here, too | |||
561 | // don't change name if source and dest model are the same! | |||
562 | if( pBookmarkDoc != this && | |||
563 | GetPageByName(sName, bIsMasterPage ) != SDRPAGE_NOTFOUND0xFFFF ) | |||
564 | { | |||
565 | // delay renaming *after* pages are copied (might destroy source otherwise) | |||
566 | aRenameSet.insert(nBMSdPage); | |||
567 | } | |||
568 | } | |||
569 | ||||
570 | Merge(*pBookmarkDoc, | |||
571 | 1, // Not the handout page | |||
572 | 0xFFFF, // But all others | |||
573 | nActualInsertPos, // Insert at position ... | |||
574 | bMergeMasterPages, // Move master pages? | |||
575 | false, // But only the master pages used | |||
576 | true, // Create an undo action | |||
577 | bCopy); // Copy (or merge) pages? | |||
578 | ||||
579 | for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++) | |||
580 | { | |||
581 | SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) ); | |||
582 | SdPage* pNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1) ); | |||
583 | ||||
584 | // delay renaming *after* pages are copied (might destroy source otherwise) | |||
585 | if( aRenameSet.find(nBMSdPage) != aRenameSet.end() ) | |||
586 | { | |||
587 | // Page name already in use -> Use default name for default and | |||
588 | // notes page | |||
589 | pPage->SetName(OUString()); | |||
590 | pNotesPage->SetName(OUString()); | |||
591 | } | |||
592 | ||||
593 | if (bLink) | |||
594 | { | |||
595 | OUString aName(aNameMap[nBMSdPage]); | |||
596 | ||||
597 | // Assemble all link names | |||
598 | pPage->SetFileName(aBookmarkName); | |||
599 | pPage->SetBookmarkName(aName); | |||
600 | } | |||
601 | ||||
602 | nActualInsertPos += 2; | |||
603 | } | |||
604 | } | |||
605 | else | |||
606 | { | |||
607 | // Insert selected pages | |||
608 | SdPage* pBMPage; | |||
609 | ||||
610 | if (nInsertPos >= GetPageCount()) | |||
611 | { | |||
612 | // Add pages to the end | |||
613 | bReplace = false; | |||
614 | nInsertPos = GetPageCount(); | |||
615 | } | |||
616 | ||||
617 | sal_uInt16 nActualInsertPos = nInsertPos; | |||
618 | ||||
619 | // Collect the bookmarked pages | |||
620 | ::std::vector<SdPage*> aBookmarkedPages (rBookmarkList.size(), nullptr); | |||
621 | for ( size_t nPos = 0, n = rBookmarkList.size(); nPos < n; ++nPos) | |||
622 | { | |||
623 | OUString aPgName(rBookmarkList[nPos]); | |||
624 | bool bIsMasterPage; | |||
625 | sal_uInt16 nBMPage = pBookmarkDoc->GetPageByName( aPgName, bIsMasterPage ); | |||
626 | ||||
627 | if (nBMPage != SDRPAGE_NOTFOUND0xFFFF) | |||
628 | { | |||
629 | aBookmarkedPages[nPos] = dynamic_cast<SdPage*>(pBookmarkDoc->GetPage(nBMPage)); | |||
630 | } | |||
631 | } | |||
632 | ||||
633 | for ( size_t nPos = 0, n = rBookmarkList.size(); nPos < n; ++nPos) | |||
634 | { | |||
635 | pBMPage = aBookmarkedPages[nPos]; | |||
636 | sal_uInt16 nBMPage = pBMPage!=nullptr ? pBMPage->GetPageNum() : SDRPAGE_NOTFOUND0xFFFF; | |||
637 | ||||
638 | if (pBMPage
| |||
639 | { | |||
640 | // It has to be a default page | |||
641 | bool bMustRename = false; | |||
642 | ||||
643 | // delay renaming *after* pages are copied (might destroy source otherwise) | |||
644 | // don't change name if source and dest model are the same! | |||
645 | // avoid renaming if replacing the same page | |||
646 | OUString aPgName(rBookmarkList[nPos]); | |||
647 | bool bIsMasterPage; | |||
648 | sal_uInt16 nPageSameName = GetPageByName(aPgName, bIsMasterPage); | |||
649 | if( pBookmarkDoc != this && | |||
650 | nPageSameName != SDRPAGE_NOTFOUND0xFFFF && | |||
651 | ( !bReplace || | |||
652 | nPageSameName != nActualInsertPos ) ) | |||
653 | { | |||
654 | bMustRename = true; | |||
655 | } | |||
656 | ||||
657 | SdPage* pBookmarkPage = pBMPage; | |||
658 | if (bReplace
| |||
659 | { | |||
660 | ReplacePageInCustomShows( dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ), pBookmarkPage ); | |||
661 | } | |||
662 | ||||
663 | Merge(*pBookmarkDoc, | |||
664 | nBMPage, // From page (default page) | |||
665 | nBMPage+1, // To page (notes page) | |||
666 | nActualInsertPos, // Insert at position | |||
667 | bMergeMasterPages, // Move master pages? | |||
668 | false, // But only the master pages used | |||
669 | true, // Create undo action | |||
670 | bCopy); // Copy (or merge) pages? | |||
671 | ||||
672 | if( bReplace
| |||
673 | { | |||
674 | if( GetPage( nActualInsertPos ) != pBookmarkPage ) | |||
675 | { | |||
676 | // bookmark page was not moved but cloned, so update custom shows again | |||
677 | ReplacePageInCustomShows( pBookmarkPage, dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ) ); | |||
678 | } | |||
679 | } | |||
680 | ||||
681 | if( bMustRename
| |||
682 | { | |||
683 | // Page name already in use -> use default name for default and | |||
684 | // notes page | |||
685 | SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) ); | |||
686 | pPage->SetName(OUString()); | |||
687 | SdPage* pNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1) ); | |||
688 | pNotesPage->SetName(OUString()); | |||
689 | } | |||
690 | ||||
691 | if (bLink) | |||
692 | { | |||
693 | SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) ); | |||
694 | pPage->SetFileName(aBookmarkName); | |||
695 | pPage->SetBookmarkName(aPgName); | |||
696 | } | |||
697 | ||||
698 | if (bReplace
| |||
699 | { | |||
700 | // Remove page and notes page. | |||
701 | const sal_uInt16 nDestPageNum(nActualInsertPos + 2); | |||
702 | SdPage* pStandardPage = nullptr; | |||
703 | ||||
704 | if(nDestPageNum < GetPageCount()) | |||
705 | { | |||
706 | pStandardPage = static_cast<SdPage*>(GetPage(nDestPageNum)); | |||
707 | } | |||
708 | ||||
709 | if (pStandardPage) | |||
710 | { | |||
711 | if( bPreservePageNames ) | |||
712 | { | |||
713 | // Take old slide names for inserted pages | |||
714 | SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) ); | |||
715 | pPage->SetName( pStandardPage->GetRealName() ); | |||
716 | } | |||
717 | ||||
718 | if( bUndo
| |||
719 | AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pStandardPage)); | |||
720 | ||||
721 | RemovePage(nDestPageNum); | |||
722 | ||||
723 | if( !bUndo
| |||
724 | delete pStandardPage; | |||
725 | } | |||
726 | ||||
727 | SdPage* pNotesPage = nullptr; | |||
728 | ||||
729 | if(nDestPageNum < GetPageCount()) | |||
730 | { | |||
731 | pNotesPage = static_cast<SdPage*>(GetPage(nDestPageNum)); | |||
732 | } | |||
733 | ||||
734 | if (pNotesPage) | |||
735 | { | |||
736 | if( bPreservePageNames
| |||
737 | { | |||
738 | // Take old slide names for inserted pages | |||
739 | SdPage* pNewNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1)); | |||
740 | if( pNewNotesPage ) | |||
741 | pNewNotesPage->SetName( pStandardPage->GetRealName() ); | |||
| ||||
742 | } | |||
743 | ||||
744 | if( bUndo ) | |||
745 | AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage)); | |||
746 | ||||
747 | RemovePage(nDestPageNum); | |||
748 | ||||
749 | if( !bUndo ) | |||
750 | delete pNotesPage; | |||
751 | } | |||
752 | ||||
753 | nReplacedStandardPages++; | |||
754 | } | |||
755 | ||||
756 | nActualInsertPos += 2; | |||
757 | } | |||
758 | } | |||
759 | } | |||
760 | ||||
761 | // We might have duplicate master pages now, as the drawing engine does not | |||
762 | // recognize duplicates. Remove these now. | |||
763 | sal_uInt16 nNewMPageCount = GetMasterPageCount(); | |||
764 | ||||
765 | // Go backwards, so the numbers don't become messed up | |||
766 | for (sal_uInt16 nPage = nNewMPageCount - 1; nPage >= nMPageCount; nPage--) | |||
767 | { | |||
768 | pRefPage = static_cast<SdPage*>( GetMasterPage(nPage) ); | |||
769 | OUString aMPLayout(pRefPage->GetLayoutName()); | |||
770 | PageKind eKind = pRefPage->GetPageKind(); | |||
771 | ||||
772 | // Does this already exist? | |||
773 | for (sal_uInt16 nTest = 0; nTest < nMPageCount; nTest++) | |||
774 | { | |||
775 | SdPage* pTest = static_cast<SdPage*>( GetMasterPage(nTest) ); | |||
776 | OUString aTest(pTest->GetLayoutName()); | |||
777 | ||||
778 | // nInsertPos > 2 is always true when inserting into non-empty models | |||
779 | if ( nInsertPos > 2 && | |||
780 | aTest == aMPLayout && | |||
781 | eKind == pTest->GetPageKind() ) | |||
782 | { | |||
783 | if( bUndo ) | |||
784 | AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pRefPage)); | |||
785 | ||||
786 | RemoveMasterPage(nPage); | |||
787 | ||||
788 | if( !bUndo ) | |||
789 | delete pRefPage; | |||
790 | nNewMPageCount--; | |||
791 | break; | |||
792 | } | |||
793 | } | |||
794 | } | |||
795 | ||||
796 | // nInsertPos > 2 is always true when inserting into non-empty models | |||
797 | if (nInsertPos > 0) | |||
798 | { | |||
799 | sal_uInt16 nSdPageStart = (nInsertPos - 1) / 2; | |||
800 | sal_uInt16 nSdPageEnd = bReplace | |||
801 | ? nSdPageStart + nReplacedStandardPages - 1 | |||
802 | : GetSdPageCount(PageKind::Standard) - nSdPageCount + nSdPageStart - 1; | |||
803 | const bool bRemoveEmptyPresObj = | |||
804 | (pBookmarkDoc->GetDocumentType() == DocumentType::Impress) && | |||
805 | (GetDocumentType() == DocumentType::Draw); | |||
806 | ||||
807 | std::vector<OUString>::iterator pExchangeIter; | |||
808 | ||||
809 | if (pExchangeList) | |||
810 | pExchangeIter = pExchangeList->begin(); | |||
811 | ||||
812 | for (sal_uInt16 nSdPage = nSdPageStart; nSdPage <= nSdPageEnd; nSdPage++) | |||
813 | { | |||
814 | pRefPage = GetSdPage(nSdPage, PageKind::Standard); | |||
815 | ||||
816 | if (pExchangeList && pExchangeIter != pExchangeList->end()) | |||
817 | { | |||
818 | // Get the name to use from Exchange list | |||
819 | OUString aExchangeName(*pExchangeIter); | |||
820 | pRefPage->SetName(aExchangeName); | |||
821 | Broadcast(SdrHint(SdrHintKind::PageOrderChange, pRefPage)); | |||
822 | ||||
823 | SdPage* pNewNotesPage = GetSdPage(nSdPage, PageKind::Notes); | |||
824 | pNewNotesPage->SetName(aExchangeName); | |||
825 | Broadcast(SdrHint(SdrHintKind::PageOrderChange, pNewNotesPage)); | |||
826 | ||||
827 | ++pExchangeIter; | |||
828 | } | |||
829 | ||||
830 | OUString aLayout(pRefPage->GetLayoutName()); | |||
831 | sal_Int32 nIndex = aLayout.indexOf( SD_LT_SEPARATOR"~LT~" ); | |||
832 | if( nIndex != -1 ) | |||
833 | aLayout = aLayout.copy(0, nIndex); | |||
834 | ||||
835 | // update layout and referred master page | |||
836 | pRefPage->SetPresentationLayout(aLayout); | |||
837 | if( bUndo ) | |||
838 | AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) ); | |||
839 | ||||
840 | if (bScaleObjects) | |||
841 | { | |||
842 | ::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower); | |||
843 | pRefPage->ScaleObjects(aSize, aBorderRect, true); | |||
844 | } | |||
845 | pRefPage->SetSize(aSize); | |||
846 | pRefPage->SetBorder(nLeft, nUpper, nRight, nLower); | |||
847 | pRefPage->SetOrientation( eOrient ); | |||
848 | ||||
849 | if( bRemoveEmptyPresObj ) | |||
850 | pRefPage->RemoveEmptyPresentationObjects(); | |||
851 | ||||
852 | pRefPage = GetSdPage(nSdPage, PageKind::Notes); | |||
853 | ||||
854 | // update layout and referred master page | |||
855 | pRefPage->SetPresentationLayout(aLayout); | |||
856 | if( bUndo ) | |||
857 | AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) ); | |||
858 | ||||
859 | if (bScaleObjects) | |||
860 | { | |||
861 | ::tools::Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower); | |||
862 | pRefPage->ScaleObjects(aNSize, aBorderRect, true); | |||
863 | } | |||
864 | ||||
865 | pRefPage->SetSize(aNSize); | |||
866 | pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower); | |||
867 | pRefPage->SetOrientation( eNOrient ); | |||
868 | ||||
869 | if( bRemoveEmptyPresObj ) | |||
870 | pRefPage->RemoveEmptyPresentationObjects(); | |||
871 | } | |||
872 | ||||
873 | ///Remove processed elements, to avoid doing hacks in InsertBookmarkAsObject | |||
874 | if ( pExchangeList ) | |||
875 | pExchangeList->erase(pExchangeList->begin(),pExchangeIter); | |||
876 | ||||
877 | for (sal_uInt16 nPage = nMPageCount; nPage < nNewMPageCount; nPage++) | |||
878 | { | |||
879 | pRefPage = static_cast<SdPage*>( GetMasterPage(nPage) ); | |||
880 | if (pRefPage->GetPageKind() == PageKind::Standard) | |||
881 | { | |||
882 | if (bScaleObjects) | |||
883 | { | |||
884 | ::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower); | |||
885 | pRefPage->ScaleObjects(aSize, aBorderRect, true); | |||
886 | } | |||
887 | pRefPage->SetSize(aSize); | |||
888 | pRefPage->SetBorder(nLeft, nUpper, nRight, nLower); | |||
889 | pRefPage->SetOrientation( eOrient ); | |||
890 | } | |||
891 | else // Can only be notes | |||
892 | { | |||
893 | if (bScaleObjects) | |||
894 | { | |||
895 | ::tools::Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower); | |||
896 | pRefPage->ScaleObjects(aNSize, aBorderRect, true); | |||
897 | } | |||
898 | pRefPage->SetSize(aNSize); | |||
899 | pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower); | |||
900 | pRefPage->SetOrientation( eNOrient ); | |||
901 | } | |||
902 | ||||
903 | if( bRemoveEmptyPresObj ) | |||
904 | pRefPage->RemoveEmptyPresentationObjects(); | |||
905 | } | |||
906 | } | |||
907 | ||||
908 | // Make absolutely sure no double masterpages are there | |||
909 | RemoveUnnecessaryMasterPages(nullptr, true); | |||
910 | ||||
911 | // Rename object styles if necessary | |||
912 | if(!aRenameStr.isEmpty()) | |||
913 | { | |||
914 | try | |||
915 | { | |||
916 | for(sal_uInt32 p = nInsertPos; p < sal_uInt32(nInsertPos) + sal_uInt32(nBMSdPageCount); p++) | |||
917 | { | |||
918 | SdPage *pPg = static_cast<SdPage *>( GetPage(p) ); | |||
919 | for(size_t i = 0; pPg && (i < pPg->GetObjCount()); ++i) | |||
920 | { | |||
921 | if(pPg->GetObj(i)->GetStyleSheet()) | |||
922 | { | |||
923 | OUString aStyleName = pPg->GetObj(i)->GetStyleSheet()->GetName(); | |||
924 | SfxStyleSheet *pSheet = lcl_findStyle(aNewGraphicStyles, aStyleName + aRenameStr); | |||
925 | if(pSheet != nullptr) | |||
926 | pPg->GetObj(i)->SetStyleSheet(pSheet, true); | |||
927 | } | |||
928 | } | |||
929 | } | |||
930 | } | |||
931 | catch(...) | |||
932 | { | |||
933 | OSL_FAIL("Exception while renaming styles @ SdDrawDocument::InsertBookmarkAsPage")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/core/drawdoc3.cxx" ":" "933" ": "), "%s", "Exception while renaming styles @ SdDrawDocument::InsertBookmarkAsPage" ); } } while (false); | |||
934 | } | |||
935 | } | |||
936 | // remove copied styles not used on any inserted page and create | |||
937 | // undo records | |||
938 | // WARNING: SdMoveStyleSheetsUndoAction clears the passed list of | |||
939 | // styles, so it cannot be used after this point | |||
940 | lcl_removeUnusedStyles(GetStyleSheetPool(), aNewGraphicStyles); | |||
941 | if (!aNewGraphicStyles.empty() && pUndoMgr) | |||
942 | pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aNewGraphicStyles, true)); | |||
943 | lcl_removeUnusedStyles(GetStyleSheetPool(), aNewCellStyles); | |||
944 | if (!aNewCellStyles.empty() && pUndoMgr) | |||
945 | pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aNewCellStyles, true)); | |||
946 | ||||
947 | if( bUndo ) | |||
948 | EndUndo(); | |||
949 | ||||
950 | if (pUndoMgr) | |||
951 | pUndoMgr->LeaveListAction(); | |||
952 | ||||
953 | return bContinue; | |||
954 | } | |||
955 | ||||
956 | // Inserts a bookmark as an object | |||
957 | bool SdDrawDocument::InsertBookmarkAsObject( | |||
958 | const std::vector<OUString> &rBookmarkList, | |||
959 | const std::vector<OUString> &rExchangeList, // List of names to use | |||
960 | ::sd::DrawDocShell* pBookmarkDocSh, | |||
961 | Point const * pObjPos, | |||
962 | bool bCalcObjCount) | |||
963 | { | |||
964 | bool bOK = true; | |||
965 | bool bOLEObjFound = false; | |||
966 | std::unique_ptr<::sd::View> pBMView; | |||
967 | ||||
968 | SdDrawDocument* pBookmarkDoc = nullptr; | |||
969 | ||||
970 | if (pBookmarkDocSh) | |||
971 | { | |||
972 | pBookmarkDoc = pBookmarkDocSh->GetDoc(); | |||
973 | } | |||
974 | else if ( mxBookmarkDocShRef.is() ) | |||
975 | { | |||
976 | pBookmarkDoc = mxBookmarkDocShRef->GetDoc(); | |||
977 | } | |||
978 | else | |||
979 | { | |||
980 | return false; | |||
981 | } | |||
982 | ||||
983 | if (rBookmarkList.empty()) | |||
984 | { | |||
985 | pBMView.reset(new ::sd::View(*pBookmarkDoc, nullptr)); | |||
986 | pBMView->EndListening(*pBookmarkDoc); | |||
987 | pBMView->MarkAll(); | |||
988 | } | |||
989 | else | |||
990 | { | |||
991 | SdrPage* pPage; | |||
992 | SdrPageView* pPV; | |||
993 | ||||
994 | for ( const auto& rBookmark : rBookmarkList ) | |||
995 | { | |||
996 | // Get names of bookmarks from the list | |||
997 | SdrObject* pObj = pBookmarkDoc->GetObj(rBookmark); | |||
998 | ||||
999 | if (pObj) | |||
1000 | { | |||
1001 | // Found an object | |||
1002 | if (pObj->GetObjInventor() == SdrInventor::Default && | |||
1003 | pObj->GetObjIdentifier() == OBJ_OLE2) | |||
1004 | { | |||
1005 | bOLEObjFound = true; | |||
1006 | } | |||
1007 | ||||
1008 | if (!pBMView) | |||
1009 | { | |||
1010 | // Create View for the first time | |||
1011 | pBMView.reset(new ::sd::View(*pBookmarkDoc, nullptr)); | |||
1012 | pBMView->EndListening(*pBookmarkDoc); | |||
1013 | } | |||
1014 | ||||
1015 | pPage = pObj->getSdrPageFromSdrObject(); | |||
1016 | ||||
1017 | if (pPage->IsMasterPage()) | |||
1018 | { | |||
1019 | pPV = pBMView->ShowSdrPage(pBMView->GetModel()->GetMasterPage(pPage->GetPageNum())); | |||
1020 | } | |||
1021 | else | |||
1022 | { | |||
1023 | pPV = pBMView->GetSdrPageView(); | |||
1024 | if( !pPV || (pPV->GetPage() != pPage)) | |||
1025 | pPV = pBMView->ShowSdrPage(pPage); | |||
1026 | } | |||
1027 | ||||
1028 | pBMView->MarkObj(pObj, pPV); | |||
1029 | } | |||
1030 | } | |||
1031 | } | |||
1032 | ||||
1033 | if (pBMView) | |||
1034 | { | |||
1035 | // Insert selected objects | |||
1036 | std::unique_ptr<::sd::View> pView(new ::sd::View(*this, nullptr)); | |||
1037 | pView->EndListening(*this); | |||
1038 | ||||
1039 | // Look for the page into which the objects are supposed to be inserted | |||
1040 | SdrPage* pPage = GetSdPage(0, PageKind::Standard); | |||
1041 | ||||
1042 | if (mpDocSh) | |||
1043 | { | |||
1044 | ::sd::ViewShell* pViewSh = mpDocSh->GetViewShell(); | |||
1045 | ||||
1046 | if (pViewSh) | |||
1047 | { | |||
1048 | // Which page is currently in view? | |||
1049 | SdrPageView* pPV = pViewSh->GetView()->GetSdrPageView(); | |||
1050 | ||||
1051 | if (pPV) | |||
1052 | { | |||
1053 | pPage = pPV->GetPage(); | |||
1054 | } | |||
1055 | else if (pViewSh->GetActualPage()) | |||
1056 | { | |||
1057 | pPage = pViewSh->GetActualPage(); | |||
1058 | } | |||
1059 | } | |||
1060 | } | |||
1061 | ||||
1062 | Point aObjPos; | |||
1063 | ||||
1064 | if (pObjPos) | |||
1065 | { | |||
1066 | aObjPos = *pObjPos; | |||
1067 | } | |||
1068 | else | |||
1069 | { | |||
1070 | aObjPos = ::tools::Rectangle(Point(), pPage->GetSize()).Center(); | |||
1071 | } | |||
1072 | ||||
1073 | size_t nCountBefore = 0; | |||
1074 | ||||
1075 | if (!rExchangeList.empty() || bCalcObjCount) | |||
1076 | { | |||
1077 | // Sort OrdNums and get the number of objects before inserting | |||
1078 | pPage->RecalcObjOrdNums(); | |||
1079 | nCountBefore = pPage->GetObjCount(); | |||
1080 | } | |||
1081 | ||||
1082 | if (bOLEObjFound) | |||
1083 | pBMView->GetDoc().SetAllocDocSh(true); | |||
1084 | ||||
1085 | SdDrawDocument* pTmpDoc = static_cast<SdDrawDocument*>( pBMView->CreateMarkedObjModel().release() ); | |||
1086 | bOK = pView->Paste(*pTmpDoc, aObjPos, pPage, SdrInsertFlags::NONE); | |||
1087 | ||||
1088 | if (bOLEObjFound) | |||
1089 | pBMView->GetDoc().SetAllocDocSh(false); | |||
1090 | ||||
1091 | if (!bOLEObjFound) | |||
1092 | delete pTmpDoc; // Would otherwise be destroyed by DocShell | |||
1093 | ||||
1094 | pView.reset(); | |||
1095 | ||||
1096 | // Get number of objects after inserting. | |||
1097 | const size_t nCount = pPage->GetObjCount(); | |||
1098 | if (nCountBefore < nCount) | |||
1099 | { | |||
1100 | size_t nObj = nCountBefore; | |||
1101 | for (const auto& rExchange : rExchangeList) | |||
1102 | { | |||
1103 | // Get the name to use from the Exchange list | |||
1104 | if (pPage->GetObj(nObj)) | |||
1105 | { | |||
1106 | pPage->GetObj(nObj)->SetName(rExchange); | |||
1107 | } | |||
1108 | ||||
1109 | ++nObj; | |||
1110 | if (nObj >= nCount) | |||
1111 | break; | |||
1112 | } | |||
1113 | } | |||
1114 | } | |||
1115 | ||||
1116 | return bOK; | |||
1117 | } | |||
1118 | ||||
1119 | // Stops the bookmark insertion | |||
1120 | void SdDrawDocument::CloseBookmarkDoc() | |||
1121 | { | |||
1122 | if (mxBookmarkDocShRef.is()) | |||
1123 | { | |||
1124 | mxBookmarkDocShRef->DoClose(); | |||
1125 | } | |||
1126 | ||||
1127 | mxBookmarkDocShRef.clear(); | |||
1128 | maBookmarkFile.clear(); | |||
1129 | } | |||
1130 | ||||
1131 | // Is this document read-only? | |||
1132 | bool SdDrawDocument::IsReadOnly() const | |||
1133 | { | |||
1134 | return false; | |||
1135 | } | |||
1136 | ||||
1137 | // In the subsequent AllocModel() a DocShell (xAllocedDocShRef) is created. | |||
1138 | // Any pre-existing DocShell is deleted | |||
1139 | void SdDrawDocument::SetAllocDocSh(bool bAlloc) | |||
1140 | { | |||
1141 | mbAllocDocSh = bAlloc; | |||
1142 | ||||
1143 | if(mxAllocedDocShRef.is()) | |||
1144 | { | |||
1145 | mxAllocedDocShRef->DoClose(); | |||
1146 | } | |||
1147 | ||||
1148 | mxAllocedDocShRef.clear(); | |||
1149 | } | |||
1150 | ||||
1151 | // Return list of CustomShows (create it, too, if necessary) | |||
1152 | SdCustomShowList* SdDrawDocument::GetCustomShowList(bool bCreate) | |||
1153 | { | |||
1154 | if (!mpCustomShowList && bCreate) | |||
1155 | { | |||
1156 | mpCustomShowList.reset(new SdCustomShowList); | |||
1157 | } | |||
1158 | ||||
1159 | return mpCustomShowList.get(); | |||
1160 | } | |||
1161 | ||||
1162 | // Remove unused master pages and layouts | |||
1163 | void SdDrawDocument::RemoveUnnecessaryMasterPages(SdPage* pMasterPage, bool bOnlyDuplicatePages, bool bUndo) | |||
1164 | { | |||
1165 | ::sd::View* pView = nullptr; | |||
1166 | SfxUndoManager* pUndoMgr = nullptr; | |||
1167 | ||||
1168 | if( bUndo && !IsUndoEnabled() ) | |||
1169 | bUndo = false; | |||
1170 | ||||
1171 | if (mpDocSh) | |||
1172 | { | |||
1173 | pUndoMgr = mpDocSh->GetUndoManager(); | |||
1174 | ||||
1175 | if (mpDocSh->GetViewShell()) | |||
1176 | pView = mpDocSh->GetViewShell()->GetView(); | |||
1177 | } | |||
1178 | ||||
1179 | // Check all master pages | |||
1180 | sal_uInt16 nSdMasterPageCount = GetMasterSdPageCount( PageKind::Standard ); | |||
1181 | for (sal_Int32 nMPage = nSdMasterPageCount - 1; nMPage >= 0; nMPage--) | |||
1182 | { | |||
1183 | SdPage* pMaster = pMasterPage; | |||
1184 | SdPage* pNotesMaster = nullptr; | |||
1185 | ||||
1186 | if (!pMaster) | |||
1187 | { | |||
1188 | pMaster = GetMasterSdPage( static_cast<sal_uInt16>(nMPage), PageKind::Standard ); | |||
1189 | pNotesMaster = GetMasterSdPage( static_cast<sal_uInt16>(nMPage), PageKind::Notes ); | |||
1190 | } | |||
1191 | else | |||
1192 | { | |||
1193 | for ( sal_uInt16 nMPg = 0; nMPg < GetMasterPageCount(); nMPg++ ) | |||
1194 | { | |||
1195 | if ( pMaster == GetMasterPage( nMPg ) ) | |||
1196 | { | |||
1197 | pNotesMaster = static_cast<SdPage*>( GetMasterPage( ++nMPg ) ); | |||
1198 | break; | |||
1199 | } | |||
1200 | } | |||
1201 | } | |||
1202 | ||||
1203 | DBG_ASSERT( pMaster->GetPageKind() == PageKind::Standard, "wrong page kind" )do { if (true && (!(pMaster->GetPageKind() == PageKind ::Standard))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/core/drawdoc3.cxx" ":" "1203" ": "), "%s", "wrong page kind"); } } while (false ); | |||
1204 | ||||
1205 | if ( pMaster->GetPageKind() == PageKind::Standard && | |||
1206 | GetMasterPageUserCount( pMaster ) == 0 && | |||
1207 | pNotesMaster ) | |||
1208 | { | |||
1209 | // Do not delete master pages that have their precious flag set | |||
1210 | bool bDeleteMaster = !pMaster->IsPrecious(); | |||
1211 | OUString aLayoutName = pMaster->GetLayoutName(); | |||
1212 | ||||
1213 | if(bOnlyDuplicatePages ) | |||
1214 | { | |||
1215 | // remove only duplicate pages | |||
1216 | bDeleteMaster = false; | |||
1217 | for (sal_uInt16 i = 0; i < GetMasterSdPageCount( PageKind::Standard ); i++) | |||
1218 | { | |||
1219 | SdPage* pMPg = GetMasterSdPage( i, PageKind::Standard ); | |||
1220 | if( pMPg != pMaster && | |||
1221 | pMPg->GetLayoutName() == aLayoutName ) | |||
1222 | { | |||
1223 | // duplicate page found -> remove it | |||
1224 | bDeleteMaster = true; | |||
1225 | } | |||
1226 | } | |||
1227 | } | |||
1228 | ||||
1229 | if( bDeleteMaster ) | |||
1230 | { | |||
1231 | if (pView) | |||
1232 | { | |||
1233 | // if MasterPage is visible hide on pageview | |||
1234 | SdrPageView* pPgView = pView->GetSdrPageView(); | |||
1235 | if (pPgView) | |||
1236 | { | |||
1237 | SdrPage* pShownPage = pPgView->GetPage(); | |||
1238 | if( (pShownPage == pMaster) || (pShownPage == pNotesMaster) ) | |||
1239 | { | |||
1240 | pView->HideSdrPage(); | |||
1241 | pView->ShowSdrPage( GetSdPage( 0, PageKind::Standard ) ); | |||
1242 | } | |||
1243 | } | |||
1244 | } | |||
1245 | ||||
1246 | if( bUndo ) | |||
1247 | { | |||
1248 | BegUndo(); | |||
1249 | AddUndo( GetSdrUndoFactory().CreateUndoDeletePage( *pNotesMaster ) ); | |||
1250 | } | |||
1251 | ||||
1252 | RemoveMasterPage( pNotesMaster->GetPageNum() ); | |||
1253 | ||||
1254 | if( !bUndo ) | |||
1255 | delete pNotesMaster; | |||
1256 | ||||
1257 | if( bUndo ) | |||
1258 | AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pMaster)); | |||
1259 | ||||
1260 | RemoveMasterPage( pMaster->GetPageNum() ); | |||
1261 | ||||
1262 | if( !bUndo ) | |||
1263 | delete pMaster; | |||
1264 | ||||
1265 | if( bUndo ) | |||
1266 | EndUndo(); // do this here already, so Joe's actions happen _between_ our own | |||
1267 | ||||
1268 | // Delete old, unused layout stylesheets | |||
1269 | bool bDeleteOldStyleSheets = true; | |||
1270 | for ( sal_uInt16 nMPg = 0; | |||
1271 | nMPg < GetMasterPageCount() && bDeleteOldStyleSheets; | |||
1272 | nMPg++ ) | |||
1273 | { | |||
1274 | SdPage* pMPg = static_cast<SdPage*>( GetMasterPage(nMPg) ); | |||
1275 | if (pMPg->GetLayoutName() == aLayoutName) | |||
1276 | { | |||
1277 | bDeleteOldStyleSheets = false; | |||
1278 | } | |||
1279 | } | |||
1280 | ||||
1281 | if (bDeleteOldStyleSheets) | |||
1282 | { | |||
1283 | SdStyleSheetVector aRemove; | |||
1284 | static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList( aLayoutName, aRemove ); | |||
1285 | ||||
1286 | if( bUndo ) | |||
1287 | { | |||
1288 | StyleSheetCopyResultVector aUndoRemove; | |||
1289 | aUndoRemove.reserve(aRemove.size()); | |||
1290 | for (const auto& a : aRemove) | |||
1291 | aUndoRemove.emplace_back(a.get(), true); | |||
1292 | ||||
1293 | if (pUndoMgr) | |||
1294 | pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aUndoRemove, false)); | |||
1295 | } | |||
1296 | ||||
1297 | for( const auto& a : aRemove ) | |||
1298 | static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->Remove(a.get()); | |||
1299 | } | |||
1300 | } | |||
1301 | } | |||
1302 | ||||
1303 | if (pMasterPage) | |||
1304 | break; // Just this one master page! | |||
1305 | } | |||
1306 | } | |||
1307 | ||||
1308 | /** Exchange master page | |||
1309 | * | |||
1310 | * Either the nSdPageNum gets a new, own master page or the master page is | |||
1311 | * exchanged completely (which then applies to all pages). | |||
1312 | * | |||
1313 | * nSdPageNum : page number that the new master page should get. | |||
1314 | * rLayoutName : LayoutName of the new master page | |||
1315 | * pSourceDoc : document (template) to get the master page from | |||
1316 | * bMaster : exchange the master page of nSdPageNum | |||
1317 | * bCheckMasters: remove unused master pages | |||
1318 | * | |||
1319 | * If pSourceDoc == NULL, an empty master page is applied. | |||
1320 | * If rLayoutName is empty, the first master page is used. | |||
1321 | */ | |||
1322 | // #i121863# factored out functionality | |||
1323 | static bool isMasterPageLayoutNameUnique(const SdDrawDocument& rDoc, const OUString& rCandidate) | |||
1324 | { | |||
1325 | if (rCandidate.isEmpty()) | |||
1326 | { | |||
1327 | return false; | |||
1328 | } | |||
1329 | ||||
1330 | const sal_uInt16 nPageCount(rDoc.GetMasterPageCount()); | |||
1331 | ||||
1332 | for(sal_uInt16 a(0); a < nPageCount; a++) | |||
1333 | { | |||
1334 | const SdrPage* pCandidate = rDoc.GetMasterPage(a); | |||
1335 | OUString aPageLayoutName(pCandidate->GetLayoutName()); | |||
1336 | sal_Int32 nIndex = aPageLayoutName.indexOf(SD_LT_SEPARATOR"~LT~"); | |||
1337 | if( nIndex != -1 ) | |||
1338 | aPageLayoutName = aPageLayoutName.copy(0, nIndex); | |||
1339 | ||||
1340 | if(aPageLayoutName == rCandidate) | |||
1341 | { | |||
1342 | return false; | |||
1343 | } | |||
1344 | } | |||
1345 | ||||
1346 | return true; | |||
1347 | } | |||
1348 | ||||
1349 | // #i121863# factored out functionality | |||
1350 | static OUString createNewMasterPageLayoutName(const SdDrawDocument& rDoc) | |||
1351 | { | |||
1352 | const OUString aBaseName(SdResId(STR_LAYOUT_DEFAULT_NAMEreinterpret_cast<char const *>("STR_LAYOUT_DEFAULT_NAME" "\004" u8"Default"))); | |||
1353 | sal_uInt16 nCount(0); | |||
1354 | for (;;) | |||
1355 | { | |||
1356 | OUString aRetval = aBaseName; | |||
1357 | if(nCount) | |||
1358 | { | |||
1359 | aRetval += OUString::number(nCount); | |||
1360 | } | |||
1361 | if (isMasterPageLayoutNameUnique(rDoc, aRetval)) | |||
1362 | return aRetval; | |||
1363 | nCount++; | |||
1364 | } | |||
1365 | } | |||
1366 | ||||
1367 | void SdDrawDocument::SetMasterPage(sal_uInt16 nSdPageNum, | |||
1368 | const OUString& rLayoutName, | |||
1369 | SdDrawDocument* pSourceDoc, | |||
1370 | bool bMaster, | |||
1371 | bool bCheckMasters) | |||
1372 | { | |||
1373 | SfxUndoManager* pUndoMgr = nullptr; | |||
1374 | ||||
1375 | if( mpDocSh ) | |||
1376 | { | |||
1377 | mpDocSh->SetWaitCursor( true ); | |||
1378 | pUndoMgr = mpDocSh->GetUndoManager(); | |||
1379 | } | |||
1380 | ||||
1381 | const bool bUndo = pUndoMgr && IsUndoEnabled(); | |||
1382 | ||||
1383 | if (bUndo) | |||
1384 | { | |||
1385 | ViewShellId nViewShellId(-1); | |||
1386 | if (sd::ViewShell* pViewShell = mpDocSh->GetViewShell()) | |||
1387 | nViewShellId = pViewShell->GetViewShellBase().GetViewShellId(); | |||
1388 | pUndoMgr->EnterListAction(SdResId(STR_UNDO_SET_PRESLAYOUTreinterpret_cast<char const *>("STR_UNDO_SET_PRESLAYOUT" "\004" u8"Apply presentation layout")), OUString(), 0, nViewShellId); | |||
1389 | } | |||
1390 | ||||
1391 | SdPage* pSelectedPage = GetSdPage(nSdPageNum, PageKind::Standard); | |||
1392 | SdPage* pNotes = static_cast<SdPage*>( GetPage(pSelectedPage->GetPageNum()+1) ); | |||
1393 | SdPage& rOldMaster = static_cast<SdPage&>(pSelectedPage->TRG_GetMasterPage()); | |||
1394 | SdPage& rOldNotesMaster = static_cast<SdPage&>(pNotes->TRG_GetMasterPage()); | |||
1395 | SdPage* pMaster = nullptr; | |||
1396 | SdPage* pNotesMaster = nullptr; | |||
1397 | OUString aOldPageLayoutName(pSelectedPage->GetLayoutName()); | |||
1398 | OUString aOldLayoutName(aOldPageLayoutName); | |||
1399 | sal_Int32 nIndex = aOldLayoutName.indexOf( SD_LT_SEPARATOR"~LT~" ); | |||
1400 | if( nIndex != -1 ) | |||
1401 | aOldLayoutName = aOldLayoutName.copy(0, nIndex); | |||
1402 | ||||
1403 | if (pSourceDoc) | |||
1404 | { | |||
1405 | std::vector<StyleReplaceData> aReplList; // List of replaced stylesheets | |||
1406 | bool bLayoutReloaded = false; // Was ex. layout reloaded? | |||
1407 | ||||
1408 | // LayoutName, Page and Notes page | |||
1409 | if (rLayoutName.isEmpty()) | |||
1410 | { | |||
1411 | // No LayoutName: take first MasterPage | |||
1412 | pMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Standard); | |||
1413 | pNotesMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Notes); | |||
1414 | } | |||
1415 | else | |||
1416 | { | |||
1417 | OUString aSearchFor = rLayoutName + SD_LT_SEPARATOR"~LT~" STR_LAYOUT_OUTLINE"Gliederung"; | |||
1418 | ||||
1419 | for (sal_uInt16 nMP = 0; nMP < pSourceDoc->GetMasterPageCount(); ++nMP) | |||
1420 | { | |||
1421 | SdPage* pMP = static_cast<SdPage*>( pSourceDoc->GetMasterPage(nMP) ); | |||
1422 | ||||
1423 | if (pMP->GetLayoutName() == aSearchFor) | |||
1424 | { | |||
1425 | if (pMP->GetPageKind() == PageKind::Standard) | |||
1426 | pMaster = pMP; | |||
1427 | if (pMP->GetPageKind() == PageKind::Notes) | |||
1428 | pNotesMaster = pMP; | |||
1429 | } | |||
1430 | if (pMaster && pNotesMaster) | |||
1431 | break; | |||
1432 | } | |||
1433 | DBG_ASSERT(pMaster, "MasterPage (Standard page) not found")do { if (true && (!(pMaster))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/core/drawdoc3.cxx" ":" "1433" ": "), "%s", "MasterPage (Standard page) not found" ); } } while (false); | |||
1434 | DBG_ASSERT(pNotesMaster, "MasterPage (Notes page) not found")do { if (true && (!(pNotesMaster))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/core/drawdoc3.cxx" ":" "1434" ": "), "%s", "MasterPage (Notes page) not found") ; } } while (false); | |||
1435 | ||||
1436 | // this should not happen, but looking at crash reports, it does | |||
1437 | if( (pMaster == nullptr) || (pNotesMaster == nullptr) ) | |||
1438 | { | |||
1439 | // so take the first MasterPage | |||
1440 | pMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Standard); | |||
1441 | pNotesMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Notes); | |||
1442 | } | |||
1443 | } | |||
1444 | ||||
1445 | // we should never reach this, but one never knows... | |||
1446 | if( (pMaster == nullptr) || (pNotesMaster == nullptr) ) | |||
1447 | { | |||
1448 | if (bUndo) | |||
1449 | pUndoMgr->LeaveListAction(); | |||
1450 | ||||
1451 | if( mpDocSh ) | |||
1452 | mpDocSh->SetWaitCursor( false ); | |||
1453 | ||||
1454 | OSL_FAIL( "SdDrawDocument::SetMasterPage() failed!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/core/drawdoc3.cxx" ":" "1454" ": "), "%s", "SdDrawDocument::SetMasterPage() failed!" ); } } while (false); | |||
1455 | ||||
1456 | return; | |||
1457 | } | |||
1458 | ||||
1459 | const OUString aOriginalNewLayoutName( pMaster->GetName() ); | |||
1460 | OUString aTargetNewLayoutName(aOriginalNewLayoutName); | |||
1461 | ||||
1462 | if (pSourceDoc != this) | |||
1463 | { | |||
1464 | // #i121863# clone masterpages, they are from another model (!) | |||
1465 | std::unique_ptr<SdPage> pNewNotesMaster(dynamic_cast< SdPage* >(pNotesMaster->CloneSdrPage(*this))); | |||
1466 | std::unique_ptr<SdPage> pNewMaster(dynamic_cast< SdPage* >(pMaster->CloneSdrPage(*this))); | |||
1467 | ||||
1468 | if(!pNewNotesMaster || !pNewMaster) | |||
1469 | { | |||
1470 | OSL_FAIL("SdDrawDocument::SetMasterPage() cloning of MasterPage/NoteAmsterPage failed!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/core/drawdoc3.cxx" ":" "1470" ": "), "%s", "SdDrawDocument::SetMasterPage() cloning of MasterPage/NoteAmsterPage failed!" ); } } while (false); | |||
1471 | return; | |||
1472 | } | |||
1473 | ||||
1474 | pNotesMaster = pNewNotesMaster.release(); | |||
1475 | pMaster = pNewMaster.release(); | |||
1476 | ||||
1477 | // layout name needs to be unique | |||
1478 | aTargetNewLayoutName = pMaster->GetLayoutName(); | |||
1479 | sal_Int32 nIndex2 = aTargetNewLayoutName.indexOf(SD_LT_SEPARATOR"~LT~"); | |||
1480 | if( nIndex2 != -1 ) | |||
1481 | aTargetNewLayoutName = aTargetNewLayoutName.copy(0, nIndex2); | |||
1482 | ||||
1483 | if(!isMasterPageLayoutNameUnique(*this, aTargetNewLayoutName)) | |||
1484 | { | |||
1485 | aTargetNewLayoutName = createNewMasterPageLayoutName(*this); | |||
1486 | ||||
1487 | OUString aTemp = aTargetNewLayoutName + SD_LT_SEPARATOR"~LT~" STR_LAYOUT_OUTLINE"Gliederung"; | |||
1488 | ||||
1489 | pMaster->SetName(aTargetNewLayoutName); | |||
1490 | pMaster->SetLayoutName(aTemp); | |||
1491 | ||||
1492 | pNotesMaster->SetName(aTargetNewLayoutName); | |||
1493 | pNotesMaster->SetLayoutName(aTemp); | |||
1494 | } | |||
1495 | } | |||
1496 | ||||
1497 | if (pSourceDoc != this) | |||
1498 | { | |||
1499 | const sal_uInt16 nMasterPageCount = GetMasterPageCount(); | |||
1500 | for ( sal_uInt16 nMPage = 0; nMPage < nMasterPageCount; nMPage++ ) | |||
1501 | { | |||
1502 | SdPage* pCheckMaster = static_cast<SdPage*>(GetMasterPage(nMPage)); | |||
1503 | if( pCheckMaster->GetName() == aTargetNewLayoutName ) | |||
1504 | { | |||
1505 | bLayoutReloaded = true; | |||
1506 | break; | |||
1507 | } | |||
1508 | } | |||
1509 | ||||
1510 | // Correct or create presentation templates -- | |||
1511 | // only worry about presentation templates | |||
1512 | OUString aName; | |||
1513 | SdStyleSheetPool* pSourceStyleSheetPool = static_cast<SdStyleSheetPool*>( pSourceDoc->GetStyleSheetPool() ); | |||
1514 | ||||
1515 | StyleSheetCopyResultVector aCreatedStyles; // List of created stylesheets | |||
1516 | SfxStyleSheetBase* pHisSheet = pSourceStyleSheetPool->First(SfxStyleFamily::Page); | |||
1517 | ||||
1518 | while (pHisSheet) | |||
1519 | { | |||
1520 | aName = pHisSheet->GetName(); | |||
1521 | ||||
1522 | // #i121863# search in source styles with original style name from source of | |||
1523 | // evtl. cloned master (not-cloned, renamed for uniqueness) | |||
1524 | if( aName.startsWith( aOriginalNewLayoutName ) ) | |||
1525 | { | |||
1526 | // #i121863# build name of evtl. cloned master style to search for | |||
1527 | if(aOriginalNewLayoutName != aTargetNewLayoutName) | |||
1528 | { | |||
1529 | const sal_Int32 nPos(aName.indexOf(SD_LT_SEPARATOR"~LT~")); | |||
1530 | aName = aTargetNewLayoutName + aName.copy(nPos); | |||
1531 | } | |||
1532 | ||||
1533 | SfxStyleSheet* pMySheet = static_cast<SfxStyleSheet*>( mxStyleSheetPool->Find(aName, SfxStyleFamily::Page) ); | |||
1534 | ||||
1535 | if (pMySheet) | |||
1536 | { | |||
1537 | // A stylesheet of the same name already exists -> overwrite contents | |||
1538 | bool bTest = pMySheet->SetName(pHisSheet->GetName()); | |||
1539 | DBG_ASSERT(bTest, "Renaming StyleSheet failed.")do { if (true && (!(bTest))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/core/drawdoc3.cxx" ":" "1539" ": "), "%s", "Renaming StyleSheet failed."); } } while (false); | |||
1540 | pMySheet->GetItemSet().ClearItem(); // Delete all | |||
1541 | ||||
1542 | if (bUndo) | |||
1543 | { | |||
1544 | pUndoMgr->AddUndoAction(std::make_unique<StyleSheetUndoAction>(this, | |||
1545 | pMySheet, &pHisSheet->GetItemSet())); | |||
1546 | } | |||
1547 | pMySheet->GetItemSet().Put(pHisSheet->GetItemSet()); | |||
1548 | pMySheet->Broadcast(SfxHint(SfxHintId::DataChanged)); | |||
1549 | } | |||
1550 | else | |||
1551 | { | |||
1552 | // create new style | |||
1553 | OUString aHelpFile; | |||
1554 | pMySheet = static_cast<SfxStyleSheet*>( &mxStyleSheetPool->Make(aName, SfxStyleFamily::Page, pHisSheet->GetMask()) ); | |||
1555 | pMySheet->SetHelpId( aHelpFile, pHisSheet->GetHelpId(aHelpFile) ); | |||
1556 | pMySheet->GetItemSet().ClearItem(); // Delete all | |||
1557 | pMySheet->GetItemSet().Put(pHisSheet->GetItemSet()); | |||
1558 | ||||
1559 | aCreatedStyles.emplace_back(static_cast<SdStyleSheet*>(pMySheet), true); | |||
1560 | } | |||
1561 | ||||
1562 | StyleReplaceData aReplData; | |||
1563 | aReplData.nNewFamily = pMySheet->GetFamily(); | |||
1564 | aReplData.nFamily = pMySheet->GetFamily(); | |||
1565 | aReplData.aNewName = pMySheet->GetName(); | |||
1566 | ||||
1567 | // #i121863# re-create original name of style used at page where to replace with | |||
1568 | // this new style | |||
1569 | OUString aTemp(pMySheet->GetName()); | |||
1570 | const sal_Int32 nPos(aTemp.indexOf(SD_LT_SEPARATOR"~LT~")); | |||
1571 | aTemp = aOldLayoutName + aTemp.copy(nPos); | |||
1572 | aReplData.aName = aTemp; | |||
1573 | aReplList.push_back(aReplData); | |||
1574 | } | |||
1575 | ||||
1576 | pHisSheet = pSourceStyleSheetPool->Next(); | |||
1577 | } | |||
1578 | ||||
1579 | // If new styles were created: re-create parent chaining of the item | |||
1580 | // sets in the styles. | |||
1581 | if(!aCreatedStyles.empty()) | |||
1582 | { | |||
1583 | for ( const auto& rRData : aReplList ) | |||
1584 | { | |||
1585 | SfxStyleSheetBase* pSOld = mxStyleSheetPool->Find(rRData.aName, SfxStyleFamily::Page); | |||
1586 | SfxStyleSheetBase* pSNew = mxStyleSheetPool->Find(rRData.aNewName, SfxStyleFamily::Page); | |||
1587 | ||||
1588 | if (pSOld && pSNew) | |||
1589 | { | |||
1590 | const OUString& rParentOfOld = pSOld->GetParent(); | |||
1591 | const OUString& rParentOfNew = pSNew->GetParent(); | |||
1592 | ||||
1593 | if (!rParentOfOld.isEmpty() && rParentOfNew.isEmpty()) | |||
1594 | { | |||
1595 | std::vector<StyleReplaceData>::iterator pRDIter = std::find_if(aReplList.begin(), aReplList.end(), | |||
1596 | [&rParentOfOld](const StyleReplaceData& rRD) { return (rRD.aName == rParentOfOld) && (rRD.aName != rRD.aNewName); }); | |||
1597 | if (pRDIter != aReplList.end()) | |||
1598 | { | |||
1599 | OUString aParentOfNew(pRDIter->aNewName); | |||
1600 | pSNew->SetParent(aParentOfNew); | |||
1601 | } | |||
1602 | } | |||
1603 | } | |||
1604 | } | |||
1605 | } | |||
1606 | ||||
1607 | if (bUndo && !aCreatedStyles.empty()) | |||
1608 | { | |||
1609 | // Add UndoAction for creating and inserting the stylesheets to | |||
1610 | // the top of the UndoManager | |||
1611 | pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>( this, aCreatedStyles, true)); | |||
1612 | } | |||
1613 | } | |||
1614 | ||||
1615 | // Create layout name based upon the name of the page layout of the | |||
1616 | // master page | |||
1617 | OUString aPageLayoutName(pMaster->GetLayoutName()); | |||
1618 | OUString aLayoutName = aPageLayoutName; | |||
1619 | sal_Int32 nIndex2 = aLayoutName.indexOf( SD_LT_SEPARATOR"~LT~" ); | |||
1620 | if( nIndex2 != -1 ) | |||
1621 | aLayoutName = aLayoutName.copy( 0, nIndex2); | |||
1622 | ||||
1623 | // #i121863# Do *not* remove from original document any longer, it is potentially used there | |||
1624 | // and would lead to crashes. Rely on the automatic process of removing unused masterpages | |||
1625 | // (see RemoveUnnecessaryMasterPages) | |||
1626 | //if (pSourceDoc != this) | |||
1627 | //{ | |||
1628 | // // Remove from the source document | |||
1629 | // pSourceDoc->RemoveMasterPage(pNotesMaster->GetPageNum()); | |||
1630 | // pSourceDoc->RemoveMasterPage(pMaster->GetPageNum()); | |||
1631 | //} | |||
1632 | ||||
1633 | // Register the new master pages with the document and then use | |||
1634 | // the new presentation layout for the default and notes pages | |||
1635 | if (pSourceDoc != this) | |||
1636 | { | |||
1637 | // Insert the master pages: | |||
1638 | // Insert master pages from new layouts at the end. | |||
1639 | // If a layout is being replaced, however, insert them before the | |||
1640 | // position of the old master page, so from now on the new master | |||
1641 | // page will be found when searching (e.g. | |||
1642 | // SdPage::SetPresentationLayout). | |||
1643 | sal_uInt16 nInsertPos = rOldMaster.GetPageNum(); | |||
1644 | BegUndo(); | |||
1645 | ||||
1646 | if (!bLayoutReloaded) | |||
1647 | nInsertPos = 0xFFFF; | |||
1648 | InsertMasterPage(pMaster, nInsertPos); | |||
1649 | if( bUndo ) | |||
1650 | AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster)); | |||
1651 | ||||
1652 | nInsertPos++; | |||
1653 | if (!bLayoutReloaded) | |||
1654 | nInsertPos = 0xFFFF; | |||
1655 | InsertMasterPage(pNotesMaster, nInsertPos); | |||
1656 | if( bUndo ) | |||
1657 | { | |||
1658 | AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster)); | |||
1659 | ||||
1660 | EndUndo(); // do this here already, so Joe's actions happen _between_ our own. | |||
1661 | } | |||
1662 | } | |||
1663 | ||||
1664 | // Fill list with pages | |||
1665 | std::vector<SdPage*> aPageList; | |||
1666 | ||||
1667 | // #98456, this has to be removed according to CL (KA 07/08/2002) | |||
1668 | // #109884# but we need them again to restore the styles of the presentation objects while undo | |||
1669 | aPageList.push_back(pMaster); | |||
1670 | aPageList.push_back(pNotesMaster); | |||
1671 | ||||
1672 | if (bMaster || bLayoutReloaded) | |||
1673 | { | |||
1674 | for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++) | |||
1675 | { | |||
1676 | SdPage* pPage = static_cast<SdPage*>( GetPage(nPage) ); | |||
1677 | OUString aTest = pPage->GetLayoutName(); | |||
1678 | if (aTest == aOldPageLayoutName) | |||
1679 | { | |||
1680 | aPageList.push_back(pPage); | |||
1681 | } | |||
1682 | } | |||
1683 | ||||
1684 | } | |||
1685 | else | |||
1686 | { | |||
1687 | aPageList.push_back(pSelectedPage); | |||
1688 | aPageList.push_back(pNotes); | |||
1689 | } | |||
1690 | ||||
1691 | for (SdPage* pPage : aPageList) | |||
1692 | { | |||
1693 | AutoLayout eAutoLayout = pPage->GetAutoLayout(); | |||
1694 | ||||
1695 | if( bUndo ) | |||
1696 | { | |||
1697 | pUndoMgr->AddUndoAction(std::make_unique<SdPresentationLayoutUndoAction> | |||
1698 | (this, | |||
1699 | pPage->IsMasterPage() ? aLayoutName : aOldLayoutName, | |||
1700 | aLayoutName, | |||
1701 | eAutoLayout, eAutoLayout, false, pPage)); | |||
1702 | } | |||
1703 | pPage->SetPresentationLayout(aLayoutName); | |||
1704 | pPage->SetAutoLayout(eAutoLayout); | |||
1705 | } | |||
1706 | ||||
1707 | // Adapt new master pages | |||
1708 | if (pSourceDoc != this) | |||
1709 | { | |||
1710 | Size aSize(rOldMaster.GetSize()); | |||
1711 | ::tools::Rectangle aBorderRect(rOldMaster.GetLeftBorder(), | |||
1712 | rOldMaster.GetUpperBorder(), | |||
1713 | rOldMaster.GetRightBorder(), | |||
1714 | rOldMaster.GetLowerBorder()); | |||
1715 | pMaster->ScaleObjects(aSize, aBorderRect, true); | |||
1716 | pMaster->SetSize(aSize); | |||
1717 | pMaster->SetBorder(rOldMaster.GetLeftBorder(), | |||
1718 | rOldMaster.GetUpperBorder(), | |||
1719 | rOldMaster.GetRightBorder(), | |||
1720 | rOldMaster.GetLowerBorder()); | |||
1721 | pMaster->SetOrientation( rOldMaster.GetOrientation() ); | |||
1722 | pMaster->SetAutoLayout(pMaster->GetAutoLayout()); | |||
1723 | ||||
1724 | aSize = rOldNotesMaster.GetSize(); | |||
1725 | ::tools::Rectangle aNotesBorderRect(rOldNotesMaster.GetLeftBorder(), | |||
1726 | rOldNotesMaster.GetUpperBorder(), | |||
1727 | rOldNotesMaster.GetRightBorder(), | |||
1728 | rOldNotesMaster.GetLowerBorder()); | |||
1729 | pNotesMaster->ScaleObjects(aSize, aNotesBorderRect, true); | |||
1730 | pNotesMaster->SetSize(aSize); | |||
1731 | pNotesMaster->SetBorder(rOldNotesMaster.GetLeftBorder(), | |||
1732 | rOldNotesMaster.GetUpperBorder(), | |||
1733 | rOldNotesMaster.GetRightBorder(), | |||
1734 | rOldNotesMaster.GetLowerBorder()); | |||
1735 | pNotesMaster->SetOrientation( rOldNotesMaster.GetOrientation() ); | |||
1736 | pNotesMaster->SetAutoLayout(pNotesMaster->GetAutoLayout()); | |||
1737 | ||||
1738 | if( (pSourceDoc->GetDocumentType() == DocumentType::Impress) && | |||
1739 | (GetDocumentType() == DocumentType::Draw) ) | |||
1740 | { | |||
1741 | pMaster->RemoveEmptyPresentationObjects(); | |||
1742 | pNotesMaster->RemoveEmptyPresentationObjects(); | |||
1743 | } | |||
1744 | } | |||
1745 | } | |||
1746 | else | |||
1747 | { | |||
1748 | // Find a new name for the layout | |||
1749 | OUString aName(createNewMasterPageLayoutName(*this)); | |||
1750 | OUString aPageLayoutName(aName + SD_LT_SEPARATOR"~LT~" STR_LAYOUT_OUTLINE"Gliederung"); | |||
1751 | ||||
1752 | // Generate new stylesheets | |||
1753 | static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutStyleSheets(aName); | |||
1754 | SdStyleSheetVector aCreatedStyles; | |||
1755 | static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList(aName, aCreatedStyles); | |||
1756 | ||||
1757 | if( bUndo ) | |||
1758 | { | |||
1759 | StyleSheetCopyResultVector aUndoInsert; | |||
1760 | aUndoInsert.reserve(aCreatedStyles.size()); | |||
1761 | for (const auto& a : aCreatedStyles) | |||
1762 | aUndoInsert.emplace_back(a.get(), true); | |||
1763 | pUndoMgr->AddUndoAction(std::make_unique<SdMoveStyleSheetsUndoAction>(this, aUndoInsert, true)); | |||
1764 | // Generate new master pages and register them with the document | |||
1765 | BegUndo(); | |||
1766 | } | |||
1767 | ||||
1768 | pMaster = AllocSdPage(true); | |||
1769 | pMaster->SetSize(pSelectedPage->GetSize()); | |||
1770 | pMaster->SetBorder(pSelectedPage->GetLeftBorder(), | |||
1771 | pSelectedPage->GetUpperBorder(), | |||
1772 | pSelectedPage->GetRightBorder(), | |||
1773 | pSelectedPage->GetLowerBorder() ); | |||
1774 | pMaster->SetName(aName); | |||
1775 | pMaster->SetLayoutName(aPageLayoutName); | |||
1776 | InsertMasterPage(pMaster); | |||
1777 | ||||
1778 | if( bUndo ) | |||
1779 | AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster)); | |||
1780 | ||||
1781 | pMaster->SetAutoLayout(AUTOLAYOUT_NONE, true, true); | |||
1782 | ||||
1783 | pNotesMaster = AllocSdPage(true); | |||
1784 | pNotesMaster->SetPageKind(PageKind::Notes); | |||
1785 | pNotesMaster->SetSize(pNotes->GetSize()); | |||
1786 | pNotesMaster->SetBorder(pNotes->GetLeftBorder(), | |||
1787 | pNotes->GetUpperBorder(), | |||
1788 | pNotes->GetRightBorder(), | |||
1789 | pNotes->GetLowerBorder() ); | |||
1790 | pNotesMaster->SetName(aName); | |||
1791 | pNotesMaster->SetLayoutName(aPageLayoutName); | |||
1792 | InsertMasterPage(pNotesMaster); | |||
1793 | ||||
1794 | if( bUndo ) | |||
1795 | AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster)); | |||
1796 | ||||
1797 | pNotesMaster->SetAutoLayout(AUTOLAYOUT_NOTES, true, true); | |||
1798 | ||||
1799 | if( bUndo ) | |||
1800 | EndUndo(); | |||
1801 | ||||
1802 | // Create a list of affected default and notes pages | |||
1803 | std::vector<SdPage*> aPageList; | |||
1804 | if (bMaster) | |||
1805 | { | |||
1806 | for (sal_uInt16 nPage = 1; nPage < GetPageCount(); nPage++) | |||
1807 | { | |||
1808 | SdPage* pPage = static_cast<SdPage*>( GetPage(nPage) ); | |||
1809 | if (pPage->GetLayoutName() == aOldPageLayoutName) | |||
1810 | { | |||
1811 | aPageList.push_back(pPage); | |||
1812 | } | |||
1813 | } | |||
1814 | } | |||
1815 | else | |||
1816 | { | |||
1817 | aPageList.push_back(pSelectedPage); | |||
1818 | aPageList.push_back(pNotes); | |||
1819 | } | |||
1820 | ||||
1821 | // Set presentation layout and AutoLayout for the affected pages | |||
1822 | for ( auto& rpPage : aPageList ) | |||
1823 | { | |||
1824 | AutoLayout eOldAutoLayout = rpPage->GetAutoLayout(); | |||
1825 | AutoLayout eNewAutoLayout = | |||
1826 | rpPage->GetPageKind() == PageKind::Standard ? AUTOLAYOUT_NONE : AUTOLAYOUT_NOTES; | |||
1827 | ||||
1828 | if( bUndo ) | |||
1829 | { | |||
1830 | pUndoMgr->AddUndoAction(std::make_unique<SdPresentationLayoutUndoAction> | |||
1831 | (this, aOldLayoutName, aName, | |||
1832 | eOldAutoLayout, eNewAutoLayout, true, | |||
1833 | rpPage)); | |||
1834 | } | |||
1835 | ||||
1836 | rpPage->SetPresentationLayout(aName); | |||
1837 | rpPage->SetAutoLayout(eNewAutoLayout); | |||
1838 | } | |||
1839 | } | |||
1840 | ||||
1841 | // If the old master pages aren't used anymore, they and their styles have | |||
1842 | // to be removed. | |||
1843 | if (bCheckMasters) | |||
1844 | { | |||
1845 | // Check all | |||
1846 | RemoveUnnecessaryMasterPages(); | |||
1847 | } | |||
1848 | else | |||
1849 | { | |||
1850 | // Check only the master page that was replaced | |||
1851 | RemoveUnnecessaryMasterPages(&rOldMaster); | |||
1852 | } | |||
1853 | ||||
1854 | if( bUndo ) | |||
1855 | pUndoMgr->LeaveListAction(); | |||
1856 | ||||
1857 | if( mpDocSh ) | |||
1858 | mpDocSh->SetWaitCursor( false ); | |||
1859 | } | |||
1860 | ||||
1861 | void SdDrawDocument::Merge(SdrModel& rSourceModel, | |||
1862 | sal_uInt16 nFirstPageNum, sal_uInt16 nLastPageNum, | |||
1863 | sal_uInt16 nDestPos, | |||
1864 | bool bMergeMasterPages, bool bAllMasterPages, | |||
1865 | bool bUndo, bool bTreadSourceAsConst) | |||
1866 | { | |||
1867 | sal_uInt16 nMasterPageCount = GetMasterPageCount(); | |||
1868 | SdrModel::Merge( rSourceModel, nFirstPageNum, nLastPageNum, nDestPos, bMergeMasterPages, bAllMasterPages, bUndo, bTreadSourceAsConst ); | |||
1869 | ||||
1870 | // add style family for each new master page | |||
1871 | for( sal_uInt16 nMaster = nMasterPageCount; nMaster < GetMasterPageCount(); nMaster++ ) | |||
1872 | { | |||
1873 | SdPage* pPage = static_cast< SdPage* >( GetMasterPage( nMaster ) ); | |||
1874 | if( pPage && pPage->IsMasterPage() && (pPage->GetPageKind() == PageKind::Standard) ) | |||
1875 | { | |||
1876 | // new master page created, add its style family | |||
1877 | SdStyleSheetPool* pStylePool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() ); | |||
1878 | if( pStylePool ) | |||
1879 | pStylePool->AddStyleFamily( pPage ); | |||
1880 | } | |||
1881 | } | |||
1882 | } | |||
1883 | ||||
1884 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |