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 [4/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/MasterPagesSelector.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPagesSelector.cxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPagesSelector.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPagesSelector.cxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,845 @@
+/**************************************************************
+ * 
+ * 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 "MasterPagesSelector.hxx"
+
+#include "MasterPageContainer.hxx"
+#include "DocumentHelper.hxx"
+#include "SidebarShellManager.hxx"
+#include "pres.hxx"
+#include "drawdoc.hxx"
+#include "DrawDocShell.hxx"
+#include "sdpage.hxx"
+#include "glob.hxx"
+#include "glob.hrc"
+#include "app.hrc"
+#include "res_bmp.hrc"
+#include "strings.hrc"
+#include "DrawViewShell.hxx"
+#include "DrawController.hxx"
+#include "SlideSorterViewShell.hxx"
+#include "PreviewValueSet.hxx"
+#include "ViewShellBase.hxx"
+#include <sfx2/objface.hxx>
+#include "sdresid.hxx"
+#include "drawview.hxx"
+#include <vcl/image.hxx>
+#include <vcl/floatwin.hxx>
+#include <svl/languageoptions.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/mnumgr.hxx>
+#include <svl/itemset.hxx>
+#include <svl/eitem.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svxids.hrc>
+#include "FrameView.hxx"
+#include "sdpage.hxx"
+#include "stlpool.hxx"
+#include "unmovss.hxx"
+#include <sfx2/request.hxx>
+#include <svl/itempool.hxx>
+
+
+using namespace ::com::sun::star::text;
+
+
+
+namespace sd { namespace sidebar {
+
+
+MasterPagesSelector::MasterPagesSelector (
+    ::Window* pParent,
+    SdDrawDocument& rDocument,
+    ViewShellBase& rBase,
+    const ::boost::shared_ptr<MasterPageContainer>& rpContainer,
+    const cssu::Reference<css::ui::XSidebar>& rxSidebar)
+    : PreviewValueSet(pParent),
+      maMutex(),
+      mpContainer(rpContainer),
+      mrDocument(rDocument),
+      mrBase(rBase),
+      mnDefaultClickAction(SID_TP_APPLY_TO_ALL_SLIDES),
+      maPreviewUpdateQueue(),
+      maCurrentItemList(),
+      maTokenToValueSetIndex(),
+      maLockedMasterPages(),
+      mxSidebar(rxSidebar)
+{
+    PreviewValueSet::SetSelectHdl (
+        LINK(this, MasterPagesSelector, ClickHandler));
+	PreviewValueSet::SetRightMouseClickHandler (
+        LINK(this, MasterPagesSelector, RightClickHandler));
+    PreviewValueSet::SetStyle(PreviewValueSet::GetStyle() | WB_NO_DIRECTSELECT);
+    PreviewValueSet::SetPreviewSize(mpContainer->GetPreviewSizePixel());
+    PreviewValueSet::Show();
+
+    Link aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener));
+    mpContainer->AddChangeListener(aChangeListener);
+}
+
+
+
+
+MasterPagesSelector::~MasterPagesSelector (void)
+{
+    Clear();
+    UpdateLocks(ItemList());
+
+    Link aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener));
+    mpContainer->RemoveChangeListener(aChangeListener);
+}
+
+
+
+
+void MasterPagesSelector::LateInit (void)
+{
+}
+
+
+
+
+sal_Int32 MasterPagesSelector::GetPreferredWidth (sal_Int32 nHeight)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    return PreviewValueSet::GetPreferredWidth (nHeight);
+}
+
+
+
+
+sal_Int32 MasterPagesSelector::GetPreferredHeight (sal_Int32 nWidth)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    return PreviewValueSet::GetPreferredHeight (nWidth);
+}
+
+
+
+
+Size MasterPagesSelector::GetPreferredSize (void)
+{
+    int nPreferredWidth = GetPreferredWidth(
+        PreviewValueSet::GetOutputSizePixel().Height());
+    int nPreferredHeight = GetPreferredHeight(nPreferredWidth);
+    return Size (nPreferredWidth, nPreferredHeight);
+
+}
+
+
+
+
+void MasterPagesSelector::UpdateLocks (const ItemList& rItemList)
+{
+    ItemList aNewLockList;
+    
+    // In here we first lock the master pages in the given list and then
+    // release the locks acquired in a previous call to this method.  When
+    // this were done the other way round the lock count of some master
+    // pages might drop temporarily to 0 and would lead to unnecessary
+    // deletion and re-creation of MasterPageDescriptor objects.
+
+    // Lock the master pages in the given list.
+    ItemList::const_iterator iItem;
+    for (iItem=rItemList.begin(); iItem!=rItemList.end(); ++iItem)
+    {
+        mpContainer->AcquireToken(*iItem);
+        aNewLockList.push_back(*iItem);
+    }
+
+    // Release the previously locked master pages.
+    ItemList::const_iterator iPage;
+    ItemList::const_iterator iEnd (maLockedMasterPages.end());
+    for (iPage=maLockedMasterPages.begin(); iPage!=iEnd; ++iPage)
+        mpContainer->ReleaseToken(*iPage);
+
+    maLockedMasterPages.swap(aNewLockList);
+}
+
+
+
+
+void MasterPagesSelector::Fill (void)
+{
+    ::std::auto_ptr<ItemList> pItemList (new ItemList());
+    
+    Fill(*pItemList);
+
+    UpdateLocks(*pItemList);
+    UpdateItemList(pItemList);
+}
+
+
+
+
+ResId MasterPagesSelector::GetContextMenuResId (void) const
+{
+    return SdResId(RID_TASKPANE_MASTERPAGESSELECTOR_POPUP);
+}
+
+
+
+
+IMPL_LINK(MasterPagesSelector, ClickHandler, PreviewValueSet*, EMPTYARG)
+{
+    // We use the framework to assign the clicked-on master page because we
+    // so use the same mechanism as the context menu does (where we do not
+    // have the option to call the assignment method directly.)
+    ExecuteCommand(mnDefaultClickAction);
+
+    return 0;
+}
+
+
+
+
+IMPL_LINK(MasterPagesSelector, RightClickHandler, MouseEvent*, pEvent)
+{
+    // Here we only prepare the display of the context menu: the item under
+    // the mouse is selected.  The actual display of the context menu is
+    // done in ContextMenuCallback which is called indirectly through
+    // PreviewValueSet::Command().
+    PreviewValueSet::GrabFocus ();
+    PreviewValueSet::ReleaseMouse();
+    SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
+    if (pViewFrame != NULL)
+    {
+        SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
+        if (pDispatcher != NULL &&  pEvent != NULL)
+        {
+            sal_uInt16 nIndex = PreviewValueSet::GetItemId (pEvent->GetPosPixel());
+            if (nIndex > 0)
+                PreviewValueSet::SelectItem (nIndex);
+        }
+    }
+    return 0;
+}
+
+
+
+
+void MasterPagesSelector::Command (const CommandEvent& rEvent)
+{
+    switch (rEvent.GetCommand())
+    {
+        case COMMAND_CONTEXTMENU:
+        {
+            // Use the currently selected item and show the popup menu in its
+            // center.
+            const sal_uInt16 nIndex = PreviewValueSet::GetSelectItemId();
+            if (nIndex > 0)
+            {
+                // The position of the upper left corner of the context menu is
+                // taken either from the mouse position (when the command was sent
+                // as reaction to a right click) or in the center of the selected
+                // item (when the command was sent as reaction to Shift+F10.)
+                Point aPosition (rEvent.GetMousePosPixel());
+                if ( ! rEvent.IsMouseEvent())
+                {
+                    Rectangle aBBox (PreviewValueSet::GetItemRect(nIndex));
+                    aPosition = aBBox.Center();
+                }
+
+                // Setup the menu.
+                ::boost::scoped_ptr<PopupMenu> pMenu (new PopupMenu(GetContextMenuResId()));
+                FloatingWindow* pMenuWindow = dynamic_cast<FloatingWindow*>(pMenu->GetWindow());
+                if (pMenuWindow != NULL)
+                    pMenuWindow->SetPopupModeFlags(
+                        pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE);
+                pMenu->SetSelectHdl(LINK(this, MasterPagesSelector, OnMenuItemSelected));
+
+                ProcessPopupMenu(*pMenu);
+
+                // Show the menu.
+                pMenu->Execute(this, Rectangle(aPosition,Size(1,1)), POPUPMENU_EXECUTE_DOWN);
+            }
+            break;
+        }
+    }
+}
+
+
+
+
+void MasterPagesSelector::ProcessPopupMenu (Menu& rMenu)
+{
+    // Disable some entries.
+    if (mpContainer->GetPreviewSize() == MasterPageContainer::SMALL)
+        rMenu.EnableItem(SID_TP_SHOW_SMALL_PREVIEW, sal_False);
+    else
+        rMenu.EnableItem(SID_TP_SHOW_LARGE_PREVIEW, sal_False);
+}
+
+
+
+
+IMPL_LINK(MasterPagesSelector, OnMenuItemSelected, Menu*, pMenu)
+{
+    if (pMenu == NULL)
+    {
+        OSL_ENSURE(pMenu!=NULL, "MasterPagesSelector::OnMenuItemSelected: illegal menu!");
+        return 0;
+    }
+
+    pMenu->Deactivate();
+    ExecuteCommand(pMenu->GetCurItemId());
+    return 0;
+}
+
+
+
+
+void MasterPagesSelector::ExecuteCommand (const sal_Int32 nCommandId)
+{
+	switch (nCommandId)
+    {
+        case SID_TP_APPLY_TO_ALL_SLIDES:
+            mrBase.SetBusyState (true);
+            AssignMasterPageToAllSlides (GetSelectedMasterPage());
+            mrBase.SetBusyState (false);
+            break;
+
+        case SID_TP_APPLY_TO_SELECTED_SLIDES:
+            mrBase.SetBusyState (true);
+            AssignMasterPageToSelectedSlides (GetSelectedMasterPage());
+            mrBase.SetBusyState (false);
+            break;
+
+        case SID_TP_USE_FOR_NEW_PRESENTATIONS:
+            DBG_ASSERT (false, 
+                "Using slides as default for new presentations"
+                " is not yet implemented");
+            break;
+
+        case SID_TP_SHOW_SMALL_PREVIEW:
+        case SID_TP_SHOW_LARGE_PREVIEW:
+        {
+            mrBase.SetBusyState (true);
+            mpContainer->SetPreviewSize(
+                nCommandId==SID_TP_SHOW_SMALL_PREVIEW
+                ? MasterPageContainer::SMALL
+                : MasterPageContainer::LARGE);
+            mrBase.SetBusyState (false);
+            if (mxSidebar.is())
+                mxSidebar->requestLayout();
+            break;
+        }
+
+        case SID_TP_EDIT_MASTER:
+        {
+            using namespace ::com::sun::star;
+            uno::Reference<drawing::XDrawPage> xSelectedMaster (
+                GetSelectedMasterPage()->getUnoPage(), uno::UNO_QUERY);
+            SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
+            if (pViewFrame != NULL && xSelectedMaster.is())
+            {
+                SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
+                if (pDispatcher != NULL)
+                {
+                    sal_uInt16 nIndex = PreviewValueSet::GetSelectItemId();
+                    pDispatcher->Execute(SID_MASTERPAGE, SFX_CALLMODE_SYNCHRON);
+                    PreviewValueSet::SelectItem (nIndex);
+                    mrBase.GetDrawController().setCurrentPage(xSelectedMaster);
+                }
+            }
+            break;
+        }
+
+        case SID_CUT:
+        case SID_COPY:
+        case SID_PASTE:
+            // Cut, copy, and paste are not supported and thus are ignored.
+            break;
+    }
+}
+
+
+
+
+IMPL_LINK(MasterPagesSelector, ContainerChangeListener, MasterPageContainerChangeEvent*, pEvent)
+{
+    if (pEvent)
+        NotifyContainerChangeEvent(*pEvent);
+    return 0;
+}
+
+
+
+
+SdPage* MasterPagesSelector::GetSelectedMasterPage (void)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    SdPage* pMasterPage = NULL;
+    sal_uInt16 nIndex = PreviewValueSet::GetSelectItemId();
+    UserData* pData = GetUserData(nIndex);
+    if (pData != NULL)
+    {
+        pMasterPage = mpContainer->GetPageObjectForToken(pData->second);
+    }
+    return pMasterPage;
+}
+
+
+
+
+/** Assemble a list of all slides of the document and pass it to
+    AssignMasterPageToPageList().
+*/
+void MasterPagesSelector::AssignMasterPageToAllSlides (SdPage* pMasterPage)
+{
+    do
+    {
+        if (pMasterPage == NULL)
+            break;
+
+        sal_uInt16 nPageCount = mrDocument.GetSdPageCount(PK_STANDARD);
+        if (nPageCount == 0)
+            break;
+
+        // Get a list of all pages.  As a little optimization we only
+        // include pages that do not already have the given master page
+        // assigned.
+        String sFullLayoutName (pMasterPage->GetLayoutName());
+        ::sd::slidesorter::SharedPageSelection pPageList (
+            new ::sd::slidesorter::SlideSorterViewShell::PageSelection());
+        for (sal_uInt16 nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
+        {
+            SdPage* pPage = mrDocument.GetSdPage (nPageIndex, PK_STANDARD);
+            if (pPage != NULL
+                && pPage->GetLayoutName().CompareTo(sFullLayoutName)!=0)
+            {
+                pPageList->push_back (pPage);
+            }
+        }
+
+        AssignMasterPageToPageList(pMasterPage, pPageList);
+    }
+    while (false);
+}
+
+
+
+
+/** Assemble a list of the currently selected slides (selected in a visible
+    slide sorter) and pass it to AssignMasterPageToPageList().
+*/
+void MasterPagesSelector::AssignMasterPageToSelectedSlides (
+    SdPage* pMasterPage)
+{
+    do
+    {
+        using namespace ::std;
+        using namespace ::sd::slidesorter;
+        using namespace ::sd::slidesorter::controller;
+
+        if (pMasterPage == NULL)
+            break;
+
+        // Find a visible slide sorter.
+        SlideSorterViewShell* pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase);
+        if (pSlideSorter == NULL)
+            break;
+
+        // Get a list of selected pages.
+        ::sd::slidesorter::SharedPageSelection pPageSelection = pSlideSorter->GetPageSelection();
+        if (pPageSelection->empty())
+            break;
+
+        AssignMasterPageToPageList(pMasterPage, pPageSelection);
+
+        // Restore the previous selection.
+        pSlideSorter->SetPageSelection(pPageSelection);
+    }
+    while (false);
+}
+
+
+
+
+void MasterPagesSelector::AssignMasterPageToPageList (
+    SdPage* pMasterPage,
+    const ::sd::slidesorter::SharedPageSelection& rPageList)
+{
+    DocumentHelper::AssignMasterPageToPageList(mrDocument, pMasterPage, rPageList);
+}
+
+
+
+
+void MasterPagesSelector::NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    switch (rEvent.meEventType)
+    {
+        case MasterPageContainerChangeEvent::SIZE_CHANGED:
+            PreviewValueSet::SetPreviewSize(mpContainer->GetPreviewSizePixel());
+            UpdateAllPreviews();
+            break;
+
+        case MasterPageContainerChangeEvent::PREVIEW_CHANGED:
+        {
+            int nIndex (GetIndexForToken(rEvent.maChildToken));
+            if (nIndex >= 0)
+            {
+                PreviewValueSet::SetItemImage (
+                    (sal_uInt16)nIndex,
+                    mpContainer->GetPreviewForToken(rEvent.maChildToken));
+                PreviewValueSet::Invalidate(PreviewValueSet::GetItemRect((sal_uInt16)nIndex));
+            }
+        }
+        break;
+
+        case MasterPageContainerChangeEvent::DATA_CHANGED:
+        {
+            InvalidateItem(rEvent.maChildToken);
+            Fill();
+        }
+        break;
+
+		default:
+			break;
+   }
+}
+
+
+
+
+MasterPagesSelector::UserData* MasterPagesSelector::CreateUserData (
+    int nIndex,
+    MasterPageContainer::Token aToken) const
+{
+    return new UserData(nIndex,aToken);
+}
+
+
+
+
+MasterPagesSelector::UserData* MasterPagesSelector::GetUserData (int nIndex) const
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    if (nIndex>0 && nIndex<=PreviewValueSet::GetItemCount())
+        return reinterpret_cast<UserData*>(PreviewValueSet::GetItemData((sal_uInt16)nIndex));
+    else
+        return NULL;
+}
+
+
+
+
+void MasterPagesSelector::SetUserData (int nIndex, UserData* pData)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    if (nIndex>0 && nIndex<=PreviewValueSet::GetItemCount())
+    {
+        UserData* pOldData = GetUserData(nIndex);
+        if (pOldData!=NULL && pOldData!=pData)
+            delete pOldData;
+        PreviewValueSet::SetItemData((sal_uInt16)nIndex, pData);
+    }
+}
+
+
+
+
+bool MasterPagesSelector::IsResizable (void)
+{
+    return false;
+}
+
+
+
+
+::Window* MasterPagesSelector::GetWindow (void)
+{
+    return this;
+}
+
+
+
+
+sal_Int32 MasterPagesSelector::GetMinimumWidth (void)
+{
+    return mpContainer->GetPreviewSizePixel().Width() + 2*3;
+}
+
+
+
+
+void MasterPagesSelector::UpdateSelection (void)
+{
+}
+
+
+
+
+void MasterPagesSelector::SetItem (
+    sal_uInt16 nIndex,
+    MasterPageContainer::Token aToken)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    RemoveTokenToIndexEntry(nIndex,aToken);
+
+    if (nIndex > 0)
+    {
+        if (aToken != MasterPageContainer::NIL_TOKEN)
+        {
+            Image aPreview (mpContainer->GetPreviewForToken(aToken));
+            MasterPageContainer::PreviewState eState (mpContainer->GetPreviewState(aToken));
+
+            if (aPreview.GetSizePixel().Width()>0)
+            {
+                if (PreviewValueSet::GetItemPos(nIndex) != VALUESET_ITEM_NOTFOUND)
+                {
+                    PreviewValueSet::SetItemImage(nIndex,aPreview);
+                    PreviewValueSet::SetItemText(nIndex, mpContainer->GetPageNameForToken(aToken));
+                }
+                else
+                {
+                    PreviewValueSet::InsertItem (
+                        nIndex,
+                        aPreview,
+                        mpContainer->GetPageNameForToken(aToken),
+                        nIndex);
+                }
+                SetUserData(nIndex, CreateUserData(nIndex,aToken));
+
+                AddTokenToIndexEntry(nIndex,aToken);
+            }
+
+            if (eState == MasterPageContainer::PS_CREATABLE)
+                mpContainer->RequestPreview(aToken);
+        }
+        else
+        {
+            PreviewValueSet::RemoveItem(nIndex);
+        }
+    }
+  
+}
+
+
+
+
+void MasterPagesSelector::AddTokenToIndexEntry (
+    sal_uInt16 nIndex,
+    MasterPageContainer::Token aToken)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    maTokenToValueSetIndex[aToken] = nIndex;
+}
+
+
+
+
+void MasterPagesSelector::RemoveTokenToIndexEntry (
+    sal_uInt16 nIndex,
+    MasterPageContainer::Token aNewToken)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    UserData* pData = GetUserData(nIndex);
+    if (pData != NULL)
+    {
+        // Get the token that the index pointed to previously.
+        MasterPageContainer::Token aOldToken (pData->second);
+
+        if (aNewToken != aOldToken
+            && nIndex == GetIndexForToken(aOldToken))
+        {
+            maTokenToValueSetIndex[aOldToken] = 0;
+        }
+    }
+}
+
+
+
+
+void MasterPagesSelector::InvalidatePreview (const SdPage* pPage)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    for (sal_uInt16 nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++)
+    {
+        UserData* pData = GetUserData(nIndex);
+        if (pData != NULL)
+        {
+            MasterPageContainer::Token aToken (pData->second);
+            if (pPage == mpContainer->GetPageObjectForToken(aToken,false))
+            {
+                mpContainer->InvalidatePreview(aToken);
+                mpContainer->RequestPreview(aToken);
+                break;
+            }
+        }
+    }
+}
+
+void MasterPagesSelector::UpdateAllPreviews (void)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+    
+    for (sal_uInt16 nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++)
+    {
+        UserData* pData = GetUserData(nIndex);
+        if (pData != NULL)
+        {
+            MasterPageContainer::Token aToken (pData->second);
+            PreviewValueSet::SetItemImage(
+                nIndex,
+                mpContainer->GetPreviewForToken(aToken));
+            if (mpContainer->GetPreviewState(aToken) == MasterPageContainer::PS_CREATABLE)
+                mpContainer->RequestPreview(aToken);
+        }
+    }
+    PreviewValueSet::Rearrange(true);
+}
+
+
+
+
+void MasterPagesSelector::ClearPageSet (void)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    for (sal_uInt16 nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++)
+    {
+        UserData* pData = GetUserData(nIndex);
+        if (pData != NULL)
+            delete pData;
+    }
+    PreviewValueSet::Clear();
+}
+
+
+
+
+void MasterPagesSelector::SetHelpId( const rtl::OString& aId )
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+	PreviewValueSet::SetHelpId( aId );
+}
+
+
+
+
+sal_Int32 MasterPagesSelector::GetIndexForToken (MasterPageContainer::Token aToken) const
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    TokenToValueSetIndex::const_iterator iIndex (maTokenToValueSetIndex.find(aToken));
+    if (iIndex != maTokenToValueSetIndex.end())
+        return iIndex->second;
+    else
+        return -1;
+}
+
+
+
+
+void MasterPagesSelector::Clear (void)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    ClearPageSet();
+}
+
+
+
+
+void MasterPagesSelector::InvalidateItem (MasterPageContainer::Token aToken)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    ItemList::iterator iItem;
+    for (iItem=maCurrentItemList.begin(); iItem!=maCurrentItemList.end(); ++iItem)
+    {
+        if (*iItem == aToken)
+        {
+            *iItem = MasterPageContainer::NIL_TOKEN;
+            break;
+        }
+    }
+}
+
+
+
+
+void MasterPagesSelector::UpdateItemList (::std::auto_ptr<ItemList> pNewItemList)
+{
+    const ::osl::MutexGuard aGuard (maMutex);
+
+    ItemList::const_iterator iNewItem (pNewItemList->begin());
+    ItemList::const_iterator iCurrentItem (maCurrentItemList.begin());
+    ItemList::const_iterator iNewEnd (pNewItemList->end());
+    ItemList::const_iterator iCurrentEnd (maCurrentItemList.end());
+    sal_uInt16 nIndex (1);
+
+    // Update existing items.
+    for ( ; iNewItem!=iNewEnd && iCurrentItem!=iCurrentEnd; ++iNewItem, ++iCurrentItem,++nIndex)
+    {
+        if (*iNewItem != *iCurrentItem)
+        {
+            SetItem(nIndex,*iNewItem);
+        }
+    }
+    
+    // Append new items.
+    for ( ; iNewItem!=iNewEnd; ++iNewItem,++nIndex)
+    {
+        SetItem(nIndex,*iNewItem);
+    }
+    
+    // Remove trailing items.
+    for ( ; iCurrentItem!=iCurrentEnd; ++iCurrentItem,++nIndex)
+    {
+        SetItem(nIndex,MasterPageContainer::NIL_TOKEN);
+    }
+
+    maCurrentItemList.swap(*pNewItemList);
+    
+    PreviewValueSet::Rearrange();
+    if (mxSidebar.is())
+        mxSidebar->requestLayout();
+}
+
+
+
+
+css::ui::LayoutSize MasterPagesSelector::GetHeightForWidth (const sal_Int32 nWidth)
+{
+    const sal_Int32 nHeight (GetPreferredHeight(nWidth));
+    return css::ui::LayoutSize(nHeight,nHeight,nHeight);
+}
+
+} } // end of namespace sd::sidebar

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPagesSelector.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPagesSelector.hxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPagesSelector.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/MasterPagesSelector.hxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,242 @@
+/**************************************************************
+ * 
+ * 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_PAGES_SELECTOR_HXX
+#define SD_SIDEBAR_PANELS_MASTER_PAGES_SELECTOR_HXX
+
+#include "MasterPageContainer.hxx"
+#include "SlideSorterViewShell.hxx"
+#include "PreviewValueSet.hxx"
+#include "ISidebarReceiver.hxx"
+#include <sfx2/sidebar/ILayoutableWindow.hxx>
+
+#include "pres.hxx"
+#include <sfx2/shell.hxx>
+#include <vcl/image.hxx>
+#include "glob.hxx"
+#include <osl/mutex.hxx>
+#include <com/sun/star/ui/XSidebar.hpp>
+
+#include <queue>
+
+namespace css = ::com::sun::star;
+namespace cssu = ::com::sun::star::uno;
+
+class MouseEvent;
+class SdDrawDocument;
+class SdPage;
+class SfxModule;
+
+namespace sd { 
+class DrawViewShell;
+class TemplateEntry;
+class TemplateDir;
+class ViewShellBase;
+}
+
+namespace sd { namespace sidebar {
+
+class PreviewValueSet;
+class SidebarShellManager;
+
+
+/** Base class of a menu that lets the user select from a list of
+    templates or designs that are loaded from files.
+*/
+class MasterPagesSelector
+    : public PreviewValueSet,
+      public sfx2::sidebar::ILayoutableWindow
+{
+public:
+    MasterPagesSelector (
+        ::Window* pParent,
+        SdDrawDocument& rDocument,
+        ViewShellBase& rBase,
+        const ::boost::shared_ptr<MasterPageContainer>& rpContainer,
+        const cssu::Reference<css::ui::XSidebar>& rxSidebar);
+    virtual ~MasterPagesSelector (void);
+
+    virtual void LateInit (void);
+
+    /** Return the height that this control needs to show all of its lines.
+    */
+    long GetRequiredHeight (int nWidth) const;
+
+    /** The given master page, either the master page of a slide or a notes
+        page, is cloned and inserted into mrDocument.  The necessary styles
+        are copied as well.
+    */
+    static SdPage* AddMasterPage (
+        SdDrawDocument* pTargetDocument,
+        SdPage* pMasterPage,
+        sal_uInt16 nInsertionIndex);
+
+    virtual Size GetPreferredSize (void);
+    virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeight);
+    virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+    virtual bool IsResizable (void);
+    virtual ::Window* GetWindow (void);
+    virtual sal_Int32 GetMinimumWidth (void);
+
+    /** Update the selection of previews according to whatever
+        influences them appart from mouse and keyboard.  If, for
+        example, the current page of the main pane changes, then call
+        this method at the CurrentMasterPagesSelector to select the
+        previews of the master pages that are assigned to the new
+        current page.
+
+        The default implementation of this method ignores the call. This is
+        used by e.g. the RecentMasterPagesSelector because it does not show
+        the currently used master pages by default and thus is not
+        influenced by its changes.
+    */
+    virtual void UpdateSelection (void);
+
+    void FillPageSet (void);
+
+    /** Make the selector empty.  This method clear the value set from any
+        entries. Overload this method to add functionality, especially to
+        destroy objects set as data items at the value set.
+    */
+    void ClearPageSet (void);
+
+	void SetHelpId( const rtl::OString& aId );
+
+    /** Mark the preview that belongs to the given index as not up-to-date
+        anymore with respect to page content or preview size.
+        The implementation of this method will either sunchronously or
+        asynchronously call UpdatePreview().
+        @param nIndex
+            Index into the value set control that is used for displaying the
+            previews.
+    */
+    void InvalidatePreview (const SdPage* pPage);
+
+    void UpdateAllPreviews (void);
+
+    // ILayoutableWindow
+    virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth);
+
+protected:
+    mutable ::osl::Mutex maMutex;
+    ::boost::shared_ptr<MasterPageContainer> mpContainer;
+
+    SdDrawDocument& mrDocument;
+    bool mbSmallPreviewSize;
+    ViewShellBase& mrBase;
+    /** Slot that is executed as default action when the left mouse button is
+        clicked over a master page.
+    */
+	sal_uInt16 mnDefaultClickAction;
+    /** Pages with pointers in this queue have their previews updated
+        eventually.  Filled by InvalidatePreview() and operated upon by
+        UpdatePreviews(). 
+    */
+    ::std::queue<sal_uInt16> maPreviewUpdateQueue;
+
+    virtual SdPage* GetSelectedMasterPage (void);
+
+    /** Assign the given master page to all slides of the document.
+        @param pMasterPage
+            The master page to assign to all slides.
+    */
+    void AssignMasterPageToAllSlides (SdPage* pMasterPage);
+
+    /** Assign the given master page to all slides that are selected in a
+        slide sorter that is displayed in the lef or center pane.  When both
+        panes display a slide sorter then the one in the center pane is
+        used.
+    */
+    void AssignMasterPageToSelectedSlides (SdPage* pMasterPage);
+
+    virtual void AssignMasterPageToPageList (
+        SdPage* pMasterPage,
+        const ::sd::slidesorter::SharedPageSelection& rPageList);
+
+    virtual void NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent);
+
+    typedef ::std::pair<int, MasterPageContainer::Token> UserData;
+    UserData* CreateUserData (int nIndex, MasterPageContainer::Token aToken) const;
+    UserData* GetUserData (int nIndex) const;
+    void SetUserData (int nIndex, UserData* pData);
+
+    virtual sal_Int32 GetIndexForToken (MasterPageContainer::Token aToken) const;
+    typedef ::std::vector<MasterPageContainer::Token> ItemList;
+    void UpdateItemList (::std::auto_ptr<ItemList> pList);
+    void Clear (void);
+    /** Invalidate the specified item so that on the next Fill() this item
+        is updated.
+    */
+    void InvalidateItem (MasterPageContainer::Token aToken);
+
+    // For every item in the ValueSet we store its associated token.  This
+    // allows a faster access and easier change tracking.
+    ItemList maCurrentItemList;
+    typedef ::std::map<MasterPageContainer::Token,sal_Int32> TokenToValueSetIndex;
+    TokenToValueSetIndex maTokenToValueSetIndex;
+
+    ItemList maLockedMasterPages;
+    /** Lock master pages in the given list and release locks that where
+        previously aquired.
+    */
+    void UpdateLocks (const ItemList& rItemList);
+
+    void Fill (void);
+    virtual void Fill (ItemList& rItemList) = 0;
+
+    /** Give derived classes the oportunity to provide their own context
+        menu.  If they do then they probably have to provide their own
+        Execute() and GetState() methods as well.
+    */
+    virtual ResId GetContextMenuResId (void) const;
+
+    virtual void Command (const CommandEvent& rEvent);
+
+    virtual void ProcessPopupMenu (Menu& rMenu);
+    virtual void ExecuteCommand (const sal_Int32 nCommandId);
+
+private:
+    cssu::Reference<css::ui::XSidebar> mxSidebar;
+
+    /** The offset between ValueSet index and MasterPageContainer::Token
+        last seen.  This value is used heuristically to speed up the lookup
+        of an index for a token.
+    */
+    DECL_LINK(ClickHandler, PreviewValueSet*);
+    DECL_LINK(RightClickHandler, MouseEvent*);
+    DECL_LINK(ContextMenuCallback, CommandEvent*);
+    DECL_LINK(ContainerChangeListener, MasterPageContainerChangeEvent*);
+    DECL_LINK(OnMenuItemSelected, Menu*);
+    
+    void SetItem (
+        sal_uInt16 nIndex,
+        MasterPageContainer::Token aToken);
+    void AddTokenToIndexEntry (
+        sal_uInt16 nIndex,
+        MasterPageContainer::Token aToken);
+    void RemoveTokenToIndexEntry (
+        sal_uInt16 nIndex,
+        MasterPageContainer::Token aToken);
+};
+
+} } // end of namespace sd::sidebar
+
+#endif

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/PanelBase.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/PanelBase.cxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/PanelBase.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/PanelBase.cxx 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.
+ * 
+ *************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include "TableDesignPanel.hxx"
+
+
+
+namespace sd { namespace sidebar {
+
+
+PanelBase::PanelBase (
+    ::Window* pParentWindow,
+    ViewShellBase& rViewShellBase)
+    : Control(pParentWindow),
+      mpWrappedControl(NULL),
+      mxSidebar(),
+      mrViewShellBase(rViewShellBase)
+{
+    OSL_TRACE("created PanelBase at %x for parent %x", this, pParentWindow);
+
+#ifdef DEBUG
+    SetText(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sd:PanelBase")));
+#endif
+}
+
+
+
+
+PanelBase::~PanelBase (void)
+{
+    OSL_TRACE("deleting wrapped control at %x", mpWrappedControl.get());
+    mpWrappedControl.reset();
+    OSL_TRACE("deleting PanelBase at %x from parent %x", this, GetParent());
+}
+
+
+
+
+
+void PanelBase::Dispose (void)
+{
+    OSL_TRACE("PanelBase::DisposeL: deleting wrapped control at %x", mpWrappedControl.get());
+    mpWrappedControl.reset();
+}
+
+
+
+
+css::ui::LayoutSize PanelBase::GetHeightForWidth (const sal_Int32 nWidth)
+{
+    sal_Int32 nHeight (0);
+    if (ProvideWrappedControl())
+        nHeight = mpWrappedControl->GetSizePixel().Height();
+    return css::ui::LayoutSize(nHeight,nHeight,nHeight);
+}
+
+
+
+
+void PanelBase::Resize (void)
+{
+    if (ProvideWrappedControl())
+    {
+        Size aNewSize (GetSizePixel());
+        mpWrappedControl->SetOutputSizePixel(aNewSize);
+    }
+}
+
+
+
+
+::com::sun::star::uno::Reference<
+    ::com::sun::star::accessibility::XAccessible> PanelBase::CreateAccessibleObject (
+        const ::com::sun::star::uno::Reference<
+        ::com::sun::star::accessibility::XAccessible>& )
+{
+    if (ProvideWrappedControl())
+        return mpWrappedControl->GetAccessible();
+    else
+        return NULL;
+}
+
+
+
+
+void PanelBase::SetSidebar (const cssu::Reference<css::ui::XSidebar>& rxSidebar)
+{
+    mxSidebar = rxSidebar;
+    if (mxSidebar.is() && mpWrappedControl!=NULL)
+        mxSidebar->requestLayout();
+}
+
+
+
+
+bool PanelBase::ProvideWrappedControl (void)
+{
+    if ( ! mpWrappedControl)
+    {
+        mpWrappedControl.reset(CreateWrappedControl(this, mrViewShellBase));
+        OSL_TRACE("created wrapped control at %x for parent PanelBase at %x", mpWrappedControl.get(), this);
+        if (mpWrappedControl)
+            mpWrappedControl->Show();
+        if (mxSidebar.is())
+            mxSidebar->requestLayout();
+    }
+    return mpWrappedControl.get() != NULL;
+}
+
+} } // end of namespace sd::sidebar

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/PanelBase.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/PanelBase.hxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/PanelBase.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/PanelBase.hxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,90 @@
+/**************************************************************
+ * 
+ * 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_PANEL_BASE_HXX
+#define SD_SIDEBAR_PANELS_PANEL_BASE_HXX
+
+#include "IDisposable.hxx"
+#include "ISidebarReceiver.hxx"
+#include <sfx2/sidebar/ILayoutableWindow.hxx>
+
+#include <vcl/ctrl.hxx>
+
+#include <boost/scoped_ptr.hpp>
+
+
+namespace css = ::com::sun::star;
+namespace cssu = ::com::sun::star::uno;
+
+namespace sd {
+    class ViewShellBase;
+}
+
+
+
+
+namespace sd { namespace sidebar {
+
+
+class PanelBase
+    : public Control,
+      public sfx2::sidebar::ILayoutableWindow,
+      public IDisposable,
+      public ISidebarReceiver
+{
+public:
+    PanelBase (
+        ::Window* pParentWindow,
+        ViewShellBase& rViewShellBase);
+    virtual ~PanelBase (void);
+
+    virtual void Resize (void);
+
+    // IDisposable
+    virtual void Dispose (void);
+    
+    // ILayoutableWindow
+    virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth);
+
+    // ISidebarReceiver
+    virtual void SetSidebar (const cssu::Reference<css::ui::XSidebar>& rxSidebar);
+
+    virtual ::com::sun::star::uno::Reference<
+        ::com::sun::star::accessibility::XAccessible > CreateAccessibleObject (
+            const ::com::sun::star::uno::Reference<
+            ::com::sun::star::accessibility::XAccessible>& rxParent);
+
+protected:
+    ::boost::scoped_ptr< ::Window> mpWrappedControl;
+    virtual ::Window* CreateWrappedControl (
+        ::Window* pParentWindow,
+        ViewShellBase& rViewShellBase) = 0;
+
+private:
+    cssu::Reference<css::ui::XSidebar> mxSidebar;
+    ViewShellBase& mrViewShellBase;
+
+    bool ProvideWrappedControl (void);
+};
+
+} } // end of namespace sd::sidebar
+
+#endif

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/PreviewValueSet.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/PreviewValueSet.cxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/PreviewValueSet.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/PreviewValueSet.cxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,205 @@
+/**************************************************************
+ * 
+ * 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 "PreviewValueSet.hxx"
+#include <vcl/image.hxx>
+
+namespace sd { namespace sidebar {
+
+
+PreviewValueSet::PreviewValueSet (::Window* pParent)
+    : ValueSet (pParent, WB_TABSTOP),
+      maPreviewSize(10,10),
+      mnBorderWidth(3),
+      mnBorderHeight(3),
+      mnMaxColumnCount(-1)
+{
+	SetStyle (
+        GetStyle() 
+        & ~(WB_ITEMBORDER)// | WB_MENUSTYLEVALUESET)
+        //        | WB_FLATVALUESET);
+        );
+
+	SetColCount(2);
+    //	SetLineCount(1);
+	SetExtraSpacing (2);
+}
+
+
+
+
+PreviewValueSet::~PreviewValueSet (void)
+{
+}
+
+
+
+
+void PreviewValueSet::SetPreviewSize (const Size& rSize)
+{
+    maPreviewSize = rSize;
+}
+
+
+
+
+void PreviewValueSet::SetRightMouseClickHandler (const Link& rLink)
+{
+    maRightMouseClickHandler = rLink;
+}
+
+
+
+
+void PreviewValueSet::MouseButtonDown (const MouseEvent& rEvent)
+{
+    if (rEvent.IsRight())
+        maRightMouseClickHandler.Call(reinterpret_cast<void*>(
+            &const_cast<MouseEvent&>(rEvent)));
+    else
+        ValueSet::MouseButtonDown (rEvent);
+
+}
+
+
+
+
+void PreviewValueSet::Paint (const Rectangle& rRect)
+{
+    SetBackground (GetSettings().GetStyleSettings().GetWindowColor());
+
+    ValueSet::Paint (rRect);
+
+    SetBackground (Wallpaper());
+}
+
+
+
+
+void PreviewValueSet::Resize (void)
+{
+    ValueSet::Resize ();
+
+    Size aWindowSize (GetOutputSizePixel());
+    if (aWindowSize.Width()>0 && aWindowSize.Height()>0)
+    {
+        Rearrange();
+    }
+}
+
+
+
+
+void PreviewValueSet::Rearrange (bool bForceRequestResize)
+{
+    sal_uInt16 nOldColumnCount (GetColCount());
+    sal_uInt16 nOldRowCount (GetLineCount());
+
+    sal_uInt16 nNewColumnCount (CalculateColumnCount (
+        GetOutputSizePixel().Width()));
+    sal_uInt16 nNewRowCount (CalculateRowCount (nNewColumnCount));
+
+    SetColCount(nNewColumnCount);
+    SetLineCount(nNewRowCount);
+
+    if (bForceRequestResize
+        || nOldColumnCount != nNewColumnCount
+        || nOldRowCount != nNewRowCount)
+    {
+        //SIDEBAR:TODO:   mpParent->RequestResize();
+    }
+}
+
+
+
+
+sal_uInt16 PreviewValueSet::CalculateColumnCount (int nWidth) const
+{
+    int nColumnCount = 0;
+    if (nWidth > 0)
+    {
+        nColumnCount = nWidth / (maPreviewSize.Width() + 2*mnBorderWidth);
+        if (nColumnCount < 1)
+            nColumnCount = 1;
+        else if (mnMaxColumnCount>0 && nColumnCount>mnMaxColumnCount)
+            nColumnCount = mnMaxColumnCount;
+    }
+    return (sal_uInt16)nColumnCount;
+}
+
+
+
+
+sal_uInt16 PreviewValueSet::CalculateRowCount (sal_uInt16 nColumnCount) const
+{
+    int nRowCount = 0;
+    int nItemCount = GetItemCount();
+    if (nColumnCount > 0)
+    {
+        nRowCount = (nItemCount+nColumnCount-1) / nColumnCount;
+        if (nRowCount < 1)
+            nRowCount = 1;
+    }
+
+    return (sal_uInt16)nRowCount;
+}
+
+
+
+
+sal_Int32 PreviewValueSet::GetPreferredWidth (sal_Int32 nHeight)
+{
+    int nPreferredWidth (maPreviewSize.Width() + 2*mnBorderWidth);
+
+    // Get height of each row.
+    int nItemHeight (maPreviewSize.Height() + 2*mnBorderHeight);
+
+    // Calculate the row- and column count and from the later the preferred
+    // width.
+    int nRowCount = nHeight / nItemHeight;
+    if (nRowCount > 0)
+    {
+        int nColumnCount = (GetItemCount()+nRowCount-1) / nRowCount;
+        if (nColumnCount > 0)
+            nPreferredWidth = (maPreviewSize.Width() + 2*mnBorderWidth) 
+                * nColumnCount;
+    }
+
+    return nPreferredWidth;
+}
+
+
+
+
+sal_Int32 PreviewValueSet::GetPreferredHeight (sal_Int32 nWidth)
+{
+    int nRowCount (CalculateRowCount(CalculateColumnCount(nWidth)));
+    int nItemHeight (maPreviewSize.Height());
+    
+    return nRowCount * (nItemHeight + 2*mnBorderHeight);
+}
+
+
+
+
+} } // end of namespace sd::sidebar

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/PreviewValueSet.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/PreviewValueSet.hxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/PreviewValueSet.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/PreviewValueSet.hxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,70 @@
+/**************************************************************
+ * 
+ * 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_PREVIEW_VALUE_SET_HXX
+#define SD_SIDEBAR_PANELS_PREVIEW_VALUE_SET_HXX
+
+#include <svtools/valueset.hxx>
+
+
+namespace sd { namespace sidebar {
+
+
+/** Adapt the svtools valueset to the needs of the master page controlls.
+*/
+class PreviewValueSet
+    : public ValueSet
+{
+public:
+    PreviewValueSet (::Window* pParent);
+    ~PreviewValueSet (void);
+
+	void SetRightMouseClickHandler (const Link& rLink);
+	virtual void Paint (const Rectangle& rRect);
+    virtual void Resize (void);
+    
+    void SetPreviewSize (const Size& rSize);
+
+    sal_Int32 GetPreferredWidth (sal_Int32 nHeight);
+    sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+
+    /** Set the number of rows and columns according to the current number
+        of items.  Call this method when new items have been inserted.
+    */
+    void Rearrange (bool bForceRequestResize = false);
+
+protected:
+    virtual void MouseButtonDown (const MouseEvent& rEvent);
+
+private:
+    Link maRightMouseClickHandler;
+    Size maPreviewSize;
+    const int mnBorderWidth;
+    const int mnBorderHeight;
+    const int mnMaxColumnCount;
+    
+    sal_uInt16 CalculateColumnCount (int nWidth) const;
+    sal_uInt16 CalculateRowCount (sal_uInt16 nColumnCount) const;
+};
+
+} } // end of namespace sd::sidebar
+
+#endif

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,181 @@
+/**************************************************************
+ * 
+ * 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 "RecentMasterPagesSelector.hxx"
+
+#include "ViewShellBase.hxx"
+#include "RecentlyUsedMasterPages.hxx"
+#include "MasterPageContainerProviders.hxx"
+#include "MasterPageObserver.hxx"
+#include "SidebarShellManager.hxx"
+#include "sdpage.hxx"
+#include "drawdoc.hxx"
+#include "app.hrc"
+#include "helpids.h"
+
+#include <vcl/bitmap.hxx>
+#include <tools/color.hxx>
+
+namespace sd { namespace sidebar {
+
+
+MasterPagesSelector* RecentMasterPagesSelector::Create (
+    ::Window* pParent,
+    ViewShellBase& rViewShellBase,
+    const cssu::Reference<css::ui::XSidebar>& rxSidebar)
+{
+    SdDrawDocument* pDocument = rViewShellBase.GetDocument();
+    if (pDocument == NULL)
+        return NULL;
+
+    ::boost::shared_ptr<MasterPageContainer> pContainer (new MasterPageContainer());
+    
+    MasterPagesSelector* pSelector(
+        new RecentMasterPagesSelector (
+            pParent, 
+            *pDocument,
+            rViewShellBase,
+            pContainer,
+            rxSidebar));
+    pSelector->LateInit();
+    pSelector->SetHelpId(HID_SD_TASK_PANE_PREVIEW_RECENT);
+
+    return pSelector;
+}
+
+
+
+
+RecentMasterPagesSelector::RecentMasterPagesSelector (
+    ::Window* pParent,
+    SdDrawDocument& rDocument,
+    ViewShellBase& rBase,
+    const ::boost::shared_ptr<MasterPageContainer>& rpContainer,
+    const cssu::Reference<css::ui::XSidebar>& rxSidebar)
+    : MasterPagesSelector (pParent, rDocument, rBase, rpContainer, rxSidebar)
+{
+}
+
+
+
+
+RecentMasterPagesSelector::~RecentMasterPagesSelector (void)
+{
+    RecentlyUsedMasterPages::Instance().RemoveEventListener (
+        LINK(this,RecentMasterPagesSelector,MasterPageListListener));
+}
+
+
+
+
+void RecentMasterPagesSelector::LateInit (void)
+{
+    MasterPagesSelector::LateInit();
+
+    MasterPagesSelector::Fill();
+    RecentlyUsedMasterPages::Instance().AddEventListener (
+        LINK(this,RecentMasterPagesSelector,MasterPageListListener));
+}
+
+
+
+
+IMPL_LINK(RecentMasterPagesSelector,MasterPageListListener, void*, EMPTYARG)
+{
+    MasterPagesSelector::Fill();
+    return 0;
+}
+
+
+
+
+void RecentMasterPagesSelector::Fill (ItemList& rItemList)
+{
+    // Create a set of names of the master pages used by the document.
+    MasterPageObserver::MasterPageNameSet aCurrentNames;
+    sal_uInt16 nMasterPageCount = mrDocument.GetMasterSdPageCount(PK_STANDARD);
+    sal_uInt16 nIndex;
+    for (nIndex=0; nIndex<nMasterPageCount; nIndex++)
+    {
+        SdPage* pMasterPage = mrDocument.GetMasterSdPage (nIndex, PK_STANDARD);
+        if (pMasterPage != NULL)
+            aCurrentNames.insert (pMasterPage->GetName());
+    }
+    MasterPageObserver::MasterPageNameSet::iterator aI;
+
+    // Insert the recently used master pages that are currently not used.
+    RecentlyUsedMasterPages& rInstance (RecentlyUsedMasterPages::Instance());
+    int nPageCount = rInstance.GetMasterPageCount();
+    for (nIndex=0; nIndex<nPageCount; nIndex++)
+    {
+        // Add an entry when a) the page is already known to the
+        // MasterPageContainer, b) the style name is empty, i.e. it has not yet
+        // been loaded (and thus can not be in use) or otherwise c) the
+        // style name is not currently in use.
+        MasterPageContainer::Token aToken (rInstance.GetTokenForIndex(nIndex));
+        if (aToken != MasterPageContainer::NIL_TOKEN)
+        {
+            String sStyleName (mpContainer->GetStyleNameForToken(aToken));
+            if (sStyleName.Len()==0 
+                || aCurrentNames.find(sStyleName) == aCurrentNames.end())
+            {
+                rItemList.push_back(aToken);
+            }
+        }
+    }
+}
+
+
+
+
+void RecentMasterPagesSelector::AssignMasterPageToPageList (
+    SdPage* pMasterPage,
+    const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList)
+{
+	sal_uInt16 nSelectedItemId = PreviewValueSet::GetSelectItemId();
+    
+    MasterPagesSelector::AssignMasterPageToPageList(pMasterPage, rpPageList);
+
+    // Restore the selection.
+    if (PreviewValueSet::GetItemCount() > 0)
+    {
+        if (PreviewValueSet::GetItemCount() >= nSelectedItemId)
+            PreviewValueSet::SelectItem(nSelectedItemId);
+        else
+            PreviewValueSet::SelectItem(PreviewValueSet::GetItemCount());
+    }
+}
+
+
+
+
+void RecentMasterPagesSelector::ProcessPopupMenu (Menu& rMenu)
+{
+    if (rMenu.GetItemPos(SID_TP_EDIT_MASTER) != MENU_ITEM_NOTFOUND)
+        rMenu.EnableItem(SID_TP_EDIT_MASTER, sal_False);
+}
+
+
+
+
+} } // end of namespace sd::sidebar

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,79 @@
+/**************************************************************
+ * 
+ * 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_RECENT_MASTER_PAGES_SELECTOR_HXX
+#define SD_SIDEBAR_PANELS_RECENT_MASTER_PAGES_SELECTOR_HXX
+
+#include "MasterPagesSelector.hxx"
+
+namespace sd { namespace sidebar {
+
+
+/** Show the recently used master pages (that are not currently used).
+*/
+class RecentMasterPagesSelector
+    : public MasterPagesSelector
+{
+public:
+    static MasterPagesSelector* Create (
+        ::Window* pParent,
+        ViewShellBase& rViewShellBase,
+        const cssu::Reference<css::ui::XSidebar>& rxSidebar);
+
+protected:
+    DECL_LINK(MasterPageListListener, void*);
+    virtual void Fill (ItemList& rItemList);
+
+	using sd::sidebar::MasterPagesSelector::Fill;
+
+    /** Forward this call to the base class but save and restore the
+        currently selected item.
+        Assign the given master page to the list of pages.
+        @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.
+    */
+    virtual void AssignMasterPageToPageList (
+        SdPage* pMasterPage,
+        const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList);
+
+    virtual void ProcessPopupMenu (Menu& rMenu);
+
+private:
+    RecentMasterPagesSelector (
+        ::Window* pParent, 
+        SdDrawDocument& rDocument,
+        ViewShellBase& rBase,
+        const ::boost::shared_ptr<MasterPageContainer>& rpContainer,
+        const cssu::Reference<css::ui::XSidebar>& rxSidebar);
+    virtual ~RecentMasterPagesSelector (void);
+
+    virtual void LateInit (void);
+};
+
+} } // end of namespace sd::sidebar
+
+#endif

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentlyUsedMasterPages.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentlyUsedMasterPages.cxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentlyUsedMasterPages.cxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentlyUsedMasterPages.cxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,494 @@
+/**************************************************************
+ * 
+ * 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 "RecentlyUsedMasterPages.hxx"
+#include "MasterPageObserver.hxx"
+#include "MasterPagesSelector.hxx"
+#include "MasterPageDescriptor.hxx"
+#include "tools/ConfigurationAccess.hxx"
+#include "drawdoc.hxx"
+#include "sdpage.hxx"
+
+#include <algorithm>
+#include <vector>
+
+#include <comphelper/processfactory.hxx>
+#include "unomodel.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/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <tools/urlobj.hxx>
+#include <unotools/confignode.hxx>
+#include <osl/doublecheckedlocking.h>
+#include <osl/getglobalmutex.hxx>
+
+using namespace ::std;
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+
+namespace {
+
+static const OUString& GetPathToImpressConfigurationRoot (void)
+{
+    static const OUString sPathToImpressConfigurationRoot (
+        RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Impress/"));
+    return sPathToImpressConfigurationRoot;
+}
+static const OUString& GetPathToSetNode (void)
+{
+    static const OUString sPathToSetNode(
+        RTL_CONSTASCII_USTRINGPARAM(
+            "MultiPaneGUI/ToolPanel/RecentlyUsedMasterPages"));
+    return sPathToSetNode;
+}
+
+
+class Descriptor
+{
+public:
+    ::rtl::OUString msURL;
+    ::rtl::OUString msName;
+    ::sd::sidebar::MasterPageContainer::Token maToken;
+    Descriptor (const ::rtl::OUString& rsURL, const ::rtl::OUString& rsName)
+        : msURL(rsURL),
+          msName(rsName),
+          maToken(::sd::sidebar::MasterPageContainer::NIL_TOKEN)
+    {}
+    Descriptor (::sd::sidebar::MasterPageContainer::Token aToken,
+        const ::rtl::OUString& rsURL, const ::rtl::OUString& rsName)
+        : msURL(rsURL),
+          msName(rsName),
+          maToken(aToken)
+    {}
+    class TokenComparator
+    { public:
+        TokenComparator(::sd::sidebar::MasterPageContainer::Token aToken)
+            : maToken(aToken) {}
+        bool operator () (const Descriptor& rDescriptor)
+        { return maToken==rDescriptor.maToken; }
+    private: ::sd::sidebar::MasterPageContainer::Token maToken;
+    };
+};
+
+} // end of anonymous namespace
+
+
+
+
+namespace sd { namespace sidebar {
+
+class RecentlyUsedMasterPages::MasterPageList : public ::std::vector<Descriptor>
+{
+public:
+    MasterPageList (void) {}
+};
+
+
+RecentlyUsedMasterPages* RecentlyUsedMasterPages::mpInstance = NULL;
+
+
+RecentlyUsedMasterPages&  RecentlyUsedMasterPages::Instance (void)
+{
+    if (mpInstance == NULL)
+    {
+        ::osl::GetGlobalMutex aMutexFunctor;
+        ::osl::MutexGuard aGuard (aMutexFunctor());
+        if (mpInstance == NULL)
+        {
+            RecentlyUsedMasterPages* pInstance = new RecentlyUsedMasterPages();
+            pInstance->LateInit();
+            SdGlobalResourceContainer::Instance().AddResource (
+                ::std::auto_ptr<SdGlobalResource>(pInstance));
+            OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+            mpInstance = pInstance;
+        }
+    }
+    else {
+        OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+    }
+    
+    return *mpInstance;
+}
+
+
+
+
+RecentlyUsedMasterPages::RecentlyUsedMasterPages (void)
+    : maListeners(),
+      mpMasterPages(new MasterPageList()),
+      mnMaxListSize(8),
+      mpContainer(new MasterPageContainer())
+{
+}
+
+
+
+
+RecentlyUsedMasterPages::~RecentlyUsedMasterPages (void)
+{
+    Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener));
+    mpContainer->RemoveChangeListener(aLink);
+    
+    MasterPageObserver::Instance().RemoveEventListener(
+        LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener));
+}
+
+
+
+
+void RecentlyUsedMasterPages::LateInit (void)
+{
+    Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener));
+    mpContainer->AddChangeListener(aLink);
+    
+    LoadPersistentValues ();
+    MasterPageObserver::Instance().AddEventListener(
+        LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener));
+}
+
+
+
+
+void RecentlyUsedMasterPages::LoadPersistentValues (void)
+{
+    try
+    {
+        do
+        {
+            tools::ConfigurationAccess aConfiguration (
+                GetPathToImpressConfigurationRoot(),
+                tools::ConfigurationAccess::READ_ONLY);
+            Reference<container::XNameAccess> xSet (
+                aConfiguration.GetConfigurationNode(GetPathToSetNode()),
+                UNO_QUERY);
+            if ( ! xSet.is())
+                break;
+
+            const String sURLMemberName (OUString::createFromAscii("URL"));
+            const String sNameMemberName (OUString::createFromAscii("Name"));
+            OUString sURL;
+            OUString sName;
+
+            // Read the names and URLs of the master pages.
+            Sequence<OUString> aKeys (xSet->getElementNames());
+            mpMasterPages->clear();
+            mpMasterPages->reserve(aKeys.getLength());
+            for (int i=0; i<aKeys.getLength(); i++)
+            {
+                Reference<container::XNameAccess> xSetItem (
+                    xSet->getByName(aKeys[i]), UNO_QUERY);
+                if (xSetItem.is())
+                {
+                    Any aURL (xSetItem->getByName(sURLMemberName));
+                    Any aName (xSetItem->getByName(sNameMemberName));
+                    aURL >>= sURL;
+                    aName >>= sName;
+                    SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
+                        MasterPageContainer::TEMPLATE,
+                        -1,
+                        sURL,
+                        String(),
+                        sName,
+                        false,
+                        ::boost::shared_ptr<PageObjectProvider>(
+                            new TemplatePageObjectProvider(sURL)),
+                        ::boost::shared_ptr<PreviewProvider>(
+                            new TemplatePreviewProvider(sURL))));
+                    // For user supplied templates we use a different
+                    // preview provider: The preview in the document shows
+                    // not only shapes on the master page but also shapes on
+                    // the foreground.  This is misleading and therefore
+                    // these previews are discarded and created directly
+                    // from the page objects.
+                    if (pDescriptor->GetURLClassification() == MasterPageDescriptor::URLCLASS_USER)
+                        pDescriptor->mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(
+                            new PagePreviewProvider());
+                    MasterPageContainer::Token aToken (mpContainer->PutMasterPage(pDescriptor));
+                    mpMasterPages->push_back(Descriptor(aToken,sURL,sName));
+                }
+            }
+
+            ResolveList();
+        }
+        while (false);
+    }
+    catch (Exception&)
+    {
+        // Ignore exception.
+    }
+}
+
+
+
+
+void RecentlyUsedMasterPages::SavePersistentValues (void)
+{
+    try
+    {
+        do
+        {
+            tools::ConfigurationAccess aConfiguration (
+                GetPathToImpressConfigurationRoot(),
+                tools::ConfigurationAccess::READ_WRITE);
+            Reference<container::XNameContainer> xSet (
+                aConfiguration.GetConfigurationNode(GetPathToSetNode()),
+                UNO_QUERY);
+            if ( ! xSet.is())
+                break;
+
+            // Clear the set.
+            Sequence<OUString> aKeys (xSet->getElementNames());
+            sal_Int32 i;
+            for (i=0; i<aKeys.getLength(); i++)
+                xSet->removeByName (aKeys[i]);
+
+            // Fill it with the URLs of this object.
+            const String sURLMemberName (OUString::createFromAscii("URL"));
+            const String sNameMemberName (OUString::createFromAscii("Name"));
+            Any aValue;
+            Reference<lang::XSingleServiceFactory> xChildFactory (
+                xSet, UNO_QUERY);
+            if ( ! xChildFactory.is())
+                break;
+            MasterPageList::const_iterator iDescriptor;
+            sal_Int32 nIndex(0);
+            for (iDescriptor=mpMasterPages->begin();
+                 iDescriptor!=mpMasterPages->end();
+                 ++iDescriptor,++nIndex)
+            {
+                // Create new child.
+                OUString sKey (OUString::createFromAscii("index_"));
+                sKey += OUString::valueOf(nIndex);
+                Reference<container::XNameReplace> xChild(
+                    xChildFactory->createInstance(), UNO_QUERY);
+                if (xChild.is())
+                {
+                    xSet->insertByName (sKey, makeAny(xChild));
+
+                    aValue <<= OUString(iDescriptor->msURL);
+                    xChild->replaceByName (sURLMemberName, aValue);
+
+                    aValue <<= OUString(iDescriptor->msName);
+                    xChild->replaceByName (sNameMemberName, aValue);
+                }
+            }
+
+            // Write the data back to disk.
+            aConfiguration.CommitChanges();
+        }
+        while (false);
+    }
+    catch (Exception&)
+    {
+        // Ignore exception.
+    }
+}
+
+
+
+
+void RecentlyUsedMasterPages::AddEventListener (const Link& rEventListener)
+{
+    if (::std::find (
+        maListeners.begin(),
+        maListeners.end(),
+        rEventListener) == maListeners.end())
+    {
+        maListeners.push_back (rEventListener);
+    }
+}
+
+
+
+
+void RecentlyUsedMasterPages::RemoveEventListener (const Link& rEventListener)
+{
+    maListeners.erase (
+        ::std::find (
+            maListeners.begin(),
+            maListeners.end(),
+            rEventListener));
+}
+
+
+
+
+int RecentlyUsedMasterPages::GetMasterPageCount (void) const
+{
+    return mpMasterPages->size();
+}
+
+
+
+
+MasterPageContainer::Token RecentlyUsedMasterPages::GetTokenForIndex (sal_uInt32 nIndex) const
+{
+    if(nIndex<mpMasterPages->size())
+        return (*mpMasterPages)[nIndex].maToken;
+    else
+        return MasterPageContainer::NIL_TOKEN;
+}
+
+
+
+
+void RecentlyUsedMasterPages::SendEvent (void)
+{
+    ::std::vector<Link>::iterator aLink (maListeners.begin());
+    ::std::vector<Link>::iterator aEnd (maListeners.end());
+    while (aLink!=aEnd)
+    {
+        aLink->Call (NULL);
+        ++aLink;
+    }
+}
+
+
+
+
+IMPL_LINK(RecentlyUsedMasterPages, MasterPageChangeListener,
+    MasterPageObserverEvent*, pEvent)
+{
+    switch (pEvent->meType)
+    {
+        case MasterPageObserverEvent::ET_MASTER_PAGE_ADDED:
+        case MasterPageObserverEvent::ET_MASTER_PAGE_EXISTS:
+            AddMasterPage(
+                mpContainer->GetTokenForStyleName(pEvent->mrMasterPageName));
+            break;
+
+        case MasterPageObserverEvent::ET_MASTER_PAGE_REMOVED:
+            // Do not change the list of recently master pages (the deleted
+            // page was recently used) but tell the listeners.  They may want
+            // to update their lists.
+            SendEvent();
+            break;
+    }
+    return 0;
+}
+
+
+
+
+IMPL_LINK(RecentlyUsedMasterPages, MasterPageContainerChangeListener,
+    MasterPageContainerChangeEvent*, pEvent)
+{
+    if (pEvent != NULL)
+        switch (pEvent->meEventType)
+        {
+            case MasterPageContainerChangeEvent::CHILD_ADDED:
+            case MasterPageContainerChangeEvent::CHILD_REMOVED:
+            case MasterPageContainerChangeEvent::INDEX_CHANGED:
+            case MasterPageContainerChangeEvent::INDEXES_CHANGED:
+                ResolveList();
+                break;
+
+            default:
+                // Ignored.
+                break;
+        }
+    return 0;
+}
+
+
+
+
+void RecentlyUsedMasterPages::AddMasterPage (
+    MasterPageContainer::Token aToken,
+    bool bMakePersistent)
+{
+    // For the page to be inserted the token has to be valid and the page
+    // has to have a valid URL.  This excludes master pages that do not come
+    // from template files.
+    if (aToken != MasterPageContainer::NIL_TOKEN
+        && mpContainer->GetURLForToken(aToken).Len()>0)
+    {
+
+        MasterPageList::iterator aIterator (
+            ::std::find_if(mpMasterPages->begin(),mpMasterPages->end(),
+                Descriptor::TokenComparator(aToken)));
+        if (aIterator != mpMasterPages->end())
+        {
+            // When an entry for the given token already exists then remove
+            // it now and insert it later at the head of the list.
+            mpMasterPages->erase (aIterator);
+        }
+
+        mpMasterPages->insert(mpMasterPages->begin(),
+            Descriptor(
+                aToken,
+                mpContainer->GetURLForToken(aToken),
+                mpContainer->GetStyleNameForToken(aToken)));
+
+        // Shorten list to maximal size.
+        while (mpMasterPages->size() > mnMaxListSize)
+        {
+            mpMasterPages->pop_back ();
+        }
+
+        if (bMakePersistent)
+            SavePersistentValues ();
+        SendEvent();
+    }
+}
+
+
+
+
+void RecentlyUsedMasterPages::ResolveList (void)
+{
+    bool bNotify (false);
+
+    MasterPageList::iterator iDescriptor;
+    for (iDescriptor=mpMasterPages->begin(); iDescriptor!=mpMasterPages->end(); ++iDescriptor)
+    {
+        if (iDescriptor->maToken == MasterPageContainer::NIL_TOKEN)
+        {
+            MasterPageContainer::Token aToken (mpContainer->GetTokenForURL(iDescriptor->msURL));
+            iDescriptor->maToken = aToken;
+            if (aToken != MasterPageContainer::NIL_TOKEN)
+                bNotify = true;
+        }
+        else
+        {
+            if ( ! mpContainer->HasToken(iDescriptor->maToken))
+            {
+                iDescriptor->maToken = MasterPageContainer::NIL_TOKEN;
+                bNotify = true;
+            }
+        }
+    }
+
+    if (bNotify)
+        SendEvent();
+}
+
+
+} } // end of namespace sd::sidebar

Added: openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentlyUsedMasterPages.hxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentlyUsedMasterPages.hxx?rev=1449041&view=auto
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentlyUsedMasterPages.hxx (added)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/RecentlyUsedMasterPages.hxx Fri Feb 22 13:50:42 2013
@@ -0,0 +1,124 @@
+/**************************************************************
+ * 
+ * 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_RECENTLY_USED_MASTER_PAGES_HXX
+#define SD_SIDEBAR_PANELS_RECENTLY_USED_MASTER_PAGES_HXX
+
+#include "tools/SdGlobalResourceContainer.hxx"
+#include <osl/mutex.hxx>
+#include <tools/link.hxx>
+#include <vcl/image.hxx>
+#include <vector>
+#include <tools/string.hxx>
+
+#include "DrawDocShell.hxx"
+#include "MasterPageContainer.hxx"
+#include <com/sun/star/uno/XInterface.hpp>
+
+class SdPage;
+
+namespace sd {
+class MasterPageObserverEvent;
+}
+
+
+namespace sd { namespace sidebar {
+
+/** This singleton holds a list of the most recently used master pages.
+*/
+class RecentlyUsedMasterPages
+    : public SdGlobalResource
+{
+public:
+    /** Return the single instance of this class.
+    */
+    static RecentlyUsedMasterPages& Instance (void);
+
+    void AddEventListener (const Link& rEventListener);
+    void RemoveEventListener (const Link& rEventListener);
+    
+    int GetMasterPageCount (void) const;
+    MasterPageContainer::Token GetTokenForIndex (sal_uInt32 nIndex) const;
+
+private:
+    /** The single instance of this class.  It is created on demand when
+        Instance() is called for the first time.
+    */
+    static RecentlyUsedMasterPages* mpInstance;
+
+    ::std::vector<Link> maListeners;
+
+    class MasterPageList;
+    ::std::auto_ptr<MasterPageList> mpMasterPages;
+    unsigned long int mnMaxListSize;
+    ::boost::shared_ptr<MasterPageContainer> mpContainer;
+    
+    RecentlyUsedMasterPages (void);
+    virtual ~RecentlyUsedMasterPages (void);
+
+    /** Call this method after a new object has been created.
+    */
+    void LateInit (void);
+
+    /// The copy constructor is not implemented.  Do not use!
+    RecentlyUsedMasterPages (const RecentlyUsedMasterPages&);
+
+    /// The assignment operator is not implemented.  Do not use!
+    RecentlyUsedMasterPages& operator= (const RecentlyUsedMasterPages&);
+
+    void SendEvent (void);
+    DECL_LINK(MasterPageChangeListener, MasterPageObserverEvent*);
+    DECL_LINK(MasterPageContainerChangeListener, MasterPageContainerChangeEvent*);
+
+    /** Add a descriptor for the specified master page to the end of the
+        list of most recently used master pages.  When the page is already a
+        member of that list the associated descriptor is moved to the end of
+        the list to make it the most recently used entry.
+        @param bMakePersistent
+            When <TRUE/> is given then the new list of recently used master
+            pages is written back into the configuration to make it
+            persistent.  Giving <FALSE/> to ommit this is used while loading
+            the persistent list from the configuration.
+    */
+    void AddMasterPage (
+        MasterPageContainer::Token aToken,
+        bool bMakePersistent = true);
+
+    /** Load the list of recently used master pages from the registry where
+        it was saved to make it persistent.
+    */
+    void LoadPersistentValues (void);
+
+    /** Save the list of recently used master pages to the registry to make
+        it presistent.
+    */
+    void SavePersistentValues (void);
+
+    void ResolveList (void);
+};
+
+
+
+} } // end of namespace sd::sidebar
+
+#endif

Modified: openoffice/branches/sidebar/main/sd/source/ui/sidebar/SidebarFactory.cxx
URL: http://svn.apache.org/viewvc/openoffice/branches/sidebar/main/sd/source/ui/sidebar/SidebarFactory.cxx?rev=1449041&r1=1449040&r2=1449041&view=diff
==============================================================================
--- openoffice/branches/sidebar/main/sd/source/ui/sidebar/SidebarFactory.cxx (original)
+++ openoffice/branches/sidebar/main/sd/source/ui/sidebar/SidebarFactory.cxx Fri Feb 22 13:50:42 2013
@@ -22,21 +22,25 @@
 #include "precompiled_sd.hxx"
 
 #include "SidebarFactory.hxx"
-#include "framework/FrameworkHelper.hxx"
 #include "framework/Pane.hxx"
 #include "ViewShellBase.hxx"
-#include "UIElementWrapper.hxx"
+#include "DrawController.hxx"
+#include "LayoutMenu.hxx"
+#include "CurrentMasterPagesSelector.hxx"
+#include "RecentMasterPagesSelector.hxx"
+#include "AllMasterPagesSelector.hxx"
+#include "CustomAnimationPanel.hxx"
+#include "TableDesignPanel.hxx"
+#include "SlideTransitionPanel.hxx"
 
 #include <sfx2/viewfrm.hxx>
+#include <sfx2/sidebar/SidebarPanelBase.hxx>
 #include <comphelper/namedvaluecollection.hxx>
 #include <vcl/window.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
 
-#include <com/sun/star/drawing/framework/XControllerManager.hpp>
-
 using namespace css;
 using namespace cssu;
-using namespace css::drawing::framework;
 using namespace ::sd::framework;
 using ::rtl::OUString;
 
@@ -58,23 +62,6 @@ namespace {
     const static char* gsResourceNameTableDesign = "/TableDesign";
 }
 
-class SidebarFactory::Implementation
-{
-public:
-    Reference<cssdf::XConfigurationController> mxConfigurationController;
-    rtl::Reference<framework::Pane> mxPane;
-    Reference<ui::XUIElement> mxUIElement;
-    Reference<frame::XController> mxController;
-    Reference<awt::XWindow> mxParentWindow;
-    bool mbIsDisposed;
-
-    Implementation (const Reference<frame::XController>& rxController);
-    ~Implementation (void);
-    void Dispose (void);
-};
-    
-
-SidebarFactory::ControllerToImplementationMap SidebarFactory::maControllerToImplementationMap;
 Reference<lang::XEventListener> mxControllerDisposeListener;
 
 
@@ -114,8 +101,7 @@ Sequence<rtl::OUString> SAL_CALL Sidebar
 
 SidebarFactory::SidebarFactory(
         const css::uno::Reference<css::uno::XComponentContext>& rxContext)
-    : SidebarFactoryInterfaceBase(m_aMutex),
-      mpImplementation()
+    : SidebarFactoryInterfaceBase(m_aMutex)
 {
 }
 
@@ -131,10 +117,6 @@ SidebarFactory::~SidebarFactory (void)
 
 void SAL_CALL SidebarFactory::disposing (void)
 {
-    SharedImplementation pImplementation;
-    pImplementation.swap(mpImplementation);
-    if (pImplementation)
-        pImplementation->Dispose();
 }
 
 
@@ -145,11 +127,6 @@ void SAL_CALL SidebarFactory::disposing 
 void SAL_CALL SidebarFactory::initialize (const Sequence<Any>& aArguments)
     throw (Exception, RuntimeException)
 {
-    if (aArguments.getLength() > 0)
-    {
-        mpImplementation = GetImplementationForController(
-            Reference<frame::XController>(aArguments[0], UNO_QUERY));
-    }
 }
 
 
@@ -181,41 +158,41 @@ Reference<ui::XUIElement> SAL_CALL Sideb
         throw RuntimeException(
             A2S("SidebarFactory::createUIElement called without XFrame"),
             NULL);
-    mpImplementation = GetImplementationForController(xFrame->getController());
-    if ( ! mpImplementation)
-        throw RuntimeException(
-            A2S("SidebarFactory::createUIElement called without XController"),
-            NULL);
-    if (mpImplementation->mxConfigurationController.is())
-        mpImplementation->mxConfigurationController->addResourceFactory(
-            FrameworkHelper::msSidebarPaneURL+A2S("*"), this);
-
-    //  Remember the parent window, so that following calls to
-    //  createResource() can access it.
-    mpImplementation->mxParentWindow = xParentWindow;
-    if (mpImplementation->mxPane.is())
-        mpImplementation->mxPane->SetWindow(VCLUnoHelper::GetWindow(xParentWindow));
+
+    // Tunnel through the controller to obtain a ViewShellBase.
+    ViewShellBase* pBase = NULL;
+    Reference<lang::XUnoTunnel> xTunnel (xFrame->getController(), UNO_QUERY);
+    if (xTunnel.is())
+    {
+        ::sd::DrawController* pController = reinterpret_cast<sd::DrawController*>(
+            xTunnel->getSomething(sd::DrawController::getUnoTunnelId()));
+        if (pController != NULL)
+            pBase = pController->GetViewShellBase();
+    }
+    if (pBase == NULL)
+        throw RuntimeException(A2S("can not get ViewShellBase for frame"), NULL);
 
     // Create a framework view.
-    OUString sTaskPanelURL;
+    ::Window* pControl = NULL;
+
 #define EndsWith(s,t) s.endsWithAsciiL(t,strlen(t))
     if (EndsWith(rsUIElementResourceURL, gsResourceNameCustomAnimations))
-        sTaskPanelURL = FrameworkHelper::msCustomAnimationTaskPanelURL;
+        pControl = new CustomAnimationPanel(pParentWindow, *pBase);
     else if (EndsWith(rsUIElementResourceURL, gsResourceNameLayouts))
-        sTaskPanelURL = FrameworkHelper::msLayoutTaskPanelURL;
+        pControl = new LayoutMenu(pParentWindow, *pBase, xSidebar);
     else if (EndsWith(rsUIElementResourceURL, gsResourceNameAllMasterPages))
-        sTaskPanelURL = FrameworkHelper::msAllMasterPagesTaskPanelURL;
+        pControl = AllMasterPagesSelector::Create(pParentWindow, *pBase, xSidebar);
     else if (EndsWith(rsUIElementResourceURL, gsResourceNameRecentMasterPages))
-        sTaskPanelURL = FrameworkHelper::msRecentMasterPagesTaskPanelURL;
+        pControl = RecentMasterPagesSelector::Create(pParentWindow, *pBase, xSidebar);
     else if (EndsWith(rsUIElementResourceURL, gsResourceNameUsedMasterPages))
-        sTaskPanelURL = FrameworkHelper::msUsedMasterPagesTaskPanelURL;
+        pControl = CurrentMasterPagesSelector::Create(pParentWindow, *pBase, xSidebar);
     else if (EndsWith(rsUIElementResourceURL, gsResourceNameSlideTransitions))
-        sTaskPanelURL = FrameworkHelper::msSlideTransitionTaskPanelURL;
+        pControl = new SlideTransitionPanel(pParentWindow, *pBase);
     else if (EndsWith(rsUIElementResourceURL, gsResourceNameTableDesign))
-        sTaskPanelURL = FrameworkHelper::msTableDesignPanelURL;
+        pControl = new TableDesignPanel(pParentWindow, *pBase);
 #undef EndsWith
-    
-    if (sTaskPanelURL.getLength() == 0)
+
+    if (pControl == NULL)
         throw lang::IllegalArgumentException();
 
     // Create a wrapper around pane and view and return it as
@@ -223,12 +200,13 @@ Reference<ui::XUIElement> SAL_CALL Sideb
     Reference<ui::XUIElement> xUIElement;
     try
     {
-        xUIElement.set(new UIElementWrapper(
+        xUIElement.set(
+            sfx2::sidebar::SidebarPanelBase::Create(
                 rsUIElementResourceURL,
                 xFrame,
-                sTaskPanelURL,
-                xSidebar,
-                VCLUnoHelper::GetWindow(xParentWindow)));
+                pControl,
+                ::boost::function<void(void)>(),
+                ui::LayoutSize(-1,-1,-1)));
     }
     catch(Exception& rException)
     {
@@ -245,48 +223,6 @@ Reference<ui::XUIElement> SAL_CALL Sideb
 
 
 
-// XResourceFactory
-
-Reference<drawing::framework::XResource>
-    SAL_CALL SidebarFactory::createResource (
-        const Reference<drawing::framework::XResourceId>& rxPaneId)
-    throw (RuntimeException, lang::IllegalArgumentException, lang::WrappedTargetException)
-{
-    if ( ! rxPaneId.is())
-        throw lang::IllegalArgumentException();
-
-    const OUString sResourceURL (rxPaneId->getResourceURL());
-    if ( ! sResourceURL.equals(FrameworkHelper::msSidebarPaneURL))
-        throw lang::IllegalArgumentException();
-
-    if ( ! mpImplementation)
-        throw RuntimeException(A2S("SidebarFactory not initialized"), NULL);
-    
-    ::Window* pWindow = VCLUnoHelper::GetWindow(mpImplementation->mxParentWindow);
-    if (pWindow == NULL)
-        throw RuntimeException();
-
-    mpImplementation->mxPane.set(new Pane(rxPaneId, pWindow));
-    Reference<drawing::framework::XResource> xPane (static_cast<XPane*>(mpImplementation->mxPane.get()));
-    return xPane;
-}
-
-
-
-
-void SAL_CALL SidebarFactory::releaseResource (
-    const Reference<drawing::framework::XResource>& rxPane)
-    throw (RuntimeException)
-{
-    (void)rxPane;
-    
-    // Any panes created by us are just wrappers around windows whose lifetime
-    // is controlled somewhere else => nothing to do.
-}
-
-
-
-
 void SAL_CALL SidebarFactory::disposing (const ::css::lang::EventObject& rEvent)
     throw(cssu::RuntimeException)
 {
@@ -302,77 +238,4 @@ void SAL_CALL SidebarFactory::disposing 
 
 
 
-SidebarFactory::SharedImplementation SidebarFactory::GetImplementationForController (
-    const cssu::Reference<css::frame::XController>& rxController)
-{
-    SharedImplementation pImplementation;
-    if (rxController.is())
-    {
-        ControllerToImplementationMap::const_iterator iImplementation (
-            maControllerToImplementationMap.find(rxController));
-        if (iImplementation == maControllerToImplementationMap.end())
-        {
-            pImplementation.reset(new Implementation(rxController));
-            maControllerToImplementationMap[rxController] = pImplementation;
-            
-            // Each Implementation object is referenced by two
-            // SidebarFactory objects.  The Implementation object is
-            // destroyed when the first of the SidebarFactory objects
-            // is disposed.
-        }
-        else
-            pImplementation = iImplementation->second;
-    }
-    return pImplementation;
-}
-
-
-
-
-//----- SidebarFactory::Implementation ----------------------------------------
-
-SidebarFactory::Implementation::Implementation (const Reference<frame::XController>& rxController)
-    : mxConfigurationController(),
-      mxPane(),
-      mxUIElement(),
-      mxController(rxController),
-      mxParentWindow(),
-      mbIsDisposed(false)
-{
-    Reference<XControllerManager> xCM (rxController, UNO_QUERY);
-    if (xCM.is())
-    {
-        mxConfigurationController = xCM->getConfigurationController();
-    }
-}
-
-
-
-
-SidebarFactory::Implementation::~Implementation (void)
-{
-    Dispose();
-}
-
-
-
-
-void SidebarFactory::Implementation::Dispose (void)
-{
-    if (mbIsDisposed)
-        return;
-
-    mbIsDisposed = true;
-
-    // Release the entry in the maControllerToImplementationMap even though there
-    // may be another object that "references" to it.
-    ControllerToImplementationMap::iterator iImplementation (
-        maControllerToImplementationMap.find(mxController));
-        if (iImplementation != maControllerToImplementationMap.end())
-            maControllerToImplementationMap.erase(iImplementation);
-    
-    mxController.clear();
-}
-
-
 } } // end of namespace sd::sidebar