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 "MasterPageContainer.hxx"
22 #include "MasterPageDescriptor.hxx"
23 #include "MasterPageContainerFiller.hxx"
24 #include "MasterPageContainerQueue.hxx"
25 #include <TemplateScanner.hxx>
26 #include <tools/AsynchronousTask.hxx>
27 #include <strings.hrc>
33 #include <unomodel.hxx>
34 #include <com/sun/star/frame/Desktop.hpp>
35 #include <com/sun/star/io/XStream.hpp>
36 #include <com/sun/star/io/XInputStream.hpp>
37 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/uno/Reference.hxx>
40 #include <com/sun/star/uno/Any.hxx>
41 #include <com/sun/star/util/XCloseable.hpp>
42 #include <comphelper/processfactory.hxx>
43 #include <sfx2/app.hxx>
44 #include <svx/svdpage.hxx>
45 #include <DrawDocShell.hxx>
46 #include <drawdoc.hxx>
48 #include <svl/itemset.hxx>
49 #include <svl/eitem.hxx>
50 #include <sdresid.hxx>
51 #include <tools/TimerBasedTaskExecution.hxx>
53 #include <osl/mutex.hxx>
54 #include <osl/getglobalmutex.hxx>
55 #include <xmloff/autolayout.hxx>
57 using namespace ::com::sun::star
;
58 using namespace ::com::sun::star::uno
;
62 typedef ::std::vector
<sd::sidebar::SharedMasterPageDescriptor
> MasterPageContainerType
;
64 } // end of anonymous namespace
66 namespace sd
{ namespace sidebar
{
68 /** Inner implementation class of the MasterPageContainer.
70 class MasterPageContainer::Implementation
71 : public SdGlobalResource
,
72 public MasterPageContainerFiller::ContainerAdapter
,
73 public MasterPageContainerQueue::ContainerAdapter
76 mutable ::osl::Mutex maMutex
;
78 static std::weak_ptr
<Implementation
> mpInstance
;
79 MasterPageContainerType maContainer
;
81 static std::shared_ptr
<Implementation
> Instance();
84 void AddChangeListener (const Link
<MasterPageContainerChangeEvent
&,void>& rLink
);
85 void RemoveChangeListener (const Link
<MasterPageContainerChangeEvent
&,void>& rLink
);
86 void UpdatePreviewSizePixel();
87 const Size
& GetPreviewSizePixel (PreviewSize eSize
) const;
89 bool HasToken (Token aToken
) const;
90 const SharedMasterPageDescriptor
GetDescriptor (MasterPageContainer::Token aToken
) const;
91 SharedMasterPageDescriptor
GetDescriptor (MasterPageContainer::Token aToken
);
92 virtual Token
PutMasterPage (const SharedMasterPageDescriptor
& rDescriptor
) override
;
93 void InvalidatePreview (Token aToken
);
94 Image
GetPreviewForToken (
96 PreviewSize ePreviewSize
);
97 PreviewState
GetPreviewState (Token aToken
) const;
98 bool RequestPreview (Token aToken
);
100 Reference
<frame::XModel
> GetModel();
101 SdDrawDocument
* GetDocument();
103 void FireContainerChange (
104 MasterPageContainerChangeEvent::EventType eType
,
107 virtual bool UpdateDescriptor (
108 const SharedMasterPageDescriptor
& rpDescriptor
,
109 bool bForcePageObject
,
111 bool bSendEvents
) override
;
113 void ReleaseDescriptor (Token aToken
);
115 /** Called by the MasterPageContainerFiller to notify that all master
116 pages from template documents have been added.
118 virtual void FillingDone() override
;
122 virtual ~Implementation() override
;
124 class Deleter
{ public:
125 void operator() (Implementation
* pObject
) { delete pObject
; }
127 friend class Deleter
;
129 enum InitializationState
{ NOT_INITIALIZED
, INITIALIZING
, INITIALIZED
} meInitializationState
;
131 std::unique_ptr
<MasterPageContainerQueue
> mpRequestQueue
;
132 css::uno::Reference
<css::frame::XModel
> mxModel
;
133 SdDrawDocument
* mpDocument
;
134 PreviewRenderer maPreviewRenderer
;
135 /** Remember whether the first page object has already been used to
136 determine the correct size ratio.
138 bool mbFirstPageObjectSeen
;
140 // The widths for the previews contain two pixels for the border that is
141 // painted around the preview.
142 static const int SMALL_PREVIEW_WIDTH
= 72 + 2;
143 static const int LARGE_PREVIEW_WIDTH
= 2*72 + 2;
145 /** This substition of page preview shows "Preparing preview" and is
146 shown as long as the actual previews are not being present.
148 Image maLargePreviewBeingCreated
;
149 Image maSmallPreviewBeingCreated
;
151 /** This substition of page preview is shown when a preview can not be
152 created and thus is not available.
154 Image maLargePreviewNotAvailable
;
155 Image maSmallPreviewNotAvailable
;
157 ::std::vector
<Link
<MasterPageContainerChangeEvent
&,void>> maChangeListeners
;
159 // We have to remember the tasks for initialization and filling in case
160 // a MasterPageContainer object is destroyed before these tasks have
162 std::weak_ptr
<sd::tools::TimerBasedTaskExecution
> mpFillerTask
;
164 Size maSmallPreviewSizePixel
;
165 Size maLargePreviewSizePixel
;
167 Image
GetPreviewSubstitution(const char* pId
, PreviewSize ePreviewSize
);
169 void CleanContainer();
172 //===== MasterPageContainer ===================================================
174 std::weak_ptr
<MasterPageContainer::Implementation
>
175 MasterPageContainer::Implementation::mpInstance
;
177 std::shared_ptr
<MasterPageContainer::Implementation
>
178 MasterPageContainer::Implementation::Instance()
180 std::shared_ptr
<MasterPageContainer::Implementation
> pInstance
;
182 if (Implementation::mpInstance
.expired())
184 ::osl::GetGlobalMutex aMutexFunctor
;
185 ::osl::MutexGuard
aGuard (aMutexFunctor());
186 if (Implementation::mpInstance
.expired())
188 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
189 pInstance
= std::shared_ptr
<MasterPageContainer::Implementation
>(
190 new MasterPageContainer::Implementation(),
191 MasterPageContainer::Implementation::Deleter());
192 SdGlobalResourceContainer::Instance().AddResource(pInstance
);
193 Implementation::mpInstance
= pInstance
;
196 pInstance
= std::shared_ptr
<MasterPageContainer::Implementation
>(
197 Implementation::mpInstance
);
201 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
202 pInstance
= std::shared_ptr
<MasterPageContainer::Implementation
>(
203 Implementation::mpInstance
);
206 DBG_ASSERT (pInstance
.get()!=nullptr,
207 "MasterPageContainer::Implementation::Instance(): instance is nullptr");
211 MasterPageContainer::MasterPageContainer()
212 : mpImpl(Implementation::Instance()),
218 MasterPageContainer::~MasterPageContainer()
222 void MasterPageContainer::AddChangeListener (const Link
<MasterPageContainerChangeEvent
&,void>& rLink
)
224 mpImpl
->AddChangeListener(rLink
);
227 void MasterPageContainer::RemoveChangeListener (const Link
<MasterPageContainerChangeEvent
&,void>& rLink
)
229 mpImpl
->RemoveChangeListener(rLink
);
232 void MasterPageContainer::SetPreviewSize (PreviewSize eSize
)
234 mePreviewSize
= eSize
;
235 mpImpl
->FireContainerChange(
236 MasterPageContainerChangeEvent::EventType::SIZE_CHANGED
,
240 Size
const & MasterPageContainer::GetPreviewSizePixel() const
242 return mpImpl
->GetPreviewSizePixel(mePreviewSize
);
245 MasterPageContainer::Token
MasterPageContainer::PutMasterPage (
246 const SharedMasterPageDescriptor
& rDescriptor
)
248 return mpImpl
->PutMasterPage(rDescriptor
);
251 void MasterPageContainer::AcquireToken (Token aToken
)
253 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
254 if (pDescriptor
.get() != nullptr)
256 ++pDescriptor
->mnUseCount
;
260 void MasterPageContainer::ReleaseToken (Token aToken
)
262 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
263 if (pDescriptor
.get() != nullptr)
265 OSL_ASSERT(pDescriptor
->mnUseCount
>0);
266 --pDescriptor
->mnUseCount
;
267 if (pDescriptor
->mnUseCount
<= 0)
269 switch (pDescriptor
->meOrigin
)
277 mpImpl
->ReleaseDescriptor(aToken
);
284 int MasterPageContainer::GetTokenCount() const
286 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
288 return mpImpl
->maContainer
.size();
291 bool MasterPageContainer::HasToken (Token aToken
) const
293 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
295 return mpImpl
->HasToken(aToken
);
298 MasterPageContainer::Token
MasterPageContainer::GetTokenForIndex (int nIndex
)
300 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
302 Token
aResult (NIL_TOKEN
);
303 if (HasToken(nIndex
))
304 aResult
= mpImpl
->maContainer
[nIndex
]->maToken
;
308 MasterPageContainer::Token
MasterPageContainer::GetTokenForURL (
309 const OUString
& sURL
)
311 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
313 Token
aResult (NIL_TOKEN
);
316 MasterPageContainerType::iterator
iEntry (
318 mpImpl
->maContainer
.begin(),
319 mpImpl
->maContainer
.end(),
320 MasterPageDescriptor::URLComparator(sURL
)));
321 if (iEntry
!= mpImpl
->maContainer
.end())
322 aResult
= (*iEntry
)->maToken
;
327 MasterPageContainer::Token
MasterPageContainer::GetTokenForStyleName (const OUString
& sStyleName
)
329 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
331 Token
aResult (NIL_TOKEN
);
332 if (!sStyleName
.isEmpty())
334 MasterPageContainerType::iterator
iEntry (
336 mpImpl
->maContainer
.begin(),
337 mpImpl
->maContainer
.end(),
338 MasterPageDescriptor::StyleNameComparator(sStyleName
)));
339 if (iEntry
!= mpImpl
->maContainer
.end())
340 aResult
= (*iEntry
)->maToken
;
345 MasterPageContainer::Token
MasterPageContainer::GetTokenForPageObject (
348 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
350 Token
aResult (NIL_TOKEN
);
351 if (pPage
!= nullptr)
353 MasterPageContainerType::iterator
iEntry (
355 mpImpl
->maContainer
.begin(),
356 mpImpl
->maContainer
.end(),
357 MasterPageDescriptor::PageObjectComparator(pPage
)));
358 if (iEntry
!= mpImpl
->maContainer
.end())
359 aResult
= (*iEntry
)->maToken
;
364 OUString
MasterPageContainer::GetURLForToken (
365 MasterPageContainer::Token aToken
)
367 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
369 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
370 if (pDescriptor
.get() != nullptr)
371 return pDescriptor
->msURL
;
376 OUString
MasterPageContainer::GetPageNameForToken (
377 MasterPageContainer::Token aToken
)
379 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
381 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
382 if (pDescriptor
.get() != nullptr)
383 return pDescriptor
->msPageName
;
388 OUString
MasterPageContainer::GetStyleNameForToken (
389 MasterPageContainer::Token aToken
)
391 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
393 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
394 if (pDescriptor
.get() != nullptr)
395 return pDescriptor
->msStyleName
;
400 SdPage
* MasterPageContainer::GetPageObjectForToken (
401 MasterPageContainer::Token aToken
,
404 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
406 SdPage
* pPageObject
= nullptr;
407 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
408 if (pDescriptor
.get() != nullptr)
410 pPageObject
= pDescriptor
->mpMasterPage
;
411 if (pPageObject
== nullptr)
413 // The page object is not (yet) present. Call
414 // UpdateDescriptor() to trigger the PageObjectProvider() to
418 if (mpImpl
->UpdateDescriptor(pDescriptor
,bLoad
,false, true))
419 pPageObject
= pDescriptor
->mpMasterPage
;
425 MasterPageContainer::Origin
MasterPageContainer::GetOriginForToken (Token aToken
)
427 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
429 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
430 if (pDescriptor
.get() != nullptr)
431 return pDescriptor
->meOrigin
;
436 sal_Int32
MasterPageContainer::GetTemplateIndexForToken (Token aToken
)
438 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
440 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
441 if (pDescriptor
.get() != nullptr)
442 return pDescriptor
->mnTemplateIndex
;
447 SharedMasterPageDescriptor
MasterPageContainer::GetDescriptorForToken (
448 MasterPageContainer::Token aToken
)
450 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
452 return mpImpl
->GetDescriptor(aToken
);
455 void MasterPageContainer::InvalidatePreview (MasterPageContainer::Token aToken
)
457 mpImpl
->InvalidatePreview(aToken
);
460 Image
MasterPageContainer::GetPreviewForToken (MasterPageContainer::Token aToken
)
462 return mpImpl
->GetPreviewForToken(aToken
,mePreviewSize
);
465 MasterPageContainer::PreviewState
MasterPageContainer::GetPreviewState (Token aToken
)
467 return mpImpl
->GetPreviewState(aToken
);
470 bool MasterPageContainer::RequestPreview (Token aToken
)
472 return mpImpl
->RequestPreview(aToken
);
475 //==== Implementation ================================================
477 MasterPageContainer::Implementation::Implementation()
480 meInitializationState(NOT_INITIALIZED
),
481 mpRequestQueue(nullptr),
485 mbFirstPageObjectSeen(false),
486 maLargePreviewBeingCreated(),
487 maSmallPreviewBeingCreated(),
488 maLargePreviewNotAvailable(),
489 maSmallPreviewNotAvailable(),
491 maSmallPreviewSizePixel(),
492 maLargePreviewSizePixel()
494 UpdatePreviewSizePixel();
497 MasterPageContainer::Implementation::~Implementation()
499 // When the initializer or filler tasks are still running then we have
500 // to stop them now in order to prevent them from calling us back.
501 tools::TimerBasedTaskExecution::ReleaseTask(mpFillerTask
);
503 mpRequestQueue
.reset();
505 uno::Reference
<util::XCloseable
> xCloseable (mxModel
, uno::UNO_QUERY
);
510 xCloseable
->close(true);
512 catch (const css::util::CloseVetoException
&)
519 void MasterPageContainer::Implementation::LateInit()
521 const ::osl::MutexGuard
aGuard (maMutex
);
523 if (meInitializationState
== NOT_INITIALIZED
)
525 meInitializationState
= INITIALIZING
;
527 OSL_ASSERT(Instance().get()==this);
528 mpRequestQueue
.reset(MasterPageContainerQueue::Create(
529 std::shared_ptr
<MasterPageContainerQueue::ContainerAdapter
>(Instance())));
531 mpFillerTask
= ::sd::tools::TimerBasedTaskExecution::Create(
532 std::shared_ptr
<tools::AsynchronousTask
>(new MasterPageContainerFiller(*this)),
536 meInitializationState
= INITIALIZED
;
540 void MasterPageContainer::Implementation::AddChangeListener (const Link
<MasterPageContainerChangeEvent
&,void>& rLink
)
542 const ::osl::MutexGuard
aGuard (maMutex
);
544 ::std::vector
<Link
<MasterPageContainerChangeEvent
&,void>>::iterator
iListener (
545 ::std::find(maChangeListeners
.begin(),maChangeListeners
.end(),rLink
));
546 if (iListener
== maChangeListeners
.end())
547 maChangeListeners
.push_back(rLink
);
551 void MasterPageContainer::Implementation::RemoveChangeListener (const Link
<MasterPageContainerChangeEvent
&,void>& rLink
)
553 const ::osl::MutexGuard
aGuard (maMutex
);
555 ::std::vector
<Link
<MasterPageContainerChangeEvent
&,void>>::iterator
iListener (
556 ::std::find(maChangeListeners
.begin(),maChangeListeners
.end(),rLink
));
557 if (iListener
!= maChangeListeners
.end())
558 maChangeListeners
.erase(iListener
);
561 void MasterPageContainer::Implementation::UpdatePreviewSizePixel()
563 const ::osl::MutexGuard
aGuard (maMutex
);
565 // The default aspect ratio is 4:3
569 // Search for the first entry with an existing master page.
570 MasterPageContainerType::const_iterator iDescriptor
;
571 MasterPageContainerType::const_iterator
iContainerEnd(maContainer
.end());
572 for (iDescriptor
=maContainer
.begin(); iDescriptor
!=iContainerEnd
; ++iDescriptor
)
573 if (*iDescriptor
!=nullptr && (*iDescriptor
)->mpMasterPage
!= nullptr)
575 Size
aPageSize ((*iDescriptor
)->mpMasterPage
->GetSize());
576 OSL_ASSERT(aPageSize
.Width() > 0 && aPageSize
.Height() > 0);
577 if (aPageSize
.Width() > 0)
578 nWidth
= aPageSize
.Width();
579 if (aPageSize
.Height() > 0)
580 nHeight
= aPageSize
.Height();
581 mbFirstPageObjectSeen
= true;
585 maSmallPreviewSizePixel
.setWidth( SMALL_PREVIEW_WIDTH
);
586 maLargePreviewSizePixel
.setWidth( LARGE_PREVIEW_WIDTH
);
588 int nNewSmallHeight ((maSmallPreviewSizePixel
.Width()-2) * nHeight
/ nWidth
+ 2);
589 int nNewLargeHeight ((maLargePreviewSizePixel
.Width()-2) * nHeight
/ nWidth
+ 2);
591 if (nNewSmallHeight
!=maSmallPreviewSizePixel
.Height()
592 || nNewLargeHeight
!=maLargePreviewSizePixel
.Height())
594 maSmallPreviewSizePixel
.setHeight( nNewSmallHeight
);
595 maLargePreviewSizePixel
.setHeight( nNewLargeHeight
);
597 MasterPageContainerChangeEvent::EventType::SIZE_CHANGED
,
602 const Size
& MasterPageContainer::Implementation::GetPreviewSizePixel (PreviewSize eSize
) const
605 return maSmallPreviewSizePixel
;
607 return maLargePreviewSizePixel
;
610 MasterPageContainer::Token
MasterPageContainer::Implementation::PutMasterPage (
611 const SharedMasterPageDescriptor
& rpDescriptor
)
613 const ::osl::MutexGuard
aGuard (maMutex
);
615 Token
aResult (NIL_TOKEN
);
617 // Get page object and preview when that is inexpensive.
618 UpdateDescriptor(rpDescriptor
,false,false, false);
620 // Look up the new MasterPageDescriptor and either insert it or update
621 // an already existing one.
622 MasterPageContainerType::iterator
aEntry (
626 MasterPageDescriptor::AllComparator(rpDescriptor
)));
627 if (aEntry
== maContainer
.end())
629 // Insert a new MasterPageDescriptor.
630 bool bIgnore (rpDescriptor
->mpPageObjectProvider
.get()==nullptr
631 && rpDescriptor
->msURL
.isEmpty());
637 aResult
= maContainer
.size();
638 rpDescriptor
->SetToken(aResult
);
640 // Templates are precious, i.e. we lock them so that they will
641 // not be destroyed when (temporarily) no one references them.
642 // They will only be deleted when the container is destroyed.
643 switch (rpDescriptor
->meOrigin
)
647 ++rpDescriptor
->mnUseCount
;
654 maContainer
.push_back(rpDescriptor
);
655 aEntry
= maContainer
.end()-1;
657 FireContainerChange(MasterPageContainerChangeEvent::EventType::CHILD_ADDED
,aResult
);
662 // Update an existing MasterPageDescriptor.
663 aResult
= (*aEntry
)->maToken
;
664 std::unique_ptr
<std::vector
<MasterPageContainerChangeEvent::EventType
> > pEventTypes(
665 (*aEntry
)->Update(*rpDescriptor
));
666 if (pEventTypes
.get()!=nullptr && pEventTypes
->size()>0)
668 // One or more aspects of the descriptor have changed. Send
669 // appropriate events to the listeners.
670 UpdateDescriptor(*aEntry
,false,false, true);
672 std::vector
<MasterPageContainerChangeEvent::EventType
>::const_iterator iEventType
;
673 for (iEventType
=pEventTypes
->begin(); iEventType
!=pEventTypes
->end(); ++iEventType
)
675 FireContainerChange( *iEventType
,(*aEntry
)->maToken
);
683 bool MasterPageContainer::Implementation::HasToken (Token aToken
) const
686 && static_cast<unsigned>(aToken
)<maContainer
.size()
687 && maContainer
[aToken
].get()!=nullptr;
690 const SharedMasterPageDescriptor
MasterPageContainer::Implementation::GetDescriptor (
693 if (aToken
>=0 && static_cast<unsigned>(aToken
)<maContainer
.size())
694 return maContainer
[aToken
];
696 return SharedMasterPageDescriptor();
699 SharedMasterPageDescriptor
MasterPageContainer::Implementation::GetDescriptor (Token aToken
)
701 if (aToken
>=0 && static_cast<unsigned>(aToken
)<maContainer
.size())
702 return maContainer
[aToken
];
704 return SharedMasterPageDescriptor();
707 void MasterPageContainer::Implementation::InvalidatePreview (Token aToken
)
709 const ::osl::MutexGuard
aGuard (maMutex
);
711 SharedMasterPageDescriptor
pDescriptor (GetDescriptor(aToken
));
712 if (pDescriptor
.get() != nullptr)
714 pDescriptor
->maSmallPreview
= Image();
715 pDescriptor
->maLargePreview
= Image();
716 RequestPreview(aToken
);
720 Image
MasterPageContainer::Implementation::GetPreviewForToken (
721 MasterPageContainer::Token aToken
,
722 PreviewSize ePreviewSize
)
724 const ::osl::MutexGuard
aGuard (maMutex
);
727 PreviewState
ePreviewState (GetPreviewState(aToken
));
729 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
731 // When the preview is missing but inexpensively creatable then do that
733 if (pDescriptor
.get()!=nullptr)
735 if (ePreviewState
== PS_CREATABLE
)
736 if (UpdateDescriptor(pDescriptor
, false,false, true))
737 if (pDescriptor
->maLargePreview
.GetSizePixel().Width() != 0)
738 ePreviewState
= PS_AVAILABLE
;
740 switch (ePreviewState
)
743 aPreview
= pDescriptor
->GetPreview(ePreviewSize
);
747 aPreview
= GetPreviewSubstitution(
748 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
,
753 aPreview
= GetPreviewSubstitution(
754 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
,
758 case PS_NOT_AVAILABLE
:
759 aPreview
= GetPreviewSubstitution(
760 STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
,
762 if (ePreviewSize
== SMALL
)
763 pDescriptor
->maSmallPreview
= aPreview
;
765 pDescriptor
->maLargePreview
= aPreview
;
773 MasterPageContainer::PreviewState
MasterPageContainer::Implementation::GetPreviewState (
776 const ::osl::MutexGuard
aGuard (maMutex
);
778 PreviewState
eState (PS_NOT_AVAILABLE
);
780 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
781 if (pDescriptor
.get() != nullptr)
783 if (pDescriptor
->maLargePreview
.GetSizePixel().Width() != 0)
784 eState
= PS_AVAILABLE
;
785 else if (pDescriptor
->mpPreviewProvider
.get() != nullptr)
787 // The preview does not exist but can be created. When that is
788 // not expensive then do it at once.
789 if (mpRequestQueue
->HasRequest(aToken
))
790 eState
= PS_PREPARING
;
792 eState
= PS_CREATABLE
;
795 eState
= PS_NOT_AVAILABLE
;
801 bool MasterPageContainer::Implementation::RequestPreview (Token aToken
)
803 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
804 if (pDescriptor
.get() != nullptr)
805 return mpRequestQueue
->RequestPreview(pDescriptor
);
810 Reference
<frame::XModel
> MasterPageContainer::Implementation::GetModel()
812 const ::osl::MutexGuard
aGuard (maMutex
);
816 // Get the desktop a s service factory.
817 uno::Reference
<frame::XDesktop2
> xDesktop
= frame::Desktop::create(
818 ::comphelper::getProcessComponentContext() );
820 // Create a new model.
822 ::comphelper::getProcessServiceFactory()->createInstance(
823 "com.sun.star.presentation.PresentationDocument"),
826 // Initialize the model.
827 uno::Reference
<frame::XLoadable
> xLoadable (mxModel
,uno::UNO_QUERY
);
829 xLoadable
->initNew();
831 // Use its tunnel to get a pointer to its core implementation.
832 uno::Reference
<lang::XUnoTunnel
> xUnoTunnel (mxModel
, uno::UNO_QUERY
);
835 mpDocument
= reinterpret_cast<SdXImpressDocument
*>(
836 xUnoTunnel
->getSomething(
837 SdXImpressDocument::getUnoTunnelId()))->GetDoc();
840 // Create a default page.
841 uno::Reference
<drawing::XDrawPagesSupplier
> xSlideSupplier (mxModel
, uno::UNO_QUERY
);
842 if (xSlideSupplier
.is())
844 uno::Reference
<drawing::XDrawPages
> xSlides (
845 xSlideSupplier
->getDrawPages(), uno::UNO_QUERY
);
848 uno::Reference
<drawing::XDrawPage
> xNewPage (xSlides
->insertNewByIndex(0));
849 uno::Reference
<beans::XPropertySet
> xProperties(xNewPage
, uno::UNO_QUERY
);
850 if (xProperties
.is())
851 xProperties
->setPropertyValue(
853 makeAny(sal_Int16(AUTOLAYOUT_TITLE
)));
860 SdDrawDocument
* MasterPageContainer::Implementation::GetDocument()
866 Image
MasterPageContainer::Implementation::GetPreviewSubstitution (
868 PreviewSize ePreviewSize
)
870 const ::osl::MutexGuard
aGuard (maMutex
);
874 if (strcmp(pId
, STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
) == 0)
876 Image
& rPreview (ePreviewSize
==SMALL
877 ? maSmallPreviewBeingCreated
878 : maLargePreviewBeingCreated
);
879 if (rPreview
.GetSizePixel().Width() == 0)
881 rPreview
= maPreviewRenderer
.RenderSubstitution(
882 ePreviewSize
==SMALL
? maSmallPreviewSizePixel
: maLargePreviewSizePixel
,
883 SdResId(STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
));
887 else if (strcmp(pId
, STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
) == 0)
889 Image
& rPreview (ePreviewSize
==SMALL
890 ? maSmallPreviewNotAvailable
891 : maLargePreviewNotAvailable
);
892 if (rPreview
.GetSizePixel().Width() == 0)
894 rPreview
= maPreviewRenderer
.RenderSubstitution(
895 ePreviewSize
==SMALL
? maSmallPreviewSizePixel
: maLargePreviewSizePixel
,
896 SdResId(STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
));
904 void MasterPageContainer::Implementation::CleanContainer()
906 // Remove the empty elements at the end of the container. The empty
907 // elements in the middle can not be removed because that would
908 // invalidate the references still held by others.
909 int nIndex (maContainer
.size()-1);
910 while (nIndex
>=0 && maContainer
[nIndex
].get()==nullptr)
912 maContainer
.resize(++nIndex
);
915 void MasterPageContainer::Implementation::FireContainerChange (
916 MasterPageContainerChangeEvent::EventType eType
,
919 ::std::vector
<Link
<MasterPageContainerChangeEvent
&,void>> aCopy(maChangeListeners
.begin(),maChangeListeners
.end());
920 ::std::vector
<Link
<MasterPageContainerChangeEvent
&,void>>::iterator iListener
;
921 MasterPageContainerChangeEvent aEvent
;
922 aEvent
.meEventType
= eType
;
923 aEvent
.maChildToken
= aToken
;
924 for (iListener
=aCopy
.begin(); iListener
!=aCopy
.end(); ++iListener
)
925 iListener
->Call(aEvent
);
928 bool MasterPageContainer::Implementation::UpdateDescriptor (
929 const SharedMasterPageDescriptor
& rpDescriptor
,
930 bool bForcePageObject
,
934 const ::osl::MutexGuard
aGuard (maMutex
);
936 // We have to create the page object when the preview provider needs it
937 // and the caller needs the preview.
938 bForcePageObject
|= (bForcePreview
939 && rpDescriptor
->mpPreviewProvider
->NeedsPageObject()
940 && rpDescriptor
->mpMasterPage
==nullptr);
942 // Define a cost threshold so that an update or page object or preview
943 // that is at least this cost are made at once. Updates with higher cost
944 // are scheduled for later.
945 sal_Int32
nCostThreshold (mpRequestQueue
->IsEmpty() ? 5 : 0);
947 // Update the page object (which may be used for the preview update).
948 if (bForcePageObject
)
950 int nPageObjectModified (rpDescriptor
->UpdatePageObject(
951 (bForcePageObject
? -1 : nCostThreshold
),
953 if (nPageObjectModified
== 1 && bSendEvents
)
955 MasterPageContainerChangeEvent::EventType::DATA_CHANGED
,
956 rpDescriptor
->maToken
);
957 if (nPageObjectModified
== -1 && bSendEvents
)
959 MasterPageContainerChangeEvent::EventType::CHILD_REMOVED
,
960 rpDescriptor
->maToken
);
961 if (nPageObjectModified
&& ! mbFirstPageObjectSeen
)
962 UpdatePreviewSizePixel();
964 // Update the preview.
965 bool bPreviewModified (rpDescriptor
->UpdatePreview(
966 (bForcePreview
? -1 : nCostThreshold
),
967 maSmallPreviewSizePixel
,
968 maLargePreviewSizePixel
,
971 if (bPreviewModified
&& bSendEvents
)
973 MasterPageContainerChangeEvent::EventType::PREVIEW_CHANGED
,
974 rpDescriptor
->maToken
);
976 return nPageObjectModified
|| bPreviewModified
;
979 void MasterPageContainer::Implementation::ReleaseDescriptor (Token aToken
)
981 if (aToken
>=0 && static_cast<unsigned>(aToken
)<maContainer
.size())
983 maContainer
[aToken
].reset();
987 void MasterPageContainer::Implementation::FillingDone()
989 mpRequestQueue
->ProcessAllRequests();
992 } } // end of namespace sd::sidebar
994 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */