cid#1607171 Data race condition
[LibreOffice.git] / sd / source / ui / view / sdwindow.cxx
blob8f71c17db9571c6eb06294a548f2bc7949f616d3
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 <Window.hxx>
21 #include <sfx2/bindings.hxx>
22 #include <sfx2/request.hxx>
24 #include <sfx2/viewfrm.hxx>
25 #include <svx/svxids.hrc>
27 #include <editeng/outliner.hxx>
28 #include <editeng/editview.hxx>
29 #include <editeng/editeng.hxx>
31 #include <app.hrc>
32 #include <ViewShell.hxx>
33 #include <DrawViewShell.hxx>
34 #include <DrawDocShell.hxx>
35 #include <PresentationViewShell.hxx>
36 #include <View.hxx>
37 #include <FrameView.hxx>
38 #include <OutlineViewShell.hxx>
39 #include <OutlineView.hxx>
40 #include <drawdoc.hxx>
41 #include <WindowUpdater.hxx>
42 #include <ViewShellBase.hxx>
43 #include <uiobject.hxx>
45 #include <officecfg/Office/Common.hxx>
46 #include <sal/log.hxx>
47 #include <tools/debug.hxx>
48 #include <vcl/commandevent.hxx>
49 #include <vcl/settings.hxx>
50 #include <comphelper/lok.hxx>
51 #include <sfx2/lokhelper.hxx>
53 namespace sd {
55 #define SCROLL_LINE_FACT 0.05 ///< factor for line scrolling
56 #define SCROLL_PAGE_FACT 0.5 ///< factor for page scrolling
57 #define SCROLL_SENSITIVE 20 ///< sensitive area in pixel
58 #define ZOOM_MULTIPLICATOR 10000 ///< multiplier to avoid rounding errors
59 #define MIN_ZOOM 5 ///< minimal zoom factor
60 #define MAX_ZOOM 3000 ///< maximal zoom factor
62 Window::Window(vcl::Window* pParent)
63 : vcl::DocWindow(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
64 DropTargetHelper( this ),
65 maWinPos(0, 0), // precautionary; but the values should be set
66 maViewOrigin(0, 0), // again from the owner of the window
67 maViewSize(1000, 1000),
68 maPrevSize(-1,-1),
69 mnMinZoom(MIN_ZOOM),
70 mnMaxZoom(MAX_ZOOM),
71 mbMinZoomAutoCalc(false),
72 mbCenterAllowed(true),
73 mnTicks (0),
74 mpViewShell(nullptr),
75 mbUseDropScroll (true)
77 SetDialogControlFlags( DialogControlFlags::Return | DialogControlFlags::WantFocus );
79 MapMode aMap(GetMapMode());
80 aMap.SetMapUnit(MapUnit::Map100thMM);
81 SetMapMode(aMap);
83 // with it, the vcl::WindowColor is used in the slide mode
84 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetWindowColor() ) );
86 // adjust contrast mode initially
87 bool bUseContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
88 GetOutDev()->SetDrawMode( bUseContrast
89 ? sd::OUTPUT_DRAWMODE_CONTRAST
90 : sd::OUTPUT_DRAWMODE_COLOR );
92 // #i78183# Added after discussed with AF
93 EnableRTL(false);
96 Window::~Window()
98 disposeOnce();
101 void Window::dispose()
103 if (mpViewShell != nullptr)
105 WindowUpdater* pWindowUpdater = mpViewShell->GetWindowUpdater();
106 if (pWindowUpdater != nullptr)
107 pWindowUpdater->UnregisterWindow (this);
109 DropTargetHelper::dispose();
110 vcl::Window::dispose();
113 void Window::SetViewShell (ViewShell* pViewSh)
115 WindowUpdater* pWindowUpdater = nullptr;
116 // Unregister at device updater of old view shell.
117 if (mpViewShell != nullptr)
119 pWindowUpdater = mpViewShell->GetWindowUpdater();
120 if (pWindowUpdater != nullptr)
121 pWindowUpdater->UnregisterWindow (this);
124 mpViewShell = pViewSh;
126 // Register at device updater of new view shell
127 if (mpViewShell != nullptr)
129 pWindowUpdater = mpViewShell->GetWindowUpdater();
130 if (pWindowUpdater != nullptr)
131 pWindowUpdater->RegisterWindow (this);
135 ViewShell* Window::GetViewShell()
137 return mpViewShell;
140 void Window::CalcMinZoom()
142 // Are we entitled to change the minimal zoom factor?
143 if ( !mbMinZoomAutoCalc )
144 return;
146 // Get current zoom factor.
147 ::tools::Long nZoom = GetZoom();
149 // Get the rectangle of the output area in logical coordinates
150 // and calculate the scaling factors that would lead to the view
151 // area (also called application area) to completely fill the
152 // window.
153 Size aWinSize = PixelToLogic(GetOutputSizePixel());
154 sal_uLong nX = static_cast<sal_uLong>(static_cast<double>(aWinSize.Width())
155 * double(ZOOM_MULTIPLICATOR) / static_cast<double>(maViewSize.Width()));
156 sal_uLong nY = static_cast<sal_uLong>(static_cast<double>(aWinSize.Height())
157 * double(ZOOM_MULTIPLICATOR) / static_cast<double>(maViewSize.Height()));
159 // Decide whether to take the larger or the smaller factor.
160 sal_uLong nFact = std::min(nX, nY);
162 // The factor is transformed according to the current zoom factor.
163 nFact = nFact * nZoom / ZOOM_MULTIPLICATOR;
164 mnMinZoom = std::max(sal_uInt16(MIN_ZOOM), static_cast<sal_uInt16>(nFact));
166 // If the current zoom factor is smaller than the calculated minimal
167 // zoom factor then set the new minimal factor as the current zoom
168 // factor.
169 if ( nZoom < static_cast<::tools::Long>(mnMinZoom) )
170 SetZoomFactor(mnMinZoom);
173 void Window::SetMinZoom (::tools::Long nMin)
175 mnMinZoom = static_cast<sal_uInt16>(nMin);
178 void Window::SetMaxZoom (::tools::Long nMax)
180 mnMaxZoom = static_cast<sal_uInt16>(nMax);
183 ::tools::Long Window::GetZoom() const
185 if( GetMapMode().GetScaleX().GetDenominator() )
187 return ::tools::Long(GetMapMode().GetScaleX() * 100);
189 else
191 return 0;
195 void Window::Resize()
197 vcl::Window::Resize();
198 CalcMinZoom();
200 if( mpViewShell && mpViewShell->GetViewFrame() )
201 mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
204 void Window::PrePaint(vcl::RenderContext& /*rRenderContext*/)
206 if ( mpViewShell )
207 mpViewShell->PrePaint();
210 void Window::Paint(vcl::RenderContext& /*rRenderContext*/, const ::tools::Rectangle& rRect)
212 if ( mpViewShell )
213 mpViewShell->Paint(rRect, this);
216 void Window::KeyInput(const KeyEvent& rKEvt)
218 if (getenv("SD_DEBUG") && rKEvt.GetKeyCode().GetCode() == KEY_F12 && mpViewShell)
220 mpViewShell->GetDoc()->dumpAsXml(nullptr);
221 if (OutlinerView *pOLV = mpViewShell->GetView()->GetTextEditOutlinerView())
222 pOLV->GetEditView().getEditEngine().dumpAsXmlEditDoc(nullptr);
223 return;
226 if (!(mpViewShell && mpViewShell->KeyInput(rKEvt, this)))
228 if (mpViewShell && rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE)
230 mpViewShell->GetViewShell()->Escape();
232 else
234 vcl::Window::KeyInput(rKEvt);
239 void Window::MouseButtonDown(const MouseEvent& rMEvt)
241 if ( mpViewShell )
242 mpViewShell->MouseButtonDown(rMEvt, this);
245 void Window::MouseMove(const MouseEvent& rMEvt)
247 if ( mpViewShell )
248 mpViewShell->MouseMove(rMEvt, this);
251 void Window::MouseButtonUp(const MouseEvent& rMEvt)
253 mnTicks = 0;
255 if ( mpViewShell )
256 mpViewShell->MouseButtonUp(rMEvt, this);
259 void Window::Command(const CommandEvent& rCEvt)
261 if (mpViewShell)
262 mpViewShell->Command(rCEvt, this);
263 //pass at least alt press/release to parent impl
264 if (rCEvt.GetCommand() == CommandEventId::ModKeyChange)
265 vcl::Window::Command(rCEvt);
266 //show the text edit outliner view cursor
267 else if (mpViewShell && !HasFocus() && rCEvt.GetCommand() == CommandEventId::CursorPos)
269 // tdf#138855 Getting Focus may destroy TextEditOutlinerView so Grab if
270 // text editing active, but fetch the TextEditOutlinerView post-grab
271 if (mpViewShell->GetView()->IsTextEdit())
273 GrabFocus();
274 OutlinerView* pOLV = mpViewShell->GetView()->GetTextEditOutlinerView();
275 if (pOLV && this == pOLV->GetWindow())
276 pOLV->ShowCursor();
281 bool Window::EventNotify( NotifyEvent& rNEvt )
283 bool bResult = false;
284 if ( mpViewShell )
286 bResult = mpViewShell->Notify(rNEvt, this);
288 if( !bResult )
289 bResult = vcl::Window::EventNotify(rNEvt);
291 return bResult;
294 void Window::RequestHelp(const HelpEvent& rEvt)
296 if (!mpViewShell || !mpViewShell->RequestHelp(rEvt))
297 vcl::Window::RequestHelp( rEvt );
301 * Set the position of the upper left corner from the visible area of the
302 * window.
304 void Window::SetWinViewPos(const Point& rPnt)
306 maWinPos = rPnt;
310 * Set origin of the representation in respect to the whole working area.
312 void Window::SetViewOrigin(const Point& rPnt)
314 maViewOrigin = rPnt;
318 * Set size of the whole working area which can be seen with the window.
320 void Window::SetViewSize(const Size& rSize)
322 maViewSize = rSize;
323 CalcMinZoom();
326 void Window::SetCenterAllowed (bool bIsAllowed)
328 mbCenterAllowed = bIsAllowed;
331 ::tools::Long Window::SetZoomFactor(::tools::Long nZoom)
333 // Clip the zoom factor to the valid range marked by nMinZoom as
334 // calculated by CalcMinZoom() and the constant MAX_ZOOM.
335 if ( nZoom > MAX_ZOOM )
336 nZoom = MAX_ZOOM;
337 if ( nZoom < static_cast<::tools::Long>(mnMinZoom) )
338 nZoom = mnMinZoom;
340 // Set the zoom factor at the window's map mode.
341 if (!comphelper::LibreOfficeKit::isActive())
343 MapMode aMap(GetMapMode());
344 aMap.SetScaleX(Fraction(nZoom, 100));
345 aMap.SetScaleY(Fraction(nZoom, 100));
346 SetMapMode(aMap);
349 // invalidate previous size - it was relative to the old scaling
350 maPrevSize = Size(-1,-1);
352 // Update the map mode's origin (to what effect?).
353 UpdateMapOrigin();
355 // Update the view's snapping to the new zoom factor.
356 if ( auto pDrawViewShell = dynamic_cast< DrawViewShell *>( mpViewShell ) )
357 pDrawViewShell->GetView()->RecalcLogicSnapMagnetic(*GetOutDev());
359 // Return the zoom factor just in case it has been changed above to lie
360 // inside the valid range.
361 return nZoom;
364 void Window::SetZoomIntegral(::tools::Long nZoom)
366 // Clip the zoom factor to the valid range marked by nMinZoom as
367 // previously calculated by <member>CalcMinZoom()</member> and the
368 // MAX_ZOOM constant.
369 if ( nZoom > MAX_ZOOM )
370 nZoom = MAX_ZOOM;
371 if ( nZoom < static_cast<::tools::Long>(mnMinZoom) )
372 nZoom = mnMinZoom;
374 // Calculate the window's new origin.
375 Size aSize = PixelToLogic(GetOutputSizePixel());
376 ::tools::Long nW = aSize.Width() * GetZoom() / nZoom;
377 ::tools::Long nH = aSize.Height() * GetZoom() / nZoom;
378 maWinPos.AdjustX((aSize.Width() - nW) / 2 );
379 maWinPos.AdjustY((aSize.Height() - nH) / 2 );
380 if ( maWinPos.X() < 0 ) maWinPos.setX( 0 );
381 if ( maWinPos.Y() < 0 ) maWinPos.setY( 0 );
383 // Finally update this window's map mode to the given zoom factor that
384 // has been clipped to the valid range.
385 SetZoomFactor(nZoom);
388 ::tools::Long Window::GetZoomForRect( const ::tools::Rectangle& rZoomRect )
390 ::tools::Long nRetZoom = 100;
392 if( (rZoomRect.GetWidth() != 0) && (rZoomRect.GetHeight() != 0))
394 // Calculate the scale factors which will lead to the given
395 // rectangle being fully visible (when translated accordingly) as
396 // large as possible in the output area independently in both
397 // coordinate directions .
398 sal_uLong nX(0);
399 sal_uLong nY(0);
401 const Size aWinSize( PixelToLogic(GetOutputSizePixel()) );
402 if(rZoomRect.GetHeight())
404 nX = static_cast<sal_uLong>(static_cast<double>(aWinSize.Height())
405 * double(ZOOM_MULTIPLICATOR) / static_cast<double>(rZoomRect.GetHeight()));
408 if(rZoomRect.GetWidth())
410 nY = static_cast<sal_uLong>(static_cast<double>(aWinSize.Width())
411 * double(ZOOM_MULTIPLICATOR) / static_cast<double>(rZoomRect.GetWidth()));
414 // Use the smaller one of both so that the zoom rectangle will be
415 // fully visible with respect to both coordinate directions.
416 sal_uLong nFact = std::min(nX, nY);
418 // Transform the current zoom factor so that it leads to the desired
419 // scaling.
420 nRetZoom = nFact * GetZoom() / ZOOM_MULTIPLICATOR;
422 // Calculate the new origin.
423 if ( nFact == 0 )
425 // Don't change anything if the scale factor is degenerate.
426 nRetZoom = GetZoom();
428 else
430 // Clip the zoom factor to the valid range marked by nMinZoom as
431 // previously calculated by <member>CalcMinZoom()</member> and the
432 // MAX_ZOOM constant.
433 if ( nRetZoom > MAX_ZOOM )
434 nRetZoom = MAX_ZOOM;
435 if ( nRetZoom < static_cast<::tools::Long>(mnMinZoom) )
436 nRetZoom = mnMinZoom;
440 return nRetZoom;
443 /** Recalculate the zoom factor and translation so that the given rectangle
444 is displayed centered and as large as possible while still being fully
445 visible in the window.
447 ::tools::Long Window::SetZoomRect (const ::tools::Rectangle& rZoomRect)
449 ::tools::Long nNewZoom = 100;
451 if (rZoomRect.GetWidth() == 0 || rZoomRect.GetHeight() == 0)
453 // The given rectangle is degenerate. Use the default zoom factor
454 // (above) of 100%.
455 SetZoomIntegral(nNewZoom);
457 else
459 Point aPos = rZoomRect.TopLeft();
460 // Transform the output area from pixel coordinates into logical
461 // coordinates.
462 Size aWinSize = PixelToLogic(GetOutputSizePixel());
463 // Paranoia! The degenerate case of zero width or height has been
464 // taken care of above.
465 DBG_ASSERT(rZoomRect.GetWidth(), "ZoomRect-Width = 0!");
466 DBG_ASSERT(rZoomRect.GetHeight(), "ZoomRect-Height = 0!");
468 // Calculate the scale factors which will lead to the given
469 // rectangle being fully visible (when translated accordingly) as
470 // large as possible in the output area independently in both
471 // coordinate directions .
472 sal_uLong nX(0);
473 sal_uLong nY(0);
475 if(rZoomRect.GetHeight())
477 nX = static_cast<sal_uLong>(static_cast<double>(aWinSize.Height())
478 * double(ZOOM_MULTIPLICATOR) / static_cast<double>(rZoomRect.GetHeight()));
481 if(rZoomRect.GetWidth())
483 nY = static_cast<sal_uLong>(static_cast<double>(aWinSize.Width())
484 * double(ZOOM_MULTIPLICATOR) / static_cast<double>(rZoomRect.GetWidth()));
487 // Use the smaller one of both so that the zoom rectangle will be
488 // fully visible with respect to both coordinate directions.
489 sal_uLong nFact = std::min(nX, nY);
491 // Transform the current zoom factor so that it leads to the desired
492 // scaling.
493 ::tools::Long nZoom = nFact * GetZoom() / ZOOM_MULTIPLICATOR;
495 // Calculate the new origin.
496 if ( nFact == 0 )
498 // Don't change anything if the scale factor is degenerate.
499 nNewZoom = GetZoom();
501 else
503 // Calculate the new window position that centers the given
504 // rectangle on the screen.
505 if ( nZoom > MAX_ZOOM )
506 nFact = nFact * MAX_ZOOM / nZoom;
508 maWinPos = maViewOrigin + aPos;
510 aWinSize.setWidth( static_cast<::tools::Long>(static_cast<double>(aWinSize.Width()) * double(ZOOM_MULTIPLICATOR) / static_cast<double>(nFact)) );
511 maWinPos.AdjustX((rZoomRect.GetWidth() - aWinSize.Width()) / 2 );
512 aWinSize.setHeight( static_cast<::tools::Long>(static_cast<double>(aWinSize.Height()) * double(ZOOM_MULTIPLICATOR) / static_cast<double>(nFact)) );
513 maWinPos.AdjustY((rZoomRect.GetHeight() - aWinSize.Height()) / 2 );
515 if ( maWinPos.X() < 0 ) maWinPos.setX( 0 );
516 if ( maWinPos.Y() < 0 ) maWinPos.setY( 0 );
518 // Adapt the window's map mode to the new zoom factor.
519 nNewZoom = SetZoomFactor(nZoom);
523 return nNewZoom;
526 void Window::SetMinZoomAutoCalc (bool bAuto)
528 mbMinZoomAutoCalc = bAuto;
532 * Calculate and set new MapMode origin.
533 * If aWinPos.X()/Y() == -1, then we center the corresponding position (e.g. for
534 * initialization).
536 void Window::UpdateMapOrigin(bool bInvalidate)
538 bool bChanged = false;
539 const Size aWinSize = PixelToLogic(GetOutputSizePixel());
541 if ( mbCenterAllowed )
543 if( maPrevSize != Size(-1,-1) )
545 // keep view centered around current pos, when window
546 // resizes
547 maWinPos.AdjustX( -((aWinSize.Width() - maPrevSize.Width()) / 2) );
548 maWinPos.AdjustY( -((aWinSize.Height() - maPrevSize.Height()) / 2) );
549 bChanged = true;
552 if ( maWinPos.X() > maViewSize.Width() - aWinSize.Width() )
554 maWinPos.setX( maViewSize.Width() - aWinSize.Width() );
555 bChanged = true;
557 if ( maWinPos.Y() > maViewSize.Height() - aWinSize.Height() )
559 maWinPos.setY( maViewSize.Height() - aWinSize.Height() );
560 bChanged = true;
562 if ( aWinSize.Width() > maViewSize.Width() || maWinPos.X() < 0 )
564 maWinPos.setX( maViewSize.Width() / 2 - aWinSize.Width() / 2 );
565 bChanged = true;
567 if ( aWinSize.Height() > maViewSize.Height() || maWinPos.Y() < 0 )
569 maWinPos.setY( maViewSize.Height() / 2 - aWinSize.Height() / 2 );
570 bChanged = true;
574 UpdateMapMode ();
576 maPrevSize = aWinSize;
578 // When tiled rendering, the above UpdateMapMode() call doesn't touch the map mode.
579 if (bChanged && bInvalidate && !comphelper::LibreOfficeKit::isActive())
580 Invalidate();
583 void Window::UpdateMapMode()
585 maWinPos -= maViewOrigin;
586 Size aPix(maWinPos.X(), maWinPos.Y());
587 aPix = LogicToPixel(aPix);
588 // Size has to be a multiple of BRUSH_SIZE due to the correct depiction of
589 // pattern
590 // #i2237#
591 // removed old stuff here which still forced zoom to be
592 // %BRUSH_SIZE which is outdated now
594 if (dynamic_cast< DrawViewShell *>( mpViewShell ))
596 // page should not "stick" to the window border
597 if (aPix.Width() == 0)
599 // #i2237#
600 // Since BRUSH_SIZE alignment is outdated now, i use the
601 // former constant here directly
602 aPix.AdjustWidth( -8 );
604 if (aPix.Height() == 0)
606 // #i2237#
607 // Since BRUSH_SIZE alignment is outdated now, i use the
608 // former constant here directly
609 aPix.AdjustHeight( -8 );
613 aPix = PixelToLogic(aPix);
614 maWinPos.setX( aPix.Width() );
615 maWinPos.setY( aPix.Height() );
616 Point aNewOrigin (-maWinPos.X(), -maWinPos.Y());
617 maWinPos += maViewOrigin;
619 if (!comphelper::LibreOfficeKit::isActive())
621 MapMode aMap(GetMapMode());
622 aMap.SetOrigin(aNewOrigin);
623 SetMapMode(aMap);
628 * @returns X position of the visible area as fraction (< 1) of the whole
629 * working area.
631 double Window::GetVisibleX() const
633 return maViewSize.Width() == 0 ? 0 : (static_cast<double>(maWinPos.X()) / maViewSize.Width());
637 * @returns Y position of the visible area as fraction (< 1) of the whole
638 * working area.
640 double Window::GetVisibleY() const
642 return maViewSize.Height() == 0 ? 0 : (static_cast<double>(maWinPos.Y()) / maViewSize.Height());
646 * Set x and y position of the visible area as fraction (< 1) of the whole
647 * working area. Negative values are ignored.
649 void Window::SetVisibleXY(double fX, double fY)
651 ::tools::Long nOldX = maWinPos.X();
652 ::tools::Long nOldY = maWinPos.Y();
654 if ( fX >= 0 )
655 maWinPos.setX( static_cast<::tools::Long>(fX * maViewSize.Width()) );
656 if ( fY >= 0 )
657 maWinPos.setY( static_cast<::tools::Long>(fY * maViewSize.Height()) );
658 UpdateMapOrigin(false);
659 Scroll(nOldX - maWinPos.X(), nOldY - maWinPos.Y(), ScrollFlags::Children);
660 PaintImmediately();
664 * @returns width of the visible area in proportion to the width of the whole
665 * working area.
667 double Window::GetVisibleWidth() const
669 Size aWinSize = PixelToLogic(GetOutputSizePixel());
670 return
671 maViewSize.Width() == 0 ? 0 : (static_cast<double>(aWinSize.Width()) / maViewSize.Width());
675 * @returns height of the visible area in proportion to the height of the whole
676 * working area.
678 double Window::GetVisibleHeight() const
680 Size aWinSize = PixelToLogic(GetOutputSizePixel());
681 return maViewSize.Height() == 0
682 ? 0 : (static_cast<double>(aWinSize.Height()) / maViewSize.Height());
685 Point Window::GetVisibleCenter()
687 Point aPos = ::tools::Rectangle(Point(), GetOutputSizePixel()).Center();
689 // For LOK
690 bool bMapModeWasEnabled(IsMapModeEnabled());
691 EnableMapMode(/*true*/);
692 aPos = PixelToLogic(aPos);
693 EnableMapMode(bMapModeWasEnabled);
695 return aPos;
699 * @returns width of a scroll column in proportion to the width of the whole
700 * working area.
702 double Window::GetScrlLineWidth() const
704 return std::min(1.0, GetVisibleWidth()) * SCROLL_LINE_FACT;
708 * @returns height of a scroll column in proportion to the height of the whole
709 * working area.
711 double Window::GetScrlLineHeight() const
713 return std::min(1.0, GetVisibleHeight()) * SCROLL_LINE_FACT;
717 * @returns width of a scroll page in proportion to the width of the whole
718 * working area.
720 double Window::GetScrlPageWidth() const
722 return std::min(1.0, GetVisibleWidth()) * SCROLL_PAGE_FACT;
726 * @returns height of a scroll page in proportion to the height of the whole
727 * working area.
729 double Window::GetScrlPageHeight() const
731 return std::min(1.0, GetVisibleHeight()) * SCROLL_PAGE_FACT;
735 * Deactivate window.
737 void Window::LoseFocus()
739 mnTicks = 0;
740 vcl::Window::LoseFocus ();
741 if (mpViewShell)
742 mpViewShell->onLoseFocus();
746 * Activate window.
748 void Window::GrabFocus()
750 mnTicks = 0;
751 vcl::Window::GrabFocus ();
752 if (mpViewShell)
753 mpViewShell->onGrabFocus();
756 void Window::DataChanged( const DataChangedEvent& rDCEvt )
758 vcl::Window::DataChanged( rDCEvt );
760 /* Omit PRINTER by all documents which are not using a printer.
761 Omit FONTS and FONTSUBSTITUTION if no text output is available or if the
762 document does not allow text. */
764 if ( !((rDCEvt.GetType() == DataChangedEventType::PRINTER) ||
765 (rDCEvt.GetType() == DataChangedEventType::DISPLAY) ||
766 (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
767 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
768 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
769 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))) )
770 return;
772 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
773 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
775 /* Rearrange or initiate Resize for scroll bars since the size of
776 the scroll bars my have changed. Within this, inside the resize-
777 handler, the size of the scroll bars will be asked from the
778 Settings. */
779 Resize();
781 /* Re-set data, which are from system control or from Settings. May
782 have to re-set more data since the resolution may also has
783 changed. */
784 if( mpViewShell )
786 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
787 DrawModeFlags nOutputMode;
788 sal_uInt16 nPreviewSlot;
790 if( rStyleSettings.GetHighContrastMode() )
791 nOutputMode = sd::OUTPUT_DRAWMODE_CONTRAST;
792 else
793 nOutputMode = sd::OUTPUT_DRAWMODE_COLOR;
795 if( rStyleSettings.GetHighContrastMode()
796 && officecfg::Office::Common::Accessibility::IsForPagePreviews::get() )
797 nPreviewSlot = SID_PREVIEW_QUALITY_CONTRAST;
798 else
799 nPreviewSlot = SID_PREVIEW_QUALITY_COLOR;
801 if( dynamic_cast< DrawViewShell *>( mpViewShell ) != nullptr )
803 GetOutDev()->SetDrawMode( nOutputMode );
804 mpViewShell->GetFrameView()->SetDrawMode( nOutputMode );
805 Invalidate();
808 // Overwrite window color for OutlineView
809 if( dynamic_cast< OutlineViewShell *>( mpViewShell ) != nullptr )
811 svtools::ColorConfig aColorConfig;
812 const Color aDocColor( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor );
813 SetBackground( Wallpaper( aDocColor ) );
816 SfxRequest aReq( nPreviewSlot, SfxCallMode::SLOT, mpViewShell->GetDocSh()->GetDoc()->GetItemPool() );
817 mpViewShell->ExecReq( aReq );
818 mpViewShell->Invalidate();
819 mpViewShell->ArrangeGUIElements();
821 // re-create handles to show new outfit
822 if(dynamic_cast< DrawViewShell *>( mpViewShell ) != nullptr)
824 mpViewShell->GetView()->AdjustMarkHdl();
829 if ( (rDCEvt.GetType() == DataChangedEventType::DISPLAY) ||
830 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
831 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
833 /* Virtual devices, which also depends on the resolution or the
834 system control, should be updated. Otherwise, we should update
835 the virtual devices at least at DataChangedEventType::DISPLAY since some
836 systems allow to change the resolution and color depth during
837 runtime. Or the virtual devices have to be updated when the color
838 palette has changed since a different color matching can be used
839 when outputting. */
842 if ( rDCEvt.GetType() == DataChangedEventType::FONTS )
844 /* If the document provides font choose boxes, we have to update
845 them. I don't know how this looks like (also not really me, I
846 only translated the comment ;). We may can handle it global. We
847 have to discuss it with PB, but he is ill at the moment.
848 Before we handle it here, discuss it with PB and me. */
851 if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
852 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) )
854 /* Do reformatting since the fonts of the document may no longer
855 exist, or exist now, or are replaced with others. */
856 if( mpViewShell )
858 DrawDocShell* pDocSh = mpViewShell->GetDocSh();
859 if( pDocSh )
860 pDocSh->SetPrinter( pDocSh->GetPrinter( true ) );
864 if ( rDCEvt.GetType() == DataChangedEventType::PRINTER )
866 /* I don't know how the handling should look like. Maybe we delete a
867 printer and look what we have to do. Maybe I have to add
868 something to the VCL, in case the used printer is deleted.
869 Otherwise I may recalculate the formatting here if the current
870 printer is destroyed. */
871 if( mpViewShell )
873 DrawDocShell* pDocSh = mpViewShell->GetDocSh();
874 if( pDocSh )
875 pDocSh->SetPrinter( pDocSh->GetPrinter( true ) );
879 // Update everything
880 Invalidate();
883 sal_Int8 Window::AcceptDrop( const AcceptDropEvent& rEvt )
885 sal_Int8 nRet = DND_ACTION_NONE;
887 if( mpViewShell && !mpViewShell->GetDocSh()->IsReadOnly() )
889 nRet = mpViewShell->AcceptDrop( rEvt, *this, this, SDRPAGE_NOTFOUND, SDRLAYER_NOTFOUND );
891 if (mbUseDropScroll && dynamic_cast< OutlineViewShell *>( mpViewShell ) == nullptr)
892 DropScroll( rEvt.maPosPixel );
895 return nRet;
898 sal_Int8 Window::ExecuteDrop( const ExecuteDropEvent& rEvt )
900 sal_Int8 nRet = DND_ACTION_NONE;
902 if( mpViewShell )
904 nRet = mpViewShell->ExecuteDrop( rEvt, *this, this, SDRPAGE_NOTFOUND, SDRLAYER_NOTFOUND );
907 return nRet;
910 void Window::SetUseDropScroll (bool bUseDropScroll)
912 mbUseDropScroll = bUseDropScroll;
915 void Window::DropScroll(const Point& rMousePos)
917 short nDx = 0;
918 short nDy = 0;
920 Size aSize = GetOutputSizePixel();
922 if (aSize.Width() > SCROLL_SENSITIVE * 3)
924 if ( rMousePos.X() < SCROLL_SENSITIVE )
926 nDx = -1;
929 if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE )
931 nDx = 1;
935 if (aSize.Height() > SCROLL_SENSITIVE * 3)
937 if ( rMousePos.Y() < SCROLL_SENSITIVE )
939 nDy = -1;
942 if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE )
944 nDy = 1;
948 if ( (nDx || nDy) && (rMousePos.X()!=0 || rMousePos.Y()!=0 ) )
950 if (mnTicks > 20)
951 mpViewShell->ScrollLines(nDx, nDy);
952 else
953 mnTicks ++;
957 css::uno::Reference<css::accessibility::XAccessible>
958 Window::CreateAccessible()
960 // If current viewshell is PresentationViewShell, just return empty because the correct ShowWin will be created later.
961 if (dynamic_cast< PresentationViewShell *>( mpViewShell ))
963 return vcl::Window::CreateAccessible ();
965 css::uno::Reference< css::accessibility::XAccessible > xAcc = GetAccessible(false);
966 if (xAcc)
968 return xAcc;
970 if (mpViewShell != nullptr)
972 xAcc = mpViewShell->CreateAccessibleDocumentView (this);
973 SetAccessible(xAcc);
974 return xAcc;
976 else
978 SAL_WARN("sd", "::sd::Window::CreateAccessible: no view shell");
979 return vcl::Window::CreateAccessible ();
983 OutlinerView* Window::GetOutlinerView() const
985 OutlinerView *pOLV = nullptr;
986 sd::View* pView = mpViewShell->GetView();
987 if (mpViewShell->GetShellType() == ViewShell::ST_OUTLINE)
989 if (OutlineView* pOView = dynamic_cast<OutlineView*>(pView))
990 pOLV = pOView->GetViewByWindow(this);
992 else if (pView->IsTextEdit())
994 pOLV = pView->GetTextEditOutlinerView();
996 return pOLV;
999 OUString Window::GetSurroundingText() const
1001 OutlinerView *pOLV = GetOutlinerView();
1002 if (pOLV)
1003 return pOLV->GetEditView().GetSurroundingText();
1004 return OUString();
1007 Selection Window::GetSurroundingTextSelection() const
1009 OutlinerView *pOLV = GetOutlinerView();
1010 if (pOLV)
1011 return pOLV->GetEditView().GetSurroundingTextSelection();
1012 return Selection( 0, 0 );
1015 bool Window::DeleteSurroundingText(const Selection& rSelection)
1017 OutlinerView *pOLV = GetOutlinerView();
1018 if (pOLV)
1019 return pOLV->GetEditView().DeleteSurroundingText(rSelection);
1020 return false;
1023 void Window::LogicInvalidate(const ::tools::Rectangle* pRectangle)
1025 DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(mpViewShell);
1026 if (!pDrawViewShell || pDrawViewShell->IsInSwitchPage())
1027 return;
1029 if (!comphelper::LibreOfficeKit::isActive())
1030 return;
1031 ::tools::Rectangle aRectangle;
1032 ::tools::Rectangle* pResultRectangle;
1033 if (!pRectangle)
1034 pResultRectangle = nullptr;
1035 else
1037 aRectangle = *pRectangle;
1038 if (GetMapMode().GetMapUnit() == MapUnit::Map100thMM)
1040 aRectangle = o3tl::convert(aRectangle, o3tl::Length::mm100, o3tl::Length::twip);
1042 pResultRectangle = &aRectangle;
1044 SfxViewShell& rSfxViewShell = pDrawViewShell->GetViewShellBase();
1045 SfxLokHelper::notifyInvalidation(&rSfxViewShell, pResultRectangle);
1048 FactoryFunction Window::GetUITestFactory() const
1050 if (get_id() == "impress_win")
1051 return ImpressWindowUIObject::create;
1053 return WindowUIObject::create;
1056 } // end of namespace sd
1058 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */