/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 . */ #include "controller/SlideSorterController.hxx" #include "SlideSorter.hxx" #include "controller/SlsPageSelector.hxx" #include "controller/SlsSelectionFunction.hxx" #include "controller/SlsProperties.hxx" #include "controller/SlsCurrentSlideManager.hxx" #include "SlsListener.hxx" #include "controller/SlsFocusManager.hxx" #include "controller/SlsAnimator.hxx" #include "controller/SlsClipboard.hxx" #include "controller/SlsInsertionIndicatorHandler.hxx" #include "controller/SlsScrollBarManager.hxx" #include "controller/SlsSelectionManager.hxx" #include "controller/SlsSlotManager.hxx" #include "controller/SlsTransferableData.hxx" #include "controller/SlsVisibleAreaManager.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsLayouter.hxx" #include "view/SlsFontProvider.hxx" #include "view/SlsPageObjectLayouter.hxx" #include "view/SlsPageObjectPainter.hxx" #include "view/SlsTheme.hxx" #include "view/SlsToolTip.hxx" #include "cache/SlsPageCache.hxx" #include "cache/SlsPageCacheManager.hxx" #include "drawdoc.hxx" #include "DrawViewShell.hxx" #include "ViewShellBase.hxx" #include "Window.hxx" #include "FrameView.hxx" #include "DrawDocShell.hxx" #include "sdpage.hxx" #include "res_bmp.hrc" #include "sdresid.hxx" #include "strings.hrc" #include "app.hrc" #include "glob.hrc" #include "sdmod.hxx" #include "sdxfer.hxx" #include "ViewShellHint.hxx" #include "AccessibleSlideSorterView.hxx" #include "AccessibleSlideSorterObject.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::sd::slidesorter::model; using namespace ::sd::slidesorter::view; using namespace ::sd::slidesorter::controller; using namespace ::basegfx; namespace sd { namespace slidesorter { namespace controller { SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), mrModel(mrSlideSorter.GetModel()), mrView(mrSlideSorter.GetView()), mpPageSelector(), mpFocusManager(), mpSlotManager(), mpScrollBarManager(), mpCurrentSlideManager(), mpSelectionManager(), mpClipboard(), mpInsertionIndicatorHandler(new InsertionIndicatorHandler(rSlideSorter)), mpAnimator(new Animator(rSlideSorter)), mpVisibleAreaManager(new VisibleAreaManager(rSlideSorter)), mpListener(), mnModelChangeLockCount(0), mbIsForcedRearrangePending(false), mbPreModelChangeDone(false), mbPostModelChangePending(false), maSelectionBeforeSwitch(), mnCurrentPageBeforeSwitch(0), mpEditModeChangeMasterPage(NULL), maTotalWindowArea(), mnPaintEntranceCount(0), mbIsContextMenuOpen(false) { SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); OSL_ASSERT(pWindow); if (pWindow) { // The whole background is painted by the view and controls. ::Window* pParentWindow = pWindow->GetParent(); OSL_ASSERT(pParentWindow!=NULL); pParentWindow->SetBackground (Wallpaper()); // Connect the view with the window that has been created by our base // class. pWindow->SetBackground(Wallpaper()); pWindow->SetCenterAllowed(false); pWindow->SetMapMode(MapMode(MAP_PIXEL)); pWindow->SetViewSize(mrView.GetModelArea().GetSize()); } } void SlideSorterController::Init (void) { mpCurrentSlideManager.reset(new CurrentSlideManager(mrSlideSorter)); mpPageSelector.reset(new PageSelector(mrSlideSorter)); mpFocusManager.reset(new FocusManager(mrSlideSorter)); mpSlotManager.reset(new SlotManager(mrSlideSorter)); mpScrollBarManager.reset(new ScrollBarManager(mrSlideSorter)); mpSelectionManager.reset(new SelectionManager(mrSlideSorter)); mpClipboard.reset(new Clipboard(mrSlideSorter)); mpScrollBarManager->LateInitialization(); // Create the selection function. SfxRequest aRequest ( SID_OBJECT_SELECT, 0, mrModel.GetDocument()->GetItemPool()); mrSlideSorter.SetCurrentFunction(CreateSelectionFunction(aRequest)); mpListener = new Listener(mrSlideSorter); mpPageSelector->GetCoreSelection(); GetSelectionManager()->SelectionHasChanged(); } SlideSorterController::~SlideSorterController (void) { try { uno::Reference xComponent ( static_cast(mpListener.get()), uno::UNO_QUERY); if (xComponent.is()) xComponent->dispose(); } catch( uno::Exception& ) { OSL_FAIL( "sd::SlideSorterController::~SlideSorterController(), exception caught!" ); } // dispose should have been called by now so that nothing is to be done // to shut down cleanly. } void SlideSorterController::Dispose (void) { mpInsertionIndicatorHandler->End(Animator::AM_Immediate); mpClipboard.reset(); mpSelectionManager.reset(); mpAnimator->Dispose(); } model::SharedPageDescriptor SlideSorterController::GetPageAt ( const Point& aWindowPosition) { sal_Int32 nHitPageIndex (mrView.GetPageIndexAtPoint(aWindowPosition)); model::SharedPageDescriptor pDescriptorAtPoint; if (nHitPageIndex >= 0) { pDescriptorAtPoint = mrModel.GetPageDescriptor(nHitPageIndex); // Depending on a property we may have to check that the mouse is no // just over the page object but over the preview area. if (pDescriptorAtPoint && mrSlideSorter.GetProperties()->IsOnlyPreviewTriggersMouseOver() && ! pDescriptorAtPoint->HasState(PageDescriptor::ST_Selected)) { // Make sure that the mouse is over the preview area. if ( ! mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox( pDescriptorAtPoint, view::PageObjectLayouter::Preview, view::PageObjectLayouter::WindowCoordinateSystem).IsInside(aWindowPosition)) { pDescriptorAtPoint.reset(); } } } return pDescriptorAtPoint; } PageSelector& SlideSorterController::GetPageSelector (void) { OSL_ASSERT(mpPageSelector.get()!=NULL); return *mpPageSelector.get(); } FocusManager& SlideSorterController::GetFocusManager (void) { OSL_ASSERT(mpFocusManager.get()!=NULL); return *mpFocusManager.get(); } Clipboard& SlideSorterController::GetClipboard (void) { OSL_ASSERT(mpClipboard.get()!=NULL); return *mpClipboard.get(); } ScrollBarManager& SlideSorterController::GetScrollBarManager (void) { OSL_ASSERT(mpScrollBarManager.get()!=NULL); return *mpScrollBarManager.get(); } ::boost::shared_ptr SlideSorterController::GetCurrentSlideManager (void) const { OSL_ASSERT(mpCurrentSlideManager.get()!=NULL); return mpCurrentSlideManager; } ::boost::shared_ptr SlideSorterController::GetSlotManager (void) const { OSL_ASSERT(mpSlotManager.get()!=NULL); return mpSlotManager; } ::boost::shared_ptr SlideSorterController::GetSelectionManager (void) const { OSL_ASSERT(mpSelectionManager.get()!=NULL); return mpSelectionManager; } ::boost::shared_ptr SlideSorterController::GetInsertionIndicatorHandler (void) const { OSL_ASSERT(mpInsertionIndicatorHandler.get()!=NULL); return mpInsertionIndicatorHandler; } void SlideSorterController::Paint ( const Rectangle& rBBox, ::Window* pWindow) { if (mnPaintEntranceCount == 0) { ++mnPaintEntranceCount; try { mrView.CompleteRedraw(pWindow, Region(rBBox), 0); } catch (const Exception&) { // Ignore all exceptions. } --mnPaintEntranceCount; } } void SlideSorterController::FuTemporary (SfxRequest& rRequest) { mpSlotManager->FuTemporary (rRequest); } void SlideSorterController::FuPermanent (SfxRequest &rRequest) { mpSlotManager->FuPermanent (rRequest); } void SlideSorterController::FuSupport (SfxRequest &rRequest) { mpSlotManager->FuSupport (rRequest); } bool SlideSorterController::Command ( const CommandEvent& rEvent, ::sd::Window* pWindow) { bool bEventHasBeenHandled = false; if (pWindow == NULL) return false; ViewShell* pViewShell = mrSlideSorter.GetViewShell(); if (pViewShell == NULL) return false; switch (rEvent.GetCommand()) { case COMMAND_CONTEXTMENU: { SdPage* pPage = NULL; sal_uInt16 nPopupId; model::PageEnumeration aSelectedPages ( PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel)); if (aSelectedPages.HasMoreElements()) pPage = aSelectedPages.GetNextElement()->GetPage(); // Choose the popup menu depending on a) the type of the main // view shell, b) the edit mode, and c) on whether the selection // is empty or not. ViewShell::ShellType eMainViewShellType (ViewShell::ST_NONE); ::boost::shared_ptr pMainViewShell ( pViewShell->GetViewShellBase().GetMainViewShell()); if (pMainViewShell.get() != NULL) eMainViewShellType = pMainViewShell->GetShellType(); switch (eMainViewShellType) { case ViewShell::ST_DRAW: if (pPage != NULL) nPopupId = RID_SLIDE_SORTER_DRAW_SEL_POPUP; else nPopupId = RID_SLIDE_SORTER_DRAW_NOSEL_POPUP; break; default: if (mrModel.GetEditMode() == EM_PAGE) if (pPage != NULL) nPopupId = RID_SLIDE_SORTER_IMPRESS_SEL_POPUP; else nPopupId = RID_SLIDE_SORTER_IMPRESS_NOSEL_POPUP; else if (pPage != NULL) nPopupId = RID_SLIDE_SORTER_MASTER_SEL_POPUP; else nPopupId = RID_SLIDE_SORTER_MASTER_NOSEL_POPUP; } ::boost::scoped_ptr pContext; if (pPage == NULL) { // When there is no selection, then we show the insertion // indicator so that the user knows where a page insertion // would take place. mpInsertionIndicatorHandler->Start(false); mpInsertionIndicatorHandler->UpdateIndicatorIcon(SD_MOD()->pTransferClip); mpInsertionIndicatorHandler->UpdatePosition( pWindow->PixelToLogic(rEvent.GetMousePosPixel()), InsertionIndicatorHandler::MoveMode); pContext.reset(new InsertionIndicatorHandler::ForceShowContext( mpInsertionIndicatorHandler)); } pWindow->ReleaseMouse(); Point aMenuLocation (0,0); if (rEvent.IsMouseEvent()) { // We have to explicitly specify the location of the menu // when the slide sorter is placed in an undocked child // menu. But when it is docked it does not hurt, so we // specify the location always. aMenuLocation = rEvent.GetMousePosPixel(); } else { // The event is not a mouse event. Use the center of the // focused page as top left position of the context menu. model::SharedPageDescriptor pDescriptor ( GetFocusManager().GetFocusedPageDescriptor()); if (pDescriptor.get() != NULL) { Rectangle aBBox ( mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox ( pDescriptor, PageObjectLayouter::PageObject, PageObjectLayouter::ModelCoordinateSystem)); aMenuLocation = aBBox.Center(); } } mbIsContextMenuOpen = true; if (pViewShell != NULL) { SfxDispatcher* pDispatcher = pViewShell->GetDispatcher(); if (pDispatcher != NULL) { pDispatcher->ExecutePopup( SdResId(nPopupId), pWindow, &aMenuLocation); mrSlideSorter.GetView().UpdatePageUnderMouse(); ::rtl::Reference pFunction(GetCurrentSelectionFunction()); if (pFunction.is()) pFunction->ResetMouseAnchor(); } } mbIsContextMenuOpen = false; if (pPage == NULL) { // Remember the position of the insertion indicator before // it is hidden, so that a pending slide insertion slot call // finds the right place to insert a new slide. GetSelectionManager()->SetInsertionPosition( GetInsertionIndicatorHandler()->GetInsertionPageIndex()); } pContext.reset(); bEventHasBeenHandled = true; } break; case COMMAND_WHEEL: { const CommandWheelData* pData = rEvent.GetWheelData(); if (pData == NULL) return false; if (pData->IsMod1()) { // We do not support zooming with control+mouse wheel. return false; } // Determine whether to scroll horizontally or vertically. This // depends on the orientation of the scroll bar and the // IsHoriz() flag of the event. if ((mrSlideSorter.GetView().GetOrientation()==view::Layouter::HORIZONTAL) == pData->IsHorz()) { GetScrollBarManager().Scroll( ScrollBarManager::Orientation_Vertical, ScrollBarManager::Unit_Slide, -pData->GetNotchDelta()); } else { GetScrollBarManager().Scroll( ScrollBarManager::Orientation_Horizontal, ScrollBarManager::Unit_Slide, -pData->GetNotchDelta()); } mrSlideSorter.GetView().UpdatePageUnderMouse(rEvent.GetMousePosPixel()); bEventHasBeenHandled = true; } break; } return bEventHasBeenHandled; } void SlideSorterController::LockModelChange (void) { mnModelChangeLockCount += 1; } void SlideSorterController::UnlockModelChange (void) { mnModelChangeLockCount -= 1; if (mnModelChangeLockCount==0 && mbPostModelChangePending) { PostModelChange(); } } void SlideSorterController::PreModelChange (void) { // Prevent PreModelChange to execute more than once per model lock. if (mbPostModelChangePending) return; mbPreModelChangeDone = true; if (mrSlideSorter.GetViewShell() != NULL) mrSlideSorter.GetViewShell()->Broadcast( ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START)); GetCurrentSlideManager()->PrepareModelChange(); if (mrSlideSorter.GetContentWindow()) mrView.PreModelChange(); mbPostModelChangePending = true; } void SlideSorterController::PostModelChange (void) { mbPostModelChangePending = false; mrModel.Resync(); SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { GetCurrentSlideManager()->HandleModelChange(); mrView.PostModelChange (); pWindow->SetViewOrigin (Point (0,0)); pWindow->SetViewSize (mrView.GetModelArea().GetSize()); // The visibility of the scroll bars may have to be changed. Then // the size of the view has to change, too. Let Rearrange() handle // that. Rearrange(mbIsForcedRearrangePending); } if (mrSlideSorter.GetViewShell() != NULL) mrSlideSorter.GetViewShell()->Broadcast( ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END)); } void SlideSorterController::HandleModelChange (void) { // Ignore this call when the document is not in a valid state, i.e. has // not the same number of regular and notes pages. bool bIsDocumentValid = (mrModel.GetDocument()->GetPageCount() % 2 == 1); if (bIsDocumentValid) { ModelChangeLock aLock (*this); PreModelChange(); } } IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent) { if (pEvent != NULL) { ::Window* pWindow = pEvent->GetWindow(); SharedSdWindow pActiveWindow (mrSlideSorter.GetContentWindow()); switch (pEvent->GetId()) { case VCLEVENT_WINDOW_ACTIVATE: case VCLEVENT_WINDOW_SHOW: if (pActiveWindow && pWindow == pActiveWindow->GetParent()) mrView.RequestRepaint(); break; case VCLEVENT_WINDOW_HIDE: if (pActiveWindow && pWindow == pActiveWindow->GetParent()) mrView.SetPageUnderMouse(SharedPageDescriptor()); break; case VCLEVENT_WINDOW_GETFOCUS: if (pActiveWindow) if (pWindow == pActiveWindow.get()) GetFocusManager().ShowFocus(false); break; case VCLEVENT_WINDOW_LOSEFOCUS: if (pActiveWindow && pWindow == pActiveWindow.get()) { GetFocusManager().HideFocus(); mrView.GetToolTip().Hide(); // Select the current slide so that it is properly // visualized when the focus is moved to the edit view. GetPageSelector().SelectPage(GetCurrentSlideManager()->GetCurrentSlide()); } break; case VCLEVENT_APPLICATION_DATACHANGED: { // Invalidate the preview cache. cache::PageCacheManager::Instance()->InvalidateAllCaches(); // Update the draw mode. sal_uLong nDrawMode (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ? ViewShell::OUTPUT_DRAWMODE_CONTRAST : ViewShell::OUTPUT_DRAWMODE_COLOR); if (mrSlideSorter.GetViewShell() != NULL) mrSlideSorter.GetViewShell()->GetFrameView()->SetDrawMode(nDrawMode); if (pActiveWindow != 0) pActiveWindow->SetDrawMode(nDrawMode); mrView.HandleDrawModeChange(); // When the system font has changed a layout has to be done. mrView.Resize(); FontProvider::Instance().Invalidate(); // Update theme colors. mrSlideSorter.GetProperties()->HandleDataChangeEvent(); mrSlideSorter.GetTheme()->Update(mrSlideSorter.GetProperties()); mrView.HandleDataChangeEvent(); } break; default: break; } } return sal_True; } void SlideSorterController::GetCtrlState (SfxItemSet& rSet) { if (rSet.GetItemState(SID_RELOAD) != SfxItemState::UNKNOWN) { // let SFx en-/disable "last version" SfxViewFrame* pSlideViewFrame = SfxViewFrame::Current(); DBG_ASSERT(pSlideViewFrame!=NULL, "SlideSorterController::GetCtrlState: ViewFrame not found"); if (pSlideViewFrame) { pSlideViewFrame->GetSlotState (SID_RELOAD, NULL, &rSet); } else // MI says: no MDIFrame --> disable { rSet.DisableItem(SID_RELOAD); } } // Output quality. if (rSet.GetItemState(SID_OUTPUT_QUALITY_COLOR)==SfxItemState::DEFAULT ||rSet.GetItemState(SID_OUTPUT_QUALITY_GRAYSCALE)==SfxItemState::DEFAULT ||rSet.GetItemState(SID_OUTPUT_QUALITY_BLACKWHITE)==SfxItemState::DEFAULT ||rSet.GetItemState(SID_OUTPUT_QUALITY_CONTRAST)==SfxItemState::DEFAULT) { if (mrSlideSorter.GetContentWindow()) { sal_uLong nMode = mrSlideSorter.GetContentWindow()->GetDrawMode(); sal_uInt16 nQuality = 0; switch (nMode) { case ViewShell::OUTPUT_DRAWMODE_COLOR: nQuality = 0; break; case ViewShell::OUTPUT_DRAWMODE_GRAYSCALE: nQuality = 1; break; case ViewShell::OUTPUT_DRAWMODE_BLACKWHITE: nQuality = 2; break; case ViewShell::OUTPUT_DRAWMODE_CONTRAST: nQuality = 3; break; } rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_COLOR, nQuality==0)); rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_GRAYSCALE, nQuality==1)); rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_BLACKWHITE, nQuality==2)); rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_CONTRAST, nQuality==3)); } } if (rSet.GetItemState(SID_MAIL_SCROLLBODY_PAGEDOWN) == SfxItemState::DEFAULT) { rSet.Put (SfxBoolItem( SID_MAIL_SCROLLBODY_PAGEDOWN, true)); } } void SlideSorterController::GetStatusBarState (SfxItemSet& rSet) { mpSlotManager->GetStatusBarState (rSet); } void SlideSorterController::ExecCtrl (SfxRequest& rRequest) { mpSlotManager->ExecCtrl (rRequest); } void SlideSorterController::GetAttrState (SfxItemSet& rSet) { mpSlotManager->GetAttrState (rSet); } void SlideSorterController::ExecStatusBar (SfxRequest& ) { } void SlideSorterController::UpdateAllPages (void) { // Do a redraw. mrSlideSorter.GetContentWindow()->Invalidate(); } Rectangle SlideSorterController::Resize (const Rectangle& rAvailableSpace) { Rectangle aContentArea (rAvailableSpace); if (maTotalWindowArea != rAvailableSpace) { maTotalWindowArea = rAvailableSpace; aContentArea = Rearrange(true); } return aContentArea; } Rectangle SlideSorterController::Rearrange (bool bForce) { Rectangle aNewContentArea (maTotalWindowArea); if (aNewContentArea.IsEmpty()) return aNewContentArea; if (mnModelChangeLockCount>0) { mbIsForcedRearrangePending |= bForce; return aNewContentArea; } else mbIsForcedRearrangePending = false; SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { if (bForce) mrView.UpdateOrientation(); // Place the scroll bars. aNewContentArea = GetScrollBarManager().PlaceScrollBars( maTotalWindowArea, mrView.GetOrientation() != view::Layouter::VERTICAL, mrView.GetOrientation() != view::Layouter::HORIZONTAL); bool bSizeHasChanged (false); // Only when bForce is not true we have to test for a size change in // order to determine whether the window and the view have to be resized. if ( ! bForce) { Rectangle aCurrentContentArea (pWindow->GetPosPixel(), pWindow->GetOutputSizePixel()); bSizeHasChanged = (aNewContentArea != aCurrentContentArea); } if (bForce || bSizeHasChanged) { // The browser window gets the remaining space. pWindow->SetPosSizePixel (aNewContentArea.TopLeft(), aNewContentArea.GetSize()); mrView.Resize(); } // Adapt the scroll bars to the new zoom factor of the browser // window and the arrangement of the page objects. GetScrollBarManager().UpdateScrollBars(false, !bForce); // Keep the current slide in the visible area. GetVisibleAreaManager().RequestCurrentSlideVisible(); mrView.RequestRepaint(); } return aNewContentArea; } rtl::Reference SlideSorterController::CreateSelectionFunction (SfxRequest& rRequest) { rtl::Reference xFunc( SelectionFunction::Create(mrSlideSorter, rRequest) ); return xFunc; } ::rtl::Reference SlideSorterController::GetCurrentSelectionFunction (void) { rtl::Reference pFunction (mrSlideSorter.GetViewShell()->GetCurrentFunction()); return ::rtl::Reference(dynamic_cast(pFunction.get())); } void SlideSorterController::PrepareEditModeChange (void) { // Before we throw away the page descriptors we prepare for selecting // descriptors in the other mode and for restoring the current // selection when switching back to the current mode. if (mrModel.GetEditMode() == EM_PAGE) { maSelectionBeforeSwitch.clear(); // Search for the first selected page and determine the master page // used by its page object. It will be selected after the switch. // In the same loop the current selection is stored. PageEnumeration aSelectedPages ( PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel)); while (aSelectedPages.HasMoreElements()) { SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); SdPage* pPage = pDescriptor->GetPage(); // Remember the master page of the first selected descriptor. if (pPage!=NULL && mpEditModeChangeMasterPage==NULL) mpEditModeChangeMasterPage = &static_cast( pPage->TRG_GetMasterPage()); maSelectionBeforeSwitch.push_back(pPage); } // Remember the current page. if (mrSlideSorter.GetViewShell() != NULL) mnCurrentPageBeforeSwitch = (mrSlideSorter.GetViewShell()->GetViewShellBase() .GetMainViewShell()->GetActualPage()->GetPageNum()-1)/2; } } bool SlideSorterController::ChangeEditMode (EditMode eEditMode) { bool bResult (false); if (mrModel.GetEditMode() != eEditMode) { ModelChangeLock aLock (*this); PreModelChange(); // Do the actual edit mode switching. bResult = mrModel.SetEditMode(eEditMode); if (bResult) HandleModelChange(); } return bResult; } 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)); while (aAllPages.HasMoreElements()) { SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); 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::iterator iPage; for (iPage=maSelectionBeforeSwitch.begin(); iPage!=maSelectionBeforeSwitch.end(); ++iPage) { mpPageSelector->SelectPage(*iPage); } maSelectionBeforeSwitch.clear( ); } mpEditModeChangeMasterPage = NULL; } void SlideSorterController::PageNameHasChanged (int nPageIndex, const OUString& rsOldName) { // Request a repaint for the page object whose name has changed. model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); if (pDescriptor.get() != NULL) mrView.RequestRepaint(pDescriptor); // Get a pointer to the corresponding accessible object and notify // that of the name change. SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if ( ! pWindow) return; ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAccessible (pWindow->GetAccessible(false)); if ( ! xAccessible.is()) return; // Now comes a small hack. We assume that the accessible object is // an instantiation of AccessibleSlideSorterView and cast it to that // class. The cleaner alternative to this cast would be a new member // in which we would store the last AccessibleSlideSorterView object // created by SlideSorterViewShell::CreateAccessibleDocumentView(). // But then there is no guaranty that the accessible object obtained // from the window really is that instance last created by // CreateAccessibleDocumentView(). // However, the dynamic cast together with the check of the result // being NULL should be safe enough. ::accessibility::AccessibleSlideSorterView* pAccessibleView = dynamic_cast< ::accessibility::AccessibleSlideSorterView*>(xAccessible.get()); if (pAccessibleView == NULL) return; ::accessibility::AccessibleSlideSorterObject* pChild = pAccessibleView->GetAccessibleChildImplementation(nPageIndex); if (pChild == NULL || pChild->GetPage() == NULL) return; OUString sOldName (rsOldName); OUString sNewName (pChild->GetPage()->GetName()); pChild->FireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::NAME_CHANGED, makeAny(sOldName), makeAny(sNewName)); } void SlideSorterController::SetDocumentSlides (const Reference& rxSlides) { if (mrModel.GetDocumentSlides() != rxSlides) { ModelChangeLock aLock (*this); PreModelChange(); mrModel.SetDocumentSlides(rxSlides); } } VisibleAreaManager& SlideSorterController::GetVisibleAreaManager (void) const { OSL_ASSERT(mpVisibleAreaManager); return *mpVisibleAreaManager; } void SlideSorterController::CheckForMasterPageAssignment (void) { if (mrModel.GetPageCount()%2==0) return; PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); while (aAllPages.HasMoreElements()) { SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); if (pDescriptor->UpdateMasterPage()) { mrView.GetPreviewCache()->InvalidatePreviewBitmap ( pDescriptor->GetPage(), true); } } } void SlideSorterController::CheckForSlideTransitionAssignment (void) { if (mrModel.GetPageCount()%2==0) return; PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); while (aAllPages.HasMoreElements()) { SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); if (pDescriptor->UpdateTransitionFlag()) { mrView.GetPreviewCache()->InvalidatePreviewBitmap ( pDescriptor->GetPage(), true); } } } //===== SlideSorterController::ModelChangeLock ================================ SlideSorterController::ModelChangeLock::ModelChangeLock ( SlideSorterController& rController) : mpController(&rController) { mpController->LockModelChange(); } SlideSorterController::ModelChangeLock::~ModelChangeLock (void) { Release(); } void SlideSorterController::ModelChangeLock::Release (void) { if (mpController != NULL) { mpController->UnlockModelChange(); mpController = NULL; } } } } } // end of namespace ::sd::slidesorter /* vim:set shiftwidth=4 softtabstop=4 expandtab: */