/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using vcl::EnumContext; namespace sd { bool DrawViewShell::mbPipette = false; 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::Create(this, pParentWindow)) , mbIsLayerModeActive(false) , mbIsInSwitchPage(false) , mpSelectionChangeHandler(new svx::sidebar::SelectionChangeHandler( [this] () { return this->GetSidebarContextName(); }, uno::Reference(&rViewShellBase.GetDrawController()), vcl::EnumContext::Context::Default)) { if (pFrameViewArgument != nullptr) mpFrameView = pFrameViewArgument; else mpFrameView = new FrameView(GetDoc()); Construct(GetDocSh(), ePageKind); mpSelectionChangeHandler->Connect(); SetContextName(GetSidebarContextName()); doShow(); ConfigureAppBackgroundColor(); SD_MOD()->GetColorConfig().AddListener(this); } DrawViewShell::~DrawViewShell() { 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; mbMousePosFreezed = false; 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(), 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.set( static_cast< ::cppu::OWeakObject* >( new ScannerEventListener( this ) ), uno::UNO_QUERY ); } 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 DrawViewShell::CreateSubController() { css::uno::Reference 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 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, long nLeft, long nRight, long nUpper, 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); } long nWidth = mpActualPage->GetSize().Width(); 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())) ) { rSet.DisableItem( SID_ATTR_ZOOM ); } else { std::unique_ptr pZoomItem; sal_uInt16 nZoom = static_cast(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( *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(pActiveWindow->GetZoom()), static_cast(pActiveWindow->GetMinZoom()), static_cast(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(aPageSize.Width() * 1.03) ); aPagePos.AdjustY(aPageSize.Height() / 2 ); aPageSize.setHeight( static_cast(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( long(aPos.X() / aUIScale) ); aPos.setY( 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( long(aPos.X() / aUIScale) ); aPos.setY( long(aPos.Y() / aUIScale) ); rSet.Put( SfxPointItem( SID_ATTR_POSITION, aPos) ); Size aSize( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() ); aSize.setHeight( long(aSize.Height() / aUIScale) ); aSize.setWidth( 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( long(aShapePosition.X() / aUIScale) ); aShapePosition.setY( long(aShapePosition.Y() / aUIScale) ); rSet.Put (SfxPointItem(SID_ATTR_POSITION, aShapePosition)); Size aSize( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() ); aSize.setHeight( long(aSize.Height() / aUIScale) ); aSize.setWidth( 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 = (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 += " (" ; aOUString += pLayer->GetName(); aOUString += ")"; } } } 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 ) ); } } void DrawViewShell::Notify (SfxBroadcaster&, const SfxHint& rHint) { if (rHint.GetId()==SfxHintId::ModeChanged) { // 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.get() ) mpAnnotationManager->ExecuteAnnotation( rRequest ); } void DrawViewShell::GetAnnotationState (SfxItemSet& rItemSet ) { if( mpAnnotationManager.get() ) 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: */