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: */
|