Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sd/source/ui/sidebar/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 29 kB image not shown  

Quelle  MasterPageContainer.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include "MasterPageContainer.hxx"

#include "MasterPageContainerProviders.hxx"
#include "MasterPageDescriptor.hxx"
#include "MasterPageContainerFiller.hxx"
#include "MasterPageContainerQueue.hxx"
#include <PreviewRenderer.hxx>
#include <tools/SdGlobalResourceContainer.hxx>
#include <strings.hrc>
#include <algorithm>
#include <memory>

#include <unomodel.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/util/CloseVetoException.hpp>
#include <comphelper/processfactory.hxx>
#include <drawdoc.hxx>
#include <sdpage.hxx>
#include <sdresid.hxx>
#include <tools/TimerBasedTaskExecution.hxx>
#include <o3tl/safeint.hxx>
#include <osl/mutex.hxx>
#include <osl/getglobalmutex.hxx>
#include <xmloff/autolayout.hxx>
#include <tools/debug.hxx>
#include <osl/diagnose.h>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

namespace {

typedef ::std::vector<sd::sidebar::SharedMasterPageDescriptor> MasterPageContainerType;

// end of anonymous namespace

namespace sd::sidebar {

/** Inner implementation class of the MasterPageContainer.
*/

class MasterPageContainer::Implementation
    : public SdGlobalResource,
      public MasterPageContainerFiller::ContainerAdapter,
      public MasterPageContainerQueue::ContainerAdapter
{
public:
    mutable ::osl::Mutex maMutex;

    static std::weak_ptr<Implementation> mpInstance;
    MasterPageContainerType maContainer;

    static std::shared_ptr<Implementation> Instance();

    void LateInit();
    void AddChangeListener (const Link<MasterPageContainerChangeEvent&,void>& rLink);
    void RemoveChangeListener (const Link<MasterPageContainerChangeEvent&,void>& rLink);
    void UpdatePreviewSizePixel();

    bool HasToken (Token aToken) const;
    SharedMasterPageDescriptor GetDescriptor (MasterPageContainer::Token aToken) const;
    virtual Token PutMasterPage (const SharedMasterPageDescriptor& rDescriptor) override;
    void InvalidatePreview (Token aToken);
    Image GetPreviewForToken (
        Token aToken,
        PreviewSize ePreviewSize);
    PreviewState GetPreviewState (Token aToken) const;
    bool RequestPreview (Token aToken);

    Reference<frame::XModel> GetModel();
    SdDrawDocument* GetDocument();

    void FireContainerChange (
        MasterPageContainerChangeEvent::EventType eType,
        Token aToken);

    virtual bool UpdateDescriptor (
        const SharedMasterPageDescriptor& rpDescriptor,
        bool bForcePageObject,
        bool bForcePreview,
        bool bSendEvents) override;

    void ReleaseDescriptor (Token aToken);

    const Size& GetPreviewSizePixel(PreviewSize pPreviewSize);

    /** Called by the MasterPageContainerFiller to notify that all master
        pages from template documents have been added.
    */

    virtual void FillingDone() override;

private:
    Implementation();
    virtual ~Implementation() override;

    class Deleter { public:
        void operator() (Implementation* pObject) { delete pObject; }
    };
    friend class Deleter;

    enum class InitializationState { NotInitialized, Initializing, Initialized };
    InitializationState meInitializationState;

    std::unique_ptr<MasterPageContainerQueue> mpRequestQueue;
    css::uno::Reference<css::frame::XModel> mxModel;
    SdDrawDocument* mpDocument;
    PreviewRenderer maPreviewRenderer;
    /** Remember whether the first page object has already been used to
        determine the correct size ratio.
    */

    bool mbFirstPageObjectSeen;

    // The widths for the previews contain two pixels for the border that is
    // painted around the preview.
    static const int SMALL_PREVIEW_WIDTH = 72 + 2;
    static const int LARGE_PREVIEW_WIDTH = 2*72 + 2;

    /** This substitution of page preview shows "Preparing preview" and is
        shown as long as the actual previews are not being present.
    */

    Image maLargePreviewBeingCreated;
    Image maSmallPreviewBeingCreated;

    /** This substitution of page preview is shown when a preview can not be
        created and thus is not available.
    */

    Image maLargePreviewNotAvailable;
    Image maSmallPreviewNotAvailable;

    ::std::vector<Link<MasterPageContainerChangeEvent&,void>> maChangeListeners;

    // We have to remember the tasks for initialization and filling in case
    // a MasterPageContainer object is destroyed before these tasks have
    // been completed.
    std::weak_ptr<sd::tools::TimerBasedTaskExecution> mpFillerTask;

    Size maSmallPreviewSizePixel;
    Size maLargePreviewSizePixel;

    Image GetPreviewSubstitution(TranslateId pId, PreviewSize ePreviewSize);

    void CleanContainer();
};

//===== MasterPageContainer ===================================================

std::weak_ptr<MasterPageContainer::Implementation>
    MasterPageContainer::Implementation::mpInstance;

std::shared_ptr<MasterPageContainer::Implementation>
    MasterPageContainer::Implementation::Instance()
{
    std::shared_ptr<MasterPageContainer::Implementation> pInstance;

    if (Implementation::mpInstance.expired())
    {
        ::osl::GetGlobalMutex aMutexFunctor;
        ::osl::MutexGuard aGuard (aMutexFunctor());
        if (Implementation::mpInstance.expired())
        {
            OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
            pInstance = std::shared_ptr<MasterPageContainer::Implementation>(
                new MasterPageContainer::Implementation(),
                MasterPageContainer::Implementation::Deleter());
            SdGlobalResourceContainer::Instance().AddResource(pInstance);
            Implementation::mpInstance = pInstance;
        }
        else
            pInstance = std::shared_ptr<MasterPageContainer::Implementation>(
                Implementation::mpInstance);
    }
    else
    {
        OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
        pInstance = std::shared_ptr<MasterPageContainer::Implementation>(
            Implementation::mpInstance);
    }

    DBG_ASSERT(pInstance != nullptr,
               "MasterPageContainer::Implementation::Instance(): instance is nullptr");
    return pInstance;
}

MasterPageContainer::MasterPageContainer()
    : mpImpl(Implementation::Instance()),
      mePreviewSize(SMALL)
{
    mpImpl->LateInit();
}

MasterPageContainer::~MasterPageContainer()
{
}

void MasterPageContainer::AddChangeListener (const Link<MasterPageContainerChangeEvent&,void>& rLink)
{
    mpImpl->AddChangeListener(rLink);
}

void MasterPageContainer::RemoveChangeListener (const Link<MasterPageContainerChangeEvent&,void>& rLink)
{
    mpImpl->RemoveChangeListener(rLink);
}

void MasterPageContainer::SetPreviewSize (PreviewSize eSize)
{
    mePreviewSize = eSize;
    mpImpl->FireContainerChange(
        MasterPageContainerChangeEvent::EventType::SIZE_CHANGED,
        NIL_TOKEN);
}

MasterPageContainer::Token MasterPageContainer::PutMasterPage (
    const std::shared_ptr<MasterPageDescriptor>& rDescriptor)
{
    return mpImpl->PutMasterPage(rDescriptor);
}

void MasterPageContainer::AcquireToken (Token aToken)
{
    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor)
    {
        ++pDescriptor->mnUseCount;
    }
}

void MasterPageContainer::ReleaseToken (Token aToken)
{
    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (!pDescriptor)
        return;

    OSL_ASSERT(pDescriptor->mnUseCount>0);
    --pDescriptor->mnUseCount;
    if (pDescriptor->mnUseCount > 0)
        return;

    switch (pDescriptor->meOrigin)
    {
        case DEFAULT:
        case TEMPLATE:
        default:
            break;

        case MASTERPAGE:
            mpImpl->ReleaseDescriptor(aToken);
            break;
    }
}

int MasterPageContainer::GetTokenCount() const
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    return mpImpl->maContainer.size();
}

bool MasterPageContainer::HasToken (Token aToken) const
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    return mpImpl->HasToken(aToken);
}

MasterPageContainer::Token MasterPageContainer::GetTokenForIndex (int nIndex)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    Token aResult (NIL_TOKEN);
    if (HasToken(nIndex))
        aResult = mpImpl->maContainer[nIndex]->maToken;
    return aResult;
}

MasterPageContainer::Token MasterPageContainer::GetTokenForURL (
    const OUString& sURL)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    Token aResult (NIL_TOKEN);
    if (!sURL.isEmpty())
    {
        MasterPageContainerType::iterator iEntry (
            ::std::find_if (
                mpImpl->maContainer.begin(),
                mpImpl->maContainer.end(),
                MasterPageDescriptor::URLComparator(sURL)));
        if (iEntry != mpImpl->maContainer.end())
            aResult = (*iEntry)->maToken;
    }
    return aResult;
}

MasterPageContainer::Token MasterPageContainer::GetTokenForStyleName (const OUString& sStyleName)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    Token aResult (NIL_TOKEN);
    if (!sStyleName.isEmpty())
    {
        MasterPageContainerType::iterator iEntry (
            ::std::find_if (
                mpImpl->maContainer.begin(),
                mpImpl->maContainer.end(),
                MasterPageDescriptor::StyleNameComparator(sStyleName)));
        if (iEntry != mpImpl->maContainer.end())
            aResult = (*iEntry)->maToken;
    }
    return aResult;
}

MasterPageContainer::Token MasterPageContainer::GetTokenForPageObject (
    const SdPage* pPage)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    Token aResult (NIL_TOKEN);
    if (pPage != nullptr)
    {
        MasterPageContainerType::iterator iEntry (
            ::std::find_if (
                mpImpl->maContainer.begin(),
                mpImpl->maContainer.end(),
                MasterPageDescriptor::PageObjectComparator(pPage)));
        if (iEntry != mpImpl->maContainer.end())
            aResult = (*iEntry)->maToken;
    }
    return aResult;
}

OUString MasterPageContainer::GetURLForToken (
    MasterPageContainer::Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor)
        return pDescriptor->msURL;
    else
        return OUString();
}

OUString MasterPageContainer::GetPageNameForToken (
    MasterPageContainer::Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor)
        return pDescriptor->msPageName;
    else
        return OUString();
}

OUString MasterPageContainer::GetStyleNameForToken (
    MasterPageContainer::Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor)
        return pDescriptor->msStyleName;
    else
        return OUString();
}

SdPage* MasterPageContainer::GetPageObjectForToken (
    MasterPageContainer::Token aToken,
    bool bLoad)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SdPage* pPageObject = nullptr;
    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor)
    {
        pPageObject = pDescriptor->mpMasterPage;
        if (pPageObject == nullptr)
        {
            // The page object is not (yet) present.  Call
            // UpdateDescriptor() to trigger the PageObjectProvider() to
            // provide it.
            if (bLoad)
                mpImpl->GetModel();
            if (mpImpl->UpdateDescriptor(pDescriptor,bLoad,falsetrue))
                pPageObject = pDescriptor->mpMasterPage;
        }
    }
    return pPageObject;
}

MasterPageContainer::Origin MasterPageContainer::GetOriginForToken (Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor)
        return pDescriptor->meOrigin;
    else
        return UNKNOWN;
}

sal_Int32 MasterPageContainer::GetTemplateIndexForToken (Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor)
        return pDescriptor->mnTemplateIndex;
    else
        return -1;
}

std::shared_ptr<MasterPageDescriptor> MasterPageContainer::GetDescriptorForToken (
    MasterPageContainer::Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    return mpImpl->GetDescriptor(aToken);
}

void MasterPageContainer::InvalidatePreview (MasterPageContainer::Token aToken)
{
    mpImpl->InvalidatePreview(aToken);
}

const Size& MasterPageContainer::GetPreviewSizePixel()
{
    return mpImpl->GetPreviewSizePixel(mePreviewSize);
}

Image MasterPageContainer::GetPreviewForToken (MasterPageContainer::Token aToken)
{
    return mpImpl->GetPreviewForToken(aToken,mePreviewSize);
}

MasterPageContainer::PreviewState MasterPageContainer::GetPreviewState (Token aToken)
{
    return mpImpl->GetPreviewState(aToken);
}

bool MasterPageContainer::RequestPreview (Token aToken)
{
    return mpImpl->RequestPreview(aToken);
}

//==== Implementation ================================================

MasterPageContainer::Implementation::Implementation()
    : meInitializationState(InitializationState::NotInitialized),
      mpDocument(nullptr),
      mbFirstPageObjectSeen(false)
{
    UpdatePreviewSizePixel();
}

MasterPageContainer::Implementation::~Implementation()
{
    // When the initializer or filler tasks are still running then we have
    // to stop them now in order to prevent them from calling us back.
    tools::TimerBasedTaskExecution::ReleaseTask(mpFillerTask);

    mpRequestQueue.reset();

    uno::Reference<util::XCloseable> xCloseable (mxModel, uno::UNO_QUERY);
    if (xCloseable.is())
    {
        try
        {
            xCloseable->close(true);
        }
        catch (const css::util::CloseVetoException&)
        {
        }
    }
    mxModel = nullptr;
}

void MasterPageContainer::Implementation::LateInit()
{
    const ::osl::MutexGuard aGuard (maMutex);

    if (meInitializationState != InitializationState::NotInitialized)
        return;

    meInitializationState = InitializationState::Initializing;

    OSL_ASSERT(Instance().get()==this);
    mpRequestQueue.reset(MasterPageContainerQueue::Create(
        std::shared_ptr<MasterPageContainerQueue::ContainerAdapter>(Instance())));

    mpFillerTask = ::sd::tools::TimerBasedTaskExecution::Create(
        std::make_shared<MasterPageContainerFiller>(*this),
        5,
        50);

    meInitializationState = InitializationState::Initialized;
}

void MasterPageContainer::Implementation::AddChangeListener (const Link<MasterPageContainerChangeEvent&,void>& rLink)
{
    const ::osl::MutexGuard aGuard (maMutex);

    ::std::vector<Link<MasterPageContainerChangeEvent&,void>>::iterator iListener (
        ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink));
    if (iListener == maChangeListeners.end())
        maChangeListeners.push_back(rLink);

}

void MasterPageContainer::Implementation::RemoveChangeListener (const Link<MasterPageContainerChangeEvent&,void>& rLink)
{
    const ::osl::MutexGuard aGuard (maMutex);

    ::std::vector<Link<MasterPageContainerChangeEvent&,void>>::iterator iListener (
        ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink));
    if (iListener != maChangeListeners.end())
        maChangeListeners.erase(iListener);
}

void MasterPageContainer::Implementation::UpdatePreviewSizePixel()
{
    const ::osl::MutexGuard aGuard (maMutex);

    // The default aspect ratio is 4:3
    int nWidth (4);
    int nHeight (3);

    // Search for the first entry with an existing master page.
    auto iDescriptor = std::find_if(maContainer.begin(), maContainer.end(),
        [](const SharedMasterPageDescriptor& rxDescriptor) {
            return rxDescriptor != nullptr && rxDescriptor->mpMasterPage != nullptr;
        });
    if (iDescriptor != maContainer.end())
    {
        Size aPageSize ((*iDescriptor)->mpMasterPage->GetSize());
        OSL_ASSERT(!aPageSize.IsEmpty());
        if (aPageSize.Width() > 0)
            nWidth = aPageSize.Width();
        if (aPageSize.Height() > 0)
            nHeight = aPageSize.Height();
        mbFirstPageObjectSeen = true;
    }

    maSmallPreviewSizePixel.setWidth( SMALL_PREVIEW_WIDTH );
    maLargePreviewSizePixel.setWidth( LARGE_PREVIEW_WIDTH );

    int nNewSmallHeight ((maSmallPreviewSizePixel.Width()-2) * nHeight / nWidth + 2);
    int nNewLargeHeight ((maLargePreviewSizePixel.Width()-2) * nHeight / nWidth + 2);

    if (nNewSmallHeight!=maSmallPreviewSizePixel.Height()
        || nNewLargeHeight!=maLargePreviewSizePixel.Height())
    {
        maSmallPreviewSizePixel.setHeight( nNewSmallHeight );
        maLargePreviewSizePixel.setHeight( nNewLargeHeight );
        FireContainerChange(
            MasterPageContainerChangeEvent::EventType::SIZE_CHANGED,
            NIL_TOKEN);
    }
}

MasterPageContainer::Token MasterPageContainer::Implementation::PutMasterPage (
    const SharedMasterPageDescriptor& rpDescriptor)
{
    const ::osl::MutexGuard aGuard (maMutex);

    Token aResult (NIL_TOKEN);

    // Get page object and preview when that is inexpensive.
    UpdateDescriptor(rpDescriptor,false,falsefalse);

    // Look up the new MasterPageDescriptor and either insert it or update
    // an already existing one.
    MasterPageContainerType::iterator aEntry (
        ::std::find_if (
            maContainer.begin(),
            maContainer.end(),
            MasterPageDescriptor::AllComparator(rpDescriptor)));
    if (aEntry == maContainer.end())
    {
        // Insert a new MasterPageDescriptor.
        bool bIgnore(rpDescriptor->mpPageObjectProvider == nullptr
                     && rpDescriptor->msURL.isEmpty());

        if ( ! bIgnore)
        {
            CleanContainer();

            aResult = maContainer.size();
            rpDescriptor->SetToken(aResult);

            // Templates are precious, i.e. we lock them so that they will
            // not be destroyed when (temporarily) no one references them.
            // They will only be deleted when the container is destroyed.
            switch (rpDescriptor->meOrigin)
            {
                case TEMPLATE:
                case DEFAULT:
                    ++rpDescriptor->mnUseCount;
                    break;

                default:
                    break;
            }

            maContainer.push_back(rpDescriptor);
            aEntry = maContainer.end()-1;

            FireContainerChange(MasterPageContainerChangeEvent::EventType::CHILD_ADDED,aResult);
        }
    }
    else
    {
        // Update an existing MasterPageDescriptor.
        aResult = (*aEntry)->maToken;
        std::unique_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pEventTypes(
            (*aEntry)->Update(*rpDescriptor));
        if (pEventTypes != nullptr && !pEventTypes->empty())
        {
            // One or more aspects of the descriptor have changed.  Send
            // appropriate events to the listeners.
            UpdateDescriptor(*aEntry,false,falsetrue);

            for (const auto& rEventType : *pEventTypes)
            {
                FireContainerChange(rEventType, (*aEntry)->maToken);
            }
        }
    }

    return aResult;
}

bool MasterPageContainer::Implementation::HasToken (Token aToken) const
{
    return aToken>=0
        && o3tl::make_unsigned(aToken)<maContainer.size()
        && maContainer[aToken];
}

SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor (Token aToken) const
{
    if (aToken>=0 && o3tl::make_unsigned(aToken)<maContainer.size())
        return maContainer[aToken];
    else
        return SharedMasterPageDescriptor();
}

void MasterPageContainer::Implementation::InvalidatePreview (Token aToken)
{
    const ::osl::MutexGuard aGuard (maMutex);

    SharedMasterPageDescriptor pDescriptor (GetDescriptor(aToken));
    if (pDescriptor)
    {
        pDescriptor->maSmallPreview = Image();
        pDescriptor->maLargePreview = Image();
        RequestPreview(aToken);
    }
}

Image MasterPageContainer::Implementation::GetPreviewForToken (
    MasterPageContainer::Token aToken,
    PreviewSize ePreviewSize)
{
    const ::osl::MutexGuard aGuard (maMutex);

    Image aPreview;
    PreviewState ePreviewState (GetPreviewState(aToken));

    SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);

    // When the preview is missing but inexpensively creatable then do that
    // now.
    if (pDescriptor)
    {
        if (ePreviewState == PS_CREATABLE)
            if (UpdateDescriptor(pDescriptor, false,falsetrue))
                if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0)
                    ePreviewState = PS_AVAILABLE;

        switch (ePreviewState)
        {
            case PS_AVAILABLE:
                aPreview = pDescriptor->GetPreview(ePreviewSize);
                break;

            case PS_PREPARING:
            case PS_CREATABLE:
                aPreview = GetPreviewSubstitution(
                    STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
                    ePreviewSize);
                break;

            case PS_NOT_AVAILABLE:
                aPreview = GetPreviewSubstitution(
                    STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION,
                    ePreviewSize);
                if (ePreviewSize == SMALL)
                    pDescriptor->maSmallPreview = aPreview;
                else
                    pDescriptor->maLargePreview = aPreview;
                break;
        }
    }

    return aPreview;
}

MasterPageContainer::PreviewState MasterPageContainer::Implementation::GetPreviewState (
    Token aToken) const
{
    const ::osl::MutexGuard aGuard (maMutex);

    PreviewState eState (PS_NOT_AVAILABLE);

    SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
    if (pDescriptor)
    {
        if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0)
            eState = PS_AVAILABLE;
        else if (pDescriptor->mpPreviewProvider != nullptr)
        {
            // The preview does not exist but can be created.  When that is
            // not expensive then do it at once.
            if (mpRequestQueue->HasRequest(aToken))
                eState = PS_PREPARING;
            else
                eState = PS_CREATABLE;
        }
        else
            eState = PS_NOT_AVAILABLE;
    }

    return eState;
}

bool MasterPageContainer::Implementation::RequestPreview (Token aToken)
{
    SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
    if (pDescriptor)
        return mpRequestQueue->RequestPreview(pDescriptor);
    else
        return false;
}

Reference<frame::XModel> MasterPageContainer::Implementation::GetModel()
{
    const ::osl::MutexGuard aGuard (maMutex);

    if ( ! mxModel.is())
    {
        // Create a new model.
        mxModel.set(
            ::comphelper::getProcessServiceFactory()->createInstance(
                u"com.sun.star.presentation.PresentationDocument"_ustr),
            uno::UNO_QUERY);

        // Initialize the model.
        uno::Reference<frame::XLoadable> xLoadable (mxModel,uno::UNO_QUERY);
        if (xLoadable.is())
            xLoadable->initNew();

        // Use its tunnel to get a pointer to its core implementation.
        uno::Reference<lang::XUnoTunnel> xUnoTunnel (mxModel, uno::UNO_QUERY);
        if (auto pSdXImpressDocument = comphelper::getFromUnoTunnel<SdXImpressDocument>(xUnoTunnel))
        {
            mpDocument = pSdXImpressDocument->GetDoc();
        }

        // Create a default page.
        uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier (mxModel, uno::UNO_QUERY);
        if (xSlideSupplier.is())
        {
            uno::Reference<drawing::XDrawPages> xSlides =
                xSlideSupplier->getDrawPages();
            if (xSlides.is())
            {
                uno::Reference<drawing::XDrawPage> xNewPage (xSlides->insertNewByIndex(0));
                uno::Reference<beans::XPropertySet> xProperties(xNewPage, uno::UNO_QUERY);
                if (xProperties.is())
                    xProperties->setPropertyValue(
                        u"Layout"_ustr,
                        Any(sal_Int16(AUTOLAYOUT_TITLE)));
            }
        }
    }
    return mxModel;
}

SdDrawDocument* MasterPageContainer::Implementation::GetDocument()
{
    GetModel();
    return mpDocument;
}

const Size& MasterPageContainer::Implementation::GetPreviewSizePixel(PreviewSize pPreviewSize)
{
    if (pPreviewSize == PreviewSize::SMALL)
        return maSmallPreviewSizePixel;
    else
        return maLargePreviewSizePixel;
}

Image MasterPageContainer::Implementation::GetPreviewSubstitution (
    TranslateId pId,
    PreviewSize ePreviewSize)
{
    const ::osl::MutexGuard aGuard (maMutex);

    Image aPreview;

    if (pId == STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION)
    {
        Image& rPreview (ePreviewSize==SMALL
            ? maSmallPreviewBeingCreated
            : maLargePreviewBeingCreated);
        if (rPreview.GetSizePixel().Width() == 0)
        {
            rPreview = maPreviewRenderer.RenderSubstitution(
                ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel,
                SdResId(STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION));
        }
        aPreview = rPreview;
    }
    else if (pId == STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION)
    {
        Image& rPreview (ePreviewSize==SMALL
            ? maSmallPreviewNotAvailable
            : maLargePreviewNotAvailable);
        if (rPreview.GetSizePixel().Width() == 0)
        {
            rPreview = maPreviewRenderer.RenderSubstitution(
                ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel,
                SdResId(STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION));
        }
        aPreview = rPreview;
    }

    return aPreview;
}

void MasterPageContainer::Implementation::CleanContainer()
{
    // Remove the empty elements at the end of the container.  The empty
    // elements in the middle can not be removed because that would
    // invalidate the references still held by others.
    int nIndex (maContainer.size()-1);
    while (nIndex>=0 && !maContainer[nIndex])
        --nIndex;
    maContainer.resize(++nIndex);
}

void MasterPageContainer::Implementation::FireContainerChange (
    MasterPageContainerChangeEvent::EventType eType,
    Token aToken)
{
    ::std::vector<Link<MasterPageContainerChangeEvent&,void>> aCopy(maChangeListeners);
    MasterPageContainerChangeEvent aEvent;
    aEvent.meEventType = eType;
    aEvent.maChildToken = aToken;
    for (const auto& rListener : aCopy)
        rListener.Call(aEvent);
}

bool MasterPageContainer::Implementation::UpdateDescriptor (
    const SharedMasterPageDescriptor& rpDescriptor,
    bool bForcePageObject,
    bool bForcePreview,
    bool bSendEvents)
{
    const ::osl::MutexGuard aGuard (maMutex);

    // We have to create the page object when the preview provider needs it
    // and the caller needs the preview.
    bForcePageObject |= (bForcePreview
        && rpDescriptor->mpPreviewProvider->NeedsPageObject()
        && rpDescriptor->mpMasterPage==nullptr);

    // Define a cost threshold so that an update or page object or preview
    // that is at least this cost are made at once. Updates with higher cost
    // are scheduled for later.
    sal_Int32 nCostThreshold (mpRequestQueue->IsEmpty() ? 5 : 0);

    // Update the page object (which may be used for the preview update).
    if (bForcePageObject)
        GetDocument();
    int nPageObjectModified (rpDescriptor->UpdatePageObject(
        (bForcePageObject ? -1 : nCostThreshold),
        mpDocument));
    if (nPageObjectModified == 1 && bSendEvents)
        FireContainerChange(
            MasterPageContainerChangeEvent::EventType::DATA_CHANGED,
            rpDescriptor->maToken);
    if (nPageObjectModified == -1 && bSendEvents)
        FireContainerChange(
            MasterPageContainerChangeEvent::EventType::CHILD_REMOVED,
            rpDescriptor->maToken);
    if (nPageObjectModified && ! mbFirstPageObjectSeen)
        UpdatePreviewSizePixel();

    // Update the preview.
    bool bPreviewModified (rpDescriptor->UpdatePreview(
        (bForcePreview ? -1 : nCostThreshold),
        maSmallPreviewSizePixel,
        maLargePreviewSizePixel,
        maPreviewRenderer));

    if (bPreviewModified && bSendEvents)
        FireContainerChange(
            MasterPageContainerChangeEvent::EventType::PREVIEW_CHANGED,
            rpDescriptor->maToken);

    return nPageObjectModified || bPreviewModified;
}

void MasterPageContainer::Implementation::ReleaseDescriptor (Token aToken)
{
    if (aToken>=0 && o3tl::make_unsigned(aToken)<maContainer.size())
    {
        maContainer[aToken].reset();
    }
}

void MasterPageContainer::Implementation::FillingDone()
{
    mpRequestQueue->ProcessAllRequests();
}

// end of namespace sd::sidebar

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=94 H=96 G=94

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.