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 <sfx2/viewsh.hxx>
26 #include <editeng/paperinf.hxx>
27 #include <svx/svdopage.hxx>
28 #include <svx/svdoole2.hxx>
29 #include <svx/svdundo.hxx>
30 #include <vcl/svapp.hxx>
31 #include <editeng/eeitem.hxx>
32 #include <editeng/langitem.hxx>
33 #include <svl/itempool.hxx>
34 #include <editeng/flditem.hxx>
36 #include <sfx2/linkmgr.hxx>
37 #include <svx/svdoutl.hxx>
38 #include <svx/svdlayer.hxx>
40 #include <svx/svditer.hxx>
41 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
42 #include <comphelper/lok.hxx>
43 #include <xmloff/autolayout.hxx>
45 #include <sdresid.hxx>
46 #include <drawdoc.hxx>
48 #include <strings.hrc>
50 #include <stlpool.hxx>
51 #include <anminfo.hxx>
52 #include <undo/undomanager.hxx>
53 #include <sfx2/lokhelper.hxx>
54 #include <unomodel.hxx>
56 #include <DrawDocShell.hxx>
58 #include "PageListWatcher.hxx"
59 #include <unokywds.hxx>
63 const long PRINT_OFFSET
= 30; // see /svx/source/dialog/page.cxx
65 using namespace com::sun::star
;
67 // Looks up an object by name
68 SdrObject
* SdDrawDocument::GetObj(const OUString
& rObjName
) const
70 SdrObject
* pObj
= nullptr;
71 SdrObject
* pObjFound
= nullptr;
72 const SdPage
* pPage
= nullptr;
74 // First search in all pages
76 const sal_uInt16 nMaxPages
= GetPageCount();
78 while (nPage
< nMaxPages
&& !pObjFound
)
80 pPage
= static_cast<const SdPage
*>( GetPage(nPage
) );
81 SdrObjListIter
aIter(pPage
, SdrIterMode::DeepWithGroups
);
83 while (aIter
.IsMore() && !pObjFound
)
87 if( ( pObj
->GetName() == rObjName
) ||
88 ( SdrInventor::Default
== pObj
->GetObjInventor() &&
89 OBJ_OLE2
== pObj
->GetObjIdentifier() &&
90 rObjName
== static_cast< SdrOle2Obj
* >( pObj
)->GetPersistName() ) )
99 // If it couldn't be found, look through all master pages
101 const sal_uInt16 nMaxMasterPages
= GetMasterPageCount();
103 while (nPage
< nMaxMasterPages
&& !pObjFound
)
105 pPage
= static_cast<const SdPage
*>( GetMasterPage(nPage
) );
106 SdrObjListIter
aIter(pPage
, SdrIterMode::DeepWithGroups
);
108 while (aIter
.IsMore() && !pObjFound
)
112 if( ( pObj
->GetName() == rObjName
) ||
113 ( SdrInventor::Default
== pObj
->GetObjInventor() &&
114 OBJ_OLE2
== pObj
->GetObjIdentifier() &&
115 rObjName
== static_cast< SdrOle2Obj
* >( pObj
)->GetPersistName() ) )
127 // Find SdPage by name
128 sal_uInt16
SdDrawDocument::GetPageByName(const OUString
& rPgName
, bool& rbIsMasterPage
) const
130 SdPage
* pPage
= nullptr;
131 sal_uInt16 nPage
= 0;
132 const sal_uInt16 nMaxPages
= GetPageCount();
133 sal_uInt16 nPageNum
= SDRPAGE_NOTFOUND
;
135 rbIsMasterPage
= false;
137 // Search all regular pages and all notes pages (handout pages are
139 while (nPage
< nMaxPages
&& nPageNum
== SDRPAGE_NOTFOUND
)
141 pPage
= const_cast<SdPage
*>(static_cast<const SdPage
*>(
145 && pPage
->GetPageKind() != PageKind::Handout
146 && pPage
->GetName() == rPgName
)
154 // Search all master pages when not found among non-master pages
155 const sal_uInt16 nMaxMasterPages
= GetMasterPageCount();
158 while (nPage
< nMaxMasterPages
&& nPageNum
== SDRPAGE_NOTFOUND
)
160 pPage
= const_cast<SdPage
*>(static_cast<const SdPage
*>(
161 GetMasterPage(nPage
)));
163 if (pPage
&& pPage
->GetName() == rPgName
)
166 rbIsMasterPage
= true;
175 bool SdDrawDocument::IsPageNameUnique( const OUString
& rPgName
) const
177 sal_uInt16 nCount
= 0;
178 SdPage
* pPage
= nullptr;
180 // Search all regular pages and all notes pages (handout pages are ignored)
181 sal_uInt16 nPage
= 0;
182 sal_uInt16 nMaxPages
= GetPageCount();
183 while (nPage
< nMaxPages
)
185 pPage
= const_cast<SdPage
*>(static_cast<const SdPage
*>(GetPage(nPage
)));
187 if (pPage
&& pPage
->GetName() == rPgName
&& pPage
->GetPageKind() != PageKind::Handout
)
193 // Search all master pages
195 nMaxPages
= GetMasterPageCount();
196 while (nPage
< nMaxPages
)
198 pPage
= const_cast<SdPage
*>(static_cast<const SdPage
*>(GetMasterPage(nPage
)));
200 if (pPage
&& pPage
->GetName() == rPgName
)
209 SdPage
* SdDrawDocument::GetSdPage(sal_uInt16 nPgNum
, PageKind ePgKind
) const
211 return mpDrawPageListWatcher
->GetSdPage(ePgKind
, sal_uInt32(nPgNum
));
214 sal_uInt16
SdDrawDocument::GetSdPageCount(PageKind ePgKind
) const
216 return static_cast<sal_uInt16
>(mpDrawPageListWatcher
->GetSdPageCount(ePgKind
));
219 SdPage
* SdDrawDocument::GetMasterSdPage(sal_uInt16 nPgNum
, PageKind ePgKind
)
221 return mpMasterPageListWatcher
->GetSdPage(ePgKind
, sal_uInt32(nPgNum
));
224 sal_uInt16
SdDrawDocument::GetMasterSdPageCount(PageKind ePgKind
) const
226 return static_cast<sal_uInt16
>(mpMasterPageListWatcher
->GetSdPageCount(ePgKind
));
229 sal_uInt16
SdDrawDocument::GetActiveSdPageCount() const
231 return static_cast<sal_uInt16
>(mpDrawPageListWatcher
->GetVisibleSdPageCount());
234 // Adapt the page numbers that are registered in the page objects of the notes
236 void SdDrawDocument::UpdatePageObjectsInNotes(sal_uInt16 nStartPos
)
238 sal_uInt16 nPageCount
= GetPageCount();
239 SdPage
* pPage
= nullptr;
241 for (sal_uInt16 nPage
= nStartPos
; nPage
< nPageCount
; nPage
++)
243 pPage
= static_cast<SdPage
*>( GetPage(nPage
) );
245 // If this is a notes page, find its page object and correct the page
247 if (pPage
&& pPage
->GetPageKind() == PageKind::Notes
)
249 const size_t nObjCount
= pPage
->GetObjCount();
250 for (size_t nObj
= 0; nObj
< nObjCount
; ++nObj
)
252 SdrObject
* pObj
= pPage
->GetObj(nObj
);
253 if (pObj
->GetObjIdentifier() == OBJ_PAGE
&&
254 pObj
->GetObjInventor() == SdrInventor::Default
)
256 // The page object is the preceding page (drawing page)
257 SAL_WARN_IF(!nStartPos
, "sd", "Position of notes page must not be 0.");
259 SAL_WARN_IF(nPage
<= 1, "sd", "Page object must not be a handout.");
261 if (nStartPos
> 0 && nPage
> 1)
262 static_cast<SdrPageObj
*>(pObj
)->SetReferencedPage(GetPage(nPage
- 1));
269 void SdDrawDocument::UpdatePageRelativeURLs(const OUString
& rOldName
, const OUString
& rNewName
)
271 if (rNewName
.isEmpty())
274 SfxItemPool
& rPool(GetPool());
275 for (const SfxPoolItem
* pItem
: rPool
.GetItemSurrogates(EE_FEATURE_FIELD
))
277 const SvxFieldItem
* pFldItem
= dynamic_cast< const SvxFieldItem
* > (pItem
);
281 SvxURLField
* pURLField
= const_cast< SvxURLField
* >( dynamic_cast<const SvxURLField
*>( pFldItem
->GetField() ) );
285 OUString aURL
= pURLField
->GetURL();
287 if (!aURL
.isEmpty() && (aURL
[0] == 35) && (aURL
.indexOf(rOldName
, 1) == 1))
289 if (aURL
.getLength() == rOldName
.getLength() + 1) // standard page name
291 aURL
= aURL
.replaceAt(1, aURL
.getLength() - 1, "") +
293 pURLField
->SetURL(aURL
);
297 const OUString
sNotes(SdResId(STR_NOTES
));
298 if (aURL
.getLength() == rOldName
.getLength() + 2 + sNotes
.getLength()
299 && aURL
.indexOf(sNotes
, rOldName
.getLength() + 2) == rOldName
.getLength() + 2)
301 aURL
= aURL
.replaceAt(1, aURL
.getLength() - 1, "") +
302 rNewName
+ " " + sNotes
;
303 pURLField
->SetURL(aURL
);
312 void SdDrawDocument::UpdatePageRelativeURLs(SdPage
const * pPage
, sal_uInt16 nPos
, sal_Int32 nIncrement
)
314 bool bNotes
= (pPage
->GetPageKind() == PageKind::Notes
);
316 SfxItemPool
& rPool(GetPool());
317 for (const SfxPoolItem
* pItem
: rPool
.GetItemSurrogates(EE_FEATURE_FIELD
))
319 const SvxFieldItem
* pFldItem
;
321 if ((pFldItem
= dynamic_cast< const SvxFieldItem
* > (pItem
)) != nullptr)
323 SvxURLField
* pURLField
= const_cast< SvxURLField
* >( dynamic_cast<const SvxURLField
*>( pFldItem
->GetField() ) );
327 OUString aURL
= pURLField
->GetURL();
329 if (!aURL
.isEmpty() && (aURL
[0] == 35))
331 OUString aHashSlide
= "#" + SdResId(STR_PAGE
);
333 if (aURL
.startsWith(aHashSlide
))
335 OUString aURLCopy
= aURL
;
336 const OUString
sNotes(SdResId(STR_NOTES
));
338 aURLCopy
= aURLCopy
.replaceAt(0, aHashSlide
.getLength(), "");
340 bool bNotesLink
= ( aURLCopy
.getLength() >= sNotes
.getLength() + 3
341 && aURLCopy
.endsWith(sNotes
) );
343 if (bNotesLink
!= bNotes
)
344 continue; // no compatible link and page
347 aURLCopy
= aURLCopy
.replaceAt(aURLCopy
.getLength() - sNotes
.getLength(), sNotes
.getLength(), "");
349 sal_Int32 number
= aURLCopy
.toInt32();
350 sal_uInt16 realPageNumber
= (nPos
+ 1)/ 2;
352 if ( number
>= realPageNumber
)
354 // update link page number
355 number
+= nIncrement
;
356 aURL
= aURL
.replaceAt(aHashSlide
.getLength() + 1, aURL
.getLength() - aHashSlide
.getLength() - 1, "") +
357 OUString::number(number
);
360 aURL
+= " " + sNotes
;
362 pURLField
->SetURL(aURL
);
372 void SdDrawDocument::MovePage(sal_uInt16 nPgNum
, sal_uInt16 nNewPos
)
374 FmFormModel::MovePage(nPgNum
, nNewPos
);
376 sal_uInt16 nMin
= std::min(nPgNum
, nNewPos
);
378 UpdatePageObjectsInNotes(nMin
);
382 void SdDrawDocument::InsertPage(SdrPage
* pPage
, sal_uInt16 nPos
)
384 bool bLast
= (nPos
== GetPageCount());
386 FmFormModel::InsertPage(pPage
, nPos
);
388 static_cast<SdPage
*>(pPage
)->ConnectLink();
390 UpdatePageObjectsInNotes(nPos
);
393 UpdatePageRelativeURLs(static_cast<SdPage
*>( pPage
), nPos
, 1);
395 if (comphelper::LibreOfficeKit::isActive() && static_cast<SdPage
*>(pPage
)->GetPageKind() == PageKind::Standard
)
397 SdXImpressDocument
* pDoc
= comphelper::getUnoTunnelImplementation
<SdXImpressDocument
>(this->getUnoModel());
398 SfxLokHelper::notifyDocumentSizeChangedAllViews(pDoc
);
403 void SdDrawDocument::DeletePage(sal_uInt16 nPgNum
)
405 FmFormModel::DeletePage(nPgNum
);
407 UpdatePageObjectsInNotes(nPgNum
);
411 SdrPage
* SdDrawDocument::RemovePage(sal_uInt16 nPgNum
)
413 SdrPage
* pPage
= FmFormModel::RemovePage(nPgNum
);
415 bool bLast
= ((nPgNum
+1)/2 == (GetPageCount()+1)/2);
417 static_cast<SdPage
*>(pPage
)->DisconnectLink();
418 ReplacePageInCustomShows( dynamic_cast< SdPage
* >( pPage
), nullptr );
419 UpdatePageObjectsInNotes(nPgNum
);
422 UpdatePageRelativeURLs(static_cast<SdPage
*>(pPage
), nPgNum
, -1);
424 if (comphelper::LibreOfficeKit::isActive() && static_cast<SdPage
*>(pPage
)->GetPageKind() == PageKind::Standard
)
426 SdXImpressDocument
* pDoc
= comphelper::getUnoTunnelImplementation
<SdXImpressDocument
>(this->getUnoModel());
427 SfxLokHelper::notifyDocumentSizeChangedAllViews(pDoc
);
433 // Warning: This is not called for new master pages created from SdrModel::Merge,
434 // you also have to modify code in SdDrawDocument::Merge!
435 void SdDrawDocument::InsertMasterPage(SdrPage
* pPage
, sal_uInt16 nPos
)
437 FmFormModel::InsertMasterPage( pPage
, nPos
);
438 if( pPage
->IsMasterPage() && (static_cast<SdPage
*>(pPage
)->GetPageKind() == PageKind::Standard
) )
440 // new master page created, add its style family
441 SdStyleSheetPool
* pStylePool
= static_cast<SdStyleSheetPool
*>( GetStyleSheetPool() );
443 pStylePool
->AddStyleFamily( static_cast<SdPage
*>(pPage
) );
447 SdrPage
* SdDrawDocument::RemoveMasterPage(sal_uInt16 nPgNum
)
449 SdPage
* pPage
= static_cast<SdPage
*>(GetMasterPage(nPgNum
));
450 if( pPage
&& pPage
->IsMasterPage() && (pPage
->GetPageKind() == PageKind::Standard
) )
452 // master page removed, remove its style family
453 SdStyleSheetPool
* pStylePool
= static_cast<SdStyleSheetPool
*>( GetStyleSheetPool() );
455 pStylePool
->RemoveStyleFamily( pPage
);
458 return FmFormModel::RemoveMasterPage(nPgNum
);
462 void SdDrawDocument::SetSelected(SdPage
* pPage
, bool bSelect
)
464 PageKind ePageKind
= pPage
->GetPageKind();
466 if (ePageKind
== PageKind::Standard
)
468 pPage
->SetSelected(bSelect
);
470 const sal_uInt16
nDestPageNum(pPage
->GetPageNum() + 1);
471 SdPage
* pNotesPage
= nullptr;
473 if(nDestPageNum
< GetPageCount())
475 pNotesPage
= static_cast<SdPage
*>(GetPage(nDestPageNum
));
478 if (pNotesPage
&& pNotesPage
->GetPageKind() == PageKind::Notes
)
480 pNotesPage
->SetSelected(bSelect
);
483 else if (ePageKind
== PageKind::Notes
)
485 pPage
->SetSelected(bSelect
);
486 SdPage
* pStandardPage
= static_cast<SdPage
*>( GetPage( pPage
->GetPageNum() - 1 ) );
488 if (pStandardPage
&& pStandardPage
->GetPageKind() == PageKind::Standard
)
489 pStandardPage
->SetSelected(bSelect
);
493 // If no pages exist yet, create them now
494 void SdDrawDocument::CreateFirstPages( SdDrawDocument
const * pRefDocument
/* = 0 */ )
496 // If no page exists yet in the model, (File -> New), insert a page
497 sal_uInt16 nPageCount
= GetPageCount();
502 // #i57181# Paper size depends on Language, like in Writer
503 Size aDefSize
= SvxPaperInfo::GetDefaultPaperSize( MapUnit::Map100thMM
);
505 // Insert handout page
506 SdPage
* pHandoutPage
= AllocSdPage(false);
508 SdPage
* pRefPage
= nullptr;
511 pRefPage
= pRefDocument
->GetSdPage( 0, PageKind::Handout
);
515 pHandoutPage
->SetSize(pRefPage
->GetSize());
516 pHandoutPage
->SetBorder( pRefPage
->GetLeftBorder(), pRefPage
->GetUpperBorder(), pRefPage
->GetRightBorder(), pRefPage
->GetLowerBorder() );
520 pHandoutPage
->SetSize(aDefSize
);
521 pHandoutPage
->SetBorder(0, 0, 0, 0);
524 pHandoutPage
->SetPageKind(PageKind::Handout
);
525 pHandoutPage
->SetName( SdResId(STR_HANDOUT
) );
526 InsertPage(pHandoutPage
, 0);
528 // Insert master page and register this with the handout page
529 SdPage
* pHandoutMPage
= AllocSdPage(true);
530 pHandoutMPage
->SetSize( pHandoutPage
->GetSize() );
531 pHandoutMPage
->SetPageKind(PageKind::Handout
);
532 pHandoutMPage
->SetBorder( pHandoutPage
->GetLeftBorder(),
533 pHandoutPage
->GetUpperBorder(),
534 pHandoutPage
->GetRightBorder(),
535 pHandoutPage
->GetLowerBorder() );
536 InsertMasterPage(pHandoutMPage
, 0);
537 pHandoutPage
->TRG_SetMasterPage( *pHandoutMPage
);
540 // If nPageCount==1 is, the model for the clipboard was created, thus a
541 // default page must already exist
543 bool bClipboard
= false;
546 pRefPage
= pRefDocument
->GetSdPage( 0, PageKind::Standard
);
550 pPage
= AllocSdPage(false);
554 pPage
->SetSize( pRefPage
->GetSize() );
555 pPage
->SetBorder( pRefPage
->GetLeftBorder(), pRefPage
->GetUpperBorder(), pRefPage
->GetRightBorder(), pRefPage
->GetLowerBorder() );
557 else if (meDocType
== DocumentType::Draw
)
559 // Draw: always use default size with margins
560 pPage
->SetSize(aDefSize
);
562 SfxPrinter
* pPrinter
= mpDocSh
->GetPrinter(false);
563 if (pPrinter
&& pPrinter
->IsValid())
565 Size
aOutSize(pPrinter
->GetOutputSize());
566 Point
aPageOffset(pPrinter
->GetPageOffset());
567 aPageOffset
-= pPrinter
->PixelToLogic( Point() );
568 long nOffset
= !aPageOffset
.X() && !aPageOffset
.Y() ? 0 : PRINT_OFFSET
;
570 sal_uLong nTop
= aPageOffset
.Y();
571 sal_uLong nLeft
= aPageOffset
.X();
572 sal_uLong nBottom
= std::max(static_cast<long>(aDefSize
.Height() - aOutSize
.Height() - nTop
+ nOffset
), 0L);
573 sal_uLong nRight
= std::max(static_cast<long>(aDefSize
.Width() - aOutSize
.Width() - nLeft
+ nOffset
), 0L);
575 pPage
->SetBorder(nLeft
, nTop
, nRight
, nBottom
);
579 // The printer is not available. Use a border of 10mm
580 // on each side instead.
581 // This has to be kept synchronized with the border
583 // SvxPageDescPage::PaperSizeSelect_Impl callback.
584 pPage
->SetBorder(1000, 1000, 1000, 1000);
589 // Impress: always use screen format, landscape.
590 Size
aSz( SvxPaperInfo::GetPaperSize(PAPER_SCREEN_16_9
, MapUnit::Map100thMM
) );
591 pPage
->SetSize( Size( aSz
.Height(), aSz
.Width() ) );
592 pPage
->SetBorder(0, 0, 0, 0);
595 InsertPage(pPage
, 1);
600 pPage
= static_cast<SdPage
*>( GetPage(1) );
603 // Insert master page, then register this with the page
604 SdPage
* pMPage
= AllocSdPage(true);
605 pMPage
->SetSize( pPage
->GetSize() );
606 pMPage
->SetBorder( pPage
->GetLeftBorder(),
607 pPage
->GetUpperBorder(),
608 pPage
->GetRightBorder(),
609 pPage
->GetLowerBorder() );
610 InsertMasterPage(pMPage
, 1);
611 pPage
->TRG_SetMasterPage( *pMPage
);
613 pMPage
->SetLayoutName( pPage
->GetLayoutName() );
616 SdPage
* pNotesPage
= AllocSdPage(false);
619 pRefPage
= pRefDocument
->GetSdPage( 0, PageKind::Notes
);
623 pNotesPage
->SetSize( pRefPage
->GetSize() );
624 pNotesPage
->SetBorder( pRefPage
->GetLeftBorder(), pRefPage
->GetUpperBorder(), pRefPage
->GetRightBorder(), pRefPage
->GetLowerBorder() );
628 // Always use portrait format
629 if (aDefSize
.Height() >= aDefSize
.Width())
631 pNotesPage
->SetSize(aDefSize
);
635 pNotesPage
->SetSize( Size(aDefSize
.Height(), aDefSize
.Width()) );
638 pNotesPage
->SetBorder(0, 0, 0, 0);
640 pNotesPage
->SetPageKind(PageKind::Notes
);
641 InsertPage(pNotesPage
, 2);
643 pNotesPage
->SetLayoutName( pPage
->GetLayoutName() );
645 // Insert master page, then register this with the notes page
646 SdPage
* pNotesMPage
= AllocSdPage(true);
647 pNotesMPage
->SetSize( pNotesPage
->GetSize() );
648 pNotesMPage
->SetPageKind(PageKind::Notes
);
649 pNotesMPage
->SetBorder( pNotesPage
->GetLeftBorder(),
650 pNotesPage
->GetUpperBorder(),
651 pNotesPage
->GetRightBorder(),
652 pNotesPage
->GetLowerBorder() );
653 InsertMasterPage(pNotesMPage
, 2);
654 pNotesPage
->TRG_SetMasterPage( *pNotesMPage
);
656 pNotesMPage
->SetLayoutName( pPage
->GetLayoutName() );
658 if( !pRefPage
&& (meDocType
!= DocumentType::Draw
) )
659 pPage
->SetAutoLayout( AUTOLAYOUT_TITLE
, true, true );
661 mpWorkStartupTimer
.reset( new Timer("DrawWorkStartupTimer") );
662 mpWorkStartupTimer
->SetInvokeHandler( LINK(this, SdDrawDocument
, WorkStartupHdl
) );
663 mpWorkStartupTimer
->SetTimeout(2000);
664 mpWorkStartupTimer
->Start();
669 // Creates missing notes and handout pages (after PowerPoint import).
670 // We assume that at least one default page and one default master page exist.
672 bool SdDrawDocument::CreateMissingNotesAndHandoutPages()
675 sal_uInt16 nPageCount
= GetPageCount();
680 SdPage
* pHandoutMPage
= static_cast<SdPage
*>( GetMasterPage(0) );
681 pHandoutMPage
->SetPageKind(PageKind::Handout
);
683 SdPage
* pHandoutPage
= static_cast<SdPage
*>( GetPage(0) );
684 pHandoutPage
->SetPageKind(PageKind::Handout
);
685 pHandoutPage
->TRG_SetMasterPage( *pHandoutMPage
);
687 for (sal_uInt16 i
= 1; i
< nPageCount
; i
= i
+ 2)
689 SdPage
* pPage
= static_cast<SdPage
*>( GetPage(i
) );
691 if(!pPage
->TRG_HasMasterPage())
693 // No master page set -> use first default master page
694 // (If there was no default page in the PPT)
695 pPage
->TRG_SetMasterPage(*GetMasterPage(1));
698 SdPage
* pNotesPage
= static_cast<SdPage
*>( GetPage(i
+1) );
699 pNotesPage
->SetPageKind(PageKind::Notes
);
701 // Set notes master page
702 sal_uInt16 nMasterPageAfterPagesMasterPage
= pPage
->TRG_GetMasterPage().GetPageNum() + 1;
703 pNotesPage
->TRG_SetMasterPage(*GetMasterPage(nMasterPageAfterPagesMasterPage
));
707 StopWorkStartupDelay();
714 void SdDrawDocument::UnselectAllPages()
716 sal_uInt16 nNoOfPages
= GetSdPageCount(PageKind::Standard
);
717 for (sal_uInt16 nPage
= 0; nPage
< nNoOfPages
; ++nPage
)
719 SdPage
* pPage
= GetSdPage(nPage
, PageKind::Standard
);
720 pPage
->SetSelected(false);
724 // + Move selected pages after said page
725 // (nTargetPage = (sal_uInt16)-1 --> move before first page)
726 // + Returns sal_True when the page has been moved
727 bool SdDrawDocument::MovePages(sal_uInt16 nTargetPage
)
729 SdPage
* pPage
= nullptr;
731 sal_uInt16 nNoOfPages
= GetSdPageCount(PageKind::Standard
);
732 bool bSomethingHappened
= false;
734 const bool bUndo
= IsUndoEnabled();
737 BegUndo(SdResId(STR_UNDO_MOVEPAGES
));
739 // List of selected pages
740 std::vector
<SdPage
*> aPageList
;
741 for (nPage
= 0; nPage
< nNoOfPages
; nPage
++)
743 pPage
= GetSdPage(nPage
, PageKind::Standard
);
745 if (pPage
->IsSelected()) {
746 aPageList
.push_back(pPage
);
750 // If necessary, look backwards, until we find a page that wasn't selected
753 if (nPage
!= sal_uInt16(-1))
755 pPage
= GetSdPage(nPage
, PageKind::Standard
);
756 while (nPage
> 0 && pPage
->IsSelected())
759 pPage
= GetSdPage(nPage
, PageKind::Standard
);
762 if (pPage
->IsSelected())
764 nPage
= sal_uInt16(-1);
768 // Insert before the first page
769 if (nPage
== sal_uInt16(-1))
771 std::vector
<SdPage
*>::reverse_iterator iter
;
772 for (iter
= aPageList
.rbegin(); iter
!= aPageList
.rend(); ++iter
)
774 nPage
= (*iter
)->GetPageNum();
777 SdrPage
* pPg
= GetPage(nPage
);
779 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
, 1));
781 pPg
= GetPage(nPage
+1);
783 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
+1, 2));
784 MovePage(nPage
+1, 2);
785 bSomethingHappened
= true;
789 // Insert after <nPage>
792 nTargetPage
= 2 * nPage
+ 1; // PageKind::Standard --> absolute
794 for (const auto& rpPage
: aPageList
)
796 nPage
= rpPage
->GetPageNum();
797 if (nPage
> nTargetPage
)
799 nTargetPage
+= 2; // Insert _after_ the page
801 if (nPage
!= nTargetPage
)
803 SdrPage
* pPg
= GetPage(nPage
);
805 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
, nTargetPage
));
806 MovePage(nPage
, nTargetPage
);
807 pPg
= GetPage(nPage
+1);
809 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
+1, nTargetPage
+1));
810 MovePage(nPage
+1, nTargetPage
+1);
811 bSomethingHappened
= true;
816 if (nPage
!= nTargetPage
)
818 SdrPage
* pPg
= GetPage(nPage
+1);
820 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
+1, nTargetPage
+1));
821 MovePage(nPage
+1, nTargetPage
+1);
822 pPg
= GetPage(nPage
);
824 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg
, nPage
, nTargetPage
));
825 MovePage(nPage
, nTargetPage
);
826 bSomethingHappened
= true;
829 nTargetPage
= rpPage
->GetPageNum();
836 return bSomethingHappened
;
839 // Return number of links in sfx2::LinkManager
840 sal_uLong
SdDrawDocument::GetLinkCount() const
842 return m_pLinkManager
->GetLinks().size();
846 void SdDrawDocument::SetLanguage( const LanguageType eLang
, const sal_uInt16 nId
)
848 bool bChanged
= false;
850 if( nId
== EE_CHAR_LANGUAGE
&& meLanguage
!= eLang
)
855 else if( nId
== EE_CHAR_LANGUAGE_CJK
&& meLanguageCJK
!= eLang
)
857 meLanguageCJK
= eLang
;
860 else if( nId
== EE_CHAR_LANGUAGE_CTL
&& meLanguageCTL
!= eLang
)
862 meLanguageCTL
= eLang
;
868 GetDrawOutliner().SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
869 m_pHitTestOutliner
->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
870 m_pItemPool
->SetPoolDefaultItem( SvxLanguageItem( eLang
, nId
) );
871 SetChanged( bChanged
);
876 LanguageType
SdDrawDocument::GetLanguage( const sal_uInt16 nId
) const
878 LanguageType eLangType
= meLanguage
;
880 if( nId
== EE_CHAR_LANGUAGE_CJK
)
881 eLangType
= meLanguageCJK
;
882 else if( nId
== EE_CHAR_LANGUAGE_CTL
)
883 eLangType
= meLanguageCTL
;
888 // Initiate WorkStartup
889 IMPL_LINK_NOARG(SdDrawDocument
, WorkStartupHdl
, Timer
*, void)
891 if (IsTransportContainer())
895 mpDocSh
->SetWaitCursor( true );
897 bool bChanged
= IsChanged(); // remember this
899 // Initialize Autolayouts
900 SdPage
* pHandoutMPage
= GetMasterSdPage(0, PageKind::Handout
);
902 if (pHandoutMPage
->GetAutoLayout() == AUTOLAYOUT_NONE
)
904 // No AutoLayout yet -> initialize
905 pHandoutMPage
->SetAutoLayout(AUTOLAYOUT_HANDOUT6
, true, true);
908 SdPage
* pPage
= GetSdPage(0, PageKind::Standard
);
910 if (pPage
->GetAutoLayout() == AUTOLAYOUT_NONE
)
912 // No AutoLayout yet -> initialize
913 pPage
->SetAutoLayout(AUTOLAYOUT_NONE
, true, true);
916 SdPage
* pNotesPage
= GetSdPage(0, PageKind::Notes
);
918 if (pNotesPage
->GetAutoLayout() == AUTOLAYOUT_NONE
)
920 // No AutoLayout yet -> initialize
921 pNotesPage
->SetAutoLayout(AUTOLAYOUT_NOTES
, true, true);
924 SetChanged(bChanged
);
927 mpDocSh
->SetWaitCursor( false );
930 // When the WorkStartupTimer has been created (this only happens in
931 // SdDrawViewShell::Construct() ), the timer may be stopped and the WorkStartup
933 void SdDrawDocument::StopWorkStartupDelay()
935 if (mpWorkStartupTimer
)
937 if ( mpWorkStartupTimer
->IsActive() )
939 // Timer not yet expired -> initiate WorkStartup
940 mpWorkStartupTimer
->Stop();
941 WorkStartupHdl(nullptr);
944 mpWorkStartupTimer
.reset();
948 // When the WorkStartupTimer has been created (this only happens in
949 // SdDrawViewShell::Construct() ), the timer may be stopped and the WorkStartup
951 SdAnimationInfo
* SdDrawDocument::GetAnimationInfo(SdrObject
* pObject
)
953 DBG_ASSERT(pObject
, "sd::SdDrawDocument::GetAnimationInfo(), invalid argument!");
955 return GetShapeUserData( *pObject
);
960 SdAnimationInfo
* SdDrawDocument::GetShapeUserData(SdrObject
& rObject
, bool bCreate
/* = false */ )
963 sal_uInt16 nUDCount
= rObject
.GetUserDataCount();
964 SdAnimationInfo
* pRet
= nullptr;
966 // Can we find animation information within the user data?
967 for (nUD
= 0; nUD
< nUDCount
; nUD
++)
969 SdrObjUserData
* pUD
= rObject
.GetUserData(nUD
);
970 if((pUD
->GetInventor() == SdrInventor::StarDrawUserData
) && (pUD
->GetId() == SD_ANIMATIONINFO_ID
))
972 pRet
= dynamic_cast<SdAnimationInfo
*>(pUD
);
977 if( (pRet
== nullptr) && bCreate
)
979 pRet
= new SdAnimationInfo( rObject
);
980 rObject
.AppendUserData( std::unique_ptr
<SdrObjUserData
>(pRet
) );
986 /** this method enforces that the masterpages are in the correct order,
987 that is at position 1 is a PageKind::Standard masterpage followed by a
988 PageKind::Notes masterpage and so on. #
990 void SdDrawDocument::CheckMasterPages()
992 sal_uInt16 nMaxPages
= GetMasterPageCount();
994 // we need at least a handout master and one master page
1000 SdPage
* pPage
= nullptr;
1004 // first see if the page order is correct
1005 for( nPage
= 1; nPage
< nMaxPages
; nPage
++ )
1007 pPage
= static_cast<SdPage
*> (GetMasterPage( nPage
));
1008 // if an odd page is not a standard page or an even page is not a notes page
1009 if( ((1 == (nPage
& 1)) && (pPage
->GetPageKind() != PageKind::Standard
) ) ||
1010 ((0 == (nPage
& 1)) && (pPage
->GetPageKind() != PageKind::Notes
) ) )
1011 break; // then we have a fatal error
1014 if( nPage
>= nMaxPages
)
1017 SdPage
* pNotesPage
= nullptr;
1019 // there is a fatal error in the master page order,
1020 // we need to repair the document
1021 bool bChanged
= false;
1024 while( nPage
< nMaxPages
)
1026 pPage
= static_cast<SdPage
*> (GetMasterPage( nPage
));
1027 if( pPage
->GetPageKind() != PageKind::Standard
)
1030 sal_uInt16 nFound
= nPage
+ 1;
1031 while( nFound
< nMaxPages
)
1033 pPage
= static_cast<SdPage
*>(GetMasterPage( nFound
));
1034 if( PageKind::Standard
== pPage
->GetPageKind() )
1036 MoveMasterPage( nFound
, nPage
);
1037 pPage
->SetInserted();
1045 // if we don't have any more standard pages, were done
1046 if( nMaxPages
== nFound
)
1052 if( nPage
< nMaxPages
)
1053 pNotesPage
= static_cast<SdPage
*>(GetMasterPage( nPage
));
1055 pNotesPage
= nullptr;
1057 if( (nullptr == pNotesPage
) || (pNotesPage
->GetPageKind() != PageKind::Notes
) || ( pPage
->GetLayoutName() != pNotesPage
->GetLayoutName() ) )
1061 sal_uInt16 nFound
= nPage
+ 1;
1062 while( nFound
< nMaxPages
)
1064 pNotesPage
= static_cast<SdPage
*>(GetMasterPage( nFound
));
1065 if( (PageKind::Notes
== pNotesPage
->GetPageKind()) && ( pPage
->GetLayoutName() == pNotesPage
->GetLayoutName() ) )
1067 MoveMasterPage( nFound
, nPage
);
1068 pNotesPage
->SetInserted();
1075 // looks like we lost a notes page
1076 if( nMaxPages
== nFound
)
1080 // first find a reference notes page for size
1081 SdPage
* pRefNotesPage
= nullptr;
1083 while( nFound
< nMaxPages
)
1085 pRefNotesPage
= static_cast<SdPage
*>(GetMasterPage( nFound
));
1086 if( PageKind::Notes
== pRefNotesPage
->GetPageKind() )
1090 if( nFound
== nMaxPages
)
1091 pRefNotesPage
= nullptr;
1093 SdPage
* pNewNotesPage
= AllocSdPage(true);
1094 pNewNotesPage
->SetPageKind(PageKind::Notes
);
1097 pNewNotesPage
->SetSize( pRefNotesPage
->GetSize() );
1098 pNewNotesPage
->SetBorder( pRefNotesPage
->GetLeftBorder(),
1099 pRefNotesPage
->GetUpperBorder(),
1100 pRefNotesPage
->GetRightBorder(),
1101 pRefNotesPage
->GetLowerBorder() );
1103 InsertMasterPage(pNewNotesPage
, nPage
);
1104 pNewNotesPage
->SetLayoutName( pPage
->GetLayoutName() );
1105 pNewNotesPage
->SetAutoLayout(AUTOLAYOUT_NOTES
, true, true );
1113 // now remove all remaining and unused non PageKind::Standard slides
1114 while( nPage
< nMaxPages
)
1118 RemoveMasterPage( nPage
);
1124 OSL_FAIL( "master pages where in a wrong order" );
1125 RecalcPageNums( true);
1129 sal_uInt16
SdDrawDocument::CreatePage (
1130 SdPage
* pActualPage
,
1132 const OUString
& sStandardPageName
,
1133 const OUString
& sNotesPageName
,
1134 AutoLayout eStandardLayout
,
1135 AutoLayout eNotesLayout
,
1138 const sal_Int32 nInsertPosition
)
1140 SdPage
* pPreviousStandardPage
;
1141 SdPage
* pPreviousNotesPage
;
1142 SdPage
* pStandardPage
;
1145 // From the given page determine the standard page and notes page of which
1146 // to take the layout and the position where to insert the new pages.
1147 if (ePageKind
== PageKind::Notes
)
1149 pPreviousNotesPage
= pActualPage
;
1150 sal_uInt16 nNotesPageNum
= pPreviousNotesPage
->GetPageNum() + 2;
1151 pPreviousStandardPage
= static_cast<SdPage
*>( GetPage(nNotesPageNum
- 3) );
1152 eStandardLayout
= pPreviousStandardPage
->GetAutoLayout();
1156 pPreviousStandardPage
= pActualPage
;
1157 sal_uInt16 nStandardPageNum
= pPreviousStandardPage
->GetPageNum() + 2;
1158 pPreviousNotesPage
= static_cast<SdPage
*>( GetPage(nStandardPageNum
- 1) );
1159 eNotesLayout
= pPreviousNotesPage
->GetAutoLayout();
1162 // Create new standard page and set it up
1163 pStandardPage
= AllocSdPage(false);
1165 // Set the size here since else the presobj autolayout
1167 pStandardPage
->SetSize( pPreviousStandardPage
->GetSize() );
1168 pStandardPage
->SetBorder( pPreviousStandardPage
->GetLeftBorder(),
1169 pPreviousStandardPage
->GetUpperBorder(),
1170 pPreviousStandardPage
->GetRightBorder(),
1171 pPreviousStandardPage
->GetLowerBorder() );
1173 // Use master page of current page.
1174 pStandardPage
->TRG_SetMasterPage(pPreviousStandardPage
->TRG_GetMasterPage());
1176 // User layout of current standard page
1177 pStandardPage
->SetLayoutName( pPreviousStandardPage
->GetLayoutName() );
1178 pStandardPage
->SetAutoLayout(eStandardLayout
, true);
1179 pStandardPage
->setHeaderFooterSettings( pPreviousStandardPage
->getHeaderFooterSettings() );
1181 // transition settings of current page
1182 pStandardPage
->setTransitionType( pPreviousStandardPage
->getTransitionType() );
1183 pStandardPage
->setTransitionSubtype( pPreviousStandardPage
->getTransitionSubtype() );
1184 pStandardPage
->setTransitionDirection( pPreviousStandardPage
->getTransitionDirection() );
1185 pStandardPage
->setTransitionFadeColor( pPreviousStandardPage
->getTransitionFadeColor() );
1186 pStandardPage
->setTransitionDuration( pPreviousStandardPage
->getTransitionDuration() );
1188 // apply previous animation timing
1189 pStandardPage
->SetPresChange( pPreviousStandardPage
->GetPresChange() );
1190 pStandardPage
->SetTime( pPreviousStandardPage
->GetTime() );
1192 // Create new notes page and set it up
1193 pNotesPage
= AllocSdPage(false);
1194 pNotesPage
->SetPageKind(PageKind::Notes
);
1196 // Use master page of current page
1197 pNotesPage
->TRG_SetMasterPage(pPreviousNotesPage
->TRG_GetMasterPage());
1199 // Use layout of current notes page
1200 pNotesPage
->SetLayoutName( pPreviousNotesPage
->GetLayoutName() );
1201 pNotesPage
->SetAutoLayout(eNotesLayout
, true);
1202 pNotesPage
->setHeaderFooterSettings( pPreviousNotesPage
->getHeaderFooterSettings() );
1204 return InsertPageSet (
1216 sal_uInt16
SdDrawDocument::DuplicatePage (sal_uInt16 nPageNum
)
1218 PageKind ePageKind
= PageKind::Standard
;
1221 SdPage
* pActualPage
= GetSdPage(nPageNum
, ePageKind
);
1223 // Get background flags
1224 SdrLayerAdmin
& rLayerAdmin
= GetLayerAdmin();
1225 SdrLayerID aBckgrnd
= rLayerAdmin
.GetLayerID(sUNO_LayerName_background
);
1226 SdrLayerID aBckgrndObj
= rLayerAdmin
.GetLayerID(sUNO_LayerName_background_objects
);
1227 SdrLayerIDSet aVisibleLayers
= pActualPage
->TRG_GetMasterPageVisibleLayers();
1229 return DuplicatePage (
1230 pActualPage
, ePageKind
,
1231 // No names for the new slides
1232 OUString(), OUString(),
1233 aVisibleLayers
.IsSet(aBckgrnd
),
1234 aVisibleLayers
.IsSet(aBckgrndObj
), -1);
1237 sal_uInt16
SdDrawDocument::DuplicatePage (
1238 SdPage
* pActualPage
,
1240 const OUString
& sStandardPageName
,
1241 const OUString
& sNotesPageName
,
1244 const sal_Int32 nInsertPosition
)
1246 SdPage
* pPreviousStandardPage
;
1247 SdPage
* pPreviousNotesPage
;
1248 SdPage
* pStandardPage
;
1251 // From the given page determine the standard page and the notes page
1252 // of which to make copies.
1253 if (ePageKind
== PageKind::Notes
)
1255 pPreviousNotesPage
= pActualPage
;
1256 sal_uInt16 nNotesPageNum
= pPreviousNotesPage
->GetPageNum() + 2;
1257 pPreviousStandardPage
= static_cast<SdPage
*>( GetPage(nNotesPageNum
- 3) );
1261 pPreviousStandardPage
= pActualPage
;
1262 sal_uInt16 nStandardPageNum
= pPreviousStandardPage
->GetPageNum() + 2;
1263 pPreviousNotesPage
= static_cast<SdPage
*>( GetPage(nStandardPageNum
- 1) );
1266 // Create duplicates of a standard page and the associated notes page
1267 pStandardPage
= static_cast<SdPage
*>( pPreviousStandardPage
->CloneSdrPage(*this) );
1268 pNotesPage
= static_cast<SdPage
*>( pPreviousNotesPage
->CloneSdrPage(*this) );
1270 return InsertPageSet (
1282 sal_uInt16
SdDrawDocument::InsertPageSet (
1283 SdPage
* pActualPage
,
1285 const OUString
& sStandardPageName
,
1286 const OUString
& sNotesPageName
,
1289 SdPage
* pStandardPage
,
1291 sal_Int32 nInsertPosition
)
1293 SdPage
* pPreviousStandardPage
;
1294 SdPage
* pPreviousNotesPage
;
1295 sal_uInt16 nStandardPageNum
;
1296 sal_uInt16 nNotesPageNum
;
1297 OUString
aNotesPageName(sNotesPageName
);
1299 // Gather some information about the standard page and the notes page
1300 // that are to be inserted. This makes sure that there is always one
1301 // standard page followed by one notes page.
1302 if (ePageKind
== PageKind::Notes
)
1304 pPreviousNotesPage
= pActualPage
;
1305 nNotesPageNum
= pPreviousNotesPage
->GetPageNum() + 2;
1306 pPreviousStandardPage
= static_cast<SdPage
*>( GetPage(nNotesPageNum
- 3) );
1307 nStandardPageNum
= nNotesPageNum
- 1;
1311 pPreviousStandardPage
= pActualPage
;
1312 nStandardPageNum
= pPreviousStandardPage
->GetPageNum() + 2;
1313 pPreviousNotesPage
= static_cast<SdPage
*>( GetPage(nStandardPageNum
- 1) );
1314 nNotesPageNum
= nStandardPageNum
+ 1;
1315 aNotesPageName
= sStandardPageName
;
1318 OSL_ASSERT(nNotesPageNum
==nStandardPageNum
+1);
1319 if (nInsertPosition
< 0)
1320 nInsertPosition
= nStandardPageNum
;
1322 // Set up and insert the standard page
1324 pPreviousStandardPage
,
1331 // Set up and insert the notes page
1332 pNotesPage
->SetPageKind(PageKind::Notes
);
1341 // Return an index that allows the caller to access the newly inserted
1342 // pages by using GetSdPage()
1343 return pStandardPage
->GetPageNum() / 2;
1346 void SdDrawDocument::SetupNewPage (
1347 SdPage
const * pPreviousPage
,
1349 const OUString
& sPageName
,
1350 sal_uInt16 nInsertionPoint
,
1354 if (pPreviousPage
!= nullptr)
1356 pPage
->SetSize( pPreviousPage
->GetSize() );
1357 pPage
->SetBorder( pPreviousPage
->GetLeftBorder(),
1358 pPreviousPage
->GetUpperBorder(),
1359 pPreviousPage
->GetRightBorder(),
1360 pPreviousPage
->GetLowerBorder() );
1362 pPage
->SetName(sPageName
);
1364 InsertPage(pPage
, nInsertionPoint
);
1366 if (pPreviousPage
!= nullptr)
1368 SdrLayerAdmin
& rLayerAdmin
= GetLayerAdmin();
1369 SdrLayerID aBckgrnd
= rLayerAdmin
.GetLayerID(sUNO_LayerName_background
);
1370 SdrLayerID aBckgrndObj
= rLayerAdmin
.GetLayerID(sUNO_LayerName_background_objects
);
1371 SdrLayerIDSet aVisibleLayers
= pPreviousPage
->TRG_GetMasterPageVisibleLayers();
1372 aVisibleLayers
.Set(aBckgrnd
, bIsPageBack
);
1373 aVisibleLayers
.Set(aBckgrndObj
, bIsPageObj
);
1374 pPage
->TRG_SetMasterPageVisibleLayers(aVisibleLayers
);
1378 sd::UndoManager
* SdDrawDocument::GetUndoManager() const
1380 return mpDocSh
? dynamic_cast< sd::UndoManager
* >(mpDocSh
->GetUndoManager()) : nullptr;
1383 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */