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 .
21 #include "MasterPageContainer.hxx"
23 #include "MasterPageDescriptor.hxx"
24 #include "MasterPageContainerFiller.hxx"
25 #include "MasterPageContainerQueue.hxx"
26 #include "TemplateScanner.hxx"
27 #include "tools/AsynchronousTask.hxx"
28 #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 <boost/weak_ptr.hpp>
58 using namespace ::com::sun::star
;
59 using namespace ::com::sun::star::uno
;
60 using namespace ::sd::toolpanel::controls
;
64 typedef ::std::vector
<SharedMasterPageDescriptor
> MasterPageContainerType
;
66 } // end of anonymous namespace
69 namespace sd
{ namespace toolpanel
{ namespace controls
{
72 /** Inner implementation class of the MasterPageContainer.
74 class MasterPageContainer::Implementation
75 : public SdGlobalResource
,
76 public MasterPageContainerFiller::ContainerAdapter
,
77 public MasterPageContainerQueue::ContainerAdapter
80 mutable ::osl::Mutex maMutex
;
82 static ::boost::weak_ptr
<Implementation
> mpInstance
;
83 MasterPageContainerType maContainer
;
85 static ::boost::shared_ptr
<Implementation
> Instance (void);
88 void AddChangeListener (const Link
& rLink
);
89 void RemoveChangeListener (const Link
& rLink
);
90 void UpdatePreviewSizePixel (void);
91 Size
GetPreviewSizePixel (PreviewSize eSize
) const;
93 bool HasToken (Token aToken
) const;
94 const SharedMasterPageDescriptor
GetDescriptor (MasterPageContainer::Token aToken
) const;
95 SharedMasterPageDescriptor
GetDescriptor (MasterPageContainer::Token aToken
);
96 virtual Token
PutMasterPage (const SharedMasterPageDescriptor
& rDescriptor
);
97 void InvalidatePreview (Token aToken
);
98 Image
GetPreviewForToken (
100 PreviewSize ePreviewSize
);
101 PreviewState
GetPreviewState (Token aToken
) const;
102 bool RequestPreview (Token aToken
);
104 Reference
<frame::XModel
> GetModel (void);
105 SdDrawDocument
* GetDocument (void);
107 void FireContainerChange (
108 MasterPageContainerChangeEvent::EventType eType
,
110 bool bNotifyAsynchronously
= false);
112 virtual bool UpdateDescriptor (
113 const SharedMasterPageDescriptor
& rpDescriptor
,
114 bool bForcePageObject
,
118 void ReleaseDescriptor (Token aToken
);
120 /** Called by the MasterPageContainerFiller to notify that all master
121 pages from template documents have been added.
123 virtual void FillingDone (void);
126 Implementation (void);
127 virtual ~Implementation (void);
129 class Deleter
{ public:
130 void operator() (Implementation
* pObject
) { delete pObject
; }
132 friend class Deleter
;
134 enum InitializationState
{ NOT_INITIALIZED
, INITIALIZING
, INITIALIZED
} meInitializationState
;
136 ::boost::scoped_ptr
<MasterPageContainerQueue
> mpRequestQueue
;
137 ::com::sun::star::uno::Reference
<com::sun::star::frame::XModel
> mxModel
;
138 SdDrawDocument
* mpDocument
;
139 PreviewRenderer maPreviewRenderer
;
140 /** Remember whether the first page object has already been used to
141 determine the correct size ratio.
143 bool mbFirstPageObjectSeen
;
145 // The widths for the previews contain two pixels for the border that is
146 // painted arround the preview.
147 static const int SMALL_PREVIEW_WIDTH
= 72 + 2;
148 static const int LARGE_PREVIEW_WIDTH
= 2*72 + 2;
150 /** This substition of page preview shows "Preparing preview" and is
151 shown as long as the actual previews are not being present.
153 Image maLargePreviewBeingCreated
;
154 Image maSmallPreviewBeingCreated
;
156 /** This substition of page preview is shown when a preview can not be
157 created and thus is not available.
159 Image maLargePreviewNotAvailable
;
160 Image maSmallPreviewNotAvailable
;
162 ::std::vector
<Link
> maChangeListeners
;
164 // We have to remember the tasks for initialization and filling in case
165 // a MasterPageContainer object is destroyed before these tasks have
167 ::boost::weak_ptr
<sd::tools::TimerBasedTaskExecution
> mpFillerTask
;
169 Size maSmallPreviewSizePixel
;
170 Size maLargePreviewSizePixel
;
171 bool mbPageRatioKnown
;
173 bool mbContainerCleaningPending
;
175 typedef ::std::pair
<MasterPageContainerChangeEvent::EventType
,Token
> EventData
;
176 DECL_LINK(AsynchronousNotifyCallback
, EventData
*);
177 ::sd::DrawDocShell
* LoadDocument (
178 const String
& sFileName
,
179 SfxObjectShellLock
& rxDocumentShell
);
181 Image
GetPreviewSubstitution (sal_uInt16 nId
, PreviewSize ePreviewSize
);
183 void CleanContainer (void);
189 //===== MasterPageContainer ===================================================
191 ::boost::weak_ptr
<MasterPageContainer::Implementation
>
192 MasterPageContainer::Implementation::mpInstance
;
193 static const MasterPageContainer::Token
NIL_TOKEN (-1);
198 ::boost::shared_ptr
<MasterPageContainer::Implementation
>
199 MasterPageContainer::Implementation::Instance (void)
201 ::boost::shared_ptr
<MasterPageContainer::Implementation
> pInstance
;
203 if (Implementation::mpInstance
.expired())
205 ::osl::GetGlobalMutex aMutexFunctor
;
206 ::osl::MutexGuard
aGuard (aMutexFunctor());
207 if (Implementation::mpInstance
.expired())
209 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
210 pInstance
= ::boost::shared_ptr
<MasterPageContainer::Implementation
>(
211 new MasterPageContainer::Implementation(),
212 MasterPageContainer::Implementation::Deleter());
213 SdGlobalResourceContainer::Instance().AddResource(pInstance
);
214 Implementation::mpInstance
= pInstance
;
217 pInstance
= ::boost::shared_ptr
<MasterPageContainer::Implementation
>(
218 Implementation::mpInstance
);
222 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
223 pInstance
= ::boost::shared_ptr
<MasterPageContainer::Implementation
>(
224 Implementation::mpInstance
);
227 DBG_ASSERT (pInstance
.get()!=NULL
,
228 "MasterPageContainer::Implementation::Instance(): instance is NULL");
235 MasterPageContainer::MasterPageContainer (void)
236 : mpImpl(Implementation::Instance()),
245 MasterPageContainer::~MasterPageContainer (void)
252 void MasterPageContainer::AddChangeListener (const Link
& rLink
)
254 mpImpl
->AddChangeListener(rLink
);
260 void MasterPageContainer::RemoveChangeListener (const Link
& rLink
)
262 mpImpl
->RemoveChangeListener(rLink
);
268 void MasterPageContainer::SetPreviewSize (PreviewSize eSize
)
270 mePreviewSize
= eSize
;
271 mpImpl
->FireContainerChange(
272 MasterPageContainerChangeEvent::SIZE_CHANGED
,
279 MasterPageContainer::PreviewSize
MasterPageContainer::GetPreviewSize (void) const
281 return mePreviewSize
;
287 Size
MasterPageContainer::GetPreviewSizePixel (void) const
289 return mpImpl
->GetPreviewSizePixel(mePreviewSize
);
295 MasterPageContainer::Token
MasterPageContainer::PutMasterPage (
296 const SharedMasterPageDescriptor
& rDescriptor
)
298 return mpImpl
->PutMasterPage(rDescriptor
);
304 void MasterPageContainer::AcquireToken (Token aToken
)
306 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
307 if (pDescriptor
.get() != NULL
)
309 ++pDescriptor
->mnUseCount
;
316 void MasterPageContainer::ReleaseToken (Token aToken
)
318 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
319 if (pDescriptor
.get() != NULL
)
321 OSL_ASSERT(pDescriptor
->mnUseCount
>0);
322 --pDescriptor
->mnUseCount
;
323 if (pDescriptor
->mnUseCount
<= 0)
325 switch (pDescriptor
->meOrigin
)
333 mpImpl
->ReleaseDescriptor(aToken
);
343 int MasterPageContainer::GetTokenCount (void) const
345 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
347 return mpImpl
->maContainer
.size();
353 bool MasterPageContainer::HasToken (Token aToken
) const
355 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
357 return mpImpl
->HasToken(aToken
);
363 MasterPageContainer::Token
MasterPageContainer::GetTokenForIndex (int nIndex
)
365 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
367 Token
aResult (NIL_TOKEN
);
368 if (HasToken(nIndex
))
369 aResult
= mpImpl
->maContainer
[nIndex
]->maToken
;
376 MasterPageContainer::Token
MasterPageContainer::GetTokenForURL (
379 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
381 Token
aResult (NIL_TOKEN
);
384 MasterPageContainerType::iterator
iEntry (
386 mpImpl
->maContainer
.begin(),
387 mpImpl
->maContainer
.end(),
388 MasterPageDescriptor::URLComparator(sURL
)));
389 if (iEntry
!= mpImpl
->maContainer
.end())
390 aResult
= (*iEntry
)->maToken
;
398 MasterPageContainer::Token
MasterPageContainer::GetTokenForStyleName (const String
& sStyleName
)
400 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
402 Token
aResult (NIL_TOKEN
);
403 if (sStyleName
.Len() > 0)
405 MasterPageContainerType::iterator
iEntry (
407 mpImpl
->maContainer
.begin(),
408 mpImpl
->maContainer
.end(),
409 MasterPageDescriptor::StyleNameComparator(sStyleName
)));
410 if (iEntry
!= mpImpl
->maContainer
.end())
411 aResult
= (*iEntry
)->maToken
;
419 MasterPageContainer::Token
MasterPageContainer::GetTokenForPageObject (
422 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
424 Token
aResult (NIL_TOKEN
);
427 MasterPageContainerType::iterator
iEntry (
429 mpImpl
->maContainer
.begin(),
430 mpImpl
->maContainer
.end(),
431 MasterPageDescriptor::PageObjectComparator(pPage
)));
432 if (iEntry
!= mpImpl
->maContainer
.end())
433 aResult
= (*iEntry
)->maToken
;
441 String
MasterPageContainer::GetURLForToken (
442 MasterPageContainer::Token aToken
)
444 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
446 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
447 if (pDescriptor
.get() != NULL
)
448 return pDescriptor
->msURL
;
456 String
MasterPageContainer::GetPageNameForToken (
457 MasterPageContainer::Token aToken
)
459 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
461 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
462 if (pDescriptor
.get() != NULL
)
463 return pDescriptor
->msPageName
;
471 String
MasterPageContainer::GetStyleNameForToken (
472 MasterPageContainer::Token aToken
)
474 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
476 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
477 if (pDescriptor
.get() != NULL
)
478 return pDescriptor
->msStyleName
;
486 SdPage
* MasterPageContainer::GetPageObjectForToken (
487 MasterPageContainer::Token aToken
,
490 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
492 SdPage
* pPageObject
= NULL
;
493 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
494 if (pDescriptor
.get() != NULL
)
496 pPageObject
= pDescriptor
->mpMasterPage
;
497 if (pPageObject
== NULL
)
499 // The page object is not (yet) present. Call
500 // UpdateDescriptor() to trigger the PageObjectProvider() to
504 if (mpImpl
->UpdateDescriptor(pDescriptor
,bLoad
,false, true))
505 pPageObject
= pDescriptor
->mpMasterPage
;
514 MasterPageContainer::Origin
MasterPageContainer::GetOriginForToken (Token aToken
)
516 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
518 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
519 if (pDescriptor
.get() != NULL
)
520 return pDescriptor
->meOrigin
;
528 sal_Int32
MasterPageContainer::GetTemplateIndexForToken (Token aToken
)
530 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
532 SharedMasterPageDescriptor pDescriptor
= mpImpl
->GetDescriptor(aToken
);
533 if (pDescriptor
.get() != NULL
)
534 return pDescriptor
->mnTemplateIndex
;
542 SharedMasterPageDescriptor
MasterPageContainer::GetDescriptorForToken (
543 MasterPageContainer::Token aToken
)
545 const ::osl::MutexGuard
aGuard (mpImpl
->maMutex
);
547 return mpImpl
->GetDescriptor(aToken
);
552 void MasterPageContainer::InvalidatePreview (MasterPageContainer::Token aToken
)
554 mpImpl
->InvalidatePreview(aToken
);
560 Image
MasterPageContainer::GetPreviewForToken (MasterPageContainer::Token aToken
)
562 return mpImpl
->GetPreviewForToken(aToken
,mePreviewSize
);
568 MasterPageContainer::PreviewState
MasterPageContainer::GetPreviewState (Token aToken
)
570 return mpImpl
->GetPreviewState(aToken
);
576 bool MasterPageContainer::RequestPreview (Token aToken
)
578 return mpImpl
->RequestPreview(aToken
);
584 //==== Implementation ================================================
586 MasterPageContainer::Implementation::Implementation (void)
589 meInitializationState(NOT_INITIALIZED
),
590 mpRequestQueue(NULL
),
594 mbFirstPageObjectSeen(false),
595 maLargePreviewBeingCreated(),
596 maSmallPreviewBeingCreated(),
597 maLargePreviewNotAvailable(),
598 maSmallPreviewNotAvailable(),
600 maSmallPreviewSizePixel(),
601 maLargePreviewSizePixel(),
602 mbPageRatioKnown(false),
603 mbContainerCleaningPending(true)
606 UpdatePreviewSizePixel();
612 MasterPageContainer::Implementation::~Implementation (void)
614 // When the initializer or filler tasks are still running then we have
615 // to stop them now in order to prevent them from calling us back.
616 tools::TimerBasedTaskExecution::ReleaseTask(mpFillerTask
);
618 mpRequestQueue
.reset();
620 uno::Reference
<util::XCloseable
> xCloseable (mxModel
, uno::UNO_QUERY
);
625 xCloseable
->close(true);
627 catch (const ::com::sun::star::util::CloseVetoException
&)
637 void MasterPageContainer::Implementation::LateInit (void)
639 const ::osl::MutexGuard
aGuard (maMutex
);
641 if (meInitializationState
== NOT_INITIALIZED
)
643 meInitializationState
= INITIALIZING
;
645 OSL_ASSERT(Instance().get()==this);
646 mpRequestQueue
.reset(MasterPageContainerQueue::Create(
647 ::boost::shared_ptr
<MasterPageContainerQueue::ContainerAdapter
>(Instance())));
649 mpFillerTask
= ::sd::tools::TimerBasedTaskExecution::Create(
650 ::boost::shared_ptr
<tools::AsynchronousTask
>(new MasterPageContainerFiller(*this)),
654 meInitializationState
= INITIALIZED
;
661 void MasterPageContainer::Implementation::AddChangeListener (const Link
& rLink
)
663 const ::osl::MutexGuard
aGuard (maMutex
);
665 ::std::vector
<Link
>::iterator
iListener (
666 ::std::find(maChangeListeners
.begin(),maChangeListeners
.end(),rLink
));
667 if (iListener
== maChangeListeners
.end())
668 maChangeListeners
.push_back(rLink
);
675 void MasterPageContainer::Implementation::RemoveChangeListener (const Link
& rLink
)
677 const ::osl::MutexGuard
aGuard (maMutex
);
679 ::std::vector
<Link
>::iterator
iListener (
680 ::std::find(maChangeListeners
.begin(),maChangeListeners
.end(),rLink
));
681 if (iListener
!= maChangeListeners
.end())
682 maChangeListeners
.erase(iListener
);
688 void MasterPageContainer::Implementation::UpdatePreviewSizePixel (void)
690 const ::osl::MutexGuard
aGuard (maMutex
);
692 // The default aspect ratio is 4:3
696 // Search for the first entry with an existing master page.
697 MasterPageContainerType::const_iterator iDescriptor
;
698 MasterPageContainerType::const_iterator
iContainerEnd(maContainer
.end());
699 for (iDescriptor
=maContainer
.begin(); iDescriptor
!=iContainerEnd
; ++iDescriptor
)
700 if (*iDescriptor
!=NULL
&& (*iDescriptor
)->mpMasterPage
!= NULL
)
702 Size
aPageSize ((*iDescriptor
)->mpMasterPage
->GetSize());
703 OSL_ASSERT(aPageSize
.Width() > 0 && aPageSize
.Height() > 0);
704 if (aPageSize
.Width() > 0)
705 nWidth
= aPageSize
.Width();
706 if (aPageSize
.Height() > 0)
707 nHeight
= aPageSize
.Height();
708 mbFirstPageObjectSeen
= true;
712 maSmallPreviewSizePixel
.Width() = SMALL_PREVIEW_WIDTH
;
713 maLargePreviewSizePixel
.Width() = LARGE_PREVIEW_WIDTH
;
715 int nNewSmallHeight ((maSmallPreviewSizePixel
.Width()-2) * nHeight
/ nWidth
+ 2);
716 int nNewLargeHeight ((maLargePreviewSizePixel
.Width()-2) * nHeight
/ nWidth
+ 2);
718 if (nNewSmallHeight
!=maSmallPreviewSizePixel
.Height()
719 || nNewLargeHeight
!=maLargePreviewSizePixel
.Height())
721 maSmallPreviewSizePixel
.Height() = nNewSmallHeight
;
722 maLargePreviewSizePixel
.Height() = nNewLargeHeight
;
724 MasterPageContainerChangeEvent::SIZE_CHANGED
,
732 Size
MasterPageContainer::Implementation::GetPreviewSizePixel (PreviewSize eSize
) const
735 return maSmallPreviewSizePixel
;
737 return maLargePreviewSizePixel
;
743 IMPL_LINK(MasterPageContainer::Implementation
,AsynchronousNotifyCallback
, EventData
*, pData
)
745 const ::osl::MutexGuard
aGuard (maMutex
);
749 FireContainerChange(pData
->first
, pData
->second
, false);
759 MasterPageContainer::Token
MasterPageContainer::Implementation::PutMasterPage (
760 const SharedMasterPageDescriptor
& rpDescriptor
)
762 const ::osl::MutexGuard
aGuard (maMutex
);
764 Token
aResult (NIL_TOKEN
);
766 // Get page object and preview when that is inexpensive.
767 UpdateDescriptor(rpDescriptor
,false,false, false);
769 // Look up the new MasterPageDescriptor and either insert it or update
770 // an already existing one.
771 MasterPageContainerType::iterator
aEntry (
775 MasterPageDescriptor::AllComparator(rpDescriptor
)));
776 if (aEntry
== maContainer
.end())
778 // Insert a new MasterPageDescriptor.
779 bool bIgnore (rpDescriptor
->mpPageObjectProvider
.get()==NULL
780 && rpDescriptor
->msURL
.isEmpty());
784 if (mbContainerCleaningPending
)
787 aResult
= maContainer
.size();
788 rpDescriptor
->SetToken(aResult
);
790 // Templates are precious, i.e. we lock them so that they will
791 // not be destroyed when (temporarily) no one references them.
792 // They will only be deleted when the container is destroyed.
793 switch (rpDescriptor
->meOrigin
)
797 ++rpDescriptor
->mnUseCount
;
804 maContainer
.push_back(rpDescriptor
);
805 aEntry
= maContainer
.end()-1;
807 FireContainerChange(MasterPageContainerChangeEvent::CHILD_ADDED
,aResult
);
812 // Update an existing MasterPageDescriptor.
813 aResult
= (*aEntry
)->maToken
;
814 ::std::auto_ptr
<std::vector
<MasterPageContainerChangeEvent::EventType
> > pEventTypes(
815 (*aEntry
)->Update(*rpDescriptor
));
816 if (pEventTypes
.get()!=NULL
&& pEventTypes
->size()>0)
818 // One or more aspects of the descriptor have changed. Send
819 // appropriate events to the listeners.
820 UpdateDescriptor(*aEntry
,false,false, true);
822 std::vector
<MasterPageContainerChangeEvent::EventType
>::const_iterator iEventType
;
823 for (iEventType
=pEventTypes
->begin(); iEventType
!=pEventTypes
->end(); ++iEventType
)
839 bool MasterPageContainer::Implementation::HasToken (Token aToken
) const
842 && (unsigned)aToken
<maContainer
.size()
843 && maContainer
[aToken
].get()!=NULL
;
849 const SharedMasterPageDescriptor
MasterPageContainer::Implementation::GetDescriptor (
852 if (aToken
>=0 && (unsigned)aToken
<maContainer
.size())
853 return maContainer
[aToken
];
855 return SharedMasterPageDescriptor();
861 SharedMasterPageDescriptor
MasterPageContainer::Implementation::GetDescriptor (Token aToken
)
863 if (aToken
>=0 && (unsigned)aToken
<maContainer
.size())
864 return maContainer
[aToken
];
866 return SharedMasterPageDescriptor();
872 void MasterPageContainer::Implementation::InvalidatePreview (Token aToken
)
874 const ::osl::MutexGuard
aGuard (maMutex
);
876 SharedMasterPageDescriptor
pDescriptor (GetDescriptor(aToken
));
877 if (pDescriptor
.get() != NULL
)
879 pDescriptor
->maSmallPreview
= Image();
880 pDescriptor
->maLargePreview
= Image();
881 RequestPreview(aToken
);
888 Image
MasterPageContainer::Implementation::GetPreviewForToken (
889 MasterPageContainer::Token aToken
,
890 PreviewSize ePreviewSize
)
892 const ::osl::MutexGuard
aGuard (maMutex
);
895 PreviewState
ePreviewState (GetPreviewState(aToken
));
897 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
899 // When the preview is missing but inexpensively creatable then do that
901 if (pDescriptor
.get()!=NULL
)
903 if (ePreviewState
== PS_CREATABLE
)
904 if (UpdateDescriptor(pDescriptor
, false,false, true))
905 if (pDescriptor
->maLargePreview
.GetSizePixel().Width() != 0)
906 ePreviewState
= PS_AVAILABLE
;
908 switch (ePreviewState
)
911 aPreview
= pDescriptor
->GetPreview(ePreviewSize
);
915 aPreview
= GetPreviewSubstitution(
916 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
,
921 aPreview
= GetPreviewSubstitution(
922 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
,
926 case PS_NOT_AVAILABLE
:
927 aPreview
= GetPreviewSubstitution(
928 STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
,
930 if (ePreviewSize
== SMALL
)
931 pDescriptor
->maSmallPreview
= aPreview
;
933 pDescriptor
->maLargePreview
= aPreview
;
944 MasterPageContainer::PreviewState
MasterPageContainer::Implementation::GetPreviewState (
947 const ::osl::MutexGuard
aGuard (maMutex
);
949 PreviewState
eState (PS_NOT_AVAILABLE
);
951 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
952 if (pDescriptor
.get() != NULL
)
954 if (pDescriptor
->maLargePreview
.GetSizePixel().Width() != 0)
955 eState
= PS_AVAILABLE
;
956 else if (pDescriptor
->mpPreviewProvider
.get() != NULL
)
958 // The preview does not exist but can be created. When that is
959 // not expensive then do it at once.
960 if (mpRequestQueue
->HasRequest(aToken
))
961 eState
= PS_PREPARING
;
963 eState
= PS_CREATABLE
;
966 eState
= PS_NOT_AVAILABLE
;
975 bool MasterPageContainer::Implementation::RequestPreview (Token aToken
)
977 SharedMasterPageDescriptor pDescriptor
= GetDescriptor(aToken
);
978 if (pDescriptor
.get() != NULL
)
979 return mpRequestQueue
->RequestPreview(pDescriptor
);
987 Reference
<frame::XModel
> MasterPageContainer::Implementation::GetModel (void)
989 const ::osl::MutexGuard
aGuard (maMutex
);
993 // Get the desktop a s service factory.
994 uno::Reference
<frame::XDesktop2
> xDesktop
= frame::Desktop::create(
995 ::comphelper::getProcessComponentContext() );
997 // Create a new model.
998 OUString
sModelServiceName ( "com.sun.star.presentation.PresentationDocument");
999 mxModel
= uno::Reference
<frame::XModel
>(
1000 ::comphelper::getProcessServiceFactory()->createInstance(
1004 // Initialize the model.
1005 uno::Reference
<frame::XLoadable
> xLoadable (mxModel
,uno::UNO_QUERY
);
1007 xLoadable
->initNew();
1009 // Use its tunnel to get a pointer to its core implementation.
1010 uno::Reference
<lang::XUnoTunnel
> xUnoTunnel (mxModel
, uno::UNO_QUERY
);
1011 if (xUnoTunnel
.is())
1013 mpDocument
= reinterpret_cast<SdXImpressDocument
*>(
1014 xUnoTunnel
->getSomething(
1015 SdXImpressDocument::getUnoTunnelId()))->GetDoc();
1018 // Create a default page.
1019 uno::Reference
<drawing::XDrawPagesSupplier
> xSlideSupplier (mxModel
, uno::UNO_QUERY
);
1020 if (xSlideSupplier
.is())
1022 uno::Reference
<drawing::XDrawPages
> xSlides (
1023 xSlideSupplier
->getDrawPages(), uno::UNO_QUERY
);
1026 sal_Int32
nIndex (0);
1027 uno::Reference
<drawing::XDrawPage
> xNewPage (xSlides
->insertNewByIndex(nIndex
));
1028 uno::Reference
<beans::XPropertySet
> xProperties(xNewPage
, uno::UNO_QUERY
);
1029 if (xProperties
.is())
1030 xProperties
->setPropertyValue(
1032 makeAny((sal_Int16
)AUTOLAYOUT_TITLE
));
1042 SdDrawDocument
* MasterPageContainer::Implementation::GetDocument (void)
1051 Image
MasterPageContainer::Implementation::GetPreviewSubstitution (
1053 PreviewSize ePreviewSize
)
1055 const ::osl::MutexGuard
aGuard (maMutex
);
1061 case STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
:
1063 Image
& rPreview (ePreviewSize
==SMALL
1064 ? maSmallPreviewBeingCreated
1065 : maLargePreviewBeingCreated
);
1066 if (rPreview
.GetSizePixel().Width() == 0)
1068 rPreview
= maPreviewRenderer
.RenderSubstitution(
1069 ePreviewSize
==SMALL
? maSmallPreviewSizePixel
: maLargePreviewSizePixel
,
1070 SdResId(STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION
));
1072 aPreview
= rPreview
;
1076 case STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
:
1078 Image
& rPreview (ePreviewSize
==SMALL
1079 ? maSmallPreviewNotAvailable
1080 : maLargePreviewNotAvailable
);
1081 if (rPreview
.GetSizePixel().Width() == 0)
1083 rPreview
= maPreviewRenderer
.RenderSubstitution(
1084 ePreviewSize
==SMALL
? maSmallPreviewSizePixel
: maLargePreviewSizePixel
,
1085 SdResId(STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION
));
1087 aPreview
= rPreview
;
1098 void MasterPageContainer::Implementation::CleanContainer (void)
1100 // Remove the empty elements at the end of the container. The empty
1101 // elements in the middle can not be removed because that would
1102 // invalidate the references still held by others.
1103 int nIndex (maContainer
.size()-1);
1104 while (nIndex
>=0 && maContainer
[nIndex
].get()==NULL
)
1106 maContainer
.resize(++nIndex
);
1112 void MasterPageContainer::Implementation::FireContainerChange (
1113 MasterPageContainerChangeEvent::EventType eType
,
1115 bool bNotifyAsynchronously
)
1117 if (bNotifyAsynchronously
)
1119 Application::PostUserEvent(
1120 LINK(this,Implementation
,AsynchronousNotifyCallback
),
1121 new EventData(eType
,aToken
));
1125 ::std::vector
<Link
> aCopy(maChangeListeners
.begin(),maChangeListeners
.end());
1126 ::std::vector
<Link
>::iterator iListener
;
1127 MasterPageContainerChangeEvent aEvent
;
1128 aEvent
.meEventType
= eType
;
1129 aEvent
.maChildToken
= aToken
;
1130 for (iListener
=aCopy
.begin(); iListener
!=aCopy
.end(); ++iListener
)
1131 iListener
->Call(&aEvent
);
1138 bool MasterPageContainer::Implementation::UpdateDescriptor (
1139 const SharedMasterPageDescriptor
& rpDescriptor
,
1140 bool bForcePageObject
,
1144 const ::osl::MutexGuard
aGuard (maMutex
);
1146 // We have to create the page object when the preview provider needs it
1147 // and the caller needs the preview.
1148 bForcePageObject
|= (bForcePreview
1149 && rpDescriptor
->mpPreviewProvider
->NeedsPageObject()
1150 && rpDescriptor
->mpMasterPage
==NULL
);
1152 // Define a cost threshold so that an update or page object or preview
1153 // that is at least this cost are made at once. Updates with higher cost
1154 // are scheduled for later.
1155 sal_Int32
nCostThreshold (mpRequestQueue
->IsEmpty() ? 5 : 0);
1157 // Update the page object (which may be used for the preview update).
1158 if (bForcePageObject
)
1160 int nPageObjectModified (rpDescriptor
->UpdatePageObject(
1161 (bForcePageObject
? -1 : nCostThreshold
),
1163 if (nPageObjectModified
== 1 && bSendEvents
)
1164 FireContainerChange(
1165 MasterPageContainerChangeEvent::DATA_CHANGED
,
1166 rpDescriptor
->maToken
);
1167 if (nPageObjectModified
== -1 && bSendEvents
)
1168 FireContainerChange(
1169 MasterPageContainerChangeEvent::CHILD_REMOVED
,
1170 rpDescriptor
->maToken
);
1171 if (nPageObjectModified
&& ! mbFirstPageObjectSeen
)
1172 UpdatePreviewSizePixel();
1174 // Update the preview.
1175 bool bPreviewModified (rpDescriptor
->UpdatePreview(
1176 (bForcePreview
? -1 : nCostThreshold
),
1177 maSmallPreviewSizePixel
,
1178 maLargePreviewSizePixel
,
1179 maPreviewRenderer
));
1181 if (bPreviewModified
&& bSendEvents
)
1182 FireContainerChange(
1183 MasterPageContainerChangeEvent::PREVIEW_CHANGED
,
1184 rpDescriptor
->maToken
);
1186 return nPageObjectModified
|| bPreviewModified
;
1192 void MasterPageContainer::Implementation::ReleaseDescriptor (Token aToken
)
1194 if (aToken
>=0 && (unsigned)aToken
<maContainer
.size())
1196 maContainer
[aToken
].reset();
1197 mbContainerCleaningPending
= true;
1204 void MasterPageContainer::Implementation::FillingDone (void)
1206 mpRequestQueue
->ProcessAllRequests();
1211 } } } // end of namespace ::sd::toolpanel::controls
1213 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */