Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sd / source / core / drawdoc2.cxx
blob1a38fb080e99222d15c86bee9919d5d96ad8055d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/wrkwin.hxx>
21 #include <vcl/settings.hxx>
23 #include <sfx2/printer.hxx>
24 #include <sfx2/app.hxx>
25 #include <Outliner.hxx>
26 #include <editeng/paperinf.hxx>
27 #include <svx/svdopage.hxx>
28 #include <svx/svdoole2.hxx>
29 #include <svx/svdotext.hxx>
30 #include <svx/svdograf.hxx>
31 #include <svx/svdundo.hxx>
32 #include <vcl/svapp.hxx>
33 #include <editeng/eeitem.hxx>
34 #include <editeng/langitem.hxx>
35 #include <svl/itempool.hxx>
36 #include <svx/svdpool.hxx>
37 #include <editeng/flditem.hxx>
39 #include <sfx2/linkmgr.hxx>
40 #include <editeng/editdata.hxx>
41 #include <svx/dialogs.hrc>
43 #include <editeng/outliner.hxx>
44 #include <svx/svditer.hxx>
45 #include <svtools/imapobj.hxx>
46 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
47 #include <boost/property_tree/json_parser.hpp>
48 #include <comphelper/lok.hxx>
49 #include <xmloff/autolayout.hxx>
51 #include <sdresid.hxx>
52 #include <drawdoc.hxx>
53 #include <sdpage.hxx>
54 #include <pglink.hxx>
55 #include <strings.hrc>
56 #include <glob.hxx>
57 #include <stlpool.hxx>
58 #include <sdiocmpt.hxx>
59 #include <anminfo.hxx>
60 #include <imapinfo.hxx>
61 #include <cusshow.hxx>
62 #include <undo/undomanager.hxx>
64 #include <DrawDocShell.hxx>
65 #include <FrameView.hxx>
67 #include "PageListWatcher.hxx"
68 #include <vcl/virdev.hxx>
69 #include <customshowlist.hxx>
71 using namespace ::sd;
73 const long PRINT_OFFSET = 30; // see /svx/source/dialog/page.cxx
75 using namespace com::sun::star;
77 // Looks up an object by name
78 SdrObject* SdDrawDocument::GetObj(const OUString& rObjName) const
80 SdrObject* pObj = nullptr;
81 SdrObject* pObjFound = nullptr;
82 const SdPage* pPage = nullptr;
84 // First search in all pages
85 sal_uInt16 nPage = 0;
86 const sal_uInt16 nMaxPages = GetPageCount();
88 while (nPage < nMaxPages && !pObjFound)
90 pPage = static_cast<const SdPage*>( GetPage(nPage) );
91 SdrObjListIter aIter(*pPage, SdrIterMode::DeepWithGroups);
93 while (aIter.IsMore() && !pObjFound)
95 pObj = aIter.Next();
97 if( ( pObj->GetName() == rObjName ) ||
98 ( SdrInventor::Default == pObj->GetObjInventor() &&
99 OBJ_OLE2 == pObj->GetObjIdentifier() &&
100 rObjName == static_cast< SdrOle2Obj* >( pObj )->GetPersistName() ) )
102 pObjFound = pObj;
106 nPage++;
109 // If it couldn't be found, look through all master pages
110 nPage = 0;
111 const sal_uInt16 nMaxMasterPages = GetMasterPageCount();
113 while (nPage < nMaxMasterPages && !pObjFound)
115 pPage = static_cast<const SdPage*>( GetMasterPage(nPage) );
116 SdrObjListIter aIter(*pPage, SdrIterMode::DeepWithGroups);
118 while (aIter.IsMore() && !pObjFound)
120 pObj = aIter.Next();
122 if( ( pObj->GetName() == rObjName ) ||
123 ( SdrInventor::Default == pObj->GetObjInventor() &&
124 OBJ_OLE2 == pObj->GetObjIdentifier() &&
125 rObjName == static_cast< SdrOle2Obj* >( pObj )->GetPersistName() ) )
127 pObjFound = pObj;
131 nPage++;
134 return pObjFound;
137 // Find SdPage by name
138 sal_uInt16 SdDrawDocument::GetPageByName(const OUString& rPgName, bool& rbIsMasterPage) const
140 SdPage* pPage = nullptr;
141 sal_uInt16 nPage = 0;
142 const sal_uInt16 nMaxPages = GetPageCount();
143 sal_uInt16 nPageNum = SDRPAGE_NOTFOUND;
145 rbIsMasterPage = false;
147 // Search all regular pages and all notes pages (handout pages are
148 // ignored)
149 while (nPage < nMaxPages && nPageNum == SDRPAGE_NOTFOUND)
151 pPage = const_cast<SdPage*>(static_cast<const SdPage*>(
152 GetPage(nPage)));
154 if (pPage != nullptr
155 && pPage->GetPageKind() != PageKind::Handout
156 && pPage->GetName() == rPgName)
158 nPageNum = nPage;
161 nPage++;
164 // Search all master pages when not found among non-master pages
165 const sal_uInt16 nMaxMasterPages = GetMasterPageCount();
166 nPage = 0;
168 while (nPage < nMaxMasterPages && nPageNum == SDRPAGE_NOTFOUND)
170 pPage = const_cast<SdPage*>(static_cast<const SdPage*>(
171 GetMasterPage(nPage)));
173 if (pPage && pPage->GetName() == rPgName)
175 nPageNum = nPage;
176 rbIsMasterPage = true;
179 nPage++;
182 return nPageNum;
185 bool SdDrawDocument::IsPageNameUnique( const OUString& rPgName ) const
187 sal_uInt16 nCount = 0;
188 SdPage* pPage = nullptr;
190 // Search all regular pages and all notes pages (handout pages are ignored)
191 sal_uInt16 nPage = 0;
192 sal_uInt16 nMaxPages = GetPageCount();
193 while (nPage < nMaxPages)
195 pPage = const_cast<SdPage*>(static_cast<const SdPage*>(GetPage(nPage)));
197 if (pPage && pPage->GetName() == rPgName && pPage->GetPageKind() != PageKind::Handout)
198 nCount++;
200 nPage++;
203 // Search all master pages
204 nPage = 0;
205 nMaxPages = GetMasterPageCount();
206 while (nPage < nMaxPages)
208 pPage = const_cast<SdPage*>(static_cast<const SdPage*>(GetMasterPage(nPage)));
210 if (pPage && pPage->GetName() == rPgName)
211 nCount++;
213 nPage++;
216 return nCount == 1;
219 SdPage* SdDrawDocument::GetSdPage(sal_uInt16 nPgNum, PageKind ePgKind) const
221 return mpDrawPageListWatcher->GetSdPage(ePgKind, sal_uInt32(nPgNum));
224 sal_uInt16 SdDrawDocument::GetSdPageCount(PageKind ePgKind) const
226 return static_cast<sal_uInt16>(mpDrawPageListWatcher->GetSdPageCount(ePgKind));
229 SdPage* SdDrawDocument::GetMasterSdPage(sal_uInt16 nPgNum, PageKind ePgKind)
231 return mpMasterPageListWatcher->GetSdPage(ePgKind, sal_uInt32(nPgNum));
234 sal_uInt16 SdDrawDocument::GetMasterSdPageCount(PageKind ePgKind) const
236 return static_cast<sal_uInt16>(mpMasterPageListWatcher->GetSdPageCount(ePgKind));
239 sal_uInt16 SdDrawDocument::GetActiveSdPageCount() const
241 return static_cast<sal_uInt16>(mpDrawPageListWatcher->GetVisibleSdPageCount());
244 // Adapt the page numbers that are registered in the page objects of the notes
245 // pages
246 void SdDrawDocument::UpdatePageObjectsInNotes(sal_uInt16 nStartPos)
248 sal_uInt16 nPageCount = GetPageCount();
249 SdPage* pPage = nullptr;
251 for (sal_uInt16 nPage = nStartPos; nPage < nPageCount; nPage++)
253 pPage = static_cast<SdPage*>( GetPage(nPage) );
255 // If this is a notes page, find its page object and correct the page
256 // number
257 if (pPage && pPage->GetPageKind() == PageKind::Notes)
259 const size_t nObjCount = pPage->GetObjCount();
260 for (size_t nObj = 0; nObj < nObjCount; ++nObj)
262 SdrObject* pObj = pPage->GetObj(nObj);
263 if (pObj->GetObjIdentifier() == OBJ_PAGE &&
264 pObj->GetObjInventor() == SdrInventor::Default)
266 // The page object is the preceding page (drawing page)
267 SAL_WARN_IF(!nStartPos, "sd", "Position of notes page must not be 0.");
269 SAL_WARN_IF(nPage <= 1, "sd", "Page object must not be a handout.");
271 if (nStartPos > 0 && nPage > 1)
272 static_cast<SdrPageObj*>(pObj)->SetReferencedPage(GetPage(nPage - 1));
279 void SdDrawDocument::UpdatePageRelativeURLs(const OUString& rOldName, const OUString& rNewName)
281 if (rNewName.isEmpty())
282 return;
284 SfxItemPool& rPool(GetPool());
285 sal_uInt32 nCount = rPool.GetItemCount2(EE_FEATURE_FIELD);
286 for (sal_uInt32 nOff = 0; nOff < nCount; nOff++)
288 const SfxPoolItem *pItem = rPool.GetItem2(EE_FEATURE_FIELD, nOff);
289 const SvxFieldItem* pFldItem = dynamic_cast< const SvxFieldItem * > (pItem);
291 if(pFldItem)
293 SvxURLField* pURLField = const_cast< SvxURLField* >( dynamic_cast<const SvxURLField*>( pFldItem->GetField() ) );
295 if(pURLField)
297 OUString aURL = pURLField->GetURL();
299 if (!aURL.isEmpty() && (aURL[0] == 35) && (aURL.indexOf(rOldName, 1) == 1))
301 if (aURL.getLength() == rOldName.getLength() + 1) // standard page name
303 aURL = aURL.replaceAt(1, aURL.getLength() - 1, "");
304 aURL += rNewName;
305 pURLField->SetURL(aURL);
307 else
309 const OUString sNotes(SdResId(STR_NOTES));
310 if (aURL.getLength() == rOldName.getLength() + 2 + sNotes.getLength()
311 && aURL.indexOf(sNotes, rOldName.getLength() + 2) == rOldName.getLength() + 2)
313 aURL = aURL.replaceAt(1, aURL.getLength() - 1, "");
314 aURL += rNewName + " " + sNotes;
315 pURLField->SetURL(aURL);
324 void SdDrawDocument::UpdatePageRelativeURLs(SdPage const * pPage, sal_uInt16 nPos, sal_Int32 nIncrement)
326 bool bNotes = (pPage->GetPageKind() == PageKind::Notes);
328 SfxItemPool& rPool(GetPool());
329 sal_uInt32 nCount = rPool.GetItemCount2(EE_FEATURE_FIELD);
330 for (sal_uInt32 nOff = 0; nOff < nCount; nOff++)
332 const SfxPoolItem *pItem = rPool.GetItem2(EE_FEATURE_FIELD, nOff);
333 const SvxFieldItem* pFldItem;
335 if ((pFldItem = dynamic_cast< const SvxFieldItem * > (pItem)) != nullptr)
337 SvxURLField* pURLField = const_cast< SvxURLField* >( dynamic_cast<const SvxURLField*>( pFldItem->GetField() ) );
339 if(pURLField)
341 OUString aURL = pURLField->GetURL();
343 if (!aURL.isEmpty() && (aURL[0] == 35))
345 OUString aHashSlide("#");
346 aHashSlide += SdResId(STR_PAGE);
348 if (aURL.startsWith(aHashSlide))
350 OUString aURLCopy = aURL;
351 const OUString sNotes(SdResId(STR_NOTES));
353 aURLCopy = aURLCopy.replaceAt(0, aHashSlide.getLength(), "");
355 bool bNotesLink = ( aURLCopy.getLength() >= sNotes.getLength() + 3
356 && aURLCopy.endsWith(sNotes) );
358 if (bNotesLink != bNotes)
359 continue; // no compatible link and page
361 if (bNotes)
362 aURLCopy = aURLCopy.replaceAt(aURLCopy.getLength() - sNotes.getLength(), sNotes.getLength(), "");
364 sal_Int32 number = aURLCopy.toInt32();
365 sal_uInt16 realPageNumber = (nPos + 1)/ 2;
367 if ( number >= realPageNumber )
369 // update link page number
370 number += nIncrement;
371 aURL = aURL.replaceAt(aHashSlide.getLength() + 1, aURL.getLength() - aHashSlide.getLength() - 1, "");
372 aURL += OUString::number(number);
373 if (bNotes)
375 aURL += " " + sNotes;
377 pURLField->SetURL(aURL);
386 // Move page
387 void SdDrawDocument::MovePage(sal_uInt16 nPgNum, sal_uInt16 nNewPos)
389 FmFormModel::MovePage(nPgNum, nNewPos);
391 sal_uInt16 nMin = std::min(nPgNum, nNewPos);
393 UpdatePageObjectsInNotes(nMin);
396 // Insert page
397 void SdDrawDocument::InsertPage(SdrPage* pPage, sal_uInt16 nPos)
399 bool bLast = (nPos == GetPageCount());
401 FmFormModel::InsertPage(pPage, nPos);
403 static_cast<SdPage*>(pPage)->ConnectLink();
405 UpdatePageObjectsInNotes(nPos);
407 if (!bLast)
408 UpdatePageRelativeURLs(static_cast<SdPage*>( pPage ), nPos, 1);
410 if (comphelper::LibreOfficeKit::isActive() && static_cast<SdPage*>(pPage)->GetPageKind() == PageKind::Standard)
412 SfxViewShell* pViewShell = SfxViewShell::GetFirst();
413 while (pViewShell)
415 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_SIZE_CHANGED, "");
416 pViewShell = SfxViewShell::GetNext(*pViewShell);
421 // Delete page
422 void SdDrawDocument::DeletePage(sal_uInt16 nPgNum)
424 FmFormModel::DeletePage(nPgNum);
426 UpdatePageObjectsInNotes(nPgNum);
429 // Remove page
430 SdrPage* SdDrawDocument::RemovePage(sal_uInt16 nPgNum)
432 SdrPage* pPage = FmFormModel::RemovePage(nPgNum);
434 bool bLast = ((nPgNum+1)/2 == (GetPageCount()+1)/2);
436 static_cast<SdPage*>(pPage)->DisconnectLink();
437 ReplacePageInCustomShows( dynamic_cast< SdPage* >( pPage ), nullptr );
438 UpdatePageObjectsInNotes(nPgNum);
440 if (!bLast)
441 UpdatePageRelativeURLs(static_cast<SdPage*>(pPage), nPgNum, -1);
443 if (comphelper::LibreOfficeKit::isActive() && static_cast<SdPage*>(pPage)->GetPageKind() == PageKind::Standard)
445 SfxViewShell* pViewShell = SfxViewShell::GetFirst();
446 while (pViewShell)
448 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_SIZE_CHANGED, "");
449 pViewShell = SfxViewShell::GetNext(*pViewShell);
453 return pPage;
456 // Warning: This is not called for new master pages created from SdrModel::Merge,
457 // you also have to modify code in SdDrawDocument::Merge!
458 void SdDrawDocument::InsertMasterPage(SdrPage* pPage, sal_uInt16 nPos )
460 FmFormModel::InsertMasterPage( pPage, nPos );
461 if( pPage->IsMasterPage() && (static_cast<SdPage*>(pPage)->GetPageKind() == PageKind::Standard) )
463 // new master page created, add its style family
464 SdStyleSheetPool* pStylePool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
465 if( pStylePool )
466 pStylePool->AddStyleFamily( static_cast<SdPage*>(pPage) );
470 SdrPage* SdDrawDocument::RemoveMasterPage(sal_uInt16 nPgNum)
472 SdPage* pPage = static_cast<SdPage*>(GetMasterPage(nPgNum ));
473 if( pPage && pPage->IsMasterPage() && (pPage->GetPageKind() == PageKind::Standard) )
475 // master page removed, remove its style family
476 SdStyleSheetPool* pStylePool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
477 if( pStylePool )
478 pStylePool->RemoveStyleFamily( pPage );
481 return FmFormModel::RemoveMasterPage(nPgNum);
484 //Select pages
485 void SdDrawDocument::SetSelected(SdPage* pPage, bool bSelect)
487 PageKind ePageKind = pPage->GetPageKind();
489 if (ePageKind == PageKind::Standard)
491 pPage->SetSelected(bSelect);
493 const sal_uInt16 nDestPageNum(pPage->GetPageNum() + 1);
494 SdPage* pNotesPage = nullptr;
496 if(nDestPageNum < GetPageCount())
498 pNotesPage = static_cast<SdPage*>(GetPage(nDestPageNum));
501 if (pNotesPage && pNotesPage->GetPageKind() == PageKind::Notes)
503 pNotesPage->SetSelected(bSelect);
506 else if (ePageKind == PageKind::Notes)
508 pPage->SetSelected(bSelect);
509 SdPage* pStandardPage = static_cast<SdPage*>( GetPage( pPage->GetPageNum() - 1 ) );
511 if (pStandardPage && pStandardPage->GetPageKind() == PageKind::Standard)
512 pStandardPage->SetSelected(bSelect);
516 // If no pages exist yet, create them now
517 void SdDrawDocument::CreateFirstPages( SdDrawDocument const * pRefDocument /* = 0 */ )
519 // If no page exists yet in the model, (File -> New), insert a page
520 sal_uInt16 nPageCount = GetPageCount();
522 if (nPageCount <= 1)
524 // #i57181# Paper size depends on Language, like in Writer
525 Size aDefSize = SvxPaperInfo::GetDefaultPaperSize( MapUnit::Map100thMM );
527 // Insert handout page
528 SdPage* pHandoutPage = AllocSdPage(false);
530 SdPage* pRefPage = nullptr;
532 if( pRefDocument )
533 pRefPage = pRefDocument->GetSdPage( 0, PageKind::Handout );
535 if( pRefPage )
537 pHandoutPage->SetSize(pRefPage->GetSize());
538 pHandoutPage->SetBorder( pRefPage->GetLeftBorder(), pRefPage->GetUpperBorder(), pRefPage->GetRightBorder(), pRefPage->GetLowerBorder() );
540 else
542 pHandoutPage->SetSize(aDefSize);
543 pHandoutPage->SetBorder(0, 0, 0, 0);
546 pHandoutPage->SetPageKind(PageKind::Handout);
547 pHandoutPage->SetName( SdResId(STR_HANDOUT) );
548 InsertPage(pHandoutPage, 0);
550 // Insert master page and register this with the handout page
551 SdPage* pHandoutMPage = AllocSdPage(true);
552 pHandoutMPage->SetSize( pHandoutPage->GetSize() );
553 pHandoutMPage->SetPageKind(PageKind::Handout);
554 pHandoutMPage->SetBorder( pHandoutPage->GetLeftBorder(),
555 pHandoutPage->GetUpperBorder(),
556 pHandoutPage->GetRightBorder(),
557 pHandoutPage->GetLowerBorder() );
558 InsertMasterPage(pHandoutMPage, 0);
559 pHandoutPage->TRG_SetMasterPage( *pHandoutMPage );
561 // Insert page
562 // If nPageCount==1 is, the model for the clipboard was created, thus a
563 // default page must already exist
564 SdPage* pPage;
565 bool bClipboard = false;
567 if( pRefDocument )
568 pRefPage = pRefDocument->GetSdPage( 0, PageKind::Standard );
570 if (nPageCount == 0)
572 pPage = AllocSdPage(false);
574 if( pRefPage )
576 pPage->SetSize( pRefPage->GetSize() );
577 pPage->SetBorder( pRefPage->GetLeftBorder(), pRefPage->GetUpperBorder(), pRefPage->GetRightBorder(), pRefPage->GetLowerBorder() );
579 else if (meDocType == DocumentType::Draw)
581 // Draw: always use default size with margins
582 pPage->SetSize(aDefSize);
584 SfxPrinter* pPrinter = mpDocSh->GetPrinter(false);
585 if (pPrinter && pPrinter->IsValid())
587 Size aOutSize(pPrinter->GetOutputSize());
588 Point aPageOffset(pPrinter->GetPageOffset());
589 aPageOffset -= pPrinter->PixelToLogic( Point() );
590 long nOffset = !aPageOffset.X() && !aPageOffset.Y() ? 0 : PRINT_OFFSET;
592 sal_uLong nTop = aPageOffset.Y();
593 sal_uLong nLeft = aPageOffset.X();
594 sal_uLong nBottom = std::max(static_cast<long>(aDefSize.Height() - aOutSize.Height() - nTop + nOffset), 0L);
595 sal_uLong nRight = std::max(static_cast<long>(aDefSize.Width() - aOutSize.Width() - nLeft + nOffset), 0L);
597 pPage->SetBorder(nLeft, nTop, nRight, nBottom);
599 else
601 // The printer is not available. Use a border of 10mm
602 // on each side instead.
603 // This has to be kept synchronized with the border
604 // width set in the
605 // SvxPageDescPage::PaperSizeSelect_Impl callback.
606 pPage->SetBorder(1000, 1000, 1000, 1000);
609 else
611 // Impress: always use screen format, landscape.
612 Size aSz( SvxPaperInfo::GetPaperSize(PAPER_SCREEN_16_9, MapUnit::Map100thMM) );
613 pPage->SetSize( Size( aSz.Height(), aSz.Width() ) );
614 pPage->SetBorder(0, 0, 0, 0);
617 InsertPage(pPage, 1);
619 else
621 bClipboard = true;
622 pPage = static_cast<SdPage*>( GetPage(1) );
625 // Insert master page, then register this with the page
626 SdPage* pMPage = AllocSdPage(true);
627 pMPage->SetSize( pPage->GetSize() );
628 pMPage->SetBorder( pPage->GetLeftBorder(),
629 pPage->GetUpperBorder(),
630 pPage->GetRightBorder(),
631 pPage->GetLowerBorder() );
632 InsertMasterPage(pMPage, 1);
633 pPage->TRG_SetMasterPage( *pMPage );
634 if( bClipboard )
635 pMPage->SetLayoutName( pPage->GetLayoutName() );
637 // Insert notes page
638 SdPage* pNotesPage = AllocSdPage(false);
640 if( pRefDocument )
641 pRefPage = pRefDocument->GetSdPage( 0, PageKind::Notes );
643 if( pRefPage )
645 pNotesPage->SetSize( pRefPage->GetSize() );
646 pNotesPage->SetBorder( pRefPage->GetLeftBorder(), pRefPage->GetUpperBorder(), pRefPage->GetRightBorder(), pRefPage->GetLowerBorder() );
648 else
650 // Always use portrait format
651 if (aDefSize.Height() >= aDefSize.Width())
653 pNotesPage->SetSize(aDefSize);
655 else
657 pNotesPage->SetSize( Size(aDefSize.Height(), aDefSize.Width()) );
660 pNotesPage->SetBorder(0, 0, 0, 0);
662 pNotesPage->SetPageKind(PageKind::Notes);
663 InsertPage(pNotesPage, 2);
664 if( bClipboard )
665 pNotesPage->SetLayoutName( pPage->GetLayoutName() );
667 // Insert master page, then register this with the notes page
668 SdPage* pNotesMPage = AllocSdPage(true);
669 pNotesMPage->SetSize( pNotesPage->GetSize() );
670 pNotesMPage->SetPageKind(PageKind::Notes);
671 pNotesMPage->SetBorder( pNotesPage->GetLeftBorder(),
672 pNotesPage->GetUpperBorder(),
673 pNotesPage->GetRightBorder(),
674 pNotesPage->GetLowerBorder() );
675 InsertMasterPage(pNotesMPage, 2);
676 pNotesPage->TRG_SetMasterPage( *pNotesMPage );
677 if( bClipboard )
678 pNotesMPage->SetLayoutName( pPage->GetLayoutName() );
680 if( !pRefPage && (meDocType != DocumentType::Draw) )
681 pPage->SetAutoLayout( AUTOLAYOUT_TITLE, true, true );
683 mpWorkStartupTimer.reset( new Timer("DrawWorkStartupTimer") );
684 mpWorkStartupTimer->SetInvokeHandler( LINK(this, SdDrawDocument, WorkStartupHdl) );
685 mpWorkStartupTimer->SetTimeout(2000);
686 mpWorkStartupTimer->Start();
688 SetChanged(false);
692 // Creates missing notes and handout pages (after PowerPoint import).
693 // We assume that at least one default page and one default master page exist.
695 bool SdDrawDocument::CreateMissingNotesAndHandoutPages()
697 bool bOK = false;
698 sal_uInt16 nPageCount = GetPageCount();
700 if (nPageCount != 0)
702 // Set PageKind
703 SdPage* pHandoutMPage = static_cast<SdPage*>( GetMasterPage(0) );
704 pHandoutMPage->SetPageKind(PageKind::Handout);
706 SdPage* pHandoutPage = static_cast<SdPage*>( GetPage(0) );
707 pHandoutPage->SetPageKind(PageKind::Handout);
708 pHandoutPage->TRG_SetMasterPage( *pHandoutMPage );
710 for (sal_uInt16 i = 1; i < nPageCount; i = i + 2)
712 SdPage* pPage = static_cast<SdPage*>( GetPage(i) );
714 if(!pPage->TRG_HasMasterPage())
716 // No master page set -> use first default master page
717 // (If there was no default page in the PPT)
718 pPage->TRG_SetMasterPage(*GetMasterPage(1));
721 SdPage* pNotesPage = static_cast<SdPage*>( GetPage(i+1) );
722 pNotesPage->SetPageKind(PageKind::Notes);
724 // Set notes master page
725 sal_uInt16 nMasterPageAfterPagesMasterPage = pPage->TRG_GetMasterPage().GetPageNum() + 1;
726 pNotesPage->TRG_SetMasterPage(*GetMasterPage(nMasterPageAfterPagesMasterPage));
729 bOK = true;
730 StopWorkStartupDelay();
731 SetChanged(false);
734 return bOK;
737 void SdDrawDocument::UnselectAllPages()
739 sal_uInt16 nNoOfPages = GetSdPageCount(PageKind::Standard);
740 for (sal_uInt16 nPage = 0; nPage < nNoOfPages; ++nPage)
742 SdPage* pPage = GetSdPage(nPage, PageKind::Standard);
743 pPage->SetSelected(false);
747 // + Move selected pages after said page
748 // (nTargetPage = (sal_uInt16)-1 --> move before first page)
749 // + Returns sal_True when the page has been moved
750 bool SdDrawDocument::MovePages(sal_uInt16 nTargetPage)
752 SdPage* pPage = nullptr;
753 sal_uInt16 nPage;
754 sal_uInt16 nNoOfPages = GetSdPageCount(PageKind::Standard);
755 bool bSomethingHappened = false;
757 const bool bUndo = IsUndoEnabled();
759 if( bUndo )
760 BegUndo(SdResId(STR_UNDO_MOVEPAGES));
762 // List of selected pages
763 std::vector<SdPage*> aPageList;
764 for (nPage = 0; nPage < nNoOfPages; nPage++)
766 pPage = GetSdPage(nPage, PageKind::Standard);
768 if (pPage->IsSelected()) {
769 aPageList.push_back(pPage);
773 // If necessary, look backwards, until we find a page that wasn't selected
774 nPage = nTargetPage;
776 if (nPage != sal_uInt16(-1))
778 pPage = GetSdPage(nPage, PageKind::Standard);
779 while (nPage > 0 && pPage->IsSelected())
781 nPage--;
782 pPage = GetSdPage(nPage, PageKind::Standard);
785 if (pPage->IsSelected())
787 nPage = sal_uInt16(-1);
791 // Insert before the first page
792 if (nPage == sal_uInt16(-1))
794 std::vector<SdPage*>::reverse_iterator iter;
795 for (iter = aPageList.rbegin(); iter != aPageList.rend(); ++iter)
797 nPage = (*iter)->GetPageNum();
798 if (nPage != 0)
800 SdrPage* pPg = GetPage(nPage);
801 if( bUndo )
802 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage, 1));
803 MovePage(nPage, 1);
804 pPg = GetPage(nPage+1);
805 if( bUndo )
806 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage+1, 2));
807 MovePage(nPage+1, 2);
808 bSomethingHappened = true;
812 // Insert after <nPage>
813 else
815 nTargetPage = nPage;
816 nTargetPage = 2 * nTargetPage + 1; // PageKind::Standard --> absolute
818 std::vector<SdPage*>::iterator iter;
819 for (iter = aPageList.begin(); iter != aPageList.end(); ++iter)
821 pPage = *iter;
822 nPage = pPage->GetPageNum();
823 if (nPage > nTargetPage)
825 nTargetPage += 2; // Insert _after_ the page
827 if (nPage != nTargetPage)
829 SdrPage* pPg = GetPage(nPage);
830 if( bUndo )
831 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage, nTargetPage));
832 MovePage(nPage, nTargetPage);
833 pPg = GetPage(nPage+1);
834 if( bUndo )
835 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage+1, nTargetPage+1));
836 MovePage(nPage+1, nTargetPage+1);
837 bSomethingHappened = true;
840 else
842 if (nPage != nTargetPage)
844 SdrPage* pPg = GetPage(nPage+1);
845 if( bUndo )
846 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage+1, nTargetPage+1));
847 MovePage(nPage+1, nTargetPage+1);
848 pPg = GetPage(nPage);
849 if( bUndo )
850 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage, nTargetPage));
851 MovePage(nPage, nTargetPage);
852 bSomethingHappened = true;
855 nTargetPage = pPage->GetPageNum();
859 if( bUndo )
860 EndUndo();
862 return bSomethingHappened;
865 // Return number of links in sfx2::LinkManager
866 sal_uLong SdDrawDocument::GetLinkCount()
868 return pLinkManager->GetLinks().size();
871 // Set Language
872 void SdDrawDocument::SetLanguage( const LanguageType eLang, const sal_uInt16 nId )
874 bool bChanged = false;
876 if( nId == EE_CHAR_LANGUAGE && meLanguage != eLang )
878 meLanguage = eLang;
879 bChanged = true;
881 else if( nId == EE_CHAR_LANGUAGE_CJK && meLanguageCJK != eLang )
883 meLanguageCJK = eLang;
884 bChanged = true;
886 else if( nId == EE_CHAR_LANGUAGE_CTL && meLanguageCTL != eLang )
888 meLanguageCTL = eLang;
889 bChanged = true;
892 if( bChanged )
894 GetDrawOutliner().SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
895 pHitTestOutliner->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
896 pItemPool->SetPoolDefaultItem( SvxLanguageItem( eLang, nId ) );
897 SetChanged( bChanged );
901 // Return language
902 LanguageType SdDrawDocument::GetLanguage( const sal_uInt16 nId ) const
904 LanguageType eLangType = meLanguage;
906 if( nId == EE_CHAR_LANGUAGE_CJK )
907 eLangType = meLanguageCJK;
908 else if( nId == EE_CHAR_LANGUAGE_CTL )
909 eLangType = meLanguageCTL;
911 return eLangType;
914 // Initiate WorkStartup
915 IMPL_LINK_NOARG(SdDrawDocument, WorkStartupHdl, Timer *, void)
917 if (IsTransportContainer())
918 return;
920 if( mpDocSh )
921 mpDocSh->SetWaitCursor( true );
923 bool bChanged = IsChanged(); // remember this
925 // Initialize Autolayouts
926 SdPage* pHandoutMPage = GetMasterSdPage(0, PageKind::Handout);
928 if (pHandoutMPage->GetAutoLayout() == AUTOLAYOUT_NONE)
930 // No AutoLayout yet -> initialize
931 pHandoutMPage->SetAutoLayout(AUTOLAYOUT_HANDOUT6, true, true);
934 SdPage* pPage = GetSdPage(0, PageKind::Standard);
936 if (pPage->GetAutoLayout() == AUTOLAYOUT_NONE)
938 // No AutoLayout yet -> initialize
939 pPage->SetAutoLayout(AUTOLAYOUT_NONE, true, true);
942 SdPage* pNotesPage = GetSdPage(0, PageKind::Notes);
944 if (pNotesPage->GetAutoLayout() == AUTOLAYOUT_NONE)
946 // No AutoLayout yet -> initialize
947 pNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
950 SetChanged(bChanged);
952 if( mpDocSh )
953 mpDocSh->SetWaitCursor( false );
956 // When the WorkStartupTimer has been created (this only happens in
957 // SdDrawViewShell::Construct() ), the timer may be stopped and the WorkStartup
958 // may be initiated.
959 void SdDrawDocument::StopWorkStartupDelay()
961 if (mpWorkStartupTimer)
963 if ( mpWorkStartupTimer->IsActive() )
965 // Timer not yet expired -> initiate WorkStartup
966 mpWorkStartupTimer->Stop();
967 WorkStartupHdl(nullptr);
970 mpWorkStartupTimer.reset();
974 // When the WorkStartupTimer has been created (this only happens in
975 // SdDrawViewShell::Construct() ), the timer may be stopped and the WorkStartup
976 // may be initiated.
977 SdAnimationInfo* SdDrawDocument::GetAnimationInfo(SdrObject* pObject)
979 DBG_ASSERT(pObject, "sd::SdDrawDocument::GetAnimationInfo(), invalid argument!");
980 if( pObject )
981 return GetShapeUserData( *pObject );
982 else
983 return nullptr;
986 SdAnimationInfo* SdDrawDocument::GetShapeUserData(SdrObject& rObject, bool bCreate /* = false */ )
988 sal_uInt16 nUD = 0;
989 sal_uInt16 nUDCount = rObject.GetUserDataCount();
990 SdAnimationInfo* pRet = nullptr;
992 // Can we find animation information within the user data?
993 for (nUD = 0; nUD < nUDCount; nUD++)
995 SdrObjUserData* pUD = rObject.GetUserData(nUD);
996 if((pUD->GetInventor() == SdrInventor::StarDrawUserData) && (pUD->GetId() == SD_ANIMATIONINFO_ID))
998 pRet = dynamic_cast<SdAnimationInfo*>(pUD);
999 break;
1003 if( (pRet == nullptr) && bCreate )
1005 pRet = new SdAnimationInfo( rObject );
1006 rObject.AppendUserData( std::unique_ptr<SdrObjUserData>(pRet) );
1009 return pRet;
1012 SdIMapInfo* SdDrawDocument::GetIMapInfo( SdrObject const * pObject )
1014 DBG_ASSERT(pObject, "Without an object there is no IMapInfo");
1016 SdIMapInfo* pIMapInfo = nullptr;
1017 sal_uInt16 nCount = pObject->GetUserDataCount();
1019 // Can we find IMap information within the user data?
1020 for ( sal_uInt16 i = 0; i < nCount; i++ )
1022 SdrObjUserData* pUserData = pObject->GetUserData( i );
1024 if ( ( pUserData->GetInventor() == SdrInventor::StarDrawUserData ) && ( pUserData->GetId() == SD_IMAPINFO_ID ) )
1025 pIMapInfo = static_cast<SdIMapInfo*>(pUserData);
1028 return pIMapInfo;
1031 IMapObject* SdDrawDocument::GetHitIMapObject( SdrObject const * pObj,
1032 const Point& rWinPoint )
1034 SdIMapInfo* pIMapInfo = GetIMapInfo( pObj );
1035 IMapObject* pIMapObj = nullptr;
1037 if ( pIMapInfo )
1039 const MapMode aMap100( MapUnit::Map100thMM );
1040 Size aGraphSize;
1041 Point aRelPoint( rWinPoint );
1042 ImageMap& rImageMap = const_cast<ImageMap&>(pIMapInfo->GetImageMap());
1043 const ::tools::Rectangle& rRect = pObj->GetLogicRect();
1044 bool bObjSupported = false;
1046 // execute HitTest
1047 if ( auto pGrafObj = dynamic_cast< const SdrGrafObj *>( pObj ) ) // simple graphics object
1049 const GeoStat& rGeo = pGrafObj->GetGeoStat();
1050 SdrGrafObjGeoData* pGeoData = static_cast<SdrGrafObjGeoData*>( pGrafObj->GetGeoData() );
1052 // Undo rotation
1053 if ( rGeo.nRotationAngle )
1054 RotatePoint( aRelPoint, rRect.TopLeft(), -rGeo.nSin, rGeo.nCos );
1056 // Undo mirroring
1057 if ( pGeoData->bMirrored )
1058 aRelPoint.setX( rRect.Right() + rRect.Left() - aRelPoint.X() );
1060 // Undo shearing
1061 if ( rGeo.nShearAngle )
1062 ShearPoint( aRelPoint, rRect.TopLeft(), -rGeo.nTan );
1064 if ( pGrafObj->GetGrafPrefMapMode().GetMapUnit() == MapUnit::MapPixel )
1065 aGraphSize = Application::GetDefaultDevice()->PixelToLogic( pGrafObj->GetGrafPrefSize(), aMap100 );
1066 else
1067 aGraphSize = OutputDevice::LogicToLogic( pGrafObj->GetGrafPrefSize(),
1068 pGrafObj->GetGrafPrefMapMode(), aMap100 );
1070 delete pGeoData;
1071 bObjSupported = true;
1073 else if ( auto pOleObj = dynamic_cast<const SdrOle2Obj* >(pObj) ) // OLE object
1075 aGraphSize = pOleObj->GetOrigObjSize();
1076 bObjSupported = true;
1079 // Everything worked out well, thus execute HitTest
1080 if ( bObjSupported )
1082 // Calculate relative position of mouse cursor
1083 aRelPoint -= rRect.TopLeft();
1084 pIMapObj = rImageMap.GetHitIMapObject( aGraphSize, rRect.GetSize(), aRelPoint );
1086 // We don't care about deactivated objects
1087 if ( pIMapObj && !pIMapObj->IsActive() )
1088 pIMapObj = nullptr;
1092 return pIMapObj;
1095 ImageMap* SdDrawDocument::GetImageMapForObject(SdrObject* pObj)
1097 SdIMapInfo* pIMapInfo = GetIMapInfo( pObj );
1098 if ( pIMapInfo )
1100 return const_cast<ImageMap*>( &(pIMapInfo->GetImageMap()) );
1102 return nullptr;
1105 /** this method enforces that the masterpages are in the correct order,
1106 that is at position 1 is a PageKind::Standard masterpage followed by a
1107 PageKind::Notes masterpage and so on. #
1109 void SdDrawDocument::CheckMasterPages()
1111 sal_uInt16 nMaxPages = GetMasterPageCount();
1113 // we need at least a handout master and one master page
1114 if( nMaxPages < 2 )
1116 return;
1119 SdPage* pPage = nullptr;
1121 sal_uInt16 nPage;
1123 // first see if the page order is correct
1124 for( nPage = 1; nPage < nMaxPages; nPage++ )
1126 pPage = static_cast<SdPage*> (GetMasterPage( nPage ));
1127 // if an odd page is not a standard page or an even page is not a notes page
1128 if( ((1 == (nPage & 1)) && (pPage->GetPageKind() != PageKind::Standard) ) ||
1129 ((0 == (nPage & 1)) && (pPage->GetPageKind() != PageKind::Notes) ) )
1130 break; // then we have a fatal error
1133 if( nPage < nMaxPages )
1135 SdPage* pNotesPage = nullptr;
1137 // there is a fatal error in the master page order,
1138 // we need to repair the document
1139 bool bChanged = false;
1141 nPage = 1;
1142 while( nPage < nMaxPages )
1144 pPage = static_cast<SdPage*> (GetMasterPage( nPage ));
1145 if( pPage->GetPageKind() != PageKind::Standard )
1147 bChanged = true;
1148 sal_uInt16 nFound = nPage + 1;
1149 while( nFound < nMaxPages )
1151 pPage = static_cast<SdPage*>(GetMasterPage( nFound ));
1152 if( PageKind::Standard == pPage->GetPageKind() )
1154 MoveMasterPage( nFound, nPage );
1155 pPage->SetInserted();
1156 break;
1160 nFound++;
1163 // if we don't have any more standard pages, were done
1164 if( nMaxPages == nFound )
1165 break;
1168 nPage++;
1170 if( nPage < nMaxPages )
1171 pNotesPage = static_cast<SdPage*>(GetMasterPage( nPage ));
1172 else
1173 pNotesPage = nullptr;
1175 if( (nullptr == pNotesPage) || (pNotesPage->GetPageKind() != PageKind::Notes) || ( pPage->GetLayoutName() != pNotesPage->GetLayoutName() ) )
1177 bChanged = true;
1179 sal_uInt16 nFound = nPage + 1;
1180 while( nFound < nMaxPages )
1182 pNotesPage = static_cast<SdPage*>(GetMasterPage( nFound ));
1183 if( (PageKind::Notes == pNotesPage->GetPageKind()) && ( pPage->GetLayoutName() == pNotesPage->GetLayoutName() ) )
1185 MoveMasterPage( nFound, nPage );
1186 pNotesPage->SetInserted();
1187 break;
1190 nFound++;
1193 // looks like we lost a notes page
1194 if( nMaxPages == nFound )
1196 // so create one
1198 // first find a reference notes page for size
1199 SdPage* pRefNotesPage = nullptr;
1200 nFound = 0;
1201 while( nFound < nMaxPages )
1203 pRefNotesPage = static_cast<SdPage*>(GetMasterPage( nFound ));
1204 if( PageKind::Notes == pRefNotesPage->GetPageKind() )
1205 break;
1206 nFound++;
1208 if( nFound == nMaxPages )
1209 pRefNotesPage = nullptr;
1211 SdPage* pNewNotesPage = AllocSdPage(true);
1212 pNewNotesPage->SetPageKind(PageKind::Notes);
1213 if( pRefNotesPage )
1215 pNewNotesPage->SetSize( pRefNotesPage->GetSize() );
1216 pNewNotesPage->SetBorder( pRefNotesPage->GetLeftBorder(),
1217 pRefNotesPage->GetUpperBorder(),
1218 pRefNotesPage->GetRightBorder(),
1219 pRefNotesPage->GetLowerBorder() );
1221 InsertMasterPage(pNewNotesPage, nPage );
1222 pNewNotesPage->SetLayoutName( pPage->GetLayoutName() );
1223 pNewNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true, true );
1224 nMaxPages++;
1228 nPage++;
1231 // now remove all remaining and unused non PageKind::Standard slides
1232 while( nPage < nMaxPages )
1234 bChanged = true;
1236 RemoveMasterPage( nPage );
1237 nMaxPages--;
1240 if( bChanged )
1242 OSL_FAIL( "master pages where in a wrong order" );
1243 RecalcPageNums( true);
1248 sal_uInt16 SdDrawDocument::CreatePage (
1249 SdPage* pActualPage,
1250 PageKind ePageKind,
1251 const OUString& sStandardPageName,
1252 const OUString& sNotesPageName,
1253 AutoLayout eStandardLayout,
1254 AutoLayout eNotesLayout,
1255 bool bIsPageBack,
1256 bool bIsPageObj,
1257 const sal_Int32 nInsertPosition)
1259 SdPage* pPreviousStandardPage;
1260 SdPage* pPreviousNotesPage;
1261 SdPage* pStandardPage;
1262 SdPage* pNotesPage;
1264 // From the given page determine the standard page and notes page of which
1265 // to take the layout and the position where to insert the new pages.
1266 if (ePageKind == PageKind::Notes)
1268 pPreviousNotesPage = pActualPage;
1269 sal_uInt16 nNotesPageNum = pPreviousNotesPage->GetPageNum() + 2;
1270 pPreviousStandardPage = static_cast<SdPage*>( GetPage(nNotesPageNum - 3) );
1271 eStandardLayout = pPreviousStandardPage->GetAutoLayout();
1273 else
1275 pPreviousStandardPage = pActualPage;
1276 sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
1277 pPreviousNotesPage = static_cast<SdPage*>( GetPage(nStandardPageNum - 1) );
1278 eNotesLayout = pPreviousNotesPage->GetAutoLayout();
1281 // Create new standard page and set it up
1282 pStandardPage = AllocSdPage(false);
1284 // Set the size here since else the presobj autolayout
1285 // will be wrong.
1286 pStandardPage->SetSize( pPreviousStandardPage->GetSize() );
1287 pStandardPage->SetBorder( pPreviousStandardPage->GetLeftBorder(),
1288 pPreviousStandardPage->GetUpperBorder(),
1289 pPreviousStandardPage->GetRightBorder(),
1290 pPreviousStandardPage->GetLowerBorder() );
1292 // Use master page of current page.
1293 pStandardPage->TRG_SetMasterPage(pPreviousStandardPage->TRG_GetMasterPage());
1295 // User layout of current standard page
1296 pStandardPage->SetLayoutName( pPreviousStandardPage->GetLayoutName() );
1297 pStandardPage->SetAutoLayout(eStandardLayout, true);
1298 pStandardPage->setHeaderFooterSettings( pPreviousStandardPage->getHeaderFooterSettings() );
1300 // transition settings of current page
1301 pStandardPage->setTransitionType( pPreviousStandardPage->getTransitionType() );
1302 pStandardPage->setTransitionSubtype( pPreviousStandardPage->getTransitionSubtype() );
1303 pStandardPage->setTransitionDirection( pPreviousStandardPage->getTransitionDirection() );
1304 pStandardPage->setTransitionFadeColor( pPreviousStandardPage->getTransitionFadeColor() );
1305 pStandardPage->setTransitionDuration( pPreviousStandardPage->getTransitionDuration() );
1307 // apply previous animation timing
1308 pStandardPage->SetPresChange( pPreviousStandardPage->GetPresChange() );
1309 pStandardPage->SetTime( pPreviousStandardPage->GetTime() );
1311 // Create new notes page and set it up
1312 pNotesPage = AllocSdPage(false);
1313 pNotesPage->SetPageKind(PageKind::Notes);
1315 // Use master page of current page
1316 pNotesPage->TRG_SetMasterPage(pPreviousNotesPage->TRG_GetMasterPage());
1318 // Use layout of current notes page
1319 pNotesPage->SetLayoutName( pPreviousNotesPage->GetLayoutName() );
1320 pNotesPage->SetAutoLayout(eNotesLayout, true);
1321 pNotesPage->setHeaderFooterSettings( pPreviousNotesPage->getHeaderFooterSettings() );
1323 return InsertPageSet (
1324 pActualPage,
1325 ePageKind,
1326 sStandardPageName,
1327 sNotesPageName,
1328 bIsPageBack,
1329 bIsPageObj,
1330 pStandardPage,
1331 pNotesPage,
1332 nInsertPosition);
1335 sal_uInt16 SdDrawDocument::DuplicatePage (sal_uInt16 nPageNum)
1337 PageKind ePageKind = PageKind::Standard;
1339 // Get current page
1340 SdPage* pActualPage = GetSdPage(nPageNum, ePageKind);
1342 // Get background flags
1343 SdrLayerAdmin& rLayerAdmin = GetLayerAdmin();
1344 SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(SdResId(STR_LAYER_BCKGRND));
1345 SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(SdResId(STR_LAYER_BCKGRNDOBJ));
1346 SdrLayerIDSet aVisibleLayers = pActualPage->TRG_GetMasterPageVisibleLayers();
1348 return DuplicatePage (
1349 pActualPage, ePageKind,
1350 // No names for the new slides
1351 OUString(), OUString(),
1352 aVisibleLayers.IsSet(aBckgrnd),
1353 aVisibleLayers.IsSet(aBckgrndObj), -1);
1356 sal_uInt16 SdDrawDocument::DuplicatePage (
1357 SdPage* pActualPage,
1358 PageKind ePageKind,
1359 const OUString& sStandardPageName,
1360 const OUString& sNotesPageName,
1361 bool bIsPageBack,
1362 bool bIsPageObj,
1363 const sal_Int32 nInsertPosition)
1365 SdPage* pPreviousStandardPage;
1366 SdPage* pPreviousNotesPage;
1367 SdPage* pStandardPage;
1368 SdPage* pNotesPage;
1370 // From the given page determine the standard page and the notes page
1371 // of which to make copies.
1372 if (ePageKind == PageKind::Notes)
1374 pPreviousNotesPage = pActualPage;
1375 sal_uInt16 nNotesPageNum = pPreviousNotesPage->GetPageNum() + 2;
1376 pPreviousStandardPage = static_cast<SdPage*>( GetPage(nNotesPageNum - 3) );
1378 else
1380 pPreviousStandardPage = pActualPage;
1381 sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
1382 pPreviousNotesPage = static_cast<SdPage*>( GetPage(nStandardPageNum - 1) );
1385 // Create duplicates of a standard page and the associated notes page
1386 pStandardPage = static_cast<SdPage*>( pPreviousStandardPage->CloneSdrPage(*this) );
1387 pNotesPage = static_cast<SdPage*>( pPreviousNotesPage->CloneSdrPage(*this) );
1389 return InsertPageSet (
1390 pActualPage,
1391 ePageKind,
1392 sStandardPageName,
1393 sNotesPageName,
1394 bIsPageBack,
1395 bIsPageObj,
1396 pStandardPage,
1397 pNotesPage,
1398 nInsertPosition);
1401 sal_uInt16 SdDrawDocument::InsertPageSet (
1402 SdPage* pActualPage,
1403 PageKind ePageKind,
1404 const OUString& sStandardPageName,
1405 const OUString& sNotesPageName,
1406 bool bIsPageBack,
1407 bool bIsPageObj,
1408 SdPage* pStandardPage,
1409 SdPage* pNotesPage,
1410 sal_Int32 nInsertPosition)
1412 SdPage* pPreviousStandardPage;
1413 SdPage* pPreviousNotesPage;
1414 sal_uInt16 nStandardPageNum;
1415 sal_uInt16 nNotesPageNum;
1416 OUString aNotesPageName(sNotesPageName);
1418 // Gather some information about the standard page and the notes page
1419 // that are to be inserted. This makes sure that there is always one
1420 // standard page followed by one notes page.
1421 if (ePageKind == PageKind::Notes)
1423 pPreviousNotesPage = pActualPage;
1424 nNotesPageNum = pPreviousNotesPage->GetPageNum() + 2;
1425 pPreviousStandardPage = static_cast<SdPage*>( GetPage(nNotesPageNum - 3) );
1426 nStandardPageNum = nNotesPageNum - 1;
1428 else
1430 pPreviousStandardPage = pActualPage;
1431 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
1432 pPreviousNotesPage = static_cast<SdPage*>( GetPage(nStandardPageNum - 1) );
1433 nNotesPageNum = nStandardPageNum + 1;
1434 aNotesPageName = sStandardPageName;
1437 OSL_ASSERT(nNotesPageNum==nStandardPageNum+1);
1438 if (nInsertPosition < 0)
1439 nInsertPosition = nStandardPageNum;
1441 // Set up and insert the standard page
1442 SetupNewPage (
1443 pPreviousStandardPage,
1444 pStandardPage,
1445 sStandardPageName,
1446 nInsertPosition,
1447 bIsPageBack,
1448 bIsPageObj);
1450 // Set up and insert the notes page
1451 pNotesPage->SetPageKind(PageKind::Notes);
1452 SetupNewPage (
1453 pPreviousNotesPage,
1454 pNotesPage,
1455 aNotesPageName,
1456 nInsertPosition+1,
1457 bIsPageBack,
1458 bIsPageObj);
1460 // Return an index that allows the caller to access the newly inserted
1461 // pages by using GetSdPage()
1462 return pStandardPage->GetPageNum() / 2;
1465 void SdDrawDocument::SetupNewPage (
1466 SdPage const * pPreviousPage,
1467 SdPage* pPage,
1468 const OUString& sPageName,
1469 sal_uInt16 nInsertionPoint,
1470 bool bIsPageBack,
1471 bool bIsPageObj)
1473 if (pPreviousPage != nullptr)
1475 pPage->SetSize( pPreviousPage->GetSize() );
1476 pPage->SetBorder( pPreviousPage->GetLeftBorder(),
1477 pPreviousPage->GetUpperBorder(),
1478 pPreviousPage->GetRightBorder(),
1479 pPreviousPage->GetLowerBorder() );
1481 pPage->SetName(sPageName);
1483 InsertPage(pPage, nInsertionPoint);
1485 if (pPreviousPage != nullptr)
1487 SdrLayerAdmin& rLayerAdmin = GetLayerAdmin();
1488 SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(SdResId(STR_LAYER_BCKGRND));
1489 SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(SdResId(STR_LAYER_BCKGRNDOBJ));
1490 SdrLayerIDSet aVisibleLayers = pPreviousPage->TRG_GetMasterPageVisibleLayers();
1491 aVisibleLayers.Set(aBckgrnd, bIsPageBack);
1492 aVisibleLayers.Set(aBckgrndObj, bIsPageObj);
1493 pPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
1497 sd::UndoManager* SdDrawDocument::GetUndoManager() const
1499 return mpDocSh ? dynamic_cast< sd::UndoManager* >(mpDocSh->GetUndoManager()) : nullptr;
1502 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */