1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MasterPageContainer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include "MasterPageContainer.hxx"
36 #include "MasterPageDescriptor.hxx"
37 #include "MasterPageContainerFiller.hxx"
38 #include "MasterPageContainerQueue.hxx"
39 #include "TemplateScanner.hxx"
40 #include "tools/AsynchronousTask.hxx"
41 #include "strings.hrc"
46 #include "unomodel.hxx"
47 #include <com/sun/star/frame/XComponentLoader.hpp>
48 #include <com/sun/star/io/XStream.hpp>
49 #include <com/sun/star/io/XInputStream.hpp>
50 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
51 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
52 #include <com/sun/star/uno/Reference.hxx>
53 #include <com/sun/star/uno/Any.hxx>
54 #include <com/sun/star/uno/Sequence.hxx>
55 #include <com/sun/star/util/XCloseable.hpp>
56 #include <comphelper/processfactory.hxx>
57 #include <tools/urlobj.hxx>
58 #include <sfx2/app.hxx>
59 #include <svx/svdpage.hxx>
60 #include "DrawDocShell.hxx"
61 #include "drawdoc.hxx"
63 #include <svtools/itemset.hxx>
64 #include <svtools/eitem.hxx>
65 #include "sdresid.hxx"
66 #include "tools/TimerBasedTaskExecution.hxx"
68 #include <osl/mutex.hxx>
69 #include <boost/weak_ptr.hpp>
71 using namespace ::com::sun::star
;
72 using namespace ::com::sun::star::uno
;
73 using namespace ::sd::toolpanel::controls
;
77 typedef ::std::vector
<SharedMasterPageDescriptor
> MasterPageContainerType
;
80 class PreviewCreationRequest
83 PreviewCreationRequest (MasterPageContainer::Token aToken
, int nPriority
);
84 MasterPageContainer::Token maToken
;
86 class Compare
{public:
87 bool operator() (const PreviewCreationRequest
& r1
,const PreviewCreationRequest
& r2
);
89 class CompareToken
{public:
90 MasterPageContainer::Token maToken
;
91 CompareToken(MasterPageContainer::Token aToken
);
92 bool operator() (const PreviewCreationRequest
& rRequest
);
97 } // end of anonymous namespace
100 namespace sd
{ namespace toolpanel
{ namespace controls
{
103 /** Inner implementation class of the MasterPageContainer.
105 class MasterPageContainer::Implementation
106 : public SdGlobalResource
,
107 public MasterPageContainerFiller::ContainerAdapter
,
108 public MasterPageContainerQueue::ContainerAdapter
111 mutable ::osl::Mutex maMutex
;
113 static ::boost::weak_ptr
<Implementation
> mpInstance
;
114 MasterPageContainerType maContainer
;
116 static ::boost::shared_ptr
<Implementation
> Instance (void);
118 void LateInit (void);
119 void AddChangeListener (const Link
& rLink
);
120 void RemoveChangeListener (const Link
& rLink
);
121 void UpdatePreviewSizePixel (void);
122 Size
GetPreviewSizePixel (PreviewSize eSize
) const;
124 bool HasToken (Token aToken
) const;
125 const SharedMasterPageDescriptor
GetDescriptor (MasterPageContainer::Token aToken
) const;
126 SharedMasterPageDescriptor
GetDescriptor (MasterPageContainer::Token aToken
);
127 virtual Token
PutMasterPage (const SharedMasterPageDescriptor
& rDescriptor
);
128 void InvalidatePreview (Token aToken
);
129 Image
GetPreviewForToken (
131 PreviewSize ePreviewSize
);
132 PreviewState
GetPreviewState (Token aToken
) const;
133 bool RequestPreview (Token aToken
);
135 Reference
<frame::XModel
> GetModel (void);
136 SdDrawDocument
* GetDocument (void);
138 void FireContainerChange (
139 MasterPageContainerChangeEvent::EventType eType
,
141 bool bNotifyAsynchronously
= false);
143 virtual bool UpdateDescriptor (
144 const SharedMasterPageDescriptor
& rpDescriptor
,
145 bool bForcePageObject
,
149 void ReleaseDescriptor (Token aToken
);
151 /** Called by the MasterPageContainerFiller to notify that all master
152 pages from template documents have been added.
154 virtual void FillingDone (void);
157 Implementation (void);
158 virtual ~Implementation (void);
160 class Deleter
{ public:
161 void operator() (Implementation
* pObject
) { delete pObject
; }
163 friend class Deleter
;
165 enum InitializationState
{ NOT_INITIALIZED
, INITIALIZING
, INITIALIZED
} meInitializationState
;
167 ::boost::scoped_ptr
<MasterPageContainerQueue
> mpRequestQueue
;
168 ::com::sun::star::uno::Reference
<com::sun::star::frame::XModel
> mxModel
;
169 SdDrawDocument
* mpDocument
;
170 PreviewRenderer maPreviewRenderer
;
171 /** Remember whether the first page object has already been used to
172 determine the correct size ratio.
174 bool mbFirstPageObjectSeen
;
176 // The widths for the previews contain two pixels for the border that is
177 // painted arround the preview.
178 static const int SMALL_PREVIEW_WIDTH
= 72 + 2;
179 static const int LARGE_PREVIEW_WIDTH
= 2*72 + 2;
181 /** This substition of page preview shows "Preparing preview" and is
182 shown as long as the actual previews are not being present.
184 Image maLargePreviewBeingCreated
;
185 Image maSmallPreviewBeingCreated
;
187 /** This substition of page preview is shown when a preview can not be
188 created and thus is not available.
190 Image maLargePreviewNotAvailable
;
191 Image maSmallPreviewNotAvailable
;
193 ::std::vector
<Link
> maChangeListeners
;
195 // We have to remember the tasks for initialization and filling in case
196 // a MasterPageContainer object is destroyed before these tasks have
198 ::boost::weak_ptr
<sd::tools::TimerBasedTaskExecution
> mpFillerTask
;
200 Size maSmallPreviewSizePixel
;
201 Size maLargePreviewSizePixel
;
202 bool mbPageRatioKnown
;
204 bool mbContainerCleaningPending
;
206 typedef ::std::pair
<MasterPageContainerChangeEvent::EventType
,Token
> EventData
;
207 DECL_LINK(AsynchronousNotifyCallback
, EventData
*);
208 ::sd::DrawDocShell
* LoadDocument (
209 const String
& sFileName
,
210 SfxObjectShellLock
& rxDocumentShell
);
212 Image
GetPreviewSubstitution (USHORT nId
, PreviewSize ePreviewSize
);
214 void CleanContainer (void);
220 //===== MasterPageContainer ===================================================
222 ::boost::weak_ptr
<MasterPageContainer::Implementation
>
223 MasterPageContainer::Implementation::mpInstance
;
224 static const MasterPageContainer::Token
NIL_TOKEN (-1);
229 ::boost::shared_ptr
<MasterPageContainer::Implementation
>
230 MasterPageContainer::Implementation::Instance (void)
232 ::boost::shared_ptr
<MasterPageContainer::Implementation
> pInstance
;
234 if (Implementation::mpInstance
.expired())
236 ::osl::GetGlobalMutex aMutexFunctor
;
237 ::osl::MutexGuard
aGuard (aMutexFunctor());
238 if (Implementation::mpInstance
.expired())
240 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
241 pInstance
= ::boost::shared_ptr
<MasterPageContainer::Implementation
>(
242 new MasterPageContainer::Implementation(),
243 MasterPageContainer::Implementation::Deleter());
244 SdGlobalResourceContainer::Instance().AddResource(pInstance
);
245 Implementation::mpInstance
= pInstance
;
248 pInstance
= ::boost::shared_ptr
<MasterPageContainer::Implementation
>(
249 Implementation::mpInstance
);
253 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
254 pInstance
= ::boost::shared_ptr
<MasterPageContainer::Implementation
>(
255 Implementation::mpInstance
);
258 DBG_ASSERT (pInstance
.get()!=NULL
,
259 "MasterPageContainer::Implementation::Instance(): instance is NULL");
266 MasterPageContainer::MasterPageContainer (void)
267 : mpImpl(Implementation::Instance()),
276 MasterPageContainer::~MasterPageContainer (void)
283 void MasterPageContainer::AddChangeListener (const Link
& rLink
)
285 mpImpl
->AddChangeListener(rLink
);
291 void MasterPageContainer::RemoveChangeListener (const Link
& rLink
)
293 mpImpl
->RemoveChangeListener(rLink
);
299 void MasterPageContainer::SetPreviewSize (PreviewSize eSize
)
301 mePreviewSize
= eSize
;
302 mpImpl
->FireContainerChange(
303 MasterPageContainerChangeEvent::SIZE_CHANGED
,
310 MasterPageContainer::PreviewSize
MasterPageContainer::GetPreviewSize (void) const
312 return mePreviewSize
;
318 Size
MasterPageContainer::GetPreviewSizePixel (void) const
320 return mpImpl
->GetPreviewSizePixel(mePreviewSize
);
326 MasterPageContainer::Token
MasterPageContainer::PutMasterPage (
327 const SharedMasterPageDescriptor
& rDescriptor
)
329 return mpImpl
->PutMasterPage(rDescriptor
);
335 void MasterPageContainer::AcquireToken (Token aToken
)
337 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
338 if (pDescriptor
.get() != NULL
)
340 ++pDescriptor
->mnUseCount
;
347 void MasterPageContainer::ReleaseToken (Token aToken
)
349 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
350 if (pDescriptor
.get() != NULL
)
352 OSL_ASSERT(pDescriptor
->mnUseCount
>0);
353 --pDescriptor
->mnUseCount
;
354 if (pDescriptor
->mnUseCount
<= 0)
356 switch (pDescriptor
->meOrigin
)
364 mpImpl
->ReleaseDescriptor(aToken
);
374 int MasterPageContainer::GetTokenCount (void) const
376 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
378 return mpImpl
->maContainer
.size();
384 bool MasterPageContainer::HasToken (Token aToken
) const
386 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
388 return mpImpl
->HasToken(aToken
);
394 MasterPageContainer::Token
MasterPageContainer::GetTokenForIndex (int nIndex
)
396 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
398 Token
aResult (NIL_TOKEN
);
399 if (HasToken(nIndex
))
400 aResult
= mpImpl
->maContainer
[nIndex
]->maToken
;
407 MasterPageContainer::Token
MasterPageContainer::GetTokenForURL (
410 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
412 Token
aResult (NIL_TOKEN
);
415 MasterPageContainerType::iterator
iEntry (
417 mpImpl
->maContainer
.begin(),
418 mpImpl
->maContainer
.end(),
419 MasterPageDescriptor::URLComparator(sURL
)));
420 if (iEntry
!= mpImpl
->maContainer
.end())
421 aResult
= (*iEntry
)->maToken
;
429 MasterPageContainer::Token
MasterPageContainer::GetTokenForPageName (
430 const String
& sPageName
)
432 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
434 Token
aResult (NIL_TOKEN
);
435 if (sPageName
.Len() > 0)
437 MasterPageContainerType::iterator
iEntry (
439 mpImpl
->maContainer
.begin(),
440 mpImpl
->maContainer
.end(),
441 MasterPageDescriptor::PageNameComparator(sPageName
)));
442 if (iEntry
!= mpImpl
->maContainer
.end())
443 aResult
= (*iEntry
)->maToken
;
451 MasterPageContainer::Token
MasterPageContainer::GetTokenForStyleName (const String
& sStyleName
)
453 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
455 Token
aResult (NIL_TOKEN
);
456 if (sStyleName
.Len() > 0)
458 MasterPageContainerType::iterator
iEntry (
460 mpImpl
->maContainer
.begin(),
461 mpImpl
->maContainer
.end(),
462 MasterPageDescriptor::StyleNameComparator(sStyleName
)));
463 if (iEntry
!= mpImpl
->maContainer
.end())
464 aResult
= (*iEntry
)->maToken
;
472 MasterPageContainer::Token
MasterPageContainer::GetTokenForPageObject (
475 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
477 Token
aResult (NIL_TOKEN
);
480 MasterPageContainerType::iterator
iEntry (
482 mpImpl
->maContainer
.begin(),
483 mpImpl
->maContainer
.end(),
484 MasterPageDescriptor::PageObjectComparator(pPage
)));
485 if (iEntry
!= mpImpl
->maContainer
.end())
486 aResult
= (*iEntry
)->maToken
;
494 String
MasterPageContainer::GetURLForToken (
495 MasterPageContainer::Token aToken
)
497 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
499 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
500 if (pDescriptor
.get() != NULL
)
501 return pDescriptor
->msURL
;
509 String
MasterPageContainer::GetPageNameForToken (
510 MasterPageContainer::Token aToken
)
512 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
514 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
515 if (pDescriptor
.get() != NULL
)
516 return pDescriptor
->msPageName
;
524 String
MasterPageContainer::GetStyleNameForToken (
525 MasterPageContainer::Token aToken
)
527 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
529 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
530 if (pDescriptor
.get() != NULL
)
531 return pDescriptor
->msStyleName
;
539 SdPage
* MasterPageContainer::GetPageObjectForToken (
540 MasterPageContainer::Token aToken
,
543 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
545 SdPage
* pPageObject
= NULL
;
546 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
547 if (pDescriptor
.get() != NULL
)
549 pPageObject
= pDescriptor
->mpMasterPage
;
550 if (pPageObject
== NULL
)
552 // The page object is not (yet) present. Call
553 // UpdateDescriptor() to trigger the PageObjectProvider() to
557 if (mpImpl
->UpdateDescriptor(pDescriptor
,bLoad
,false, true))
558 pPageObject
= pDescriptor
->mpMasterPage
;
567 MasterPageContainer::Origin
MasterPageContainer::GetOriginForToken (Token aToken
)
569 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
571 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
572 if (pDescriptor
.get() != NULL
)
573 return pDescriptor
->meOrigin
;
581 sal_Int32
MasterPageContainer::GetTemplateIndexForToken (Token aToken
)
583 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
585 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
586 if (pDescriptor
.get() != NULL
)
587 return pDescriptor
->mnTemplateIndex
;
595 void MasterPageContainer::SetPreviewProviderForToken (
597 const ::boost::shared_ptr
<PreviewProvider
>& rpPreviewProvider
)
599 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
601 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
602 if (pDescriptor
.get()!=NULL
)
604 pDescriptor
->mpPreviewProvider
= rpPreviewProvider
;
605 mpImpl
->InvalidatePreview(aToken
);
612 SdPage
* MasterPageContainer::GetSlideForToken (
613 MasterPageContainer::Token aToken
,
616 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
618 SdPage
* pSlide
= NULL
;
619 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
620 if (pDescriptor
.get() != NULL
)
622 pSlide
= pDescriptor
->mpSlide
;
623 if (pSlide
==NULL
&& bLoad
)
625 GetPageObjectForToken(aToken
, bLoad
);
626 pSlide
= pDescriptor
->mpSlide
;
635 SharedMasterPageDescriptor
MasterPageContainer::GetDescriptorForToken (
636 MasterPageContainer::Token aToken
)
638 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
640 return mpImpl
->GetDescriptor(aToken
);
646 bool MasterPageContainer::UpdateDescriptor (
647 const SharedMasterPageDescriptor
& rpDescriptor
,
648 bool bForcePageObject
,
652 return mpImpl
->UpdateDescriptor(rpDescriptor
, bForcePageObject
, bForcePreview
, bSendEvents
);
658 void MasterPageContainer::InvalidatePreview (MasterPageContainer::Token aToken
)
660 mpImpl
->InvalidatePreview(aToken
);
666 Image
MasterPageContainer::GetPreviewForToken (MasterPageContainer::Token aToken
)
668 return mpImpl
->GetPreviewForToken(aToken
,mePreviewSize
);
674 MasterPageContainer::PreviewState
MasterPageContainer::GetPreviewState (Token aToken
)
676 return mpImpl
->GetPreviewState(aToken
);
682 bool MasterPageContainer::RequestPreview (Token aToken
)
684 return mpImpl
->RequestPreview(aToken
);
690 //==== Implementation ================================================
692 MasterPageContainer::Implementation::Implementation (void)
695 meInitializationState(NOT_INITIALIZED
),
696 mpRequestQueue(NULL
),
700 mbFirstPageObjectSeen(false),
701 maLargePreviewBeingCreated(),
702 maSmallPreviewBeingCreated(),
703 maLargePreviewNotAvailable(),
704 maSmallPreviewNotAvailable(),
706 maSmallPreviewSizePixel(),
707 maLargePreviewSizePixel(),
708 mbPageRatioKnown(false),
709 mbContainerCleaningPending(true)
712 UpdatePreviewSizePixel();
718 MasterPageContainer::Implementation::~Implementation (void)
720 // When the initializer or filler tasks are still running then we have
721 // to stop them now in order to prevent them from calling us back.
722 tools::TimerBasedTaskExecution::ReleaseTask(mpFillerTask
);
724 mpRequestQueue
.reset();
726 uno::Reference
<util::XCloseable
> xCloseable (mxModel
, uno::UNO_QUERY
);
731 xCloseable
->close(true);
733 catch (::com::sun::star::util::CloseVetoException aException
)
743 void MasterPageContainer::Implementation::LateInit (void)
745 const ::osl::MutexGuard
aGuard (maMutex
);
747 if (meInitializationState
== NOT_INITIALIZED
)
749 meInitializationState
= INITIALIZING
;
751 OSL_ASSERT(Instance().get()==this);
752 mpRequestQueue
.reset(MasterPageContainerQueue::Create(
753 ::boost::shared_ptr
<MasterPageContainerQueue::ContainerAdapter
>(Instance())));
755 mpFillerTask
= ::sd::tools::TimerBasedTaskExecution::Create(
756 ::boost::shared_ptr
<tools::AsynchronousTask
>(new MasterPageContainerFiller(*this)),
760 meInitializationState
= INITIALIZED
;
767 void MasterPageContainer::Implementation::AddChangeListener (const Link
& rLink
)
769 const ::osl::MutexGuard
aGuard (maMutex
);
771 ::std::vector
<Link
>::iterator
iListener (
772 ::std::find(maChangeListeners
.begin(),maChangeListeners
.end(),rLink
));
773 if (iListener
== maChangeListeners
.end())
774 maChangeListeners
.push_back(rLink
);
781 void MasterPageContainer::Implementation::RemoveChangeListener (const Link
& rLink
)
783 const ::osl::MutexGuard
aGuard (maMutex
);
785 ::std::vector
<Link
>::iterator
iListener (
786 ::std::find(maChangeListeners
.begin(),maChangeListeners
.end(),rLink
));
787 if (iListener
!= maChangeListeners
.end())
788 maChangeListeners
.erase(iListener
);
794 void MasterPageContainer::Implementation::UpdatePreviewSizePixel (void)
796 const ::osl::MutexGuard
aGuard (maMutex
);
798 // The default aspect ratio is 4:3
802 // Search for the first entry with an existing master page.
803 MasterPageContainerType::const_iterator iDescriptor
;
804 MasterPageContainerType::const_iterator
iContainerEnd(maContainer
.end());
805 for (iDescriptor
=maContainer
.begin(); iDescriptor
!=iContainerEnd
; ++iDescriptor
)
806 if (*iDescriptor
!=NULL
&& (*iDescriptor
)->mpMasterPage
!= NULL
)
808 Size
aPageSize ((*iDescriptor
)->mpMasterPage
->GetSize());
809 nWidth
= aPageSize
.Width();
810 nHeight
= aPageSize
.Height();
811 mbFirstPageObjectSeen
= true;
815 maSmallPreviewSizePixel
.Width() = SMALL_PREVIEW_WIDTH
;
816 maLargePreviewSizePixel
.Width() = LARGE_PREVIEW_WIDTH
;
818 int nNewSmallHeight ((maSmallPreviewSizePixel
.Width()-2) * nHeight
/ nWidth
+ 2);
819 int nNewLargeHeight ((maLargePreviewSizePixel
.Width()-2) * nHeight
/ nWidth
+ 2);
821 if (nNewSmallHeight
!=maSmallPreviewSizePixel
.Height()
822 || nNewLargeHeight
!=maLargePreviewSizePixel
.Height())
824 maSmallPreviewSizePixel
.Height() = nNewSmallHeight
;
825 maLargePreviewSizePixel
.Height() = nNewLargeHeight
;
827 MasterPageContainerChangeEvent::SIZE_CHANGED
,
835 Size
MasterPageContainer::Implementation::GetPreviewSizePixel (PreviewSize eSize
) const
838 return maSmallPreviewSizePixel
;
840 return maLargePreviewSizePixel
;
846 IMPL_LINK(MasterPageContainer::Implementation
,AsynchronousNotifyCallback
, EventData
*, pData
)
848 const ::osl::MutexGuard
aGuard (maMutex
);
852 FireContainerChange(pData
->first
, pData
->second
, false);
862 MasterPageContainer::Token
MasterPageContainer::Implementation::PutMasterPage (
863 const SharedMasterPageDescriptor
& rpDescriptor
)
865 const ::osl::MutexGuard
aGuard (maMutex
);
867 Token
aResult (NIL_TOKEN
);
869 // Get page object and preview when that is inexpensive.
870 UpdateDescriptor(rpDescriptor
,false,false, false);
872 // Look up the new MasterPageDescriptor and either insert it or update
873 // an already existing one.
874 MasterPageContainerType::iterator
aEntry (
878 MasterPageDescriptor::AllComparator(rpDescriptor
)));
879 if (aEntry
== maContainer
.end())
881 // Insert a new MasterPageDescriptor.
882 bool bIgnore (rpDescriptor
->mpPageObjectProvider
.get()==NULL
883 && rpDescriptor
->msURL
.getLength()==0);
887 if (mbContainerCleaningPending
)
890 aResult
= maContainer
.size();
891 rpDescriptor
->SetToken(aResult
);
893 // Templates are precious, i.e. we lock them so that they will
894 // not be destroyed when (temporarily) no one references them.
895 // They will only be deleted when the container is destroyed.
896 switch (rpDescriptor
->meOrigin
)
900 ++rpDescriptor
->mnUseCount
;
907 maContainer
.push_back(rpDescriptor
);
908 aEntry
= maContainer
.end()-1;
910 FireContainerChange(MasterPageContainerChangeEvent::CHILD_ADDED
,aResult
);
915 // Update an existing MasterPageDescriptor.
916 aResult
= (*aEntry
)->maToken
;
917 ::std::auto_ptr
<std::vector
<MasterPageContainerChangeEvent::EventType
> > pEventTypes(
918 (*aEntry
)->Update(*rpDescriptor
));
919 if (pEventTypes
.get()!=NULL
&& pEventTypes
->size()>0)
921 // One or more aspects of the descriptor have changed. Send
922 // appropriate events to the listeners.
923 UpdateDescriptor(*aEntry
,false,false, true);
925 std::vector
<MasterPageContainerChangeEvent::EventType
>::const_iterator iEventType
;
926 for (iEventType
=pEventTypes
->begin(); iEventType
!=pEventTypes
->end(); ++iEventType
)
942 bool MasterPageContainer::Implementation::HasToken (Token aToken
) const
945 && (unsigned)aToken
<maContainer
.size()
946 && maContainer
[aToken
].get()!=NULL
;
952 const SharedMasterPageDescriptor
MasterPageContainer::Implementation::GetDescriptor (
955 if (aToken
>=0 && (unsigned)aToken
<maContainer
.size())
956 return maContainer
[aToken
];
958 return SharedMasterPageDescriptor();
964 SharedMasterPageDescriptor
MasterPageContainer::Implementation::GetDescriptor (Token aToken
)
966 if (aToken
>=0 && (unsigned)aToken
<maContainer
.size())
967 return maContainer
[aToken
];
969 return SharedMasterPageDescriptor();
975 void MasterPageContainer::Implementation::InvalidatePreview (Token aToken
)
977 const ::osl::MutexGuard
aGuard (maMutex
);
979 SharedMasterPageDescriptor
pDescriptor (GetDescriptor(aToken
));
980 if (pDescriptor
.get() != NULL
)
982 pDescriptor
->maSmallPreview
= Image();
983 pDescriptor
->maLargePreview
= Image();
984 RequestPreview(aToken
);
991 Image
MasterPageContainer::Implementation::GetPreviewForToken (
992 MasterPageContainer::Token aToken
,
993 PreviewSize ePreviewSize
)
995 const ::osl::MutexGuard
aGuard (maMutex
);
998 PreviewState
ePreviewState (GetPreviewState(aToken
));
1000 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
1002 // When the preview is missing but inexpensively creatable then do that
1004 if (pDescriptor
.get()!=NULL
)
1006 if (ePreviewState
== PS_CREATABLE
)
1007 if (UpdateDescriptor(pDescriptor
, false,false, true))
1008 if (pDescriptor
->maLargePreview
.GetSizePixel().Width() != 0)
1009 ePreviewState
= PS_AVAILABLE
;
1011 switch (ePreviewState
)
1014 aPreview
= pDescriptor
->GetPreview(ePreviewSize
);
1018 aPreview
= GetPreviewSubstitution(
1019 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
,
1024 aPreview
= GetPreviewSubstitution(
1025 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
,
1029 case PS_NOT_AVAILABLE
:
1030 aPreview
= GetPreviewSubstitution(
1031 STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
,
1033 if (ePreviewSize
== SMALL
)
1034 pDescriptor
->maSmallPreview
= aPreview
;
1036 pDescriptor
->maLargePreview
= aPreview
;
1047 MasterPageContainer::PreviewState
MasterPageContainer::Implementation::GetPreviewState (
1050 const ::osl::MutexGuard
aGuard (maMutex
);
1052 PreviewState
eState (PS_NOT_AVAILABLE
);
1054 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
1055 if (pDescriptor
.get() != NULL
)
1057 if (pDescriptor
->maLargePreview
.GetSizePixel().Width() != 0)
1058 eState
= PS_AVAILABLE
;
1059 else if (pDescriptor
->mpPreviewProvider
.get() != NULL
)
1061 // The preview does not exist but can be created. When that is
1062 // not expensive then do it at once.
1063 if (mpRequestQueue
->HasRequest(aToken
))
1064 eState
= PS_PREPARING
;
1066 eState
= PS_CREATABLE
;
1069 eState
= PS_NOT_AVAILABLE
;
1078 bool MasterPageContainer::Implementation::RequestPreview (Token aToken
)
1080 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
1081 if (pDescriptor
.get() != NULL
)
1082 return mpRequestQueue
->RequestPreview(pDescriptor
);
1090 Reference
<frame::XModel
> MasterPageContainer::Implementation::GetModel (void)
1092 const ::osl::MutexGuard
aGuard (maMutex
);
1094 if ( ! mxModel
.is())
1096 // Get the desktop a s service factory.
1097 ::rtl::OUString
sDesktopServiceName (
1098 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop"));
1099 uno::Reference
<frame::XComponentLoader
> xDesktop (
1100 ::comphelper::getProcessServiceFactory()->createInstance(
1101 sDesktopServiceName
),
1104 // Create a new model.
1105 ::rtl::OUString
sModelServiceName (
1106 RTL_CONSTASCII_USTRINGPARAM(
1107 "com.sun.star.presentation.PresentationDocument"));
1108 mxModel
= uno::Reference
<frame::XModel
>(
1109 ::comphelper::getProcessServiceFactory()->createInstance(
1113 // Initialize the model.
1114 uno::Reference
<frame::XLoadable
> xLoadable (mxModel
,uno::UNO_QUERY
);
1116 xLoadable
->initNew();
1118 // Use its tunnel to get a pointer to its core implementation.
1119 uno::Reference
<lang::XUnoTunnel
> xUnoTunnel (mxModel
, uno::UNO_QUERY
);
1120 if (xUnoTunnel
.is())
1122 mpDocument
= reinterpret_cast<SdXImpressDocument
*>(
1123 xUnoTunnel
->getSomething(
1124 SdXImpressDocument::getUnoTunnelId()))->GetDoc();
1127 // Create a default page.
1128 uno::Reference
<drawing::XDrawPagesSupplier
> xSlideSupplier (mxModel
, uno::UNO_QUERY
);
1129 if (xSlideSupplier
.is())
1131 uno::Reference
<drawing::XDrawPages
> xSlides (
1132 xSlideSupplier
->getDrawPages(), uno::UNO_QUERY
);
1135 sal_Int32
nIndex (0);
1136 uno::Reference
<drawing::XDrawPage
> xNewPage (xSlides
->insertNewByIndex(nIndex
));
1137 uno::Reference
<beans::XPropertySet
> xProperties(xNewPage
, uno::UNO_QUERY
);
1138 if (xProperties
.is())
1139 xProperties
->setPropertyValue(
1140 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Layout")),
1141 makeAny((sal_Int16
)AUTOLAYOUT_TITLE
));
1151 SdDrawDocument
* MasterPageContainer::Implementation::GetDocument (void)
1160 Image
MasterPageContainer::Implementation::GetPreviewSubstitution (
1162 PreviewSize ePreviewSize
)
1164 const ::osl::MutexGuard
aGuard (maMutex
);
1170 case STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
:
1172 Image
& rPreview (ePreviewSize
==SMALL
1173 ? maSmallPreviewBeingCreated
1174 : maLargePreviewBeingCreated
);
1175 if (rPreview
.GetSizePixel().Width() == 0)
1177 rPreview
= maPreviewRenderer
.RenderSubstitution(
1178 ePreviewSize
==SMALL
? maSmallPreviewSizePixel
: maLargePreviewSizePixel
,
1179 SdResId(STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
));
1181 aPreview
= rPreview
;
1185 case STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
:
1187 Image
& rPreview (ePreviewSize
==SMALL
1188 ? maSmallPreviewNotAvailable
1189 : maLargePreviewNotAvailable
);
1190 if (rPreview
.GetSizePixel().Width() == 0)
1192 rPreview
= maPreviewRenderer
.RenderSubstitution(
1193 ePreviewSize
==SMALL
? maSmallPreviewSizePixel
: maLargePreviewSizePixel
,
1194 SdResId(STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
));
1196 aPreview
= rPreview
;
1207 void MasterPageContainer::Implementation::CleanContainer (void)
1209 // Remove the empty elements at the end of the container. The empty
1210 // elements in the middle can not be removed because that would
1211 // invalidate the references still held by others.
1212 int nIndex (maContainer
.size()-1);
1213 while (nIndex
>=0 && maContainer
[nIndex
].get()==NULL
)
1215 maContainer
.resize(++nIndex
);
1221 void MasterPageContainer::Implementation::FireContainerChange (
1222 MasterPageContainerChangeEvent::EventType eType
,
1224 bool bNotifyAsynchronously
)
1226 if (bNotifyAsynchronously
)
1228 Application::PostUserEvent(
1229 LINK(this,Implementation
,AsynchronousNotifyCallback
),
1230 new EventData(eType
,aToken
));
1234 ::std::vector
<Link
> aCopy(maChangeListeners
.begin(),maChangeListeners
.end());
1235 ::std::vector
<Link
>::iterator iListener
;
1236 MasterPageContainerChangeEvent aEvent
;
1237 aEvent
.meEventType
= eType
;
1238 aEvent
.maChildToken
= aToken
;
1239 for (iListener
=aCopy
.begin(); iListener
!=aCopy
.end(); ++iListener
)
1240 iListener
->Call(&aEvent
);
1247 bool MasterPageContainer::Implementation::UpdateDescriptor (
1248 const SharedMasterPageDescriptor
& rpDescriptor
,
1249 bool bForcePageObject
,
1253 const ::osl::MutexGuard
aGuard (maMutex
);
1255 // We have to create the page object when the preview provider needs it
1256 // and the caller needs the preview.
1257 bForcePageObject
|= (bForcePreview
1258 && rpDescriptor
->mpPreviewProvider
->NeedsPageObject()
1259 && rpDescriptor
->mpMasterPage
==NULL
);
1261 // Define a cost threshold so that an update or page object or preview
1262 // that is at least this cost are made at once. Updates with higher cost
1263 // are scheduled for later.
1264 sal_Int32
nCostThreshold (mpRequestQueue
->IsEmpty() ? 5 : 0);
1266 // Update the page object (which may be used for the preview update).
1267 if (bForcePageObject
)
1269 bool bPageObjectModified (rpDescriptor
->UpdatePageObject(
1270 (bForcePageObject
? -1 : nCostThreshold
),
1272 if (bPageObjectModified
&& bSendEvents
)
1273 FireContainerChange(
1274 MasterPageContainerChangeEvent::DATA_CHANGED
,
1275 rpDescriptor
->maToken
);
1276 if (bPageObjectModified
&& ! mbFirstPageObjectSeen
)
1277 UpdatePreviewSizePixel();
1279 // Update the preview.
1280 bool bPreviewModified (rpDescriptor
->UpdatePreview(
1281 (bForcePreview
? -1 : nCostThreshold
),
1282 maSmallPreviewSizePixel
,
1283 maLargePreviewSizePixel
,
1284 maPreviewRenderer
));
1286 if (bPreviewModified
&& bSendEvents
)
1287 FireContainerChange(
1288 MasterPageContainerChangeEvent::PREVIEW_CHANGED
,
1289 rpDescriptor
->maToken
);
1291 return bPageObjectModified
|| bPreviewModified
;
1297 void MasterPageContainer::Implementation::ReleaseDescriptor (Token aToken
)
1299 if (aToken
>=0 && (unsigned)aToken
<maContainer
.size())
1301 maContainer
[aToken
].reset();
1302 mbContainerCleaningPending
= true;
1309 void MasterPageContainer::Implementation::FillingDone (void)
1311 mpRequestQueue
->ProcessAllRequests();
1316 } } } // end of namespace ::sd::toolpanel::controls
1323 //===== PreviewCreationRequest ================================================
1325 PreviewCreationRequest::PreviewCreationRequest (
1326 MasterPageContainer::Token aToken
,
1329 mnPriority(nPriority
)
1336 bool PreviewCreationRequest::Compare::operator() (
1337 const PreviewCreationRequest
& aRequest1
,
1338 const PreviewCreationRequest
& aRequest2
)
1340 if (aRequest1
.mnPriority
!= aRequest2
.mnPriority
)
1342 // Prefer requests with higher priority.
1343 return aRequest1
.mnPriority
> aRequest2
.mnPriority
;
1347 // Prefer tokens that have been earlier created (those with lower
1349 return aRequest1
.maToken
< aRequest2
.maToken
;
1356 PreviewCreationRequest::CompareToken::CompareToken (MasterPageContainer::Token aToken
)
1364 bool PreviewCreationRequest::CompareToken::operator() (const PreviewCreationRequest
& aRequest
)
1366 return maToken
==aRequest
.maToken
;
1371 } // end of anonymous namespace