LibreOffice Module sd (master) 1
MasterPageContainer.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21
26#include <PreviewRenderer.hxx>
28#include <strings.hrc>
29#include <algorithm>
30#include <memory>
31
32#include <unomodel.hxx>
33#include <com/sun/star/lang/XMultiServiceFactory.hpp>
34#include <com/sun/star/uno/Reference.hxx>
35#include <com/sun/star/uno/Any.hxx>
36#include <com/sun/star/util/XCloseable.hpp>
37#include <com/sun/star/util/CloseVetoException.hpp>
39#include <drawdoc.hxx>
40#include <sdpage.hxx>
41#include <sdresid.hxx>
43#include <o3tl/safeint.hxx>
44#include <osl/mutex.hxx>
45#include <osl/getglobalmutex.hxx>
46#include <xmloff/autolayout.hxx>
47#include <tools/debug.hxx>
48#include <osl/diagnose.h>
49
50using namespace ::com::sun::star;
51using namespace ::com::sun::star::uno;
52
53namespace {
54
55typedef ::std::vector<sd::sidebar::SharedMasterPageDescriptor> MasterPageContainerType;
56
57} // end of anonymous namespace
58
59namespace sd::sidebar {
60
64 : public SdGlobalResource,
67{
68public:
69 mutable ::osl::Mutex maMutex;
70
71 static std::weak_ptr<Implementation> mpInstance;
72 MasterPageContainerType maContainer;
73
74 static std::shared_ptr<Implementation> Instance();
75
76 void LateInit();
80 const Size& GetPreviewSizePixel (PreviewSize eSize) const;
81
82 bool HasToken (Token aToken) const;
84 virtual Token PutMasterPage (const SharedMasterPageDescriptor& rDescriptor) override;
85 void InvalidatePreview (Token aToken);
87 Token aToken,
88 PreviewSize ePreviewSize);
89 PreviewState GetPreviewState (Token aToken) const;
90 bool RequestPreview (Token aToken);
91
92 Reference<frame::XModel> GetModel();
94
97 Token aToken);
98
99 virtual bool UpdateDescriptor (
100 const SharedMasterPageDescriptor& rpDescriptor,
101 bool bForcePageObject,
102 bool bForcePreview,
103 bool bSendEvents) override;
104
105 void ReleaseDescriptor (Token aToken);
106
110 virtual void FillingDone() override;
111
112private:
114 virtual ~Implementation() override;
115
116 class Deleter { public:
117 void operator() (Implementation* pObject) { delete pObject; }
118 };
119 friend class Deleter;
120
121 enum class InitializationState { NotInitialized, Initializing, Initialized };
123
124 std::unique_ptr<MasterPageContainerQueue> mpRequestQueue;
125 css::uno::Reference<css::frame::XModel> mxModel;
132
133 // The widths for the previews contain two pixels for the border that is
134 // painted around the preview.
135 static const int SMALL_PREVIEW_WIDTH = 72 + 2;
136 static const int LARGE_PREVIEW_WIDTH = 2*72 + 2;
137
143
149
150 ::std::vector<Link<MasterPageContainerChangeEvent&,void>> maChangeListeners;
151
152 // We have to remember the tasks for initialization and filling in case
153 // a MasterPageContainer object is destroyed before these tasks have
154 // been completed.
155 std::weak_ptr<sd::tools::TimerBasedTaskExecution> mpFillerTask;
156
159
161
162 void CleanContainer();
163};
164
165//===== MasterPageContainer ===================================================
166
167std::weak_ptr<MasterPageContainer::Implementation>
169
170std::shared_ptr<MasterPageContainer::Implementation>
172{
173 std::shared_ptr<MasterPageContainer::Implementation> pInstance;
174
175 if (Implementation::mpInstance.expired())
176 {
177 ::osl::GetGlobalMutex aMutexFunctor;
178 ::osl::MutexGuard aGuard (aMutexFunctor());
179 if (Implementation::mpInstance.expired())
180 {
181 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
182 pInstance = std::shared_ptr<MasterPageContainer::Implementation>(
186 Implementation::mpInstance = pInstance;
187 }
188 else
189 pInstance = std::shared_ptr<MasterPageContainer::Implementation>(
191 }
192 else
193 {
194 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
195 pInstance = std::shared_ptr<MasterPageContainer::Implementation>(
197 }
198
199 DBG_ASSERT(pInstance != nullptr,
200 "MasterPageContainer::Implementation::Instance(): instance is nullptr");
201 return pInstance;
202}
203
205 : mpImpl(Implementation::Instance()),
207{
208 mpImpl->LateInit();
209}
210
212{
213}
214
216{
217 mpImpl->AddChangeListener(rLink);
218}
219
221{
222 mpImpl->RemoveChangeListener(rLink);
223}
224
226{
227 mePreviewSize = eSize;
228 mpImpl->FireContainerChange(
230 NIL_TOKEN);
231}
232
234{
235 return mpImpl->GetPreviewSizePixel(mePreviewSize);
236}
237
239 const std::shared_ptr<MasterPageDescriptor>& rDescriptor)
240{
241 return mpImpl->PutMasterPage(rDescriptor);
242}
243
245{
246 SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
247 if (pDescriptor)
248 {
249 ++pDescriptor->mnUseCount;
250 }
251}
252
254{
255 SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
256 if (!pDescriptor)
257 return;
258
259 OSL_ASSERT(pDescriptor->mnUseCount>0);
260 --pDescriptor->mnUseCount;
261 if (pDescriptor->mnUseCount > 0)
262 return;
263
264 switch (pDescriptor->meOrigin)
265 {
266 case DEFAULT:
267 case TEMPLATE:
268 default:
269 break;
270
271 case MASTERPAGE:
272 mpImpl->ReleaseDescriptor(aToken);
273 break;
274 }
275}
276
278{
279 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
280
281 return mpImpl->maContainer.size();
282}
283
285{
286 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
287
288 return mpImpl->HasToken(aToken);
289}
290
292{
293 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
294
295 Token aResult (NIL_TOKEN);
296 if (HasToken(nIndex))
297 aResult = mpImpl->maContainer[nIndex]->maToken;
298 return aResult;
299}
300
302 const OUString& sURL)
303{
304 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
305
306 Token aResult (NIL_TOKEN);
307 if (!sURL.isEmpty())
308 {
309 MasterPageContainerType::iterator iEntry (
310 ::std::find_if (
311 mpImpl->maContainer.begin(),
312 mpImpl->maContainer.end(),
314 if (iEntry != mpImpl->maContainer.end())
315 aResult = (*iEntry)->maToken;
316 }
317 return aResult;
318}
319
321{
322 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
323
324 Token aResult (NIL_TOKEN);
325 if (!sStyleName.isEmpty())
326 {
327 MasterPageContainerType::iterator iEntry (
328 ::std::find_if (
329 mpImpl->maContainer.begin(),
330 mpImpl->maContainer.end(),
332 if (iEntry != mpImpl->maContainer.end())
333 aResult = (*iEntry)->maToken;
334 }
335 return aResult;
336}
337
339 const SdPage* pPage)
340{
341 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
342
343 Token aResult (NIL_TOKEN);
344 if (pPage != nullptr)
345 {
346 MasterPageContainerType::iterator iEntry (
347 ::std::find_if (
348 mpImpl->maContainer.begin(),
349 mpImpl->maContainer.end(),
351 if (iEntry != mpImpl->maContainer.end())
352 aResult = (*iEntry)->maToken;
353 }
354 return aResult;
355}
356
359{
360 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
361
362 SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
363 if (pDescriptor)
364 return pDescriptor->msURL;
365 else
366 return OUString();
367}
368
371{
372 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
373
374 SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
375 if (pDescriptor)
376 return pDescriptor->msPageName;
377 else
378 return OUString();
379}
380
383{
384 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
385
386 SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
387 if (pDescriptor)
388 return pDescriptor->msStyleName;
389 else
390 return OUString();
391}
392
395 bool bLoad)
396{
397 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
398
399 SdPage* pPageObject = nullptr;
400 SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
401 if (pDescriptor)
402 {
403 pPageObject = pDescriptor->mpMasterPage;
404 if (pPageObject == nullptr)
405 {
406 // The page object is not (yet) present. Call
407 // UpdateDescriptor() to trigger the PageObjectProvider() to
408 // provide it.
409 if (bLoad)
410 mpImpl->GetModel();
411 if (mpImpl->UpdateDescriptor(pDescriptor,bLoad,false, true))
412 pPageObject = pDescriptor->mpMasterPage;
413 }
414 }
415 return pPageObject;
416}
417
419{
420 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
421
422 SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
423 if (pDescriptor)
424 return pDescriptor->meOrigin;
425 else
426 return UNKNOWN;
427}
428
430{
431 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
432
433 SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
434 if (pDescriptor)
435 return pDescriptor->mnTemplateIndex;
436 else
437 return -1;
438}
439
440std::shared_ptr<MasterPageDescriptor> MasterPageContainer::GetDescriptorForToken (
442{
443 const ::osl::MutexGuard aGuard (mpImpl->maMutex);
444
445 return mpImpl->GetDescriptor(aToken);
446}
447
449{
450 mpImpl->InvalidatePreview(aToken);
451}
452
454{
455 return mpImpl->GetPreviewForToken(aToken,mePreviewSize);
456}
457
459{
460 return mpImpl->GetPreviewState(aToken);
461}
462
464{
465 return mpImpl->RequestPreview(aToken);
466}
467
468//==== Implementation ================================================
469
471 : meInitializationState(InitializationState::NotInitialized),
472 mpDocument(nullptr),
473 mbFirstPageObjectSeen(false)
474{
476}
477
479{
480 // When the initializer or filler tasks are still running then we have
481 // to stop them now in order to prevent them from calling us back.
483
484 mpRequestQueue.reset();
485
486 uno::Reference<util::XCloseable> xCloseable (mxModel, uno::UNO_QUERY);
487 if (xCloseable.is())
488 {
489 try
490 {
491 xCloseable->close(true);
492 }
493 catch (const css::util::CloseVetoException&)
494 {
495 }
496 }
497 mxModel = nullptr;
498}
499
501{
502 const ::osl::MutexGuard aGuard (maMutex);
503
504 if (meInitializationState != InitializationState::NotInitialized)
505 return;
506
507 meInitializationState = InitializationState::Initializing;
508
509 OSL_ASSERT(Instance().get()==this);
510 mpRequestQueue.reset(MasterPageContainerQueue::Create(
511 std::shared_ptr<MasterPageContainerQueue::ContainerAdapter>(Instance())));
512
514 std::make_shared<MasterPageContainerFiller>(*this),
515 5,
516 50);
517
518 meInitializationState = InitializationState::Initialized;
519}
520
522{
523 const ::osl::MutexGuard aGuard (maMutex);
524
525 ::std::vector<Link<MasterPageContainerChangeEvent&,void>>::iterator iListener (
526 ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink));
527 if (iListener == maChangeListeners.end())
528 maChangeListeners.push_back(rLink);
529
530}
531
533{
534 const ::osl::MutexGuard aGuard (maMutex);
535
536 ::std::vector<Link<MasterPageContainerChangeEvent&,void>>::iterator iListener (
537 ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink));
538 if (iListener != maChangeListeners.end())
539 maChangeListeners.erase(iListener);
540}
541
543{
544 const ::osl::MutexGuard aGuard (maMutex);
545
546 // The default aspect ratio is 4:3
547 int nWidth (4);
548 int nHeight (3);
549
550 // Search for the first entry with an existing master page.
551 auto iDescriptor = std::find_if(maContainer.begin(), maContainer.end(),
552 [](const SharedMasterPageDescriptor& rxDescriptor) {
553 return rxDescriptor != nullptr && rxDescriptor->mpMasterPage != nullptr;
554 });
555 if (iDescriptor != maContainer.end())
556 {
557 Size aPageSize ((*iDescriptor)->mpMasterPage->GetSize());
558 OSL_ASSERT(!aPageSize.IsEmpty());
559 if (aPageSize.Width() > 0)
560 nWidth = aPageSize.Width();
561 if (aPageSize.Height() > 0)
562 nHeight = aPageSize.Height();
563 mbFirstPageObjectSeen = true;
564 }
565
566 maSmallPreviewSizePixel.setWidth( SMALL_PREVIEW_WIDTH );
567 maLargePreviewSizePixel.setWidth( LARGE_PREVIEW_WIDTH );
568
569 int nNewSmallHeight ((maSmallPreviewSizePixel.Width()-2) * nHeight / nWidth + 2);
570 int nNewLargeHeight ((maLargePreviewSizePixel.Width()-2) * nHeight / nWidth + 2);
571
572 if (nNewSmallHeight!=maSmallPreviewSizePixel.Height()
573 || nNewLargeHeight!=maLargePreviewSizePixel.Height())
574 {
575 maSmallPreviewSizePixel.setHeight( nNewSmallHeight );
576 maLargePreviewSizePixel.setHeight( nNewLargeHeight );
577 FireContainerChange(
579 NIL_TOKEN);
580 }
581}
582
584{
585 if (eSize == SMALL)
586 return maSmallPreviewSizePixel;
587 else
588 return maLargePreviewSizePixel;
589}
590
592 const SharedMasterPageDescriptor& rpDescriptor)
593{
594 const ::osl::MutexGuard aGuard (maMutex);
595
596 Token aResult (NIL_TOKEN);
597
598 // Get page object and preview when that is inexpensive.
599 UpdateDescriptor(rpDescriptor,false,false, false);
600
601 // Look up the new MasterPageDescriptor and either insert it or update
602 // an already existing one.
603 MasterPageContainerType::iterator aEntry (
604 ::std::find_if (
605 maContainer.begin(),
606 maContainer.end(),
608 if (aEntry == maContainer.end())
609 {
610 // Insert a new MasterPageDescriptor.
611 bool bIgnore(rpDescriptor->mpPageObjectProvider == nullptr
612 && rpDescriptor->msURL.isEmpty());
613
614 if ( ! bIgnore)
615 {
616 CleanContainer();
617
618 aResult = maContainer.size();
619 rpDescriptor->SetToken(aResult);
620
621 // Templates are precious, i.e. we lock them so that they will
622 // not be destroyed when (temporarily) no one references them.
623 // They will only be deleted when the container is destroyed.
624 switch (rpDescriptor->meOrigin)
625 {
626 case TEMPLATE:
627 case DEFAULT:
628 ++rpDescriptor->mnUseCount;
629 break;
630
631 default:
632 break;
633 }
634
635 maContainer.push_back(rpDescriptor);
636 aEntry = maContainer.end()-1;
637
639 }
640 }
641 else
642 {
643 // Update an existing MasterPageDescriptor.
644 aResult = (*aEntry)->maToken;
645 std::unique_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pEventTypes(
646 (*aEntry)->Update(*rpDescriptor));
647 if (pEventTypes != nullptr && !pEventTypes->empty())
648 {
649 // One or more aspects of the descriptor have changed. Send
650 // appropriate events to the listeners.
651 UpdateDescriptor(*aEntry,false,false, true);
652
653 for (const auto& rEventType : *pEventTypes)
654 {
655 FireContainerChange(rEventType, (*aEntry)->maToken);
656 }
657 }
658 }
659
660 return aResult;
661}
662
664{
665 return aToken>=0
666 && o3tl::make_unsigned(aToken)<maContainer.size()
667 && maContainer[aToken];
668}
669
671{
672 if (aToken>=0 && o3tl::make_unsigned(aToken)<maContainer.size())
673 return maContainer[aToken];
674 else
676}
677
679{
680 const ::osl::MutexGuard aGuard (maMutex);
681
682 SharedMasterPageDescriptor pDescriptor (GetDescriptor(aToken));
683 if (pDescriptor)
684 {
685 pDescriptor->maSmallPreview = Image();
686 pDescriptor->maLargePreview = Image();
687 RequestPreview(aToken);
688 }
689}
690
693 PreviewSize ePreviewSize)
694{
695 const ::osl::MutexGuard aGuard (maMutex);
696
697 Image aPreview;
698 PreviewState ePreviewState (GetPreviewState(aToken));
699
700 SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
701
702 // When the preview is missing but inexpensively creatable then do that
703 // now.
704 if (pDescriptor)
705 {
706 if (ePreviewState == PS_CREATABLE)
707 if (UpdateDescriptor(pDescriptor, false,false, true))
708 if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0)
709 ePreviewState = PS_AVAILABLE;
710
711 switch (ePreviewState)
712 {
713 case PS_AVAILABLE:
714 aPreview = pDescriptor->GetPreview(ePreviewSize);
715 break;
716
717 case PS_PREPARING:
718 aPreview = GetPreviewSubstitution(
719 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
720 ePreviewSize);
721 break;
722
723 case PS_CREATABLE:
724 aPreview = GetPreviewSubstitution(
725 STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
726 ePreviewSize);
727 break;
728
729 case PS_NOT_AVAILABLE:
730 aPreview = GetPreviewSubstitution(
731 STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION,
732 ePreviewSize);
733 if (ePreviewSize == SMALL)
734 pDescriptor->maSmallPreview = aPreview;
735 else
736 pDescriptor->maLargePreview = aPreview;
737 break;
738 }
739 }
740
741 return aPreview;
742}
743
745 Token aToken) const
746{
747 const ::osl::MutexGuard aGuard (maMutex);
748
750
751 SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
752 if (pDescriptor)
753 {
754 if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0)
755 eState = PS_AVAILABLE;
756 else if (pDescriptor->mpPreviewProvider != nullptr)
757 {
758 // The preview does not exist but can be created. When that is
759 // not expensive then do it at once.
760 if (mpRequestQueue->HasRequest(aToken))
761 eState = PS_PREPARING;
762 else
763 eState = PS_CREATABLE;
764 }
765 else
766 eState = PS_NOT_AVAILABLE;
767 }
768
769 return eState;
770}
771
773{
774 SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
775 if (pDescriptor)
776 return mpRequestQueue->RequestPreview(pDescriptor);
777 else
778 return false;
779}
780
782{
783 const ::osl::MutexGuard aGuard (maMutex);
784
785 if ( ! mxModel.is())
786 {
787 // Create a new model.
788 mxModel.set(
789 ::comphelper::getProcessServiceFactory()->createInstance(
790 "com.sun.star.presentation.PresentationDocument"),
791 uno::UNO_QUERY);
792
793 // Initialize the model.
794 uno::Reference<frame::XLoadable> xLoadable (mxModel,uno::UNO_QUERY);
795 if (xLoadable.is())
796 xLoadable->initNew();
797
798 // Use its tunnel to get a pointer to its core implementation.
799 uno::Reference<lang::XUnoTunnel> xUnoTunnel (mxModel, uno::UNO_QUERY);
800 if (auto pSdXImpressDocument = comphelper::getFromUnoTunnel<SdXImpressDocument>(xUnoTunnel))
801 {
802 mpDocument = pSdXImpressDocument->GetDoc();
803 }
804
805 // Create a default page.
806 uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier (mxModel, uno::UNO_QUERY);
807 if (xSlideSupplier.is())
808 {
809 uno::Reference<drawing::XDrawPages> xSlides =
810 xSlideSupplier->getDrawPages();
811 if (xSlides.is())
812 {
813 uno::Reference<drawing::XDrawPage> xNewPage (xSlides->insertNewByIndex(0));
814 uno::Reference<beans::XPropertySet> xProperties(xNewPage, uno::UNO_QUERY);
815 if (xProperties.is())
816 xProperties->setPropertyValue(
817 "Layout",
818 Any(sal_Int16(AUTOLAYOUT_TITLE)));
819 }
820 }
821 }
822 return mxModel;
823}
824
826{
827 GetModel();
828 return mpDocument;
829}
830
832 TranslateId pId,
833 PreviewSize ePreviewSize)
834{
835 const ::osl::MutexGuard aGuard (maMutex);
836
837 Image aPreview;
838
839 if (pId == STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION)
840 {
841 Image& rPreview (ePreviewSize==SMALL
842 ? maSmallPreviewBeingCreated
843 : maLargePreviewBeingCreated);
844 if (rPreview.GetSizePixel().Width() == 0)
845 {
846 rPreview = maPreviewRenderer.RenderSubstitution(
847 ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel,
848 SdResId(STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION));
849 }
850 aPreview = rPreview;
851 }
852 else if (pId == STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION)
853 {
854 Image& rPreview (ePreviewSize==SMALL
855 ? maSmallPreviewNotAvailable
856 : maLargePreviewNotAvailable);
857 if (rPreview.GetSizePixel().Width() == 0)
858 {
859 rPreview = maPreviewRenderer.RenderSubstitution(
860 ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel,
861 SdResId(STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION));
862 }
863 aPreview = rPreview;
864 }
865
866 return aPreview;
867}
868
870{
871 // Remove the empty elements at the end of the container. The empty
872 // elements in the middle can not be removed because that would
873 // invalidate the references still held by others.
874 int nIndex (maContainer.size()-1);
875 while (nIndex>=0 && !maContainer[nIndex])
876 --nIndex;
877 maContainer.resize(++nIndex);
878}
879
882 Token aToken)
883{
884 ::std::vector<Link<MasterPageContainerChangeEvent&,void>> aCopy(maChangeListeners);
886 aEvent.meEventType = eType;
887 aEvent.maChildToken = aToken;
888 for (const auto& rListener : aCopy)
889 rListener.Call(aEvent);
890}
891
893 const SharedMasterPageDescriptor& rpDescriptor,
894 bool bForcePageObject,
895 bool bForcePreview,
896 bool bSendEvents)
897{
898 const ::osl::MutexGuard aGuard (maMutex);
899
900 // We have to create the page object when the preview provider needs it
901 // and the caller needs the preview.
902 bForcePageObject |= (bForcePreview
903 && rpDescriptor->mpPreviewProvider->NeedsPageObject()
904 && rpDescriptor->mpMasterPage==nullptr);
905
906 // Define a cost threshold so that an update or page object or preview
907 // that is at least this cost are made at once. Updates with higher cost
908 // are scheduled for later.
909 sal_Int32 nCostThreshold (mpRequestQueue->IsEmpty() ? 5 : 0);
910
911 // Update the page object (which may be used for the preview update).
912 if (bForcePageObject)
913 GetDocument();
914 int nPageObjectModified (rpDescriptor->UpdatePageObject(
915 (bForcePageObject ? -1 : nCostThreshold),
916 mpDocument));
917 if (nPageObjectModified == 1 && bSendEvents)
918 FireContainerChange(
920 rpDescriptor->maToken);
921 if (nPageObjectModified == -1 && bSendEvents)
922 FireContainerChange(
924 rpDescriptor->maToken);
925 if (nPageObjectModified && ! mbFirstPageObjectSeen)
926 UpdatePreviewSizePixel();
927
928 // Update the preview.
929 bool bPreviewModified (rpDescriptor->UpdatePreview(
930 (bForcePreview ? -1 : nCostThreshold),
931 maSmallPreviewSizePixel,
932 maLargePreviewSizePixel,
933 maPreviewRenderer));
934
935 if (bPreviewModified && bSendEvents)
936 FireContainerChange(
938 rpDescriptor->maToken);
939
940 return nPageObjectModified || bPreviewModified;
941}
942
944{
945 if (aToken>=0 && o3tl::make_unsigned(aToken)<maContainer.size())
946 {
947 maContainer[aToken].reset();
948 }
949}
950
952{
953 mpRequestQueue->ProcessAllRequests();
954}
955
956} // end of namespace sd::sidebar
957
958/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::frame::XModel2 > mxModel
std::mutex maMutex
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
AnyEventRef aEvent
AUTOLAYOUT_TITLE
Size GetSizePixel() const
bool IsEmpty() const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
void AddResource(::std::unique_ptr< SdGlobalResource > pResource)
Add a resource to the container.
static SdGlobalResourceContainer & Instance()
For some changes to the set of master pages in a MasterPageContainer or to the data stored for each m...
static MasterPageContainerQueue * Create(const std::weak_ptr< ContainerAdapter > &rpContainer)
Inner implementation class of the MasterPageContainer.
void RemoveChangeListener(const Link< MasterPageContainerChangeEvent &, void > &rLink)
void FireContainerChange(MasterPageContainerChangeEvent::EventType eType, Token aToken)
css::uno::Reference< css::frame::XModel > mxModel
::std::vector< Link< MasterPageContainerChangeEvent &, void > > maChangeListeners
std::weak_ptr< sd::tools::TimerBasedTaskExecution > mpFillerTask
Image GetPreviewForToken(Token aToken, PreviewSize ePreviewSize)
const Size & GetPreviewSizePixel(PreviewSize eSize) const
std::unique_ptr< MasterPageContainerQueue > mpRequestQueue
SharedMasterPageDescriptor GetDescriptor(MasterPageContainer::Token aToken) const
virtual Token PutMasterPage(const SharedMasterPageDescriptor &rDescriptor) override
static std::shared_ptr< Implementation > Instance()
static std::weak_ptr< Implementation > mpInstance
Image maLargePreviewNotAvailable
This substitution of page preview is shown when a preview can not be created and thus is not availabl...
void AddChangeListener(const Link< MasterPageContainerChangeEvent &, void > &rLink)
bool mbFirstPageObjectSeen
Remember whether the first page object has already been used to determine the correct size ratio.
Image maLargePreviewBeingCreated
This substitution of page preview shows "Preparing preview" and is shown as long as the actual previe...
virtual void FillingDone() override
Called by the MasterPageContainerFiller to notify that all master pages from template documents have ...
Image GetPreviewSubstitution(TranslateId pId, PreviewSize ePreviewSize)
virtual bool UpdateDescriptor(const SharedMasterPageDescriptor &rpDescriptor, bool bForcePageObject, bool bForcePreview, bool bSendEvents) override
sal_Int32 GetTemplateIndexForToken(Token aToken)
Token PutMasterPage(const std::shared_ptr< MasterPageDescriptor > &rDescriptor)
Put the master page identified and described by the given parameters into the container.
void RemoveChangeListener(const Link< MasterPageContainerChangeEvent &, void > &rLink)
std::shared_ptr< Implementation > mpImpl
void SetPreviewSize(PreviewSize eSize)
There are two different preview sizes, a small one and a large one.
int GetTokenCount() const
This and the GetTokenForIndex() methods can be used to iterate over all members of the container.
Image GetPreviewForToken(Token aToken)
Return a preview for the specified token.
Size const & GetPreviewSizePixel() const
Return the preview size in pixels.
Token GetTokenForStyleName(const OUString &sStyleName)
Token GetTokenForURL(const OUString &sURL)
OUString GetPageNameForToken(Token aToken)
Token GetTokenForPageObject(const SdPage *pPage)
SdPage * GetPageObjectForToken(Token aToken, bool bLoad)
PreviewState GetPreviewState(Token aToken)
std::shared_ptr< MasterPageDescriptor > GetDescriptorForToken(Token aToken)
Token GetTokenForIndex(int nIndex)
Return a token for an index in the range 0 <= index < GetTokenCount().
bool HasToken(Token aToken) const
Determine whether the container has a member for the given token.
void AddChangeListener(const Link< MasterPageContainerChangeEvent &, void > &rLink)
bool RequestPreview(Token aToken)
This method is typically called for entries in the container for which GetPreviewState() returns OS_C...
Origin
Each entry of the container is either the first page of a template document or is a master page of an...
OUString GetStyleNameForToken(Token aToken)
static void ReleaseTask(const std::weak_ptr< TimerBasedTaskExecution > &rpTask)
Convenience method that calls Release() on the given task.
static std::shared_ptr< TimerBasedTaskExecution > Create(const std::shared_ptr< AsynchronousTask > &rpTask, sal_uInt32 nMillisecondsBetweenSteps, sal_uInt32 nMaxTimePerStep)
Create a new object of this class.
#define DBG_ASSERT(sCon, aError)
EmbeddedObjectRef * pObject
DocumentType eType
sal_Int32 nIndex
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::shared_ptr< MasterPageDescriptor > SharedMasterPageDescriptor
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
OUString SdResId(TranslateId aId)
Definition: sdmod.cxx:83