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/frame/XComponentLoader.hpp>
36 #include <com/sun/star/io/XStream.hpp>
37 #include <com/sun/star/io/XInputStream.hpp>
38 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <com/sun/star/uno/Reference.hxx>
41 #include <com/sun/star/uno/Any.hxx>
42 #include <com/sun/star/uno/Sequence.hxx>
43 #include <com/sun/star/util/XCloseable.hpp>
44 #include <comphelper/processfactory.hxx>
45 #include <sfx2/app.hxx>
46 #include <svx/svdpage.hxx>
47 #include "DrawDocShell.hxx"
48 #include "drawdoc.hxx"
50 #include <svl/itemset.hxx>
51 #include <svl/eitem.hxx>
52 #include "sdresid.hxx"
53 #include "tools/TimerBasedTaskExecution.hxx"
55 #include <osl/mutex.hxx>
56 #include <osl/getglobalmutex.hxx>
57 #include <boost/scoped_ptr.hpp>
58 #include <boost/weak_ptr.hpp>
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::uno
;
65 typedef ::std::vector
<sd::sidebar::SharedMasterPageDescriptor
> MasterPageContainerType
;
67 } // end of anonymous namespace
69 namespace sd
{ namespace sidebar
{
71 /** Inner implementation class of the MasterPageContainer.
73 class MasterPageContainer::Implementation
74 : public SdGlobalResource
,
75 public MasterPageContainerFiller::ContainerAdapter
,
76 public MasterPageContainerQueue::ContainerAdapter
79 mutable ::osl::Mutex maMutex
;
81 static ::boost::weak_ptr
<Implementation
> mpInstance
;
82 MasterPageContainerType maContainer
;
84 static ::boost::shared_ptr
<Implementation
> Instance();
87 void AddChangeListener (const Link
<>& rLink
);
88 void RemoveChangeListener (const Link
<>& rLink
);
89 void UpdatePreviewSizePixel();
90 Size
GetPreviewSizePixel (PreviewSize eSize
) const;
92 bool HasToken (Token aToken
) const;
93 const SharedMasterPageDescriptor
GetDescriptor (MasterPageContainer::Token aToken
) const;
94 SharedMasterPageDescriptor
GetDescriptor (MasterPageContainer::Token aToken
);
95 virtual Token
PutMasterPage (const SharedMasterPageDescriptor
& rDescriptor
) SAL_OVERRIDE
;
96 void InvalidatePreview (Token aToken
);
97 Image
GetPreviewForToken (
99 PreviewSize ePreviewSize
);
100 PreviewState
GetPreviewState (Token aToken
) const;
101 bool RequestPreview (Token aToken
);
103 Reference
<frame::XModel
> GetModel();
104 SdDrawDocument
* GetDocument();
106 void FireContainerChange (
107 MasterPageContainerChangeEvent::EventType eType
,
109 bool bNotifyAsynchronously
= false);
111 virtual bool UpdateDescriptor (
112 const SharedMasterPageDescriptor
& rpDescriptor
,
113 bool bForcePageObject
,
115 bool bSendEvents
) SAL_OVERRIDE
;
117 void ReleaseDescriptor (Token aToken
);
119 /** Called by the MasterPageContainerFiller to notify that all master
120 pages from template documents have been added.
122 virtual void FillingDone() SAL_OVERRIDE
;
126 virtual ~Implementation();
128 class Deleter
{ public:
129 void operator() (Implementation
* pObject
) { delete pObject
; }
131 friend class Deleter
;
133 enum InitializationState
{ NOT_INITIALIZED
, INITIALIZING
, INITIALIZED
} meInitializationState
;
135 ::boost::scoped_ptr
<MasterPageContainerQueue
> mpRequestQueue
;
136 ::com::sun::star::uno::Reference
<com::sun::star::frame::XModel
> mxModel
;
137 SdDrawDocument
* mpDocument
;
138 PreviewRenderer maPreviewRenderer
;
139 /** Remember whether the first page object has already been used to
140 determine the correct size ratio.
142 bool mbFirstPageObjectSeen
;
144 // The widths for the previews contain two pixels for the border that is
145 // painted around the preview.
146 static const int SMALL_PREVIEW_WIDTH
= 72 + 2;
147 static const int LARGE_PREVIEW_WIDTH
= 2*72 + 2;
149 /** This substition of page preview shows "Preparing preview" and is
150 shown as long as the actual previews are not being present.
152 Image maLargePreviewBeingCreated
;
153 Image maSmallPreviewBeingCreated
;
155 /** This substition of page preview is shown when a preview can not be
156 created and thus is not available.
158 Image maLargePreviewNotAvailable
;
159 Image maSmallPreviewNotAvailable
;
161 ::std::vector
<Link
<>> maChangeListeners
;
163 // We have to remember the tasks for initialization and filling in case
164 // a MasterPageContainer object is destroyed before these tasks have
166 ::boost::weak_ptr
<sd::tools::TimerBasedTaskExecution
> mpFillerTask
;
168 Size maSmallPreviewSizePixel
;
169 Size maLargePreviewSizePixel
;
171 bool mbContainerCleaningPending
;
173 typedef ::std::pair
<MasterPageContainerChangeEvent::EventType
,Token
> EventData
;
174 DECL_LINK(AsynchronousNotifyCallback
, EventData
*);
176 Image
GetPreviewSubstitution (sal_uInt16 nId
, PreviewSize ePreviewSize
);
178 void CleanContainer();
181 //===== MasterPageContainer ===================================================
183 ::boost::weak_ptr
<MasterPageContainer::Implementation
>
184 MasterPageContainer::Implementation::mpInstance
;
186 ::boost::shared_ptr
<MasterPageContainer::Implementation
>
187 MasterPageContainer::Implementation::Instance()
189 ::boost::shared_ptr
<MasterPageContainer::Implementation
> pInstance
;
191 if (Implementation::mpInstance
.expired())
193 ::osl::GetGlobalMutex aMutexFunctor
;
194 ::osl::MutexGuard
aGuard (aMutexFunctor());
195 if (Implementation::mpInstance
.expired())
197 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
198 pInstance
= ::boost::shared_ptr
<MasterPageContainer::Implementation
>(
199 new MasterPageContainer::Implementation(),
200 MasterPageContainer::Implementation::Deleter());
201 SdGlobalResourceContainer::Instance().AddResource(pInstance
);
202 Implementation::mpInstance
= pInstance
;
205 pInstance
= ::boost::shared_ptr
<MasterPageContainer::Implementation
>(
206 Implementation::mpInstance
);
210 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
211 pInstance
= ::boost::shared_ptr
<MasterPageContainer::Implementation
>(
212 Implementation::mpInstance
);
215 DBG_ASSERT (pInstance
.get()!=NULL
,
216 "MasterPageContainer::Implementation::Instance(): instance is NULL");
220 MasterPageContainer::MasterPageContainer()
221 : mpImpl(Implementation::Instance()),
227 MasterPageContainer::~MasterPageContainer()
231 void MasterPageContainer::AddChangeListener (const Link
<>& rLink
)
233 mpImpl
->AddChangeListener(rLink
);
236 void MasterPageContainer::RemoveChangeListener (const Link
<>& rLink
)
238 mpImpl
->RemoveChangeListener(rLink
);
241 void MasterPageContainer::SetPreviewSize (PreviewSize eSize
)
243 mePreviewSize
= eSize
;
244 mpImpl
->FireContainerChange(
245 MasterPageContainerChangeEvent::SIZE_CHANGED
,
249 Size
MasterPageContainer::GetPreviewSizePixel() const
251 return mpImpl
->GetPreviewSizePixel(mePreviewSize
);
254 MasterPageContainer::Token
MasterPageContainer::PutMasterPage (
255 const SharedMasterPageDescriptor
& rDescriptor
)
257 return mpImpl
->PutMasterPage(rDescriptor
);
260 void MasterPageContainer::AcquireToken (Token aToken
)
262 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
263 if (pDescriptor
.get() != NULL
)
265 ++pDescriptor
->mnUseCount
;
269 void MasterPageContainer::ReleaseToken (Token aToken
)
271 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
272 if (pDescriptor
.get() != NULL
)
274 OSL_ASSERT(pDescriptor
->mnUseCount
>0);
275 --pDescriptor
->mnUseCount
;
276 if (pDescriptor
->mnUseCount
<= 0)
278 switch (pDescriptor
->meOrigin
)
286 mpImpl
->ReleaseDescriptor(aToken
);
293 int MasterPageContainer::GetTokenCount() const
295 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
297 return mpImpl
->maContainer
.size();
300 bool MasterPageContainer::HasToken (Token aToken
) const
302 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
304 return mpImpl
->HasToken(aToken
);
307 MasterPageContainer::Token
MasterPageContainer::GetTokenForIndex (int nIndex
)
309 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
311 Token
aResult (NIL_TOKEN
);
312 if (HasToken(nIndex
))
313 aResult
= mpImpl
->maContainer
[nIndex
]->maToken
;
317 MasterPageContainer::Token
MasterPageContainer::GetTokenForURL (
318 const OUString
& sURL
)
320 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
322 Token
aResult (NIL_TOKEN
);
325 MasterPageContainerType::iterator
iEntry (
327 mpImpl
->maContainer
.begin(),
328 mpImpl
->maContainer
.end(),
329 MasterPageDescriptor::URLComparator(sURL
)));
330 if (iEntry
!= mpImpl
->maContainer
.end())
331 aResult
= (*iEntry
)->maToken
;
336 MasterPageContainer::Token
MasterPageContainer::GetTokenForStyleName (const OUString
& sStyleName
)
338 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
340 Token
aResult (NIL_TOKEN
);
341 if (!sStyleName
.isEmpty())
343 MasterPageContainerType::iterator
iEntry (
345 mpImpl
->maContainer
.begin(),
346 mpImpl
->maContainer
.end(),
347 MasterPageDescriptor::StyleNameComparator(sStyleName
)));
348 if (iEntry
!= mpImpl
->maContainer
.end())
349 aResult
= (*iEntry
)->maToken
;
354 MasterPageContainer::Token
MasterPageContainer::GetTokenForPageObject (
357 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
359 Token
aResult (NIL_TOKEN
);
362 MasterPageContainerType::iterator
iEntry (
364 mpImpl
->maContainer
.begin(),
365 mpImpl
->maContainer
.end(),
366 MasterPageDescriptor::PageObjectComparator(pPage
)));
367 if (iEntry
!= mpImpl
->maContainer
.end())
368 aResult
= (*iEntry
)->maToken
;
373 OUString
MasterPageContainer::GetURLForToken (
374 MasterPageContainer::Token aToken
)
376 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
378 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
379 if (pDescriptor
.get() != NULL
)
380 return pDescriptor
->msURL
;
385 OUString
MasterPageContainer::GetPageNameForToken (
386 MasterPageContainer::Token aToken
)
388 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
390 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
391 if (pDescriptor
.get() != NULL
)
392 return pDescriptor
->msPageName
;
397 OUString
MasterPageContainer::GetStyleNameForToken (
398 MasterPageContainer::Token aToken
)
400 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
402 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
403 if (pDescriptor
.get() != NULL
)
404 return pDescriptor
->msStyleName
;
409 SdPage
* MasterPageContainer::GetPageObjectForToken (
410 MasterPageContainer::Token aToken
,
413 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
415 SdPage
* pPageObject
= NULL
;
416 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
417 if (pDescriptor
.get() != NULL
)
419 pPageObject
= pDescriptor
->mpMasterPage
;
420 if (pPageObject
== NULL
)
422 // The page object is not (yet) present. Call
423 // UpdateDescriptor() to trigger the PageObjectProvider() to
427 if (mpImpl
->UpdateDescriptor(pDescriptor
,bLoad
,false, true))
428 pPageObject
= pDescriptor
->mpMasterPage
;
434 MasterPageContainer::Origin
MasterPageContainer::GetOriginForToken (Token aToken
)
436 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
438 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
439 if (pDescriptor
.get() != NULL
)
440 return pDescriptor
->meOrigin
;
445 sal_Int32
MasterPageContainer::GetTemplateIndexForToken (Token aToken
)
447 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
449 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
450 if (pDescriptor
.get() != NULL
)
451 return pDescriptor
->mnTemplateIndex
;
456 SharedMasterPageDescriptor
MasterPageContainer::GetDescriptorForToken (
457 MasterPageContainer::Token aToken
)
459 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
461 return mpImpl
->GetDescriptor(aToken
);
464 void MasterPageContainer::InvalidatePreview (MasterPageContainer::Token aToken
)
466 mpImpl
->InvalidatePreview(aToken
);
469 Image
MasterPageContainer::GetPreviewForToken (MasterPageContainer::Token aToken
)
471 return mpImpl
->GetPreviewForToken(aToken
,mePreviewSize
);
474 MasterPageContainer::PreviewState
MasterPageContainer::GetPreviewState (Token aToken
)
476 return mpImpl
->GetPreviewState(aToken
);
479 bool MasterPageContainer::RequestPreview (Token aToken
)
481 return mpImpl
->RequestPreview(aToken
);
484 //==== Implementation ================================================
486 MasterPageContainer::Implementation::Implementation()
489 meInitializationState(NOT_INITIALIZED
),
490 mpRequestQueue(NULL
),
494 mbFirstPageObjectSeen(false),
495 maLargePreviewBeingCreated(),
496 maSmallPreviewBeingCreated(),
497 maLargePreviewNotAvailable(),
498 maSmallPreviewNotAvailable(),
500 maSmallPreviewSizePixel(),
501 maLargePreviewSizePixel(),
502 mbContainerCleaningPending(true)
505 UpdatePreviewSizePixel();
508 MasterPageContainer::Implementation::~Implementation()
510 // When the initializer or filler tasks are still running then we have
511 // to stop them now in order to prevent them from calling us back.
512 tools::TimerBasedTaskExecution::ReleaseTask(mpFillerTask
);
514 mpRequestQueue
.reset();
516 uno::Reference
<util::XCloseable
> xCloseable (mxModel
, uno::UNO_QUERY
);
521 xCloseable
->close(true);
523 catch (const ::com::sun::star::util::CloseVetoException
&)
530 void MasterPageContainer::Implementation::LateInit()
532 const ::osl::MutexGuard
aGuard (maMutex
);
534 if (meInitializationState
== NOT_INITIALIZED
)
536 meInitializationState
= INITIALIZING
;
538 OSL_ASSERT(Instance().get()==this);
539 mpRequestQueue
.reset(MasterPageContainerQueue::Create(
540 ::boost::shared_ptr
<MasterPageContainerQueue::ContainerAdapter
>(Instance())));
542 mpFillerTask
= ::sd::tools::TimerBasedTaskExecution::Create(
543 ::boost::shared_ptr
<tools::AsynchronousTask
>(new MasterPageContainerFiller(*this)),
547 meInitializationState
= INITIALIZED
;
551 void MasterPageContainer::Implementation::AddChangeListener (const Link
<>& rLink
)
553 const ::osl::MutexGuard
aGuard (maMutex
);
555 ::std::vector
<Link
<>>::iterator
iListener (
556 ::std::find(maChangeListeners
.begin(),maChangeListeners
.end(),rLink
));
557 if (iListener
== maChangeListeners
.end())
558 maChangeListeners
.push_back(rLink
);
562 void MasterPageContainer::Implementation::RemoveChangeListener (const Link
<>& rLink
)
564 const ::osl::MutexGuard
aGuard (maMutex
);
566 ::std::vector
<Link
<>>::iterator
iListener (
567 ::std::find(maChangeListeners
.begin(),maChangeListeners
.end(),rLink
));
568 if (iListener
!= maChangeListeners
.end())
569 maChangeListeners
.erase(iListener
);
572 void MasterPageContainer::Implementation::UpdatePreviewSizePixel()
574 const ::osl::MutexGuard
aGuard (maMutex
);
576 // The default aspect ratio is 4:3
580 // Search for the first entry with an existing master page.
581 MasterPageContainerType::const_iterator iDescriptor
;
582 MasterPageContainerType::const_iterator
iContainerEnd(maContainer
.end());
583 for (iDescriptor
=maContainer
.begin(); iDescriptor
!=iContainerEnd
; ++iDescriptor
)
584 if (*iDescriptor
!=0 && (*iDescriptor
)->mpMasterPage
!= NULL
)
586 Size
aPageSize ((*iDescriptor
)->mpMasterPage
->GetSize());
587 OSL_ASSERT(aPageSize
.Width() > 0 && aPageSize
.Height() > 0);
588 if (aPageSize
.Width() > 0)
589 nWidth
= aPageSize
.Width();
590 if (aPageSize
.Height() > 0)
591 nHeight
= aPageSize
.Height();
592 mbFirstPageObjectSeen
= true;
596 maSmallPreviewSizePixel
.Width() = SMALL_PREVIEW_WIDTH
;
597 maLargePreviewSizePixel
.Width() = LARGE_PREVIEW_WIDTH
;
599 int nNewSmallHeight ((maSmallPreviewSizePixel
.Width()-2) * nHeight
/ nWidth
+ 2);
600 int nNewLargeHeight ((maLargePreviewSizePixel
.Width()-2) * nHeight
/ nWidth
+ 2);
602 if (nNewSmallHeight
!=maSmallPreviewSizePixel
.Height()
603 || nNewLargeHeight
!=maLargePreviewSizePixel
.Height())
605 maSmallPreviewSizePixel
.Height() = nNewSmallHeight
;
606 maLargePreviewSizePixel
.Height() = nNewLargeHeight
;
608 MasterPageContainerChangeEvent::SIZE_CHANGED
,
613 Size
MasterPageContainer::Implementation::GetPreviewSizePixel (PreviewSize eSize
) const
616 return maSmallPreviewSizePixel
;
618 return maLargePreviewSizePixel
;
621 IMPL_LINK(MasterPageContainer::Implementation
,AsynchronousNotifyCallback
, EventData
*, pData
)
623 const ::osl::MutexGuard
aGuard (maMutex
);
627 FireContainerChange(pData
->first
, pData
->second
, false);
634 MasterPageContainer::Token
MasterPageContainer::Implementation::PutMasterPage (
635 const SharedMasterPageDescriptor
& rpDescriptor
)
637 const ::osl::MutexGuard
aGuard (maMutex
);
639 Token
aResult (NIL_TOKEN
);
641 // Get page object and preview when that is inexpensive.
642 UpdateDescriptor(rpDescriptor
,false,false, false);
644 // Look up the new MasterPageDescriptor and either insert it or update
645 // an already existing one.
646 MasterPageContainerType::iterator
aEntry (
650 MasterPageDescriptor::AllComparator(rpDescriptor
)));
651 if (aEntry
== maContainer
.end())
653 // Insert a new MasterPageDescriptor.
654 bool bIgnore (rpDescriptor
->mpPageObjectProvider
.get()==NULL
655 && rpDescriptor
->msURL
.isEmpty());
659 if (mbContainerCleaningPending
)
662 aResult
= maContainer
.size();
663 rpDescriptor
->SetToken(aResult
);
665 // Templates are precious, i.e. we lock them so that they will
666 // not be destroyed when (temporarily) no one references them.
667 // They will only be deleted when the container is destroyed.
668 switch (rpDescriptor
->meOrigin
)
672 ++rpDescriptor
->mnUseCount
;
679 maContainer
.push_back(rpDescriptor
);
680 aEntry
= maContainer
.end()-1;
682 FireContainerChange(MasterPageContainerChangeEvent::CHILD_ADDED
,aResult
);
687 // Update an existing MasterPageDescriptor.
688 aResult
= (*aEntry
)->maToken
;
689 std::unique_ptr
<std::vector
<MasterPageContainerChangeEvent::EventType
> > pEventTypes(
690 (*aEntry
)->Update(*rpDescriptor
));
691 if (pEventTypes
.get()!=NULL
&& pEventTypes
->size()>0)
693 // One or more aspects of the descriptor have changed. Send
694 // appropriate events to the listeners.
695 UpdateDescriptor(*aEntry
,false,false, true);
697 std::vector
<MasterPageContainerChangeEvent::EventType
>::const_iterator iEventType
;
698 for (iEventType
=pEventTypes
->begin(); iEventType
!=pEventTypes
->end(); ++iEventType
)
711 bool MasterPageContainer::Implementation::HasToken (Token aToken
) const
714 && (unsigned)aToken
<maContainer
.size()
715 && maContainer
[aToken
].get()!=NULL
;
718 const SharedMasterPageDescriptor
MasterPageContainer::Implementation::GetDescriptor (
721 if (aToken
>=0 && (unsigned)aToken
<maContainer
.size())
722 return maContainer
[aToken
];
724 return SharedMasterPageDescriptor();
727 SharedMasterPageDescriptor
MasterPageContainer::Implementation::GetDescriptor (Token aToken
)
729 if (aToken
>=0 && (unsigned)aToken
<maContainer
.size())
730 return maContainer
[aToken
];
732 return SharedMasterPageDescriptor();
735 void MasterPageContainer::Implementation::InvalidatePreview (Token aToken
)
737 const ::osl::MutexGuard
aGuard (maMutex
);
739 SharedMasterPageDescriptor
pDescriptor (GetDescriptor(aToken
));
740 if (pDescriptor
.get() != NULL
)
742 pDescriptor
->maSmallPreview
= Image();
743 pDescriptor
->maLargePreview
= Image();
744 RequestPreview(aToken
);
748 Image
MasterPageContainer::Implementation::GetPreviewForToken (
749 MasterPageContainer::Token aToken
,
750 PreviewSize ePreviewSize
)
752 const ::osl::MutexGuard
aGuard (maMutex
);
755 PreviewState
ePreviewState (GetPreviewState(aToken
));
757 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
759 // When the preview is missing but inexpensively creatable then do that
761 if (pDescriptor
.get()!=NULL
)
763 if (ePreviewState
== PS_CREATABLE
)
764 if (UpdateDescriptor(pDescriptor
, false,false, true))
765 if (pDescriptor
->maLargePreview
.GetSizePixel().Width() != 0)
766 ePreviewState
= PS_AVAILABLE
;
768 switch (ePreviewState
)
771 aPreview
= pDescriptor
->GetPreview(ePreviewSize
);
775 aPreview
= GetPreviewSubstitution(
776 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
,
781 aPreview
= GetPreviewSubstitution(
782 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
,
786 case PS_NOT_AVAILABLE
:
787 aPreview
= GetPreviewSubstitution(
788 STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
,
790 if (ePreviewSize
== SMALL
)
791 pDescriptor
->maSmallPreview
= aPreview
;
793 pDescriptor
->maLargePreview
= aPreview
;
801 MasterPageContainer::PreviewState
MasterPageContainer::Implementation::GetPreviewState (
804 const ::osl::MutexGuard
aGuard (maMutex
);
806 PreviewState
eState (PS_NOT_AVAILABLE
);
808 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
809 if (pDescriptor
.get() != NULL
)
811 if (pDescriptor
->maLargePreview
.GetSizePixel().Width() != 0)
812 eState
= PS_AVAILABLE
;
813 else if (pDescriptor
->mpPreviewProvider
.get() != NULL
)
815 // The preview does not exist but can be created. When that is
816 // not expensive then do it at once.
817 if (mpRequestQueue
->HasRequest(aToken
))
818 eState
= PS_PREPARING
;
820 eState
= PS_CREATABLE
;
823 eState
= PS_NOT_AVAILABLE
;
829 bool MasterPageContainer::Implementation::RequestPreview (Token aToken
)
831 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
832 if (pDescriptor
.get() != NULL
)
833 return mpRequestQueue
->RequestPreview(pDescriptor
);
838 Reference
<frame::XModel
> MasterPageContainer::Implementation::GetModel()
840 const ::osl::MutexGuard
aGuard (maMutex
);
844 // Get the desktop a s service factory.
845 uno::Reference
<frame::XDesktop2
> xDesktop
= frame::Desktop::create(
846 ::comphelper::getProcessComponentContext() );
848 // Create a new model.
849 OUString
sModelServiceName ( "com.sun.star.presentation.PresentationDocument");
850 mxModel
= uno::Reference
<frame::XModel
>(
851 ::comphelper::getProcessServiceFactory()->createInstance(
855 // Initialize the model.
856 uno::Reference
<frame::XLoadable
> xLoadable (mxModel
,uno::UNO_QUERY
);
858 xLoadable
->initNew();
860 // Use its tunnel to get a pointer to its core implementation.
861 uno::Reference
<lang::XUnoTunnel
> xUnoTunnel (mxModel
, uno::UNO_QUERY
);
864 mpDocument
= reinterpret_cast<SdXImpressDocument
*>(
865 xUnoTunnel
->getSomething(
866 SdXImpressDocument::getUnoTunnelId()))->GetDoc();
869 // Create a default page.
870 uno::Reference
<drawing::XDrawPagesSupplier
> xSlideSupplier (mxModel
, uno::UNO_QUERY
);
871 if (xSlideSupplier
.is())
873 uno::Reference
<drawing::XDrawPages
> xSlides (
874 xSlideSupplier
->getDrawPages(), uno::UNO_QUERY
);
877 sal_Int32
nIndex (0);
878 uno::Reference
<drawing::XDrawPage
> xNewPage (xSlides
->insertNewByIndex(nIndex
));
879 uno::Reference
<beans::XPropertySet
> xProperties(xNewPage
, uno::UNO_QUERY
);
880 if (xProperties
.is())
881 xProperties
->setPropertyValue(
883 makeAny((sal_Int16
)AUTOLAYOUT_TITLE
));
890 SdDrawDocument
* MasterPageContainer::Implementation::GetDocument()
896 Image
MasterPageContainer::Implementation::GetPreviewSubstitution (
898 PreviewSize ePreviewSize
)
900 const ::osl::MutexGuard
aGuard (maMutex
);
906 case STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
:
908 Image
& rPreview (ePreviewSize
==SMALL
909 ? maSmallPreviewBeingCreated
910 : maLargePreviewBeingCreated
);
911 if (rPreview
.GetSizePixel().Width() == 0)
913 rPreview
= maPreviewRenderer
.RenderSubstitution(
914 ePreviewSize
==SMALL
? maSmallPreviewSizePixel
: maLargePreviewSizePixel
,
915 SdResId(STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
));
921 case STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
:
923 Image
& rPreview (ePreviewSize
==SMALL
924 ? maSmallPreviewNotAvailable
925 : maLargePreviewNotAvailable
);
926 if (rPreview
.GetSizePixel().Width() == 0)
928 rPreview
= maPreviewRenderer
.RenderSubstitution(
929 ePreviewSize
==SMALL
? maSmallPreviewSizePixel
: maLargePreviewSizePixel
,
930 SdResId(STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
));
940 void MasterPageContainer::Implementation::CleanContainer()
942 // Remove the empty elements at the end of the container. The empty
943 // elements in the middle can not be removed because that would
944 // invalidate the references still held by others.
945 int nIndex (maContainer
.size()-1);
946 while (nIndex
>=0 && maContainer
[nIndex
].get()==NULL
)
948 maContainer
.resize(++nIndex
);
951 void MasterPageContainer::Implementation::FireContainerChange (
952 MasterPageContainerChangeEvent::EventType eType
,
954 bool bNotifyAsynchronously
)
956 if (bNotifyAsynchronously
)
958 Application::PostUserEvent(
959 LINK(this,Implementation
,AsynchronousNotifyCallback
),
960 new EventData(eType
,aToken
));
964 ::std::vector
<Link
<>> aCopy(maChangeListeners
.begin(),maChangeListeners
.end());
965 ::std::vector
<Link
<>>::iterator iListener
;
966 MasterPageContainerChangeEvent aEvent
;
967 aEvent
.meEventType
= eType
;
968 aEvent
.maChildToken
= aToken
;
969 for (iListener
=aCopy
.begin(); iListener
!=aCopy
.end(); ++iListener
)
970 iListener
->Call(&aEvent
);
974 bool MasterPageContainer::Implementation::UpdateDescriptor (
975 const SharedMasterPageDescriptor
& rpDescriptor
,
976 bool bForcePageObject
,
980 const ::osl::MutexGuard
aGuard (maMutex
);
982 // We have to create the page object when the preview provider needs it
983 // and the caller needs the preview.
984 bForcePageObject
|= (bForcePreview
985 && rpDescriptor
->mpPreviewProvider
->NeedsPageObject()
986 && rpDescriptor
->mpMasterPage
==NULL
);
988 // Define a cost threshold so that an update or page object or preview
989 // that is at least this cost are made at once. Updates with higher cost
990 // are scheduled for later.
991 sal_Int32
nCostThreshold (mpRequestQueue
->IsEmpty() ? 5 : 0);
993 // Update the page object (which may be used for the preview update).
994 if (bForcePageObject
)
996 int nPageObjectModified (rpDescriptor
->UpdatePageObject(
997 (bForcePageObject
? -1 : nCostThreshold
),
999 if (nPageObjectModified
== 1 && bSendEvents
)
1000 FireContainerChange(
1001 MasterPageContainerChangeEvent::DATA_CHANGED
,
1002 rpDescriptor
->maToken
);
1003 if (nPageObjectModified
== -1 && bSendEvents
)
1004 FireContainerChange(
1005 MasterPageContainerChangeEvent::CHILD_REMOVED
,
1006 rpDescriptor
->maToken
);
1007 if (nPageObjectModified
&& ! mbFirstPageObjectSeen
)
1008 UpdatePreviewSizePixel();
1010 // Update the preview.
1011 bool bPreviewModified (rpDescriptor
->UpdatePreview(
1012 (bForcePreview
? -1 : nCostThreshold
),
1013 maSmallPreviewSizePixel
,
1014 maLargePreviewSizePixel
,
1015 maPreviewRenderer
));
1017 if (bPreviewModified
&& bSendEvents
)
1018 FireContainerChange(
1019 MasterPageContainerChangeEvent::PREVIEW_CHANGED
,
1020 rpDescriptor
->maToken
);
1022 return nPageObjectModified
|| bPreviewModified
;
1025 void MasterPageContainer::Implementation::ReleaseDescriptor (Token aToken
)
1027 if (aToken
>=0 && (unsigned)aToken
<maContainer
.size())
1029 maContainer
[aToken
].reset();
1030 mbContainerCleaningPending
= true;
1034 void MasterPageContainer::Implementation::FillingDone()
1036 mpRequestQueue
->ProcessAllRequests();
1039 } } // end of namespace sd::sidebar
1041 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */