LCOV - code coverage report
Current view: top level - sd/source/ui/sidebar - MasterPageContainer.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 2 409 0.5 %
Date: 2015-06-13 12:38:46 Functions: 2 57 3.5 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      20             : #include "MasterPageContainer.hxx"
      21             : 
      22             : #include "MasterPageDescriptor.hxx"
      23             : #include "MasterPageContainerFiller.hxx"
      24             : #include "MasterPageContainerQueue.hxx"
      25             : #include "TemplateScanner.hxx"
      26             : #include "tools/AsynchronousTask.hxx"
      27             : #include "strings.hrc"
      28             : #include <algorithm>
      29             : #include <list>
      30             : #include <memory>
      31             : #include <set>
      32             : 
      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 <osl/getglobalmutex.hxx>
      57             : #include <boost/scoped_ptr.hpp>
      58             : #include <boost/weak_ptr.hpp>
      59             : 
      60             : using namespace ::com::sun::star;
      61             : using namespace ::com::sun::star::uno;
      62             : 
      63             : namespace {
      64             : 
      65             : typedef ::std::vector<sd::sidebar::SharedMasterPageDescriptor> MasterPageContainerType;
      66             : 
      67             : } // end of anonymous namespace
      68             : 
      69             : namespace sd { namespace sidebar {
      70             : 
      71             : /** Inner implementation class of the MasterPageContainer.
      72             : */
      73             : class MasterPageContainer::Implementation
      74             :     : public SdGlobalResource,
      75             :       public MasterPageContainerFiller::ContainerAdapter,
      76             :       public MasterPageContainerQueue::ContainerAdapter
      77             : {
      78             : public:
      79             :     mutable ::osl::Mutex maMutex;
      80             : 
      81             :     static ::boost::weak_ptr<Implementation> mpInstance;
      82             :     MasterPageContainerType maContainer;
      83             : 
      84             :     static ::boost::shared_ptr<Implementation> Instance();
      85             : 
      86             :     void LateInit();
      87             :     void AddChangeListener (const Link<>& rLink);
      88             :     void RemoveChangeListener (const Link<>& rLink);
      89             :     void UpdatePreviewSizePixel();
      90             :     Size GetPreviewSizePixel (PreviewSize eSize) const;
      91             : 
      92             :     bool HasToken (Token aToken) const;
      93             :     const SharedMasterPageDescriptor GetDescriptor (MasterPageContainer::Token aToken) const;
      94             :     SharedMasterPageDescriptor GetDescriptor (MasterPageContainer::Token aToken);
      95             :     virtual Token PutMasterPage (const SharedMasterPageDescriptor& rDescriptor) SAL_OVERRIDE;
      96             :     void InvalidatePreview (Token aToken);
      97             :     Image GetPreviewForToken (
      98             :         Token aToken,
      99             :         PreviewSize ePreviewSize);
     100             :     PreviewState GetPreviewState (Token aToken) const;
     101             :     bool RequestPreview (Token aToken);
     102             : 
     103             :     Reference<frame::XModel> GetModel();
     104             :     SdDrawDocument* GetDocument();
     105             : 
     106             :     void FireContainerChange (
     107             :         MasterPageContainerChangeEvent::EventType eType,
     108             :         Token aToken,
     109             :         bool bNotifyAsynchronously = false);
     110             : 
     111             :     virtual bool UpdateDescriptor (
     112             :         const SharedMasterPageDescriptor& rpDescriptor,
     113             :         bool bForcePageObject,
     114             :         bool bForcePreview,
     115             :         bool bSendEvents) SAL_OVERRIDE;
     116             : 
     117             :     void ReleaseDescriptor (Token aToken);
     118             : 
     119             :     /** Called by the MasterPageContainerFiller to notify that all master
     120             :         pages from template documents have been added.
     121             :     */
     122             :     virtual void FillingDone() SAL_OVERRIDE;
     123             : 
     124             : private:
     125             :     Implementation();
     126             :     virtual ~Implementation();
     127             : 
     128             :     class Deleter { public:
     129           0 :         void operator() (Implementation* pObject) { delete pObject; }
     130             :     };
     131             :     friend class Deleter;
     132             : 
     133             :     enum InitializationState { NOT_INITIALIZED, INITIALIZING, INITIALIZED } meInitializationState;
     134             : 
     135             :     ::boost::scoped_ptr<MasterPageContainerQueue> mpRequestQueue;
     136             :     ::com::sun::star::uno::Reference<com::sun::star::frame::XModel> mxModel;
     137             :     SdDrawDocument* mpDocument;
     138             :     PreviewRenderer maPreviewRenderer;
     139             :     /** Remember whether the first page object has already been used to
     140             :         determine the correct size ratio.
     141             :     */
     142             :     bool mbFirstPageObjectSeen;
     143             : 
     144             :     // The widths for the previews contain two pixels for the border that is
     145             :     // painted around the preview.
     146             :     static const int SMALL_PREVIEW_WIDTH = 72 + 2;
     147             :     static const int LARGE_PREVIEW_WIDTH = 2*72 + 2;
     148             : 
     149             :     /** This substition of page preview shows "Preparing preview" and is
     150             :         shown as long as the actual previews are not being present.
     151             :     */
     152             :     Image maLargePreviewBeingCreated;
     153             :     Image maSmallPreviewBeingCreated;
     154             : 
     155             :     /** This substition of page preview is shown when a preview can not be
     156             :         created and thus is not available.
     157             :     */
     158             :     Image maLargePreviewNotAvailable;
     159             :     Image maSmallPreviewNotAvailable;
     160             : 
     161             :     ::std::vector<Link<>> maChangeListeners;
     162             : 
     163             :     // We have to remember the tasks for initialization and filling in case
     164             :     // a MasterPageContainer object is destroyed before these tasks have
     165             :     // been completed.
     166             :     ::boost::weak_ptr<sd::tools::TimerBasedTaskExecution> mpFillerTask;
     167             : 
     168             :     Size maSmallPreviewSizePixel;
     169             :     Size maLargePreviewSizePixel;
     170             : 
     171             :     bool mbContainerCleaningPending;
     172             : 
     173             :     typedef ::std::pair<MasterPageContainerChangeEvent::EventType,Token> EventData;
     174             :     DECL_LINK(AsynchronousNotifyCallback, EventData*);
     175             : 
     176             :     Image GetPreviewSubstitution (sal_uInt16 nId, PreviewSize ePreviewSize);
     177             : 
     178             :     void CleanContainer();
     179             : };
     180             : 
     181             : //===== MasterPageContainer ===================================================
     182             : 
     183             : ::boost::weak_ptr<MasterPageContainer::Implementation>
     184          22 :     MasterPageContainer::Implementation::mpInstance;
     185             : 
     186             : ::boost::shared_ptr<MasterPageContainer::Implementation>
     187           0 :     MasterPageContainer::Implementation::Instance()
     188             : {
     189           0 :     ::boost::shared_ptr<MasterPageContainer::Implementation> pInstance;
     190             : 
     191           0 :     if (Implementation::mpInstance.expired())
     192             :     {
     193             :         ::osl::GetGlobalMutex aMutexFunctor;
     194           0 :         ::osl::MutexGuard aGuard (aMutexFunctor());
     195           0 :         if (Implementation::mpInstance.expired())
     196             :         {
     197             :             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     198           0 :             pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>(
     199           0 :                 new MasterPageContainer::Implementation(),
     200           0 :                 MasterPageContainer::Implementation::Deleter());
     201           0 :             SdGlobalResourceContainer::Instance().AddResource(pInstance);
     202           0 :             Implementation::mpInstance = pInstance;
     203             :         }
     204             :         else
     205           0 :             pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>(
     206           0 :                 Implementation::mpInstance);
     207             :     }
     208             :     else
     209             :     {
     210             :         OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     211           0 :         pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>(
     212           0 :             Implementation::mpInstance);
     213             :     }
     214             : 
     215             :     DBG_ASSERT (pInstance.get()!=NULL,
     216             :         "MasterPageContainer::Implementation::Instance(): instance is NULL");
     217           0 :     return pInstance;
     218             : }
     219             : 
     220           0 : MasterPageContainer::MasterPageContainer()
     221             :     : mpImpl(Implementation::Instance()),
     222           0 :       mePreviewSize(SMALL)
     223             : {
     224           0 :     mpImpl->LateInit();
     225           0 : }
     226             : 
     227           0 : MasterPageContainer::~MasterPageContainer()
     228             : {
     229           0 : }
     230             : 
     231           0 : void MasterPageContainer::AddChangeListener (const Link<>& rLink)
     232             : {
     233           0 :     mpImpl->AddChangeListener(rLink);
     234           0 : }
     235             : 
     236           0 : void MasterPageContainer::RemoveChangeListener (const Link<>& rLink)
     237             : {
     238           0 :     mpImpl->RemoveChangeListener(rLink);
     239           0 : }
     240             : 
     241           0 : void MasterPageContainer::SetPreviewSize (PreviewSize eSize)
     242             : {
     243           0 :     mePreviewSize = eSize;
     244             :     mpImpl->FireContainerChange(
     245             :         MasterPageContainerChangeEvent::SIZE_CHANGED,
     246           0 :         NIL_TOKEN);
     247           0 : }
     248             : 
     249           0 : Size MasterPageContainer::GetPreviewSizePixel() const
     250             : {
     251           0 :     return mpImpl->GetPreviewSizePixel(mePreviewSize);
     252             : }
     253             : 
     254           0 : MasterPageContainer::Token MasterPageContainer::PutMasterPage (
     255             :     const SharedMasterPageDescriptor& rDescriptor)
     256             : {
     257           0 :     return mpImpl->PutMasterPage(rDescriptor);
     258             : }
     259             : 
     260           0 : void MasterPageContainer::AcquireToken (Token aToken)
     261             : {
     262           0 :     SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
     263           0 :     if (pDescriptor.get() != NULL)
     264             :     {
     265           0 :         ++pDescriptor->mnUseCount;
     266           0 :     }
     267           0 : }
     268             : 
     269           0 : void MasterPageContainer::ReleaseToken (Token aToken)
     270             : {
     271           0 :     SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
     272           0 :     if (pDescriptor.get() != NULL)
     273             :     {
     274             :         OSL_ASSERT(pDescriptor->mnUseCount>0);
     275           0 :         --pDescriptor->mnUseCount;
     276           0 :         if (pDescriptor->mnUseCount <= 0)
     277             :         {
     278           0 :             switch (pDescriptor->meOrigin)
     279             :             {
     280             :                 case DEFAULT:
     281             :                 case TEMPLATE:
     282             :                 default:
     283           0 :                     break;
     284             : 
     285             :                 case MASTERPAGE:
     286           0 :                     mpImpl->ReleaseDescriptor(aToken);
     287           0 :                     break;
     288             :             }
     289             :         }
     290           0 :     }
     291           0 : }
     292             : 
     293           0 : int MasterPageContainer::GetTokenCount() const
     294             : {
     295           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     296             : 
     297           0 :     return mpImpl->maContainer.size();
     298             : }
     299             : 
     300           0 : bool MasterPageContainer::HasToken (Token aToken) const
     301             : {
     302           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     303             : 
     304           0 :     return mpImpl->HasToken(aToken);
     305             : }
     306             : 
     307           0 : MasterPageContainer::Token MasterPageContainer::GetTokenForIndex (int nIndex)
     308             : {
     309           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     310             : 
     311           0 :     Token aResult (NIL_TOKEN);
     312           0 :     if (HasToken(nIndex))
     313           0 :         aResult = mpImpl->maContainer[nIndex]->maToken;
     314           0 :     return aResult;
     315             : }
     316             : 
     317           0 : MasterPageContainer::Token MasterPageContainer::GetTokenForURL (
     318             :     const OUString& sURL)
     319             : {
     320           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     321             : 
     322           0 :     Token aResult (NIL_TOKEN);
     323           0 :     if (!sURL.isEmpty())
     324             :     {
     325             :         MasterPageContainerType::iterator iEntry (
     326             :             ::std::find_if (
     327           0 :                 mpImpl->maContainer.begin(),
     328           0 :                 mpImpl->maContainer.end(),
     329           0 :                 MasterPageDescriptor::URLComparator(sURL)));
     330           0 :         if (iEntry != mpImpl->maContainer.end())
     331           0 :             aResult = (*iEntry)->maToken;
     332             :     }
     333           0 :     return aResult;
     334             : }
     335             : 
     336           0 : MasterPageContainer::Token MasterPageContainer::GetTokenForStyleName (const OUString& sStyleName)
     337             : {
     338           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     339             : 
     340           0 :     Token aResult (NIL_TOKEN);
     341           0 :     if (!sStyleName.isEmpty())
     342             :     {
     343             :         MasterPageContainerType::iterator iEntry (
     344             :             ::std::find_if (
     345           0 :                 mpImpl->maContainer.begin(),
     346           0 :                 mpImpl->maContainer.end(),
     347           0 :                 MasterPageDescriptor::StyleNameComparator(sStyleName)));
     348           0 :         if (iEntry != mpImpl->maContainer.end())
     349           0 :             aResult = (*iEntry)->maToken;
     350             :     }
     351           0 :     return aResult;
     352             : }
     353             : 
     354           0 : MasterPageContainer::Token MasterPageContainer::GetTokenForPageObject (
     355             :     const SdPage* pPage)
     356             : {
     357           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     358             : 
     359           0 :     Token aResult (NIL_TOKEN);
     360           0 :     if (pPage != NULL)
     361             :     {
     362             :         MasterPageContainerType::iterator iEntry (
     363             :             ::std::find_if (
     364           0 :                 mpImpl->maContainer.begin(),
     365           0 :                 mpImpl->maContainer.end(),
     366           0 :                 MasterPageDescriptor::PageObjectComparator(pPage)));
     367           0 :         if (iEntry != mpImpl->maContainer.end())
     368           0 :             aResult = (*iEntry)->maToken;
     369             :     }
     370           0 :     return aResult;
     371             : }
     372             : 
     373           0 : OUString MasterPageContainer::GetURLForToken (
     374             :     MasterPageContainer::Token aToken)
     375             : {
     376           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     377             : 
     378           0 :     SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
     379           0 :     if (pDescriptor.get() != NULL)
     380           0 :         return pDescriptor->msURL;
     381             :     else
     382           0 :         return OUString();
     383             : }
     384             : 
     385           0 : OUString MasterPageContainer::GetPageNameForToken (
     386             :     MasterPageContainer::Token aToken)
     387             : {
     388           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     389             : 
     390           0 :     SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
     391           0 :     if (pDescriptor.get() != NULL)
     392           0 :         return pDescriptor->msPageName;
     393             :     else
     394           0 :         return OUString();
     395             : }
     396             : 
     397           0 : OUString MasterPageContainer::GetStyleNameForToken (
     398             :     MasterPageContainer::Token aToken)
     399             : {
     400           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     401             : 
     402           0 :     SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
     403           0 :     if (pDescriptor.get() != NULL)
     404           0 :         return pDescriptor->msStyleName;
     405             :     else
     406           0 :         return OUString();
     407             : }
     408             : 
     409           0 : SdPage* MasterPageContainer::GetPageObjectForToken (
     410             :     MasterPageContainer::Token aToken,
     411             :     bool bLoad)
     412             : {
     413           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     414             : 
     415           0 :     SdPage* pPageObject = NULL;
     416           0 :     SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
     417           0 :     if (pDescriptor.get() != NULL)
     418             :     {
     419           0 :         pPageObject = pDescriptor->mpMasterPage;
     420           0 :         if (pPageObject == NULL)
     421             :         {
     422             :             // The page object is not (yet) present.  Call
     423             :             // UpdateDescriptor() to trigger the PageObjectProvider() to
     424             :             // provide it.
     425           0 :             if (bLoad)
     426           0 :                 mpImpl->GetModel();
     427           0 :             if (mpImpl->UpdateDescriptor(pDescriptor,bLoad,false, true))
     428           0 :                 pPageObject = pDescriptor->mpMasterPage;
     429             :         }
     430             :     }
     431           0 :     return pPageObject;
     432             : }
     433             : 
     434           0 : MasterPageContainer::Origin MasterPageContainer::GetOriginForToken (Token aToken)
     435             : {
     436           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     437             : 
     438           0 :     SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
     439           0 :     if (pDescriptor.get() != NULL)
     440           0 :         return pDescriptor->meOrigin;
     441             :     else
     442           0 :         return UNKNOWN;
     443             : }
     444             : 
     445           0 : sal_Int32 MasterPageContainer::GetTemplateIndexForToken (Token aToken)
     446             : {
     447           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     448             : 
     449           0 :     SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
     450           0 :     if (pDescriptor.get() != NULL)
     451           0 :         return pDescriptor->mnTemplateIndex;
     452             :     else
     453           0 :         return -1;
     454             : }
     455             : 
     456           0 : SharedMasterPageDescriptor MasterPageContainer::GetDescriptorForToken (
     457             :     MasterPageContainer::Token aToken)
     458             : {
     459           0 :     const ::osl::MutexGuard aGuard (mpImpl->maMutex);
     460             : 
     461           0 :     return mpImpl->GetDescriptor(aToken);
     462             : }
     463             : 
     464           0 : void MasterPageContainer::InvalidatePreview (MasterPageContainer::Token aToken)
     465             : {
     466           0 :     mpImpl->InvalidatePreview(aToken);
     467           0 : }
     468             : 
     469           0 : Image MasterPageContainer::GetPreviewForToken (MasterPageContainer::Token aToken)
     470             : {
     471           0 :     return mpImpl->GetPreviewForToken(aToken,mePreviewSize);
     472             : }
     473             : 
     474           0 : MasterPageContainer::PreviewState MasterPageContainer::GetPreviewState (Token aToken)
     475             : {
     476           0 :     return mpImpl->GetPreviewState(aToken);
     477             : }
     478             : 
     479           0 : bool MasterPageContainer::RequestPreview (Token aToken)
     480             : {
     481           0 :     return mpImpl->RequestPreview(aToken);
     482             : }
     483             : 
     484             : //==== Implementation ================================================
     485             : 
     486           0 : MasterPageContainer::Implementation::Implementation()
     487             :     : maMutex(),
     488             :       maContainer(),
     489             :       meInitializationState(NOT_INITIALIZED),
     490             :       mpRequestQueue(NULL),
     491             :       mxModel(NULL),
     492             :       mpDocument(NULL),
     493             :       maPreviewRenderer(),
     494             :       mbFirstPageObjectSeen(false),
     495             :       maLargePreviewBeingCreated(),
     496             :       maSmallPreviewBeingCreated(),
     497             :       maLargePreviewNotAvailable(),
     498             :       maSmallPreviewNotAvailable(),
     499             :       maChangeListeners(),
     500             :       maSmallPreviewSizePixel(),
     501             :       maLargePreviewSizePixel(),
     502           0 :       mbContainerCleaningPending(true)
     503             : 
     504             : {
     505           0 :     UpdatePreviewSizePixel();
     506           0 : }
     507             : 
     508           0 : MasterPageContainer::Implementation::~Implementation()
     509             : {
     510             :     // When the initializer or filler tasks are still running then we have
     511             :     // to stop them now in order to prevent them from calling us back.
     512           0 :     tools::TimerBasedTaskExecution::ReleaseTask(mpFillerTask);
     513             : 
     514           0 :     mpRequestQueue.reset();
     515             : 
     516           0 :     uno::Reference<util::XCloseable> xCloseable (mxModel, uno::UNO_QUERY);
     517           0 :     if (xCloseable.is())
     518             :     {
     519             :         try
     520             :         {
     521           0 :             xCloseable->close(true);
     522             :         }
     523           0 :         catch (const ::com::sun::star::util::CloseVetoException&)
     524             :         {
     525             :         }
     526             :     }
     527           0 :     mxModel = NULL;
     528           0 : }
     529             : 
     530           0 : void MasterPageContainer::Implementation::LateInit()
     531             : {
     532           0 :     const ::osl::MutexGuard aGuard (maMutex);
     533             : 
     534           0 :     if (meInitializationState == NOT_INITIALIZED)
     535             :     {
     536           0 :         meInitializationState = INITIALIZING;
     537             : 
     538             :         OSL_ASSERT(Instance().get()==this);
     539             :         mpRequestQueue.reset(MasterPageContainerQueue::Create(
     540           0 :             ::boost::shared_ptr<MasterPageContainerQueue::ContainerAdapter>(Instance())));
     541             : 
     542           0 :         mpFillerTask = ::sd::tools::TimerBasedTaskExecution::Create(
     543           0 :             ::boost::shared_ptr<tools::AsynchronousTask>(new MasterPageContainerFiller(*this)),
     544             :             5,
     545           0 :             50);
     546             : 
     547           0 :         meInitializationState = INITIALIZED;
     548           0 :     }
     549           0 : }
     550             : 
     551           0 : void MasterPageContainer::Implementation::AddChangeListener (const Link<>& rLink)
     552             : {
     553           0 :     const ::osl::MutexGuard aGuard (maMutex);
     554             : 
     555             :     ::std::vector<Link<>>::iterator iListener (
     556           0 :         ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink));
     557           0 :     if (iListener == maChangeListeners.end())
     558           0 :         maChangeListeners.push_back(rLink);
     559             : 
     560           0 : }
     561             : 
     562           0 : void MasterPageContainer::Implementation::RemoveChangeListener (const Link<>& rLink)
     563             : {
     564           0 :     const ::osl::MutexGuard aGuard (maMutex);
     565             : 
     566             :     ::std::vector<Link<>>::iterator iListener (
     567           0 :         ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink));
     568           0 :     if (iListener != maChangeListeners.end())
     569           0 :         maChangeListeners.erase(iListener);
     570           0 : }
     571             : 
     572           0 : void MasterPageContainer::Implementation::UpdatePreviewSizePixel()
     573             : {
     574           0 :     const ::osl::MutexGuard aGuard (maMutex);
     575             : 
     576             :     // The default aspect ratio is 4:3
     577           0 :     int nWidth (4);
     578           0 :     int nHeight (3);
     579             : 
     580             :     // Search for the first entry with an existing master page.
     581           0 :     MasterPageContainerType::const_iterator iDescriptor;
     582           0 :     MasterPageContainerType::const_iterator iContainerEnd(maContainer.end());
     583           0 :     for (iDescriptor=maContainer.begin(); iDescriptor!=iContainerEnd; ++iDescriptor)
     584           0 :         if (*iDescriptor!=0 && (*iDescriptor)->mpMasterPage != NULL)
     585             :         {
     586           0 :             Size aPageSize ((*iDescriptor)->mpMasterPage->GetSize());
     587             :             OSL_ASSERT(aPageSize.Width() > 0 && aPageSize.Height() > 0);
     588           0 :             if (aPageSize.Width() > 0)
     589           0 :                 nWidth = aPageSize.Width();
     590           0 :             if (aPageSize.Height() > 0)
     591           0 :                 nHeight = aPageSize.Height();
     592           0 :             mbFirstPageObjectSeen = true;
     593           0 :             break;
     594             :         }
     595             : 
     596           0 :     maSmallPreviewSizePixel.Width() = SMALL_PREVIEW_WIDTH;
     597           0 :     maLargePreviewSizePixel.Width() = LARGE_PREVIEW_WIDTH;
     598             : 
     599           0 :     int nNewSmallHeight ((maSmallPreviewSizePixel.Width()-2) * nHeight / nWidth + 2);
     600           0 :     int nNewLargeHeight ((maLargePreviewSizePixel.Width()-2) * nHeight / nWidth + 2);
     601             : 
     602           0 :     if (nNewSmallHeight!=maSmallPreviewSizePixel.Height()
     603           0 :         || nNewLargeHeight!=maLargePreviewSizePixel.Height())
     604             :     {
     605           0 :         maSmallPreviewSizePixel.Height() = nNewSmallHeight;
     606           0 :         maLargePreviewSizePixel.Height() = nNewLargeHeight;
     607             :         FireContainerChange(
     608             :             MasterPageContainerChangeEvent::SIZE_CHANGED,
     609           0 :             NIL_TOKEN);
     610           0 :     }
     611           0 : }
     612             : 
     613           0 : Size MasterPageContainer::Implementation::GetPreviewSizePixel (PreviewSize eSize) const
     614             : {
     615           0 :     if (eSize == SMALL)
     616           0 :         return maSmallPreviewSizePixel;
     617             :     else
     618           0 :         return maLargePreviewSizePixel;
     619             : }
     620             : 
     621           0 : IMPL_LINK(MasterPageContainer::Implementation,AsynchronousNotifyCallback, EventData*, pData)
     622             : {
     623           0 :     const ::osl::MutexGuard aGuard (maMutex);
     624             : 
     625           0 :     if (pData != NULL)
     626             :     {
     627           0 :         FireContainerChange(pData->first, pData->second, false);
     628           0 :         delete pData;
     629             :     }
     630             : 
     631           0 :     return 0;
     632             : }
     633             : 
     634           0 : MasterPageContainer::Token MasterPageContainer::Implementation::PutMasterPage (
     635             :     const SharedMasterPageDescriptor& rpDescriptor)
     636             : {
     637           0 :     const ::osl::MutexGuard aGuard (maMutex);
     638             : 
     639           0 :     Token aResult (NIL_TOKEN);
     640             : 
     641             :     // Get page object and preview when that is inexpensive.
     642           0 :     UpdateDescriptor(rpDescriptor,false,false, false);
     643             : 
     644             :     // Look up the new MasterPageDescriptor and either insert it or update
     645             :     // an already existing one.
     646             :     MasterPageContainerType::iterator aEntry (
     647             :         ::std::find_if (
     648             :             maContainer.begin(),
     649             :             maContainer.end(),
     650           0 :             MasterPageDescriptor::AllComparator(rpDescriptor)));
     651           0 :     if (aEntry == maContainer.end())
     652             :     {
     653             :         // Insert a new MasterPageDescriptor.
     654           0 :         bool bIgnore (rpDescriptor->mpPageObjectProvider.get()==NULL
     655           0 :             && rpDescriptor->msURL.isEmpty());
     656             : 
     657           0 :         if ( ! bIgnore)
     658             :         {
     659           0 :             if (mbContainerCleaningPending)
     660           0 :                 CleanContainer();
     661             : 
     662           0 :             aResult = maContainer.size();
     663           0 :             rpDescriptor->SetToken(aResult);
     664             : 
     665             :             // Templates are precious, i.e. we lock them so that they will
     666             :             // not be destroyed when (temporarily) no one references them.
     667             :             // They will only be deleted when the container is destroyed.
     668           0 :             switch (rpDescriptor->meOrigin)
     669             :             {
     670             :                 case TEMPLATE:
     671             :                 case DEFAULT:
     672           0 :                     ++rpDescriptor->mnUseCount;
     673           0 :                     break;
     674             : 
     675             :                 default:
     676           0 :                     break;
     677             :             }
     678             : 
     679           0 :             maContainer.push_back(rpDescriptor);
     680           0 :             aEntry = maContainer.end()-1;
     681             : 
     682           0 :             FireContainerChange(MasterPageContainerChangeEvent::CHILD_ADDED,aResult);
     683             :         }
     684             :     }
     685             :     else
     686             :     {
     687             :         // Update an existing MasterPageDescriptor.
     688           0 :         aResult = (*aEntry)->maToken;
     689             :         std::unique_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pEventTypes(
     690           0 :             (*aEntry)->Update(*rpDescriptor));
     691           0 :         if (pEventTypes.get()!=NULL && pEventTypes->size()>0)
     692             :         {
     693             :             // One or more aspects of the descriptor have changed.  Send
     694             :             // appropriate events to the listeners.
     695           0 :             UpdateDescriptor(*aEntry,false,false, true);
     696             : 
     697           0 :             std::vector<MasterPageContainerChangeEvent::EventType>::const_iterator iEventType;
     698           0 :             for (iEventType=pEventTypes->begin(); iEventType!=pEventTypes->end(); ++iEventType)
     699             :             {
     700             :                 FireContainerChange(
     701           0 :                     *iEventType,
     702           0 :                     (*aEntry)->maToken,
     703           0 :                     false);
     704             :             }
     705           0 :         }
     706             :     }
     707             : 
     708           0 :     return aResult;
     709             : }
     710             : 
     711           0 : bool MasterPageContainer::Implementation::HasToken (Token aToken) const
     712             : {
     713             :     return aToken>=0
     714           0 :         && (unsigned)aToken<maContainer.size()
     715           0 :         && maContainer[aToken].get()!=NULL;
     716             : }
     717             : 
     718           0 : const SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor (
     719             :     Token aToken) const
     720             : {
     721           0 :     if (aToken>=0 && (unsigned)aToken<maContainer.size())
     722           0 :         return maContainer[aToken];
     723             :     else
     724           0 :         return SharedMasterPageDescriptor();
     725             : }
     726             : 
     727           0 : SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor (Token aToken)
     728             : {
     729           0 :     if (aToken>=0 && (unsigned)aToken<maContainer.size())
     730           0 :         return maContainer[aToken];
     731             :     else
     732           0 :         return SharedMasterPageDescriptor();
     733             : }
     734             : 
     735           0 : void MasterPageContainer::Implementation::InvalidatePreview (Token aToken)
     736             : {
     737           0 :     const ::osl::MutexGuard aGuard (maMutex);
     738             : 
     739           0 :     SharedMasterPageDescriptor pDescriptor (GetDescriptor(aToken));
     740           0 :     if (pDescriptor.get() != NULL)
     741             :     {
     742           0 :         pDescriptor->maSmallPreview = Image();
     743           0 :         pDescriptor->maLargePreview = Image();
     744           0 :         RequestPreview(aToken);
     745           0 :     }
     746           0 : }
     747             : 
     748           0 : Image MasterPageContainer::Implementation::GetPreviewForToken (
     749             :     MasterPageContainer::Token aToken,
     750             :     PreviewSize ePreviewSize)
     751             : {
     752           0 :     const ::osl::MutexGuard aGuard (maMutex);
     753             : 
     754           0 :     Image aPreview;
     755           0 :     PreviewState ePreviewState (GetPreviewState(aToken));
     756             : 
     757           0 :     SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
     758             : 
     759             :     // When the preview is missing but inexpensively creatable then do that
     760             :     // now.
     761           0 :     if (pDescriptor.get()!=NULL)
     762             :     {
     763           0 :         if (ePreviewState == PS_CREATABLE)
     764           0 :             if (UpdateDescriptor(pDescriptor, false,false, true))
     765           0 :                 if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0)
     766           0 :                     ePreviewState = PS_AVAILABLE;
     767             : 
     768           0 :         switch (ePreviewState)
     769             :         {
     770             :             case PS_AVAILABLE:
     771           0 :                 aPreview = pDescriptor->GetPreview(ePreviewSize);
     772           0 :                 break;
     773             : 
     774             :             case PS_PREPARING:
     775           0 :                 aPreview = GetPreviewSubstitution(
     776             :                     STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
     777           0 :                     ePreviewSize);
     778           0 :                 break;
     779             : 
     780             :             case PS_CREATABLE:
     781           0 :                 aPreview = GetPreviewSubstitution(
     782             :                     STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
     783           0 :                     ePreviewSize);
     784           0 :                 break;
     785             : 
     786             :             case PS_NOT_AVAILABLE:
     787           0 :                 aPreview = GetPreviewSubstitution(
     788             :                     STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION,
     789           0 :                     ePreviewSize);
     790           0 :                 if (ePreviewSize == SMALL)
     791           0 :                     pDescriptor->maSmallPreview = aPreview;
     792             :                 else
     793           0 :                     pDescriptor->maLargePreview = aPreview;
     794           0 :                 break;
     795             :         }
     796             :     }
     797             : 
     798           0 :     return aPreview;
     799             : }
     800             : 
     801           0 : MasterPageContainer::PreviewState MasterPageContainer::Implementation::GetPreviewState (
     802             :     Token aToken) const
     803             : {
     804           0 :     const ::osl::MutexGuard aGuard (maMutex);
     805             : 
     806           0 :     PreviewState eState (PS_NOT_AVAILABLE);
     807             : 
     808           0 :     SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
     809           0 :     if (pDescriptor.get() != NULL)
     810             :     {
     811           0 :         if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0)
     812           0 :             eState = PS_AVAILABLE;
     813           0 :         else if (pDescriptor->mpPreviewProvider.get() != NULL)
     814             :         {
     815             :             // The preview does not exist but can be created.  When that is
     816             :             // not expensive then do it at once.
     817           0 :             if (mpRequestQueue->HasRequest(aToken))
     818           0 :                 eState = PS_PREPARING;
     819             :             else
     820           0 :                 eState = PS_CREATABLE;
     821             :         }
     822             :         else
     823           0 :             eState = PS_NOT_AVAILABLE;
     824             :     }
     825             : 
     826           0 :     return eState;
     827             : }
     828             : 
     829           0 : bool MasterPageContainer::Implementation::RequestPreview (Token aToken)
     830             : {
     831           0 :     SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
     832           0 :     if (pDescriptor.get() != NULL)
     833           0 :         return mpRequestQueue->RequestPreview(pDescriptor);
     834             :     else
     835           0 :         return false;
     836             : }
     837             : 
     838           0 : Reference<frame::XModel> MasterPageContainer::Implementation::GetModel()
     839             : {
     840           0 :     const ::osl::MutexGuard aGuard (maMutex);
     841             : 
     842           0 :     if ( ! mxModel.is())
     843             :     {
     844             :         // Get the desktop a s service factory.
     845             :         uno::Reference<frame::XDesktop2> xDesktop  = frame::Desktop::create(
     846           0 :             ::comphelper::getProcessComponentContext() );
     847             : 
     848             :         // Create a new model.
     849           0 :         OUString sModelServiceName ( "com.sun.star.presentation.PresentationDocument");
     850           0 :         mxModel = uno::Reference<frame::XModel>(
     851           0 :             ::comphelper::getProcessServiceFactory()->createInstance(
     852           0 :                 sModelServiceName),
     853           0 :             uno::UNO_QUERY);
     854             : 
     855             :         // Initialize the model.
     856           0 :         uno::Reference<frame::XLoadable> xLoadable (mxModel,uno::UNO_QUERY);
     857           0 :         if (xLoadable.is())
     858           0 :             xLoadable->initNew();
     859             : 
     860             :         // Use its tunnel to get a pointer to its core implementation.
     861           0 :         uno::Reference<lang::XUnoTunnel> xUnoTunnel (mxModel, uno::UNO_QUERY);
     862           0 :         if (xUnoTunnel.is())
     863             :         {
     864             :             mpDocument = reinterpret_cast<SdXImpressDocument*>(
     865           0 :                 xUnoTunnel->getSomething(
     866           0 :                     SdXImpressDocument::getUnoTunnelId()))->GetDoc();
     867             :         }
     868             : 
     869             :         // Create a default page.
     870           0 :         uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier (mxModel, uno::UNO_QUERY);
     871           0 :         if (xSlideSupplier.is())
     872             :         {
     873             :             uno::Reference<drawing::XDrawPages> xSlides (
     874           0 :                 xSlideSupplier->getDrawPages(), uno::UNO_QUERY);
     875           0 :             if (xSlides.is())
     876             :             {
     877           0 :                 sal_Int32 nIndex (0);
     878           0 :                 uno::Reference<drawing::XDrawPage> xNewPage (xSlides->insertNewByIndex(nIndex));
     879           0 :                 uno::Reference<beans::XPropertySet> xProperties(xNewPage, uno::UNO_QUERY);
     880           0 :                 if (xProperties.is())
     881           0 :                     xProperties->setPropertyValue(
     882             :                         "Layout",
     883           0 :                         makeAny((sal_Int16)AUTOLAYOUT_TITLE));
     884           0 :             }
     885           0 :         }
     886             :     }
     887           0 :     return mxModel;
     888             : }
     889             : 
     890           0 : SdDrawDocument* MasterPageContainer::Implementation::GetDocument()
     891             : {
     892           0 :     GetModel();
     893           0 :     return mpDocument;
     894             : }
     895             : 
     896           0 : Image MasterPageContainer::Implementation::GetPreviewSubstitution (
     897             :     sal_uInt16 nId,
     898             :     PreviewSize ePreviewSize)
     899             : {
     900           0 :     const ::osl::MutexGuard aGuard (maMutex);
     901             : 
     902           0 :     Image aPreview;
     903             : 
     904           0 :     switch (nId)
     905             :     {
     906             :         case STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION:
     907             :         {
     908             :             Image& rPreview (ePreviewSize==SMALL
     909             :                 ? maSmallPreviewBeingCreated
     910           0 :                 : maLargePreviewBeingCreated);
     911           0 :             if (rPreview.GetSizePixel().Width() == 0)
     912             :             {
     913           0 :                 rPreview = maPreviewRenderer.RenderSubstitution(
     914             :                     ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel,
     915           0 :                     SdResId(STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION));
     916             :             }
     917           0 :             aPreview = rPreview;
     918             :         }
     919           0 :         break;
     920             : 
     921             :         case STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION:
     922             :         {
     923             :             Image& rPreview (ePreviewSize==SMALL
     924             :                 ? maSmallPreviewNotAvailable
     925           0 :                 : maLargePreviewNotAvailable);
     926           0 :             if (rPreview.GetSizePixel().Width() == 0)
     927             :             {
     928           0 :                 rPreview = maPreviewRenderer.RenderSubstitution(
     929             :                     ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel,
     930           0 :                     SdResId(STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION));
     931             :             }
     932           0 :             aPreview = rPreview;
     933             :         }
     934           0 :         break;
     935             :     }
     936             : 
     937           0 :     return aPreview;
     938             : }
     939             : 
     940           0 : void MasterPageContainer::Implementation::CleanContainer()
     941             : {
     942             :     // Remove the empty elements at the end of the container.  The empty
     943             :     // elements in the middle can not be removed because that would
     944             :     // invalidate the references still held by others.
     945           0 :     int nIndex (maContainer.size()-1);
     946           0 :     while (nIndex>=0 && maContainer[nIndex].get()==NULL)
     947           0 :         --nIndex;
     948           0 :     maContainer.resize(++nIndex);
     949           0 : }
     950             : 
     951           0 : void MasterPageContainer::Implementation::FireContainerChange (
     952             :     MasterPageContainerChangeEvent::EventType eType,
     953             :     Token aToken,
     954             :     bool bNotifyAsynchronously)
     955             : {
     956           0 :     if (bNotifyAsynchronously)
     957             :     {
     958             :         Application::PostUserEvent(
     959             :             LINK(this,Implementation,AsynchronousNotifyCallback),
     960           0 :             new EventData(eType,aToken));
     961             :     }
     962             :     else
     963             :     {
     964           0 :         ::std::vector<Link<>> aCopy(maChangeListeners.begin(),maChangeListeners.end());
     965           0 :         ::std::vector<Link<>>::iterator iListener;
     966             :         MasterPageContainerChangeEvent aEvent;
     967           0 :         aEvent.meEventType = eType;
     968           0 :         aEvent.maChildToken = aToken;
     969           0 :         for (iListener=aCopy.begin(); iListener!=aCopy.end(); ++iListener)
     970           0 :             iListener->Call(&aEvent);
     971             :     }
     972           0 : }
     973             : 
     974           0 : bool MasterPageContainer::Implementation::UpdateDescriptor (
     975             :     const SharedMasterPageDescriptor& rpDescriptor,
     976             :     bool bForcePageObject,
     977             :     bool bForcePreview,
     978             :     bool bSendEvents)
     979             : {
     980           0 :     const ::osl::MutexGuard aGuard (maMutex);
     981             : 
     982             :     // We have to create the page object when the preview provider needs it
     983             :     // and the caller needs the preview.
     984             :     bForcePageObject |= (bForcePreview
     985           0 :         && rpDescriptor->mpPreviewProvider->NeedsPageObject()
     986           0 :         && rpDescriptor->mpMasterPage==NULL);
     987             : 
     988             :     // Define a cost threshold so that an update or page object or preview
     989             :     // that is at least this cost are made at once. Updates with higher cost
     990             :     // are scheduled for later.
     991           0 :     sal_Int32 nCostThreshold (mpRequestQueue->IsEmpty() ? 5 : 0);
     992             : 
     993             :     // Update the page object (which may be used for the preview update).
     994           0 :     if (bForcePageObject)
     995           0 :         GetDocument();
     996             :     int nPageObjectModified (rpDescriptor->UpdatePageObject(
     997             :         (bForcePageObject ? -1 : nCostThreshold),
     998           0 :         mpDocument));
     999           0 :     if (nPageObjectModified == 1 && bSendEvents)
    1000             :         FireContainerChange(
    1001             :             MasterPageContainerChangeEvent::DATA_CHANGED,
    1002           0 :             rpDescriptor->maToken);
    1003           0 :     if (nPageObjectModified == -1 && bSendEvents)
    1004             :         FireContainerChange(
    1005             :             MasterPageContainerChangeEvent::CHILD_REMOVED,
    1006           0 :             rpDescriptor->maToken);
    1007           0 :     if (nPageObjectModified && ! mbFirstPageObjectSeen)
    1008           0 :         UpdatePreviewSizePixel();
    1009             : 
    1010             :     // Update the preview.
    1011             :     bool bPreviewModified (rpDescriptor->UpdatePreview(
    1012             :         (bForcePreview ? -1 : nCostThreshold),
    1013             :         maSmallPreviewSizePixel,
    1014             :         maLargePreviewSizePixel,
    1015           0 :         maPreviewRenderer));
    1016             : 
    1017           0 :     if (bPreviewModified && bSendEvents)
    1018             :         FireContainerChange(
    1019             :             MasterPageContainerChangeEvent::PREVIEW_CHANGED,
    1020           0 :             rpDescriptor->maToken);
    1021             : 
    1022           0 :     return nPageObjectModified || bPreviewModified;
    1023             : }
    1024             : 
    1025           0 : void MasterPageContainer::Implementation::ReleaseDescriptor (Token aToken)
    1026             : {
    1027           0 :     if (aToken>=0 && (unsigned)aToken<maContainer.size())
    1028             :     {
    1029           0 :         maContainer[aToken].reset();
    1030           0 :         mbContainerCleaningPending = true;
    1031             :     }
    1032           0 : }
    1033             : 
    1034           0 : void MasterPageContainer::Implementation::FillingDone()
    1035             : {
    1036           0 :     mpRequestQueue->ProcessAllRequests();
    1037           0 : }
    1038             : 
    1039          66 : } } // end of namespace sd::sidebar
    1040             : 
    1041             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11