From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- sd/source/ui/slidesorter/shell/SlideSorter.cxx | 456 ++++++++++ .../ui/slidesorter/shell/SlideSorterService.cxx | 412 +++++++++ .../ui/slidesorter/shell/SlideSorterService.hxx | 153 ++++ .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 924 +++++++++++++++++++++ 4 files changed, 1945 insertions(+) create mode 100644 sd/source/ui/slidesorter/shell/SlideSorter.cxx create mode 100644 sd/source/ui/slidesorter/shell/SlideSorterService.cxx create mode 100644 sd/source/ui/slidesorter/shell/SlideSorterService.hxx create mode 100644 sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx (limited to 'sd/source/ui/slidesorter/shell') diff --git a/sd/source/ui/slidesorter/shell/SlideSorter.cxx b/sd/source/ui/slidesorter/shell/SlideSorter.cxx new file mode 100644 index 000000000..550a40469 --- /dev/null +++ b/sd/source/ui/slidesorter/shell/SlideSorter.cxx @@ -0,0 +1,456 @@ +/* -*- 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 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; + +namespace sd::slidesorter { + +namespace { +class ContentWindow : public ::sd::Window +{ +public: + ContentWindow(vcl::Window& rParent, SlideSorter& rSlideSorter); + + void SetCurrentFunction (const rtl::Reference& rpFunction); + virtual void Paint(vcl::RenderContext& /*rRenderContext*/, const ::tools::Rectangle& rRect) override; + virtual void KeyInput (const KeyEvent& rEvent) override; + virtual void MouseMove (const MouseEvent& rEvent) override; + virtual void MouseButtonUp (const MouseEvent& rEvent) override; + virtual void MouseButtonDown (const MouseEvent& rEvent) override; + virtual void Command (const CommandEvent& rEvent) override; + virtual bool EventNotify (NotifyEvent& rEvent) override; + +private: + SlideSorter& mrSlideSorter; + rtl::Reference mpCurrentFunction; +}; +} + +//===== SlideSorter =========================================================== + +std::shared_ptr SlideSorter::CreateSlideSorter( + ViewShell& rViewShell, + sd::Window* pContentWindow, + ScrollBar* pHorizontalScrollBar, + ScrollBar* pVerticalScrollBar, + ScrollBarBox* pScrollBarBox) +{ + std::shared_ptr pSlideSorter( + new SlideSorter( + rViewShell, + pContentWindow, + pHorizontalScrollBar, + pVerticalScrollBar, + pScrollBarBox), + o3tl::default_delete()); + pSlideSorter->Init(); + return pSlideSorter; +} + +std::shared_ptr SlideSorter::CreateSlideSorter ( + ViewShellBase& rBase, + vcl::Window& rParentWindow) +{ + std::shared_ptr pSlideSorter( + new SlideSorter( + rBase, + rParentWindow), + o3tl::default_delete()); + pSlideSorter->Init(); + return pSlideSorter; +} + +SlideSorter::SlideSorter ( + ViewShell& rViewShell, + sd::Window* pContentWindow, + ScrollBar* pHorizontalScrollBar, + ScrollBar* pVerticalScrollBar, + ScrollBarBox* pScrollBarBox) + : mbIsValid(false), + mpViewShell(&rViewShell), + mpViewShellBase(&rViewShell.GetViewShellBase()), + mpContentWindow(pContentWindow), + mpHorizontalScrollBar(pHorizontalScrollBar), + mpVerticalScrollBar(pVerticalScrollBar), + mpScrollBarBox(pScrollBarBox), + mpProperties(std::make_shared()), + mpTheme(std::make_shared(mpProperties)) +{ +} + +SlideSorter::SlideSorter ( + ViewShellBase& rBase, + vcl::Window& rParentWindow) + : mbIsValid(false), + mpViewShell(nullptr), + mpViewShellBase(&rBase), + mpContentWindow(VclPtr::Create(rParentWindow,*this )), + mpHorizontalScrollBar(VclPtr::Create(&rParentWindow,WinBits(WB_HSCROLL | WB_DRAG))), + mpVerticalScrollBar(VclPtr::Create(&rParentWindow,WinBits(WB_VSCROLL | WB_DRAG))), + mpScrollBarBox(VclPtr::Create(&rParentWindow)), + mpProperties(std::make_shared()), + mpTheme(std::make_shared(mpProperties)) +{ +} + +void SlideSorter::Init() +{ + if (mpViewShellBase != nullptr) + mxControllerWeak = mpViewShellBase->GetController(); + + // Reinitialize colors in Properties with window specific values. + if (mpContentWindow) + { + mpProperties->SetBackgroundColor( + mpContentWindow->GetSettings().GetStyleSettings().GetWindowColor()); + mpProperties->SetTextColor( + mpContentWindow->GetSettings().GetStyleSettings().GetWindowTextColor()); + mpProperties->SetSelectionColor( + mpContentWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor()); + mpProperties->SetHighlightColor( + mpContentWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor()); + } + + CreateModelViewController (); + + SetupListeners (); + + // Initialize the window. + sd::Window *pContentWindow = GetContentWindow().get(); + if (!pContentWindow) + return; + + vcl::Window* pParentWindow = pContentWindow->GetParent(); + if (pParentWindow != nullptr) + pParentWindow->SetBackground(Wallpaper()); + pContentWindow->SetBackground(Wallpaper()); + pContentWindow->SetViewOrigin (Point(0,0)); + // We do our own scrolling while dragging a page selection. + pContentWindow->SetUseDropScroll (false); + // Change the winbits so that the active window accepts the focus. + pContentWindow->SetStyle ((pContentWindow->GetStyle() & ~WB_DIALOGCONTROL) | WB_TABSTOP); + pContentWindow->Hide(); + + // Set view pointer of base class. + SetupControls(); + + mbIsValid = true; +} + +SlideSorter::~SlideSorter() +{ + mbIsValid = false; + + ReleaseListeners(); + + // Dispose model, view and controller to avoid calls between them when + // they are being destructed and one or two of them are already gone. + mpSlideSorterController->Dispose(); + mpSlideSorterView->Dispose(); + mpSlideSorterModel->Dispose(); + + // Reset the auto pointers explicitly to control the order of destruction. + mpSlideSorterController.reset(); + mpSlideSorterView.reset(); + mpSlideSorterModel.reset(); + + mpHorizontalScrollBar.reset(); + mpVerticalScrollBar.reset(); + mpScrollBarBox.reset(); +} + +model::SlideSorterModel& SlideSorter::GetModel() const +{ + assert(mpSlideSorterModel); + return *mpSlideSorterModel; +} + +view::SlideSorterView& SlideSorter::GetView() const +{ + assert(mpSlideSorterView); + return *mpSlideSorterView; +} + +controller::SlideSorterController& SlideSorter::GetController() const +{ + assert(mpSlideSorterController); + return *mpSlideSorterController; +} + +Reference SlideSorter::GetXController() const +{ + Reference xController(mxControllerWeak); + return xController; +} + +void SlideSorter::Paint (const ::tools::Rectangle& rRepaintArea) +{ + GetController().Paint( + rRepaintArea, + GetContentWindow()); +} + +void SlideSorter::SetupControls() +{ + GetVerticalScrollBar()->Show(); +} + +void SlideSorter::SetupListeners() +{ + sd::Window *pWindow = GetContentWindow().get(); + if (pWindow) + { + vcl::Window* pParentWindow = pWindow->GetParent(); + if (pParentWindow != nullptr) + pParentWindow->AddEventListener( + LINK( + mpSlideSorterController.get(), + controller::SlideSorterController, + WindowEventHandler)); + pWindow->AddEventListener( + LINK( + mpSlideSorterController.get(), + controller::SlideSorterController, + WindowEventHandler)); + } + Application::AddEventListener( + LINK( + mpSlideSorterController.get(), + controller::SlideSorterController, + ApplicationEventHandler)); + + mpSlideSorterController->GetScrollBarManager().Connect(); +} + +void SlideSorter::ReleaseListeners() +{ + mpSlideSorterController->GetScrollBarManager().Disconnect(); + + sd::Window *pWindow (GetContentWindow().get()); + if (pWindow) + { + pWindow->RemoveEventListener( + LINK(mpSlideSorterController.get(), + controller::SlideSorterController, + WindowEventHandler)); + + vcl::Window* pParentWindow = pWindow->GetParent(); + if (pParentWindow != nullptr) + pParentWindow->RemoveEventListener( + LINK(mpSlideSorterController.get(), + controller::SlideSorterController, + WindowEventHandler)); + } + Application::RemoveEventListener( + LINK(mpSlideSorterController.get(), + controller::SlideSorterController, + ApplicationEventHandler)); +} + +void SlideSorter::CreateModelViewController() +{ + mpSlideSorterModel.reset(CreateModel()); + DBG_ASSERT(mpSlideSorterModel != nullptr, "Can not create model for slide browser"); + + mpSlideSorterView.reset(new view::SlideSorterView (*this)); + mpSlideSorterController.reset(new controller::SlideSorterController(*this)); + + // Now that model, view, and controller are constructed, do the + // initialization that relies on all three being in place. + mpSlideSorterController->Init(); + mpSlideSorterView->Init(); +} + +model::SlideSorterModel* SlideSorter::CreateModel() +{ + // Get pointers to the document. + ViewShellBase* pViewShellBase = GetViewShellBase(); + if (pViewShellBase != nullptr) + { + assert (pViewShellBase->GetDocument() != nullptr); + + return new model::SlideSorterModel(*this); + } + else + return nullptr; +} + +void SlideSorter::ArrangeGUIElements ( + const Point& rOffset, + const Size& rSize) +{ + Point aOrigin (rOffset); + + if (rSize.Width()>0 + && rSize.Height()>0 + && GetContentWindow() + && GetContentWindow()->IsVisible()) + { + // Prevent untimely redraws while the view is not yet correctly + // resized. + view::SlideSorterView::DrawLock aLock (*this); + GetContentWindow()->EnablePaint (false); + + mpSlideSorterController->Resize (::tools::Rectangle(aOrigin, rSize)); + + GetContentWindow()->EnablePaint (true); + } +} + +void SlideSorter::RelocateToWindow (vcl::Window* pParentWindow) +{ + // Stop all animations for they have been started for the old window. + mpSlideSorterController->GetAnimator()->RemoveAllAnimations(); + + ReleaseListeners(); + + if (mpViewShell) + { + mpViewShell->ViewShell::RelocateToParentWindow(pParentWindow); + } + + SetupControls(); + SetupListeners(); + + // For accessibility we have to shortly hide the content window. This + // triggers the construction of a new accessibility object for the new + // view shell. (One is created earlier while the constructor of the base + // class is executed. But because at that time the correct + // accessibility object can not be constructed we do that now.) + if (mpContentWindow) + { + mpContentWindow->Hide(); + mpContentWindow->Show(); + } +} + +void SlideSorter::SetCurrentFunction (const rtl::Reference& rpFunction) +{ + if (GetViewShell() != nullptr) + { + GetViewShell()->SetCurrentFunction(rpFunction); + GetViewShell()->SetOldFunction(rpFunction); + } + else + { + ContentWindow* pWindow = dynamic_cast(GetContentWindow().get()); + if (pWindow != nullptr) + pWindow->SetCurrentFunction(rpFunction); + } +} + +std::shared_ptr const & SlideSorter::GetProperties() const +{ + assert(mpProperties); + return mpProperties; +} + +std::shared_ptr const & SlideSorter::GetTheme() const +{ + assert(mpTheme); + return mpTheme; +} + +//===== ContentWindow ========================================================= + +namespace { + +ContentWindow::ContentWindow( + vcl::Window& rParent, + SlideSorter& rSlideSorter) + : ::sd::Window(&rParent), + mrSlideSorter(rSlideSorter) +{ + SetDialogControlFlags(GetDialogControlFlags() & ~DialogControlFlags::WantFocus); + SetStyle(GetStyle() | WB_NOPOINTERFOCUS); +} + +void ContentWindow::SetCurrentFunction (const rtl::Reference& rpFunction) +{ + mpCurrentFunction = rpFunction; +} + +void ContentWindow::Paint (vcl::RenderContext& /*rRenderContext*/, const ::tools::Rectangle& rRect) +{ + mrSlideSorter.Paint(rRect); +} + +void ContentWindow::KeyInput (const KeyEvent& rEvent) +{ + if (mpCurrentFunction.is()) + mpCurrentFunction->KeyInput(rEvent); +} + +void ContentWindow::MouseMove (const MouseEvent& rEvent) +{ + if (mpCurrentFunction.is()) + mpCurrentFunction->MouseMove(rEvent); +} + +void ContentWindow::MouseButtonUp(const MouseEvent& rEvent) +{ + if (mpCurrentFunction.is()) + mpCurrentFunction->MouseButtonUp(rEvent); +} + +void ContentWindow::MouseButtonDown(const MouseEvent& rEvent) +{ + if (mpCurrentFunction.is()) + mpCurrentFunction->MouseButtonDown(rEvent); +} + +void ContentWindow::Command(const CommandEvent& rEvent) +{ + if (mpCurrentFunction.is()) + mpCurrentFunction->Command(rEvent); +} + +bool ContentWindow::EventNotify(NotifyEvent&) +{ + return false; +} + +} // end of anonymous namespace + +} // end of namespace ::sd::slidesorter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/slidesorter/shell/SlideSorterService.cxx b/sd/source/ui/slidesorter/shell/SlideSorterService.cxx new file mode 100644 index 000000000..a086f3b9e --- /dev/null +++ b/sd/source/ui/slidesorter/shell/SlideSorterService.cxx @@ -0,0 +1,412 @@ +/* -*- 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 "SlideSorterService.hxx" +#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 ::com::sun::star::drawing::framework; +using ::sd::slidesorter::view::Layouter; + +namespace sd::slidesorter { + +//===== SlideSorterService ========================================================== + +SlideSorterService::SlideSorterService() +{ +} + +SlideSorterService::~SlideSorterService() +{ +} + +void SlideSorterService::disposing(std::unique_lock&) +{ + mpSlideSorter.reset(); + + if (mxParentWindow.is()) + { + mxParentWindow->removeWindowListener(this); + } +} + +//----- XInitialization ------------------------------------------------------- + +void SAL_CALL SlideSorterService::initialize (const Sequence& rArguments) +{ + ThrowIfDisposed(); + + if (rArguments.getLength() != 3) + { + throw RuntimeException("SlideSorterService: invalid number of arguments", + static_cast(this)); + } + + mxViewId.set(rArguments[0], UNO_QUERY_THROW); + + // Get the XController. + Reference xController (rArguments[1], UNO_QUERY_THROW); + + // Tunnel through the controller to obtain a ViewShellBase. + ViewShellBase* pBase = nullptr; + Reference xTunnel (xController, UNO_QUERY_THROW); + ::sd::DrawController* pController = comphelper::getFromUnoTunnel(xTunnel); + if (pController != nullptr) + pBase = pController->GetViewShellBase(); + + // Get the parent window. + mxParentWindow.set(rArguments[2], UNO_QUERY_THROW); + VclPtr pParentWindow = VCLUnoHelper::GetWindow(mxParentWindow); + + mxParentWindow->addWindowListener(this); + + if (pBase != nullptr && pParentWindow) + mpSlideSorter = SlideSorter::CreateSlideSorter( + *pBase, + *pParentWindow); + + Resize(); +} + +//----- XView ----------------------------------------------------------------- + +Reference SAL_CALL SlideSorterService::getResourceId() +{ + return mxViewId; +} + +sal_Bool SAL_CALL SlideSorterService::isAnchorOnly() +{ + return false; +} + +//----- XWindowListener ------------------------------------------------------- + +void SAL_CALL SlideSorterService::windowResized (const awt::WindowEvent&) +{ + ThrowIfDisposed(); + + Resize(); +} + +void SAL_CALL SlideSorterService::windowMoved (const awt::WindowEvent&) {} + +void SAL_CALL SlideSorterService::windowShown (const lang::EventObject&) +{ + ThrowIfDisposed(); + Resize(); +} + +void SAL_CALL SlideSorterService::windowHidden (const lang::EventObject&) +{ + ThrowIfDisposed(); +} + +//----- lang::XEventListener -------------------------------------------------- + +void SAL_CALL SlideSorterService::disposing (const lang::EventObject& rEvent) +{ + if (rEvent.Source == mxParentWindow) + mxParentWindow = nullptr; +} + +//----- XDrawView ------------------------------------------------------------- + +void SAL_CALL SlideSorterService::setCurrentPage(const Reference& rxSlide) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr) + mpSlideSorter->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange( + mpSlideSorter->GetModel().GetIndex(rxSlide)); +} + +Reference SAL_CALL SlideSorterService::getCurrentPage() +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr) + return mpSlideSorter->GetController().GetCurrentSlideManager()->GetCurrentSlide()->GetXDrawPage(); + else + return nullptr; +} + +//----- attributes ------------------------------------------------------------ + +Reference SAL_CALL SlideSorterService::getDocumentSlides() +{ + return mpSlideSorter->GetModel().GetDocumentSlides(); +} + +void SAL_CALL SlideSorterService::setDocumentSlides ( + const Reference& rxSlides) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetController().SetDocumentSlides(rxSlides); +} + +sal_Bool SAL_CALL SlideSorterService::getIsHighlightCurrentSlide() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return false; + else + return mpSlideSorter->GetProperties()->IsHighlightCurrentSlide(); +} + +void SAL_CALL SlideSorterService::setIsHighlightCurrentSlide (sal_Bool bValue) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + { + mpSlideSorter->GetProperties()->SetHighlightCurrentSlide(bValue); + controller::SlideSorterController::ModelChangeLock aLock (mpSlideSorter->GetController()); + mpSlideSorter->GetController().HandleModelChange(); + } +} + +sal_Bool SAL_CALL SlideSorterService::getIsShowSelection() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return false; + else + return mpSlideSorter->GetProperties()->IsShowSelection(); +} + +void SAL_CALL SlideSorterService::setIsShowSelection (sal_Bool bValue) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetProperties()->SetShowSelection(bValue); +} + +sal_Bool SAL_CALL SlideSorterService::getIsShowFocus() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return false; + else + return mpSlideSorter->GetProperties()->IsShowFocus(); +} + +void SAL_CALL SlideSorterService::setIsShowFocus (sal_Bool bValue) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetProperties()->SetShowFocus(bValue); +} + +sal_Bool SAL_CALL SlideSorterService::getIsCenterSelection() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return false; + else + return mpSlideSorter->GetProperties()->IsCenterSelection(); +} + +void SAL_CALL SlideSorterService::setIsCenterSelection (sal_Bool bValue) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetProperties()->SetCenterSelection(bValue); +} + +sal_Bool SAL_CALL SlideSorterService::getIsSuspendPreviewUpdatesDuringFullScreenPresentation() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return true; + else + return mpSlideSorter->GetProperties() + ->IsSuspendPreviewUpdatesDuringFullScreenPresentation(); +} + +void SAL_CALL SlideSorterService::setIsSuspendPreviewUpdatesDuringFullScreenPresentation ( + sal_Bool bValue) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetProperties() + ->SetSuspendPreviewUpdatesDuringFullScreenPresentation(bValue); +} + +sal_Bool SAL_CALL SlideSorterService::getIsOrientationVertical() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return true; + else + return mpSlideSorter->GetView().GetOrientation() != Layouter::HORIZONTAL; +} + +void SAL_CALL SlideSorterService::setIsOrientationVertical (sal_Bool bValue) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetView().SetOrientation(bValue + ? Layouter::GRID + : Layouter::HORIZONTAL); +} + +sal_Bool SAL_CALL SlideSorterService::getIsSmoothScrolling() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return false; + else + return mpSlideSorter->GetProperties()->IsSmoothSelectionScrolling(); +} + +void SAL_CALL SlideSorterService::setIsSmoothScrolling (sal_Bool bValue) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetProperties()->SetSmoothSelectionScrolling(bValue); +} + +sal_Int32 SAL_CALL SlideSorterService::getBackgroundColor() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return util::Color(); + else + return util::Color( + mpSlideSorter->GetProperties()->GetBackgroundColor()); +} + +void SAL_CALL SlideSorterService::setBackgroundColor (sal_Int32 aBackgroundColor) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetProperties()->SetBackgroundColor(Color(ColorTransparency, aBackgroundColor)); +} + +sal_Int32 SAL_CALL SlideSorterService::getTextColor() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return util::Color(); + else + return util::Color( + mpSlideSorter->GetProperties()->GetTextColor()); +} + +void SAL_CALL SlideSorterService::setTextColor (sal_Int32 aTextColor) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetProperties()->SetTextColor(Color(ColorTransparency, aTextColor)); +} + +sal_Int32 SAL_CALL SlideSorterService::getSelectionColor() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return util::Color(); + else + return util::Color( + mpSlideSorter->GetProperties()->GetSelectionColor()); +} + +void SAL_CALL SlideSorterService::setSelectionColor (sal_Int32 aSelectionColor) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetProperties()->SetSelectionColor(Color(ColorTransparency, aSelectionColor)); +} + +sal_Int32 SAL_CALL SlideSorterService::getHighlightColor() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return util::Color(); + else + return util::Color( + mpSlideSorter->GetProperties()->GetHighlightColor()); +} + +void SAL_CALL SlideSorterService::setHighlightColor (sal_Int32 aHighlightColor) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetProperties()->SetHighlightColor(Color(ColorTransparency, aHighlightColor)); +} + +sal_Bool SAL_CALL SlideSorterService::getIsUIReadOnly() +{ + ThrowIfDisposed(); + if (mpSlideSorter == nullptr || !mpSlideSorter->IsValid()) + return true; + else + return mpSlideSorter->GetProperties()->IsUIReadOnly(); +} + +void SAL_CALL SlideSorterService::setIsUIReadOnly (sal_Bool bIsUIReadOnly) +{ + ThrowIfDisposed(); + if (mpSlideSorter != nullptr && mpSlideSorter->IsValid()) + mpSlideSorter->GetProperties()->SetUIReadOnly(bIsUIReadOnly); +} + +void SlideSorterService::Resize() +{ + if (mxParentWindow.is()) + { + awt::Rectangle aWindowBox = mxParentWindow->getPosSize(); + mpSlideSorter->ArrangeGUIElements( + Point(0,0), + Size(aWindowBox.Width, aWindowBox.Height)); + } +} + +void SlideSorterService::ThrowIfDisposed() +{ + if (SlideSorterServiceInterfaceBase::m_bDisposed) + { + throw lang::DisposedException ("SlideSorterService object has already been disposed", + static_cast(this)); + } +} + +} // end of namespace ::sd::slidesorter + + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_comp_Draw_SlideSorter_get_implementation(css::uno::XComponentContext* /*context*/, + css::uno::Sequence const &) +{ + return cppu::acquire(new sd::slidesorter::SlideSorterService); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/slidesorter/shell/SlideSorterService.hxx b/sd/source/ui/slidesorter/shell/SlideSorterService.hxx new file mode 100644 index 000000000..579a5bae5 --- /dev/null +++ b/sd/source/ui/slidesorter/shell/SlideSorterService.hxx @@ -0,0 +1,153 @@ +/* -*- 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 . + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace com::sun::star::awt { class XWindow; } + +namespace sd::slidesorter { + +typedef comphelper::WeakComponentImplHelper < + css::drawing::XSlideSorterBase, + css::lang::XInitialization, + css::awt::XWindowListener +> SlideSorterServiceInterfaceBase; + +class SlideSorter; + +/** Implementation of the com.sun.star.drawing.SlideSorter service. +*/ +class SlideSorterService + : public SlideSorterServiceInterfaceBase +{ +public: + explicit SlideSorterService(); + virtual ~SlideSorterService() override; + SlideSorterService(const SlideSorterService&) = delete; + SlideSorterService& operator=(const SlideSorterService&) = delete; + virtual void disposing(std::unique_lock&) override; + + // XInitialization + + virtual void SAL_CALL initialize (const css::uno::Sequence& rArguments) override; + + // XResourceId + + css::uno::Reference SAL_CALL getResourceId() override; + + sal_Bool SAL_CALL isAnchorOnly() override; + + // XWindowListener + + virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; + + virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; + + virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; + + virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; + + // lang::XEventListener + virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; + + // XDrawView + + virtual void SAL_CALL setCurrentPage( + const css::uno::Reference& rxSlide) override; + + virtual css::uno::Reference SAL_CALL getCurrentPage() override; + + // Attributes + + virtual css::uno::Reference SAL_CALL getDocumentSlides() override; + + virtual void SAL_CALL setDocumentSlides ( + const css::uno::Reference& rxSlides) override; + + virtual sal_Bool SAL_CALL getIsHighlightCurrentSlide() override; + + virtual void SAL_CALL setIsHighlightCurrentSlide (sal_Bool bIsHighlightCurrentSlide) override; + + virtual sal_Bool SAL_CALL getIsShowSelection() override; + + virtual void SAL_CALL setIsShowSelection (sal_Bool bIsShowSelection) override; + + virtual sal_Bool SAL_CALL getIsCenterSelection() override; + + virtual void SAL_CALL setIsCenterSelection (sal_Bool bIsCenterSelection) override; + + virtual sal_Bool SAL_CALL getIsSuspendPreviewUpdatesDuringFullScreenPresentation() override; + + virtual void SAL_CALL setIsSuspendPreviewUpdatesDuringFullScreenPresentation ( + sal_Bool bIsSuspendPreviewUpdatesDuringFullScreenPresentation) override; + + virtual sal_Bool SAL_CALL getIsOrientationVertical() override; + + virtual void SAL_CALL setIsOrientationVertical (sal_Bool bIsOrientationVertical) override; + + virtual sal_Bool SAL_CALL getIsSmoothScrolling() override; + + virtual void SAL_CALL setIsSmoothScrolling (sal_Bool bIsOrientationVertical) override; + + virtual sal_Int32 SAL_CALL getBackgroundColor() override; + + virtual void SAL_CALL setBackgroundColor (sal_Int32 aBackgroundColor) override; + + virtual sal_Int32 SAL_CALL getTextColor() override; + + virtual void SAL_CALL setTextColor (sal_Int32 aTextColor) override; + + virtual sal_Int32 SAL_CALL getSelectionColor() override; + + virtual void SAL_CALL setSelectionColor (sal_Int32 aSelectionColor) override; + + virtual sal_Int32 SAL_CALL getHighlightColor() override; + + virtual void SAL_CALL setHighlightColor (sal_Int32 aHighlightColor) override; + + virtual sal_Bool SAL_CALL getIsUIReadOnly() override; + + virtual void SAL_CALL setIsUIReadOnly (sal_Bool bIsUIReadOnly) override; + + virtual sal_Bool SAL_CALL getIsShowFocus() override; + + virtual void SAL_CALL setIsShowFocus (sal_Bool bIsShowFocus) override; + +private: + std::shared_ptr mpSlideSorter; + css::uno::Reference mxViewId; + css::uno::Reference mxParentWindow; + + void Resize(); + + /** @throws css::lang::DisposedException when the object has already been + disposed. + */ + void ThrowIfDisposed(); +}; + +} // end of namespace ::sd::slidesorter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx new file mode 100644 index 000000000..af5bd5791 --- /dev/null +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -0,0 +1,924 @@ +#/* -*- 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ::sd::slidesorter; +#define ShellClass_SlideSorterViewShell +#include + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; + +using ::sd::framework::FrameworkHelper; +using ::vcl::EnumContext; +using namespace sfx2::sidebar; + +namespace sd::slidesorter { + +namespace { + +bool inChartContext(const sd::View* pView) +{ + if (!pView) + return false; + + SfxViewShell* pViewShell = pView->GetSfxViewShell(); + SidebarController* pSidebar = SidebarController::GetSidebarControllerForView(pViewShell); + if (pSidebar) + return pSidebar->hasChartContextCurrently(); + + return false; +} + +} // anonymous namespace + + +SFX_IMPL_INTERFACE(SlideSorterViewShell, SfxShell) + +void SlideSorterViewShell::InitInterface_Impl() +{ + GetStaticInterface()->RegisterChildWindow(::sfx2::sidebar::SidebarChildWindow::GetChildWindowId()); + GetStaticInterface()->RegisterChildWindow(DevelopmentToolChildWindow::GetChildWindowId()); +} + + +std::shared_ptr SlideSorterViewShell::Create ( + SfxViewFrame* pFrame, + ViewShellBase& rViewShellBase, + vcl::Window* pParentWindow, + FrameView* pFrameViewArgument) +{ + std::shared_ptr pViewShell; + try + { + pViewShell.reset( + new SlideSorterViewShell(pFrame,rViewShellBase,pParentWindow,pFrameViewArgument)); + pViewShell->Initialize(); + if (pViewShell->mpSlideSorter == nullptr) + pViewShell.reset(); + } + catch(Exception&) + { + pViewShell.reset(); + } + return pViewShell; +} + +SlideSorterViewShell::SlideSorterViewShell ( + SfxViewFrame* /*pFrame*/, + ViewShellBase& rViewShellBase, + vcl::Window* pParentWindow, + FrameView* pFrameViewArgument) + : ViewShell (pParentWindow, rViewShellBase), + mbIsArrangeGUIElementsPending(true) +{ + GetContentWindow()->set_id("slidesorter"); + meShellType = ST_SLIDE_SORTER; + + if (pFrameViewArgument != nullptr) + mpFrameView = pFrameViewArgument; + else + mpFrameView = new FrameView(GetDoc()); + GetFrameView()->Connect(); + + SetName ("SlideSorterViewShell"); + + pParentWindow->SetStyle(pParentWindow->GetStyle() | WB_DIALOGCONTROL); +} + +SlideSorterViewShell::~SlideSorterViewShell() +{ + DisposeFunctions(); + + try + { + ::sd::Window* pWindow = GetActiveWindow(); + if (pWindow!=nullptr) + { + css::uno::Reference xComponent ( + pWindow->GetAccessible(false), + css::uno::UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + } + } + catch( css::uno::Exception& ) + { + TOOLS_WARN_EXCEPTION( "sd", "sd::SlideSorterViewShell::~SlideSorterViewShell()" ); + } + GetFrameView()->Disconnect(); +} + +void SlideSorterViewShell::Initialize() +{ + mpSlideSorter = SlideSorter::CreateSlideSorter( + *this, + mpContentWindow, + mpHorizontalScrollBar, + mpVerticalScrollBar, + mpScrollBarBox); + mpView = &mpSlideSorter->GetView(); + + doShow(); + + SetPool( &GetDoc()->GetPool() ); + SetUndoManager( GetDoc()->GetDocSh()->GetUndoManager() ); + + // For accessibility we have to shortly hide the content window. + // This triggers the construction of a new accessibility object for + // the new view shell. (One is created earlier while the constructor + // of the base class is executed. At that time the correct + // accessibility object can not be constructed.) + sd::Window *pWindow (mpSlideSorter->GetContentWindow().get()); + if (pWindow) + { + pWindow->Hide(); + pWindow->Show(); + } +} + +void SlideSorterViewShell::Init (bool bIsMainViewShell) +{ + ViewShell::Init(bIsMainViewShell); + + // since the updatePageList will show focus, the window.show() must be called ahead. This show is deferred from Init() + ::sd::Window* pActiveWindow = GetActiveWindow(); + if (pActiveWindow) + pActiveWindow->Show(); + mpSlideSorter->GetModel().UpdatePageList(); + + if (mpContentWindow) + mpContentWindow->SetViewShell(this); +} + +SlideSorterViewShell* SlideSorterViewShell::GetSlideSorter (ViewShellBase& rBase) +{ + SlideSorterViewShell* pViewShell = nullptr; + + // Test the center and left pane for showing a slide sorter. + OUString aPaneURLs[] = { + FrameworkHelper::msCenterPaneURL, + FrameworkHelper::msFullScreenPaneURL, + FrameworkHelper::msLeftImpressPaneURL, + FrameworkHelper::msLeftDrawPaneURL, + OUString()}; + + try + { + std::shared_ptr pFrameworkHelper (FrameworkHelper::Instance(rBase)); + if (pFrameworkHelper->IsValid()) + for (int i=0; pViewShell==nullptr && !aPaneURLs[i].isEmpty(); ++i) + { + pViewShell = dynamic_cast( + pFrameworkHelper->GetViewShell(aPaneURLs[i]).get()); + } + } + catch (RuntimeException&) + {} + + return pViewShell; +} + +Reference SlideSorterViewShell::CreateSubController() +{ + Reference xSubController; + + if (IsMainViewShell()) + { + // Create uno controller for the main view shell. + xSubController.set( new SdUnoSlideView( *mpSlideSorter)); + } + + return xSubController; +} + +/** If there is a valid controller then create a new instance of + AccessibleSlideSorterView. Otherwise delegate this call + to the base class to return a default object (probably an empty + reference). +*/ +css::uno::Reference + SlideSorterViewShell::CreateAccessibleDocumentView (::sd::Window* pWindow) +{ + // When the view is not set then the initialization is not yet complete + // and we can not yet provide an accessibility object. + if (mpView == nullptr || mpSlideSorter == nullptr) + return nullptr; + + assert(mpSlideSorter); + + rtl::Reference<::accessibility::AccessibleSlideSorterView> pAccessibleView = + new ::accessibility::AccessibleSlideSorterView( + *mpSlideSorter, + pWindow); + + pAccessibleView->Init(); + + return pAccessibleView; +} + +void SlideSorterViewShell::SwitchViewFireFocus(const css::uno::Reference< css::accessibility::XAccessible >& xAcc ) +{ + if (xAcc) + { + ::accessibility::AccessibleSlideSorterView* pBase = static_cast< ::accessibility::AccessibleSlideSorterView* >(xAcc.get()); + if (pBase) + { + pBase->SwitchViewActivated(); + } + } +} + +SlideSorter& SlideSorterViewShell::GetSlideSorter() const +{ + assert(mpSlideSorter); + return *mpSlideSorter; +} + +bool SlideSorterViewShell::RelocateToParentWindow (vcl::Window* pParentWindow) +{ + assert(mpSlideSorter); + if ( ! mpSlideSorter) + return false; + + mpSlideSorter->RelocateToWindow(pParentWindow); + ReadFrameViewData(mpFrameView); + + return true; +} + +SfxUndoManager* SlideSorterViewShell::ImpGetUndoManager() const +{ + SfxShell* pObjectBar = GetViewShellBase().GetViewShellManager()->GetTopShell(); + if (pObjectBar != nullptr) + { + // When it exists then return the undo manager of the currently + // active object bar. The object bar is missing when the + // SlideSorterViewShell is not the main view shell. + return pObjectBar->GetUndoManager(); + } + else + { + // Return the undo manager of this shell when there is no object or + // tool bar. + return const_cast(this)->GetUndoManager(); + } +} + +SdPage* SlideSorterViewShell::getCurrentPage() const +{ + // since SlideSorterViewShell::GetActualPage() currently also + // returns master pages, which is a wrong behaviour for GetActualPage(), + // we can just use that for now + return const_cast(this)->GetActualPage(); +} + +SdPage* SlideSorterViewShell::GetActualPage() +{ + SdPage* pCurrentPage = nullptr; + + // 1. Try to get the current page from the view shell in the center pane + // (if we are that not ourself). + if ( ! IsMainViewShell()) + { + std::shared_ptr pMainViewShell = GetViewShellBase().GetMainViewShell(); + if (pMainViewShell != nullptr) + pCurrentPage = pMainViewShell->GetActualPage(); + } + + if (pCurrentPage == nullptr) + { + model::SharedPageDescriptor pDescriptor ( + mpSlideSorter->GetController().GetCurrentSlideManager()->GetCurrentSlide()); + if (pDescriptor) + pCurrentPage = pDescriptor->GetPage(); + } + + return pCurrentPage; +} + +void SlideSorterViewShell::GetMenuState ( SfxItemSet& rSet) +{ + ViewShell::GetMenuState(rSet); + assert(mpSlideSorter); + mpSlideSorter->GetController().GetSlotManager()->GetMenuState(rSet); +} + +void SlideSorterViewShell::GetClipboardState ( SfxItemSet& rSet) +{ + ViewShell::GetMenuState(rSet); + assert(mpSlideSorter); + mpSlideSorter->GetController().GetSlotManager()->GetClipboardState(rSet); +} + +void SlideSorterViewShell::ExecCtrl (SfxRequest& rRequest) +{ + assert(mpSlideSorter); + mpSlideSorter->GetController().ExecCtrl(rRequest); +} + +void SlideSorterViewShell::GetCtrlState (SfxItemSet& rSet) +{ + assert(mpSlideSorter); + mpSlideSorter->GetController().GetCtrlState(rSet); +} + +void SlideSorterViewShell::FuSupport (SfxRequest& rRequest) +{ + assert(mpSlideSorter); + mpSlideSorter->GetController().FuSupport(rRequest); +} + +/** We have to handle those slot calls here that need to have access to + private or protected members and methods of this class. +*/ +void SlideSorterViewShell::FuTemporary (SfxRequest& rRequest) +{ + assert(mpSlideSorter); + switch (rRequest.GetSlot()) + { + case SID_MODIFYPAGE: + { + SdPage* pCurrentPage = GetActualPage(); + if (pCurrentPage != nullptr) + mpImpl->ProcessModifyPageSlot ( + rRequest, + pCurrentPage, + PageKind::Standard); + Cancel(); + rRequest.Done (); + } + break; + + default: + mpSlideSorter->GetController().FuTemporary(rRequest); + break; + } +} + +void SlideSorterViewShell::GetStatusBarState (SfxItemSet& rSet) +{ + assert(mpSlideSorter); + mpSlideSorter->GetController().GetStatusBarState(rSet); +} + +void SlideSorterViewShell::FuPermanent (SfxRequest& rRequest) +{ + assert(mpSlideSorter); + mpSlideSorter->GetController().FuPermanent(rRequest); +} + +void SlideSorterViewShell::GetAttrState (SfxItemSet& rSet) +{ + assert(mpSlideSorter); + mpSlideSorter->GetController().GetAttrState(rSet); +} + +void SlideSorterViewShell::ExecStatusBar (SfxRequest& ) +{ +} + +void SlideSorterViewShell::Paint ( + const ::tools::Rectangle& rBBox, + ::sd::Window* pWindow) +{ + SetActiveWindow (pWindow); + assert(mpSlideSorter); + if (mpSlideSorter) + mpSlideSorter->GetController().Paint(rBBox,pWindow); +} + +void SlideSorterViewShell::ArrangeGUIElements() +{ + if (IsActive()) + { + assert(mpSlideSorter); + mpSlideSorter->ArrangeGUIElements(maViewPos, maViewSize); + mbIsArrangeGUIElementsPending = false; + } + else + mbIsArrangeGUIElementsPending = true; +} + +void SlideSorterViewShell::Activate (bool bIsMDIActivate) +{ + if(inChartContext(GetView())) + { + // Avoid context changes for chart during activation / deactivation. + const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false)); + + ViewShell::Activate(bIsMDIActivate); + + SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled); + return; + } + + ViewShell::Activate(bIsMDIActivate); + if (mbIsArrangeGUIElementsPending) + ArrangeGUIElements(); + + // Determine and broadcast the context that belongs to the main view shell. + EnumContext::Context eContext = EnumContext::Context::Unknown; + std::shared_ptr pMainViewShell (GetViewShellBase().GetMainViewShell()); + ViewShell::ShellType eMainViewShellType ( + pMainViewShell + ? pMainViewShell->GetShellType() + : ViewShell::ST_NONE); + switch (eMainViewShellType) + { + case ViewShell::ST_IMPRESS: + case ViewShell::ST_SLIDE_SORTER: + case ViewShell::ST_NOTES: + case ViewShell::ST_DRAW: + eContext = EnumContext::Context::DrawPage; + if( nullptr != dynamic_cast< const DrawViewShell *>( pMainViewShell.get() )) + { + DrawViewShell* pDrawViewShell = dynamic_cast(pMainViewShell.get()); + if (pDrawViewShell != nullptr) + eContext = EnumContext::GetContextEnum(pDrawViewShell->GetSidebarContextName()); + } + break; + + default: + break; + } + ContextChangeEventMultiplexer::NotifyContextChange( + &GetViewShellBase(), + eContext); +} + +void SlideSorterViewShell::Deactivate (bool /*bIsMDIActivate*/) +{ + // Save Settings - Specifically SlidesPerRow to retrieve it later + WriteFrameViewData(); +} + +void SlideSorterViewShell::Command ( + const CommandEvent& rEvent, + ::sd::Window* pWindow) +{ + assert(mpSlideSorter); + if ( ! mpSlideSorter->GetController().Command (rEvent, pWindow)) + ViewShell::Command (rEvent, pWindow); +} + +void SlideSorterViewShell::ReadFrameViewData (FrameView* pFrameView) +{ + assert(mpSlideSorter); + if (pFrameView != nullptr) + { + view::SlideSorterView& rView (mpSlideSorter->GetView()); + + sal_uInt16 nSlidesPerRow (pFrameView->GetSlidesPerRow()); + if (nSlidesPerRow > 0 + && rView.GetOrientation() == view::Layouter::GRID + && IsMainViewShell()) + { + rView.GetLayouter().SetColumnCount(nSlidesPerRow,nSlidesPerRow); + } + if (IsMainViewShell()) + mpSlideSorter->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange( + mpFrameView->GetSelectedPage()); + mpSlideSorter->GetController().Rearrange(true); + + // DrawMode for 'main' window + if (GetActiveWindow()->GetOutDev()->GetDrawMode() != pFrameView->GetDrawMode() ) + GetActiveWindow()->GetOutDev()->SetDrawMode( pFrameView->GetDrawMode() ); + } + + // When this slide sorter is not displayed in the main window then we do + // not share the same frame view and have to find other ways to acquire + // certain values. + if ( ! IsMainViewShell()) + { + std::shared_ptr pMainViewShell = GetViewShellBase().GetMainViewShell(); + if (pMainViewShell != nullptr) + mpSlideSorter->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange( + pMainViewShell->getCurrentPage()); + } +} + +void SlideSorterViewShell::WriteFrameViewData() +{ + assert(mpSlideSorter); + if (mpFrameView == nullptr) + return; + + view::SlideSorterView& rView (mpSlideSorter->GetView()); + mpFrameView->SetSlidesPerRow(static_cast(rView.GetLayouter().GetColumnCount())); + + // DrawMode for 'main' window + if( mpFrameView->GetDrawMode() != GetActiveWindow()->GetOutDev()->GetDrawMode() ) + mpFrameView->SetDrawMode( GetActiveWindow()->GetOutDev()->GetDrawMode() ); + + SdPage* pActualPage = GetActualPage(); + if (pActualPage != nullptr) + { + if (IsMainViewShell()) + mpFrameView->SetSelectedPage((pActualPage->GetPageNum()- 1) / 2); + // else + // The slide sorter is not expected to switch the current page + // other than by double clicks. That is handled separately. + } + else + { + // We have no current page to set but at least we can make sure + // that the index of the frame view has a legal value. + if (mpFrameView->GetSelectedPage() >= mpSlideSorter->GetModel().GetPageCount()) + mpFrameView->SetSelectedPage(static_cast(mpSlideSorter->GetModel().GetPageCount())-1); + } +} + +void SlideSorterViewShell::SetZoom (::tools::Long ) +{ + // Ignored. + // The zoom scale is adapted internally to fit a number of columns in + // the window. +} + +void SlideSorterViewShell::SetZoomRect (const ::tools::Rectangle& rZoomRect) +{ + assert(mpSlideSorter); + Size aPageSize (mpSlideSorter->GetView().GetLayouter().GetPageObjectSize()); + + ::tools::Rectangle aRect(rZoomRect); + + if (aRect.GetWidth() < aPageSize.Width()) + { + ::tools::Long nWidthDiff = (aPageSize.Width() - aRect.GetWidth()) / 2; + + aRect.AdjustLeft( -nWidthDiff ); + aRect.AdjustRight(nWidthDiff ); + + if (aRect.Left() < 0) + { + aRect.SetPos(Point(0, aRect.Top())); + } + } + + if (aRect.GetHeight() < aPageSize.Height()) + { + ::tools::Long nHeightDiff = (aPageSize.Height() - aRect.GetHeight()) / 2; + + aRect.AdjustTop( -nHeightDiff ); + aRect.AdjustBottom(nHeightDiff ); + + if (aRect.Top() < 0) + { + aRect.SetPos(Point(aRect.Left(), 0)); + } + } + + ViewShell::SetZoomRect(aRect); + + GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM ); + GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER ); +} + +void SlideSorterViewShell::UpdateScrollBars() +{ + // Do not call the overwritten method of the base class: We do all the + // scroll bar setup by ourselves. + mpSlideSorter->GetController().GetScrollBarManager().UpdateScrollBars(true); +} + +void SlideSorterViewShell::StartDrag ( + const Point& rDragPt, + vcl::Window* pWindow ) +{ + assert(mpSlideSorter); + mpSlideSorter->GetController().GetClipboard().StartDrag ( + rDragPt, + pWindow); +} + +sal_Int8 SlideSorterViewShell::AcceptDrop ( + const AcceptDropEvent& rEvt, + DropTargetHelper& rTargetHelper, + ::sd::Window* pTargetWindow, + sal_uInt16 nPage, + SdrLayerID nLayer) +{ + assert(mpSlideSorter); + return mpSlideSorter->GetController().GetClipboard().AcceptDrop ( + rEvt, + rTargetHelper, + pTargetWindow, + nPage, + nLayer); +} + +sal_Int8 SlideSorterViewShell::ExecuteDrop ( + const ExecuteDropEvent& rEvt, + DropTargetHelper& rTargetHelper, + ::sd::Window* pTargetWindow, + sal_uInt16 nPage, + SdrLayerID nLayer) +{ + assert(mpSlideSorter); + return mpSlideSorter->GetController().GetClipboard().ExecuteDrop ( + rEvt, + rTargetHelper, + pTargetWindow, + nPage, + nLayer); +} + +std::shared_ptr + SlideSorterViewShell::GetPageSelection() const +{ + assert(mpSlideSorter); + return mpSlideSorter->GetController().GetPageSelector().GetPageSelection(); +} + +void SlideSorterViewShell::SetPageSelection ( + const std::shared_ptr& rSelection) +{ + assert(mpSlideSorter); + mpSlideSorter->GetController().GetPageSelector().SetPageSelection(rSelection, true); +} + +void SlideSorterViewShell::AddSelectionChangeListener ( + const Link& rCallback) +{ + assert(mpSlideSorter); + mpSlideSorter->GetController().GetSelectionManager()->AddSelectionChangeListener(rCallback); +} + +void SlideSorterViewShell::RemoveSelectionChangeListener ( + const Link& rCallback) +{ + assert(mpSlideSorter); + mpSlideSorter->GetController().GetSelectionManager()->RemoveSelectionChangeListener(rCallback); +} + +void SlideSorterViewShell::MainViewEndEditAndUnmarkAll() +{ + std::shared_ptr pMainViewShell = GetViewShellBase().GetMainViewShell(); + DrawViewShell* pDrawViewShell = dynamic_cast(pMainViewShell.get()); + SdrView* pView = pDrawViewShell ? pDrawViewShell->GetDrawView() : nullptr; + if (pView) + { + pView->SdrEndTextEdit(); + pView->UnmarkAll(); + } +} + +std::pair SlideSorterViewShell::SyncPageSelectionToDocument(const std::shared_ptr &rpSelection) +{ + sal_uInt16 firstSelectedPageNo = SAL_MAX_UINT16; + sal_uInt16 lastSelectedPageNo = 0; + + GetDoc()->UnselectAllPages(); + for (auto& rpPage : *rpSelection) + { + // Check page number + sal_uInt16 pageNo = rpPage->GetPageNum(); + if (pageNo > lastSelectedPageNo) + lastSelectedPageNo = pageNo; + if (pageNo < firstSelectedPageNo) + firstSelectedPageNo = pageNo; + GetDoc()->SetSelected(rpPage, true); + } + + return std::make_pair(firstSelectedPageNo, lastSelectedPageNo); +} + +void SlideSorterViewShell::ExecMovePageFirst (SfxRequest& /*rReq*/) +{ + MainViewEndEditAndUnmarkAll(); + + std::shared_ptr xSelection(GetPageSelection()); + + // SdDrawDocument MovePages is based on SdPage IsSelected, so + // transfer the SlideSorter selection to SdPages + SyncPageSelectionToDocument(xSelection); + + // Moves selected pages after page -1 + GetDoc()->MovePages( sal_uInt16(-1) ); + + PostMoveSlidesActions(xSelection); +} + +void SlideSorterViewShell::GetStateMovePageFirst (SfxItemSet& rSet) +{ + if ( ! IsMainViewShell()) + { + std::shared_ptr pMainViewShell = GetViewShellBase().GetMainViewShell(); + DrawViewShell* pDrawViewShell = dynamic_cast(pMainViewShell.get()); + if (pDrawViewShell != nullptr && pDrawViewShell->GetPageKind() == PageKind::Handout) + { + rSet.DisableItem( SID_MOVE_PAGE_FIRST ); + rSet.DisableItem( SID_MOVE_PAGE_UP ); + return; + } + } + + std::shared_ptr xSelection(GetPageSelection()); + + // SdDrawDocument MovePages is based on SdPage IsSelected, so + // transfer the SlideSorter selection to SdPages + sal_uInt16 firstSelectedPageNo = SyncPageSelectionToDocument(xSelection).first; + // Now compute human page number from internal page number + firstSelectedPageNo = (firstSelectedPageNo - 1) / 2; + + if (firstSelectedPageNo == 0) + { + rSet.DisableItem( SID_MOVE_PAGE_FIRST ); + rSet.DisableItem( SID_MOVE_PAGE_UP ); + } +} + +void SlideSorterViewShell::ExecMovePageUp (SfxRequest& /*rReq*/) +{ + MainViewEndEditAndUnmarkAll(); + + std::shared_ptr xSelection(GetPageSelection()); + + // SdDrawDocument MovePages is based on SdPage IsSelected, so + // transfer the SlideSorter selection to SdPages + sal_uInt16 firstSelectedPageNo = SyncPageSelectionToDocument(xSelection).first; + + // In case no slide is selected + if (firstSelectedPageNo == SAL_MAX_UINT16) + return; + + // Now compute human page number from internal page number + firstSelectedPageNo = (firstSelectedPageNo - 1) / 2; + + if (firstSelectedPageNo == 0) + return; + + // Move pages before firstSelectedPageNo - 1 (so after firstSelectedPageNo - 2), + // remembering that -1 means at first, which is good. + GetDoc()->MovePages( firstSelectedPageNo - 2 ); + + PostMoveSlidesActions(xSelection); +} + +void SlideSorterViewShell::GetStateMovePageUp (SfxItemSet& rSet) +{ + GetStateMovePageFirst(rSet); +} + +void SlideSorterViewShell::ExecMovePageDown (SfxRequest& /*rReq*/) +{ + MainViewEndEditAndUnmarkAll(); + + std::shared_ptr xSelection(GetPageSelection()); + + // SdDrawDocument MovePages is based on SdPage IsSelected, so + // transfer the SlideSorter selection to SdPages + sal_uInt16 lastSelectedPageNo = SyncPageSelectionToDocument(xSelection).second; + + // Get page number of the last page + sal_uInt16 nNoOfPages = GetDoc()->GetSdPageCount(PageKind::Standard); + + // Now compute human page number from internal page number + lastSelectedPageNo = (lastSelectedPageNo - 1) / 2; + if (lastSelectedPageNo == nNoOfPages - 1) + return; + + // Move to position after lastSelectedPageNo + GetDoc()->MovePages( lastSelectedPageNo + 1 ); + + PostMoveSlidesActions(xSelection); +} + +void SlideSorterViewShell::GetStateMovePageDown (SfxItemSet& rSet) +{ + GetStateMovePageLast( rSet ); +} + +void SlideSorterViewShell::ExecMovePageLast (SfxRequest& /*rReq*/) +{ + MainViewEndEditAndUnmarkAll(); + + std::shared_ptr xSelection(GetPageSelection()); + + // SdDrawDocument MovePages is based on SdPage IsSelected, so + // transfer the SlideSorter selection to SdPages + SyncPageSelectionToDocument(xSelection); + + // Get page number of the last page + sal_uInt16 nNoOfPages = GetDoc()->GetSdPageCount(PageKind::Standard); + + // Move to position after last page No (=Number of pages - 1) + GetDoc()->MovePages( nNoOfPages - 1 ); + + PostMoveSlidesActions(xSelection); +} + +void SlideSorterViewShell::GetStateMovePageLast (SfxItemSet& rSet) +{ + std::shared_ptr pMainViewShell = GetViewShellBase().GetMainViewShell(); + DrawViewShell* pDrawViewShell = dynamic_cast(pMainViewShell.get()); + if (pDrawViewShell != nullptr && pDrawViewShell->GetPageKind() == PageKind::Handout) + { + rSet.DisableItem( SID_MOVE_PAGE_LAST ); + rSet.DisableItem( SID_MOVE_PAGE_DOWN ); + return; + } + + std::shared_ptr xSelection(GetPageSelection()); + + // SdDrawDocument MovePages is based on SdPage IsSelected, so + // transfer the SlideSorter selection to SdPages + sal_uInt16 lastSelectedPageNo = SyncPageSelectionToDocument(xSelection).second; + + // Get page number of the last page + sal_uInt16 nNoOfPages = GetDoc()->GetSdPageCount(PageKind::Standard); + + // Now compute human page number from internal page number + lastSelectedPageNo = (lastSelectedPageNo - 1) / 2; + if (lastSelectedPageNo == nNoOfPages - 1) + { + rSet.DisableItem( SID_MOVE_PAGE_LAST ); + rSet.DisableItem( SID_MOVE_PAGE_DOWN ); + } +} + +void SlideSorterViewShell::PostMoveSlidesActions(const std::shared_ptr &rpSelection) +{ + sal_uInt16 nNoOfPages = GetDoc()->GetSdPageCount(PageKind::Standard); + for (sal_uInt16 nPage = 0; nPage < nNoOfPages; nPage++) + { + SdPage* pPage = GetDoc()->GetSdPage(nPage, PageKind::Standard); + GetDoc()->SetSelected(pPage, false); + } + + mpSlideSorter->GetController().GetPageSelector().DeselectAllPages(); + for (const auto& rpPage : *rpSelection) + { + mpSlideSorter->GetController().GetPageSelector().SelectPage(rpPage); + } + + // Refresh toolbar icons + SfxBindings& rBindings = GetViewFrame()->GetBindings(); + rBindings.Invalidate(SID_MOVE_PAGE_FIRST); + rBindings.Invalidate(SID_MOVE_PAGE_UP); + rBindings.Invalidate(SID_MOVE_PAGE_DOWN); + rBindings.Invalidate(SID_MOVE_PAGE_LAST); + +} + +} // end of namespace ::sd::slidesorter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3