diff options
Diffstat (limited to '')
-rw-r--r-- | sd/source/ui/view/drviewsa.cxx | 873 |
1 files changed, 873 insertions, 0 deletions
diff --git a/sd/source/ui/view/drviewsa.cxx b/sd/source/ui/view/drviewsa.cxx new file mode 100644 index 0000000000..5d5cfe6132 --- /dev/null +++ b/sd/source/ui/view/drviewsa.cxx @@ -0,0 +1,873 @@ +/* -*- 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(); + SD_MOD()->GetColorConfig().AddListener(this); + maViewOptions.mnDocBackgroundColor = SD_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor; + + if (comphelper::LibreOfficeKit::isActive()) + { + SdXImpressDocument* pModel = comphelper::getFromUnoTunnel<SdXImpressDocument>(rViewShellBase.GetCurrentDocument()); + SfxLokHelper::notifyViewRenderState(&rViewShellBase, pModel); + } +} + +DrawViewShell::~DrawViewShell() +{ + suppress_fun_call_w_exception(ImplDestroy()); +} + +void DrawViewShell::ImplDestroy() +{ + SD_MOD()->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 ("DrawViewShell"); + + mnLockCount = 0; + + 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() ) ) + { + // 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()) + || !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()) || !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 + { + if ( mpDrawView->AreObjectsMarked() ) + { + ::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; + } + return EnumContext::GetContextName( + svx::sidebar::SelectionAnalyzer::GetContextForSelection_SD( + mpDrawView->GetMarkedObjectList(), + 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 ); +} + + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |