1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/settings.hxx>
22 #include <sal/log.hxx>
23 #include <tools/debug.hxx>
24 #include <sfx2/printer.hxx>
25 #include <editeng/paperinf.hxx>
26 #include <svx/svdopage.hxx>
27 #include <svx/svdoole2.hxx>
28 #include <svx/svdundo.hxx>
29 #include <vcl/svapp.hxx>
30 #include <editeng/eeitem.hxx>
31 #include <editeng/langitem.hxx>
32 #include <svl/itempool.hxx>
33 #include <editeng/flditem.hxx>
35 #include <sfx2/linkmgr.hxx>
36 #include <svx/svdoutl.hxx>
37 #include <svx/svdlayer.hxx>
39 #include <svx/svditer.hxx>
40 #include <comphelper/lok.hxx>
41 #include <xmloff/autolayout.hxx>
43 #include <sdresid.hxx>
44 #include <drawdoc.hxx>
46 #include <strings.hrc>
48 #include <stlpool.hxx>
49 #include <anminfo.hxx>
50 #include <undo/undomanager.hxx>
51 #include <sfx2/lokhelper.hxx>
52 #include <unomodel.hxx>
54 #include <DrawDocShell.hxx>
56 #include "PageListWatcher.hxx"
57 #include <unokywds.hxx>
61 const ::tools::Long PRINT_OFFSET
= 30; // see /svx/source/dialog/page.cxx
63 using namespace com::sun::star
;
65 // Looks up an object by name
66 SdrObject
* SdDrawDocument::GetObj(std::u16string_view rObjName
) const
68 SdrObject
* pObj
= nullptr;
69 SdrObject
* pObjFound
= nullptr;
70 const SdPage
* pPage
= nullptr;
72 // First search in all pages
74 const sal_uInt16 nMaxPages
= GetPageCount();
76 while (nPage
< nMaxPages
&& !pObjFound
)
78 pPage
= static_cast<const SdPage
*>( GetPage(nPage
) );
79 SdrObjListIter
aIter(pPage
, SdrIterMode::DeepWithGroups
);
81 while (aIter
.IsMore() && !pObjFound
)
85 if( ( pObj
->GetName() == rObjName
) ||
86 ( SdrInventor::Default
== pObj
->GetObjInventor() &&
87 SdrObjKind::OLE2
== pObj
->GetObjIdentifier() &&
88 rObjName
== static_cast< SdrOle2Obj
* >( pObj
)->GetPersistName() ) )
97 // If it couldn't be found, look through all master pages
99 const sal_uInt16 nMaxMasterPages
= GetMasterPageCount();
101 while (nPage
< nMaxMasterPages
&& !pObjFound
)
103 pPage
= static_cast<const SdPage
*>( GetMasterPage(nPage
) );
104 SdrObjListIter
aIter(pPage
, SdrIterMode::DeepWithGroups
);
106 while (aIter
.IsMore() && !pObjFound
)
110 if( ( pObj
->GetName() == rObjName
) ||
111 ( SdrInventor::Default
== pObj
->GetObjInventor() &&
112 SdrObjKind::OLE2
== pObj
->GetObjIdentifier() &&
113 rObjName
== static_cast< SdrOle2Obj
* >( pObj
)->GetPersistName() ) )
125 // Find SdPage by name
126 sal_uInt16
SdDrawDocument::GetPageByName(std::u16string_view rPgName
, bool& rbIsMasterPage
) const
128 SdPage
* pPage
= nullptr;
129 sal_uInt16 nPage
= 0;
130 const sal_uInt16 nMaxPages
= GetPageCount();
131 sal_uInt16 nPageNum
= SDRPAGE_NOTFOUND
;
133 rbIsMasterPage
= false;
135 // Search all regular pages and all notes pages (handout pages are
137 while (nPage
< nMaxPages
&& nPageNum
== SDRPAGE_NOTFOUND
)
139 pPage
= const_cast<SdPage
*>(static_cast<const SdPage
*>(
143 && pPage
->GetPageKind() != PageKind::Handout
144 && pPage
->GetName() == rPgName
)
152 // Search all master pages when not found among non-master pages
153 const sal_uInt16 nMaxMasterPages
= GetMasterPageCount();
156 while (nPage
< nMaxMasterPages
&& nPageNum
== SDRPAGE_NOTFOUND
)
158 pPage
= const_cast<SdPage
*>(static_cast<const SdPage
*>(
159 GetMasterPage(nPage
)));
161 if (pPage
&& pPage
->GetName() == rPgName
)
164 rbIsMasterPage
= true;
173 bool SdDrawDocument::IsPageNameUnique( std::u16string_view rPgName
) const
175 sal_uInt16 nCount
= 0;
176 SdPage
* pPage
= nullptr;
178 // Search all regular pages and all notes pages (handout pages are ignored)
179 sal_uInt16 nPage
= 0;
180 sal_uInt16 nMaxPages
= GetPageCount();
181 while (nPage
< nMaxPages
)
183 pPage
= const_cast<SdPage
*>(static_cast<const SdPage
*>(GetPage(nPage
)));
185 if (pPage
&& pPage
->GetName() == rPgName
&& pPage
->GetPageKind() != PageKind::Handout
)
191 // Search all master pages
193 nMaxPages
= GetMasterPageCount();
194 while (nPage
< nMaxPages
)
196 pPage
= const_cast<SdPage
*>(static_cast<const SdPage
*>(GetMasterPage(nPage
)));
198 if (pPage
&& pPage
->GetName() == rPgName
)
207 SdPage
* SdDrawDocument::GetSdPage(sal_uInt16 nPgNum
, PageKind ePgKind
) const
209 return mpDrawPageListWatcher
->GetSdPage(ePgKind
, sal_uInt32(nPgNum
));
212 sal_uInt16
SdDrawDocument::GetSdPageCount(PageKind ePgKind
) const
214 return static_cast<sal_uInt16
>(mpDrawPageListWatcher
->GetSdPageCount(ePgKind
));
217 SdPage
* SdDrawDocument::GetMasterSdPage(sal_uInt16 nPgNum
, PageKind ePgKind
)
219 return mpMasterPageListWatcher
->GetSdPage(ePgKind
, sal_uInt32(nPgNum
));
222 sal_uInt16
SdDrawDocument::GetMasterSdPageCount(PageKind ePgKind
) const
224 return static_cast<sal_uInt16
>(mpMasterPageListWatcher
->GetSdPageCount(ePgKind
));
227 sal_uInt16
SdDrawDocument::GetActiveSdPageCount() const
229 return static_cast<sal_uInt16
>(mpDrawPageListWatcher
->GetVisibleSdPageCount());
232 // Adapt the page numbers that are registered in the page objects of the notes
234 void SdDrawDocument::UpdatePageObjectsInNotes(sal_uInt16 nStartPos
)
236 sal_uInt16 nPageCount
= GetPageCount();
237 SdPage
* pPage
= nullptr;
239 for (sal_uInt16 nPage
= nStartPos
; nPage
< nPageCount
; nPage
++)
241 pPage
= static_cast<SdPage
*>( GetPage(nPage
) );
243 // If this is a notes page, find its page object and correct the page
245 if (pPage
&& pPage
->GetPageKind() == PageKind::Notes
)
247 const size_t nObjCount
= pPage
->GetObjCount();
248 for (size_t nObj
= 0; nObj
< nObjCount
; ++nObj
)
250 SdrObject
* pObj
= pPage
->GetObj(nObj
);
251 if (pObj
->GetObjIdentifier() == SdrObjKind::Page
&&
252 pObj
->GetObjInventor() == SdrInventor::Default
)
254 // The page object is the preceding page (drawing page)
255 SAL_WARN_IF(!nStartPos
, "sd", "Position of notes page must not be 0.");
257 SAL_WARN_IF(nPage
<= 1, "sd", "Page object must not be a handout.");
259 if (nStartPos
> 0 && nPage
> 1)
260 static_cast<SdrPageObj
*>(pObj
)->SetReferencedPage(GetPage(nPage
- 1));
267 void SdDrawDocument::UpdatePageRelativeURLs(std::u16string_view aOldName
, std::u16string_view aNewName
)
269 if (aNewName
.empty())
272 SfxItemPool
& rPool(GetPool());
273 for (const SfxPoolItem
* pItem
: rPool
.GetItemSurrogates(EE_FEATURE_FIELD
))
275 const SvxFieldItem
* pFldItem
= dynamic_cast< const SvxFieldItem
* > (pItem
);
279 SvxURLField
* pURLField
= const_cast< SvxURLField
* >( dynamic_cast<const SvxURLField
*>( pFldItem
->GetField() ) );
283 OUString aURL
= pURLField
->GetURL();
285 if (!aURL
.isEmpty() && (aURL
[0] == 35) && (aURL
.indexOf(aOldName
, 1) == 1))
287 if (aURL
.getLength() == sal_Int32(aOldName
.size() + 1)) // standard page name
289 aURL
= aURL
.replaceAt(1, aURL
.getLength() - 1, u
"") +
291 pURLField
->SetURL(aURL
);
295 const OUString
sNotes(SdResId(STR_NOTES
));
296 if (aURL
.getLength() == sal_Int32(aOldName
.size()) + 2 + sNotes
.getLength()
297 && aURL
.indexOf(sNotes
, aOldName
.size() + 2) == sal_Int32(aOldName
.size() + 2))
299 aURL
= aURL
.replaceAt(1, aURL
.getLength() - 1, u
"") +
300 aNewName
+ " " + sNotes
;
301 pURLField
->SetURL(aURL
);
310 void SdDrawDocument::UpdatePageRelativeURLs(SdPage
const * pPage
, sal_uInt16 nPos
, sal_Int32 nIncrement
)
312 bool bNotes
= (pPage
->GetPageKind() == PageKind::Notes
);
314 SfxItemPool
& rPool(GetPool());
315 for (const SfxPoolItem
* pItem
: rPool
.GetItemSurrogates(EE_FEATURE_FIELD
))
317 const SvxFieldItem
* pFldItem
;
319 if ((pFldItem
= dynamic_cast< const SvxFieldItem
* > (pItem
)) != nullptr)
321 SvxURLField
* pURLField
= const_cast< SvxURLField
* >( dynamic_cast<const SvxURLField
*>( pFldItem
->GetField() ) );
325 OUString aURL
= pURLField
->GetURL();
327 if (!aURL
.isEmpty() && (aURL
[0] == 35))
329 OUString aHashSlide
= "#" + SdResId(STR_PAGE
);
331 if (aURL
.startsWith(aHashSlide
))
333 OUString aURLCopy
= aURL
;
334 const OUString
sNotes(SdResId(STR_NOTES
));
336 aURLCopy
= aURLCopy
.replaceAt(0, aHashSlide
.getLength(), u
"");
338 bool bNotesLink
= ( aURLCopy
.getLength() >= sNotes
.getLength() + 3
339 && aURLCopy
.endsWith(sNotes
) );
341 if (bNotesLink
!= bNotes
)
342 continue; // no compatible link and page
345 aURLCopy
= aURLCopy
.replaceAt(aURLCopy
.getLength() - sNotes
.getLength(), sNotes
.getLength(), u
"");
347 sal_Int32 number
= aURLCopy
.toInt32();
348 sal_uInt16 realPageNumber
= (nPos
+ 1)/ 2;
350 if ( number
>= realPageNumber
)
352 // update link page number
353 number
+= nIncrement
;
354 aURL
= aURL
.replaceAt(aHashSlide
.getLength() + 1, aURL
.getLength() - aHashSlide
.getLength() - 1, u
"") +
355 OUString::number(number
);
358 aURL
+= " " + sNotes
;
360 pURLField
->SetURL(aURL
);
370 void SdDrawDocument::MovePage(sal_uInt16 nPgNum
, sal_uInt16 nNewPos
)
372 FmFormModel::MovePage(nPgNum
, nNewPos
);
374 sal_uInt16 nMin
= std::min(nPgNum
, nNewPos
);
376 UpdatePageObjectsInNotes(nMin
);
380 void SdDrawDocument::InsertPage(SdrPage
* pPage
, sal_uInt16 nPos
)
382 bool bLast
= (nPos
== GetPageCount());
384 FmFormModel::InsertPage(pPage
, nPos
);
386 static_cast<SdPage
*>(pPage
)->ConnectLink();
388 UpdatePageObjectsInNotes(nPos
);
391 UpdatePageRelativeURLs(static_cast<SdPage
*>( pPage
), nPos
, 1);
393 if (comphelper::LibreOfficeKit::isActive() && static_cast<SdPage
*>(pPage
)->GetPageKind() == PageKind::Standard
)
395 SdXImpressDocument
* pDoc
= comphelper::getFromUnoTunnel
<SdXImpressDocument
>(this->getUnoModel());
396 SfxLokHelper::notifyDocumentSizeChangedAllViews(pDoc
);
401 void SdDrawDocument::DeletePage(sal_uInt16 nPgNum
)
403 FmFormModel::DeletePage(nPgNum
);
405 UpdatePageObjectsInNotes(nPgNum
);
409 rtl::Reference
<SdrPage
> SdDrawDocument::RemovePage(sal_uInt16 nPgNum
)
411 rtl::Reference
<SdrPage
> pPage
= FmFormModel::RemovePage(nPgNum
);
413 bool bLast
= ((nPgNum
+1)/2 == (GetPageCount()+1)/2);
415 auto pSdPage
= static_cast<SdPage
*>(pPage
.get());
416 pSdPage
->DisconnectLink();
417 ReplacePageInCustomShows( pSdPage
, nullptr );
418 UpdatePageObjectsInNotes(nPgNum
);
421 UpdatePageRelativeURLs(pSdPage
, nPgNum
, -1);
423 if (comphelper::LibreOfficeKit::isActive() && pSdPage
->GetPageKind() == PageKind::Standard
)
425 SdXImpressDocument
* pDoc
= comphelper::getFromUnoTunnel
<SdXImpressDocument
>(this->getUnoModel());
426 SfxLokHelper::notifyDocumentSizeChangedAllViews(pDoc
);
432 // Warning: This is not called for new master pages created from SdrModel::Merge,
433 // you also have to modify code in SdDrawDocument::Merge!
434 void SdDrawDocument::InsertMasterPage(SdrPage
* pPage
, sal_uInt16 nPos
)
436 FmFormModel::InsertMasterPage( pPage
, nPos
);
437 if( pPage
->IsMasterPage() && (static_cast<SdPage
*>(pPage
)->GetPageKind() == PageKind::Standard
) )
439 // new master page created, add its style family
440 SdStyleSheetPool
* pStylePool
= static_cast<SdStyleSheetPool
*>( GetStyleSheetPool() );
442 pStylePool
->AddStyleFamily( static_cast<SdPage
*>(pPage
) );
446 rtl::Reference
<SdrPage
> SdDrawDocument::RemoveMasterPage(sal_uInt16 nPgNum
)
448 SdPage
* pPage
= static_cast<SdPage
*>(GetMasterPage(nPgNum
));
449 if( pPage
&& pPage
->IsMasterPage() && (pPage
->GetPageKind() == PageKind::Standard
) )
451 // master page removed, remove its style family
452 SdStyleSheetPool
* pStylePool
= static_cast<SdStyleSheetPool
*>( GetStyleSheetPool() );
454 pStylePool
->RemoveStyleFamily( pPage
);
457 return FmFormModel::RemoveMasterPage(nPgNum
);
461 void SdDrawDocument::SetSelected(SdPage
* pPage
, bool bSelect
)
463 PageKind ePageKind
= pPage
->GetPageKind();
465 if (ePageKind
== PageKind::Standard
)
467 pPage
->SetSelected(bSelect
);
469 const sal_uInt16
nDestPageNum(pPage
->GetPageNum() + 1);
470 SdPage
* pNotesPage
= nullptr;
472 if(nDestPageNum
< GetPageCount())
474 pNotesPage
= static_cast<SdPage
*>(GetPage(nDestPageNum
));
477 if (pNotesPage
&& pNotesPage
->GetPageKind() == PageKind::Notes
)
479 pNotesPage
->SetSelected(bSelect
);
482 else if (ePageKind
== PageKind::Notes
)
484 pPage
->SetSelected(bSelect
);
485 SdPage
* pStandardPage
= static_cast<SdPage
*>( GetPage( pPage
->GetPageNum() - 1 ) );
487 if (pStandardPage
&& pStandardPage
->GetPageKind() == PageKind::Standard
)
488 pStandardPage
->SetSelected(bSelect
);
492 // If no pages exist yet, create them now
493 void SdDrawDocument::CreateFirstPages( SdDrawDocument
const * pRefDocument
/* = 0 */ )
495 // If no page exists yet in the model, (File -> New), insert a page
496 sal_uInt16 nPageCount
= GetPageCount();
501 // #i57181# Paper size depends on Language, like in Writer
502 Size aDefSize
= SvxPaperInfo::GetDefaultPaperSize( MapUnit::Map100thMM
);
504 // Insert handout page
505 rtl::Reference
<SdPage
> pHandoutPage
= AllocSdPage(false);
507 SdPage
* pRefPage
= nullptr;
510 pRefPage
= pRefDocument
->GetSdPage( 0, PageKind::Handout
);
514 pHandoutPage
->SetSize(pRefPage
->GetSize());
515 pHandoutPage
->SetBorder( pRefPage
->GetLeftBorder(), pRefPage
->GetUpperBorder(), pRefPage
->GetRightBorder(), pRefPage
->GetLowerBorder() );
519 pHandoutPage
->SetSize(aDefSize
);
520 pHandoutPage
->SetBorder(0, 0, 0, 0);
523 pHandoutPage
->SetPageKind(PageKind::Handout
);
524 pHandoutPage
->SetName( SdResId(STR_HANDOUT
) );
525 InsertPage(pHandoutPage
.get(), 0);
527 // Insert master page and register this with the handout page
528 rtl::Reference
<SdPage
> pHandoutMPage
= AllocSdPage(true);
529 pHandoutMPage
->SetSize( pHandoutPage
->GetSize() );
530 pHandoutMPage
->SetPageKind(PageKind::Handout
);
531 pHandoutMPage
->SetBorder( pHandoutPage
->GetLeftBorder(),
532 pHandoutPage
->GetUpperBorder(),
533 pHandoutPage
->GetRightBorder(),
534 pHandoutPage
->GetLowerBorder() );
535 InsertMasterPage(pHandoutMPage
.get(), 0);
536 pHandoutPage
->TRG_SetMasterPage( *pHandoutMPage
);
539 // If nPageCount==1 is, the model for the clipboard was created, thus a
540 // default page must already exist
541 rtl::Reference
<SdPage
> pPage
;
542 bool bClipboard
= false;
545 pRefPage
= pRefDocument
->GetSdPage( 0, PageKind::Standard
);
549 pPage
= AllocSdPage(false);
553 pPage
->SetSize( pRefPage
->GetSize() );
554 pPage
->SetBorder( pRefPage
->GetLeftBorder(), pRefPage
->GetUpperBorder(), pRefPage
->GetRightBorder(), pRefPage
->GetLowerBorder() );
556 else if (meDocType
== DocumentType::Draw
)
558 // Draw: always use default size with margins
559 pPage
->SetSize(aDefSize
);
561 SfxPrinter
* pPrinter
= mpDocSh
->GetPrinter(false);
562 if (pPrinter
&& pPrinter
->IsValid())
564 Size
aOutSize(pPrinter
->GetOutputSize());
565 Point
aPageOffset(pPrinter
->GetPageOffset());
566 aPageOffset
-= pPrinter
->PixelToLogic( Point() );
567 ::tools::Long nOffset
= !aPageOffset
.X() && !aPageOffset
.Y() ? 0 : PRINT_OFFSET
;
569 sal_uLong nTop
= aPageOffset
.Y();
570 sal_uLong nLeft
= aPageOffset
.X();
571 sal_uLong nBottom
= std::max(::tools::Long(aDefSize
.Height() - aOutSize
.Height() - nTop
+ nOffset
), ::tools::Long(0));
572 sal_uLong nRight
= std::max(::tools::Long(aDefSize
.Width() - aOutSize
.Width() - nLeft
+ nOffset
), ::tools::Long(0));
574 pPage
->SetBorder(nLeft
, nTop
, nRight
, nBottom
);
578 // The printer is not available. Use a border of 10mm
579 // on each side instead.
580 // This has to be kept synchronized with the border
582 // SvxPageDescPage::PaperSizeSelect_Impl callback.
583 pPage
->SetBorder(1000, 1000, 1000, 1000);
588 // Impress: always use screen format, landscape.
589 Size
aSz( SvxPaperInfo::GetPaperSize(PAPER_SCREEN_16_9
, MapUnit::Map100thMM
) );
590 pPage
->SetSize( Size( aSz
.Height(), aSz
.Width() ) );
591 pPage
->SetBorder(0, 0, 0, 0);
594 InsertPage(pPage
.get(), 1);
599 pPage
= static_cast<SdPage
*>( GetPage(1) );
602 // Insert master page, then register this with the page
603 rtl::Reference
<SdPage
> pMPage
= AllocSdPage(true);
604 pMPage
->SetSize( pPage
->GetSize() );
605 pMPage
->SetBorder( pPage
->GetLeftBorder(),
606 pPage
->GetUpperBorder(),
607 pPage
->GetRightBorder(),
608 pPage
->GetLowerBorder() );
609 InsertMasterPage(pMPage
.get(), 1);
610 pPage
->TRG_SetMasterPage( *pMPage
);
612 pMPage
->SetLayoutName( pPage
->GetLayoutName() );
615 rtl::Reference
<SdPage
> pNotesPage
= AllocSdPage(false);
618 pRefPage
= pRefDocument
->GetSdPage( 0, PageKind::Notes
);
622 pNotesPage
->SetSize( pRefPage
->GetSize() );
623 pNotesPage
->SetBorder( pRefPage
->GetLeftBorder(), pRefPage
->GetUpperBorder(), pRefPage
->GetRightBorder(), pRefPage
->GetLowerBorder() );
627 // Always use portrait format
628 if (aDefSize
.Height() >= aDefSize
.Width())
630 pNotesPage
->SetSize(aDefSize
);
634 pNotesPage
->SetSize( Size(aDefSize
.Height(), aDefSize
.Width()) );
637 pNotesPage
->SetBorder(0, 0, 0, 0);
639 pNotesPage
->SetPageKind(PageKind::Notes
);
640 InsertPage(pNotesPage
.get(), 2);
642 pNotesPage
->SetLayoutName( pPage
->GetLayoutName() );
644 // Insert master page, then register this with the notes page
645 rtl::Reference
<SdPage
> pNotesMPage
= AllocSdPage(true);
646 pNotesMPage
->SetSize( pNotesPage
->GetSize() );
647 pNotesMPage
->SetPageKind(PageKind::Notes
);
648 pNotesMPage
->SetBorder( pNotesPage
->GetLeftBorder(),
649 pNotesPage
->GetUpperBorder(),
650 pNotesPage
->GetRightBorder(),
651 pNotesPage
->GetLowerBorder() );
652 InsertMasterPage(pNotesMPage
.get(), 2);
653 pNotesPage
->TRG_SetMasterPage( *pNotesMPage
);
655 pNotesMPage
->SetLayoutName( pPage
->GetLayoutName() );
657 if( !pRefPage
&& (meDocType
!= DocumentType::Draw
) )
658 pPage
->SetAutoLayout( AUTOLAYOUT_TITLE
, true, true );
660 mpWorkStartupTimer
.reset( new Timer("DrawWorkStartupTimer") );
661 mpWorkStartupTimer
->SetInvokeHandler( LINK(this, SdDrawDocument
, WorkStartupHdl
) );
662 mpWorkStartupTimer
->SetTimeout(2000);
663 mpWorkStartupTimer
->Start();
668 // Creates missing notes and handout pages (after PowerPoint import).
669 // We assume that at least one default page and one default master page exist.
671 bool SdDrawDocument::CreateMissingNotesAndHandoutPages()
674 sal_uInt16 nPageCount
= GetPageCount();
679 SdPage
* pHandoutMPage
= static_cast<SdPage
*>( GetMasterPage(0) );
680 pHandoutMPage
->SetPageKind(PageKind::Handout
);
682 SdPage
* pHandoutPage
= static_cast<SdPage
*>( GetPage(0) );
683 pHandoutPage
->SetPageKind(PageKind::Handout
);
684 pHandoutPage
->TRG_SetMasterPage( *pHandoutMPage
);
686 for (sal_uInt16 i
= 1; i
< nPageCount
; i
= i
+ 2)
688 SdPage
* pPage
= static_cast<SdPage
*>( GetPage(i
) );
690 if(!pPage
->TRG_HasMasterPage())
692 // No master page set -> use first default master page
693 // (If there was no default page in the PPT)
694 pPage
->TRG_SetMasterPage(*GetMasterPage(1));
697 SdPage
* pNotesPage
= static_cast<SdPage
*>( GetPage(i
+1) );
698 pNotesPage
->SetPageKind(PageKind::Notes
);
700 // Set notes master page
701 sal_uInt16 nMasterPageAfterPagesMasterPage
= pPage
->TRG_GetMasterPage().GetPageNum() + 1;
702 pNotesPage
->TRG_SetMasterPage(*GetMasterPage(nMasterPageAfterPagesMasterPage
));
706 StopWorkStartupDelay();
713 void SdDrawDocument::UnselectAllPages()
715 sal_uInt16 nNoOfPages
= GetSdPageCount(PageKind::Standard
);
716 for (sal_uInt16 nPage
= 0; nPage
< nNoOfPages
; ++nPage
)
718 SdPage
* pPage
= GetSdPage(nPage
, PageKind::Standard
);
719 pPage
->SetSelected(false);
723 // + Move selected pages after said page
724 // (nTargetPage = (sal_uInt16)-1 --> move before first page)
725 // + Returns sal_True when the page has been moved
726 bool SdDrawDocument::MovePages(sal_uInt16 nTargetPage
)
728 SdPage
* pPage
= nullptr;
730 sal_uInt16 nNoOfPages
= GetSdPageCount(PageKind::Standard
);
731 bool bSomethingHappened
= false;
733 const bool bUndo
= IsUndoEnabled();
736 BegUndo(SdResId(STR_UNDO_MOVEPAGES
));
738 // List of selected pages
739 std::vector
<SdPage
*> aPageList
;
740 for (nPage
= 0; nPage
< nNoOfPages
; nPage
++)
742 pPage
= GetSdPage(nPage
, PageKind::Standard
);
744 if (pPage
->IsSelected()) {
745 aPageList
.push_back(pPage
);
749 // If necessary, look backwards, until we find a page that wasn't selected
752 if (nPage
!= sal_uInt16(-1))
754 pPage
= GetSdPage(nPage
, PageKind::Standard
);
755 while (nPage
> 0 && pPage
->IsSelected())
758 pPage
= GetSdPage(nPage
, PageKind::Standard
);
761 if (pPage
->IsSelected())
763 nPage
= sal_uInt16(-1);
767 // Insert before the first page
768 if (nPage
== sal_uInt16(-1))
770 std::vector
<SdPage
*>::reverse_iterator iter
;
771 for (iter
= aPageList
.rbegin(); iter
!= aPageList
.rend(); ++iter
)
773 nPage
= (*iter
)->GetPageNum();
776 SdrPage
* pPg
= GetPage(nPage
);
778 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
, 1));
780 pPg
= GetPage(nPage
+1);
782 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
+1, 2));
783 MovePage(nPage
+1, 2);
784 bSomethingHappened
= true;
788 // Insert after <nPage>
791 nTargetPage
= 2 * nPage
+ 1; // PageKind::Standard --> absolute
793 for (const auto& rpPage
: aPageList
)
795 nPage
= rpPage
->GetPageNum();
796 if (nPage
> nTargetPage
)
798 nTargetPage
+= 2; // Insert _after_ the page
800 if (nPage
!= nTargetPage
)
802 SdrPage
* pPg
= GetPage(nPage
);
804 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
, nTargetPage
));
805 MovePage(nPage
, nTargetPage
);
806 pPg
= GetPage(nPage
+1);
808 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
+1, nTargetPage
+1));
809 MovePage(nPage
+1, nTargetPage
+1);
810 bSomethingHappened
= true;
815 if (nPage
!= nTargetPage
)
817 SdrPage
* pPg
= GetPage(nPage
+1);
819 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
+1, nTargetPage
+1));
820 MovePage(nPage
+1, nTargetPage
+1);
821 pPg
= GetPage(nPage
);
823 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
, nTargetPage
));
824 MovePage(nPage
, nTargetPage
);
825 bSomethingHappened
= true;
828 nTargetPage
= rpPage
->GetPageNum();
835 return bSomethingHappened
;
838 // Return number of links in sfx2::LinkManager
839 sal_uLong
SdDrawDocument::GetLinkCount() const
841 return m_pLinkManager
->GetLinks().size();
845 void SdDrawDocument::SetLanguage( const LanguageType eLang
, const sal_uInt16 nId
)
847 bool bChanged
= false;
849 if( nId
== EE_CHAR_LANGUAGE
&& meLanguage
!= eLang
)
854 else if( nId
== EE_CHAR_LANGUAGE_CJK
&& meLanguageCJK
!= eLang
)
856 meLanguageCJK
= eLang
;
859 else if( nId
== EE_CHAR_LANGUAGE_CTL
&& meLanguageCTL
!= eLang
)
861 meLanguageCTL
= eLang
;
867 GetDrawOutliner().SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
868 m_pHitTestOutliner
->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
869 m_pItemPool
->SetPoolDefaultItem( SvxLanguageItem( eLang
, nId
) );
870 SetChanged( bChanged
);
875 LanguageType
SdDrawDocument::GetLanguage( const sal_uInt16 nId
) const
877 LanguageType eLangType
= meLanguage
;
879 if( nId
== EE_CHAR_LANGUAGE_CJK
)
880 eLangType
= meLanguageCJK
;
881 else if( nId
== EE_CHAR_LANGUAGE_CTL
)
882 eLangType
= meLanguageCTL
;
887 // Initiate WorkStartup
888 IMPL_LINK_NOARG(SdDrawDocument
, WorkStartupHdl
, Timer
*, void)
890 if (IsTransportContainer())
894 mpDocSh
->SetWaitCursor( true );
896 bool bChanged
= IsChanged(); // remember this
898 // Initialize Autolayouts
899 SdPage
* pHandoutMPage
= GetMasterSdPage(0, PageKind::Handout
);
901 if (pHandoutMPage
->GetAutoLayout() == AUTOLAYOUT_NONE
)
903 // No AutoLayout yet -> initialize
904 pHandoutMPage
->SetAutoLayout(AUTOLAYOUT_HANDOUT6
, true, true);
907 SdPage
* pPage
= GetSdPage(0, PageKind::Standard
);
909 if (pPage
->GetAutoLayout() == AUTOLAYOUT_NONE
)
911 // No AutoLayout yet -> initialize
912 pPage
->SetAutoLayout(AUTOLAYOUT_NONE
, true, true);
915 SdPage
* pNotesPage
= GetSdPage(0, PageKind::Notes
);
917 if (pNotesPage
->GetAutoLayout() == AUTOLAYOUT_NONE
)
919 // No AutoLayout yet -> initialize
920 pNotesPage
->SetAutoLayout(AUTOLAYOUT_NOTES
, true, true);
923 SetChanged(bChanged
);
926 mpDocSh
->SetWaitCursor( false );
929 // When the WorkStartupTimer has been created (this only happens in
930 // SdDrawViewShell::Construct() ), the timer may be stopped and the WorkStartup
932 void SdDrawDocument::StopWorkStartupDelay()
934 if (mpWorkStartupTimer
)
936 if ( mpWorkStartupTimer
->IsActive() )
938 // Timer not yet expired -> initiate WorkStartup
939 mpWorkStartupTimer
->Stop();
940 WorkStartupHdl(nullptr);
943 mpWorkStartupTimer
.reset();
947 // When the WorkStartupTimer has been created (this only happens in
948 // SdDrawViewShell::Construct() ), the timer may be stopped and the WorkStartup
950 SdAnimationInfo
* SdDrawDocument::GetAnimationInfo(SdrObject
* pObject
)
952 DBG_ASSERT(pObject
, "sd::SdDrawDocument::GetAnimationInfo(), invalid argument!");
954 return GetShapeUserData( *pObject
);
959 SdAnimationInfo
* SdDrawDocument::GetShapeUserData(SdrObject
& rObject
, bool bCreate
/* = false */ )
962 sal_uInt16 nUDCount
= rObject
.GetUserDataCount();
963 SdAnimationInfo
* pRet
= nullptr;
965 // Can we find animation information within the user data?
966 for (nUD
= 0; nUD
< nUDCount
; nUD
++)
968 SdrObjUserData
* pUD
= rObject
.GetUserData(nUD
);
969 if((pUD
->GetInventor() == SdrInventor::StarDrawUserData
) && (pUD
->GetId() == SD_ANIMATIONINFO_ID
))
971 pRet
= dynamic_cast<SdAnimationInfo
*>(pUD
);
976 if( (pRet
== nullptr) && bCreate
)
978 pRet
= new SdAnimationInfo( rObject
);
979 rObject
.AppendUserData( std::unique_ptr
<SdrObjUserData
>(pRet
) );
985 /** this method enforces that the masterpages are in the correct order,
986 that is at position 1 is a PageKind::Standard masterpage followed by a
987 PageKind::Notes masterpage and so on. #
989 void SdDrawDocument::CheckMasterPages()
991 sal_uInt16 nMaxPages
= GetMasterPageCount();
993 // we need at least a handout master and one master page
999 SdPage
* pPage
= nullptr;
1003 // first see if the page order is correct
1004 for( nPage
= 1; nPage
< nMaxPages
; nPage
++ )
1006 pPage
= static_cast<SdPage
*> (GetMasterPage( nPage
));
1007 // if an odd page is not a standard page or an even page is not a notes page
1008 if( ((1 == (nPage
& 1)) && (pPage
->GetPageKind() != PageKind::Standard
) ) ||
1009 ((0 == (nPage
& 1)) && (pPage
->GetPageKind() != PageKind::Notes
) ) )
1010 break; // then we have a fatal error
1013 if( nPage
>= nMaxPages
)
1016 SdPage
* pNotesPage
= nullptr;
1018 // there is a fatal error in the master page order,
1019 // we need to repair the document
1020 bool bChanged
= false;
1023 while( nPage
< nMaxPages
)
1025 pPage
= static_cast<SdPage
*> (GetMasterPage( nPage
));
1026 if( pPage
->GetPageKind() != PageKind::Standard
)
1029 sal_uInt16 nFound
= nPage
+ 1;
1030 while( nFound
< nMaxPages
)
1032 pPage
= static_cast<SdPage
*>(GetMasterPage( nFound
));
1033 if( PageKind::Standard
== pPage
->GetPageKind() )
1035 MoveMasterPage( nFound
, nPage
);
1036 pPage
->SetInserted();
1044 // if we don't have any more standard pages, were done
1045 if( nMaxPages
== nFound
)
1051 if( nPage
< nMaxPages
)
1052 pNotesPage
= static_cast<SdPage
*>(GetMasterPage( nPage
));
1054 pNotesPage
= nullptr;
1056 if( (nullptr == pNotesPage
) || (pNotesPage
->GetPageKind() != PageKind::Notes
) || ( pPage
->GetLayoutName() != pNotesPage
->GetLayoutName() ) )
1060 sal_uInt16 nFound
= nPage
+ 1;
1061 while( nFound
< nMaxPages
)
1063 pNotesPage
= static_cast<SdPage
*>(GetMasterPage( nFound
));
1064 if( (PageKind::Notes
== pNotesPage
->GetPageKind()) && ( pPage
->GetLayoutName() == pNotesPage
->GetLayoutName() ) )
1066 MoveMasterPage( nFound
, nPage
);
1067 pNotesPage
->SetInserted();
1074 // looks like we lost a notes page
1075 if( nMaxPages
== nFound
)
1079 // first find a reference notes page for size
1080 SdPage
* pRefNotesPage
= nullptr;
1082 while( nFound
< nMaxPages
)
1084 pRefNotesPage
= static_cast<SdPage
*>(GetMasterPage( nFound
));
1085 if( PageKind::Notes
== pRefNotesPage
->GetPageKind() )
1089 if( nFound
== nMaxPages
)
1090 pRefNotesPage
= nullptr;
1092 rtl::Reference
<SdPage
> pNewNotesPage
= AllocSdPage(true);
1093 pNewNotesPage
->SetPageKind(PageKind::Notes
);
1096 pNewNotesPage
->SetSize( pRefNotesPage
->GetSize() );
1097 pNewNotesPage
->SetBorder( pRefNotesPage
->GetLeftBorder(),
1098 pRefNotesPage
->GetUpperBorder(),
1099 pRefNotesPage
->GetRightBorder(),
1100 pRefNotesPage
->GetLowerBorder() );
1102 InsertMasterPage(pNewNotesPage
.get(), nPage
);
1103 pNewNotesPage
->SetLayoutName( pPage
->GetLayoutName() );
1104 pNewNotesPage
->SetAutoLayout(AUTOLAYOUT_NOTES
, true, true );
1112 // now remove all remaining and unused non PageKind::Standard slides
1113 while( nPage
< nMaxPages
)
1117 RemoveMasterPage( nPage
);
1123 OSL_FAIL( "master pages where in a wrong order" );
1124 RecalcPageNums( true);
1128 sal_uInt16
SdDrawDocument::CreatePage (
1129 SdPage
* pActualPage
,
1131 const OUString
& sStandardPageName
,
1132 const OUString
& sNotesPageName
,
1133 AutoLayout eStandardLayout
,
1134 AutoLayout eNotesLayout
,
1137 const sal_Int32 nInsertPosition
)
1139 SdPage
* pPreviousStandardPage
;
1140 SdPage
* pPreviousNotesPage
;
1141 rtl::Reference
<SdPage
> pStandardPage
;
1142 rtl::Reference
<SdPage
> pNotesPage
;
1144 // From the given page determine the standard page and notes page of which
1145 // to take the layout and the position where to insert the new pages.
1146 if (ePageKind
== PageKind::Notes
)
1148 pPreviousNotesPage
= pActualPage
;
1149 sal_uInt16 nNotesPageNum
= pPreviousNotesPage
->GetPageNum() + 2;
1150 pPreviousStandardPage
= static_cast<SdPage
*>( GetPage(nNotesPageNum
- 3) );
1151 eStandardLayout
= pPreviousStandardPage
->GetAutoLayout();
1155 pPreviousStandardPage
= pActualPage
;
1156 sal_uInt16 nStandardPageNum
= pPreviousStandardPage
->GetPageNum() + 2;
1157 pPreviousNotesPage
= static_cast<SdPage
*>( GetPage(nStandardPageNum
- 1) );
1158 eNotesLayout
= pPreviousNotesPage
->GetAutoLayout();
1161 // Create new standard page and set it up
1162 pStandardPage
= AllocSdPage(false);
1164 // Set the size here since else the presobj autolayout
1166 pStandardPage
->SetSize( pPreviousStandardPage
->GetSize() );
1167 pStandardPage
->SetBorder( pPreviousStandardPage
->GetLeftBorder(),
1168 pPreviousStandardPage
->GetUpperBorder(),
1169 pPreviousStandardPage
->GetRightBorder(),
1170 pPreviousStandardPage
->GetLowerBorder() );
1172 // Use master page of current page.
1173 pStandardPage
->TRG_SetMasterPage(pPreviousStandardPage
->TRG_GetMasterPage());
1175 // User layout of current standard page
1176 pStandardPage
->SetLayoutName( pPreviousStandardPage
->GetLayoutName() );
1177 pStandardPage
->SetAutoLayout(eStandardLayout
, true);
1178 pStandardPage
->setHeaderFooterSettings( pPreviousStandardPage
->getHeaderFooterSettings() );
1180 // transition settings of current page
1181 pStandardPage
->setTransitionType( pPreviousStandardPage
->getTransitionType() );
1182 pStandardPage
->setTransitionSubtype( pPreviousStandardPage
->getTransitionSubtype() );
1183 pStandardPage
->setTransitionDirection( pPreviousStandardPage
->getTransitionDirection() );
1184 pStandardPage
->setTransitionFadeColor( pPreviousStandardPage
->getTransitionFadeColor() );
1185 pStandardPage
->setTransitionDuration( pPreviousStandardPage
->getTransitionDuration() );
1187 // apply previous animation timing
1188 pStandardPage
->SetPresChange( pPreviousStandardPage
->GetPresChange() );
1189 pStandardPage
->SetTime( pPreviousStandardPage
->GetTime() );
1191 // Create new notes page and set it up
1192 pNotesPage
= AllocSdPage(false);
1193 pNotesPage
->SetPageKind(PageKind::Notes
);
1195 // Use master page of current page
1196 pNotesPage
->TRG_SetMasterPage(pPreviousNotesPage
->TRG_GetMasterPage());
1198 // Use layout of current notes page
1199 pNotesPage
->SetLayoutName( pPreviousNotesPage
->GetLayoutName() );
1200 pNotesPage
->SetAutoLayout(eNotesLayout
, true);
1201 pNotesPage
->setHeaderFooterSettings( pPreviousNotesPage
->getHeaderFooterSettings() );
1203 return InsertPageSet (
1210 pStandardPage
.get(),
1215 sal_uInt16
SdDrawDocument::DuplicatePage (sal_uInt16 nPageNum
)
1217 PageKind ePageKind
= PageKind::Standard
;
1220 SdPage
* pActualPage
= GetSdPage(nPageNum
, ePageKind
);
1222 // Get background flags
1223 SdrLayerAdmin
& rLayerAdmin
= GetLayerAdmin();
1224 SdrLayerID aBckgrnd
= rLayerAdmin
.GetLayerID(sUNO_LayerName_background
);
1225 SdrLayerID aBckgrndObj
= rLayerAdmin
.GetLayerID(sUNO_LayerName_background_objects
);
1226 SdrLayerIDSet aVisibleLayers
= pActualPage
->TRG_GetMasterPageVisibleLayers();
1228 return DuplicatePage (
1229 pActualPage
, ePageKind
,
1230 // No names for the new slides
1231 OUString(), OUString(),
1232 aVisibleLayers
.IsSet(aBckgrnd
),
1233 aVisibleLayers
.IsSet(aBckgrndObj
), -1);
1236 sal_uInt16
SdDrawDocument::DuplicatePage (
1237 SdPage
* pActualPage
,
1239 const OUString
& sStandardPageName
,
1240 const OUString
& sNotesPageName
,
1243 const sal_Int32 nInsertPosition
)
1245 SdPage
* pPreviousStandardPage
;
1246 SdPage
* pPreviousNotesPage
;
1247 rtl::Reference
<SdPage
> pStandardPage
;
1248 rtl::Reference
<SdPage
> pNotesPage
;
1250 // From the given page determine the standard page and the notes page
1251 // of which to make copies.
1252 if (ePageKind
== PageKind::Notes
)
1254 pPreviousNotesPage
= pActualPage
;
1255 sal_uInt16 nNotesPageNum
= pPreviousNotesPage
->GetPageNum() + 2;
1256 pPreviousStandardPage
= static_cast<SdPage
*>( GetPage(nNotesPageNum
- 3) );
1260 pPreviousStandardPage
= pActualPage
;
1261 sal_uInt16 nStandardPageNum
= pPreviousStandardPage
->GetPageNum() + 2;
1262 pPreviousNotesPage
= static_cast<SdPage
*>( GetPage(nStandardPageNum
- 1) );
1265 // Create duplicates of a standard page and the associated notes page
1266 pStandardPage
= static_cast<SdPage
*>( pPreviousStandardPage
->CloneSdrPage(*this).get() );
1267 pNotesPage
= static_cast<SdPage
*>( pPreviousNotesPage
->CloneSdrPage(*this).get() );
1269 return InsertPageSet (
1276 pStandardPage
.get(),
1281 sal_uInt16
SdDrawDocument::InsertPageSet (
1282 SdPage
* pActualPage
,
1284 const OUString
& sStandardPageName
,
1285 const OUString
& sNotesPageName
,
1288 SdPage
* pStandardPage
,
1290 sal_Int32 nInsertPosition
)
1292 SdPage
* pPreviousStandardPage
;
1293 SdPage
* pPreviousNotesPage
;
1294 sal_uInt16 nStandardPageNum
;
1295 sal_uInt16 nNotesPageNum
;
1296 OUString
aNotesPageName(sNotesPageName
);
1298 // Gather some information about the standard page and the notes page
1299 // that are to be inserted. This makes sure that there is always one
1300 // standard page followed by one notes page.
1301 if (ePageKind
== PageKind::Notes
)
1303 pPreviousNotesPage
= pActualPage
;
1304 nNotesPageNum
= pPreviousNotesPage
->GetPageNum() + 2;
1305 pPreviousStandardPage
= static_cast<SdPage
*>( GetPage(nNotesPageNum
- 3) );
1306 nStandardPageNum
= nNotesPageNum
- 1;
1310 pPreviousStandardPage
= pActualPage
;
1311 nStandardPageNum
= pPreviousStandardPage
->GetPageNum() + 2;
1312 pPreviousNotesPage
= static_cast<SdPage
*>( GetPage(nStandardPageNum
- 1) );
1313 nNotesPageNum
= nStandardPageNum
+ 1;
1314 aNotesPageName
= sStandardPageName
;
1317 OSL_ASSERT(nNotesPageNum
==nStandardPageNum
+1);
1318 if (nInsertPosition
< 0)
1319 nInsertPosition
= nStandardPageNum
;
1321 // Set up and insert the standard page
1323 pPreviousStandardPage
,
1330 // Set up and insert the notes page
1331 pNotesPage
->SetPageKind(PageKind::Notes
);
1340 // Return an index that allows the caller to access the newly inserted
1341 // pages by using GetSdPage()
1342 return pStandardPage
->GetPageNum() / 2;
1345 void SdDrawDocument::SetupNewPage (
1346 SdPage
const * pPreviousPage
,
1348 const OUString
& sPageName
,
1349 sal_uInt16 nInsertionPoint
,
1353 if (pPreviousPage
!= nullptr)
1355 pPage
->SetSize( pPreviousPage
->GetSize() );
1356 pPage
->SetBorder( pPreviousPage
->GetLeftBorder(),
1357 pPreviousPage
->GetUpperBorder(),
1358 pPreviousPage
->GetRightBorder(),
1359 pPreviousPage
->GetLowerBorder() );
1361 pPage
->SetName(sPageName
);
1363 InsertPage(pPage
, nInsertionPoint
);
1365 if (pPreviousPage
!= nullptr)
1367 SdrLayerAdmin
& rLayerAdmin
= GetLayerAdmin();
1368 SdrLayerID aBckgrnd
= rLayerAdmin
.GetLayerID(sUNO_LayerName_background
);
1369 SdrLayerID aBckgrndObj
= rLayerAdmin
.GetLayerID(sUNO_LayerName_background_objects
);
1370 SdrLayerIDSet aVisibleLayers
= pPreviousPage
->TRG_GetMasterPageVisibleLayers();
1371 aVisibleLayers
.Set(aBckgrnd
, bIsPageBack
);
1372 aVisibleLayers
.Set(aBckgrndObj
, bIsPageObj
);
1373 pPage
->TRG_SetMasterPageVisibleLayers(aVisibleLayers
);
1377 sd::UndoManager
* SdDrawDocument::GetUndoManager() const
1379 return mpDocSh
? dynamic_cast< sd::UndoManager
* >(mpDocSh
->GetUndoManager()) : nullptr;
1382 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */