You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by af...@apache.org on 2013/02/22 14:50:46 UTC

svn commit: r1449041 [3/5] - in /openoffice/branches/sidebar/main: officecfg/registry/data/org/openoffice/Office/UI/ sd/prj/ sd/sdi/ sd/source/ui/app/ sd/source/ui/framework/factories/ sd/source/ui/framework/module/ sd/source/ui/func/ sd/source/ui/inc/...

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerFiller.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerFiller.hxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerFiller.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerFiller.hxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,89 @@
+/**************************************************************
+ * 
+ * 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
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+#ifndef SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_FILLER_HXX
+#define SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_FILLER_HXX
+
+#include "MasterPageContainer.hxx"
+#include "MasterPageDescriptor.hxx"
+#include "tools/AsynchronousTask.hxx"
+
+namespace sd {
+class TemplateScanner;
+class TemplateEntry;
+}
+
+namespace sd { namespace sidebar {
+
+/** Fill a MasterPageContainer with information about the available master
+    pages.  These are provided by one default page and from the existing
+    Impress templates.  This is done asynchronously.
+*/
+class MasterPageContainerFiller
+    : public ::sd::tools::AsynchronousTask
+{
+public:
+    class ContainerAdapter
+    {
+    public:
+        virtual MasterPageContainer::Token PutMasterPage (
+            const SharedMasterPageDescriptor& rpDescriptor) = 0;
+        /** This method is called when all Impress templates have been added
+            to the container via the PutMasterPage() method.
+        */
+        virtual void FillingDone (void) = 0;
+    };
+    
+    MasterPageContainerFiller (ContainerAdapter& rContainerAdapter);
+    virtual ~MasterPageContainerFiller (void);
+    
+    /** Run the next step of the task.  After HasNextStep() returns false
+        this method should ignore further calls.
+    */
+    virtual void RunNextStep (void);
+
+    /** Return <TRUE/> when there is at least one more step to execute.
+        When the task has been executed completely then <FALSE/> is
+        returned.
+    */
+    virtual bool HasNextStep (void);
+
+private:
+    ContainerAdapter& mrContainerAdapter;
+    // Remember what the next step has to do.
+    enum State {
+        INITIALIZE_TEMPLATE_SCANNER,
+        SCAN_TEMPLATE,
+        ADD_TEMPLATE,
+        ERROR,
+        DONE
+    } meState;
+    ::std::auto_ptr<TemplateScanner> mpScannerTask;
+    const TemplateEntry* mpLastAddedEntry;
+    int mnIndex;
+    
+    State ScanTemplate (void);
+    State AddTemplate (void);
+};
+
+} } // end of namespace sd::sidebar
+
+#endif

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerProviders.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerProviders.cxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerProviders.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerProviders.cxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,420 @@
+/**************************************************************
+ * 
+ * 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
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include "MasterPageContainerProviders.hxx"
+
+#include "DrawDocShell.hxx"
+#include "drawdoc.hxx"
+#include "PreviewRenderer.hxx"
+#include <comphelper/processfactory.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <unotools/ucbstreamhelper.hxx>
+#include <vcl/image.hxx>
+#include <vcl/pngread.hxx>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace sd { namespace sidebar {
+
+
+//===== PagePreviewProvider ===================================================
+
+PagePreviewProvider::PagePreviewProvider (void)
+{
+}
+
+
+
+
+Image PagePreviewProvider::operator () (
+    int nWidth,
+    SdPage* pPage,
+    ::sd::PreviewRenderer& rRenderer)
+{
+    Image aPreview;
+    
+    if (pPage != NULL)
+    {
+        // Use the given renderer to create a preview of the given page
+        // object.
+        aPreview = rRenderer.RenderPage(
+            pPage,
+            nWidth,
+            String::CreateFromAscii(""),
+            false);
+    }
+
+    return aPreview;
+}
+
+
+
+
+int PagePreviewProvider::GetCostIndex (void)
+{
+    return 5;
+}
+
+
+
+
+bool PagePreviewProvider::NeedsPageObject (void)
+{
+    return true;
+}
+
+
+
+
+//===== TemplatePreviewProvider ===============================================
+
+TemplatePreviewProvider::TemplatePreviewProvider (const ::rtl::OUString& rsURL)
+    : msURL(rsURL)
+{
+}
+
+
+
+
+Image TemplatePreviewProvider::operator() (
+    int nWidth,
+    SdPage* pPage,
+    ::sd::PreviewRenderer& rRenderer)
+{
+    // Unused parameters.
+    (void)nWidth;
+    (void)pPage; 
+    (void)rRenderer;
+    
+    // Load the thumbnail from a template document.
+	uno::Reference<io::XInputStream> xIStream;
+
+    uno::Reference< lang::XMultiServiceFactory > xServiceManager (
+        ::comphelper::getProcessServiceFactory());
+	if (xServiceManager.is())
+	{
+		try
+        {
+			uno::Reference<lang::XSingleServiceFactory> xStorageFactory(
+				xServiceManager->createInstance( 
+                    ::rtl::OUString::createFromAscii(
+                        "com.sun.star.embed.StorageFactory")),
+				uno::UNO_QUERY);
+		
+			if (xStorageFactory.is())
+			{
+				uno::Sequence<uno::Any> aArgs (2);
+				aArgs[0] <<= msURL;
+				aArgs[1] <<= embed::ElementModes::READ;
+				uno::Reference<embed::XStorage> xDocStorage (
+                    xStorageFactory->createInstanceWithArguments(aArgs),
+                    uno::UNO_QUERY);
+
+                try
+                {
+                    if (xDocStorage.is())
+                    {
+                        uno::Reference<embed::XStorage> xStorage (
+                            xDocStorage->openStorageElement(
+                                ::rtl::OUString::createFromAscii("Thumbnails"),
+                                embed::ElementModes::READ));
+                        if (xStorage.is())
+                        {
+                            uno::Reference<io::XStream> xThumbnailCopy (
+                                xStorage->cloneStreamElement(
+                                    ::rtl::OUString::createFromAscii(
+                                        "thumbnail.png")));
+                            if (xThumbnailCopy.is())
+                                xIStream = xThumbnailCopy->getInputStream();
+                        }
+                    }
+                }
+                catch (uno::Exception& rException)
+                {
+                    OSL_TRACE (
+                        "caught exception while trying to access Thumbnail/thumbnail.png of %s: %s",
+                        ::rtl::OUStringToOString(msURL,
+                            RTL_TEXTENCODING_UTF8).getStr(),
+                        ::rtl::OUStringToOString(rException.Message,
+                            RTL_TEXTENCODING_UTF8).getStr());
+                }
+
+                try
+                {
+                    // An (older) implementation had a bug - The storage
+                    // name was "Thumbnail" instead of "Thumbnails".  The
+                    // old name is still used as fallback but this code can
+                    // be removed soon.
+                    if ( ! xIStream.is())
+                    {
+                        uno::Reference<embed::XStorage> xStorage (
+                            xDocStorage->openStorageElement(
+                                ::rtl::OUString::createFromAscii("Thumbnail"),
+                                embed::ElementModes::READ));
+                        if (xStorage.is())
+                        {
+                            uno::Reference<io::XStream> xThumbnailCopy (
+                                xStorage->cloneStreamElement(
+                                    ::rtl::OUString::createFromAscii(
+                                        "thumbnail.png")));
+                            if (xThumbnailCopy.is())
+                                xIStream = xThumbnailCopy->getInputStream();
+                        }
+					}
+                }
+                catch (uno::Exception& rException)
+                {
+                    OSL_TRACE (
+                        "caught exception while trying to access Thumbnails/thumbnail.png of %s: %s",
+                        ::rtl::OUStringToOString(msURL,
+                            RTL_TEXTENCODING_UTF8).getStr(),
+                        ::rtl::OUStringToOString(rException.Message,
+                            RTL_TEXTENCODING_UTF8).getStr());
+                }
+			}
+		}
+		catch (uno::Exception& rException)
+		{
+            OSL_TRACE (
+                "caught exception while trying to access tuhmbnail of %s: %s",
+                ::rtl::OUStringToOString(msURL,
+                    RTL_TEXTENCODING_UTF8).getStr(),
+                ::rtl::OUStringToOString(rException.Message,
+                    RTL_TEXTENCODING_UTF8).getStr());
+        }
+	}
+
+    // Extract the image from the stream.
+    BitmapEx aThumbnail;
+	if (xIStream.is())
+    {
+        ::std::auto_ptr<SvStream> pStream (
+            ::utl::UcbStreamHelper::CreateStream (xIStream));
+        ::vcl::PNGReader aReader (*pStream);
+        aThumbnail = aReader.Read ();
+    }
+
+    // Note that the preview is returned without scaling it to the desired
+    // width.  This gives the caller the chance to take advantage of a
+    // possibly larger resolution then was asked for.
+    return aThumbnail;
+}
+
+
+
+
+int TemplatePreviewProvider::GetCostIndex (void)
+{
+    return 10;
+}
+
+
+
+
+bool TemplatePreviewProvider::NeedsPageObject (void)
+{
+    return false;
+}
+
+
+
+
+//===== TemplatePageObjectProvider =============================================
+
+TemplatePageObjectProvider::TemplatePageObjectProvider (const ::rtl::OUString& rsURL)
+    : msURL(rsURL),
+      mxDocumentShell()
+{
+}
+
+
+
+
+SdPage* TemplatePageObjectProvider::operator() (SdDrawDocument* pContainerDocument)
+{
+    // Unused parameters.
+    (void)pContainerDocument;
+    
+    SdPage* pPage = NULL;
+    
+    mxDocumentShell = NULL;
+    ::sd::DrawDocShell* pDocumentShell = NULL;
+    try
+    {
+        // Load the template document and return its first page.
+        pDocumentShell = LoadDocument (msURL);
+        if (pDocumentShell != NULL)
+        {
+            SdDrawDocument* pDocument = pDocumentShell->GetDoc();
+            if (pDocument != NULL)
+            {
+                pPage = pDocument->GetMasterSdPage(0, PK_STANDARD);
+                // In order to make the newly loaded master page deletable
+                // when copied into documents it is marked as no "precious".
+                // When it is modified then it is marked as "precious".
+                if (pPage != NULL)
+                    pPage->SetPrecious(false);
+            }
+        }
+    }
+    catch (uno::RuntimeException)
+    {
+        DBG_UNHANDLED_EXCEPTION();
+        pPage = NULL;
+    }
+
+    return pPage;
+}
+
+
+
+
+::sd::DrawDocShell* TemplatePageObjectProvider::LoadDocument (const ::rtl::OUString& sFileName)
+{
+	SfxApplication* pSfxApp = SFX_APP();
+    SfxItemSet* pSet = new SfxAllItemSet (pSfxApp->GetPool());
+    pSet->Put (SfxBoolItem (SID_TEMPLATE, sal_True));
+    pSet->Put (SfxBoolItem (SID_PREVIEW, sal_True));
+    if (pSfxApp->LoadTemplate (mxDocumentShell, sFileName, sal_True, pSet))
+    {
+        mxDocumentShell = NULL;
+    }
+    SfxObjectShell* pShell = mxDocumentShell;
+    return PTR_CAST(::sd::DrawDocShell,pShell);
+}
+
+
+
+
+int TemplatePageObjectProvider::GetCostIndex (void)
+{
+    return 20;
+}
+
+
+
+
+bool TemplatePageObjectProvider::operator== (const PageObjectProvider& rProvider)
+{
+    const TemplatePageObjectProvider* pTemplatePageObjectProvider
+        = dynamic_cast<const TemplatePageObjectProvider*>(&rProvider);
+    if (pTemplatePageObjectProvider != NULL)
+        return (msURL == pTemplatePageObjectProvider->msURL);
+    else
+        return false;
+}
+
+
+
+
+//===== DefaultPageObjectProvider ==============================================
+
+DefaultPageObjectProvider::DefaultPageObjectProvider (void)
+{
+}
+
+
+
+
+SdPage* DefaultPageObjectProvider::operator () (SdDrawDocument* pContainerDocument)
+{
+    SdPage* pLocalMasterPage = NULL;
+    if (pContainerDocument != NULL)
+    {
+        sal_Int32 nIndex (0);
+        SdPage* pLocalSlide = pContainerDocument->GetSdPage((sal_uInt16)nIndex, PK_STANDARD);
+        if (pLocalSlide!=NULL && pLocalSlide->TRG_HasMasterPage())
+            pLocalMasterPage = dynamic_cast<SdPage*>(&pLocalSlide->TRG_GetMasterPage());
+    }
+
+    if (pLocalMasterPage == NULL)
+    {
+        DBG_ASSERT(false, "can not create master page for slide");
+    }
+
+    return pLocalMasterPage;
+}
+
+
+
+
+int DefaultPageObjectProvider::GetCostIndex (void)
+{
+    return 15;
+}
+
+
+
+
+bool DefaultPageObjectProvider::operator== (const PageObjectProvider& rProvider)
+{
+    return (dynamic_cast<const DefaultPageObjectProvider*>(&rProvider) != NULL);
+}
+
+
+
+
+//===== ExistingPageProvider ==================================================
+
+ExistingPageProvider::ExistingPageProvider (SdPage* pPage)
+    : mpPage(pPage)
+{
+}
+
+
+
+
+SdPage* ExistingPageProvider::operator() (SdDrawDocument* pDocument)
+{
+    (void)pDocument; // Unused parameter.
+    
+    return mpPage;
+}
+
+
+
+
+int ExistingPageProvider::GetCostIndex (void)
+{
+    return 0;
+}
+
+
+
+
+bool ExistingPageProvider::operator== (const PageObjectProvider& rProvider)
+{
+    const ExistingPageProvider* pExistingPageProvider
+        = dynamic_cast<const ExistingPageProvider*>(&rProvider);
+    if (pExistingPageProvider != NULL)
+        return (mpPage == pExistingPageProvider->mpPage);
+    else
+        return false;
+}
+
+
+} } // end of namespace sd::sidebar

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerProviders.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerProviders.hxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerProviders.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerProviders.hxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,183 @@
+/**************************************************************
+ * 
+ * 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
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+#ifndef SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_PROVIDERS_HXX
+#define SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_PROVIDERS_HXX
+
+#include <rtl/ustring.hxx>
+#include <sfx2/objsh.hxx>
+
+class Image;
+class SdDrawDocument;
+class SdPage;
+namespace sd { class PreviewRenderer; }
+namespace sd { class DrawDocShell; }
+
+
+namespace sd { namespace sidebar {
+
+
+/** Interface for a provider of page objects.  It is used by the
+    MasterPageDescriptor to create master page objects on demand.
+*/
+class PageObjectProvider
+{
+public:
+    /** Return a master page either by returning an already existing one, by
+        creating a new page, or by loading a document.
+        @param pDocument
+            The document of the MasterPageContainer.  It may be used to
+            create new pages.
+    */
+    virtual SdPage* operator() (SdDrawDocument* pDocument) = 0;
+
+    /** An abstract value for the expected cost of providing a master page
+        object.
+        @return
+            A value of 0 represents for the lowest cost, i.e. an almost
+            immediate return.  Positive values stand for higher costs.
+            Negative values are not supported.
+    */
+    virtual int GetCostIndex (void) = 0;
+
+    virtual bool operator== (const PageObjectProvider& rProvider) = 0;
+};
+
+
+
+
+class PreviewProvider
+{
+public:
+    /** Create a preview image in the specified width.
+        @param nWidth
+            Requested width of the preview.  The calling method can cope
+            with other sizes as well but the resulting image quality is
+            better when the returned image has the requested size.
+        @param pPage
+            Page object for which a preview is requested.  This may be NULL
+            when the page object is expensive to get and the PreviewProvider
+            does not need this object (NeedsPageObject() returns false.)
+        @param rRenderer
+            This PreviewRenderer may be used by the PreviewProvider to
+            create a preview image.
+    */
+    virtual Image operator() (int nWidth, SdPage* pPage, ::sd::PreviewRenderer& rRenderer) = 0;
+
+    /** Return a value that indicates how expensive the creation of a
+        preview image is.  The higher the returned value the more expensive
+        is the preview creation.  Return 0 when the preview is already
+        present and can be returned immediately.
+    */
+    virtual int GetCostIndex (void) = 0;
+
+    /** Return whether the page object passed is necessary to create a
+        preview.
+    */
+    virtual bool NeedsPageObject (void) = 0;
+};
+
+
+
+
+/** Provide previews of existing page objects by rendering them.
+*/
+class PagePreviewProvider : public PreviewProvider
+{
+public:
+    PagePreviewProvider (void);
+    virtual Image operator () (int nWidth, SdPage* pPage, ::sd::PreviewRenderer& rRenderer);
+    virtual int GetCostIndex (void);
+    virtual bool NeedsPageObject (void);
+private:
+};
+
+
+
+
+/** Provide master page objects for template documents for which only the
+    URL is given.
+*/
+class TemplatePageObjectProvider : public PageObjectProvider
+{
+public:
+    TemplatePageObjectProvider (const ::rtl::OUString& rsURL);
+    virtual ~TemplatePageObjectProvider (void) {};
+    virtual SdPage* operator () (SdDrawDocument* pDocument);
+    virtual int GetCostIndex (void);
+    virtual bool operator== (const PageObjectProvider& rProvider);
+private:
+    ::rtl::OUString msURL;
+    SfxObjectShellLock mxDocumentShell;
+    ::sd::DrawDocShell* LoadDocument (const ::rtl::OUString& sFileName);
+};
+
+
+
+
+/** Provide previews for template documents by loading the thumbnails from
+    the documents.
+*/
+class TemplatePreviewProvider : public PreviewProvider
+{
+public:
+    TemplatePreviewProvider (const ::rtl::OUString& rsURL);
+    virtual ~TemplatePreviewProvider (void) {};
+    virtual Image operator() (int nWidth, SdPage* pPage, ::sd::PreviewRenderer& rRenderer);
+    virtual int GetCostIndex (void);
+    virtual bool NeedsPageObject (void);
+private:
+    ::rtl::OUString msURL;
+};
+
+
+
+
+/** Create an empty default master page.
+*/
+class DefaultPageObjectProvider : public PageObjectProvider
+{
+public:
+    DefaultPageObjectProvider (void);
+    virtual SdPage* operator () (SdDrawDocument* pDocument);
+    virtual int GetCostIndex (void);
+    virtual bool operator== (const PageObjectProvider& rProvider);
+};
+
+
+
+/** This implementation of the PageObjectProvider simply returns an already
+    existing master page object.
+*/
+class ExistingPageProvider : public PageObjectProvider
+{
+public:
+    ExistingPageProvider (SdPage* pPage);
+    virtual SdPage* operator() (SdDrawDocument* pDocument);
+    virtual int GetCostIndex (void);
+    virtual bool operator== (const PageObjectProvider& rProvider);
+private:
+    SdPage* mpPage;
+};
+
+} } // end of namespace sd::sidebar
+
+#endif

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerQueue.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerQueue.cxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerQueue.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerQueue.cxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,297 @@
+/**************************************************************
+ * 
+ * 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
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include "MasterPageContainerQueue.hxx"
+
+#include "tools/IdleDetection.hxx"
+
+#include <set>
+
+namespace sd { namespace sidebar {
+
+const sal_Int32 MasterPageContainerQueue::snDelayedCreationTimeout (15);
+const sal_Int32 MasterPageContainerQueue::snDelayedCreationTimeoutWhenNotIdle (100);
+const sal_Int32 MasterPageContainerQueue::snMasterPagePriorityBoost (5);
+const sal_Int32 MasterPageContainerQueue::snWaitForMoreRequestsPriorityThreshold (-10);
+sal_uInt32 MasterPageContainerQueue::snWaitForMoreRequestsCount(15);
+
+//===== MasterPageContainerQueue::PreviewCreationRequest ======================
+
+class MasterPageContainerQueue::PreviewCreationRequest
+{
+public:
+    PreviewCreationRequest (const SharedMasterPageDescriptor& rpDescriptor, int nPriority)
+        : mpDescriptor(rpDescriptor),
+          mnPriority(nPriority)
+    {}
+    SharedMasterPageDescriptor mpDescriptor;
+    int mnPriority;
+    class Compare {public:
+        bool operator() (const PreviewCreationRequest& r1,const PreviewCreationRequest& r2)
+        {
+            if (r1.mnPriority != r2.mnPriority)
+            {
+                // Prefer requests with higher priority.
+                return r1.mnPriority > r2.mnPriority;
+            }
+            else
+            {
+                // Prefer tokens that have been earlier created (those with lower
+                // value).
+                return r1.mpDescriptor->maToken < r2.mpDescriptor->maToken;
+            }
+        }
+    };
+    class CompareToken {public:
+        MasterPageContainer::Token maToken;
+        CompareToken(MasterPageContainer::Token aToken) : maToken(aToken) {}
+        bool operator() (const PreviewCreationRequest& rRequest)
+        {     return maToken==rRequest.mpDescriptor->maToken; }
+    };
+};
+
+
+
+
+//===== MasterPageContainerQueue::RequestQueue ================================
+
+class MasterPageContainerQueue::RequestQueue
+    : public ::std::set<PreviewCreationRequest,PreviewCreationRequest::Compare>
+{
+public:
+    RequestQueue (void) {}
+};
+
+
+
+
+//===== MasterPageContainerQueue ==============================================
+
+MasterPageContainerQueue* MasterPageContainerQueue::Create (
+    const ::boost::weak_ptr<ContainerAdapter>& rpContainer)
+{
+    MasterPageContainerQueue* pQueue = new MasterPageContainerQueue(rpContainer);
+    pQueue->LateInit();
+    return pQueue;
+}
+
+
+
+
+MasterPageContainerQueue::MasterPageContainerQueue (
+    const ::boost::weak_ptr<ContainerAdapter>& rpContainer)
+    : mpWeakContainer(rpContainer),
+      mpRequestQueue(new RequestQueue()),
+      maDelayedPreviewCreationTimer(),
+      mnRequestsServedCount(0)
+{
+}
+
+
+
+
+MasterPageContainerQueue::~MasterPageContainerQueue (void)
+{
+    maDelayedPreviewCreationTimer.Stop();
+    while ( ! mpRequestQueue->empty())
+        mpRequestQueue->erase(mpRequestQueue->begin());
+}
+
+
+
+
+void MasterPageContainerQueue::LateInit (void)
+{
+    // Set up the timer for the delayed creation of preview bitmaps.
+    maDelayedPreviewCreationTimer.SetTimeout (snDelayedCreationTimeout);
+    Link aLink (LINK(this,MasterPageContainerQueue,DelayedPreviewCreation));
+    maDelayedPreviewCreationTimer.SetTimeoutHdl(aLink);
+}
+
+
+
+
+bool MasterPageContainerQueue::RequestPreview (const SharedMasterPageDescriptor& rpDescriptor)
+{
+    bool bSuccess (false);
+    if (rpDescriptor.get() != NULL
+        && rpDescriptor->maLargePreview.GetSizePixel().Width() == 0)
+    {
+        sal_Int32 nPriority (CalculatePriority(rpDescriptor));
+        
+        // Add a new or replace an existing request.
+        RequestQueue::iterator iRequest (::std::find_if(
+            mpRequestQueue->begin(),
+            mpRequestQueue->end(),
+            PreviewCreationRequest::CompareToken(rpDescriptor->maToken)));
+        // When a request for the same token exists then the lowest of the
+        // two priorities is used.
+        if (iRequest != mpRequestQueue->end())
+            if (iRequest->mnPriority < nPriority)
+            {
+                mpRequestQueue->erase(iRequest);
+                iRequest = mpRequestQueue->end();
+            }
+
+        // Add a new request when none exists (or has just been erased).
+        if (iRequest == mpRequestQueue->end())
+        {
+            mpRequestQueue->insert(PreviewCreationRequest(rpDescriptor,nPriority));
+            maDelayedPreviewCreationTimer.Start();
+            bSuccess = true;
+        }
+    }
+    return bSuccess;
+}
+
+
+
+
+sal_Int32 MasterPageContainerQueue::CalculatePriority (
+    const SharedMasterPageDescriptor& rpDescriptor) const
+{
+    sal_Int32 nPriority;
+
+    // The cost is used as a starting value.
+    int nCost (0);
+    if (rpDescriptor->mpPreviewProvider.get() != NULL)
+    {
+        nCost = rpDescriptor->mpPreviewProvider->GetCostIndex();
+        if (rpDescriptor->mpPreviewProvider->NeedsPageObject())
+            if (rpDescriptor->mpPageObjectProvider.get() != NULL)
+                nCost += rpDescriptor->mpPageObjectProvider->GetCostIndex();
+    }
+
+    // Its negative value is used so that requests with a low cost are
+    // preferred over those with high costs.
+    nPriority = -nCost;
+
+    // Add a term that introduces an order based on the appearance in the
+    // AllMasterPagesSelector.
+    nPriority -= rpDescriptor->maToken / 3;
+    
+    // Process requests for the CurrentMasterPagesSelector first.
+    if (rpDescriptor->meOrigin == MasterPageContainer::MASTERPAGE)
+        nPriority += snMasterPagePriorityBoost;
+
+    return nPriority;
+}
+
+
+
+
+IMPL_LINK(MasterPageContainerQueue, DelayedPreviewCreation, Timer*, pTimer)
+{
+    bool bIsShowingFullScreenShow (false);
+    bool bWaitForMoreRequests (false);
+
+    do
+    {
+        if (mpRequestQueue->size() == 0)
+            break;
+
+        // First check whether the system is idle.
+        sal_Int32 nIdleState (tools::IdleDetection::GetIdleState());
+        if (nIdleState != tools::IdleDetection::IDET_IDLE)
+        {
+            if ((nIdleState&tools::IdleDetection::IDET_FULL_SCREEN_SHOW_ACTIVE) != 0)
+                bIsShowingFullScreenShow = true;
+            break;
+        }
+
+        PreviewCreationRequest aRequest (*mpRequestQueue->begin());
+
+        // Check if the request should really be processed right now.
+        // Reasons to not do it are when its cost is high and not many other
+        // requests have been inserted into the queue that would otherwise
+        // be processed first.
+        if (aRequest.mnPriority < snWaitForMoreRequestsPriorityThreshold
+            && (mnRequestsServedCount+mpRequestQueue->size() < snWaitForMoreRequestsCount))
+        {
+            // Wait for more requests before this one is processed.  Note
+            // that the queue processing is not started anew when this
+            // method is left.  That is done when the next request is
+            // inserted.
+            bWaitForMoreRequests = true;
+            break;
+        }
+
+        mpRequestQueue->erase(mpRequestQueue->begin());
+        
+        if (aRequest.mpDescriptor.get() != NULL)
+        {
+            mnRequestsServedCount += 1;
+            if ( ! mpWeakContainer.expired())
+            {
+                ::boost::shared_ptr<ContainerAdapter> pContainer (mpWeakContainer);
+                if (pContainer.get() != NULL)
+                    pContainer->UpdateDescriptor(aRequest.mpDescriptor,false,true,true);
+            }
+        }
+    }
+    while (false);
+    
+    if (mpRequestQueue->size() > 0 && ! bWaitForMoreRequests)
+    {
+        int nTimeout (snDelayedCreationTimeout);
+        if (bIsShowingFullScreenShow)
+            nTimeout = snDelayedCreationTimeoutWhenNotIdle;
+        maDelayedPreviewCreationTimer.SetTimeout(nTimeout);
+        pTimer->Start();
+    }
+
+    return 0;
+}
+
+
+
+
+bool MasterPageContainerQueue::HasRequest (MasterPageContainer::Token aToken) const
+{
+    RequestQueue::iterator iRequest (::std::find_if(
+        mpRequestQueue->begin(),
+        mpRequestQueue->end(),
+        PreviewCreationRequest::CompareToken(aToken)));
+    return (iRequest != mpRequestQueue->end());
+}
+
+
+
+
+bool MasterPageContainerQueue::IsEmpty (void) const
+{
+    return mpRequestQueue->empty();
+}
+
+
+
+
+void MasterPageContainerQueue::ProcessAllRequests (void)
+{
+    snWaitForMoreRequestsCount = 0;
+    if (mpRequestQueue->size() > 0)
+        maDelayedPreviewCreationTimer.Start();
+}
+
+
+} } // end of namespace sd::sidebar

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerQueue.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerQueue.hxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerQueue.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageContainerQueue.hxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,130 @@
+/**************************************************************
+ * 
+ * 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
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+#ifndef SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_QUEUE_HXX
+#define SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_QUEUE_HXX
+
+#include "MasterPageContainer.hxx"
+#include "MasterPageDescriptor.hxx"
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+namespace sd { namespace sidebar {
+
+
+/** The queue stores and processes all requests from a MasterPageContainer
+    for the creation of previews.
+    The order of request processing and its timing is controlled by a
+    heuristic that uses values given with each request and which is
+    controlled by various parameters that are described below.
+*/
+class MasterPageContainerQueue
+{
+public:
+    class ContainerAdapter { public:
+        virtual bool UpdateDescriptor (
+            const SharedMasterPageDescriptor& rpDescriptor,
+            bool bForcePageObject,
+            bool bForcePreview,
+            bool bSendEvents) = 0;
+    };
+
+    static MasterPageContainerQueue* Create (
+        const ::boost::weak_ptr<ContainerAdapter>& rpContainer);
+    virtual ~MasterPageContainerQueue (void);
+
+    /** This method is typically called for entries in the container for
+        which GetPreviewState() returns OS_CREATABLE.  The creation of the
+        preview is then scheduled to be executed asynchronously at a later
+        point in time.  When the preview is available the change listeners
+        will be notified.
+    */
+    bool RequestPreview (const SharedMasterPageDescriptor& rDescriptor);
+
+    /** Return <TRUE/> when there is a request currently in the queue for
+        the given token.
+    */
+    bool HasRequest (MasterPageContainer::Token aToken) const;
+
+    /** Return <TRUE/> when there is at least one request in the queue.
+    */
+    bool IsEmpty (void) const;
+
+    /** After this call the queue does not wait anymore for requests with
+        higher priority when only a small number of requests with lower
+        priority are present.  This method should be called when all
+        templates are inserted into the MasterPageContainer.
+    */
+    void ProcessAllRequests (void);
+    
+private:
+    ::boost::weak_ptr<ContainerAdapter> mpWeakContainer;
+    class PreviewCreationRequest;
+    class RequestQueue;
+    ::boost::scoped_ptr<RequestQueue> mpRequestQueue;
+    Timer maDelayedPreviewCreationTimer;
+    sal_uInt32 mnRequestsServedCount;
+
+    // There are a couple of values that define various aspects of the
+    // heuristic that defines the order and timing in which requests for
+    // preview creation are processed.
+    
+    /** The time to wait (in milliseconds) between the creation of previews.
+    */
+    static const sal_Int32 snDelayedCreationTimeout;
+
+    /** The time to wait when the system is not idle.
+    */
+    static const sal_Int32 snDelayedCreationTimeoutWhenNotIdle;
+    
+    /** Requests for previews of master pages in a document have their
+        priority increased by this value.
+    */
+    static const sal_Int32 snMasterPagePriorityBoost;
+
+    /** When only requests which a priority lower than this threshold exist
+        and not many requests have been made yet then wait with processing
+        them until more requests are present.
+    */
+    static const sal_Int32 snWaitForMoreRequestsPriorityThreshold;
+
+    /** When only requests which a priority lower than a threshold exist
+        and not more requests than this number have been made or already
+        processed then wait with processing them until more requests are
+        present.
+    */
+    static sal_uInt32 snWaitForMoreRequestsCount;
+    
+    MasterPageContainerQueue (const ::boost::weak_ptr<ContainerAdapter>& rpContainer);
+    void LateInit (void);
+
+    /** Calculate the priority that defines the order in which requests
+        are processed.
+    */
+    sal_Int32 CalculatePriority (const SharedMasterPageDescriptor& rDescriptor) const;
+    
+    DECL_LINK(DelayedPreviewCreation, Timer *);
+};
+
+} } // end of namespace sd::sidebar
+
+#endif

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageDescriptor.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageDescriptor.cxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageDescriptor.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageDescriptor.cxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,416 @@
+/**************************************************************
+ * 
+ * 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
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include "MasterPageDescriptor.hxx"
+
+#include "DocumentHelper.hxx"
+#include "sdpage.hxx"
+#include <tools/urlobj.hxx>
+
+namespace sd { namespace sidebar {
+
+
+//===== MasterPageDescriptor ==================================================
+
+MasterPageDescriptor::MasterPageDescriptor (
+    MasterPageContainer::Origin eOrigin,
+    const sal_Int32 nTemplateIndex,
+    const String& rsURL,
+    const String& rsPageName,
+    const String& rsStyleName,
+    const bool bIsPrecious,
+    const ::boost::shared_ptr<PageObjectProvider>& rpPageObjectProvider,
+    const ::boost::shared_ptr<PreviewProvider>& rpPreviewProvider)
+    : maToken(MasterPageContainer::NIL_TOKEN),
+      meOrigin(eOrigin),
+      msURL(INetURLObject(rsURL).GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS)),
+      msPageName(rsPageName),
+      msStyleName(rsStyleName),
+      mbIsPrecious(bIsPrecious),
+      mpMasterPage(NULL),
+      mpSlide(NULL),
+      maSmallPreview(),
+      maLargePreview(),
+      mpPreviewProvider(rpPreviewProvider),
+      mpPageObjectProvider(rpPageObjectProvider),
+      mnTemplateIndex(nTemplateIndex),
+      meURLClassification(URLCLASS_UNDETERMINED),
+      mnUseCount(0)
+{
+}
+   
+
+
+
+MasterPageDescriptor::MasterPageDescriptor (const MasterPageDescriptor& rDescriptor)
+    : maToken(rDescriptor.maToken),
+      meOrigin(rDescriptor.meOrigin),
+      msURL(rDescriptor.msURL),
+      msPageName(rDescriptor.msPageName),
+      msStyleName(rDescriptor.msStyleName),
+      mbIsPrecious(rDescriptor.mbIsPrecious),
+      mpMasterPage(rDescriptor.mpMasterPage),
+      mpSlide(rDescriptor.mpSlide),
+      maSmallPreview(rDescriptor.maSmallPreview),
+      maLargePreview(rDescriptor.maLargePreview),
+      mpPreviewProvider(rDescriptor.mpPreviewProvider),
+      mpPageObjectProvider(rDescriptor.mpPageObjectProvider),
+      mnTemplateIndex(rDescriptor.mnTemplateIndex),
+      meURLClassification(rDescriptor.meURLClassification),
+      mnUseCount(rDescriptor.mnUseCount)
+{
+}
+
+
+
+
+MasterPageDescriptor::~MasterPageDescriptor (void)
+{
+}
+
+
+
+
+void MasterPageDescriptor::SetToken (MasterPageContainer::Token aToken)
+{
+    maToken = aToken;
+}
+
+
+
+
+Image MasterPageDescriptor::GetPreview (MasterPageContainer::PreviewSize eSize)
+{
+    if (eSize == MasterPageContainer::SMALL)
+        return maSmallPreview;
+    else
+        return maLargePreview;
+}
+
+
+
+
+::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> >
+    MasterPageDescriptor::Update (
+        const MasterPageDescriptor& rDescriptor)
+{
+    bool bDataChanged (false);
+    bool bIndexChanged (false);
+    bool bPreviewChanged (false);
+
+    if (meOrigin==MasterPageContainer::UNKNOWN
+        && rDescriptor.meOrigin!=MasterPageContainer::UNKNOWN)
+    {
+        meOrigin = rDescriptor.meOrigin;
+        bIndexChanged = true;
+    }
+    
+    if (msURL.getLength()==0 && rDescriptor.msURL.getLength()!=0)
+    {
+        msURL = rDescriptor.msURL;
+        bDataChanged = true;
+    }
+    
+    if (msPageName.getLength()==0 && rDescriptor.msPageName.getLength()!=0)
+    {
+        msPageName = rDescriptor.msPageName;
+        bDataChanged = true;
+    }
+    
+    if (msStyleName.getLength()==0 && rDescriptor.msStyleName.getLength()!=0)
+    {
+        msStyleName = rDescriptor.msStyleName;
+        bDataChanged = true;
+    }
+    
+    if (mpPageObjectProvider.get()==NULL && rDescriptor.mpPageObjectProvider.get()!=NULL)
+    {
+        mpPageObjectProvider = rDescriptor.mpPageObjectProvider;
+        bDataChanged = true;
+    }
+    
+     if (mpPreviewProvider.get()==NULL && rDescriptor.mpPreviewProvider.get()!=NULL)
+     {
+         mpPreviewProvider = rDescriptor.mpPreviewProvider;
+         bPreviewChanged = true;
+     }
+
+     if (mnTemplateIndex<0 && rDescriptor.mnTemplateIndex>=0)
+     {
+         mnTemplateIndex = rDescriptor.mnTemplateIndex;
+         bIndexChanged = true;
+     }
+
+     // Prepare the list of event types that will be returned.
+     ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pResult;
+     if (bDataChanged || bIndexChanged || bPreviewChanged)
+     {
+         pResult.reset(new std::vector<MasterPageContainerChangeEvent::EventType>());
+         if (bDataChanged)
+             pResult->push_back(MasterPageContainerChangeEvent::DATA_CHANGED);
+         if (bIndexChanged)
+             pResult->push_back(MasterPageContainerChangeEvent::INDEX_CHANGED);
+         if (bPreviewChanged)
+             pResult->push_back(MasterPageContainerChangeEvent::PREVIEW_CHANGED);
+     }
+     
+     return pResult;
+}
+
+
+
+
+bool MasterPageDescriptor::UpdatePageObject (
+    sal_Int32 nCostThreshold,
+    SdDrawDocument* pDocument)
+{
+    bool bModified (false);
+    
+    // Update the page object when that is not yet known.
+    if (mpMasterPage == NULL
+        && mpPageObjectProvider.get()!=NULL
+        && (nCostThreshold<0 || mpPageObjectProvider->GetCostIndex()<=nCostThreshold))
+    {
+        // Note that pDocument may be NULL.
+            
+        SdPage* pPage = (*mpPageObjectProvider)(pDocument);
+        if (meOrigin == MasterPageContainer::MASTERPAGE)
+        {
+            mpMasterPage = pPage;
+            if (mpMasterPage != NULL)
+                mpMasterPage->SetPrecious(mbIsPrecious);
+        }
+        else
+        {
+            // Master pages from templates are copied into the local document.
+            if (pDocument != NULL)
+                mpMasterPage = DocumentHelper::CopyMasterPageToLocalDocument(*pDocument,pPage);
+            mpSlide = DocumentHelper::GetSlideForMasterPage(mpMasterPage);
+        }
+
+        if (mpMasterPage != NULL)
+        {
+            // Update page name and style name.
+            if (msPageName.getLength() == 0)
+                msPageName = mpMasterPage->GetName();
+            msStyleName = mpMasterPage->GetName();
+
+            // Delete an existing substitution. The next request for a preview
+            // will create the real one.
+            maSmallPreview = Image();
+            maLargePreview = Image();
+            mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider());
+        }
+        else
+        {
+            DBG_ASSERT(false, "UpdatePageObject: master page is NULL");
+        }
+
+        bModified = true;
+    }
+
+    return bModified;
+}
+
+
+
+
+bool MasterPageDescriptor::UpdatePreview (
+    sal_Int32 nCostThreshold,
+    const Size& rSmallSize,
+    const Size& rLargeSize,
+    ::sd::PreviewRenderer& rRenderer)
+{
+    bool bModified (false);
+    
+    // Update the preview when that is not yet known.
+    if (maLargePreview.GetSizePixel().Width()==0
+        && mpPreviewProvider.get()!=NULL
+        && (nCostThreshold<0 || mpPreviewProvider->GetCostIndex()<=nCostThreshold))
+    {
+        SdPage* pPage = mpSlide;
+        if (pPage == NULL)
+        {
+            pPage = mpMasterPage;
+        }
+        maLargePreview = (*mpPreviewProvider)(
+            rLargeSize.Width(),
+            pPage,
+            rRenderer);
+        if (maLargePreview.GetSizePixel().Width() > 0)
+        {
+            // Create the small preview by scaling the large one down.
+            maSmallPreview = rRenderer.ScaleBitmap(
+                maLargePreview.GetBitmapEx(),
+                rSmallSize.Width());
+            // The large preview may not have the desired width.  Scale it
+            // accrodingly.
+            if (maLargePreview.GetSizePixel().Width() != rLargeSize.Width())
+                maLargePreview = rRenderer.ScaleBitmap(
+                    maLargePreview.GetBitmapEx(),
+                    rLargeSize.Width());
+            bModified = true;
+        }
+    }
+
+    return bModified;
+}
+
+
+
+
+MasterPageDescriptor::URLClassification MasterPageDescriptor::GetURLClassification (void)
+{
+    if (meURLClassification == URLCLASS_UNDETERMINED)
+    {
+        if (msURL.getLength() == 0)
+            meURLClassification = URLCLASS_UNKNOWN;
+        else if (msURL.indexOf(::rtl::OUString::createFromAscii("presnt"))>=0)
+        {
+            meURLClassification = URLCLASS_PRESENTATION;
+        }
+        else if (msURL.indexOf(::rtl::OUString::createFromAscii("layout"))>=0)
+        {
+            meURLClassification = URLCLASS_LAYOUT;
+        }
+        else if (msURL.indexOf(::rtl::OUString::createFromAscii("educate"))>=0)
+        {
+            meURLClassification = URLCLASS_OTHER;
+        }
+        else
+        {
+            meURLClassification = URLCLASS_USER;
+        }
+    }
+    
+    return meURLClassification;
+}
+
+
+
+//===== URLComparator =========================================================
+
+MasterPageDescriptor::URLComparator::URLComparator (const ::rtl::OUString& sURL)
+    : msURL(sURL)
+{
+}
+
+
+
+
+bool MasterPageDescriptor::URLComparator::operator() (
+    const SharedMasterPageDescriptor& rDescriptor)
+{
+    if (rDescriptor.get() == NULL)
+        return false;
+    else
+        return rDescriptor->msURL.equals(msURL);
+}
+
+
+
+
+// ===== StyleNameComparator ==================================================
+
+MasterPageDescriptor::StyleNameComparator::StyleNameComparator (const ::rtl::OUString& sStyleName)
+    : msStyleName(sStyleName)
+{
+}
+
+
+
+
+bool MasterPageDescriptor::StyleNameComparator::operator() (
+    const SharedMasterPageDescriptor& rDescriptor)
+{
+    if (rDescriptor.get() == NULL)
+        return false;
+    else
+        return rDescriptor->msStyleName.equals(msStyleName);
+}
+
+
+
+
+//===== PageObjectComparator ==================================================
+
+MasterPageDescriptor::PageObjectComparator::PageObjectComparator (const SdPage* pPageObject) 
+    : mpMasterPage(pPageObject)
+{
+}
+
+
+
+
+bool MasterPageDescriptor::PageObjectComparator::operator() (
+    const SharedMasterPageDescriptor& rDescriptor)
+{
+    if (rDescriptor.get() == NULL)
+        return false;
+    else
+        return rDescriptor->mpMasterPage==mpMasterPage;
+}
+
+
+
+
+//===== AllComparator =========================================================
+
+MasterPageDescriptor::AllComparator::AllComparator(const SharedMasterPageDescriptor& rDescriptor)
+    : mpDescriptor(rDescriptor)
+{
+}
+
+
+
+
+bool MasterPageDescriptor::AllComparator::operator() (const SharedMasterPageDescriptor&rDescriptor)
+{
+    if (rDescriptor.get() == NULL)
+        return false;
+    else
+    {
+        // Take URL, page name, style name, and page object into account
+        // when comparing two descriptors.  When two descriptors are
+        // identical in any of these values then their are thought of as
+        // equivalent.  Only the Origin has to be the same in both
+        // descriptors.
+        return
+            mpDescriptor->meOrigin == rDescriptor->meOrigin
+            && (
+                (mpDescriptor->msURL.getLength()>0
+                    && mpDescriptor->msURL.equals(rDescriptor->msURL))
+                || (mpDescriptor->msPageName.getLength()>0
+                    && mpDescriptor->msPageName.equals(rDescriptor->msPageName))
+                || (mpDescriptor->msStyleName.getLength()>0
+                    && mpDescriptor->msStyleName.equals(rDescriptor->msStyleName))
+                || (mpDescriptor->mpMasterPage!=NULL
+                    && mpDescriptor->mpMasterPage==rDescriptor->mpMasterPage)
+                || (mpDescriptor->mpPageObjectProvider.get()!=NULL
+                    && rDescriptor->mpPageObjectProvider.get()!=NULL
+                    && mpDescriptor->mpPageObjectProvider==rDescriptor->mpPageObjectProvider));
+    }
+}
+
+
+} } // end of namespace sd::sidebar

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageDescriptor.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageDescriptor.hxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageDescriptor.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageDescriptor.hxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,234 @@
+/**************************************************************
+ * 
+ * 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
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+#ifndef SD_SIDEBAR_PANELS_MASTER_PAGE_DESCRIPTOR_HXX
+#define SD_SIDEBAR_PANELS_MASTER_PAGE_DESCRIPTOR_HXX
+
+#include "MasterPageContainer.hxx"
+#include <boost/shared_ptr.hpp>
+
+namespace sd { namespace sidebar {
+
+class PageObjectProvider;
+class PreviewProvider;
+
+class MasterPageDescriptor;
+typedef ::boost::shared_ptr<MasterPageDescriptor> SharedMasterPageDescriptor;
+
+/** A collection of data that is stored for every master page in the
+    MasterpageContainer.
+*/
+class MasterPageDescriptor
+{
+public:
+    MasterPageDescriptor (
+        MasterPageContainer::Origin eOrigin,
+        const sal_Int32 nTemplateIndex,
+        const String& rURL,
+        const String& rPageName,
+        const String& rStyleName,
+        const bool bIsPrecious,
+        const ::boost::shared_ptr<PageObjectProvider>& rpPageObjectProvider,
+        const ::boost::shared_ptr<PreviewProvider>& rpPreviewProvider);
+    MasterPageDescriptor (const MasterPageDescriptor& rDescriptor);
+    ~MasterPageDescriptor (void);
+
+    void SetToken (MasterPageContainer::Token aToken);
+
+    /** Update the called MasterPageDescriptor object with values from the
+        given one.  Only those values are updated that have default values
+        in the called object and that have non-default values in the given
+        one.
+        @return
+            Returns a list of event types for which event notifications have
+            to be sent to listeners.  The list may be empty or NULL.
+    */
+    ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> >
+        Update (
+            const MasterPageDescriptor& rDescriptor);
+    
+    /** This convenience method returns either a small or a large preview,
+        depending on the given size specifier.
+        Note that the previews are not created when they are not present.
+        @return
+            The returned preview may be empty.
+    */
+    Image GetPreview (MasterPageContainer::PreviewSize ePreviewSize);
+
+    /** Use the PreviewProvider to get access to a preview of the master
+        page.
+        
+        Note that this is only done, when either bForce is <TRUE/> or
+        the PreviewProvider::GetCostIndex() returns 0.
+        
+        The small preview is created by scaling the large one, not by
+        calling PreviewProvider::operator() a second time.
+        
+        It is the responsibility of the caller to call UpdatePageObject()
+        before calling this method  when the PreviewProvider can only work
+        when the master page object is present, i.e. its NeedsPageObject()
+        method returns <TRUE/>.
+        
+        @param nCostThreshold
+            When this is zero or positive then the preview is created only
+            when the preview provider has a cost equal to or smaller than
+            this threshold.  A negative value forces the preview to be
+            created, regardless of the cost.
+        @param rSmallSize
+            Size of the small preview.
+        @param rLargeSize
+            Size of the large preview.
+        @param rRenderer
+            A PreviewRenderer object that may be used to create a preview.
+        @return
+            When the previews are successfully provided then <TRUE/> is
+            returned.
+    */
+    bool UpdatePreview (
+        sal_Int32 nCostThreshold,
+        const Size& rSmallSize,
+        const Size& rLargeSize,
+        ::sd::PreviewRenderer& rRenderer);
+
+    /** Use the PageObjectProvider to get access to the master page object.
+        
+        Note that this is only done, when either bForce is <TRUE/> or the
+        PreviewProvider::GetCostIndex() returns 0.
+
+        @param nCostThreshold
+            When this is zero or positive then the page object is created
+            only when the page object provider has a cost equal to or
+            smaller than this threshold.  A negative value forces the
+            page object be created, regardless of the cost.
+        @param pDocument
+            This document of the MasterPageContainer may be used to create
+            a page object with or store one in.
+        @return
+            When the master page object is successfully provided then
+            <TRUE/> is returned.
+    */
+    bool UpdatePageObject (
+        sal_Int32 nCostThreshold,
+        SdDrawDocument* pDocument);
+
+    enum URLClassification {
+        URLCLASS_USER,
+        URLCLASS_LAYOUT,
+        URLCLASS_PRESENTATION,
+        URLCLASS_OTHER,
+        URLCLASS_UNKNOWN,
+        URLCLASS_UNDETERMINED
+    };
+
+    URLClassification GetURLClassification (void);
+    
+    /** The Token under which the MasterPageContainer gives access to the
+        object.
+    */
+    MasterPageContainer::Token maToken;
+
+    /** A rough specification of the origin of the master page.
+    */
+    MasterPageContainer::Origin meOrigin;
+    
+    /** The URL is not empty for master pages loaded from a template
+        document.
+    */
+    ::rtl::OUString msURL;
+    
+    /** Taken from the title of the template file.
+    */
+    ::rtl::OUString msPageName;
+    
+    /** Taken from the master page object.
+    */
+    ::rtl::OUString msStyleName;
+
+    const bool mbIsPrecious;
+
+    /** The actual master page.
+    */
+    SdPage* mpMasterPage;
+    
+    /** A slide that uses the master page.
+    */
+    SdPage* mpSlide;
+    
+    /** A small (the default size) preview of the master page.  May be
+        empty.  When this smaller preview is not empty then the larger one
+        is not empty, too.
+    */
+    Image maSmallPreview;
+    
+    /** A large preview of the master page.  May be empty.  When this larger
+        preview is not empty then the smaller one is not empty, too.
+    */
+    Image maLargePreview;
+
+    /** The prewview provider. May be empty.  May be replaced during the
+        lifetime of a MasterPageDescriptor object.
+    */
+    ::boost::shared_ptr<PreviewProvider> mpPreviewProvider;
+
+    /** The master page provider.  May be empty.  May be replaced during
+        the lifetime of a MasterPageDescriptor object.
+    */
+    ::boost::shared_ptr<PageObjectProvider> mpPageObjectProvider;
+    
+    /** This index represents the order in which templates are provided via
+        the TemplateScanner.  It defines the order in which the entries in
+        the AllMasterPagesSelector are displayed.  The default value is -1.
+    */
+    sal_Int32 mnTemplateIndex;
+
+    URLClassification meURLClassification;
+
+    sal_Int32 mnUseCount;
+
+    class URLComparator { public:
+        ::rtl::OUString msURL;
+        URLComparator (const ::rtl::OUString& sURL);
+        bool operator() (const SharedMasterPageDescriptor& rDescriptor);
+    };
+    class StyleNameComparator { public:
+        ::rtl::OUString msStyleName;
+        StyleNameComparator (const ::rtl::OUString& sStyleName);
+        bool operator() (const SharedMasterPageDescriptor& rDescriptor);
+    };
+    class PageObjectComparator { public:
+        const SdPage* mpMasterPage;
+        PageObjectComparator (const SdPage* pPageObject);
+        bool operator() (const SharedMasterPageDescriptor& rDescriptor);
+    };
+    class AllComparator { public:
+        AllComparator(const SharedMasterPageDescriptor& rDescriptor);
+        bool operator() (const SharedMasterPageDescriptor& rDescriptor);
+    private:
+        SharedMasterPageDescriptor mpDescriptor;
+    };
+
+
+};
+
+
+} } // end of namespace sd::sidebar
+
+#endif

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageObserver.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageObserver.cxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageObserver.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPageObserver.cxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,419 @@
+/**************************************************************
+ * 
+ * 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
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include "MasterPageObserver.hxx"
+
+#include <algorithm>
+#include "drawdoc.hxx"
+#include "sdpage.hxx"
+#include <hash_map>
+#include <set>
+#include <vector>
+#include <svl/lstner.hxx>
+#include <osl/doublecheckedlocking.h>
+#include <osl/getglobalmutex.hxx>
+
+
+namespace sd {
+
+class MasterPageObserver::Implementation
+    : public SfxListener
+{
+public:
+    /** The single instance of this class.  It is created on demand when
+        Instance() is called for the first time.
+    */
+    static MasterPageObserver* mpInstance;
+
+    /** The master page observer will listen to events of this document and
+        detect changes of the use of master pages.
+    */
+    void RegisterDocument (SdDrawDocument& rDocument);
+
+    /** The master page observer will stop to listen to events of this
+        document.
+    */
+    void UnregisterDocument (SdDrawDocument& rDocument);
+    
+    /** Add a listener that is informed of master pages that are newly
+        assigned to slides or become unassigned.
+        @param rEventListener
+            The event listener to call for future events.  Call
+            RemoveEventListener() before the listener is destroyed.
+    */
+    void AddEventListener (const Link& rEventListener);
+
+    /** Remove the given listener from the list of listeners.
+        @param rEventListener
+            After this method returns the given listener is not called back
+            from this object.  Passing a listener that has not
+            been registered before is safe and is silently ignored.
+    */
+    void RemoveEventListener (const Link& rEventListener);
+
+    /** Return a set of the names of master pages for the given document.
+        This convenience method exists because this set is part of the
+        internal data structure and thus takes no time to create.
+    */
+    inline MasterPageObserver::MasterPageNameSet GetMasterPageNames (
+        SdDrawDocument& rDocument);
+
+private:
+    ::std::vector<Link> maListeners;
+
+    struct DrawDocHash {
+        size_t operator()(SdDrawDocument* argument) const 
+        { return reinterpret_cast<unsigned long>(argument); }
+    };
+    typedef ::std::hash_map<SdDrawDocument*,
+                            MasterPageObserver::MasterPageNameSet,
+                            DrawDocHash>
+        MasterPageContainer;
+    MasterPageContainer maUsedMasterPages;
+
+    virtual void Notify(
+        SfxBroadcaster& rBroadcaster,
+        const SfxHint& rHint);
+
+    void AnalyzeUsedMasterPages (SdDrawDocument& rDocument);
+
+    void SendEvent (MasterPageObserverEvent& rEvent);
+};
+
+MasterPageObserver* MasterPageObserver::Implementation::mpInstance = NULL;
+
+
+
+//===== MasterPageObserver ====================================================
+
+MasterPageObserver&  MasterPageObserver::Instance (void)
+{
+    if (Implementation::mpInstance == NULL)
+    {
+        ::osl::GetGlobalMutex aMutexFunctor;
+        ::osl::MutexGuard aGuard (aMutexFunctor());
+        if (Implementation::mpInstance == NULL)
+        {
+            MasterPageObserver* pInstance = new MasterPageObserver ();
+            SdGlobalResourceContainer::Instance().AddResource (
+                ::std::auto_ptr<SdGlobalResource>(pInstance));
+            OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+            Implementation::mpInstance = pInstance;
+        }
+    }
+    else
+    {
+        OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+    }
+    
+    DBG_ASSERT(Implementation::mpInstance!=NULL,
+        "MasterPageObserver::Instance(): instance is NULL");
+    return *Implementation::mpInstance;
+}
+
+
+
+
+void MasterPageObserver::RegisterDocument (SdDrawDocument& rDocument)
+{
+    mpImpl->RegisterDocument (rDocument);
+}
+
+
+
+
+void MasterPageObserver::UnregisterDocument (SdDrawDocument& rDocument)
+{
+    mpImpl->UnregisterDocument (rDocument);
+}
+
+
+
+    
+void MasterPageObserver::AddEventListener (const Link& rEventListener)
+{
+
+    mpImpl->AddEventListener (rEventListener);
+}
+
+
+
+
+void MasterPageObserver::RemoveEventListener (const Link& rEventListener)
+{
+    mpImpl->RemoveEventListener (rEventListener);
+}
+
+
+
+
+MasterPageObserver::MasterPageObserver (void)
+    : mpImpl (new Implementation())
+{}
+
+
+
+
+MasterPageObserver::~MasterPageObserver (void)
+{}
+
+
+
+
+//===== MasterPageObserver::Implementation ====================================
+
+void MasterPageObserver::Implementation::RegisterDocument (
+    SdDrawDocument& rDocument)
+{
+    // Gather the names of all the master pages in the given document.
+    MasterPageContainer::data_type aMasterPageSet;
+    sal_uInt16 nMasterPageCount = rDocument.GetMasterSdPageCount(PK_STANDARD);
+    for (sal_uInt16 nIndex=0; nIndex<nMasterPageCount; nIndex++)
+    {
+        SdPage* pMasterPage = rDocument.GetMasterSdPage (nIndex, PK_STANDARD);
+        if (pMasterPage != NULL)
+            aMasterPageSet.insert (pMasterPage->GetName());
+    }
+
+    maUsedMasterPages[&rDocument] = aMasterPageSet;
+
+    StartListening (rDocument);
+}
+
+
+
+
+void MasterPageObserver::Implementation::UnregisterDocument (
+    SdDrawDocument& rDocument)
+{
+    EndListening (rDocument);
+
+	MasterPageContainer::iterator aMasterPageDescriptor(maUsedMasterPages.find(&rDocument));
+	if(aMasterPageDescriptor != maUsedMasterPages.end())
+		maUsedMasterPages.erase(aMasterPageDescriptor);
+}
+
+
+
+    
+void MasterPageObserver::Implementation::AddEventListener (
+    const Link& rEventListener)
+{
+    if (::std::find (
+        maListeners.begin(),
+        maListeners.end(),
+        rEventListener) == maListeners.end())
+    {
+        maListeners.push_back (rEventListener);
+        
+        // Tell the new listener about all the master pages that are
+        // currently in use.
+        typedef ::std::vector<String> StringList;
+        StringList aNewMasterPages;
+        StringList aRemovedMasterPages;
+        MasterPageContainer::iterator aDocumentIterator;
+        for (aDocumentIterator=maUsedMasterPages.begin();
+             aDocumentIterator!=maUsedMasterPages.end();
+             ++aDocumentIterator)
+        {
+            ::std::set<String>::reverse_iterator aNameIterator;
+            for (aNameIterator=aDocumentIterator->second.rbegin();
+                 aNameIterator!=aDocumentIterator->second.rend();
+                 ++aNameIterator)
+            {
+			  MasterPageObserverEvent aEvent (
+				  MasterPageObserverEvent::ET_MASTER_PAGE_EXISTS,
+				  *aDocumentIterator->first,
+				  *aNameIterator);
+			  SendEvent (aEvent);
+            }
+        }
+    }
+}
+
+
+
+
+void MasterPageObserver::Implementation::RemoveEventListener (
+    const Link& rEventListener)
+{
+    maListeners.erase (
+        ::std::find (
+            maListeners.begin(),
+            maListeners.end(),
+            rEventListener));
+}
+
+
+
+
+MasterPageObserver::MasterPageNameSet 
+    MasterPageObserver::Implementation::GetMasterPageNames (
+        SdDrawDocument& rDocument)
+{
+    MasterPageContainer::iterator aMasterPageDescriptor (
+        maUsedMasterPages.find(&rDocument));
+    if (aMasterPageDescriptor != maUsedMasterPages.end())
+        return aMasterPageDescriptor->second;
+    else
+        // Not found so return an empty set.
+        return MasterPageObserver::MasterPageNameSet();
+}
+
+
+
+
+void MasterPageObserver::Implementation::Notify(
+    SfxBroadcaster& rBroadcaster,
+    const SfxHint& rHint)
+{
+    if (rHint.ISA(SdrHint))
+    {
+        SdrHint& rSdrHint (*PTR_CAST(SdrHint,&rHint));
+        switch (rSdrHint.GetKind())
+        {
+            case HINT_PAGEORDERCHG:
+                // Process the modified set of pages only when the number of
+                // standard and notes master pages are equal.  This test
+                // filters out events that are sent in between the insertion
+                // of a new standard master page and a new notes master
+                // page.
+                if (rBroadcaster.ISA(SdDrawDocument))
+                {
+                    SdDrawDocument& rDocument (
+                        static_cast<SdDrawDocument&>(rBroadcaster));
+                    if (rDocument.GetMasterSdPageCount(PK_STANDARD)
+                        == rDocument.GetMasterSdPageCount(PK_NOTES))
+                    {
+                        AnalyzeUsedMasterPages (rDocument);
+                    }
+                }
+                break;
+
+			default:
+				break;
+        }
+    }
+}
+
+
+
+
+void MasterPageObserver::Implementation::AnalyzeUsedMasterPages (
+    SdDrawDocument& rDocument)
+{
+    // Create a set of names of the master pages used by the given document.
+    sal_uInt16 nMasterPageCount = rDocument.GetMasterSdPageCount(PK_STANDARD);
+    ::std::set<String> aCurrentMasterPages;
+    for (sal_uInt16 nIndex=0; nIndex<nMasterPageCount; nIndex++)
+    {
+        SdPage* pMasterPage = rDocument.GetMasterSdPage (nIndex, PK_STANDARD);
+        if (pMasterPage != NULL)
+            aCurrentMasterPages.insert (pMasterPage->GetName());
+        OSL_TRACE("currently used master page %d is %s",
+            nIndex,
+            ::rtl::OUStringToOString(pMasterPage->GetName(),
+                RTL_TEXTENCODING_UTF8).getStr());
+    }
+
+    typedef ::std::vector<String> StringList;
+    StringList aNewMasterPages;
+    StringList aRemovedMasterPages;
+    MasterPageContainer::iterator aOldMasterPagesDescriptor (
+        maUsedMasterPages.find(&rDocument));
+    if (aOldMasterPagesDescriptor != maUsedMasterPages.end())
+    {
+        StringList::iterator I;
+
+        ::std::set<String>::iterator J;
+        int i=0;
+        for (J=aOldMasterPagesDescriptor->second.begin(); 
+             J!=aOldMasterPagesDescriptor->second.end(); 
+             ++J)
+            OSL_TRACE("old used master page %d is %s",
+            i++,
+            ::rtl::OUStringToOString(*J,
+                RTL_TEXTENCODING_UTF8).getStr());
+
+        // Send events about the newly used master pages.
+        ::std::set_difference (
+            aCurrentMasterPages.begin(),
+            aCurrentMasterPages.end(),
+            aOldMasterPagesDescriptor->second.begin(),
+            aOldMasterPagesDescriptor->second.end(),
+            ::std::back_insert_iterator<StringList>(aNewMasterPages));
+        for (I=aNewMasterPages.begin(); I!=aNewMasterPages.end(); ++I)
+        {
+            OSL_TRACE("    added master page %s",
+                ::rtl::OUStringToOString(*I,
+                    RTL_TEXTENCODING_UTF8).getStr());
+
+			MasterPageObserverEvent aEvent (
+				MasterPageObserverEvent::ET_MASTER_PAGE_ADDED, 
+				rDocument, 
+				*I);
+            SendEvent (aEvent);
+        }
+
+        // Send events about master pages that are not used any longer.
+        ::std::set_difference (
+            aOldMasterPagesDescriptor->second.begin(),
+            aOldMasterPagesDescriptor->second.end(),
+            aCurrentMasterPages.begin(),
+            aCurrentMasterPages.end(),
+            ::std::back_insert_iterator<StringList>(aRemovedMasterPages));
+        for (I=aRemovedMasterPages.begin(); I!=aRemovedMasterPages.end(); ++I)
+        {
+            OSL_TRACE("    removed master page %s",
+                ::rtl::OUStringToOString(*I,
+                    RTL_TEXTENCODING_UTF8).getStr());
+
+			MasterPageObserverEvent aEvent (
+				MasterPageObserverEvent::ET_MASTER_PAGE_REMOVED,
+				rDocument, 
+				*I);
+			SendEvent (aEvent);
+        }
+
+        // Store the new list of master pages.
+        aOldMasterPagesDescriptor->second = aCurrentMasterPages;
+    }
+}
+
+
+
+
+void MasterPageObserver::Implementation::SendEvent (
+    MasterPageObserverEvent& rEvent)
+{
+    ::std::vector<Link>::iterator aLink (maListeners.begin());
+    ::std::vector<Link>::iterator aEnd (maListeners.end());
+    while (aLink!=aEnd)
+    {
+        aLink->Call (&rEvent);
+        ++aLink;
+    }
+}
+
+
+} // end of namespace sd