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/19 10:09:05 UTC

svn commit: r1447641 [4/9] - in /openoffice/branches/sidebar/main: default_images/sfx2/res/symphony/ framework/inc/services/ framework/source/services/ offapi/com/sun/star/ui/ officecfg/registry/data/org/openoffice/Office/ officecfg/registry/data/org/o...

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/DocumentHelper.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/DocumentHelper.cxx?rev=1447641&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/DocumentHelper.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/DocumentHelper.cxx Tue Feb 19 09:09:02 2013
@@ -0,0 +1,578 @@
+/**************************************************************
+ * 
+ * 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 "DocumentHelper.hxx"
+
+#include "drawdoc.hxx"
+#include "DrawDocShell.hxx"
+#include "sdpage.hxx"
+#include "glob.hxx"
+#include "unmovss.hxx"
+#include "strings.hrc"
+#include "sdresid.hxx"
+#include "undoback.hxx"
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include "stlpool.hxx"
+#include <svx/xfillit0.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star;
+
+namespace sd { namespace sidebar {
+
+SdPage* DocumentHelper::CopyMasterPageToLocalDocument (
+    SdDrawDocument& rTargetDocument,
+    SdPage* pMasterPage)
+{
+    SdPage* pNewMasterPage = NULL;
+
+    do
+    {
+        if (pMasterPage == NULL)
+            break;
+
+        // Check the presence of the source document.
+        SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>(
+            pMasterPage->GetModel());
+        if (pSourceDocument == NULL)
+            break;
+
+        // When the given master page already belongs to the target document
+        // then there is nothing more to do.
+        if (pSourceDocument == &rTargetDocument)
+        {
+            pNewMasterPage = pMasterPage;
+            break;
+        }
+
+        // Test if the master pages of both the slide and its notes page are
+        // present.  This is not the case when we are called during the
+        // creation of the slide master page because then the notes master
+        // page is not there.
+        sal_uInt16 nSourceMasterPageCount = pSourceDocument->GetMasterPageCount();
+        if (nSourceMasterPageCount%2 == 0)
+            // There should be 1 handout page + n slide masters + n notes
+            // masters = 2*n+1.  An even value indicates that a new slide
+            // master but not yet the notes master has been inserted.
+            break;
+        sal_uInt16 nIndex = pMasterPage->GetPageNum();
+        if (nSourceMasterPageCount <= nIndex+1)
+            break;
+        // Get the slide master page.
+        if (pMasterPage != static_cast<SdPage*>(
+            pSourceDocument->GetMasterPage(nIndex)))
+            break;
+        // Get the notes master page.
+        SdPage* pNotesMasterPage = static_cast<SdPage*>(
+            pSourceDocument->GetMasterPage(nIndex+1));
+        if (pNotesMasterPage == NULL)
+            break;
+
+
+        // Check if a master page with the same name as that of the given
+        // master page already exists.
+        bool bPageExists (false);
+        sal_uInt16 nMasterPageCount(rTargetDocument.GetMasterSdPageCount(PK_STANDARD));
+        for (sal_uInt16 nMaster=0; nMaster<nMasterPageCount; nMaster++)
+        {
+            SdPage* pCandidate = static_cast<SdPage*>(
+                rTargetDocument.GetMasterSdPage (nMaster, PK_STANDARD));
+            if (pMasterPage!=NULL
+                && pCandidate->GetName().CompareTo(pMasterPage->GetName())==0)
+            {
+                bPageExists = true;
+                pNewMasterPage = pCandidate;
+                break;
+            }
+        }
+        if (bPageExists)
+            break;
+        
+        // Create a new slide (and its notes page.)
+        uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier (
+            rTargetDocument.getUnoModel(), uno::UNO_QUERY);
+        if ( ! xSlideSupplier.is())
+            break;
+        uno::Reference<drawing::XDrawPages> xSlides (
+            xSlideSupplier->getDrawPages(), uno::UNO_QUERY);
+        if ( ! xSlides.is())
+            break;
+        xSlides->insertNewByIndex (xSlides->getCount());
+
+        // Set a layout.
+        SdPage* pSlide = rTargetDocument.GetSdPage(
+            rTargetDocument.GetSdPageCount(PK_STANDARD)-1,
+            PK_STANDARD);
+        if (pSlide == NULL)
+            break;
+        pSlide->SetAutoLayout(AUTOLAYOUT_TITLE, sal_True);
+
+        // Create a copy of the master page and the associated notes
+        // master page and insert them into our document.
+        pNewMasterPage = AddMasterPage(rTargetDocument, pMasterPage);
+        if (pNewMasterPage==NULL)
+            break;
+        SdPage* pNewNotesMasterPage 
+            = AddMasterPage(rTargetDocument, pNotesMasterPage);
+        if (pNewNotesMasterPage==NULL)
+            break;
+
+        // Make the connection from the new slide to the master page
+        // (and do the same for the notes page.)
+        rTargetDocument.SetMasterPage (
+            rTargetDocument.GetSdPageCount(PK_STANDARD)-1,
+            pNewMasterPage->GetName(),
+            &rTargetDocument,
+            sal_False, // Connect the new master page with the new slide but
+                   // do not modify other (master) pages.
+            sal_True);
+    }
+    while (false);
+
+    // We are not interested in any automatisms for our modified internal
+    // document.
+    rTargetDocument.SetChanged (sal_False);
+
+    return pNewMasterPage;
+}
+
+
+
+
+SdPage* DocumentHelper::GetSlideForMasterPage (SdPage* pMasterPage)
+{
+    SdPage* pCandidate = NULL;
+
+    SdDrawDocument* pDocument = NULL;
+    if (pMasterPage != NULL)
+        pDocument = dynamic_cast<SdDrawDocument*>(pMasterPage->GetModel());
+
+    // Iterate over all pages and check if it references the given master
+    // page.
+    if (pDocument!=NULL && pDocument->GetSdPageCount(PK_STANDARD) > 0)
+    {
+        // In most cases a new slide has just been inserted so start with
+        // the last page.
+        sal_uInt16 nPageIndex (pDocument->GetSdPageCount(PK_STANDARD)-1);
+        bool bFound (false);
+        while ( ! bFound)
+        {
+            pCandidate = pDocument->GetSdPage(
+                nPageIndex,
+                PK_STANDARD);
+            if (pCandidate != NULL)
+            {
+                if (static_cast<SdPage*>(&pCandidate->TRG_GetMasterPage())
+                    == pMasterPage)
+                {
+                    bFound = true;
+                    break;
+                }
+            }
+
+            if (nPageIndex == 0)
+                break;
+            else
+                nPageIndex --;
+        }
+
+        // If no page was found that refernced the given master page reset
+        // the pointer that is returned.
+        if ( ! bFound)
+            pCandidate = NULL;
+    }
+
+    return pCandidate;
+}
+
+
+
+
+SdPage* DocumentHelper::AddMasterPage (
+    SdDrawDocument& rTargetDocument,
+    SdPage* pMasterPage)
+{
+    SdPage* pClonedMasterPage = NULL;
+
+    if (pMasterPage!=NULL)
+    {
+        try
+        {
+            // Duplicate the master page.
+            pClonedMasterPage = static_cast<SdPage*>(pMasterPage->Clone());
+
+            // Copy the necessary styles.
+            SdDrawDocument* pSourceDocument
+                = static_cast<SdDrawDocument*>(pMasterPage->GetModel());
+            if (pSourceDocument != NULL)
+                ProvideStyles (*pSourceDocument, rTargetDocument, pClonedMasterPage);
+
+            // Copy the precious flag.
+            pClonedMasterPage->SetPrecious(pMasterPage->IsPrecious());
+            
+            // Now that the styles are available we can insert the cloned
+            // master page.
+            rTargetDocument.InsertMasterPage (pClonedMasterPage);
+        }
+        catch (uno::Exception& rException)
+        {
+            pClonedMasterPage = NULL;
+            DBG_UNHANDLED_EXCEPTION();
+        }
+        catch (::std::exception rException)
+        {
+            pClonedMasterPage = NULL;
+            OSL_TRACE ("caught general exception");
+        }
+        catch (...)
+        {
+            pClonedMasterPage = NULL;
+            OSL_TRACE ("caught general exception");
+        }
+    }
+
+    return pClonedMasterPage;
+}
+
+
+
+
+void DocumentHelper::ProvideStyles (
+    SdDrawDocument& rSourceDocument,
+    SdDrawDocument& rTargetDocument,
+    SdPage* pPage)
+{
+    // Get the layout name of the given page.
+    String sLayoutName (pPage->GetLayoutName());
+    sLayoutName.Erase (sLayoutName.SearchAscii (SD_LT_SEPARATOR));
+
+    // Copy the style sheet from source to target document.
+	SdStyleSheetPool* pSourceStyleSheetPool =
+        static_cast<SdStyleSheetPool*>(rSourceDocument.GetStyleSheetPool());
+	SdStyleSheetPool* pTargetStyleSheetPool =
+        static_cast<SdStyleSheetPool*>(rTargetDocument.GetStyleSheetPool());
+    SdStyleSheetVector aCreatedStyles;
+    pTargetStyleSheetPool->CopyLayoutSheets (
+        sLayoutName, 
+        *pSourceStyleSheetPool, 
+        aCreatedStyles);
+
+    // Add an undo action for the copied style sheets.
+    if( !aCreatedStyles.empty() )
+    {
+     	::svl::IUndoManager* pUndoManager = rTargetDocument.GetDocSh()->GetUndoManager();
+       if (pUndoManager != NULL)
+       {
+           SdMoveStyleSheetsUndoAction* pMovStyles =
+               new SdMoveStyleSheetsUndoAction (
+                   &rTargetDocument, 
+                   aCreatedStyles, 
+                   sal_True);
+           pUndoManager->AddUndoAction (pMovStyles);
+       }
+    }
+}
+
+
+
+
+void DocumentHelper::AssignMasterPageToPageList (
+    SdDrawDocument& rTargetDocument,
+    SdPage* pMasterPage,
+    const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList)
+{
+    do
+    {
+        if (pMasterPage == NULL && pMasterPage->IsMasterPage())
+            break;
+
+        // Make the layout name by stripping ouf the layout postfix from the
+        // layout name of the given master page.
+        String sFullLayoutName (pMasterPage->GetLayoutName());
+        String sBaseLayoutName (sFullLayoutName);
+        sBaseLayoutName.Erase (sBaseLayoutName.SearchAscii (SD_LT_SEPARATOR));
+
+        if (rpPageList->empty())
+            break;
+
+        // Create a second list that contains only the valid pointers to
+        // pages for which an assignment is necessary.
+        ::std::vector<SdPage*>::const_iterator iPage;
+        ::std::vector<SdPage*> aCleanedList;
+        for (iPage=rpPageList->begin(); iPage!=rpPageList->end(); ++iPage)
+        {
+            OSL_ASSERT(*iPage!=NULL && (*iPage)->GetModel() == &rTargetDocument);
+            if (*iPage != NULL
+                && (*iPage)->GetLayoutName().CompareTo(sFullLayoutName)!=0)
+            {
+                aCleanedList.push_back(*iPage);
+            }
+        }
+        if (aCleanedList.empty() )
+            break;
+
+		::svl::IUndoManager* pUndoMgr = rTargetDocument.GetDocSh()->GetUndoManager();
+		if( pUndoMgr )
+			pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_SET_PRESLAYOUT)), String());
+
+        SdPage* pMasterPageInDocument = ProvideMasterPage(rTargetDocument,pMasterPage,rpPageList);
+        if (pMasterPageInDocument == NULL)
+            break;
+
+        // Assign the master pages to the given list of pages.
+        for (iPage=aCleanedList.begin(); 
+             iPage!=aCleanedList.end(); 
+             ++iPage)
+        {
+            AssignMasterPageToPage (
+                pMasterPageInDocument,
+                sBaseLayoutName,
+                *iPage);
+        }
+
+		if( pUndoMgr )
+			pUndoMgr->LeaveListAction();
+    }
+    while (false);
+}
+
+
+
+
+SdPage* DocumentHelper::AddMasterPage (
+    SdDrawDocument& rTargetDocument,
+    SdPage* pMasterPage,
+    sal_uInt16 nInsertionIndex)
+{
+    SdPage* pClonedMasterPage = NULL;
+
+    if (pMasterPage!=NULL)
+    {
+        // Duplicate the master page.
+        pClonedMasterPage = static_cast<SdPage*>(pMasterPage->Clone());
+
+        // Copy the precious flag.
+        pClonedMasterPage->SetPrecious(pMasterPage->IsPrecious());
+        
+        // Copy the necessary styles.
+        SdDrawDocument* pSourceDocument
+            = static_cast<SdDrawDocument*>(pMasterPage->GetModel());
+        if (pSourceDocument != NULL)
+        {
+            ProvideStyles (*pSourceDocument, rTargetDocument, pClonedMasterPage);
+
+            // Now that the styles are available we can insert the cloned
+            // master page.
+            rTargetDocument.InsertMasterPage (pClonedMasterPage, nInsertionIndex);
+
+            // Adapt the size of the new master page to that of the pages in
+            // the document.
+            Size aNewSize (rTargetDocument.GetSdPage(0, pMasterPage->GetPageKind())->GetSize());
+            Rectangle aBorders (
+                pClonedMasterPage->GetLftBorder(),
+                pClonedMasterPage->GetUppBorder(),
+                pClonedMasterPage->GetRgtBorder(),
+                pClonedMasterPage->GetLwrBorder());
+            pClonedMasterPage->ScaleObjects(aNewSize, aBorders, sal_True);
+            pClonedMasterPage->SetSize(aNewSize);
+            pClonedMasterPage->CreateTitleAndLayout(sal_True);
+        }
+    }
+
+    return pClonedMasterPage;
+}
+
+
+
+
+/** In here we have to handle three cases:
+    1. pPage is a normal slide.  We can use SetMasterPage to assign the
+    master pages to it.
+    2. pPage is a master page that is used by at least one slide.  We can
+    assign the master page to these slides.
+    3. pPage is a master page that is currently not used by any slide.
+    We can delete that page and add copies of the given master pages
+    instead.
+
+    For points 2 and 3 where one master page A is assigned to another B we have
+    to keep in mind that the master page that page A has already been
+    inserted into the target document.
+*/
+void DocumentHelper::AssignMasterPageToPage (
+    SdPage* pMasterPage,
+    const String& rsBaseLayoutName,
+    SdPage* pPage)
+{
+    // Leave early when the parameters are invalid.
+    if (pPage == NULL || pMasterPage == NULL)
+        return;
+    SdDrawDocument* pDocument = dynamic_cast<SdDrawDocument*>(pPage->GetModel());
+    if (pDocument == NULL)
+        return;
+    
+    if ( ! pPage->IsMasterPage())
+    {
+        // 1. Remove the background object (so that that, if it exists, does
+        // not override the new master page) and assign the master page to
+        // the regular slide.
+        pDocument->GetDocSh()->GetUndoManager()->AddUndoAction(
+            new SdBackgroundObjUndoAction(
+                *pDocument, *pPage, pPage->getSdrPageProperties().GetItemSet()),
+            sal_True);
+        pPage->getSdrPageProperties().PutItem(XFillStyleItem(XFILL_NONE));
+          
+        pDocument->SetMasterPage (
+            (pPage->GetPageNum()-1)/2,
+            rsBaseLayoutName,
+            pDocument,
+            sal_False,
+            sal_False);
+    }
+    else
+    {
+        // Find first slide that uses the master page.
+        SdPage* pSlide = NULL;
+        sal_uInt16 nPageCount = pDocument->GetSdPageCount(PK_STANDARD);
+        for (sal_uInt16 nPage=0; nPage<nPageCount&&pSlide==NULL; nPage++)
+        {
+            SdrPage* pCandidate = pDocument->GetSdPage(nPage,PK_STANDARD);
+            if (pCandidate != NULL
+                && pCandidate->TRG_HasMasterPage()
+                && &(pCandidate->TRG_GetMasterPage()) == pPage)
+            {
+                pSlide = static_cast<SdPage*>(pCandidate);
+            }
+        }
+
+        if (pSlide != NULL)
+        {
+            // 2. Assign the given master pages to the first slide that was
+            // found above that uses the master page.
+            pDocument->SetMasterPage (
+                (pSlide->GetPageNum()-1)/2,
+                rsBaseLayoutName,
+                pDocument,
+                sal_False,
+                sal_False);
+        }
+        else
+        {
+            // 3. Replace the master page A by a copy of the given master
+            // page B.
+            pDocument->RemoveUnnecessaryMasterPages (
+                pPage, sal_False);
+        }
+    }
+}
+
+
+
+
+SdPage* DocumentHelper::ProvideMasterPage (
+    SdDrawDocument& rTargetDocument,
+    SdPage* pMasterPage,
+    const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList)
+{
+    // Make sure that both the master page and its notes master exist
+    // in the source document.  If one is missing then return without
+    // making any changes.
+    if (pMasterPage == NULL)
+    {
+        // The caller should make sure that the master page is valid.
+        OSL_ASSERT(pMasterPage != NULL);
+        return NULL;
+    }
+    SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>(pMasterPage->GetModel());
+    if (pSourceDocument == NULL)
+        return NULL;
+    SdPage* pNotesMasterPage = static_cast<SdPage*>(
+        pSourceDocument->GetMasterPage(pMasterPage->GetPageNum()+1));
+    if (pNotesMasterPage == NULL)
+    {
+        // The model is not in a valid state.  Maybe a new master page
+        // is being (not finished yet) created?  Return without making
+        // any changes.
+        return NULL;
+    }
+
+    SdPage* pMasterPageInDocument = NULL;
+    // Search for a master page with the same name as the given one in
+    // the target document.
+    const XubString sMasterPageLayoutName (pMasterPage->GetLayoutName());
+    for (sal_uInt16 nIndex=0,nCount=rTargetDocument.GetMasterPageCount(); nIndex<nCount; ++nIndex)
+    {
+        SdPage* pCandidate = static_cast<SdPage*>(rTargetDocument.GetMasterPage(nIndex));
+        if (pCandidate!=NULL 
+            && sMasterPageLayoutName==pCandidate->GetLayoutName())
+        {
+            // The requested master page does already exist in the
+            // target document, return it.
+            return pCandidate;
+        }
+    }
+    
+    // The given master page does not already belong to the target
+    // document so we have to create copies and insert them into the
+    // targer document.
+
+    // Determine the position where the new master pages are inserted.
+    // By default they are inserted at the end.  When we assign to a
+    // master page then insert after the last of the (selected) pages.
+    sal_uInt16 nInsertionIndex = rTargetDocument.GetMasterPageCount();
+    if (rpPageList->front()->IsMasterPage())
+    {
+        nInsertionIndex = rpPageList->back()->GetPageNum();
+    }
+
+    // Clone the master page.
+    if (pMasterPage->GetModel() != &rTargetDocument)
+    {
+        pMasterPageInDocument = AddMasterPage (rTargetDocument, pMasterPage, nInsertionIndex);
+        if( rTargetDocument.IsUndoEnabled() )
+				rTargetDocument.AddUndo(
+					rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pMasterPageInDocument));
+    }
+    else
+        pMasterPageInDocument = pMasterPage;
+
+    // Clone the notes master.
+    if (pNotesMasterPage->GetModel() != &rTargetDocument)
+    {
+        SdPage* pClonedNotesMasterPage 
+            = AddMasterPage (rTargetDocument, pNotesMasterPage, nInsertionIndex+1);
+        if( rTargetDocument.IsUndoEnabled() )
+            rTargetDocument.AddUndo(
+                rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pClonedNotesMasterPage));
+    }
+
+    return pMasterPageInDocument;
+}
+
+
+
+
+
+} } // end of namespace sd::sidebar

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/DocumentHelper.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/DocumentHelper.hxx?rev=1447641&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/DocumentHelper.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/DocumentHelper.hxx Tue Feb 19 09:09:02 2013
@@ -0,0 +1,110 @@
+/**************************************************************
+ * 
+ * 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_DCUMENT_HELPER_HXX
+#define SD_SIDEBAR_PANELS_DCUMENT_HELPER_HXX
+
+#include <tools/solar.h>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+class SdDrawDocument;
+class SdPage;
+class String;
+
+namespace sd { namespace sidebar {
+
+/** A collection of methods supporting the handling of master pages.
+*/
+class DocumentHelper
+{
+public:
+    /** Return a copy of the given master page in the given document.
+    */
+    static SdPage* CopyMasterPageToLocalDocument (
+        SdDrawDocument& rTargetDocument,
+        SdPage* pMasterPage);
+
+    /** Return and, when not yet present, create a slide that uses the given
+        masster page.
+    */
+    static SdPage* GetSlideForMasterPage (SdPage* pMasterPage);
+
+    /** Copy the styles used by the given page from the source document to
+        the target document.
+    */
+    static void ProvideStyles (
+        SdDrawDocument& rSourceDocument,
+        SdDrawDocument& rTargetDocument,
+        SdPage* pPage);
+
+    /** Assign the given master page to the list of pages.
+        @param rTargetDocument
+            The document that is the owner of the pages in rPageList.
+        @param pMasterPage
+            This master page will usually be a member of the list of all
+            available master pages as provided by the MasterPageContainer.
+        @param rPageList
+            The pages to which to assign the master page.  These pages may
+            be slides or master pages themselves.
+    */
+    static void AssignMasterPageToPageList (
+        SdDrawDocument& rTargetDocument,
+        SdPage* pMasterPage,
+        const ::boost::shared_ptr<std::vector<SdPage*> >& rPageList);
+
+private:
+    static SdPage* AddMasterPage (
+        SdDrawDocument& rTargetDocument,
+        SdPage* pMasterPage);
+    static SdPage* AddMasterPage (
+        SdDrawDocument& rTargetDocument,
+        SdPage* pMasterPage,
+        sal_uInt16 nInsertionIndex);
+    static SdPage* ProvideMasterPage (
+        SdDrawDocument& rTargetDocument,
+        SdPage* pMasterPage,
+        const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList);
+    
+    /** Assign the given master page to the given page.
+        @param pMasterPage
+            In contrast to AssignMasterPageToPageList() this page is assumed
+            to be in the target document, i.e. the same document that pPage
+            is in.  The caller will usually call AddMasterPage() to create a
+            clone of a master page in a another document to create it.
+        @param rsBaseLayoutName
+            The layout name of the given master page.  It is given so that
+            it has not to be created on every call.  It could be generated
+            from the given master page, though.
+        @param pPage
+            The page to which to assign the master page.  It can be a slide
+            or a master page itself.
+    */
+    static void AssignMasterPageToPage (
+        SdPage* pMasterPage,
+        const String& rsBaseLayoutName,
+        SdPage* pPage);
+};
+
+
+} } // end of namespace sd::sidebar
+
+#endif

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/LayoutMenu.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/LayoutMenu.cxx?rev=1447641&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/LayoutMenu.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/LayoutMenu.cxx Tue Feb 19 09:09:02 2013
@@ -0,0 +1,1018 @@
+/**************************************************************
+ * 
+ * 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 "LayoutMenu.hxx"
+
+#include "../SidebarShellManager.hxx"
+#include "app.hrc"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsPageSelector.hxx"
+#include "drawdoc.hxx"
+#include "framework/FrameworkHelper.hxx"
+#include "glob.hrc"
+#include "glob.hxx"
+#include "helpids.h"
+#include "pres.hxx"
+#include "res_bmp.hrc"
+#include "sdpage.hxx"
+#include "sdresid.hxx"
+#include "strings.hrc"
+#include "tools/SlotStateListener.hxx"
+#include "DrawController.hxx"
+#include "DrawDocShell.hxx"
+#include "DrawViewShell.hxx"
+#include "EventMultiplexer.hxx"
+#include "SidebarViewShell.hxx"
+#include "SlideSorterViewShell.hxx"
+#include "ViewShellBase.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/languageoptions.hxx>
+#include <vcl/image.hxx>
+
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/drawing/framework/ResourceId.hpp>
+
+#include <vector>
+#include <memory>
+
+using namespace ::sd::sidebar;
+#define LayoutMenu
+#include "sdslots.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using namespace ::sd::slidesorter;
+using ::sd::framework::FrameworkHelper;
+
+namespace sd { namespace sidebar {
+
+
+SFX_IMPL_INTERFACE(LayoutMenu, SfxShell, 
+    SdResId(STR_SIDEBAR_LAYOUTMENU))
+{
+	SFX_POPUPMENU_REGISTRATION(SdResId(RID_TASKPANE_LAYOUTMENU_POPUP));
+}
+
+TYPEINIT1(LayoutMenu, SfxShell);
+
+struct snewfoil_value_info
+{
+    sal_uInt16 mnBmpResId;
+    sal_uInt16 mnHCBmpResId;
+    sal_uInt16 mnStrResId;
+    WritingMode meWritingMode;
+    AutoLayout maAutoLayout;
+};
+
+static snewfoil_value_info notes[] =
+{
+    {BMP_FOILN_01, BMP_FOILN_01_H, STR_AUTOLAYOUT_NOTES, WritingMode_LR_TB,
+     AUTOLAYOUT_NOTES},
+    {0, 0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE},
+};
+
+static snewfoil_value_info handout[] =
+{
+    {BMP_FOILH_01, BMP_FOILH_01_H, STR_AUTOLAYOUT_HANDOUT1, WritingMode_LR_TB,
+     AUTOLAYOUT_HANDOUT1},
+    {BMP_FOILH_02, BMP_FOILH_02_H, STR_AUTOLAYOUT_HANDOUT2, WritingMode_LR_TB,
+     AUTOLAYOUT_HANDOUT2},
+    {BMP_FOILH_03, BMP_FOILH_03_H, STR_AUTOLAYOUT_HANDOUT3, WritingMode_LR_TB,
+     AUTOLAYOUT_HANDOUT3},
+    {BMP_FOILH_04, BMP_FOILH_04_H, STR_AUTOLAYOUT_HANDOUT4, WritingMode_LR_TB,
+     AUTOLAYOUT_HANDOUT4},
+    {BMP_FOILH_06, BMP_FOILH_06_H, STR_AUTOLAYOUT_HANDOUT6, WritingMode_LR_TB,
+     AUTOLAYOUT_HANDOUT6},
+    {BMP_FOILH_09, BMP_FOILH_09_H, STR_AUTOLAYOUT_HANDOUT9, WritingMode_LR_TB,
+     AUTOLAYOUT_HANDOUT9},
+    {0, 0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE},
+};
+
+static snewfoil_value_info standard[] =
+{
+    {BMP_LAYOUT_EMPTY, BMP_LAYOUT_EMPTY_H, STR_AUTOLAYOUT_NONE, WritingMode_LR_TB,        AUTOLAYOUT_NONE},
+	{BMP_LAYOUT_HEAD03, BMP_LAYOUT_HEAD03_H, STR_AUTOLAYOUT_TITLE, WritingMode_LR_TB,       AUTOLAYOUT_TITLE},
+    {BMP_LAYOUT_HEAD02, BMP_LAYOUT_HEAD02_H, STR_AUTOLAYOUT_CONTENT, WritingMode_LR_TB,        AUTOLAYOUT_ENUM},   
+	{BMP_LAYOUT_HEAD02A, BMP_LAYOUT_HEAD02A_H, STR_AUTOLAYOUT_2CONTENT, WritingMode_LR_TB,       AUTOLAYOUT_2TEXT},
+	{BMP_LAYOUT_HEAD01, BMP_LAYOUT_HEAD01_H, STR_AUTOLAYOUT_ONLY_TITLE, WritingMode_LR_TB,  AUTOLAYOUT_ONLY_TITLE},    
+	{BMP_LAYOUT_TEXTONLY, BMP_LAYOUT_TEXTONLY_H, STR_AUTOLAYOUT_ONLY_TEXT, WritingMode_LR_TB,   AUTOLAYOUT_ONLY_TEXT},
+    {BMP_LAYOUT_HEAD03B, BMP_LAYOUT_HEAD03B_H, STR_AUTOLAYOUT_2CONTENT_CONTENT, WritingMode_LR_TB,    AUTOLAYOUT_2OBJTEXT},
+	{BMP_LAYOUT_HEAD03C, BMP_LAYOUT_HEAD03C_H, STR_AUTOLAYOUT_CONTENT_2CONTENT, WritingMode_LR_TB,    AUTOLAYOUT_TEXT2OBJ},
+	{BMP_LAYOUT_HEAD03A, BMP_LAYOUT_HEAD03A_H, STR_AUTOLAYOUT_2CONTENT_OVER_CONTENT,WritingMode_LR_TB, AUTOLAYOUT_2OBJOVERTEXT},    
+	{BMP_LAYOUT_HEAD02B, BMP_LAYOUT_HEAD02B_H, STR_AUTOLAYOUT_CONTENT_OVER_CONTENT, WritingMode_LR_TB, AUTOLAYOUT_OBJOVERTEXT},
+    {BMP_LAYOUT_HEAD04, BMP_LAYOUT_HEAD04_H, STR_AUTOLAYOUT_4CONTENT, WritingMode_LR_TB,        AUTOLAYOUT_4OBJ},   
+	{BMP_LAYOUT_HEAD06, BMP_LAYOUT_HEAD06_H, STR_AUTOLAYOUT_6CONTENT, WritingMode_LR_TB,    AUTOLAYOUT_6CLIPART},
+
+	// vertical
+    {BMP_LAYOUT_VERTICAL02, BMP_LAYOUT_VERTICAL02_H, STR_AL_VERT_TITLE_TEXT_CHART, WritingMode_TB_RL,AUTOLAYOUT_VERTICAL_TITLE_TEXT_CHART},
+    {BMP_LAYOUT_VERTICAL01, BMP_LAYOUT_VERTICAL01_H, STR_AL_VERT_TITLE_VERT_OUTLINE, WritingMode_TB_RL, AUTOLAYOUT_VERTICAL_TITLE_VERTICAL_OUTLINE},
+    {BMP_LAYOUT_HEAD02, BMP_LAYOUT_HEAD02_H, STR_AL_TITLE_VERT_OUTLINE, WritingMode_TB_RL, AUTOLAYOUT_TITLE_VERTICAL_OUTLINE},
+    {BMP_LAYOUT_HEAD02A, BMP_LAYOUT_HEAD02A_H, STR_AL_TITLE_VERT_OUTLINE_CLIPART,   WritingMode_TB_RL, AUTOLAYOUT_TITLE_VERTICAL_OUTLINE_CLIPART},
+    {0, 0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE}
+};
+
+
+
+
+LayoutMenu::LayoutMenu (
+    ::Window* pParent,
+    ViewShellBase& rViewShellBase,
+    SidebarShellManager& rSubShellManager)
+    : ValueSet (pParent),
+      DragSourceHelper(this),
+      DropTargetHelper(this),
+      mrBase(rViewShellBase),
+      mrShellManager(rSubShellManager),
+      mbUseOwnScrollBar(false),
+      mnPreferredColumnCount(3),
+      mxListener(NULL),
+      mbSelectionUpdatePending(true),
+      mbIsMainViewChangePending(false),
+      mxSidebar(),
+      mbIsDisposed(false)
+{
+    implConstruct( *mrBase.GetDocument()->GetDocSh() );
+
+#ifdef DEBUG
+    SetText(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sd:LayoutMenu")));
+#endif
+}
+
+
+
+
+void LayoutMenu::implConstruct( DrawDocShell& rDocumentShell )
+{
+    OSL_ENSURE( mrBase.GetDocument()->GetDocSh() == &rDocumentShell,
+        "LayoutMenu::implConstruct: hmm?" );
+    // if this fires, then my assumption that the rDocumentShell parameter to our first ctor is superfluous ...
+
+	SetStyle (
+        ( GetStyle()  & ~(WB_ITEMBORDER) )
+        | WB_TABSTOP
+        | WB_NO_DIRECTSELECT
+        );
+    if (mbUseOwnScrollBar)
+        SetStyle (GetStyle() | WB_VSCROLL);
+	SetExtraSpacing(2);
+	SetSelectHdl (LINK(this, LayoutMenu, ClickHandler));
+	SetPool (&rDocumentShell.GetDoc()->GetPool());
+    SetName(String(RTL_CONSTASCII_USTRINGPARAM("LayoutMenu")));
+    InvalidateContent();
+
+    Link aEventListenerLink (LINK(this,LayoutMenu,EventMultiplexerListener));
+    mrBase.GetEventMultiplexer()->AddEventListener(aEventListenerLink,
+        ::sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE
+        | ::sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION
+        | ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
+        | ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
+        | ::sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED
+        | ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL
+        | ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER);
+
+    Window::SetHelpId(HID_SD_TASK_PANE_PREVIEW_LAYOUTS);
+    SetAccessibleName(SdResId(STR_TASKPANEL_LAYOUT_MENU_TITLE));
+    
+    Link aStateChangeLink (LINK(this,LayoutMenu,StateChangeHandler));
+    mxListener = new ::sd::tools::SlotStateListener(
+        aStateChangeLink,
+        Reference<frame::XDispatchProvider>(mrBase.GetController()->getFrame(), UNO_QUERY),
+        ::rtl::OUString::createFromAscii(".uno:VerticalTextState"));
+
+    // Add this new object as shell to the shell factory.
+    GetShellManager()->AddSubShell(SHELLID_SD_TASK_PANE_PREVIEW_LAYOUTS,this,this);
+    
+    SetSizePixel(GetParent()->GetSizePixel());
+    Link aWindowEventHandlerLink (LINK(this,LayoutMenu,WindowEventHandler));
+    GetParent()->AddEventListener(aWindowEventHandlerLink);
+}
+
+
+
+
+LayoutMenu::~LayoutMenu (void)
+{
+    Dispose();
+}
+
+
+
+
+void LayoutMenu::Dispose (void)
+{
+    if (mbIsDisposed)
+        return;
+
+    mbIsDisposed = true;
+
+    // Tell the shell factory that this object is no longer available.
+    if (GetShellManager() != NULL)
+        GetShellManager()->RemoveSubShell(this);
+    
+    Reference<lang::XComponent> xComponent (mxListener, UNO_QUERY);
+    if (xComponent.is())
+        xComponent->dispose();
+
+    Clear();
+    Link aLink (LINK(this,LayoutMenu,EventMultiplexerListener));
+    mrBase.GetEventMultiplexer()->RemoveEventListener (aLink);
+
+    Link aWindowEventHandlerLink (LINK(this,LayoutMenu,WindowEventHandler));
+    GetParent()->RemoveEventListener(aWindowEventHandlerLink);
+}
+
+
+
+
+AutoLayout LayoutMenu::GetSelectedAutoLayout (void)
+{
+    AutoLayout aResult = AUTOLAYOUT_NONE;
+    
+    if ( ! IsNoSelection() && GetSelectItemId()!=0)
+    {
+        AutoLayout* pLayout = static_cast<AutoLayout*>(GetItemData(GetSelectItemId()));
+        if (pLayout != NULL)
+            aResult = *pLayout;
+    }
+
+    return aResult;
+}
+
+
+
+
+/** The preferred size depends on the preferred number of columns, the
+    number of items, and the size of the items.
+*/
+Size LayoutMenu::GetPreferredSize (void)
+{
+    Size aItemSize = CalcItemSizePixel (Size());
+    Size aPreferredWindowSize = CalcWindowSizePixel (
+        aItemSize, 
+         (sal_uInt16)mnPreferredColumnCount,
+        (sal_uInt16)CalculateRowCount (aItemSize,mnPreferredColumnCount));
+    return aPreferredWindowSize;
+}
+
+
+
+
+sal_Int32 LayoutMenu::GetPreferredWidth (sal_Int32 nHeight)
+{
+    sal_Int32 nPreferredWidth = 100;
+    if (GetItemCount() > 0)
+    {
+        Image aImage = GetItemImage(GetItemId(0));
+        Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel());
+        if (nHeight>0 && aItemSize.Height()>0)
+        {
+            int nRowCount = nHeight / aItemSize.Height();
+            if (nRowCount <= 0)
+                nRowCount = 1;
+            int nColumnCount = (GetItemCount() + nRowCount-1) / nRowCount;
+            nPreferredWidth = nColumnCount * aItemSize.Width();
+        }
+    }
+
+    return nPreferredWidth;
+}
+
+
+
+
+ui::LayoutSize LayoutMenu::GetHeightForWidth (const sal_Int32 nWidth)
+{
+    sal_Int32 nPreferredHeight = 200;
+    if ( ! mbUseOwnScrollBar && GetItemCount()>0)
+    {
+        Image aImage = GetItemImage(GetItemId(0));
+        Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel());
+        if (nWidth>0 && aItemSize.Width()>0)
+        {
+            aItemSize.Width() += 8;
+            aItemSize.Height() += 8;
+            int nColumnCount = nWidth / aItemSize.Width();
+            if (nColumnCount <= 0)
+                nColumnCount = 1;
+            else if (nColumnCount > 4)
+                nColumnCount = 4;
+            int nRowCount = (GetItemCount() + nColumnCount-1) / nColumnCount;
+            nPreferredHeight = nRowCount * aItemSize.Height();
+        }
+    }
+    return ui::LayoutSize(nPreferredHeight,nPreferredHeight,nPreferredHeight);
+}
+
+
+
+
+sal_Int32 LayoutMenu::GetMinimumWidth (void)
+{
+    sal_Int32 nMinimumWidth = 0;
+    if (GetItemCount()>0)
+    {
+        Image aImage = GetItemImage(GetItemId(0));
+        Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel());
+        nMinimumWidth = aItemSize.Width();
+    }
+    return nMinimumWidth;
+}
+
+
+
+
+void LayoutMenu::UpdateEnabledState (const MasterMode eMode)
+{
+    bool bIsEnabled (false);
+
+    ::boost::shared_ptr<ViewShell> pMainViewShell (mrBase.GetMainViewShell());
+    if (pMainViewShell)
+    {
+        switch (pMainViewShell->GetShellType())
+        {
+            case ViewShell::ST_NONE:
+            case ViewShell::ST_OUTLINE:
+            case ViewShell::ST_PRESENTATION:
+            case ViewShell::ST_SIDEBAR:
+                // The complete task pane is disabled for these values or
+                // not even visible.  Disabling the LayoutMenu would be
+                // logical but unnecessary.  The main disadvantage is that
+                // after re-enabling it (typically) another panel is
+                // expanded.
+                bIsEnabled = true;
+                break;
+                
+            case ViewShell::ST_DRAW:
+            case ViewShell::ST_IMPRESS:
+            {
+                switch (eMode)
+                {
+                    case MM_UNKNOWN:
+                    {
+                        ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
+                            ::boost::dynamic_pointer_cast<DrawViewShell>(pMainViewShell));
+                        if (pDrawViewShell)
+                            bIsEnabled = pDrawViewShell->GetEditMode() != EM_MASTERPAGE;
+                        break;
+                    }
+                    case MM_NORMAL:
+                        bIsEnabled = true;
+                        break;
+
+                    case MM_MASTER:
+                        bIsEnabled = false;
+                        break;
+                }
+                break;
+            }
+
+            case ViewShell::ST_HANDOUT:
+            case ViewShell::ST_NOTES:
+            case ViewShell::ST_SLIDE_SORTER:
+            default:
+                bIsEnabled = true;
+                break;
+        }
+    }
+}
+
+
+
+
+void LayoutMenu::Paint (const Rectangle& rRect)
+{
+	SetBackground (GetSettings().GetStyleSettings().GetWindowColor());
+
+    if (mbSelectionUpdatePending)
+    {
+        mbSelectionUpdatePending = false;
+        UpdateSelection();
+    }
+    ValueSet::Paint (rRect);
+
+	SetBackground (Wallpaper());
+}
+
+
+
+
+void LayoutMenu::Resize (void)
+{
+    Size aWindowSize = GetOutputSizePixel();
+    if (IsVisible() && aWindowSize.Width() > 0)
+    {
+        // Calculate the number of rows and columns.
+        if (GetItemCount() > 0)
+        {
+            Image aImage = GetItemImage(GetItemId(0));
+            Size aItemSize = CalcItemSizePixel (
+                aImage.GetSizePixel());
+            aItemSize.Width() += 8;
+            aItemSize.Height() += 8;
+            int nColumnCount = aWindowSize.Width() / aItemSize.Width();
+            if (nColumnCount < 1)
+                nColumnCount = 1;
+            else if (nColumnCount > 4)
+                nColumnCount = 4;
+
+            int nRowCount = CalculateRowCount (aItemSize, nColumnCount);
+            
+            SetColCount ((sal_uInt16)nColumnCount);
+            SetLineCount ((sal_uInt16)nRowCount);
+        }
+    }
+
+    ValueSet::Resize ();
+}
+
+
+
+
+void LayoutMenu::MouseButtonDown (const MouseEvent& rEvent)
+{
+    // As a preparation for the context menu the item under the mouse is
+    // selected.
+    if (rEvent.IsRight())
+    {
+        ReleaseMouse();
+        sal_uInt16 nIndex = GetItemId (rEvent.GetPosPixel());
+        if (nIndex > 0)
+            SelectItem(nIndex);
+    }
+    
+    ValueSet::MouseButtonDown (rEvent);
+}
+
+
+
+
+void LayoutMenu::Execute (SfxRequest& rRequest)
+{
+	switch (rRequest.GetSlot())
+    {
+        case SID_TP_APPLY_TO_SELECTED_SLIDES:
+            AssignLayoutToSelectedSlides(GetSelectedAutoLayout());
+            rRequest.Done();
+            break;
+
+        case SID_INSERTPAGE_LAYOUT_MENU:
+            // Add arguments to this slot and forward it to the main view
+            // shell.
+            InsertPageWithLayout(GetSelectedAutoLayout());
+            break;
+    }
+}
+
+
+
+
+void LayoutMenu::GetState (SfxItemSet& rItemSet)
+{
+    // Cut and paste is not supported.  The SID_(CUT,COPY,PASTE) entries
+    // therefore must not show up in the context menu.
+    rItemSet.DisableItem (SID_CUT);
+    rItemSet.DisableItem (SID_COPY);
+    rItemSet.DisableItem (SID_PASTE);
+
+    // The SID_INSERTPAGE_LAYOUT_MENU slot depends on the SID_INSERTPAGE
+    // slot being supported elsewhere.
+    const SfxPoolItem* pItem = NULL;
+    const SfxItemState aState (
+        mrBase.GetViewFrame()->GetDispatcher()->QueryState(SID_INSERTPAGE, pItem));
+    if (aState == SFX_ITEM_DISABLED)
+        rItemSet.DisableItem(SID_INSERTPAGE_LAYOUT_MENU);
+}
+
+
+
+
+void LayoutMenu::InsertPageWithLayout (AutoLayout aLayout)
+{
+    ViewShell* pViewShell = mrBase.GetMainViewShell().get();
+    if (pViewShell == NULL)
+        return;
+
+    SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
+    if (pViewFrame == NULL)
+        return;
+
+    SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
+    if (pDispatcher == NULL)
+        return;
+
+    // Call SID_INSERTPAGE with the right arguments.  This is because
+    // the popup menu can not call this slot with arguments directly.
+    SfxRequest aRequest (CreateRequest(SID_INSERTPAGE, aLayout));
+    if (aRequest.GetArgs() != NULL)
+    {
+        pDispatcher->Execute(
+            SID_INSERTPAGE,
+            SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
+            *aRequest.GetArgs());
+    }
+    UpdateSelection();
+}
+
+
+
+
+SidebarShellManager* LayoutMenu::GetShellManager()
+{
+    return &mrShellManager;
+}
+
+
+
+
+void LayoutMenu::InvalidateContent (void)
+{
+    // The number of items may have changed.  Request a resize so that the
+    // vertical size of this control can be adapted.
+    //    RequestResize();
+
+    // Throw away the current set and fill the menu anew according to the
+    // current settings (this includes the support for vertical writing.)
+    Fill();
+}
+
+
+
+
+int LayoutMenu::CalculateRowCount (const Size&, int nColumnCount)
+{
+    int nRowCount = 0;
+
+    if (GetItemCount() > 0 && nColumnCount > 0)
+    {
+        nRowCount = (GetItemCount() + nColumnCount - 1) / nColumnCount;
+        //        nRowCount = GetOutputSizePixel().Height() / rItemSize.Height();
+        if (nRowCount < 1)
+            nRowCount = 1;
+    }
+
+    return nRowCount;
+}
+
+
+
+
+IMPL_LINK(LayoutMenu, ClickHandler, ValueSet*, EMPTYARG)
+{
+    AssignLayoutToSelectedSlides (GetSelectedAutoLayout());
+    return 0;
+}
+
+
+
+
+/** The specified layout is assigned to the current page of the view shell
+    in the center pane.
+*/
+void LayoutMenu::AssignLayoutToSelectedSlides (AutoLayout aLayout)
+{
+    using namespace ::sd::slidesorter;
+    using namespace ::sd::slidesorter::controller;
+
+    do
+    {
+        // The view shell in the center pane has to be present.
+        ViewShell* pMainViewShell = mrBase.GetMainViewShell().get();
+        if (pMainViewShell == NULL)
+            break;
+
+        // Determine if the current view is in an invalid master page mode.
+        // The handout view is always in master page mode and therefore not
+        // invalid.
+        bool bMasterPageMode (false);
+        switch (pMainViewShell->GetShellType())
+        {
+            case ViewShell::ST_NOTES:
+            case ViewShell::ST_IMPRESS:
+            {
+                DrawViewShell* pDrawViewShell = static_cast<DrawViewShell*>(pMainViewShell);
+                if (pDrawViewShell != NULL)
+                    if (pDrawViewShell->GetEditMode() == EM_MASTERPAGE)
+                        bMasterPageMode = true;
+            }
+			default:
+				break;
+        }
+        if (bMasterPageMode)
+            break;
+
+        // Get a list of all selected slides and call the SID_MODIFYPAGE
+        // slot for all of them.
+		::sd::slidesorter::SharedPageSelection pPageSelection;
+
+        // Get a list of selected pages.
+        // First we try to obtain this list from a slide sorter.  This is
+        // possible only some of the view shells in the center pane.  When
+        // no valid slide sorter is available then ask the main view shell
+        // for its current page.
+        SlideSorterViewShell* pSlideSorter = NULL;
+        switch (pMainViewShell->GetShellType())
+        {
+            case ViewShell::ST_IMPRESS:
+            case ViewShell::ST_NOTES:
+            case ViewShell::ST_SLIDE_SORTER:
+                pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase);
+                break;
+			default:
+				break;
+        }
+		if (pSlideSorter != NULL)
+		{
+			// There is a slide sorter visible so get the list of selected pages from it.
+            pPageSelection = pSlideSorter->GetPageSelection();
+		}
+
+		if( (pSlideSorter == NULL) || (pPageSelection.get() == 0) || pPageSelection->empty() )
+		{
+			// No valid slide sorter available.  Ask the main view shell for
+			// its current page.
+            pPageSelection.reset(new ::sd::slidesorter::SlideSorterViewShell::PageSelection());
+            pPageSelection->push_back(pMainViewShell->GetActualPage());
+		}
+			
+
+		if (pPageSelection->empty())
+			break;
+
+		::std::vector<SdPage*>::iterator iPage;
+		for (iPage=pPageSelection->begin(); iPage!=pPageSelection->end(); ++iPage)
+			{
+				if ((*iPage) == NULL)
+					continue;
+
+				// Call the SID_ASSIGN_LAYOUT slot with all the necessary parameters.
+				SfxRequest aRequest (mrBase.GetViewFrame(), SID_ASSIGN_LAYOUT);
+				aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATPAGE, ((*iPage)->GetPageNum()-1)/2));
+				aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout));
+				pMainViewShell->ExecuteSlot (aRequest, sal_Bool(sal_False));
+			}
+    }
+    while(false);
+}
+
+
+
+
+SfxRequest LayoutMenu::CreateRequest (
+    sal_uInt16 nSlotId,
+    AutoLayout aLayout)
+{
+    SfxRequest aRequest (mrBase.GetViewFrame(), nSlotId);
+
+    do
+    {
+        SdrLayerAdmin& rLayerAdmin (mrBase.GetDocument()->GetLayerAdmin());
+        sal_uInt8 aBackground (rLayerAdmin.GetLayerID(
+            String(SdResId(STR_LAYER_BCKGRND)), sal_False));
+        sal_uInt8 aBackgroundObject (rLayerAdmin.GetLayerID(
+            String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False));
+        ViewShell* pViewShell = mrBase.GetMainViewShell().get();
+        if (pViewShell == NULL)
+            break;
+        SdPage* pPage = pViewShell->GetActualPage();
+        if (pPage == NULL)
+            break;
+
+        SetOfByte aVisibleLayers (pPage->TRG_GetMasterPageVisibleLayers());
+    
+        aRequest.AppendItem(
+            SfxStringItem (ID_VAL_PAGENAME, String()));//pPage->GetName()));
+        aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout));
+        aRequest.AppendItem(
+            SfxBoolItem(ID_VAL_ISPAGEBACK, aVisibleLayers.IsSet(aBackground)));
+        aRequest.AppendItem(
+            SfxBoolItem(
+                ID_VAL_ISPAGEOBJ,
+                aVisibleLayers.IsSet(aBackgroundObject)));
+    }
+    while (false);
+
+    return aRequest;
+}
+
+
+
+
+void LayoutMenu::Fill (void)
+{
+	const bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
+	SvtLanguageOptions aLanguageOptions;
+    sal_Bool bVertical = aLanguageOptions.IsVerticalTextEnabled();
+    SdDrawDocument* pDocument = mrBase.GetDocument();
+    sal_Bool bRightToLeft = (pDocument!=NULL 
+        && pDocument->GetDefaultWritingMode() == WritingMode_RL_TB);
+
+    // Get URL of the view in the center pane.
+    ::rtl::OUString sCenterPaneViewName;
+    try
+    {
+        Reference<XControllerManager> xControllerManager (
+            Reference<XWeak>(&mrBase.GetDrawController()), UNO_QUERY_THROW);
+        Reference<XResourceId> xPaneId (ResourceId::create(
+            ::comphelper::getProcessComponentContext(),
+            FrameworkHelper::msCenterPaneURL));
+        Reference<XView> xView (FrameworkHelper::Instance(mrBase)->GetView(xPaneId));
+        if (xView.is())
+            sCenterPaneViewName = xView->getResourceId()->getResourceURL();
+    }
+    catch (RuntimeException&)
+    {}
+    
+	snewfoil_value_info* pInfo = NULL;
+    if (sCenterPaneViewName.equals(framework::FrameworkHelper::msNotesViewURL))
+    {
+        pInfo = notes;
+    }
+    else if (sCenterPaneViewName.equals(framework::FrameworkHelper::msHandoutViewURL))
+    {
+        pInfo = handout;
+    }
+    else if (sCenterPaneViewName.equals(framework::FrameworkHelper::msImpressViewURL)
+        || sCenterPaneViewName.equals(framework::FrameworkHelper::msSlideSorterURL))
+    {
+        pInfo = standard;
+    }
+    else
+    {
+        pInfo = NULL;
+	}
+
+    Clear();
+    int n = 0;
+	for (sal_uInt16 i=1; pInfo!=NULL&&pInfo->mnBmpResId!=0; i++,pInfo++)
+	{
+        if ((WritingMode_TB_RL != pInfo->meWritingMode) || bVertical)
+        {
+            BitmapEx aBmp (SdResId (bHighContrast 
+                             ? pInfo->mnHCBmpResId 
+                             : pInfo->mnBmpResId));
+		
+            if (bRightToLeft && (WritingMode_TB_RL != pInfo->meWritingMode))
+                aBmp.Mirror (BMP_MIRROR_HORZ);
+
+            InsertItem (i, aBmp, String (SdResId (pInfo->mnStrResId)));
+            SetItemData (i, new AutoLayout(pInfo->maAutoLayout));
+            n++;
+        }
+	}
+
+    mbSelectionUpdatePending = true;
+}
+
+
+
+
+void LayoutMenu::Clear (void)
+{
+    for (sal_uInt16 nId=1; nId<=GetItemCount(); nId++)
+        delete static_cast<AutoLayout*>(GetItemData(nId));
+    ValueSet::Clear();
+}
+
+
+
+void LayoutMenu::StartDrag (sal_Int8 , const Point& )
+{
+}
+
+
+
+
+sal_Int8 LayoutMenu::AcceptDrop (const AcceptDropEvent& )
+{
+    return 0;
+}
+
+
+
+
+sal_Int8 LayoutMenu::ExecuteDrop (const ExecuteDropEvent& )
+{
+    return 0;
+}
+
+
+
+
+void LayoutMenu::Command (const CommandEvent& rEvent)
+{
+    switch (rEvent.GetCommand())
+    {
+        case COMMAND_CONTEXTMENU:
+            if ( ! SD_MOD()->GetWaterCan())
+            {
+                if (GetShellManager() != NULL)
+                    GetShellManager()->MoveToTop(this);
+                if (rEvent.IsMouseEvent())
+                {
+                    // Do not show the context menu when the mouse was not
+                    // pressed over an item.
+                    if (GetItemId(rEvent.GetMousePosPixel()) > 0)
+                        mrBase.GetViewFrame()->GetDispatcher()->ExecutePopup(
+                            SdResId(RID_TASKPANE_LAYOUTMENU_POPUP));
+                }
+                else
+                {
+                    // When the command event was not caused by a mouse
+                    // event (for example a key press instead) then show the
+                    // popup menu at the center of the current item.
+                    if (GetSelectItemId() != (sal_uInt16)-1)
+                    {
+                    	Rectangle aBBox (GetItemRect(GetSelectItemId()));
+                        Point aPosition (aBBox.Center());
+                        mrBase.GetViewFrame()->GetDispatcher()->ExecutePopup(
+                            SdResId(RID_TASKPANE_LAYOUTMENU_POPUP),
+                            this,
+                            &aPosition);
+                    }
+                }
+            }
+            break;
+
+        default:
+            ValueSet::Command(rEvent);
+            break;
+    }
+}
+
+
+
+
+IMPL_LINK(LayoutMenu, StateChangeHandler, ::rtl::OUString*, EMPTYARG)
+{
+    InvalidateContent();
+    return 0;
+}
+
+
+
+
+void LayoutMenu::UpdateSelection (void)
+{
+    bool bItemSelected = false;
+
+    do
+    {
+        // Get current page of main view.
+        ViewShell* pViewShell = mrBase.GetMainViewShell().get();
+        if (pViewShell == NULL)
+            break;
+        
+        SdPage* pCurrentPage = pViewShell->getCurrentPage();
+        if (pCurrentPage == NULL)
+            break;
+
+        // Get layout of current page.
+        AutoLayout aLayout (pCurrentPage->GetAutoLayout());
+        if (aLayout<AUTOLAYOUT__START || aLayout>AUTOLAYOUT__END)
+            break;
+
+        // Find the entry of the menu for to the layout.
+        sal_uInt16 nItemCount (GetItemCount());
+        for (sal_uInt16 nId=1; nId<=nItemCount; nId++)
+        {
+            if (*static_cast<AutoLayout*>(GetItemData(nId)) == aLayout)
+            {
+                SelectItem(nId);
+                bItemSelected = true;
+                break;
+            }
+        }
+    }
+    while (false);
+
+    if ( ! bItemSelected)
+        SetNoSelection();
+}
+
+
+
+
+IMPL_LINK(LayoutMenu, EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent*, pEvent)
+{
+    switch (pEvent->meEventId)
+    {
+        case ::sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
+        case ::sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION:
+            if ( ! mbSelectionUpdatePending)
+                UpdateSelection();
+            break;
+
+        case ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
+            mbIsMainViewChangePending = true;
+            UpdateEnabledState(MM_UNKNOWN);
+            break;
+
+        case ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
+            HideFocus();
+            break;
+
+        case ::sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
+            if (mbIsMainViewChangePending)
+            {
+                mbIsMainViewChangePending = false;
+                InvalidateContent();
+            }
+            break;
+
+        case ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL:
+            UpdateEnabledState(MM_NORMAL);
+            break;
+
+        case ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER:
+            UpdateEnabledState(MM_MASTER);
+            break;
+
+        default:
+            /* Ignored */
+            break;
+    }
+
+    return 0;
+}
+
+
+
+
+IMPL_LINK(LayoutMenu, WindowEventHandler, VclWindowEvent*, pEvent)
+{
+    if (pEvent != NULL)
+    {
+        switch (pEvent->GetId())
+        {
+            case VCLEVENT_WINDOW_SHOW:
+            case VCLEVENT_WINDOW_RESIZE:
+                SetSizePixel(GetParent()->GetSizePixel());
+                return sal_True;
+
+            default:
+                return sal_False;
+        }
+
+        const SfxSimpleHint* pSimpleHint = PTR_CAST(SfxSimpleHint, pEvent);
+        if (pSimpleHint != NULL
+            && pSimpleHint->GetId() == SFX_HINT_DYING)
+        {
+            return sal_True;
+        }
+    }
+
+    return sal_False;
+}
+
+
+
+
+void LayoutMenu::DataChanged (const DataChangedEvent& rEvent)
+{
+    Fill();
+    ValueSet::DataChanged(rEvent);
+}
+
+
+
+
+void LayoutMenu::SetSidebar (const cssu::Reference<css::ui::XSidebar>& rxSidebar)
+{
+    mxSidebar = rxSidebar;
+    if (mxSidebar.is())
+        mxSidebar->requestLayout();
+}
+
+
+
+} } // end of namespace ::sd::sidebar

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/LayoutMenu.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/LayoutMenu.hxx?rev=1447641&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/LayoutMenu.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/panels/LayoutMenu.hxx Tue Feb 19 09:09:02 2013
@@ -0,0 +1,241 @@
+/**************************************************************
+ * 
+ * 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_LAYOUT_MENU_HXX
+#define SD_SIDEBAR_LAYOUT_MENU_HXX
+
+#include "../IDisposable.hxx"
+#include "../ILayoutableWindow.hxx"
+#include "../ISidebarReceiver.hxx"
+
+#include "glob.hxx"
+#include "pres.hxx"
+
+#include <vcl/ctrl.hxx>
+#include <svtools/valueset.hxx>
+#include <svtools/transfer.hxx>
+#include <sfx2/shell.hxx>
+
+#include <com/sun/star/frame/XStatusListener.hpp>
+#include <com/sun/star/ui/XSidebar.hpp>
+
+
+class SfxModule;
+
+namespace css = ::com::sun::star;
+namespace cssu = ::com::sun::star::uno;
+
+namespace sd {
+class DrawDocShell;
+class PaneManagerEvent;
+class ViewShellBase;
+}
+
+
+namespace sd { namespace tools {
+class EventMultiplexerEvent;
+} }
+
+
+namespace sd { namespace sidebar {
+
+class ControlFactory;
+class SidebarViewShell;
+class SidebarShellManager;
+
+
+class LayoutMenu
+    : public ValueSet,
+      public SfxShell,
+      public DragSourceHelper, 
+      public DropTargetHelper,
+      public ILayoutableWindow,
+      public IDisposable,
+      public ISidebarReceiver
+{
+public:
+    TYPEINFO();
+    SFX_DECL_INTERFACE(SD_IF_SDLAYOUTMENU)
+
+    /** Create a new layout menu.  Depending on the given flag it
+        displays its own scroll bar or lets a surrounding window
+        handle that.
+        @param i_pParent
+            the parent node in the control tree
+        @param i_rPanelViewShell
+            the view shell of the task pane.
+    */
+    LayoutMenu (
+        ::Window* pParent,
+        ViewShellBase& rViewShellBase,
+        SidebarShellManager& rSubShellManager);
+    virtual ~LayoutMenu (void);
+
+    virtual void Dispose (void);
+    
+    /** Return a numerical value representing the currently selected
+        layout.
+    */
+    AutoLayout GetSelectedAutoLayout (void);
+
+    Size GetPreferredSize (void);
+    sal_Int32 GetPreferredWidth (sal_Int32 nHeight);
+    sal_Int32 GetMinimumWidth (void);
+
+    // From ILayoutableWindow
+    virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth);
+
+    // From ::Window
+	virtual void Paint (const Rectangle& rRect);
+    virtual void Resize (void);
+
+    /** Show a context menu when the right mouse button is pressed.
+    */
+    virtual void MouseButtonDown (const MouseEvent& rEvent);
+
+    void Execute (SfxRequest& rRequest);
+    void GetState (SfxItemSet& rItemSet);
+
+    /** The LayoutMenu does not support some main views.  In this case the
+        LayoutMenu is disabled.  This state is updated in this method.
+        @param eMode
+            On some occasions the edit mode is being switched when this
+            method is called can not (yet) be reliably detected.  Luckily,
+            in these cases the new value is provided by some broadcaster.
+            On other occasions the edit mode is not modified and is also not
+            provided.  Therefore the Unknown value.
+    */
+    enum MasterMode { MM_NORMAL, MM_MASTER, MM_UNKNOWN };
+    void UpdateEnabledState (const MasterMode eMode);
+
+    SidebarShellManager* GetShellManager (void);
+
+    /** Call this method when the set of displayed layouts is not up-to-date
+        anymore.  It will re-assemple this set according to the current
+        settings.
+    */
+    void InvalidateContent (void);
+
+	// DragSourceHelper
+	virtual void StartDrag (sal_Int8 nAction, const Point& rPosPixel);
+
+	// DropTargetHelper
+	virtual sal_Int8 AcceptDrop (const AcceptDropEvent& rEvent);
+	virtual sal_Int8 ExecuteDrop (const ExecuteDropEvent& rEvent);
+
+    /** The context menu is requested over this Command() method.
+    */
+	virtual void Command (const CommandEvent& rEvent);
+
+    /** Call Fill() when switching to or from high contrast mode so that the
+        correct set of icons is displayed.
+    */
+    virtual void DataChanged (const DataChangedEvent& rEvent);
+
+    // ISidebarReceiver
+    virtual void SetSidebar (const cssu::Reference<css::ui::XSidebar>& rxSidebar);
+
+	using Window::GetWindow;
+	using ValueSet::StartDrag;
+
+private:
+    ViewShellBase& mrBase;
+    SidebarShellManager& mrShellManager;
+
+    /** Do we use our own scroll bar or is viewport handling done by
+        our parent?
+    */
+    bool mbUseOwnScrollBar;
+
+    /** If we are asked for the preferred window size, then use this
+        many columns for the calculation.
+    */
+    const int mnPreferredColumnCount;
+    cssu::Reference<css::frame::XStatusListener> mxListener;
+    bool mbSelectionUpdatePending;
+    bool mbIsMainViewChangePending;
+    cssu::Reference<css::ui::XSidebar> mxSidebar;
+    bool mbIsDisposed;
+
+    /** Calculate the number of displayed rows.  This depends on the given
+        item size, the given number of columns, and the size of the
+        control.  Note that this is not the number of rows managed by the
+        valueset.  This number may be larger.  In that case a vertical
+        scroll bar is displayed.
+    */
+    int CalculateRowCount (const Size& rItemSize, int nColumnCount);
+
+    /** Fill the value set with the layouts that are applicable to the
+        current main view shell.
+    */
+    void Fill (void);
+
+    /** Remove all items from the value set.
+    */
+    void Clear (void);
+
+    /** Assign the given layout to all selected slides of a slide sorter.
+        If no slide sorter is active then this call is ignored.  The slide
+        sorter in the center pane is preferred if the choice exists.
+    */
+    void AssignLayoutToSelectedSlides (AutoLayout aLayout);
+
+    /** Insert a new page with the given layout.  The page is inserted via
+        the main view shell, i.e. its SID_INSERTPAGE slot is called.  It it
+        does not support this slot then inserting a new page does not take
+        place.  The new page is inserted after the currently active one (the
+        one returned by ViewShell::GetActualPage().)
+    */
+    void InsertPageWithLayout (AutoLayout aLayout);
+
+    /** Create a request structure that can be used with the SID_INSERTPAGE
+        and SID_MODIFYPAGE slots.  The parameters are set so that the given
+        layout is assigned to the current page of the main view shell.
+        @param nSlotId
+            Supported slots are SID_INSERTPAGE and SID_MODIFYPAGE.
+        @param aLayout
+            Layout of the page to insert or to assign.
+    */
+    SfxRequest CreateRequest (
+        sal_uInt16 nSlotId,
+        AutoLayout aLayout);
+
+    /** Select the layout that is used by the current page.
+    */
+    void UpdateSelection (void);
+
+    // internal ctor
+    void    implConstruct( DrawDocShell& rDocumentShell );
+
+    /** When clicked then set the current page of the view in the center pane.
+    */
+    DECL_LINK(ClickHandler, ValueSet*);
+    DECL_LINK(RightClickHandler, MouseEvent*);
+    DECL_LINK(StateChangeHandler, ::rtl::OUString*);
+    DECL_LINK(EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent*);
+    DECL_LINK(WindowEventHandler, VclWindowEvent*);
+};
+
+} } // end of namespace ::sd::toolpanel
+
+#endif