merge the formfield patch from ooo-build
[ooovba.git] / sd / source / ui / slidesorter / model / SlideSorterModel.cxx
blobcb4dd25aaef9a08d02971bc58827f9da75fc7c79
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SlideSorterModel.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "precompiled_sd.hxx"
33 #include "model/SlideSorterModel.hxx"
35 #include "SlideSorter.hxx"
36 #include "model/SlsPageDescriptor.hxx"
37 #include "model/SlsPageEnumerationProvider.hxx"
38 #include "controller/SlideSorterController.hxx"
39 #include "controller/SlsPageObjectFactory.hxx"
40 #include "controller/SlsProperties.hxx"
41 #include "controller/SlsPageSelector.hxx"
42 #include "controller/SlsCurrentSlideManager.hxx"
43 #include "view/SlideSorterView.hxx"
44 #include "taskpane/SlideSorterCacheDisplay.hxx"
45 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
46 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 #include <com/sun/star/beans/UnknownPropertyException.hpp>
50 #include "ViewShellBase.hxx"
51 #include "DrawViewShell.hxx"
52 #include "drawdoc.hxx"
53 #include "sdpage.hxx"
54 #include "FrameView.hxx"
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
59 namespace sd { namespace slidesorter { namespace model {
61 namespace {
62 class CompareToXDrawPage
64 public:
65 CompareToXDrawPage (const Reference<drawing::XDrawPage>& rxSlide) : mxSlide(rxSlide) {}
66 bool operator() (const SharedPageDescriptor& rpDescriptor)
67 { return rpDescriptor.get()!=NULL && rpDescriptor->GetXDrawPage()==mxSlide; }
68 private:
69 Reference<drawing::XDrawPage> mxSlide;
76 SlideSorterModel::SlideSorterModel (SlideSorter& rSlideSorter)
77 : maMutex(),
78 mrSlideSorter(rSlideSorter),
79 mxSlides(),
80 mePageKind(PK_STANDARD),
81 meEditMode(EM_PAGE),
82 maPageDescriptors(0),
83 mpPageObjectFactory(NULL)
90 SlideSorterModel::~SlideSorterModel (void)
92 ClearDescriptorList ();
98 SdDrawDocument* SlideSorterModel::GetDocument (void)
100 if (mrSlideSorter.GetViewShellBase() != NULL)
101 return mrSlideSorter.GetViewShellBase()->GetDocument();
102 else
103 return NULL;
109 bool SlideSorterModel::SetEditMode (EditMode eEditMode)
111 bool bEditModeChanged = false;
112 if (meEditMode != eEditMode)
114 meEditMode = eEditMode;
115 UpdatePageList();
116 ClearDescriptorList();
117 bEditModeChanged = true;
119 return bEditModeChanged;
125 bool SlideSorterModel::SetEditModeFromController (void)
127 bool bIsMasterPageMode = false;
128 // Get the edit mode from the controller.
131 Reference<beans::XPropertySet> xSet (mrSlideSorter.GetXController(), UNO_QUERY_THROW);
132 Any aValue (xSet->getPropertyValue(
133 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsMasterPageMode"))));
134 aValue >>= bIsMasterPageMode;
136 catch (RuntimeException&)
138 // When the property is not supported then the master
139 // page mode is not supported, too.
140 bIsMasterPageMode = false;
143 return SetEditMode(bIsMasterPageMode ? EM_MASTERPAGE : EM_PAGE);
149 EditMode SlideSorterModel::GetEditMode (void) const
151 return meEditMode;
157 PageKind SlideSorterModel::GetPageType (void) const
159 return mePageKind;
165 sal_Int32 SlideSorterModel::GetPageCount (void) const
167 return maPageDescriptors.size();
173 SharedPageDescriptor SlideSorterModel::GetPageDescriptor (
174 const sal_Int32 nPageIndex,
175 const bool bCreate) const
177 ::osl::MutexGuard aGuard (maMutex);
179 SharedPageDescriptor pDescriptor;
181 if (nPageIndex>=0 && nPageIndex<GetPageCount())
183 pDescriptor = maPageDescriptors[nPageIndex];
184 if (pDescriptor == NULL && bCreate && mxSlides.is())
186 SdDrawDocument* pModel = const_cast<SlideSorterModel*>(this)->GetDocument();
187 SdPage* pPage = NULL;
188 if (pModel != NULL)
190 if (meEditMode == EM_PAGE)
191 pPage = pModel->GetSdPage ((USHORT)nPageIndex, mePageKind);
192 else
193 pPage = pModel->GetMasterSdPage ((USHORT)nPageIndex, mePageKind);
195 pDescriptor.reset(new PageDescriptor (
196 Reference<drawing::XDrawPage>(mxSlides->getByIndex(nPageIndex),UNO_QUERY),
197 pPage,
198 nPageIndex,
199 GetPageObjectFactory()));
200 maPageDescriptors[nPageIndex] = pDescriptor;
204 return pDescriptor;
210 sal_Int32 SlideSorterModel::GetIndex (const Reference<drawing::XDrawPage>& rxSlide) const
212 ::osl::MutexGuard aGuard (maMutex);
214 // First try to guess the right index.
215 Reference<beans::XPropertySet> xSet (rxSlide, UNO_QUERY);
216 if (xSet.is())
220 const Any aNumber (xSet->getPropertyValue(::rtl::OUString::createFromAscii("Number")));
221 sal_Int16 nNumber (-1);
222 aNumber >>= nNumber;
223 nNumber -= 1;
224 SharedPageDescriptor pDescriptor (GetPageDescriptor(nNumber, false));
225 if (pDescriptor.get() != NULL
226 && pDescriptor->GetXDrawPage() == rxSlide)
228 return nNumber;
231 catch (beans::UnknownPropertyException&)
233 OSL_ASSERT(false);
235 catch (lang::DisposedException&)
237 OSL_ASSERT(false);
241 // Guess was wrong, iterate over all slides and search for the right
242 // one.
243 const sal_Int32 nCount (maPageDescriptors.size());
244 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
246 SharedPageDescriptor pDescriptor (maPageDescriptors[nIndex]);
248 // Make sure that the descriptor exists. Without it the given slide
249 // can not be found.
250 if (pDescriptor.get() == NULL)
252 // Call GetPageDescriptor() to create the missing descriptor.
253 pDescriptor = GetPageDescriptor(nIndex,true);
256 if (pDescriptor->GetXDrawPage() == rxSlide)
257 return nIndex;
260 return -1;
266 /** For now this method uses a trivial algorithm: throw away all descriptors
267 and create them anew (on demand). The main problem that we are facing
268 when designing a better algorithm is that we can not compare pointers to
269 pages stored in the PageDescriptor objects and those obtained from the
270 document: pages may have been deleted and others may have been created
271 at the exact same memory locations.
273 void SlideSorterModel::Resync (void)
275 ::osl::MutexGuard aGuard (maMutex);
276 ClearDescriptorList ();
277 AdaptSize();
283 void SlideSorterModel::ClearDescriptorList (void)
285 ::osl::MutexGuard aGuard (maMutex);
287 // Clear the cache of page descriptors.
288 DescriptorContainer::iterator I;
289 for (I=maPageDescriptors.begin(); I!=maPageDescriptors.end(); I++)
291 if (I->get() != NULL)
293 if ( ! I->unique())
295 OSL_TRACE("SlideSorterModel::ClearDescriptorList: trying to delete page descriptor that is still used with count %d", I->use_count());
296 // No assertion here because that can hang the office when
297 // opening a dialog from here.
299 I->reset();
307 void SlideSorterModel::SynchronizeDocumentSelection (void)
309 ::osl::MutexGuard aGuard (maMutex);
311 PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(*this));
312 while (aAllPages.HasMoreElements())
314 SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
315 pDescriptor->GetPage()->SetSelected (pDescriptor->IsSelected());
322 void SlideSorterModel::SynchronizeModelSelection (void)
324 ::osl::MutexGuard aGuard (maMutex);
326 PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(*this));
327 while (aAllPages.HasMoreElements())
329 SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
330 if (pDescriptor->GetPage()->IsSelected())
331 pDescriptor->Select ();
332 else
333 pDescriptor->Deselect ();
340 void SlideSorterModel::SetPageObjectFactory(
341 ::std::auto_ptr<controller::PageObjectFactory> pPageObjectFactory)
343 ::osl::MutexGuard aGuard (maMutex);
345 mpPageObjectFactory = pPageObjectFactory;
346 // When a NULL pointer was given then create a default factory.
347 const controller::PageObjectFactory& rFactory (GetPageObjectFactory());
348 PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(*this));
349 while (aAllPages.HasMoreElements())
351 SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
352 pDescriptor->SetPageObjectFactory(rFactory);
359 const controller::PageObjectFactory&
360 SlideSorterModel::GetPageObjectFactory (void) const
362 ::osl::MutexGuard aGuard (maMutex);
364 if (mpPageObjectFactory.get() == NULL)
366 // We have to create a new factory. The pointer is mutable so we
367 // are alowed to do so.
368 mpPageObjectFactory = ::std::auto_ptr<controller::PageObjectFactory> (
369 new controller::PageObjectFactory(
370 mrSlideSorter.GetView().GetPreviewCache(),
371 mrSlideSorter.GetController().GetProperties()));
373 return *mpPageObjectFactory.get();
379 ::osl::Mutex& SlideSorterModel::GetMutex (void)
381 return maMutex;
387 void SlideSorterModel::SetDocumentSlides (
388 const Reference<container::XIndexAccess>& rxSlides)
390 ::osl::MutexGuard aGuard (maMutex);
392 // Reset the current page so to cause everbody to release references to it.
393 mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(-1);
395 mxSlides = rxSlides;
396 Resync();
398 ViewShell* pViewShell = mrSlideSorter.GetViewShell();
399 if (pViewShell != NULL)
401 SdPage* pPage = pViewShell->getCurrentPage();
402 if (pPage != NULL)
403 mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(
404 GetIndex(Reference<drawing::XDrawPage>(pPage->getUnoPage(), UNO_QUERY)));
405 else
407 // No current page. This can only be when the slide sorter is
408 // the main view shell. Get current slide form frame view.
409 const FrameView* pFrameView = pViewShell->GetFrameView();
410 if (pFrameView != NULL)
411 mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(
412 pFrameView->GetSelectedPage());
413 else
415 // No frame view. As a last resort use the first slide as
416 // current slide.
417 mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(0);
426 Reference<container::XIndexAccess> SlideSorterModel::GetDocumentSlides (void) const
428 ::osl::MutexGuard aGuard (maMutex);
429 return mxSlides;
435 void SlideSorterModel::UpdatePageList (void)
437 ::osl::MutexGuard aGuard (maMutex);
439 Reference<container::XIndexAccess> xPages;
441 // Get the list of pages according to the edit mode.
442 Reference<frame::XController> xController (mrSlideSorter.GetXController());
443 if (xController.is())
445 switch (meEditMode)
447 case EM_MASTERPAGE:
449 Reference<drawing::XMasterPagesSupplier> xSupplier (
450 xController->getModel(), UNO_QUERY);
451 if (xSupplier.is())
453 xPages = Reference<container::XIndexAccess>(
454 xSupplier->getMasterPages(), UNO_QUERY);
457 break;
459 case EM_PAGE:
461 Reference<drawing::XDrawPagesSupplier> xSupplier (
462 xController->getModel(), UNO_QUERY);
463 if (xSupplier.is())
465 xPages = Reference<container::XIndexAccess>(
466 xSupplier->getDrawPages(), UNO_QUERY);
469 break;
471 default:
472 // We should never get here.
473 OSL_ASSERT(false);
474 break;
478 mrSlideSorter.GetController().SetDocumentSlides(xPages);
484 void SlideSorterModel::AdaptSize (void)
486 if (mxSlides.is())
487 maPageDescriptors.resize(mxSlides->getCount());
488 else
489 maPageDescriptors.resize(0);
492 } } } // end of namespace ::sd::slidesorter::model