cid#1607171 Data race condition
[LibreOffice.git] / sd / source / ui / view / viewshe2.cxx
blob3c2e70b37184302191806c1fdef10a36490eb3d9
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 <com/sun/star/embed/EmbedVerbs.hpp>
21 #include <com/sun/star/embed/XEmbeddedObject.hpp>
23 #include <ViewShell.hxx>
24 #include <ViewShellHint.hxx>
26 #include <ViewShellImplementation.hxx>
27 #include <FactoryIds.hxx>
29 #include <svx/svxids.hrc>
30 #include <svx/svdpagv.hxx>
31 #include <sfx2/dispatch.hxx>
32 #include <svx/ruler.hxx>
33 #include <editeng/outliner.hxx>
34 #include <svtools/ehdl.hxx>
35 #include <svx/svdoole2.hxx>
36 #include <svtools/sfxecode.hxx>
37 #include <unotools/moduleoptions.hxx>
38 #include <comphelper/classids.hxx>
39 #include <osl/diagnose.h>
41 #include <strings.hrc>
42 #include <app.hrc>
43 #include <unokywds.hxx>
45 #include <sdundogr.hxx>
46 #include <FrameView.hxx>
47 #include <sdresid.hxx>
48 #include <drawdoc.hxx>
49 #include <View.hxx>
50 #include <fupoor.hxx>
51 #include <Client.hxx>
52 #include <DrawDocShell.hxx>
53 #include <sdpage.hxx>
54 #include <DrawViewShell.hxx>
55 #include <ViewShellBase.hxx>
57 #include <Window.hxx>
59 #include <sfx2/viewfrm.hxx>
60 #include <svtools/soerr.hxx>
61 #include <svx/charthelper.hxx>
62 #include <comphelper/lok.hxx>
64 using namespace com::sun::star;
66 namespace
68 inline double getViewToScrollScalarForPanAcrossPages(sal_uInt16 nTotalPages, double fVisibleHeight,
69 ::tools::Long nScrollRangeMax)
71 // fTotalScrollableRange is (1 - fVisibleHeight) for all of the
72 // pages except the last one. Because switch to the next page
73 // happens when the view reaches bottom.
74 double fTotalScrollableRange = (nTotalPages - 1) * (1 - fVisibleHeight) + 1.0;
75 return nScrollRangeMax / fTotalScrollableRange;
79 namespace sd {
81 /**
82 * adjust Thumbpos and VisibleSize
84 void ViewShell::UpdateScrollBars()
86 if (mpHorizontalScrollBar)
88 ::tools::Long nW = static_cast<::tools::Long>(std::min(1.0, mpContentWindow->GetVisibleWidth()) * 32000);
89 ::tools::Long nX = static_cast<::tools::Long>(mpContentWindow->GetVisibleX() * 32000);
90 mpHorizontalScrollBar->SetVisibleSize(nW);
91 mpHorizontalScrollBar->SetThumbPos(nX);
92 nW = 32000 - nW;
93 ::tools::Long nLine = static_cast<::tools::Long>(mpContentWindow->GetScrlLineWidth() * nW);
94 ::tools::Long nPage = static_cast<::tools::Long>(mpContentWindow->GetScrlPageWidth() * nW);
95 mpHorizontalScrollBar->SetLineSize(nLine);
96 mpHorizontalScrollBar->SetPageSize(nPage);
99 if (mpVerticalScrollBar)
101 if (CanPanAcrossPages())
103 SdPage* pPage = static_cast<DrawViewShell*>(this)->GetActualPage();
104 sal_uInt16 nCurPage = (pPage->GetPageNum() - 1) / 2;
105 sal_uInt16 nTotalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
107 // nRangeMax is max int, and not ::tools::Long since the underlying
108 // implementation weld::Scrollbar uses int
109 ::tools::Long nRangeMax = std::numeric_limits<int>::max();
110 double fVisibleHeight = std::min(mpContentWindow->GetVisibleHeight(), 1.0);
111 double fMappingFactor
112 = getViewToScrollScalarForPanAcrossPages(nTotalPages, fVisibleHeight, nRangeMax);
113 double fVisibleY = std::max(0.0, mpContentWindow->GetVisibleY());
114 double fCurrentThumbPos = nCurPage * (1 - fVisibleHeight) + fVisibleY;
115 double fScrollLineHeight
116 = mpContentWindow->GetScrlLineHeight() * (1.0 - fVisibleHeight);
117 double fScrollPageHeight
118 = mpContentWindow->GetScrlPageHeight() * (1.0 - fVisibleHeight);
120 mpVerticalScrollBar->SetRange(Range(0, nRangeMax));
121 mpVerticalScrollBar->SetVisibleSize(fVisibleHeight * fMappingFactor);
122 mpVerticalScrollBar->SetThumbPos(fCurrentThumbPos * fMappingFactor);
123 mpVerticalScrollBar->SetLineSize(fScrollLineHeight * fMappingFactor);
124 mpVerticalScrollBar->SetPageSize(fScrollPageHeight * fMappingFactor);
126 else if (IsPageFlipMode()) // ie in zoom mode where no panning
128 SdPage* pPage = static_cast<DrawViewShell*>(this)->GetActualPage();
129 sal_uInt16 nCurPage = (pPage->GetPageNum() - 1) / 2;
130 sal_uInt16 nTotalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
131 mpVerticalScrollBar->SetRange(Range(0,256*nTotalPages));
132 mpVerticalScrollBar->SetVisibleSize(256);
133 mpVerticalScrollBar->SetThumbPos(256*nCurPage);
134 mpVerticalScrollBar->SetLineSize(256);
135 mpVerticalScrollBar->SetPageSize(256);
137 else // single page pan mode
139 ::tools::Long nH = static_cast<::tools::Long>(std::min(1.0, mpContentWindow->GetVisibleHeight()) * 32000);
140 ::tools::Long nY = static_cast<::tools::Long>(mpContentWindow->GetVisibleY() * 32000);
142 mpVerticalScrollBar->SetRange(Range(0,32000));
143 mpVerticalScrollBar->SetVisibleSize(nH);
144 mpVerticalScrollBar->SetThumbPos(nY);
145 nH = 32000 - nH;
146 ::tools::Long nLine = static_cast<::tools::Long>(mpContentWindow->GetScrlLineHeight() * nH);
147 ::tools::Long nPage = static_cast<::tools::Long>(mpContentWindow->GetScrlPageHeight() * nH);
148 mpVerticalScrollBar->SetLineSize(nLine);
149 mpVerticalScrollBar->SetPageSize(nPage);
153 if (mbHasRulers)
155 UpdateHRuler();
156 UpdateVRuler();
161 * Handling for horizontal Scrollbars
163 IMPL_LINK_NOARG(ViewShell, HScrollHdl, weld::Scrollbar&, void)
165 VirtHScrollHdl(mpHorizontalScrollBar);
169 * virtual scroll handler for horizontal Scrollbars
171 void ViewShell::VirtHScrollHdl(ScrollAdaptor* pHScroll)
173 double fX = static_cast<double>(pHScroll->GetThumbPos()) / pHScroll->GetRange().Len();
175 // scroll all windows of the column
176 ::sd::View* pView = GetView();
177 OutlinerView* pOLV = nullptr;
179 if (pView)
180 pOLV = pView->GetTextEditOutlinerView();
182 if (pOLV)
183 pOLV->HideCursor();
185 mpContentWindow->SetVisibleXY(fX, -1);
187 ::tools::Rectangle aVisArea = GetDocSh()->GetVisArea(ASPECT_CONTENT);
188 Point aVisAreaPos = GetActiveWindow()->PixelToLogic( Point(0,0) );
189 aVisArea.SetPos(aVisAreaPos);
190 GetDocSh()->SetVisArea(aVisArea);
192 Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
193 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
194 VisAreaChanged(aVisAreaWin);
196 if (pView)
198 pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
201 if (pOLV)
202 pOLV->ShowCursor();
204 if (mbHasRulers)
205 UpdateHRuler();
209 * handling for vertical Scrollbars
211 IMPL_LINK_NOARG(ViewShell, VScrollHdl, weld::Scrollbar&, void)
213 VirtVScrollHdl(mpVerticalScrollBar);
217 * handling for vertical Scrollbars
219 void ViewShell::VirtVScrollHdl(ScrollAdaptor* pVScroll)
221 auto doScrollView = [&](double fY)
223 ::sd::View* pView = GetView();
224 OutlinerView* pOLV = nullptr;
226 if (pView)
227 pOLV = pView->GetTextEditOutlinerView();
229 if (pOLV)
230 pOLV->HideCursor();
232 mpContentWindow->SetVisibleXY(-1, fY);
234 ::tools::Rectangle aVisArea = GetDocSh()->GetVisArea(ASPECT_CONTENT);
235 Point aVisAreaPos = GetActiveWindow()->PixelToLogic( Point(0,0) );
236 aVisArea.SetPos(aVisAreaPos);
237 GetDocSh()->SetVisArea(aVisArea);
239 Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
240 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
241 VisAreaChanged(aVisAreaWin);
243 if (pView)
245 pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
248 if (pOLV)
249 pOLV->ShowCursor();
251 if (mbHasRulers)
252 UpdateVRuler();
255 if (CanPanAcrossPages())
257 SdPage* pPage = static_cast<DrawViewShell*>(this)->GetActualPage();
258 auto nCurPage = (pPage->GetPageNum() - 1) >> 1;
259 sal_uInt16 nTotalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
261 double fVisibleHeight = mpContentWindow->GetVisibleHeight();
262 double fMappingFactor = getViewToScrollScalarForPanAcrossPages(nTotalPages, fVisibleHeight,
263 pVScroll->GetRange().Max());
265 double fScrollableDistancePerPage = 1 - std::min(fVisibleHeight, 1.0);
267 sal_uInt16 nNewPage
268 = std::min((pVScroll->GetThumbPos() / fMappingFactor) / fScrollableDistancePerPage,
269 static_cast<double>(nTotalPages - 1));
271 if (nCurPage != nNewPage)
272 static_cast<DrawViewShell*>(this)->SwitchPage(nNewPage);
274 double fNewPageStart = nNewPage * fScrollableDistancePerPage;
275 double fY = (pVScroll->GetThumbPos() / fMappingFactor) - fNewPageStart;
277 doScrollView(fY);
279 else if (IsPageFlipMode())
281 SdPage* pPage = static_cast<DrawViewShell*>(this)->GetActualPage();
282 auto nCurPage = (pPage->GetPageNum() - 1) >> 1;
283 sal_uInt16 nNewPage = static_cast<sal_uInt16>(pVScroll->GetThumbPos())/256;
284 if( nCurPage != nNewPage )
285 static_cast<DrawViewShell*>(this)->SwitchPage(nNewPage);
287 else // single page panning mode
289 double fY = static_cast<double>(pVScroll->GetThumbPos()) / pVScroll->GetRange().Len();
290 doScrollView(fY);
294 VclPtr<SvxRuler> ViewShell::CreateHRuler(::sd::Window* )
296 return nullptr;
299 VclPtr<SvxRuler> ViewShell::CreateVRuler(::sd::Window* )
301 return nullptr;
304 void ViewShell::UpdateHRuler()
308 void ViewShell::UpdateVRuler()
313 * Scroll a specific number of lines. Is used in the automatic scrolling
314 * (character/drag).
316 void ViewShell::ScrollLines(::tools::Long nLinesX, ::tools::Long nLinesY)
318 if ( nLinesX )
320 nLinesX *= mpHorizontalScrollBar->GetLineSize();
322 if ( nLinesY )
324 nLinesY *= mpVerticalScrollBar->GetLineSize();
327 Scroll(nLinesX, nLinesY);
330 void ViewShell::Scroll(::tools::Long nScrollX, ::tools::Long nScrollY)
332 if (nScrollX)
334 ::tools::Long nNewThumb = mpHorizontalScrollBar->GetThumbPos() + nScrollX;
335 mpHorizontalScrollBar->SetThumbPos(nNewThumb);
337 if (nScrollY)
339 ::tools::Long nNewThumb = mpVerticalScrollBar->GetThumbPos() + nScrollY;
340 mpVerticalScrollBar->SetThumbPos(nNewThumb);
342 double fX = static_cast<double>(mpHorizontalScrollBar->GetThumbPos()) /
343 mpHorizontalScrollBar->GetRange().Len();
344 double fY = static_cast<double>(mpVerticalScrollBar->GetThumbPos()) /
345 mpVerticalScrollBar->GetRange().Len();
347 GetActiveWindow()->SetVisibleXY(fX, fY);
349 ::tools::Rectangle aVisArea = GetDocSh()->GetVisArea(ASPECT_CONTENT);
350 Point aVisAreaPos = GetActiveWindow()->PixelToLogic( Point(0,0) );
351 aVisArea.SetPos(aVisAreaPos);
352 GetDocSh()->SetVisArea(aVisArea);
354 Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
355 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
356 VisAreaChanged(aVisAreaWin);
358 ::sd::View* pView = GetView();
359 if (pView)
361 pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
364 if (mbHasRulers)
366 UpdateHRuler();
367 UpdateVRuler();
372 * Set zoom factor for all split windows.
374 void ViewShell::SetZoom(::tools::Long nZoom)
376 Fraction aUIScale(nZoom, 100);
377 aUIScale *= GetDoc()->GetUIScale();
379 if (mpHorizontalRuler)
380 mpHorizontalRuler->SetZoom(aUIScale);
382 if (mpVerticalRuler)
383 mpVerticalRuler->SetZoom(aUIScale);
385 if (mpContentWindow)
387 mpContentWindow->SetZoomIntegral(nZoom);
389 // #i74769# Here is a 2nd way (besides Window::Scroll) to set the visible prt
390 // of the window. It needs - like Scroll(ScrollFlags::Children) does - also to move
391 // the child windows. I am trying InvalidateFlags::Children here which makes things better,
392 // but does not solve the problem completely. Need to ask PL.
393 mpContentWindow->Invalidate(InvalidateFlags::Children);
396 Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
397 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
398 VisAreaChanged(aVisAreaWin);
400 ::sd::View* pView = GetView();
401 if (pView)
403 pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
406 UpdateScrollBars();
409 ::tools::Long ViewShell::GetZoom() const
411 if (mpContentWindow)
413 return mpContentWindow->GetZoom();
416 return 0;
420 * Set zoom rectangle for active window. Sets all split windows to the same zoom
421 * factor.
423 void ViewShell::SetZoomRect(const ::tools::Rectangle& rZoomRect)
425 ::tools::Long nZoom = GetActiveWindow()->SetZoomRect(rZoomRect);
426 Fraction aUIScale(nZoom, 100);
427 aUIScale *= GetDoc()->GetUIScale();
429 Point aPos = GetActiveWindow()->GetWinViewPos();
431 if (mpHorizontalRuler)
432 mpHorizontalRuler->SetZoom(aUIScale);
434 if (mpVerticalRuler)
435 mpVerticalRuler->SetZoom(aUIScale);
437 if (mpContentWindow)
439 Point aNewPos = mpContentWindow->GetWinViewPos();
440 aNewPos.setX( aPos.X() );
441 aNewPos.setY( aPos.Y() );
442 mpContentWindow->SetZoomIntegral(nZoom);
443 mpContentWindow->SetWinViewPos(aNewPos);
444 mpContentWindow->UpdateMapOrigin();
446 // When tiled rendering, UpdateMapOrigin() doesn't touch the map mode.
447 if (!comphelper::LibreOfficeKit::isActive())
448 // #i74769# see above
449 mpContentWindow->Invalidate(InvalidateFlags::Children);
452 Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
453 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
454 VisAreaChanged(aVisAreaWin);
456 ::sd::View* pView = GetView();
457 if (pView)
459 pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
462 UpdateScrollBars();
466 * Initialize imaging parameters for all split windows.
468 void ViewShell::InitWindows(const Point& rViewOrigin, const Size& rViewSize,
469 const Point& rWinPos, bool bUpdate)
471 if (mpContentWindow)
473 mpContentWindow->SetViewOrigin(rViewOrigin);
474 mpContentWindow->SetViewSize(rViewSize);
475 mpContentWindow->SetWinViewPos(rWinPos);
477 if ( bUpdate )
479 mpContentWindow->UpdateMapOrigin();
480 mpContentWindow->Invalidate();
484 Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
485 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
486 VisAreaChanged(aVisAreaWin);
488 ::sd::View* pView = GetView();
489 if (pView)
491 pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
496 * Invalidate all split windows below the ?provided rectangle.
498 void ViewShell::InvalidateWindows()
500 if (mpContentWindow)
501 mpContentWindow->Invalidate();
505 * Draw a selection rectangle with the ?provided pen on all split windows.
507 void ViewShell::DrawMarkRect(const ::tools::Rectangle& rRect) const
509 if (mpContentWindow)
511 mpContentWindow->InvertTracking(rRect, ShowTrackFlags::Object | ShowTrackFlags::TrackWindow);
515 void ViewShell::SetPageSizeAndBorder(PageKind ePageKind, const Size& rNewSize,
516 ::tools::Long nLeft, ::tools::Long nRight,
517 ::tools::Long nUpper, ::tools::Long nLower, bool bScaleAll,
518 Orientation eOrientation, sal_uInt16 nPaperBin,
519 bool bBackgroundFullSize)
521 const sal_uInt16 nMasterPageCnt(GetDoc()->GetMasterSdPageCount(ePageKind));
522 const sal_uInt16 nPageCnt(GetDoc()->GetSdPageCount(ePageKind));
524 if(0 == nPageCnt && 0 == nMasterPageCnt)
526 return;
529 std::unique_ptr<SdUndoGroup> pUndoGroup;
530 SfxViewShell* pViewShell(GetViewShell());
531 if (pViewShell)
533 pUndoGroup.reset(new SdUndoGroup(GetDoc()));
534 pUndoGroup->SetComment(SdResId(STR_UNDO_CHANGE_PAGEFORMAT));
536 Broadcast (ViewShellHint(ViewShellHint::HINT_PAGE_RESIZE_START));
538 // use Model-based method at SdDrawDocument
539 GetDoc()->AdaptPageSizeForAllPages(
540 rNewSize,
541 ePageKind,
542 pUndoGroup.get(),
543 nLeft,
544 nRight,
545 nUpper,
546 nLower,
547 bScaleAll,
548 eOrientation,
549 nPaperBin,
550 bBackgroundFullSize);
552 // adjust handout page to new format of the standard page
553 if(0 != nPageCnt && ((ePageKind == PageKind::Standard) || (ePageKind == PageKind::Handout)))
555 GetDoc()->GetSdPage(0, PageKind::Handout)->CreateTitleAndLayout(true);
558 // handed over undo group to undo manager
559 if (pViewShell)
561 pViewShell->GetViewFrame().GetObjectShell()->GetUndoManager()->AddUndoAction(std::move(pUndoGroup));
564 // calculate View-Sizes
565 SdPage* pPage(0 != nPageCnt
566 ? GetDoc()->GetSdPage(0, ePageKind)
567 : GetDoc()->GetMasterSdPage(0, ePageKind));
568 const ::tools::Long nWidth(pPage->GetSize().Width());
569 const ::tools::Long nHeight(pPage->GetSize().Height());
570 const Point aPageOrg(nWidth, nHeight / 2);
571 const Size aViewSize(nWidth * 3, nHeight * 2);
572 Point aVisAreaPos;
573 ::sd::View* pView(GetView());
574 const Point aNewOrigin(pPage->GetLeftBorder(), pPage->GetUpperBorder());
576 InitWindows(aPageOrg, aViewSize, Point(-1, -1), true);
578 if ( GetDocSh()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
580 aVisAreaPos = GetDocSh()->GetVisArea(ASPECT_CONTENT).TopLeft();
583 if (pView)
585 pView->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aViewSize));
588 UpdateScrollBars();
590 if (pView)
592 pView->GetSdrPageView()->SetPageOrigin(aNewOrigin);
595 if(nullptr != pViewShell)
597 pViewShell->GetViewFrame().GetBindings().Invalidate(SID_RULER_NULL_OFFSET);
598 // zoom onto (new) page size
599 pViewShell->GetViewFrame().GetDispatcher()->Execute(SID_SIZE_PAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
602 Broadcast(ViewShellHint(ViewShellHint::HINT_PAGE_RESIZE_END));
606 * Set zoom factor for InPlace
608 void ViewShell::SetZoomFactor(const Fraction& rZoomX, const Fraction&)
610 ::tools::Long nZoom = static_cast<::tools::Long>(static_cast<double>(rZoomX) * 100);
611 SetZoom(nZoom);
614 void ViewShell::SetActiveWindow (::sd::Window* pWin)
616 SfxViewShell* pViewShell = GetViewShell();
617 assert(pViewShell!=nullptr);
619 if (pViewShell->GetWindow() != pWin)
621 // #i31551# was wrong, it may have been a problem with the repaint at that time.
622 // For transparent form controls, it is necessary to have that flag set, all apps
623 // do set it. Enabling again.
624 if (pWin)
626 pWin->EnableChildTransparentMode();
630 if (mpActiveWindow.get() != pWin)
631 mpActiveWindow = pWin;
633 // The rest of this function is not guarded anymore against calling this
634 // method with an already active window because the functions may still
635 // point to the old window when the new one has already been assigned to
636 // pWindow elsewhere.
637 ::sd::View* pView = GetView();
638 if (pView)
640 pView->SetActualWin(pWin->GetOutDev());
642 if(HasCurrentFunction())
644 GetCurrentFunction()->SetWindow(pWin);
648 bool ViewShell::RequestHelp(const HelpEvent& rHEvt)
650 bool bReturn = false;
652 if (bool(rHEvt.GetMode()))
654 if(HasCurrentFunction())
656 bReturn = GetCurrentFunction()->RequestHelp(rHEvt);
660 return bReturn;
663 void ViewShell::SetFrameView (FrameView* pNewFrameView)
665 mpFrameView = pNewFrameView;
666 ReadFrameViewData (mpFrameView);
669 /*************************************************************************
671 |* Read FrameViews data and set actual views data
673 \************************************************************************/
675 void ViewShell::ReadFrameViewData(FrameView*)
679 /*************************************************************************
681 |* Write actual views data to FrameView
683 \************************************************************************/
685 void ViewShell::WriteFrameViewData()
689 bool ViewShell::ActivateObject(SdrOle2Obj* pObj, sal_Int32 nVerb)
691 ErrCode aErrCode = ERRCODE_NONE;
693 SfxErrorContext aEC(ERRCTX_SO_DOVERB, GetFrameWeld(), RID_SO_ERRCTX);
694 bool bAbort = false;
695 GetDocSh()->SetWaitCursor( true );
696 SfxViewShell* pViewShell = GetViewShell();
697 assert(pViewShell!=nullptr);
698 bool bChangeDefaultsForChart = false;
700 uno::Reference < embed::XEmbeddedObject > xObj = pObj->GetObjRef();
701 if ( !xObj.is() )
703 // provide OLE object to empty OLE object
704 OUString aName = pObj->GetProgName();
705 OUString aObjName;
706 SvGlobalName aClass;
708 if( aName == "StarChart" || aName == "StarOrg" )
710 if( SvtModuleOptions().IsChartInstalled() )
712 aClass = SvGlobalName( SO3_SCH_CLASSID );
713 bChangeDefaultsForChart = true;
716 else if( aName == "StarCalc" )
718 if( SvtModuleOptions().IsCalcInstalled() )
719 aClass = SvGlobalName( SO3_SC_CLASSID );
721 else if( aName == "StarMath" )
723 if( SvtModuleOptions().IsMathInstalled() )
724 aClass = SvGlobalName( SO3_SM_CLASSID );
727 if ( aClass != SvGlobalName() )
728 xObj = GetDocSh()->GetEmbeddedObjectContainer().CreateEmbeddedObject( aClass.GetByteSequence(), aObjName );
730 if( !xObj.is() )
732 aName.clear();
734 // call dialog "insert OLE object"
735 GetDocSh()->SetWaitCursor( false );
736 pViewShell->GetViewFrame().GetDispatcher()->Execute(
737 SID_INSERT_OBJECT,
738 SfxCallMode::SYNCHRON | SfxCallMode::RECORD);
739 xObj = pObj->GetObjRef();
740 GetDocSh()->SetWaitCursor( true );
742 if (!xObj.is())
744 bAbort = true;
748 if ( xObj.is() )
750 // OLE object is no longer empty
751 pObj->SetEmptyPresObj(false);
752 pObj->SetOutlinerParaObject(std::nullopt);
753 pObj->ClearGraphic();
755 // the empty OLE object gets a new IPObj
756 if (!aName.isEmpty())
758 pObj->SetObjRef(xObj);
759 pObj->SetName(aObjName);
760 pObj->SetPersistName(aObjName);
762 else
764 // insertion was done by the dialog
765 pObj->SetObjRef(xObj);
768 ::tools::Rectangle aRect = pObj->GetLogicRect();
770 if ( pObj->GetAspect() != embed::Aspects::MSOLE_ICON )
772 awt::Size aSz;
773 aSz.Width = aRect.GetWidth();
774 aSz.Height = aRect.GetHeight();
775 xObj->setVisualAreaSize( pObj->GetAspect(), aSz );
778 GetViewShellBase().SetVerbs( xObj->getSupportedVerbs() );
780 nVerb = embed::EmbedVerbs::MS_OLEVERB_SHOW;
782 else
784 aErrCode = ERRCODE_SFX_OLEGENERAL;
788 if( aErrCode == ERRCODE_NONE )
790 ::sd::View* pView = GetView();
792 if (pView->IsTextEdit())
794 pView->SdrEndTextEdit();
797 SfxInPlaceClient* pSdClient =
798 pViewShell->FindIPClient(pObj->GetObjRef(), GetActiveWindow());
800 if ( !pSdClient )
802 pSdClient = new Client(pObj, this, GetActiveWindow());
805 ::tools::Rectangle aRect = pObj->GetLogicRect();
808 // #i118485# center on BoundRect for activation,
809 // OLE may be sheared/rotated now
810 const ::tools::Rectangle& rBoundRect = pObj->GetCurrentBoundRect();
811 const Point aDelta(rBoundRect.Center() - aRect.Center());
812 aRect.Move(aDelta.X(), aDelta.Y());
815 Size aDrawSize = aRect.GetSize();
817 MapMode aMapMode( GetDoc()->GetScaleUnit() );
818 Size aObjAreaSize = pObj->GetOrigObjSize( &aMapMode );
819 if( pObj->IsChart() ) //charts never should be stretched see #i84323# for example
820 aObjAreaSize = aDrawSize;
822 Fraction aScaleWidth (aDrawSize.Width(), aObjAreaSize.Width() );
823 Fraction aScaleHeight(aDrawSize.Height(), aObjAreaSize.Height() );
824 aScaleWidth.ReduceInaccurate(10); // compatible to the SdrOle2Obj
825 aScaleHeight.ReduceInaccurate(10);
826 pSdClient->SetSizeScale(aScaleWidth, aScaleHeight);
828 // visible section is only changed in-place!
829 aRect.SetSize(aObjAreaSize);
830 // the object area size must be set after scaling, since it triggers the resizing
831 pSdClient->SetObjArea(aRect);
833 if( bChangeDefaultsForChart && xObj.is())
835 ChartHelper::AdaptDefaultsForChart( xObj );
838 pSdClient->DoVerb(nVerb); // if necessary, ErrCode is outputted by Sfx
839 pViewShell->GetViewFrame().GetBindings().Invalidate(
840 SID_NAVIGATOR_STATE, true);
843 GetDocSh()->SetWaitCursor( false );
845 if (aErrCode != ERRCODE_NONE && !bAbort)
847 ErrorHandler::HandleError(ErrCodeMsg(aErrCode));
850 return aErrCode == ERRCODE_NONE;
854 * @returns enclosing rectangle of all (split-) windows.
856 const ::tools::Rectangle& ViewShell::GetAllWindowRect()
858 maAllWindowRectangle.SetPos(
859 mpContentWindow->OutputToScreenPixel(Point(0,0)));
860 return maAllWindowRectangle;
863 void ViewShell::ReadUserData()
865 // zoom onto VisArea from FrameView
866 GetViewShell()->GetViewFrame().GetDispatcher()->Execute(SID_SIZE_VISAREA,
867 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
870 void ViewShell::WriteUserData()
872 // writing of our data is always done in WriteFrameViewData()
873 WriteFrameViewData();
877 * Switch ruler on/off
879 void ViewShell::SetRuler(bool bRuler)
881 mbHasRulers = ( bRuler && !GetDocSh()->IsPreview() ); // no rulers on preview mode
883 if (mpHorizontalRuler)
885 if (mbHasRulers)
887 mpHorizontalRuler->Show();
889 else
891 mpHorizontalRuler->Hide();
895 if (mpVerticalRuler)
897 if (mbHasRulers)
899 mpVerticalRuler->Show();
901 else
903 mpVerticalRuler->Hide();
907 OSL_ASSERT(GetViewShell()!=nullptr);
908 if (IsMainViewShell())
909 GetViewShell()->InvalidateBorder();
912 void ViewShell::SetScrollBarsVisible(bool bVisible)
914 if (mpVerticalScrollBar)
915 mpVerticalScrollBar->Show( bVisible );
917 if (mpHorizontalScrollBar)
918 mpHorizontalScrollBar->Show( bVisible );
921 sal_Int8 ViewShell::AcceptDrop (
922 const AcceptDropEvent& rEvt,
923 DropTargetHelper& rTargetHelper,
924 ::sd::Window* /*pTargetWindow*/,
925 sal_uInt16 /*nPage*/,
926 SdrLayerID nLayer)
928 ::sd::View* pView = GetView();
929 return( pView ? pView->AcceptDrop( rEvt, rTargetHelper, nLayer ) : DND_ACTION_NONE );
932 sal_Int8 ViewShell::ExecuteDrop (
933 const ExecuteDropEvent& rEvt,
934 DropTargetHelper& /*rTargetHelper*/,
935 ::sd::Window* pTargetWindow,
936 sal_uInt16 nPage,
937 SdrLayerID nLayer)
939 ::sd::View* pView = GetView();
940 return pView ? pView->ExecuteDrop( rEvt, pTargetWindow, nPage, nLayer ) : DND_ACTION_NONE;
943 void ViewShell::WriteUserDataSequence ( css::uno::Sequence < css::beans::PropertyValue >& rSequence )
945 const sal_Int32 nIndex = rSequence.getLength();
946 rSequence.realloc( nIndex + 1 );
947 auto pSequence = rSequence.getArray();
949 OSL_ASSERT (GetViewShell()!=nullptr);
950 // Get the view id from the view shell in the center pane. This will
951 // usually be the called view shell, but to be on the safe side we call
952 // the main view shell explicitly.
953 SfxInterfaceId nViewID (IMPRESS_FACTORY_ID);
954 if (auto pViewShell = GetViewShellBase().GetMainViewShell().get())
955 nViewID = pViewShell->mpImpl->GetViewId();
956 pSequence[nIndex].Name = sUNO_View_ViewId;
957 pSequence[nIndex].Value <<= "view" + OUString::number( static_cast<sal_uInt16>(nViewID));
959 mpFrameView->WriteUserDataSequence( rSequence );
962 void ViewShell::ReadUserDataSequence ( const css::uno::Sequence < css::beans::PropertyValue >& rSequence )
964 mpFrameView->ReadUserDataSequence( rSequence );
967 void ViewShell::VisAreaChanged(const ::tools::Rectangle& /*rRect*/)
969 OSL_ASSERT (GetViewShell()!=nullptr);
970 GetViewShell()->VisAreaChanged();
973 void ViewShell::SetWinViewPos(const Point& rWinPos)
975 if (mpContentWindow)
977 mpContentWindow->SetWinViewPos(rWinPos);
979 mpContentWindow->UpdateMapOrigin();
980 mpContentWindow->Invalidate();
983 if (mbHasRulers)
985 UpdateHRuler();
986 UpdateVRuler();
989 UpdateScrollBars();
991 Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
992 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
993 VisAreaChanged(aVisAreaWin);
995 ::sd::View* pView = GetView();
996 if (pView)
998 pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
1002 Point const & ViewShell::GetWinViewPos() const
1004 return mpContentWindow->GetWinViewPos();
1007 Point const & ViewShell::GetViewOrigin() const
1009 return mpContentWindow->GetViewOrigin();
1012 } // end of namespace sd
1014 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */