| /************************************************************** |
| * |
| * 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 "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 "SlsSelectionCommand.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 "TextLogger.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 "FrameView.hxx" |
| #include "ViewShellHint.hxx" |
| #include "AccessibleSlideSorterView.hxx" |
| #include "AccessibleSlideSorterObject.hxx" |
| |
| #include <vcl/window.hxx> |
| #include <svx/svdopage.hxx> |
| #include <svx/svxids.hrc> |
| #include <svx/ruler.hxx> |
| #include <svx/zoomitem.hxx> |
| #include <svtools/tabbar.hxx> |
| #include <sfx2/request.hxx> |
| #include <sfx2/viewfrm.hxx> |
| #include <sfx2/dispatch.hxx> |
| #include <tools/link.hxx> |
| #include <vcl/svapp.hxx> |
| |
| #include <com/sun/star/lang/XComponent.hpp> |
| #include <com/sun/star/drawing/XMasterPagesSupplier.hpp> |
| #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> |
| #include <com/sun/star/drawing/XDrawPages.hpp> |
| #include <com/sun/star/accessibility/AccessibleEventId.hpp> |
| |
| 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(), |
| mpClipboard(), |
| mpScrollBarManager(), |
| mpCurrentSlideManager(), |
| mpSelectionManager(), |
| 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)); |
| mpClipboard.reset(new Clipboard(mrSlideSorter)); |
| mpScrollBarManager.reset(new ScrollBarManager(mrSlideSorter)); |
| mpSelectionManager.reset(new SelectionManager(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<lang::XComponent> xComponent ( |
| static_cast<XWeak*>(mpListener.get()), uno::UNO_QUERY); |
| if (xComponent.is()) |
| xComponent->dispose(); |
| } |
| catch( uno::Exception& e ) |
| { |
| (void)e; |
| DBG_ERROR( "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); |
| 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<CurrentSlideManager> SlideSorterController::GetCurrentSlideManager (void) const |
| { |
| OSL_ASSERT(mpCurrentSlideManager.get()!=NULL); |
| return mpCurrentSlideManager; |
| } |
| |
| |
| |
| |
| ::boost::shared_ptr<SlotManager> SlideSorterController::GetSlotManager (void) const |
| { |
| OSL_ASSERT(mpSlotManager.get()!=NULL); |
| return mpSlotManager; |
| } |
| |
| |
| |
| |
| ::boost::shared_ptr<SelectionManager> SlideSorterController::GetSelectionManager (void) const |
| { |
| OSL_ASSERT(mpSelectionManager.get()!=NULL); |
| return mpSelectionManager; |
| } |
| |
| |
| |
| |
| ::boost::shared_ptr<InsertionIndicatorHandler> |
| 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<ViewShell> 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<InsertionIndicatorHandler::ForceShowContext> 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(false); |
| ::rtl::Reference<SelectionFunction> 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(), false); |
| |
| 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( bool(pActiveWindow) ) |
| 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) != SFX_ITEM_UNKNOWN) |
| { |
| // "Letzte Version" vom SFx en/disablen lassen |
| SfxViewFrame* pSlideViewFrame = SfxViewFrame::Current(); |
| DBG_ASSERT(pSlideViewFrame!=NULL, |
| "SlideSorterController::GetCtrlState: ViewFrame not found"); |
| if (pSlideViewFrame) |
| { |
| pSlideViewFrame->GetSlotState (SID_RELOAD, NULL, &rSet); |
| } |
| else // MI sagt: kein MDIFrame --> disablen |
| { |
| rSet.DisableItem(SID_RELOAD); |
| } |
| } |
| |
| // Output quality. |
| if (rSet.GetItemState(SID_OUTPUT_QUALITY_COLOR)==SFX_ITEM_AVAILABLE |
| ||rSet.GetItemState(SID_OUTPUT_QUALITY_GRAYSCALE)==SFX_ITEM_AVAILABLE |
| ||rSet.GetItemState(SID_OUTPUT_QUALITY_BLACKWHITE)==SFX_ITEM_AVAILABLE |
| ||rSet.GetItemState(SID_OUTPUT_QUALITY_CONTRAST)==SFX_ITEM_AVAILABLE) |
| { |
| 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, |
| (sal_Bool)(nQuality==0))); |
| rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_GRAYSCALE, |
| (sal_Bool)(nQuality==1))); |
| rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_BLACKWHITE, |
| (sal_Bool)(nQuality==2))); |
| rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_CONTRAST, |
| (sal_Bool)(nQuality==3))); |
| } |
| } |
| |
| if (rSet.GetItemState(SID_MAIL_SCROLLBODY_PAGEDOWN) == SFX_ITEM_AVAILABLE) |
| { |
| rSet.Put (SfxBoolItem( SID_MAIL_SCROLLBODY_PAGEDOWN, sal_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; |
| } |
| |
| |
| |
| |
| FunctionReference SlideSorterController::CreateSelectionFunction (SfxRequest& rRequest) |
| { |
| FunctionReference xFunc( SelectionFunction::Create(mrSlideSorter, rRequest) ); |
| return xFunc; |
| } |
| |
| |
| |
| |
| ::rtl::Reference<SelectionFunction> SlideSorterController::GetCurrentSelectionFunction (void) |
| { |
| FunctionReference pFunction (mrSlideSorter.GetViewShell()->GetCurrentFunction()); |
| return ::rtl::Reference<SelectionFunction>(dynamic_cast<SelectionFunction*>(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<SdPage&>( |
| 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<SdPage*>::iterator iPage; |
| for (iPage=maSelectionBeforeSwitch.begin(); |
| iPage!=maSelectionBeforeSwitch.end(); |
| ++iPage) |
| { |
| mpPageSelector->SelectPage(*iPage); |
| } |
| maSelectionBeforeSwitch.clear( ); |
| } |
| mpEditModeChangeMasterPage = NULL; |
| } |
| |
| |
| |
| |
| void SlideSorterController::PageNameHasChanged (int nPageIndex, const String& 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. |
| do |
| { |
| SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); |
| if ( ! pWindow) |
| break; |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > |
| xAccessible (pWindow->GetAccessible(sal_False)); |
| if ( ! xAccessible.is()) |
| break; |
| |
| // 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) |
| break; |
| |
| ::accessibility::AccessibleSlideSorterObject* pChild |
| = pAccessibleView->GetAccessibleChildImplementation(nPageIndex); |
| if (pChild == NULL || pChild->GetPage() == NULL) |
| break; |
| |
| ::rtl::OUString sOldName (rsOldName); |
| ::rtl::OUString sNewName (pChild->GetPage()->GetName()); |
| pChild->FireAccessibleEvent( |
| ::com::sun::star::accessibility::AccessibleEventId::NAME_CHANGED, |
| makeAny(sOldName), |
| makeAny(sNewName)); |
| } |
| while (false); |
| } |
| |
| |
| |
| |
| bool SlideSorterController::IsContextMenuOpen (void) const |
| { |
| return mbIsContextMenuOpen; |
| } |
| |
| |
| |
| |
| void SlideSorterController::SetDocumentSlides (const Reference<container::XIndexAccess>& rxSlides) |
| { |
| if (mrModel.GetDocumentSlides() != rxSlides) |
| { |
| ModelChangeLock aLock (*this); |
| PreModelChange(); |
| |
| mrModel.SetDocumentSlides(rxSlides); |
| } |
| } |
| |
| |
| |
| |
| ::boost::shared_ptr<Animator> SlideSorterController::GetAnimator (void) const |
| { |
| return mpAnimator; |
| } |
| |
| |
| |
| |
| 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 |