fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / sd / source / ui / toolpanel / controls / MasterPageContainer.cxx
blob1a59444fe92d8edfe3984dff889d7928fdab380a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
29 #include <algorithm>
30 #include <list>
31 #include <set>
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"
49 #include "sdpage.hxx"
50 #include <svl/itemset.hxx>
51 #include <svl/eitem.hxx>
52 #include "sdresid.hxx"
53 #include "tools/TimerBasedTaskExecution.hxx"
54 #include "pres.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;
62 namespace {
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
79 public:
80 mutable ::osl::Mutex maMutex;
82 static ::boost::weak_ptr<Implementation> mpInstance;
83 MasterPageContainerType maContainer;
85 static ::boost::shared_ptr<Implementation> Instance (void);
87 void LateInit (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 (
99 Token aToken,
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,
109 Token aToken,
110 bool bNotifyAsynchronously = false);
112 virtual bool UpdateDescriptor (
113 const SharedMasterPageDescriptor& rpDescriptor,
114 bool bForcePageObject,
115 bool bForcePreview,
116 bool bSendEvents);
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);
125 private:
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
166 // been completed.
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;
216 else
217 pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>(
218 Implementation::mpInstance);
220 else
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");
229 return pInstance;
235 MasterPageContainer::MasterPageContainer (void)
236 : mpImpl(Implementation::Instance()),
237 mePreviewSize(SMALL)
239 mpImpl->LateInit();
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,
273 NIL_TOKEN);
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)
327 case DEFAULT:
328 case TEMPLATE:
329 default:
330 break;
332 case MASTERPAGE:
333 mpImpl->ReleaseDescriptor(aToken);
334 break;
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;
370 return aResult;
376 MasterPageContainer::Token MasterPageContainer::GetTokenForURL (
377 const String& sURL)
379 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
381 Token aResult (NIL_TOKEN);
382 if (sURL.Len() > 0)
384 MasterPageContainerType::iterator iEntry (
385 ::std::find_if (
386 mpImpl->maContainer.begin(),
387 mpImpl->maContainer.end(),
388 MasterPageDescriptor::URLComparator(sURL)));
389 if (iEntry != mpImpl->maContainer.end())
390 aResult = (*iEntry)->maToken;
392 return aResult;
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 (
406 ::std::find_if (
407 mpImpl->maContainer.begin(),
408 mpImpl->maContainer.end(),
409 MasterPageDescriptor::StyleNameComparator(sStyleName)));
410 if (iEntry != mpImpl->maContainer.end())
411 aResult = (*iEntry)->maToken;
413 return aResult;
419 MasterPageContainer::Token MasterPageContainer::GetTokenForPageObject (
420 const SdPage* pPage)
422 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
424 Token aResult (NIL_TOKEN);
425 if (pPage != NULL)
427 MasterPageContainerType::iterator iEntry (
428 ::std::find_if (
429 mpImpl->maContainer.begin(),
430 mpImpl->maContainer.end(),
431 MasterPageDescriptor::PageObjectComparator(pPage)));
432 if (iEntry != mpImpl->maContainer.end())
433 aResult = (*iEntry)->maToken;
435 return aResult;
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;
449 else
450 return String();
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;
464 else
465 return String();
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;
479 else
480 return String();
486 SdPage* MasterPageContainer::GetPageObjectForToken (
487 MasterPageContainer::Token aToken,
488 bool bLoad)
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
501 // provide it.
502 if (bLoad)
503 mpImpl->GetModel();
504 if (mpImpl->UpdateDescriptor(pDescriptor,bLoad,false, true))
505 pPageObject = pDescriptor->mpMasterPage;
508 return pPageObject;
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;
521 else
522 return UNKNOWN;
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;
535 else
536 return -1;
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)
587 : maMutex(),
588 maContainer(),
589 meInitializationState(NOT_INITIALIZED),
590 mpRequestQueue(NULL),
591 mxModel(NULL),
592 mpDocument(NULL),
593 maPreviewRenderer(),
594 mbFirstPageObjectSeen(false),
595 maLargePreviewBeingCreated(),
596 maSmallPreviewBeingCreated(),
597 maLargePreviewNotAvailable(),
598 maSmallPreviewNotAvailable(),
599 maChangeListeners(),
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);
621 if (xCloseable.is())
625 xCloseable->close(true);
627 catch (const ::com::sun::star::util::CloseVetoException&)
631 mxModel = NULL;
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)),
652 50);
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
693 int nWidth (4);
694 int nHeight (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;
709 break;
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;
723 FireContainerChange(
724 MasterPageContainerChangeEvent::SIZE_CHANGED,
725 NIL_TOKEN);
732 Size MasterPageContainer::Implementation::GetPreviewSizePixel (PreviewSize eSize) const
734 if (eSize == SMALL)
735 return maSmallPreviewSizePixel;
736 else
737 return maLargePreviewSizePixel;
743 IMPL_LINK(MasterPageContainer::Implementation,AsynchronousNotifyCallback, EventData*, pData)
745 const ::osl::MutexGuard aGuard (maMutex);
747 if (pData != NULL)
749 FireContainerChange(pData->first, pData->second, false);
750 delete pData;
753 return 0;
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 (
772 ::std::find_if (
773 maContainer.begin(),
774 maContainer.end(),
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());
782 if ( ! bIgnore)
784 if (mbContainerCleaningPending)
785 CleanContainer();
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)
795 case TEMPLATE:
796 case DEFAULT:
797 ++rpDescriptor->mnUseCount;
798 break;
800 default:
801 break;
804 maContainer.push_back(rpDescriptor);
805 aEntry = maContainer.end()-1;
807 FireContainerChange(MasterPageContainerChangeEvent::CHILD_ADDED,aResult);
810 else
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)
825 FireContainerChange(
826 *iEventType,
827 (*aEntry)->maToken,
828 false);
833 return aResult;
839 bool MasterPageContainer::Implementation::HasToken (Token aToken) const
841 return aToken>=0
842 && (unsigned)aToken<maContainer.size()
843 && maContainer[aToken].get()!=NULL;
849 const SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor (
850 Token aToken) const
852 if (aToken>=0 && (unsigned)aToken<maContainer.size())
853 return maContainer[aToken];
854 else
855 return SharedMasterPageDescriptor();
861 SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor (Token aToken)
863 if (aToken>=0 && (unsigned)aToken<maContainer.size())
864 return maContainer[aToken];
865 else
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);
894 Image aPreview;
895 PreviewState ePreviewState (GetPreviewState(aToken));
897 SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
899 // When the preview is missing but inexpensively creatable then do that
900 // now.
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)
910 case PS_AVAILABLE:
911 aPreview = pDescriptor->GetPreview(ePreviewSize);
912 break;
914 case PS_PREPARING:
915 aPreview = GetPreviewSubstitution(
916 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
917 ePreviewSize);
918 break;
920 case PS_CREATABLE:
921 aPreview = GetPreviewSubstitution(
922 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
923 ePreviewSize);
924 break;
926 case PS_NOT_AVAILABLE:
927 aPreview = GetPreviewSubstitution(
928 STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION,
929 ePreviewSize);
930 if (ePreviewSize == SMALL)
931 pDescriptor->maSmallPreview = aPreview;
932 else
933 pDescriptor->maLargePreview = aPreview;
934 break;
938 return aPreview;
944 MasterPageContainer::PreviewState MasterPageContainer::Implementation::GetPreviewState (
945 Token aToken) const
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;
962 else
963 eState = PS_CREATABLE;
965 else
966 eState = PS_NOT_AVAILABLE;
969 return eState;
975 bool MasterPageContainer::Implementation::RequestPreview (Token aToken)
977 SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
978 if (pDescriptor.get() != NULL)
979 return mpRequestQueue->RequestPreview(pDescriptor);
980 else
981 return false;
987 Reference<frame::XModel> MasterPageContainer::Implementation::GetModel (void)
989 const ::osl::MutexGuard aGuard (maMutex);
991 if ( ! mxModel.is())
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(
1001 sModelServiceName),
1002 uno::UNO_QUERY);
1004 // Initialize the model.
1005 uno::Reference<frame::XLoadable> xLoadable (mxModel,uno::UNO_QUERY);
1006 if (xLoadable.is())
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);
1024 if (xSlides.is())
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(
1031 "Layout",
1032 makeAny((sal_Int16)AUTOLAYOUT_TITLE));
1036 return mxModel;
1042 SdDrawDocument* MasterPageContainer::Implementation::GetDocument (void)
1044 GetModel();
1045 return mpDocument;
1051 Image MasterPageContainer::Implementation::GetPreviewSubstitution (
1052 sal_uInt16 nId,
1053 PreviewSize ePreviewSize)
1055 const ::osl::MutexGuard aGuard (maMutex);
1057 Image aPreview;
1059 switch (nId)
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;
1074 break;
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;
1089 break;
1092 return aPreview;
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)
1105 --nIndex;
1106 maContainer.resize(++nIndex);
1112 void MasterPageContainer::Implementation::FireContainerChange (
1113 MasterPageContainerChangeEvent::EventType eType,
1114 Token aToken,
1115 bool bNotifyAsynchronously)
1117 if (bNotifyAsynchronously)
1119 Application::PostUserEvent(
1120 LINK(this,Implementation,AsynchronousNotifyCallback),
1121 new EventData(eType,aToken));
1123 else
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,
1141 bool bForcePreview,
1142 bool bSendEvents)
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)
1159 GetDocument();
1160 int nPageObjectModified (rpDescriptor->UpdatePageObject(
1161 (bForcePageObject ? -1 : nCostThreshold),
1162 mpDocument));
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: */