Related: #i123197# Fixed selection problems when switching...

between normal and master mode.

(cherry picked from commit 163d414311b0c8bcb1b0ad7c7cbf364e0ad4e4c4)

Change-Id: Ibabee4c67367c367a9ce1c5afffa76efa3f66bd7
diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
index 8f1542a..6a613d8 100644
--- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
+++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
@@ -934,6 +934,8 @@ void SlideSorterController::FinishEditModeChange (void)
{
    if (mrModel.GetEditMode() == EM_MASTERPAGE)
    {
        mpPageSelector->DeselectAllPages();

        // Search for the master page that was determined in
        // PrepareEditModeChange() and make it the current page.
        PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
@@ -943,16 +945,20 @@ void SlideSorterController::FinishEditModeChange (void)
            if (pDescriptor->GetPage() == mpEditModeChangeMasterPage)
            {
                GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
                mpPageSelector->SelectPage(pDescriptor);
                break;
            }
        }
    }
    else
    {
        PageSelector::BroadcastLock aBroadcastLock (*mpPageSelector);

        SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(mnCurrentPageBeforeSwitch));
        GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);

        // Restore the selection.
        mpPageSelector->DeselectAllPages();
        ::std::vector<SdPage*>::iterator iPage;
        for (iPage=maSelectionBeforeSwitch.begin();
             iPage!=maSelectionBeforeSwitch.end();
@@ -1025,12 +1031,6 @@ void SlideSorterController::SetDocumentSlides (const Reference<container::XIndex
        PreModelChange();

        mrModel.SetDocumentSlides(rxSlides);
        mrView.Layout();

        // Select just the current slide.
        PageSelector::BroadcastLock aBroadcastLock (*mpPageSelector);
        mpPageSelector->DeselectAllPages();
        mpPageSelector->SelectPage(mpCurrentSlideManager->GetCurrentSlide());
    }
}

diff --git a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx
index 8518279..512dbab4 100644
--- a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx
@@ -81,11 +81,14 @@ void CurrentSlideManager::NotifyCurrentSlideChange (const sal_Int32 nSlideIndex)
{
    if (mnCurrentSlideIndex != nSlideIndex)
    {
        PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter.GetController().GetPageSelector());

        mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();

        ReleaseCurrentSlide();
        AcquireCurrentSlide(nSlideIndex);

        // Update the selection.
        mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
        if (mpCurrentSlide)
        {
            mrSlideSorter.GetController().GetPageSelector().SelectPage(mpCurrentSlide);
diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
index 4121add..1484159 100644
--- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx
@@ -60,7 +60,7 @@ PageSelector::PageSelector (SlideSorter& rSlideSorter)
      mpSelectionAnchor(),
      mpCurrentPage(),
      mnUpdateLockCount(0),
      mbIsUpdateCurrentPagePending(false)
      mbIsUpdateCurrentPagePending(true)
{
    CountSelectedPages ();
}
@@ -375,27 +375,39 @@ void PageSelector::UpdateCurrentPage (const bool bUpdateOnlyWhenPending)
    mbIsUpdateCurrentPagePending = false;

    // Make the first selected page the current page.
    SharedPageDescriptor pCurrentPageDescriptor;
    const sal_Int32 nPageCount (GetPageCount());
    for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
    {
        SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
        if (pDescriptor && pDescriptor->HasState(PageDescriptor::ST_Selected))
        if ( ! pDescriptor)
            continue;
        if (pDescriptor->HasState(PageDescriptor::ST_Selected))
        {
            // Switching the current slide normally sets also the selection
            // to just the new current slide.  To prevent that, we store
            // (and at the end of this scope restore) the current selection.
            ::boost::shared_ptr<PageSelection> pSelection (GetPageSelection());

            mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);

            // Restore the selection and prevent a recursive call to
            // UpdateCurrentPage().
            SetPageSelection(pSelection, false);
            return;
            pCurrentPageDescriptor = pDescriptor;
            break;
        }
    }
    if ( ! pCurrentPageDescriptor && nPageCount>0)
    {
        // No page is selected.  Make the first slide the current page.
        pCurrentPageDescriptor = mrModel.GetPageDescriptor(0);
    }

    // No page is selected.  Do not change the current slide.
    if (pCurrentPageDescriptor)
    {
        // Switching the current slide normally sets also the
        // selection to just the new current slide.  To prevent that,
        // we store (and at the end of this scope restore) the current
        // selection.
        ::boost::shared_ptr<PageSelection> pSelection (GetPageSelection());

        mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pCurrentPageDescriptor);

        // Restore the selection and prevent a recursive call to
        // UpdateCurrentPage().
        SetPageSelection(pSelection, false);
    }
}


diff --git a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx
index efcbcda..09fc74c 100644
--- a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx
+++ b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx
@@ -43,7 +43,7 @@ class SlideSorter;
namespace sd { namespace slidesorter { namespace model {

inline sal_Int32 FromCoreIndex (const sal_uInt16 nCoreIndex) { return (nCoreIndex-1)/2; }
inline sal_uInt16 ToCoreIndex (const sal_Int32 nIndex) { return nIndex*2+1; }
inline sal_uInt16 ToCoreIndex (const sal_Int32 nIndex) { return static_cast<sal_uInt16>(nIndex*2+1); }

/** The model of the slide sorter gives access to the slides that are to be
    displayed in the slide sorter view.  Via the SetDocumentSlides() method
diff --git a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx
index 46eb6bd..1c21d0e 100644
--- a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx
+++ b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx
@@ -158,7 +158,6 @@ bool SlideSorterModel::SetEditMode (EditMode eEditMode)
    {
        meEditMode = eEditMode;
        UpdatePageList();
        ClearDescriptorList();
        bEditModeChanged = true;
    }
    return bEditModeChanged;
@@ -409,7 +408,8 @@ void SlideSorterModel::SynchronizeDocumentSelection (void)
    while (aAllPages.HasMoreElements())
    {
        SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
        pDescriptor->GetPage()->SetSelected(pDescriptor->HasState(PageDescriptor::ST_Selected));
        const bool bIsSelected (pDescriptor->HasState(PageDescriptor::ST_Selected));
        pDescriptor->GetPage()->SetSelected(bIsSelected);
    }
}

@@ -424,7 +424,8 @@ void SlideSorterModel::SynchronizeModelSelection (void)
    while (aAllPages.HasMoreElements())
    {
        SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
        pDescriptor->SetState(PageDescriptor::ST_Selected, pDescriptor->GetPage()->IsSelected());
        const bool bIsSelected (pDescriptor->GetPage()->IsSelected());
        pDescriptor->SetState(PageDescriptor::ST_Selected, bIsSelected);
    }
}

@@ -444,11 +445,29 @@ void SlideSorterModel::SetDocumentSlides (
{
    ::osl::MutexGuard aGuard (maMutex);

    // Reset the current page so to cause everbody to release references to it.
    // Make the current selection persistent and then release the
    // current set of pages.
    SynchronizeDocumentSelection();
    mxSlides = NULL;
    ClearDescriptorList ();

    // Reset the current page to cause everbody to release references to it.
    mrSlideSorter.GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(-1);

    // Set the new set of pages.
    mxSlides = rxSlides;
    Resync();
    AdaptSize();
    SynchronizeModelSelection();
    mrSlideSorter.GetController().GetPageSelector().CountSelectedPages();

    model::PageEnumeration aSelectedPages (
        model::PageEnumerationProvider::CreateSelectedPagesEnumeration(*this));
    if (aSelectedPages.HasMoreElements())
    {
        SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
        mrSlideSorter.GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(
            pDescriptor->GetPage());
    }

    ViewShell* pViewShell = mrSlideSorter.GetViewShell();
    if (pViewShell != NULL)
@@ -652,7 +671,6 @@ void SlideSorterModel::InsertSlide (SdPage* pPage)

    // Update page indices.
    UpdateIndices(nIndex+1);
    OSL_TRACE("page inserted");
}


@@ -690,7 +708,6 @@ void SlideSorterModel::DeleteSlide (const SdPage* pPage)
        maPageDescriptors.erase(maPageDescriptors.begin()+nIndex);
        UpdateIndices(nIndex);
    }
    OSL_TRACE("page removed");
}


diff --git a/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx b/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx
index d3f0c68..144e714 100644
--- a/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx
+++ b/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx
@@ -65,7 +65,9 @@ void ViewCacheContext::NotifyPreviewCreation (
    }
    else
    {
        OSL_ASSERT(pDescriptor);
        // It is OK when a preview was created for a page that is not
        // currently displayed because both normal and master pages are
        // kept in the same cache.
    }
}