summaryrefslogtreecommitdiff
path: root/sd/source/ui/slidesorter/model/SlideSorterModel.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/slidesorter/model/SlideSorterModel.cxx')
-rw-r--r--sd/source/ui/slidesorter/model/SlideSorterModel.cxx407
1 files changed, 351 insertions, 56 deletions
diff --git a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx
index 80e822e9b102..57c887d6f02c 100644
--- a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx
+++ b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx
@@ -34,10 +34,10 @@
#include "model/SlsPageDescriptor.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "controller/SlideSorterController.hxx"
-#include "controller/SlsPageObjectFactory.hxx"
#include "controller/SlsProperties.hxx"
#include "controller/SlsPageSelector.hxx"
#include "controller/SlsCurrentSlideManager.hxx"
+#include "controller/SlsSlotManager.hxx"
#include "view/SlideSorterView.hxx"
#include "taskpane/SlideSorterCacheDisplay.hxx"
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
@@ -47,6 +47,7 @@
#include "ViewShellBase.hxx"
#include "DrawViewShell.hxx"
+#include "DrawDocShell.hxx"
#include "drawdoc.hxx"
#include "sdpage.hxx"
#include "FrameView.hxx"
@@ -68,6 +69,56 @@ namespace {
private:
Reference<drawing::XDrawPage> mxSlide;
};
+
+ bool PrintModel (const SlideSorterModel& rModel)
+ {
+ for (sal_Int32 nIndex=0,nCount=rModel.GetPageCount(); nIndex<nCount; ++nIndex)
+ {
+ SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex));
+ if (pDescriptor)
+ {
+ OSL_TRACE("%d %d %d %d %x",
+ nIndex,
+ pDescriptor->GetPageIndex(),
+ pDescriptor->GetVisualState().mnPageId,
+ FromCoreIndex(pDescriptor->GetPage()->GetPageNum()),
+ pDescriptor->GetPage());
+ }
+ else
+ {
+ OSL_TRACE("%d", nIndex);
+ }
+ }
+
+ return true;
+ }
+ bool CheckModel (const SlideSorterModel& rModel)
+ {
+ for (sal_Int32 nIndex=0,nCount=rModel.GetPageCount(); nIndex<nCount; ++nIndex)
+ {
+ SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex));
+ if ( ! pDescriptor)
+ {
+ PrintModel(rModel);
+ OSL_ASSERT(pDescriptor);
+ return false;
+ }
+ if (nIndex != pDescriptor->GetPageIndex())
+ {
+ PrintModel(rModel);
+ OSL_ASSERT(nIndex == pDescriptor->GetPageIndex());
+ return false;
+ }
+ if (nIndex != pDescriptor->GetVisualState().mnPageId)
+ {
+ PrintModel(rModel);
+ OSL_ASSERT(nIndex == pDescriptor->GetVisualState().mnPageId);
+ return false;
+ }
+ }
+
+ return true;
+ }
}
@@ -79,8 +130,7 @@ SlideSorterModel::SlideSorterModel (SlideSorter& rSlideSorter)
mxSlides(),
mePageKind(PK_STANDARD),
meEditMode(EM_PAGE),
- maPageDescriptors(0),
- mpPageObjectFactory(NULL)
+ maPageDescriptors(0)
{
}
@@ -95,6 +145,21 @@ SlideSorterModel::~SlideSorterModel (void)
+void SlideSorterModel::Init (void)
+{
+}
+
+
+
+
+void SlideSorterModel::Dispose (void)
+{
+ ClearDescriptorList ();
+}
+
+
+
+
SdDrawDocument* SlideSorterModel::GetDocument (void)
{
if (mrSlideSorter.GetViewShellBase() != NULL)
@@ -159,20 +224,11 @@ SharedPageDescriptor SlideSorterModel::GetPageDescriptor (
pDescriptor = maPageDescriptors[nPageIndex];
if (pDescriptor == NULL && bCreate && mxSlides.is())
{
- SdDrawDocument* pModel = const_cast<SlideSorterModel*>(this)->GetDocument();
- SdPage* pPage = NULL;
- if (pModel != NULL)
- {
- if (meEditMode == EM_PAGE)
- pPage = pModel->GetSdPage ((USHORT)nPageIndex, mePageKind);
- else
- pPage = pModel->GetMasterSdPage ((USHORT)nPageIndex, mePageKind);
- }
+ SdPage* pPage = GetPage(nPageIndex);
pDescriptor.reset(new PageDescriptor (
Reference<drawing::XDrawPage>(mxSlides->getByIndex(nPageIndex),UNO_QUERY),
pPage,
- nPageIndex,
- GetPageObjectFactory()));
+ nPageIndex));
maPageDescriptors[nPageIndex] = pDescriptor;
}
}
@@ -235,6 +291,59 @@ sal_Int32 SlideSorterModel::GetIndex (const Reference<drawing::XDrawPage>& rxSli
+sal_Int32 SlideSorterModel::GetIndex (const SdrPage* pPage) const
+{
+ if (pPage == NULL)
+ return -1;
+
+ ::osl::MutexGuard aGuard (maMutex);
+
+ // First try to guess the right index.
+ sal_Int16 nNumber ((pPage->GetPageNum()-1)/2);
+ SharedPageDescriptor pDescriptor (GetPageDescriptor(nNumber, false));
+ if (pDescriptor.get() != NULL
+ && pDescriptor->GetPage() == pPage)
+ {
+ return nNumber;
+ }
+
+ // Guess was wrong, iterate over all slides and search for the right
+ // one.
+ const sal_Int32 nCount (maPageDescriptors.size());
+ for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
+ {
+ pDescriptor = maPageDescriptors[nIndex];
+
+ // Make sure that the descriptor exists. Without it the given slide
+ // can not be found.
+ if (pDescriptor.get() == NULL)
+ {
+ // Call GetPageDescriptor() to create the missing descriptor.
+ pDescriptor = GetPageDescriptor(nIndex, true);
+ }
+
+ if (pDescriptor->GetPage() == pPage)
+ return nIndex;
+ }
+
+ return -1;
+}
+
+
+
+
+sal_uInt16 SlideSorterModel::GetCoreIndex (const sal_Int32 nIndex) const
+{
+ SharedPageDescriptor pDescriptor (GetPageDescriptor(nIndex));
+ if (pDescriptor)
+ return pDescriptor->GetPage()->GetPageNum();
+ else
+ return mxSlides->getCount()*2+1;
+}
+
+
+
+
/** For now this method uses a trivial algorithm: throw away all descriptors
and create them anew (on demand). The main problem that we are facing
when designing a better algorithm is that we can not compare pointers to
@@ -245,8 +354,39 @@ sal_Int32 SlideSorterModel::GetIndex (const Reference<drawing::XDrawPage>& rxSli
void SlideSorterModel::Resync (void)
{
::osl::MutexGuard aGuard (maMutex);
- ClearDescriptorList ();
- AdaptSize();
+
+ // Check if document and this model really differ.
+ bool bIsUpToDate (true);
+ SdDrawDocument* pDocument = GetDocument();
+ if (pDocument!=NULL && maPageDescriptors.size()==pDocument->GetSdPageCount(mePageKind))
+ {
+ for (sal_Int32 nIndex=0,nCount=maPageDescriptors.size(); nIndex<nCount; ++nIndex)
+ {
+ if (maPageDescriptors[nIndex]
+ && maPageDescriptors[nIndex]->GetPage()
+ != GetPage(nIndex))
+ {
+ OSL_TRACE("page %d differs\n", nIndex);
+ bIsUpToDate = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ bIsUpToDate = false;
+ OSL_TRACE("models differ");
+ }
+
+ if ( ! bIsUpToDate)
+ {
+ SynchronizeDocumentSelection(); // Try to make the current selection persistent.
+ ClearDescriptorList ();
+ AdaptSize();
+ SynchronizeModelSelection();
+ mrSlideSorter.GetController().GetPageSelector().CountSelectedPages();
+ }
+ CheckModel(*this);
}
@@ -254,21 +394,26 @@ void SlideSorterModel::Resync (void)
void SlideSorterModel::ClearDescriptorList (void)
{
- ::osl::MutexGuard aGuard (maMutex);
+ DescriptorContainer aDescriptors;
+
+ {
+ ::osl::MutexGuard aGuard (maMutex);
+ aDescriptors.swap(maPageDescriptors);
+ }
- // Clear the cache of page descriptors.
- DescriptorContainer::iterator I;
- for (I=maPageDescriptors.begin(); I!=maPageDescriptors.end(); ++I)
+ for (DescriptorContainer::iterator iDescriptor=aDescriptors.begin(), iEnd=aDescriptors.end();
+ iDescriptor!=iEnd;
+ ++iDescriptor)
{
- if (I->get() != NULL)
+ if (iDescriptor->get() != NULL)
{
- if ( ! I->unique())
+ if ( ! iDescriptor->unique())
{
- OSL_TRACE("SlideSorterModel::ClearDescriptorList: trying to delete page descriptor that is still used with count %d", I->use_count());
+ OSL_TRACE("SlideSorterModel::ClearDescriptorList: trying to delete page descriptor that is still used with count %d", iDescriptor->use_count());
// No assertion here because that can hang the office when
// opening a dialog from here.
}
- I->reset();
+ iDescriptor->reset();
}
}
}
@@ -284,44 +429,23 @@ void SlideSorterModel::SynchronizeDocumentSelection (void)
while (aAllPages.HasMoreElements())
{
SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
- pDescriptor->GetPage()->SetSelected (pDescriptor->IsSelected());
+ pDescriptor->GetPage()->SetSelected(pDescriptor->HasState(PageDescriptor::ST_Selected));
}
}
-void SlideSorterModel::SetPageObjectFactory(
- ::std::auto_ptr<controller::PageObjectFactory> pPageObjectFactory)
-{
- ::osl::MutexGuard aGuard (maMutex);
-
- mpPageObjectFactory = pPageObjectFactory;
- // When a NULL pointer was given then create a default factory.
- const controller::PageObjectFactory& rFactory (GetPageObjectFactory());
- PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(*this));
- while (aAllPages.HasMoreElements())
- {
- SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
- pDescriptor->SetPageObjectFactory(rFactory);
- }
-}
-
-const controller::PageObjectFactory&
- SlideSorterModel::GetPageObjectFactory (void) const
+void SlideSorterModel::SynchronizeModelSelection (void)
{
::osl::MutexGuard aGuard (maMutex);
- if (mpPageObjectFactory.get() == NULL)
+ PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(*this));
+ while (aAllPages.HasMoreElements())
{
- // We have to create a new factory. The pointer is mutable so we
- // are alowed to do so.
- mpPageObjectFactory = ::std::auto_ptr<controller::PageObjectFactory> (
- new controller::PageObjectFactory(
- mrSlideSorter.GetView().GetPreviewCache(),
- mrSlideSorter.GetController().GetProperties()));
+ SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
+ pDescriptor->SetState(PageDescriptor::ST_Selected, pDescriptor->GetPage()->IsSelected());
}
- return *mpPageObjectFactory.get();
}
@@ -341,7 +465,7 @@ void SlideSorterModel::SetDocumentSlides (
::osl::MutexGuard aGuard (maMutex);
// Reset the current page so to cause everbody to release references to it.
- mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(-1);
+ mrSlideSorter.GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(-1);
mxSlides = rxSlides;
Resync();
@@ -351,24 +475,27 @@ void SlideSorterModel::SetDocumentSlides (
{
SdPage* pPage = pViewShell->getCurrentPage();
if (pPage != NULL)
- mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(
- GetIndex(Reference<drawing::XDrawPage>(pPage->getUnoPage(), UNO_QUERY)));
+ mrSlideSorter.GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(
+ pPage);
else
{
// No current page. This can only be when the slide sorter is
// the main view shell. Get current slide form frame view.
const FrameView* pFrameView = pViewShell->GetFrameView();
if (pFrameView != NULL)
- mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(
+ mrSlideSorter.GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(
pFrameView->GetSelectedPage());
else
{
// No frame view. As a last resort use the first slide as
// current slide.
- mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(0);
+ mrSlideSorter.GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(
+ sal_Int32(0));
}
}
}
+
+ mrSlideSorter.GetController().GetSlotManager()->NotifyEditModeChange();
}
@@ -440,6 +567,174 @@ void SlideSorterModel::AdaptSize (void)
maPageDescriptors.resize(0);
}
+
+
+
+bool SlideSorterModel::IsReadOnly (void) const
+{
+ if (mrSlideSorter.GetViewShellBase() != NULL
+ && mrSlideSorter.GetViewShellBase()->GetDocShell())
+ return mrSlideSorter.GetViewShellBase()->GetDocShell()->IsReadOnly();
+ else
+ return true;
+}
+
+
+
+
+void SlideSorterModel::SaveCurrentSelection (void)
+{
+ PageEnumeration aPages (PageEnumerationProvider::CreateAllPagesEnumeration(*this));
+ while (aPages.HasMoreElements())
+ {
+ SharedPageDescriptor pDescriptor (aPages.GetNextElement());
+ pDescriptor->SetState(
+ PageDescriptor::ST_WasSelected,
+ pDescriptor->HasState(PageDescriptor::ST_Selected));
+ }
+}
+
+
+
+
+Region SlideSorterModel::RestoreSelection (void)
+{
+ Region aRepaintRegion;
+ PageEnumeration aPages (PageEnumerationProvider::CreateAllPagesEnumeration(*this));
+ while (aPages.HasMoreElements())
+ {
+ SharedPageDescriptor pDescriptor (aPages.GetNextElement());
+ if (pDescriptor->SetState(
+ PageDescriptor::ST_Selected,
+ pDescriptor->HasState(PageDescriptor::ST_WasSelected)))
+ {
+ aRepaintRegion.Union(pDescriptor->GetBoundingBox());
+ }
+ }
+ return aRepaintRegion;
+}
+
+
+
+
+bool SlideSorterModel::NotifyPageEvent (const SdrPage* pSdrPage)
+{
+ ::osl::MutexGuard aGuard (maMutex);
+
+ SdPage* pPage = const_cast<SdPage*>(dynamic_cast<const SdPage*>(pSdrPage));
+ if (pPage == NULL)
+ return false;
+
+ // We are only interested in pages that are currently served by this
+ // model.
+ if (pPage->GetPageKind() != mePageKind)
+ return false;
+ if (pPage->IsMasterPage() != (meEditMode==EM_MASTERPAGE))
+ return false;
+
+ if (pPage->IsInserted())
+ InsertSlide(pPage);
+ else
+ DeleteSlide(pPage);
+ CheckModel(*this);
+
+ return true;
+}
+
+
+
+
+void SlideSorterModel::InsertSlide (SdPage* pPage)
+{
+ // Find the index at which to insert the given page.
+ sal_uInt16 nCoreIndex (pPage->GetPageNum());
+ sal_Int32 nIndex (FromCoreIndex(nCoreIndex));
+ if (pPage != GetPage(nIndex))
+ return;
+
+ // Check that the pages in the document before and after the given page
+ // are present in this model.
+ if (nIndex>0)
+ if (GetPage(nIndex-1) != GetPageDescriptor(nIndex-1)->GetPage())
+ return;
+ if (size_t(nIndex)<maPageDescriptors.size()-1)
+ if (GetPage(nIndex+1) != GetPageDescriptor(nIndex)->GetPage())
+ return;
+
+ // Insert the given page at index nIndex
+ maPageDescriptors.insert(
+ maPageDescriptors.begin()+nIndex,
+ SharedPageDescriptor(
+ new PageDescriptor (
+ Reference<drawing::XDrawPage>(mxSlides->getByIndex(nIndex),UNO_QUERY),
+ pPage,
+ nIndex)));
+
+ // Update page indices.
+ UpdateIndices(nIndex+1);
+ OSL_TRACE("page inserted");
+}
+
+
+
+
+void SlideSorterModel::DeleteSlide (const SdPage* pPage)
+{
+ const sal_Int32 nIndex (GetIndex(pPage));
+ if (maPageDescriptors[nIndex])
+ if (maPageDescriptors[nIndex]->GetPage() != pPage)
+ return;
+
+ maPageDescriptors.erase(maPageDescriptors.begin()+nIndex);
+ UpdateIndices(nIndex);
+ OSL_TRACE("page removed");
+}
+
+
+
+
+void SlideSorterModel::UpdateIndices (const sal_Int32 nFirstIndex)
+{
+ for (sal_Int32 nDescriptorIndex=0,nCount=maPageDescriptors.size();
+ nDescriptorIndex<nCount;
+ ++nDescriptorIndex)
+ {
+ SharedPageDescriptor& rpDescriptor (maPageDescriptors[nDescriptorIndex]);
+ if (rpDescriptor)
+ {
+ if (nDescriptorIndex < nFirstIndex)
+ {
+ if (rpDescriptor->GetPageIndex()!=nDescriptorIndex)
+ {
+ OSL_ASSERT(rpDescriptor->GetPageIndex()==nDescriptorIndex);
+ }
+ }
+ else
+ {
+ rpDescriptor->SetPageIndex(nDescriptorIndex);
+ }
+ }
+ }
+}
+
+
+
+
+SdPage* SlideSorterModel::GetPage (const sal_Int32 nSdIndex) const
+{
+ SdDrawDocument* pModel = const_cast<SlideSorterModel*>(this)->GetDocument();
+ if (pModel != NULL)
+ {
+ if (meEditMode == EM_PAGE)
+ return pModel->GetSdPage ((sal_uInt16)nSdIndex, mePageKind);
+ else
+ return pModel->GetMasterSdPage ((sal_uInt16)nSdIndex, mePageKind);
+ }
+ else
+ return NULL;
+}
+
+
} } } // end of namespace ::sd::slidesorter::model
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */