cid#1607171 Data race condition
[LibreOffice.git] / sd / source / ui / view / drviewsa.cxx
bloba624679029683ea1097edad3c591081dcc5f34b5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <DrawViewShell.hxx>
21 #include <com/sun/star/scanner/ScannerManager.hpp>
22 #include <cppuhelper/implbase.hxx>
23 #include <comphelper/processfactory.hxx>
24 #include <editeng/sizeitem.hxx>
25 #include <svx/svdlayer.hxx>
26 #include <svx/svdograf.hxx>
27 #include <sfx2/zoomitem.hxx>
28 #include <sfx2/lokhelper.hxx>
29 #include <svx/svdpagv.hxx>
30 #include <svl/ptitem.hxx>
31 #include <svl/stritem.hxx>
32 #include <sfx2/request.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <svx/zoomslideritem.hxx>
35 #include <svl/eitem.hxx>
37 #include <sdcommands.h>
38 #include <svx/f3dchild.hxx>
39 #include <svx/clipfmtitem.hxx>
41 #include <sfx2/viewfrm.hxx>
42 #include <svtools/cliplistener.hxx>
43 #include <svx/float3d.hxx>
44 #include <svx/extedit.hxx>
45 #include <svx/sidebar/SelectionAnalyzer.hxx>
46 #include <svx/sidebar/SelectionChangeHandler.hxx>
47 #include <helpids.h>
49 #include <view/viewoverlaymanager.hxx>
50 #include <app.hrc>
51 #include <strings.hrc>
52 #include <sdmod.hxx>
53 #include <sdpage.hxx>
54 #include <FrameView.hxx>
55 #include <drawdoc.hxx>
56 #include <sdresid.hxx>
57 #include <DrawDocShell.hxx>
58 #include <Window.hxx>
59 #include <fupoor.hxx>
60 #include <fusel.hxx>
61 #include <funavig.hxx>
62 #include <drawview.hxx>
63 #include <SdUnoDrawView.hxx>
64 #include <ViewShellBase.hxx>
65 #include <slideshow.hxx>
66 #include <annotationmanager.hxx>
67 #include <DrawController.hxx>
68 #include <unomodel.hxx>
69 #include <comphelper/diagnose_ex.hxx>
70 #include <comphelper/lok.hxx>
71 #include <comphelper/servicehelper.hxx>
72 #include <LayerTabBar.hxx>
74 #include <memory>
76 using namespace ::com::sun::star;
77 using namespace ::com::sun::star::uno;
78 using vcl::EnumContext;
80 namespace sd {
82 bool DrawViewShell::mbPipette = false;
84 namespace {
86 class ScannerEventListener : public ::cppu::WeakImplHelper< lang::XEventListener >
88 private:
90 DrawViewShell* mpParent;
92 public:
94 explicit ScannerEventListener( DrawViewShell* pParent ) : mpParent( pParent ) {}
96 // XEventListener
97 virtual void SAL_CALL disposing( const lang::EventObject& rEventObject ) override;
99 void ParentDestroyed() { mpParent = nullptr; }
104 void SAL_CALL ScannerEventListener::disposing( const lang::EventObject& /*rEventObject*/ )
106 if( mpParent )
107 mpParent->ScannerEvent();
110 DrawViewShell::DrawViewShell( ViewShellBase& rViewShellBase, vcl::Window* pParentWindow, PageKind ePageKind, FrameView* pFrameViewArgument )
111 : ViewShell (pParentWindow, rViewShellBase)
112 , maTabControl(VclPtr<sd::TabControl>::Create(this, pParentWindow))
113 , mbIsLayerModeActive(false)
114 , mbIsInSwitchPage(false)
115 , mpSelectionChangeHandler(new svx::sidebar::SelectionChangeHandler(
116 [this] () { return this->GetSidebarContextName(); },
117 uno::Reference<frame::XController>(rViewShellBase.GetDrawController()),
118 vcl::EnumContext::Context::Default))
119 , mbMouseButtonDown(false)
120 , mbMouseSelecting(false)
122 if (pFrameViewArgument != nullptr)
123 mpFrameView = pFrameViewArgument;
124 else
125 mpFrameView = new FrameView(GetDoc());
126 Construct(GetDocSh(), ePageKind);
128 mpSelectionChangeHandler->Connect();
130 SetContextName(GetSidebarContextName());
132 doShow();
134 ConfigureAppBackgroundColor();
135 SdModule* mod = SdModule::get();
136 mod->GetColorConfig().AddListener(this);
138 if (comphelper::LibreOfficeKit::isActive())
140 // get the full page size in pixels
141 mpContentWindow->EnableMapMode();
142 Size aSize(mpContentWindow->LogicToPixel(GetView()->GetSdrPageView()->GetPage()->GetSize()));
143 // Disable map mode, so that it's possible to send mouse event
144 // coordinates in logic units
145 mpContentWindow->EnableMapMode(false);
147 // arrange UI elements again with new view size
148 GetParentWindow()->SetSizePixel(aSize);
149 Resize();
151 SdXImpressDocument* pModel = comphelper::getFromUnoTunnel<SdXImpressDocument>(rViewShellBase.GetCurrentDocument());
152 SfxLokHelper::notifyViewRenderState(&rViewShellBase, pModel);
156 DrawViewShell::~DrawViewShell()
158 suppress_fun_call_w_exception(ImplDestroy());
161 void DrawViewShell::ImplDestroy()
163 destroyXSlideShowInstance();
165 SdModule::get()->GetColorConfig().RemoveListener(this);
167 mpSelectionChangeHandler->Disconnect();
169 mpAnnotationManager.reset();
170 mpViewOverlayManager.reset();
172 OSL_ASSERT (GetViewShell()!=nullptr);
174 if( mxScannerListener.is() )
175 static_cast< ScannerEventListener* >( mxScannerListener.get() )->ParentDestroyed();
177 // Remove references to items within Svx3DWin
178 // (maybe do a listening sometime in Svx3DWin)
179 sal_uInt16 nId = Svx3DChildWindow::GetChildWindowId();
180 SfxChildWindow* pWindow = GetViewFrame() ? GetViewFrame()->GetChildWindow(nId) : nullptr;
181 if(pWindow)
183 Svx3DWin* p3DWin = static_cast< Svx3DWin* > (pWindow->GetWindow());
184 if(p3DWin)
185 p3DWin->DocumentReload();
188 EndListening (*GetDoc());
189 EndListening (*GetDocSh());
191 if( SlideShow::IsRunning(*this) )
192 StopSlideShow();
194 DisposeFunctions();
196 sal_uInt16 aPageCnt = GetDoc()->GetSdPageCount(mePageKind);
198 for (sal_uInt16 i = 0; i < aPageCnt; i++)
200 SdPage* pPage = GetDoc()->GetSdPage(i, mePageKind);
202 if (pPage == mpActualPage)
204 GetDoc()->SetSelected(pPage, true);
206 else
208 GetDoc()->SetSelected(pPage, false);
212 if ( mxClipEvtLstnr.is() )
214 mxClipEvtLstnr->RemoveListener( GetActiveWindow() );
215 mxClipEvtLstnr->ClearCallbackLink(); // prevent callback if another thread is waiting
216 mxClipEvtLstnr.clear();
219 mpDrawView.reset();
220 // Set mpView to NULL so that the destructor of the ViewShell base class
221 // does not access it.
222 mpView = nullptr;
224 mpFrameView->Disconnect();
225 maTabControl.disposeAndClear();
229 * common part of both constructors
231 void DrawViewShell::Construct(DrawDocShell* pDocSh, PageKind eInitialPageKind)
233 mpActualPage = nullptr;
234 mbReadOnly = GetDocSh()->IsReadOnly();
235 mxClipEvtLstnr.clear();
236 mbPastePossible = false;
237 mbIsLayerModeActive = false;
239 mpFrameView->Connect();
241 OSL_ASSERT (GetViewShell()!=nullptr);
243 SetPool( &GetDoc()->GetPool() );
245 GetDoc()->CreateFirstPages();
247 mpDrawView.reset( new DrawView(pDocSh, GetActiveWindow()->GetOutDev(), this) );
248 mpView = mpDrawView.get(); // Pointer of base class ViewShell
249 mpDrawView->SetSwapAsynchron(); // Asynchronous load of graphics
251 // We do not read the page kind from the frame view anymore so we have
252 // to set it in order to resync frame view and this view.
253 mpFrameView->SetPageKind(eInitialPageKind);
254 mePageKind = eInitialPageKind;
255 meEditMode = EditMode::Page;
256 DocumentType eDocType = GetDoc()->GetDocumentType(); // RTTI does not work here
257 switch (mePageKind)
259 case PageKind::Standard:
260 meShellType = ST_IMPRESS;
261 break;
263 case PageKind::Notes:
264 meShellType = ST_NOTES;
265 break;
267 case PageKind::Handout:
268 meShellType = ST_HANDOUT;
269 break;
272 Size aPageSize( GetDoc()->GetSdPage(0, mePageKind)->GetSize() );
273 Point aPageOrg( aPageSize.Width(), aPageSize.Height() / 2);
274 Size aSize(aPageSize.Width() * 3, aPageSize.Height() * 2);
275 InitWindows(aPageOrg, aSize, Point(-1, -1));
277 Point aVisAreaPos;
279 if ( pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
281 aVisAreaPos = pDocSh->GetVisArea(ASPECT_CONTENT).TopLeft();
284 mpDrawView->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aSize));
286 // objects can not grow bigger than ViewSize
287 GetDoc()->SetMaxObjSize(aSize);
289 // Split-Handler for TabControls
290 maTabControl->SetSplitHdl( LINK( this, DrawViewShell, TabSplitHdl ) );
292 /* In order to set the correct EditMode of the FrameView, we select another
293 one (small trick). */
294 if (mpFrameView->GetViewShEditMode(/*mePageKind*/) == EditMode::Page)
296 meEditMode = EditMode::MasterPage;
298 else
300 meEditMode = EditMode::Page;
303 // Use configuration of FrameView
304 ReadFrameViewData(mpFrameView);
306 if( eDocType == DocumentType::Draw )
308 GetActiveWindow()->SetHelpId( HID_SDGRAPHICVIEWSHELL );
310 else
312 if (mePageKind == PageKind::Notes)
314 GetActiveWindow()->SetHelpId( CMD_SID_NOTES_MODE );
316 // AutoLayouts have to be created
317 GetDoc()->StopWorkStartupDelay();
319 else if (mePageKind == PageKind::Handout)
321 GetActiveWindow()->SetHelpId( CMD_SID_HANDOUT_MASTER_MODE );
323 // AutoLayouts have to be created
324 GetDoc()->StopWorkStartupDelay();
326 else
328 GetActiveWindow()->SetHelpId( HID_SDDRAWVIEWSHELL );
332 // start selection function
333 SfxRequest aReq(SID_OBJECT_SELECT, SfxCallMode::SLOT, GetDoc()->GetItemPool());
334 FuPermanent(aReq);
335 mpDrawView->SetFrameDragSingles();
337 if (pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED)
339 mbZoomOnPage = false;
341 else
343 mbZoomOnPage = true;
346 mbIsRulerDrag = false;
348 SetName (u"DrawViewShell"_ustr);
350 mnLockCount = 0;
352 const uno::Reference< uno::XComponentContext >& xContext( ::comphelper::getProcessComponentContext() );
356 mxScannerManager = scanner::ScannerManager::create( xContext );
358 mxScannerListener = new ScannerEventListener( this );
360 catch (DeploymentException const &)
362 SAL_INFO("sd", "Scanner manager not available");
364 catch (Exception const &)
366 // Eat the exception and log it
367 // We can still continue if scanner manager is not available.
368 DBG_UNHANDLED_EXCEPTION("sd");
371 mpAnnotationManager.reset( new AnnotationManager( GetViewShellBase() ) );
372 mpViewOverlayManager.reset( new ViewOverlayManager( GetViewShellBase() ) );
375 void DrawViewShell::Init (bool bIsMainViewShell)
377 ViewShell::Init(bIsMainViewShell);
379 if (!IsListening(*GetDocSh()))
380 StartListening (*GetDocSh());
383 void DrawViewShell::Shutdown()
385 ViewShell::Shutdown();
387 if(SlideShow::IsRunning( GetViewShellBase() )
388 && !SlideShow::IsInteractiveSlideshow( &GetViewShellBase() )) // IASS
390 // Turn off effects.
391 GetDrawView()->SetAnimationMode(SdrAnimationMode::Disable);
395 css::uno::Reference<css::drawing::XDrawSubController> DrawViewShell::CreateSubController()
397 css::uno::Reference<css::drawing::XDrawSubController> xSubController;
399 if (IsMainViewShell())
401 // Create uno sub controller for the main view shell.
402 xSubController.set( new SdUnoDrawView( *this, *GetView()));
405 return xSubController;
408 bool DrawViewShell::RelocateToParentWindow (vcl::Window* pParentWindow)
410 // DrawViewShells can not be relocated to a new parent window at the
411 // moment, so return <FALSE/> except when the given parent window is the
412 // parent window that is already in use.
413 return pParentWindow==GetParentWindow();
417 * check if we have to draw a polyline
421 Polylines are represented by macros as a sequence of:
422 MoveTo (x, y)
423 LineTo (x, y) [or BezierTo (x, y)]
424 LineTo (x, y)
426 There is no end command for polylines. Therefore, we have to test all
427 commands in the requests for LineTo (BezierTo) and we have to gather
428 the point-parameter. The first not-LineTo leads to the creation of the
429 polyline from the gathered points.
432 void DrawViewShell::CheckLineTo(SfxRequest& rReq)
434 #ifdef DBG_UTIL
435 if(rReq.IsAPI())
437 if(SID_LINETO == rReq.GetSlot() || SID_BEZIERTO == rReq.GetSlot() || SID_MOVETO == rReq.GetSlot() )
439 OSL_FAIL("DrawViewShell::CheckLineTo: slots SID_LINETO, SID_BEZIERTO, SID_MOVETO no longer supported.");
442 #endif
444 rReq.Ignore ();
448 * Change page parameter if SID_PAGESIZE or SID_PAGEMARGIN
450 void DrawViewShell::SetupPage (Size const &rSize,
451 ::tools::Long nLeft,
452 ::tools::Long nRight,
453 ::tools::Long nUpper,
454 ::tools::Long nLower,
455 bool bSize,
456 bool bMargin,
457 bool bScaleAll)
459 sal_uInt16 nPageCnt = GetDoc()->GetMasterSdPageCount(mePageKind);
460 sal_uInt16 i;
462 for (i = 0; i < nPageCnt; i++)
464 // first, handle all master pages
465 SdPage *pPage = GetDoc()->GetMasterSdPage(i, mePageKind);
467 if( pPage )
469 if( bSize )
471 ::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
472 pPage->ScaleObjects(rSize, aBorderRect, bScaleAll);
473 pPage->SetSize(rSize);
476 if( bMargin )
478 pPage->SetLeftBorder(nLeft);
479 pPage->SetRightBorder(nRight);
480 pPage->SetUpperBorder(nUpper);
481 pPage->SetLowerBorder(nLower);
484 if ( mePageKind == PageKind::Standard )
486 GetDoc()->GetMasterSdPage(i, PageKind::Notes)->CreateTitleAndLayout();
489 pPage->CreateTitleAndLayout();
493 nPageCnt = GetDoc()->GetSdPageCount(mePageKind);
495 for (i = 0; i < nPageCnt; i++)
497 // then, handle all pages
498 SdPage *pPage = GetDoc()->GetSdPage(i, mePageKind);
500 if( pPage )
502 if( bSize )
504 ::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
505 pPage->ScaleObjects(rSize, aBorderRect, bScaleAll);
506 pPage->SetSize(rSize);
508 if( bMargin )
510 pPage->SetLeftBorder(nLeft);
511 pPage->SetRightBorder(nRight);
512 pPage->SetUpperBorder(nUpper);
513 pPage->SetLowerBorder(nLower);
516 if ( mePageKind == PageKind::Standard )
518 SdPage* pNotesPage = GetDoc()->GetSdPage(i, PageKind::Notes);
519 pNotesPage->SetAutoLayout( pNotesPage->GetAutoLayout() );
522 pPage->SetAutoLayout( pPage->GetAutoLayout() );
526 if ( mePageKind == PageKind::Standard )
528 SdPage* pHandoutPage = GetDoc()->GetSdPage(0, PageKind::Handout);
529 pHandoutPage->CreateTitleAndLayout(true);
532 ::tools::Long nWidth = mpActualPage->GetSize().Width();
533 ::tools::Long nHeight = mpActualPage->GetSize().Height();
535 Point aPageOrg(nWidth, nHeight / 2);
536 Size aSize( nWidth * 3, nHeight * 2);
538 InitWindows(aPageOrg, aSize, Point(-1, -1), true);
540 Point aVisAreaPos;
542 if ( GetDocSh()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
544 aVisAreaPos = GetDocSh()->GetVisArea(ASPECT_CONTENT).TopLeft();
547 GetView()->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aSize));
549 UpdateScrollBars();
551 Point aNewOrigin(mpActualPage->GetLeftBorder(), mpActualPage->GetUpperBorder());
552 GetView()->GetSdrPageView()->SetPageOrigin(aNewOrigin);
554 GetViewFrame()->GetBindings().Invalidate(SID_RULER_NULL_OFFSET);
556 // zoom onto (new) page size
557 GetViewFrame()->GetDispatcher()->Execute(SID_SIZE_PAGE,
558 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
561 void DrawViewShell::GetStatusBarState(SfxItemSet& rSet)
563 /* Zoom-Item
564 Here we should propagate the corresponding value (Optimal ?, page width
565 or page) with the help of the ZoomItems !!! */
566 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ATTR_ZOOM ) )
568 if (GetDocSh()->IsUIActive()
569 || (SlideShow::IsRunning(GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow(&GetViewShellBase())) // IASS
570 || !GetActiveWindow())
572 rSet.DisableItem( SID_ATTR_ZOOM );
574 else
576 std::unique_ptr<SvxZoomItem> pZoomItem;
577 sal_uInt16 nZoom = static_cast<sal_uInt16>(GetActiveWindow()->GetZoom());
579 if( mbZoomOnPage )
580 pZoomItem.reset(new SvxZoomItem( SvxZoomType::WHOLEPAGE, nZoom ));
581 else
582 pZoomItem.reset(new SvxZoomItem( SvxZoomType::PERCENT, nZoom ));
584 // constrain area
585 SvxZoomEnableFlags nZoomValues = SvxZoomEnableFlags::ALL;
586 SdrPageView* pPageView = mpDrawView->GetSdrPageView();
588 if( pPageView && pPageView->GetObjList()->GetObjCount() == 0 )
590 nZoomValues &= ~SvxZoomEnableFlags::OPTIMAL;
593 pZoomItem->SetValueSet( nZoomValues );
594 rSet.Put( std::move(pZoomItem) );
597 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ATTR_ZOOMSLIDER ) )
599 rtl::Reference< sd::SlideShow > xSlideshow( SlideShow::GetSlideShow( GetDoc() ) );
600 if (GetDocSh()->IsUIActive()
601 || (xSlideshow.is() && xSlideshow->isRunning() && !xSlideshow->IsInteractiveSlideshow()) // IASS
602 || !GetActiveWindow() )
604 rSet.DisableItem( SID_ATTR_ZOOMSLIDER );
606 else
608 sd::Window * pActiveWindow = GetActiveWindow();
609 SvxZoomSliderItem aZoomItem( static_cast<sal_uInt16>(pActiveWindow->GetZoom()), static_cast<sal_uInt16>(pActiveWindow->GetMinZoom()), static_cast<sal_uInt16>(pActiveWindow->GetMaxZoom()) ) ;
611 SdrPageView* pPageView = mpDrawView->GetSdrPageView();
612 if( pPageView )
614 Point aPagePos(0, 0);
615 Size aPageSize = pPageView->GetPage()->GetSize();
617 aPagePos.AdjustX(aPageSize.Width() / 2 );
618 aPageSize.setWidth( static_cast<::tools::Long>(aPageSize.Width() * 1.03) );
620 aPagePos.AdjustY(aPageSize.Height() / 2 );
621 aPageSize.setHeight( static_cast<::tools::Long>(aPageSize.Height() * 1.03) );
622 aPagePos.AdjustY( -(aPageSize.Height() / 2) );
624 aPagePos.AdjustX( -(aPageSize.Width() / 2) );
626 ::tools::Rectangle aFullPageZoomRect( aPagePos, aPageSize );
627 aZoomItem.AddSnappingPoint( pActiveWindow->GetZoomForRect( aFullPageZoomRect ) );
629 aZoomItem.AddSnappingPoint(100);
630 rSet.Put( aZoomItem );
634 SdrPageView* pPageView = mpDrawView->GetSdrPageView();
635 if (pPageView)
637 Point aPos = GetActiveWindow()->PixelToLogic(maMousePos);
638 pPageView->LogicToPagePos(aPos);
639 Fraction aUIScale(GetDoc()->GetUIScale());
640 aPos.setX( ::tools::Long(aPos.X() / aUIScale) );
641 aPos.setY( ::tools::Long(aPos.Y() / aUIScale) );
643 // position- and size items
644 if ( mpDrawView->IsAction() )
646 ::tools::Rectangle aRect;
647 mpDrawView->TakeActionRect( aRect );
649 if ( aRect.IsEmpty() )
650 rSet.Put( SfxPointItem(SID_ATTR_POSITION, aPos) );
651 else
653 pPageView->LogicToPagePos(aRect);
654 aPos = aRect.TopLeft();
655 aPos.setX( ::tools::Long(aPos.X() / aUIScale) );
656 aPos.setY( ::tools::Long(aPos.Y() / aUIScale) );
657 rSet.Put( SfxPointItem( SID_ATTR_POSITION, aPos) );
658 Size aSize( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() );
659 aSize.setHeight( ::tools::Long(aSize.Height() / aUIScale) );
660 aSize.setWidth( ::tools::Long(aSize.Width() / aUIScale) );
661 rSet.Put( SvxSizeItem( SID_ATTR_SIZE, aSize) );
664 else
666 const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
667 if ( rMarkList.GetMarkCount() != 0 )
669 ::tools::Rectangle aRect = mpDrawView->GetAllMarkedRect();
670 pPageView->LogicToPagePos(aRect);
672 // Show the position of the selected shape(s)
673 Point aShapePosition (aRect.TopLeft());
674 aShapePosition.setX( ::tools::Long(aShapePosition.X() / aUIScale) );
675 aShapePosition.setY( ::tools::Long(aShapePosition.Y() / aUIScale) );
676 rSet.Put (SfxPointItem(SID_ATTR_POSITION, aShapePosition));
678 Size aSize( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() );
679 aSize.setHeight( ::tools::Long(aSize.Height() / aUIScale) );
680 aSize.setWidth( ::tools::Long(aSize.Width() / aUIScale) );
681 rSet.Put( SvxSizeItem( SID_ATTR_SIZE, aSize) );
683 else
685 rSet.Put( SfxPointItem(SID_ATTR_POSITION, aPos) );
686 rSet.Put( SvxSizeItem( SID_ATTR_SIZE, Size( 0, 0 ) ) );
691 // Display of current page and layer.
692 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_STATUS_PAGE ) )
694 sal_Int32 nPageCount = sal_Int32(GetDoc()->GetSdPageCount(mePageKind));
695 sal_Int32 nActivePageCount = sal_Int32(GetDoc()->GetActiveSdPageCount());
696 // Always show the slide/page number.
697 OUString aOUString;
698 if (GetDoc()->GetDocumentType() == DocumentType::Draw)
699 aOUString = (nPageCount == nActivePageCount) ? SdResId(STR_SD_PAGE_COUNT_DRAW) : SdResId(STR_SD_PAGE_COUNT_CUSTOM_DRAW);
700 else
701 aOUString = (nPageCount == nActivePageCount) ? SdResId(STR_SD_PAGE_COUNT) : SdResId(STR_SD_PAGE_COUNT_CUSTOM);
703 aOUString = aOUString.replaceFirst("%1", OUString::number(maTabControl->GetCurPagePos() + 1));
704 aOUString = aOUString.replaceFirst("%2", OUString::number(nPageCount));
705 if(nPageCount != nActivePageCount)
706 aOUString = aOUString.replaceFirst("%3", OUString::number(nActivePageCount));
708 // If in layer mode additionally show the layer that contains all
709 // selected shapes of the page. If the shapes are distributed on
710 // more than one layer, no layer name is shown.
711 if (IsLayerModeActive())
713 SdrLayerAdmin& rLayerAdmin = GetDoc()->GetLayerAdmin();
714 SdrLayerID nLayer(0), nOldLayer(0);
715 SdrObject* pObj = nullptr;
716 const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
717 const size_t nMarkCount = rMarkList.GetMarkCount();
718 bool bOneLayer = true;
720 // Use the first ten selected shapes as a (hopefully
721 // representative) sample of all shapes of the current page.
722 // Detect whether they belong to the same layer.
723 for( size_t j = 0; j < nMarkCount && bOneLayer && j < 10; ++j )
725 pObj = rMarkList.GetMark( j )->GetMarkedSdrObj();
726 if( pObj )
728 nLayer = pObj->GetLayer();
730 if( j != 0 && nLayer != nOldLayer )
731 bOneLayer = false;
733 nOldLayer = nLayer;
737 // Append the layer name to the current page number.
738 if( bOneLayer && nMarkCount )
740 SdrLayer* pLayer = rLayerAdmin.GetLayerPerID( nLayer );
741 if( pLayer )
743 aOUString += " (" + LayerTabBar::convertToLocalizedName(pLayer->GetName()) + ")";
748 rSet.Put (SfxStringItem (SID_STATUS_PAGE, aOUString));
750 // Layout
751 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_STATUS_LAYOUT ) )
753 OUString aString = mpActualPage->GetLayoutName();
754 sal_Int32 nPos = aString.indexOf(SD_LT_SEPARATOR);
755 if (nPos != -1)
756 aString = aString.copy(0, nPos);
757 rSet.Put( SfxStringItem( SID_STATUS_LAYOUT, aString ) );
759 // Scale
760 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_SCALE ) )
762 const Fraction& aUIScale = GetDoc()->GetUIScale();
763 OUString aString = OUString::number(aUIScale.GetNumerator()) +
764 ":" + OUString::number(aUIScale.GetDenominator());
765 rSet.Put( SfxStringItem( SID_SCALE, aString ) );
769 void DrawViewShell::Notify (SfxBroadcaster&, const SfxHint& rHint)
771 if (rHint.GetId()!=SfxHintId::ModeChanged)
772 return;
774 // Change to selection when turning on read-only mode.
775 if(GetDocSh()->IsReadOnly() && dynamic_cast< FuSelection* >( GetCurrentFunction().get() ) )
777 SfxRequest aReq(SID_OBJECT_SELECT, SfxCallMode::SLOT, GetDoc()->GetItemPool());
778 FuPermanent(aReq);
781 // Turn on design mode when document is not read-only.
782 if (GetDocSh()->IsReadOnly() != mbReadOnly )
784 mbReadOnly = GetDocSh()->IsReadOnly();
786 SfxBoolItem aItem( SID_FM_DESIGN_MODE, !mbReadOnly );
787 GetViewFrame()->GetDispatcher()->ExecuteList(SID_FM_DESIGN_MODE,
788 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { &aItem });
793 void DrawViewShell::ExecuteAnnotation (SfxRequest const & rRequest)
795 if (mpAnnotationManager)
796 mpAnnotationManager->ExecuteAnnotation( rRequest );
799 void DrawViewShell::GetAnnotationState (SfxItemSet& rItemSet )
801 if (mpAnnotationManager)
802 mpAnnotationManager->GetAnnotationState( rItemSet );
805 OUString const & DrawViewShell::GetSidebarContextName() const
807 svx::sidebar::SelectionAnalyzer::ViewType eViewType (svx::sidebar::SelectionAnalyzer::ViewType::Standard);
808 switch (mePageKind)
810 case PageKind::Handout:
811 eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Handout;
812 break;
813 case PageKind::Notes:
814 eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Notes;
815 break;
816 case PageKind::Standard:
817 if (meEditMode == EditMode::MasterPage)
818 eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Master;
819 else
820 eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Standard;
821 break;
823 const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
824 return EnumContext::GetContextName(
825 svx::sidebar::SelectionAnalyzer::GetContextForSelection_SD(
826 rMarkList,
827 eViewType));
830 void DrawViewShell::ExecGoToNextPage (SfxRequest& rReq)
832 SetCurrentFunction( FuNavigation::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
833 Cancel();
836 void DrawViewShell::GetStateGoToNextPage (SfxItemSet& rSet)
838 SdPage* pPage = GetActualPage();
839 sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
840 sal_uInt16 totalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
841 if (nSdPage + 1 >= totalPages)
842 rSet.DisableItem( SID_GO_TO_NEXT_PAGE );
845 void DrawViewShell::ExecGoToPreviousPage (SfxRequest& rReq)
847 SetCurrentFunction( FuNavigation::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
848 Cancel();
851 void DrawViewShell::GetStateGoToPreviousPage (SfxItemSet& rSet)
853 SdPage* pPage = GetActualPage();
854 sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
855 if (nSdPage == 0)
856 rSet.DisableItem( SID_GO_TO_PREVIOUS_PAGE );
860 void DrawViewShell::ExecGoToFirstPage (SfxRequest& rReq)
862 SetCurrentFunction( FuNavigation::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
863 Cancel();
866 void DrawViewShell::GetStateGoToFirstPage (SfxItemSet& rSet)
868 SdPage* pPage = GetActualPage();
869 sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
870 if (nSdPage == 0)
871 rSet.DisableItem( SID_GO_TO_FIRST_PAGE );
874 void DrawViewShell::ExecGoToLastPage (SfxRequest& rReq)
876 SetCurrentFunction( FuNavigation::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
877 Cancel();
880 void DrawViewShell::GetStateGoToLastPage (SfxItemSet& rSet)
882 SdPage* pPage = GetActualPage();
883 sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
884 sal_uInt16 totalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
885 if (nSdPage + 1 >= totalPages)
886 rSet.DisableItem( SID_GO_TO_LAST_PAGE );
889 void DrawViewShell::ExecGoToPage (SfxRequest& rReq)
891 SetCurrentFunction( FuNavigation::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
892 Cancel();
895 void DrawViewShell::GetStateGoToPage (SfxItemSet& rSet)
897 if (meEditMode == EditMode::MasterPage)
898 rSet.DisableItem( SID_GO_TO_PAGE );
901 } // end of namespace sd
903 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */