9f35c2b6cd
ViewShellBase is the SfxViewShell and is the analogue of the equivalent writer/calc SfxViewShell's, while a DrawViewShell is one of multiple sd::ViewShells that can exist inside that SfxViewShell Issue: * When creating new shell instances, background color is fetched from application configuration. * When multiple users are active on an Impress document, if one switches to notes view, a new shell is created. * Background color for the new shell is fetched from app colors. * If another user has switched to dark mode, the user which just switched to notes view, will see dark mode for their background. Moving the SdViewOptions options down the ViewShellBase means that multiple sd::ViewShells hosted within that ViewShellBase share the same view settings. Change-Id: Id875260dda89311ab8029ead08b47f80fd14604f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177253 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
903 lines
29 KiB
C++
903 lines
29 KiB
C++
/* -*- 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 <DrawViewShell.hxx>
|
|
#include <com/sun/star/scanner/ScannerManager.hpp>
|
|
#include <cppuhelper/implbase.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <editeng/sizeitem.hxx>
|
|
#include <svx/svdlayer.hxx>
|
|
#include <svx/svdograf.hxx>
|
|
#include <sfx2/zoomitem.hxx>
|
|
#include <sfx2/lokhelper.hxx>
|
|
#include <svx/svdpagv.hxx>
|
|
#include <svl/ptitem.hxx>
|
|
#include <svl/stritem.hxx>
|
|
#include <sfx2/request.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <svx/zoomslideritem.hxx>
|
|
#include <svl/eitem.hxx>
|
|
|
|
#include <sdcommands.h>
|
|
#include <svx/f3dchild.hxx>
|
|
#include <svx/clipfmtitem.hxx>
|
|
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <svtools/cliplistener.hxx>
|
|
#include <svx/float3d.hxx>
|
|
#include <svx/extedit.hxx>
|
|
#include <svx/sidebar/SelectionAnalyzer.hxx>
|
|
#include <svx/sidebar/SelectionChangeHandler.hxx>
|
|
#include <helpids.h>
|
|
|
|
#include <view/viewoverlaymanager.hxx>
|
|
#include <app.hrc>
|
|
#include <strings.hrc>
|
|
#include <sdmod.hxx>
|
|
#include <sdpage.hxx>
|
|
#include <FrameView.hxx>
|
|
#include <drawdoc.hxx>
|
|
#include <sdresid.hxx>
|
|
#include <DrawDocShell.hxx>
|
|
#include <Window.hxx>
|
|
#include <fupoor.hxx>
|
|
#include <fusel.hxx>
|
|
#include <funavig.hxx>
|
|
#include <drawview.hxx>
|
|
#include <SdUnoDrawView.hxx>
|
|
#include <ViewShellBase.hxx>
|
|
#include <slideshow.hxx>
|
|
#include <annotationmanager.hxx>
|
|
#include <DrawController.hxx>
|
|
#include <unomodel.hxx>
|
|
#include <comphelper/diagnose_ex.hxx>
|
|
#include <comphelper/lok.hxx>
|
|
#include <comphelper/servicehelper.hxx>
|
|
#include <LayerTabBar.hxx>
|
|
|
|
#include <memory>
|
|
|
|
using namespace ::com::sun::star;
|
|
using namespace ::com::sun::star::uno;
|
|
using vcl::EnumContext;
|
|
|
|
namespace sd {
|
|
|
|
bool DrawViewShell::mbPipette = false;
|
|
|
|
namespace {
|
|
|
|
class ScannerEventListener : public ::cppu::WeakImplHelper< lang::XEventListener >
|
|
{
|
|
private:
|
|
|
|
DrawViewShell* mpParent;
|
|
|
|
public:
|
|
|
|
explicit ScannerEventListener( DrawViewShell* pParent ) : mpParent( pParent ) {}
|
|
|
|
// XEventListener
|
|
virtual void SAL_CALL disposing( const lang::EventObject& rEventObject ) override;
|
|
|
|
void ParentDestroyed() { mpParent = nullptr; }
|
|
};
|
|
|
|
}
|
|
|
|
void SAL_CALL ScannerEventListener::disposing( const lang::EventObject& /*rEventObject*/ )
|
|
{
|
|
if( mpParent )
|
|
mpParent->ScannerEvent();
|
|
}
|
|
|
|
DrawViewShell::DrawViewShell( ViewShellBase& rViewShellBase, vcl::Window* pParentWindow, PageKind ePageKind, FrameView* pFrameViewArgument )
|
|
: ViewShell (pParentWindow, rViewShellBase)
|
|
, maTabControl(VclPtr<sd::TabControl>::Create(this, pParentWindow))
|
|
, mbIsLayerModeActive(false)
|
|
, mbIsInSwitchPage(false)
|
|
, mpSelectionChangeHandler(new svx::sidebar::SelectionChangeHandler(
|
|
[this] () { return this->GetSidebarContextName(); },
|
|
uno::Reference<frame::XController>(rViewShellBase.GetDrawController()),
|
|
vcl::EnumContext::Context::Default))
|
|
, mbMouseButtonDown(false)
|
|
, mbMouseSelecting(false)
|
|
{
|
|
if (pFrameViewArgument != nullptr)
|
|
mpFrameView = pFrameViewArgument;
|
|
else
|
|
mpFrameView = new FrameView(GetDoc());
|
|
Construct(GetDocSh(), ePageKind);
|
|
|
|
mpSelectionChangeHandler->Connect();
|
|
|
|
SetContextName(GetSidebarContextName());
|
|
|
|
doShow();
|
|
|
|
ConfigureAppBackgroundColor();
|
|
SdModule* mod = SdModule::get();
|
|
mod->GetColorConfig().AddListener(this);
|
|
|
|
if (comphelper::LibreOfficeKit::isActive())
|
|
{
|
|
// get the full page size in pixels
|
|
mpContentWindow->EnableMapMode();
|
|
Size aSize(mpContentWindow->LogicToPixel(GetView()->GetSdrPageView()->GetPage()->GetSize()));
|
|
// Disable map mode, so that it's possible to send mouse event
|
|
// coordinates in logic units
|
|
mpContentWindow->EnableMapMode(false);
|
|
|
|
// arrange UI elements again with new view size
|
|
GetParentWindow()->SetSizePixel(aSize);
|
|
Resize();
|
|
|
|
SdXImpressDocument* pModel = comphelper::getFromUnoTunnel<SdXImpressDocument>(rViewShellBase.GetCurrentDocument());
|
|
SfxLokHelper::notifyViewRenderState(&rViewShellBase, pModel);
|
|
}
|
|
}
|
|
|
|
DrawViewShell::~DrawViewShell()
|
|
{
|
|
suppress_fun_call_w_exception(ImplDestroy());
|
|
}
|
|
|
|
void DrawViewShell::ImplDestroy()
|
|
{
|
|
destroyXSlideShowInstance();
|
|
|
|
SdModule::get()->GetColorConfig().RemoveListener(this);
|
|
|
|
mpSelectionChangeHandler->Disconnect();
|
|
|
|
mpAnnotationManager.reset();
|
|
mpViewOverlayManager.reset();
|
|
|
|
OSL_ASSERT (GetViewShell()!=nullptr);
|
|
|
|
if( mxScannerListener.is() )
|
|
static_cast< ScannerEventListener* >( mxScannerListener.get() )->ParentDestroyed();
|
|
|
|
// Remove references to items within Svx3DWin
|
|
// (maybe do a listening sometime in Svx3DWin)
|
|
sal_uInt16 nId = Svx3DChildWindow::GetChildWindowId();
|
|
SfxChildWindow* pWindow = GetViewFrame() ? GetViewFrame()->GetChildWindow(nId) : nullptr;
|
|
if(pWindow)
|
|
{
|
|
Svx3DWin* p3DWin = static_cast< Svx3DWin* > (pWindow->GetWindow());
|
|
if(p3DWin)
|
|
p3DWin->DocumentReload();
|
|
}
|
|
|
|
EndListening (*GetDoc());
|
|
EndListening (*GetDocSh());
|
|
|
|
if( SlideShow::IsRunning(*this) )
|
|
StopSlideShow();
|
|
|
|
DisposeFunctions();
|
|
|
|
sal_uInt16 aPageCnt = GetDoc()->GetSdPageCount(mePageKind);
|
|
|
|
for (sal_uInt16 i = 0; i < aPageCnt; i++)
|
|
{
|
|
SdPage* pPage = GetDoc()->GetSdPage(i, mePageKind);
|
|
|
|
if (pPage == mpActualPage)
|
|
{
|
|
GetDoc()->SetSelected(pPage, true);
|
|
}
|
|
else
|
|
{
|
|
GetDoc()->SetSelected(pPage, false);
|
|
}
|
|
}
|
|
|
|
if ( mxClipEvtLstnr.is() )
|
|
{
|
|
mxClipEvtLstnr->RemoveListener( GetActiveWindow() );
|
|
mxClipEvtLstnr->ClearCallbackLink(); // prevent callback if another thread is waiting
|
|
mxClipEvtLstnr.clear();
|
|
}
|
|
|
|
mpDrawView.reset();
|
|
// Set mpView to NULL so that the destructor of the ViewShell base class
|
|
// does not access it.
|
|
mpView = nullptr;
|
|
|
|
mpFrameView->Disconnect();
|
|
maTabControl.disposeAndClear();
|
|
}
|
|
|
|
/**
|
|
* common part of both constructors
|
|
*/
|
|
void DrawViewShell::Construct(DrawDocShell* pDocSh, PageKind eInitialPageKind)
|
|
{
|
|
mpActualPage = nullptr;
|
|
mbReadOnly = GetDocSh()->IsReadOnly();
|
|
mxClipEvtLstnr.clear();
|
|
mbPastePossible = false;
|
|
mbIsLayerModeActive = false;
|
|
|
|
mpFrameView->Connect();
|
|
|
|
OSL_ASSERT (GetViewShell()!=nullptr);
|
|
|
|
SetPool( &GetDoc()->GetPool() );
|
|
|
|
GetDoc()->CreateFirstPages();
|
|
|
|
mpDrawView.reset( new DrawView(pDocSh, GetActiveWindow()->GetOutDev(), this) );
|
|
mpView = mpDrawView.get(); // Pointer of base class ViewShell
|
|
mpDrawView->SetSwapAsynchron(); // Asynchronous load of graphics
|
|
|
|
// We do not read the page kind from the frame view anymore so we have
|
|
// to set it in order to resync frame view and this view.
|
|
mpFrameView->SetPageKind(eInitialPageKind);
|
|
mePageKind = eInitialPageKind;
|
|
meEditMode = EditMode::Page;
|
|
DocumentType eDocType = GetDoc()->GetDocumentType(); // RTTI does not work here
|
|
switch (mePageKind)
|
|
{
|
|
case PageKind::Standard:
|
|
meShellType = ST_IMPRESS;
|
|
break;
|
|
|
|
case PageKind::Notes:
|
|
meShellType = ST_NOTES;
|
|
break;
|
|
|
|
case PageKind::Handout:
|
|
meShellType = ST_HANDOUT;
|
|
break;
|
|
}
|
|
|
|
Size aPageSize( GetDoc()->GetSdPage(0, mePageKind)->GetSize() );
|
|
Point aPageOrg( aPageSize.Width(), aPageSize.Height() / 2);
|
|
Size aSize(aPageSize.Width() * 3, aPageSize.Height() * 2);
|
|
InitWindows(aPageOrg, aSize, Point(-1, -1));
|
|
|
|
Point aVisAreaPos;
|
|
|
|
if ( pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
|
|
{
|
|
aVisAreaPos = pDocSh->GetVisArea(ASPECT_CONTENT).TopLeft();
|
|
}
|
|
|
|
mpDrawView->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aSize));
|
|
|
|
// objects can not grow bigger than ViewSize
|
|
GetDoc()->SetMaxObjSize(aSize);
|
|
|
|
// Split-Handler for TabControls
|
|
maTabControl->SetSplitHdl( LINK( this, DrawViewShell, TabSplitHdl ) );
|
|
|
|
/* In order to set the correct EditMode of the FrameView, we select another
|
|
one (small trick). */
|
|
if (mpFrameView->GetViewShEditMode(/*mePageKind*/) == EditMode::Page)
|
|
{
|
|
meEditMode = EditMode::MasterPage;
|
|
}
|
|
else
|
|
{
|
|
meEditMode = EditMode::Page;
|
|
}
|
|
|
|
// Use configuration of FrameView
|
|
ReadFrameViewData(mpFrameView);
|
|
|
|
if( eDocType == DocumentType::Draw )
|
|
{
|
|
GetActiveWindow()->SetHelpId( HID_SDGRAPHICVIEWSHELL );
|
|
}
|
|
else
|
|
{
|
|
if (mePageKind == PageKind::Notes)
|
|
{
|
|
GetActiveWindow()->SetHelpId( CMD_SID_NOTES_MODE );
|
|
|
|
// AutoLayouts have to be created
|
|
GetDoc()->StopWorkStartupDelay();
|
|
}
|
|
else if (mePageKind == PageKind::Handout)
|
|
{
|
|
GetActiveWindow()->SetHelpId( CMD_SID_HANDOUT_MASTER_MODE );
|
|
|
|
// AutoLayouts have to be created
|
|
GetDoc()->StopWorkStartupDelay();
|
|
}
|
|
else
|
|
{
|
|
GetActiveWindow()->SetHelpId( HID_SDDRAWVIEWSHELL );
|
|
}
|
|
}
|
|
|
|
// start selection function
|
|
SfxRequest aReq(SID_OBJECT_SELECT, SfxCallMode::SLOT, GetDoc()->GetItemPool());
|
|
FuPermanent(aReq);
|
|
mpDrawView->SetFrameDragSingles();
|
|
|
|
if (pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED)
|
|
{
|
|
mbZoomOnPage = false;
|
|
}
|
|
else
|
|
{
|
|
mbZoomOnPage = true;
|
|
}
|
|
|
|
mbIsRulerDrag = false;
|
|
|
|
SetName (u"DrawViewShell"_ustr);
|
|
|
|
mnLockCount = 0;
|
|
|
|
const uno::Reference< uno::XComponentContext >& xContext( ::comphelper::getProcessComponentContext() );
|
|
|
|
try
|
|
{
|
|
mxScannerManager = scanner::ScannerManager::create( xContext );
|
|
|
|
mxScannerListener = new ScannerEventListener( this );
|
|
}
|
|
catch (DeploymentException const &)
|
|
{
|
|
SAL_INFO("sd", "Scanner manager not available");
|
|
}
|
|
catch (Exception const &)
|
|
{
|
|
// Eat the exception and log it
|
|
// We can still continue if scanner manager is not available.
|
|
DBG_UNHANDLED_EXCEPTION("sd");
|
|
}
|
|
|
|
mpAnnotationManager.reset( new AnnotationManager( GetViewShellBase() ) );
|
|
mpViewOverlayManager.reset( new ViewOverlayManager( GetViewShellBase() ) );
|
|
}
|
|
|
|
void DrawViewShell::Init (bool bIsMainViewShell)
|
|
{
|
|
ViewShell::Init(bIsMainViewShell);
|
|
|
|
if (!IsListening(*GetDocSh()))
|
|
StartListening (*GetDocSh());
|
|
}
|
|
|
|
void DrawViewShell::Shutdown()
|
|
{
|
|
ViewShell::Shutdown();
|
|
|
|
if(SlideShow::IsRunning( GetViewShellBase() )
|
|
&& !SlideShow::IsInteractiveSlideshow( &GetViewShellBase() )) // IASS
|
|
{
|
|
// Turn off effects.
|
|
GetDrawView()->SetAnimationMode(SdrAnimationMode::Disable);
|
|
}
|
|
}
|
|
|
|
css::uno::Reference<css::drawing::XDrawSubController> DrawViewShell::CreateSubController()
|
|
{
|
|
css::uno::Reference<css::drawing::XDrawSubController> xSubController;
|
|
|
|
if (IsMainViewShell())
|
|
{
|
|
// Create uno sub controller for the main view shell.
|
|
xSubController.set( new SdUnoDrawView( *this, *GetView()));
|
|
}
|
|
|
|
return xSubController;
|
|
}
|
|
|
|
bool DrawViewShell::RelocateToParentWindow (vcl::Window* pParentWindow)
|
|
{
|
|
// DrawViewShells can not be relocated to a new parent window at the
|
|
// moment, so return <FALSE/> except when the given parent window is the
|
|
// parent window that is already in use.
|
|
return pParentWindow==GetParentWindow();
|
|
}
|
|
|
|
/**
|
|
* check if we have to draw a polyline
|
|
*/
|
|
|
|
/*
|
|
Polylines are represented by macros as a sequence of:
|
|
MoveTo (x, y)
|
|
LineTo (x, y) [or BezierTo (x, y)]
|
|
LineTo (x, y)
|
|
:
|
|
There is no end command for polylines. Therefore, we have to test all
|
|
commands in the requests for LineTo (BezierTo) and we have to gather
|
|
the point-parameter. The first not-LineTo leads to the creation of the
|
|
polyline from the gathered points.
|
|
*/
|
|
|
|
void DrawViewShell::CheckLineTo(SfxRequest& rReq)
|
|
{
|
|
#ifdef DBG_UTIL
|
|
if(rReq.IsAPI())
|
|
{
|
|
if(SID_LINETO == rReq.GetSlot() || SID_BEZIERTO == rReq.GetSlot() || SID_MOVETO == rReq.GetSlot() )
|
|
{
|
|
OSL_FAIL("DrawViewShell::CheckLineTo: slots SID_LINETO, SID_BEZIERTO, SID_MOVETO no longer supported.");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
rReq.Ignore ();
|
|
}
|
|
|
|
/**
|
|
* Change page parameter if SID_PAGESIZE or SID_PAGEMARGIN
|
|
*/
|
|
void DrawViewShell::SetupPage (Size const &rSize,
|
|
::tools::Long nLeft,
|
|
::tools::Long nRight,
|
|
::tools::Long nUpper,
|
|
::tools::Long nLower,
|
|
bool bSize,
|
|
bool bMargin,
|
|
bool bScaleAll)
|
|
{
|
|
sal_uInt16 nPageCnt = GetDoc()->GetMasterSdPageCount(mePageKind);
|
|
sal_uInt16 i;
|
|
|
|
for (i = 0; i < nPageCnt; i++)
|
|
{
|
|
// first, handle all master pages
|
|
SdPage *pPage = GetDoc()->GetMasterSdPage(i, mePageKind);
|
|
|
|
if( pPage )
|
|
{
|
|
if( bSize )
|
|
{
|
|
::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
|
|
pPage->ScaleObjects(rSize, aBorderRect, bScaleAll);
|
|
pPage->SetSize(rSize);
|
|
|
|
}
|
|
if( bMargin )
|
|
{
|
|
pPage->SetLeftBorder(nLeft);
|
|
pPage->SetRightBorder(nRight);
|
|
pPage->SetUpperBorder(nUpper);
|
|
pPage->SetLowerBorder(nLower);
|
|
}
|
|
|
|
if ( mePageKind == PageKind::Standard )
|
|
{
|
|
GetDoc()->GetMasterSdPage(i, PageKind::Notes)->CreateTitleAndLayout();
|
|
}
|
|
|
|
pPage->CreateTitleAndLayout();
|
|
}
|
|
}
|
|
|
|
nPageCnt = GetDoc()->GetSdPageCount(mePageKind);
|
|
|
|
for (i = 0; i < nPageCnt; i++)
|
|
{
|
|
// then, handle all pages
|
|
SdPage *pPage = GetDoc()->GetSdPage(i, mePageKind);
|
|
|
|
if( pPage )
|
|
{
|
|
if( bSize )
|
|
{
|
|
::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
|
|
pPage->ScaleObjects(rSize, aBorderRect, bScaleAll);
|
|
pPage->SetSize(rSize);
|
|
}
|
|
if( bMargin )
|
|
{
|
|
pPage->SetLeftBorder(nLeft);
|
|
pPage->SetRightBorder(nRight);
|
|
pPage->SetUpperBorder(nUpper);
|
|
pPage->SetLowerBorder(nLower);
|
|
}
|
|
|
|
if ( mePageKind == PageKind::Standard )
|
|
{
|
|
SdPage* pNotesPage = GetDoc()->GetSdPage(i, PageKind::Notes);
|
|
pNotesPage->SetAutoLayout( pNotesPage->GetAutoLayout() );
|
|
}
|
|
|
|
pPage->SetAutoLayout( pPage->GetAutoLayout() );
|
|
}
|
|
}
|
|
|
|
if ( mePageKind == PageKind::Standard )
|
|
{
|
|
SdPage* pHandoutPage = GetDoc()->GetSdPage(0, PageKind::Handout);
|
|
pHandoutPage->CreateTitleAndLayout(true);
|
|
}
|
|
|
|
::tools::Long nWidth = mpActualPage->GetSize().Width();
|
|
::tools::Long nHeight = mpActualPage->GetSize().Height();
|
|
|
|
Point aPageOrg(nWidth, nHeight / 2);
|
|
Size aSize( nWidth * 3, nHeight * 2);
|
|
|
|
InitWindows(aPageOrg, aSize, Point(-1, -1), true);
|
|
|
|
Point aVisAreaPos;
|
|
|
|
if ( GetDocSh()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
|
|
{
|
|
aVisAreaPos = GetDocSh()->GetVisArea(ASPECT_CONTENT).TopLeft();
|
|
}
|
|
|
|
GetView()->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aSize));
|
|
|
|
UpdateScrollBars();
|
|
|
|
Point aNewOrigin(mpActualPage->GetLeftBorder(), mpActualPage->GetUpperBorder());
|
|
GetView()->GetSdrPageView()->SetPageOrigin(aNewOrigin);
|
|
|
|
GetViewFrame()->GetBindings().Invalidate(SID_RULER_NULL_OFFSET);
|
|
|
|
// zoom onto (new) page size
|
|
GetViewFrame()->GetDispatcher()->Execute(SID_SIZE_PAGE,
|
|
SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
|
|
}
|
|
|
|
void DrawViewShell::GetStatusBarState(SfxItemSet& rSet)
|
|
{
|
|
/* Zoom-Item
|
|
Here we should propagate the corresponding value (Optimal ?, page width
|
|
or page) with the help of the ZoomItems !!! */
|
|
if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ATTR_ZOOM ) )
|
|
{
|
|
if (GetDocSh()->IsUIActive()
|
|
|| (SlideShow::IsRunning(GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow(&GetViewShellBase())) // IASS
|
|
|| !GetActiveWindow())
|
|
{
|
|
rSet.DisableItem( SID_ATTR_ZOOM );
|
|
}
|
|
else
|
|
{
|
|
std::unique_ptr<SvxZoomItem> pZoomItem;
|
|
sal_uInt16 nZoom = static_cast<sal_uInt16>(GetActiveWindow()->GetZoom());
|
|
|
|
if( mbZoomOnPage )
|
|
pZoomItem.reset(new SvxZoomItem( SvxZoomType::WHOLEPAGE, nZoom ));
|
|
else
|
|
pZoomItem.reset(new SvxZoomItem( SvxZoomType::PERCENT, nZoom ));
|
|
|
|
// constrain area
|
|
SvxZoomEnableFlags nZoomValues = SvxZoomEnableFlags::ALL;
|
|
SdrPageView* pPageView = mpDrawView->GetSdrPageView();
|
|
|
|
if( pPageView && pPageView->GetObjList()->GetObjCount() == 0 )
|
|
{
|
|
nZoomValues &= ~SvxZoomEnableFlags::OPTIMAL;
|
|
}
|
|
|
|
pZoomItem->SetValueSet( nZoomValues );
|
|
rSet.Put( std::move(pZoomItem) );
|
|
}
|
|
}
|
|
if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ATTR_ZOOMSLIDER ) )
|
|
{
|
|
rtl::Reference< sd::SlideShow > xSlideshow( SlideShow::GetSlideShow( GetDoc() ) );
|
|
if (GetDocSh()->IsUIActive()
|
|
|| (xSlideshow.is() && xSlideshow->isRunning() && !xSlideshow->IsInteractiveSlideshow()) // IASS
|
|
|| !GetActiveWindow() )
|
|
{
|
|
rSet.DisableItem( SID_ATTR_ZOOMSLIDER );
|
|
}
|
|
else
|
|
{
|
|
sd::Window * pActiveWindow = GetActiveWindow();
|
|
SvxZoomSliderItem aZoomItem( static_cast<sal_uInt16>(pActiveWindow->GetZoom()), static_cast<sal_uInt16>(pActiveWindow->GetMinZoom()), static_cast<sal_uInt16>(pActiveWindow->GetMaxZoom()) ) ;
|
|
|
|
SdrPageView* pPageView = mpDrawView->GetSdrPageView();
|
|
if( pPageView )
|
|
{
|
|
Point aPagePos(0, 0);
|
|
Size aPageSize = pPageView->GetPage()->GetSize();
|
|
|
|
aPagePos.AdjustX(aPageSize.Width() / 2 );
|
|
aPageSize.setWidth( static_cast<::tools::Long>(aPageSize.Width() * 1.03) );
|
|
|
|
aPagePos.AdjustY(aPageSize.Height() / 2 );
|
|
aPageSize.setHeight( static_cast<::tools::Long>(aPageSize.Height() * 1.03) );
|
|
aPagePos.AdjustY( -(aPageSize.Height() / 2) );
|
|
|
|
aPagePos.AdjustX( -(aPageSize.Width() / 2) );
|
|
|
|
::tools::Rectangle aFullPageZoomRect( aPagePos, aPageSize );
|
|
aZoomItem.AddSnappingPoint( pActiveWindow->GetZoomForRect( aFullPageZoomRect ) );
|
|
}
|
|
aZoomItem.AddSnappingPoint(100);
|
|
rSet.Put( aZoomItem );
|
|
}
|
|
}
|
|
|
|
SdrPageView* pPageView = mpDrawView->GetSdrPageView();
|
|
if (pPageView)
|
|
{
|
|
Point aPos = GetActiveWindow()->PixelToLogic(maMousePos);
|
|
pPageView->LogicToPagePos(aPos);
|
|
Fraction aUIScale(GetDoc()->GetUIScale());
|
|
aPos.setX( ::tools::Long(aPos.X() / aUIScale) );
|
|
aPos.setY( ::tools::Long(aPos.Y() / aUIScale) );
|
|
|
|
// position- and size items
|
|
if ( mpDrawView->IsAction() )
|
|
{
|
|
::tools::Rectangle aRect;
|
|
mpDrawView->TakeActionRect( aRect );
|
|
|
|
if ( aRect.IsEmpty() )
|
|
rSet.Put( SfxPointItem(SID_ATTR_POSITION, aPos) );
|
|
else
|
|
{
|
|
pPageView->LogicToPagePos(aRect);
|
|
aPos = aRect.TopLeft();
|
|
aPos.setX( ::tools::Long(aPos.X() / aUIScale) );
|
|
aPos.setY( ::tools::Long(aPos.Y() / aUIScale) );
|
|
rSet.Put( SfxPointItem( SID_ATTR_POSITION, aPos) );
|
|
Size aSize( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() );
|
|
aSize.setHeight( ::tools::Long(aSize.Height() / aUIScale) );
|
|
aSize.setWidth( ::tools::Long(aSize.Width() / aUIScale) );
|
|
rSet.Put( SvxSizeItem( SID_ATTR_SIZE, aSize) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
|
|
if ( rMarkList.GetMarkCount() != 0 )
|
|
{
|
|
::tools::Rectangle aRect = mpDrawView->GetAllMarkedRect();
|
|
pPageView->LogicToPagePos(aRect);
|
|
|
|
// Show the position of the selected shape(s)
|
|
Point aShapePosition (aRect.TopLeft());
|
|
aShapePosition.setX( ::tools::Long(aShapePosition.X() / aUIScale) );
|
|
aShapePosition.setY( ::tools::Long(aShapePosition.Y() / aUIScale) );
|
|
rSet.Put (SfxPointItem(SID_ATTR_POSITION, aShapePosition));
|
|
|
|
Size aSize( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() );
|
|
aSize.setHeight( ::tools::Long(aSize.Height() / aUIScale) );
|
|
aSize.setWidth( ::tools::Long(aSize.Width() / aUIScale) );
|
|
rSet.Put( SvxSizeItem( SID_ATTR_SIZE, aSize) );
|
|
}
|
|
else
|
|
{
|
|
rSet.Put( SfxPointItem(SID_ATTR_POSITION, aPos) );
|
|
rSet.Put( SvxSizeItem( SID_ATTR_SIZE, Size( 0, 0 ) ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Display of current page and layer.
|
|
if( SfxItemState::DEFAULT == rSet.GetItemState( SID_STATUS_PAGE ) )
|
|
{
|
|
sal_Int32 nPageCount = sal_Int32(GetDoc()->GetSdPageCount(mePageKind));
|
|
sal_Int32 nActivePageCount = sal_Int32(GetDoc()->GetActiveSdPageCount());
|
|
// Always show the slide/page number.
|
|
OUString aOUString;
|
|
if (GetDoc()->GetDocumentType() == DocumentType::Draw)
|
|
aOUString = (nPageCount == nActivePageCount) ? SdResId(STR_SD_PAGE_COUNT_DRAW) : SdResId(STR_SD_PAGE_COUNT_CUSTOM_DRAW);
|
|
else
|
|
aOUString = (nPageCount == nActivePageCount) ? SdResId(STR_SD_PAGE_COUNT) : SdResId(STR_SD_PAGE_COUNT_CUSTOM);
|
|
|
|
aOUString = aOUString.replaceFirst("%1", OUString::number(maTabControl->GetCurPagePos() + 1));
|
|
aOUString = aOUString.replaceFirst("%2", OUString::number(nPageCount));
|
|
if(nPageCount != nActivePageCount)
|
|
aOUString = aOUString.replaceFirst("%3", OUString::number(nActivePageCount));
|
|
|
|
// If in layer mode additionally show the layer that contains all
|
|
// selected shapes of the page. If the shapes are distributed on
|
|
// more than one layer, no layer name is shown.
|
|
if (IsLayerModeActive())
|
|
{
|
|
SdrLayerAdmin& rLayerAdmin = GetDoc()->GetLayerAdmin();
|
|
SdrLayerID nLayer(0), nOldLayer(0);
|
|
SdrObject* pObj = nullptr;
|
|
const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
|
|
const size_t nMarkCount = rMarkList.GetMarkCount();
|
|
bool bOneLayer = true;
|
|
|
|
// Use the first ten selected shapes as a (hopefully
|
|
// representative) sample of all shapes of the current page.
|
|
// Detect whether they belong to the same layer.
|
|
for( size_t j = 0; j < nMarkCount && bOneLayer && j < 10; ++j )
|
|
{
|
|
pObj = rMarkList.GetMark( j )->GetMarkedSdrObj();
|
|
if( pObj )
|
|
{
|
|
nLayer = pObj->GetLayer();
|
|
|
|
if( j != 0 && nLayer != nOldLayer )
|
|
bOneLayer = false;
|
|
|
|
nOldLayer = nLayer;
|
|
}
|
|
}
|
|
|
|
// Append the layer name to the current page number.
|
|
if( bOneLayer && nMarkCount )
|
|
{
|
|
SdrLayer* pLayer = rLayerAdmin.GetLayerPerID( nLayer );
|
|
if( pLayer )
|
|
{
|
|
aOUString += " (" + LayerTabBar::convertToLocalizedName(pLayer->GetName()) + ")";
|
|
}
|
|
}
|
|
}
|
|
|
|
rSet.Put (SfxStringItem (SID_STATUS_PAGE, aOUString));
|
|
}
|
|
// Layout
|
|
if( SfxItemState::DEFAULT == rSet.GetItemState( SID_STATUS_LAYOUT ) )
|
|
{
|
|
OUString aString = mpActualPage->GetLayoutName();
|
|
sal_Int32 nPos = aString.indexOf(SD_LT_SEPARATOR);
|
|
if (nPos != -1)
|
|
aString = aString.copy(0, nPos);
|
|
rSet.Put( SfxStringItem( SID_STATUS_LAYOUT, aString ) );
|
|
}
|
|
// Scale
|
|
if( SfxItemState::DEFAULT == rSet.GetItemState( SID_SCALE ) )
|
|
{
|
|
const Fraction& aUIScale = GetDoc()->GetUIScale();
|
|
OUString aString = OUString::number(aUIScale.GetNumerator()) +
|
|
":" + OUString::number(aUIScale.GetDenominator());
|
|
rSet.Put( SfxStringItem( SID_SCALE, aString ) );
|
|
}
|
|
}
|
|
|
|
void DrawViewShell::Notify (SfxBroadcaster&, const SfxHint& rHint)
|
|
{
|
|
if (rHint.GetId()!=SfxHintId::ModeChanged)
|
|
return;
|
|
|
|
// Change to selection when turning on read-only mode.
|
|
if(GetDocSh()->IsReadOnly() && dynamic_cast< FuSelection* >( GetCurrentFunction().get() ) )
|
|
{
|
|
SfxRequest aReq(SID_OBJECT_SELECT, SfxCallMode::SLOT, GetDoc()->GetItemPool());
|
|
FuPermanent(aReq);
|
|
}
|
|
|
|
// Turn on design mode when document is not read-only.
|
|
if (GetDocSh()->IsReadOnly() != mbReadOnly )
|
|
{
|
|
mbReadOnly = GetDocSh()->IsReadOnly();
|
|
|
|
SfxBoolItem aItem( SID_FM_DESIGN_MODE, !mbReadOnly );
|
|
GetViewFrame()->GetDispatcher()->ExecuteList(SID_FM_DESIGN_MODE,
|
|
SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { &aItem });
|
|
}
|
|
|
|
}
|
|
|
|
void DrawViewShell::ExecuteAnnotation (SfxRequest const & rRequest)
|
|
{
|
|
if (mpAnnotationManager)
|
|
mpAnnotationManager->ExecuteAnnotation( rRequest );
|
|
}
|
|
|
|
void DrawViewShell::GetAnnotationState (SfxItemSet& rItemSet )
|
|
{
|
|
if (mpAnnotationManager)
|
|
mpAnnotationManager->GetAnnotationState( rItemSet );
|
|
}
|
|
|
|
OUString const & DrawViewShell::GetSidebarContextName() const
|
|
{
|
|
svx::sidebar::SelectionAnalyzer::ViewType eViewType (svx::sidebar::SelectionAnalyzer::ViewType::Standard);
|
|
switch (mePageKind)
|
|
{
|
|
case PageKind::Handout:
|
|
eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Handout;
|
|
break;
|
|
case PageKind::Notes:
|
|
eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Notes;
|
|
break;
|
|
case PageKind::Standard:
|
|
if (meEditMode == EditMode::MasterPage)
|
|
eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Master;
|
|
else
|
|
eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Standard;
|
|
break;
|
|
}
|
|
const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
|
|
return EnumContext::GetContextName(
|
|
svx::sidebar::SelectionAnalyzer::GetContextForSelection_SD(
|
|
rMarkList,
|
|
eViewType));
|
|
}
|
|
|
|
void DrawViewShell::ExecGoToNextPage (SfxRequest& rReq)
|
|
{
|
|
SetCurrentFunction( FuNavigation::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
|
|
Cancel();
|
|
}
|
|
|
|
void DrawViewShell::GetStateGoToNextPage (SfxItemSet& rSet)
|
|
{
|
|
SdPage* pPage = GetActualPage();
|
|
sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
|
|
sal_uInt16 totalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
|
|
if (nSdPage + 1 >= totalPages)
|
|
rSet.DisableItem( SID_GO_TO_NEXT_PAGE );
|
|
}
|
|
|
|
void DrawViewShell::ExecGoToPreviousPage (SfxRequest& rReq)
|
|
{
|
|
SetCurrentFunction( FuNavigation::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
|
|
Cancel();
|
|
}
|
|
|
|
void DrawViewShell::GetStateGoToPreviousPage (SfxItemSet& rSet)
|
|
{
|
|
SdPage* pPage = GetActualPage();
|
|
sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
|
|
if (nSdPage == 0)
|
|
rSet.DisableItem( SID_GO_TO_PREVIOUS_PAGE );
|
|
}
|
|
|
|
|
|
void DrawViewShell::ExecGoToFirstPage (SfxRequest& rReq)
|
|
{
|
|
SetCurrentFunction( FuNavigation::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
|
|
Cancel();
|
|
}
|
|
|
|
void DrawViewShell::GetStateGoToFirstPage (SfxItemSet& rSet)
|
|
{
|
|
SdPage* pPage = GetActualPage();
|
|
sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
|
|
if (nSdPage == 0)
|
|
rSet.DisableItem( SID_GO_TO_FIRST_PAGE );
|
|
}
|
|
|
|
void DrawViewShell::ExecGoToLastPage (SfxRequest& rReq)
|
|
{
|
|
SetCurrentFunction( FuNavigation::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
|
|
Cancel();
|
|
}
|
|
|
|
void DrawViewShell::GetStateGoToLastPage (SfxItemSet& rSet)
|
|
{
|
|
SdPage* pPage = GetActualPage();
|
|
sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
|
|
sal_uInt16 totalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
|
|
if (nSdPage + 1 >= totalPages)
|
|
rSet.DisableItem( SID_GO_TO_LAST_PAGE );
|
|
}
|
|
|
|
void DrawViewShell::ExecGoToPage (SfxRequest& rReq)
|
|
{
|
|
SetCurrentFunction( FuNavigation::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
|
|
Cancel();
|
|
}
|
|
|
|
void DrawViewShell::GetStateGoToPage (SfxItemSet& rSet)
|
|
{
|
|
if (meEditMode == EditMode::MasterPage)
|
|
rSet.DisableItem( SID_GO_TO_PAGE );
|
|
}
|
|
|
|
} // end of namespace sd
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|