1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <limits.h>
21 
22 #include <o3tl/float_int_conversion.hxx>
23 #include <sal/log.hxx>
24 
25 #include <vcl/dialog.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/fixed.hxx>
28 #include <vcl/layout.hxx>
29 #include <vcl/timer.hxx>
30 #include <vcl/window.hxx>
31 #include <vcl/scrbar.hxx>
32 #include <vcl/dockwin.hxx>
33 #include <vcl/settings.hxx>
34 #include <vcl/builder.hxx>
35 
36 #include <window.h>
37 #include <svdata.hxx>
38 #include <salgdi.hxx>
39 #include <salframe.hxx>
40 #include <scrwnd.hxx>
41 
42 #include <com/sun/star/accessibility/AccessibleRelation.hpp>
43 #include <com/sun/star/accessibility/AccessibleRole.hpp>
44 
45 using namespace com::sun::star;
46 
47 namespace vcl {
48 
ShowFocus(const tools::Rectangle & rRect)49 void Window::ShowFocus( const tools::Rectangle& rRect )
50 {
51     if( mpWindowImpl->mbInShowFocus )
52         return;
53     mpWindowImpl->mbInShowFocus = true;
54 
55     ImplWinData* pWinData = ImplGetWinData();
56 
57     // native themeing suggest not to use focus rects
58     if( ! ( mpWindowImpl->mbUseNativeFocus &&
59             IsNativeWidgetEnabled() ) )
60     {
61         if ( !mpWindowImpl->mbInPaint )
62         {
63             if ( mpWindowImpl->mbFocusVisible )
64             {
65                 if ( *pWinData->mpFocusRect == rRect )
66                 {
67                     mpWindowImpl->mbInShowFocus = false;
68                     return;
69                 }
70 
71                 ImplInvertFocus( *pWinData->mpFocusRect );
72             }
73 
74             ImplInvertFocus( rRect );
75         }
76         pWinData->mpFocusRect = rRect;
77         mpWindowImpl->mbFocusVisible = true;
78     }
79     else
80     {
81         if( ! mpWindowImpl->mbNativeFocusVisible )
82         {
83             mpWindowImpl->mbNativeFocusVisible = true;
84             if ( !mpWindowImpl->mbInPaint )
85                 Invalidate();
86         }
87     }
88     mpWindowImpl->mbInShowFocus = false;
89 }
90 
HideFocus()91 void Window::HideFocus()
92 {
93 
94     if( mpWindowImpl->mbInHideFocus )
95         return;
96     mpWindowImpl->mbInHideFocus = true;
97 
98     // native themeing can suggest not to use focus rects
99     if( ! ( mpWindowImpl->mbUseNativeFocus &&
100             IsNativeWidgetEnabled() ) )
101     {
102         if ( !mpWindowImpl->mbFocusVisible )
103         {
104             mpWindowImpl->mbInHideFocus = false;
105             return;
106         }
107 
108         if ( !mpWindowImpl->mbInPaint )
109             ImplInvertFocus( *ImplGetWinData()->mpFocusRect );
110         mpWindowImpl->mbFocusVisible = false;
111     }
112     else
113     {
114         if( mpWindowImpl->mbNativeFocusVisible )
115         {
116             mpWindowImpl->mbNativeFocusVisible = false;
117             if ( !mpWindowImpl->mbInPaint )
118                 Invalidate();
119         }
120     }
121     mpWindowImpl->mbInHideFocus = false;
122 }
123 
ShowTracking(const tools::Rectangle & rRect,ShowTrackFlags nFlags)124 void Window::ShowTracking( const tools::Rectangle& rRect, ShowTrackFlags nFlags )
125 {
126     ImplWinData* pWinData = ImplGetWinData();
127 
128     if ( !mpWindowImpl->mbInPaint || !(nFlags & ShowTrackFlags::TrackWindow) )
129     {
130         if ( mpWindowImpl->mbTrackVisible )
131         {
132             if ( (*pWinData->mpTrackRect  == rRect) &&
133                  (pWinData->mnTrackFlags    == nFlags) )
134                 return;
135 
136             InvertTracking( *pWinData->mpTrackRect, pWinData->mnTrackFlags );
137         }
138 
139         InvertTracking( rRect, nFlags );
140     }
141 
142     pWinData->mpTrackRect = rRect;
143     pWinData->mnTrackFlags      = nFlags;
144     mpWindowImpl->mbTrackVisible              = true;
145 }
146 
HideTracking()147 void Window::HideTracking()
148 {
149     if ( mpWindowImpl->mbTrackVisible )
150     {
151         ImplWinData* pWinData = ImplGetWinData();
152         if ( !mpWindowImpl->mbInPaint || !(pWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
153             InvertTracking( *pWinData->mpTrackRect, pWinData->mnTrackFlags );
154         mpWindowImpl->mbTrackVisible = false;
155     }
156 }
157 
InvertTracking(const tools::Rectangle & rRect,ShowTrackFlags nFlags)158 void Window::InvertTracking( const tools::Rectangle& rRect, ShowTrackFlags nFlags )
159 {
160     OutputDevice *pOutDev = GetOutDev();
161     tools::Rectangle aRect( pOutDev->ImplLogicToDevicePixel( rRect ) );
162 
163     if ( aRect.IsEmpty() )
164         return;
165     aRect.Justify();
166 
167     SalGraphics* pGraphics;
168 
169     if ( nFlags & ShowTrackFlags::TrackWindow )
170     {
171         if ( !IsDeviceOutputNecessary() )
172             return;
173 
174         // we need a graphics
175         if ( !mpGraphics )
176         {
177             if ( !pOutDev->AcquireGraphics() )
178                 return;
179         }
180 
181         if ( mbInitClipRegion )
182             InitClipRegion();
183 
184         if ( mbOutputClipped )
185             return;
186 
187         pGraphics = mpGraphics;
188     }
189     else
190     {
191         pGraphics = ImplGetFrameGraphics();
192 
193         if ( nFlags & ShowTrackFlags::Clip )
194         {
195             Point aPoint( mnOutOffX, mnOutOffY );
196             vcl::Region aRegion( tools::Rectangle( aPoint,
197                                        Size( mnOutWidth, mnOutHeight ) ) );
198             ImplClipBoundaries( aRegion, false, false );
199             pOutDev->SelectClipRegion( aRegion, pGraphics );
200         }
201     }
202 
203     ShowTrackFlags nStyle = nFlags & ShowTrackFlags::StyleMask;
204     if ( nStyle == ShowTrackFlags::Object )
205         pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::TrackFrame, this );
206     else if ( nStyle == ShowTrackFlags::Split )
207         pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::N50, this );
208     else
209     {
210         long nBorder = 1;
211         if ( nStyle == ShowTrackFlags::Big )
212             nBorder = 5;
213         pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), nBorder, SalInvert::N50, this );
214         pGraphics->Invert( aRect.Left(), aRect.Bottom()-nBorder+1, aRect.GetWidth(), nBorder, SalInvert::N50, this );
215         pGraphics->Invert( aRect.Left(), aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, this );
216         pGraphics->Invert( aRect.Right()-nBorder+1, aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, this );
217     }
218 }
219 
IMPL_LINK(Window,ImplTrackTimerHdl,Timer *,pTimer,void)220 IMPL_LINK( Window, ImplTrackTimerHdl, Timer*, pTimer, void )
221 {
222     ImplSVData* pSVData = ImplGetSVData();
223 
224     // if Button-Repeat we have to change the timeout
225     if ( pSVData->maWinData.mnTrackFlags & StartTrackingFlags::ButtonRepeat )
226         pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
227 
228     // create Tracking-Event
229     Point           aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
230     if( ImplIsAntiparallel() )
231     {
232         // re-mirror frame pos at pChild
233         const OutputDevice *pOutDev = GetOutDev();
234         pOutDev->ReMirror( aMousePos );
235     }
236     MouseEvent      aMEvt( ImplFrameToOutput( aMousePos ),
237                            mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
238                            mpWindowImpl->mpFrameData->mnMouseCode,
239                            mpWindowImpl->mpFrameData->mnMouseCode );
240     TrackingEvent   aTEvt( aMEvt, TrackingEventFlags::Repeat );
241     Tracking( aTEvt );
242 }
243 
StartTracking(StartTrackingFlags nFlags)244 void Window::StartTracking( StartTrackingFlags nFlags )
245 {
246     ImplSVData* pSVData = ImplGetSVData();
247 
248     if ( pSVData->maWinData.mpTrackWin.get() != this )
249     {
250         if ( pSVData->maWinData.mpTrackWin )
251             pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel );
252     }
253 
254     if ( nFlags & (StartTrackingFlags::ScrollRepeat | StartTrackingFlags::ButtonRepeat) )
255     {
256         pSVData->maWinData.mpTrackTimer = new AutoTimer;
257 
258         if ( nFlags & StartTrackingFlags::ScrollRepeat )
259             pSVData->maWinData.mpTrackTimer->SetTimeout( MouseSettings::GetScrollRepeat() );
260         else
261             pSVData->maWinData.mpTrackTimer->SetTimeout( MouseSettings::GetButtonStartRepeat() );
262         pSVData->maWinData.mpTrackTimer->SetInvokeHandler( LINK( this, Window, ImplTrackTimerHdl ) );
263         pSVData->maWinData.mpTrackTimer->SetDebugName( "vcl::Window pSVData->maWinData.mpTrackTimer" );
264         pSVData->maWinData.mpTrackTimer->Start();
265     }
266 
267     pSVData->maWinData.mpTrackWin   = this;
268     pSVData->maWinData.mnTrackFlags = nFlags;
269     CaptureMouse();
270 }
271 
EndTracking(TrackingEventFlags nFlags)272 void Window::EndTracking( TrackingEventFlags nFlags )
273 {
274     ImplSVData* pSVData = ImplGetSVData();
275 
276     if ( pSVData->maWinData.mpTrackWin.get() == this )
277     {
278         if ( pSVData->maWinData.mpTrackTimer )
279         {
280             delete pSVData->maWinData.mpTrackTimer;
281             pSVData->maWinData.mpTrackTimer = nullptr;
282         }
283 
284         pSVData->maWinData.mpTrackWin    = nullptr;
285         pSVData->maWinData.mnTrackFlags  = StartTrackingFlags::NONE;
286         ReleaseMouse();
287 
288         // call EndTracking if required
289         {
290             Point           aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
291             if( ImplIsAntiparallel() )
292             {
293                 // re-mirror frame pos at pChild
294                 const OutputDevice *pOutDev = GetOutDev();
295                 pOutDev->ReMirror( aMousePos );
296             }
297 
298             MouseEvent      aMEvt( ImplFrameToOutput( aMousePos ),
299                                    mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
300                                    mpWindowImpl->mpFrameData->mnMouseCode,
301                                    mpWindowImpl->mpFrameData->mnMouseCode );
302             TrackingEvent   aTEvt( aMEvt, nFlags | TrackingEventFlags::End );
303             // CompatTracking effectively
304             if (!mpWindowImpl || mpWindowImpl->mbInDispose)
305                 return Window::Tracking( aTEvt );
306             else
307                 return Tracking( aTEvt );
308         }
309     }
310 }
311 
IsTracking() const312 bool Window::IsTracking() const
313 {
314     return (ImplGetSVData()->maWinData.mpTrackWin == this);
315 }
316 
StartAutoScroll(StartAutoScrollFlags nFlags)317 void Window::StartAutoScroll( StartAutoScrollFlags nFlags )
318 {
319     ImplSVData* pSVData = ImplGetSVData();
320 
321     if ( pSVData->maWinData.mpAutoScrollWin.get() != this )
322     {
323         if ( pSVData->maWinData.mpAutoScrollWin )
324             pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
325     }
326 
327     pSVData->maWinData.mpAutoScrollWin = this;
328     pSVData->maWinData.mnAutoScrollFlags = nFlags;
329     pSVData->maAppData.mpWheelWindow = VclPtr<ImplWheelWindow>::Create( this );
330 }
331 
EndAutoScroll()332 void Window::EndAutoScroll()
333 {
334     ImplSVData* pSVData = ImplGetSVData();
335 
336     if ( pSVData->maWinData.mpAutoScrollWin.get() == this )
337     {
338         pSVData->maWinData.mpAutoScrollWin = nullptr;
339         pSVData->maWinData.mnAutoScrollFlags = StartAutoScrollFlags::NONE;
340         pSVData->maAppData.mpWheelWindow->ImplStop();
341         pSVData->maAppData.mpWheelWindow->SetParentToDefaultWindow();
342         pSVData->maAppData.mpWheelWindow.disposeAndClear();
343     }
344 }
345 
SaveFocus()346 VclPtr<vcl::Window> Window::SaveFocus()
347 {
348     ImplSVData* pSVData = ImplGetSVData();
349     if ( pSVData->maWinData.mpFocusWin )
350     {
351         return pSVData->maWinData.mpFocusWin;
352     }
353     else
354         return nullptr;
355 }
356 
EndSaveFocus(const VclPtr<vcl::Window> & xFocusWin)357 void Window::EndSaveFocus(const VclPtr<vcl::Window>& xFocusWin)
358 {
359     if (xFocusWin && !xFocusWin->IsDisposed())
360     {
361         xFocusWin->GrabFocus();
362     }
363 }
364 
SetZoom(const Fraction & rZoom)365 void Window::SetZoom( const Fraction& rZoom )
366 {
367     if ( mpWindowImpl && mpWindowImpl->maZoom != rZoom )
368     {
369         mpWindowImpl->maZoom = rZoom;
370         CompatStateChanged( StateChangedType::Zoom );
371     }
372 }
373 
WinFloatRound(double fVal)374 static long WinFloatRound( double fVal )
375 {
376     return( fVal > 0.0 ? static_cast<long>( fVal + 0.5 ) : -static_cast<long>( -fVal + 0.5 ) );
377 }
378 
SetZoomedPointFont(vcl::RenderContext & rRenderContext,const vcl::Font & rFont)379 void Window::SetZoomedPointFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
380 {
381     const Fraction& rZoom = GetZoom();
382     if (rZoom.GetNumerator() != rZoom.GetDenominator())
383     {
384         vcl::Font aFont(rFont);
385         Size aSize = aFont.GetFontSize();
386         aSize.setWidth( WinFloatRound(double(aSize.Width() * rZoom)) );
387         aSize.setHeight( WinFloatRound(double(aSize.Height() * rZoom)) );
388         aFont.SetFontSize(aSize);
389         SetPointFont(rRenderContext, aFont);
390     }
391     else
392     {
393         SetPointFont(rRenderContext, rFont);
394     }
395 }
396 
CalcZoom(long nCalc) const397 long Window::CalcZoom( long nCalc ) const
398 {
399 
400     const Fraction& rZoom = GetZoom();
401     if ( rZoom.GetNumerator() != rZoom.GetDenominator() )
402     {
403         double n = double(nCalc * rZoom);
404         nCalc = WinFloatRound( n );
405     }
406     return nCalc;
407 }
408 
SetControlFont()409 void Window::SetControlFont()
410 {
411     if (mpWindowImpl && mpWindowImpl->mpControlFont)
412     {
413         mpWindowImpl->mpControlFont.reset();
414         CompatStateChanged(StateChangedType::ControlFont);
415     }
416 }
417 
SetControlFont(const vcl::Font & rFont)418 void Window::SetControlFont(const vcl::Font& rFont)
419 {
420     if (rFont == vcl::Font())
421     {
422         SetControlFont();
423         return;
424     }
425 
426     if (mpWindowImpl->mpControlFont)
427     {
428         if (*mpWindowImpl->mpControlFont == rFont)
429             return;
430         *mpWindowImpl->mpControlFont = rFont;
431     }
432     else
433         mpWindowImpl->mpControlFont.reset( new vcl::Font(rFont) );
434 
435     CompatStateChanged(StateChangedType::ControlFont);
436 }
437 
GetControlFont() const438 vcl::Font Window::GetControlFont() const
439 {
440     if (mpWindowImpl->mpControlFont)
441         return *mpWindowImpl->mpControlFont;
442     else
443     {
444         vcl::Font aFont;
445         return aFont;
446     }
447 }
448 
ApplyControlFont(vcl::RenderContext & rRenderContext,const vcl::Font & rFont)449 void Window::ApplyControlFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
450 {
451     vcl::Font aFont(rFont);
452     if (IsControlFont())
453         aFont.Merge(GetControlFont());
454     SetZoomedPointFont(rRenderContext, aFont);
455 }
456 
SetControlForeground()457 void Window::SetControlForeground()
458 {
459     if (mpWindowImpl->mbControlForeground)
460     {
461         mpWindowImpl->maControlForeground = COL_TRANSPARENT;
462         mpWindowImpl->mbControlForeground = false;
463         CompatStateChanged(StateChangedType::ControlForeground);
464     }
465 }
466 
SetControlForeground(const Color & rColor)467 void Window::SetControlForeground(const Color& rColor)
468 {
469     if (rColor.GetTransparency())
470     {
471         if (mpWindowImpl->mbControlForeground)
472         {
473             mpWindowImpl->maControlForeground = COL_TRANSPARENT;
474             mpWindowImpl->mbControlForeground = false;
475             CompatStateChanged(StateChangedType::ControlForeground);
476         }
477     }
478     else
479     {
480         if (mpWindowImpl->maControlForeground != rColor)
481         {
482             mpWindowImpl->maControlForeground = rColor;
483             mpWindowImpl->mbControlForeground = true;
484             CompatStateChanged(StateChangedType::ControlForeground);
485         }
486     }
487 }
488 
ApplyControlForeground(vcl::RenderContext & rRenderContext,const Color & rDefaultColor)489 void Window::ApplyControlForeground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
490 {
491     Color aTextColor(rDefaultColor);
492     if (IsControlForeground())
493         aTextColor = GetControlForeground();
494     rRenderContext.SetTextColor(aTextColor);
495 }
496 
SetControlBackground()497 void Window::SetControlBackground()
498 {
499     if (mpWindowImpl->mbControlBackground)
500     {
501         mpWindowImpl->maControlBackground = COL_TRANSPARENT;
502         mpWindowImpl->mbControlBackground = false;
503         CompatStateChanged(StateChangedType::ControlBackground);
504     }
505 }
506 
SetControlBackground(const Color & rColor)507 void Window::SetControlBackground(const Color& rColor)
508 {
509     if (rColor.GetTransparency())
510     {
511         if (mpWindowImpl->mbControlBackground)
512         {
513             mpWindowImpl->maControlBackground = COL_TRANSPARENT;
514             mpWindowImpl->mbControlBackground = false;
515             CompatStateChanged(StateChangedType::ControlBackground);
516         }
517     }
518     else
519     {
520         if (mpWindowImpl->maControlBackground != rColor)
521         {
522             mpWindowImpl->maControlBackground = rColor;
523             mpWindowImpl->mbControlBackground = true;
524             CompatStateChanged(StateChangedType::ControlBackground);
525         }
526     }
527 }
528 
ApplyControlBackground(vcl::RenderContext & rRenderContext,const Color & rDefaultColor)529 void Window::ApplyControlBackground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
530 {
531     Color aColor(rDefaultColor);
532     if (IsControlBackground())
533         aColor = GetControlBackground();
534     rRenderContext.SetBackground(aColor);
535 }
536 
CalcWindowSize(const Size & rOutSz) const537 Size Window::CalcWindowSize( const Size& rOutSz ) const
538 {
539     Size aSz = rOutSz;
540     aSz.AdjustWidth(mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder );
541     aSz.AdjustHeight(mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
542     return aSz;
543 }
544 
CalcOutputSize(const Size & rWinSz) const545 Size Window::CalcOutputSize( const Size& rWinSz ) const
546 {
547     Size aSz = rWinSz;
548     aSz.AdjustWidth( -(mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder) );
549     aSz.AdjustHeight( -(mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder) );
550     return aSz;
551 }
552 
GetDrawPixelFont(OutputDevice const * pDev) const553 vcl::Font Window::GetDrawPixelFont(OutputDevice const * pDev) const
554 {
555     vcl::Font aFont = GetPointFont(*const_cast<Window*>(this));
556     Size aFontSize = aFont.GetFontSize();
557     MapMode aPtMapMode(MapUnit::MapPoint);
558     aFontSize = pDev->LogicToPixel( aFontSize, aPtMapMode );
559     aFont.SetFontSize( aFontSize );
560     return aFont;
561 }
562 
GetDrawPixel(OutputDevice const * pDev,long nPixels) const563 long Window::GetDrawPixel( OutputDevice const * pDev, long nPixels ) const
564 {
565     long nP = nPixels;
566     if ( pDev->GetOutDevType() != OUTDEV_WINDOW )
567     {
568         MapMode aMap( MapUnit::Map100thMM );
569         Size aSz( nP, 0 );
570         aSz = PixelToLogic( aSz, aMap );
571         aSz = pDev->LogicToPixel( aSz, aMap );
572         nP = aSz.Width();
573     }
574     return nP;
575 }
576 
lcl_HandleScrollHelper(ScrollBar * pScrl,double nN,bool isMultiplyByLineSize)577 static void lcl_HandleScrollHelper( ScrollBar* pScrl, double nN, bool isMultiplyByLineSize )
578 {
579     if ( pScrl && nN && pScrl->IsEnabled() && pScrl->IsInputEnabled() && ! pScrl->IsInModalMode() )
580     {
581         long nNewPos = pScrl->GetThumbPos();
582 
583         if ( nN == double(-LONG_MAX) )
584             nNewPos += pScrl->GetPageSize();
585         else if ( nN == double(LONG_MAX) )
586             nNewPos -= pScrl->GetPageSize();
587         else
588         {
589             // allowing both chunked and continuous scrolling
590             if(isMultiplyByLineSize){
591                 nN*=pScrl->GetLineSize();
592             }
593 
594             const double fVal = nNewPos - nN;
595 
596             if ( !o3tl::convertsToAtLeast(fVal, LONG_MIN) )
597                 nNewPos = LONG_MIN;
598             else if ( !o3tl::convertsToAtMost(fVal, LONG_MAX) )
599                 nNewPos = LONG_MAX;
600             else
601                 nNewPos = static_cast<long>(fVal);
602         }
603 
604         pScrl->DoScroll( nNewPos );
605     }
606 
607 }
608 
HandleScrollCommand(const CommandEvent & rCmd,ScrollBar * pHScrl,ScrollBar * pVScrl)609 bool Window::HandleScrollCommand( const CommandEvent& rCmd,
610                                   ScrollBar* pHScrl, ScrollBar* pVScrl )
611 {
612     bool bRet = false;
613 
614     if ( pHScrl || pVScrl )
615     {
616         switch( rCmd.GetCommand() )
617         {
618             case CommandEventId::StartAutoScroll:
619             {
620                 StartAutoScrollFlags nFlags = StartAutoScrollFlags::NONE;
621                 if ( pHScrl )
622                 {
623                     if ( (pHScrl->GetVisibleSize() < pHScrl->GetRangeMax()) &&
624                          pHScrl->IsEnabled() && pHScrl->IsInputEnabled() && ! pHScrl->IsInModalMode() )
625                         nFlags |= StartAutoScrollFlags::Horz;
626                 }
627                 if ( pVScrl )
628                 {
629                     if ( (pVScrl->GetVisibleSize() < pVScrl->GetRangeMax()) &&
630                          pVScrl->IsEnabled() && pVScrl->IsInputEnabled() && ! pVScrl->IsInModalMode() )
631                         nFlags |= StartAutoScrollFlags::Vert;
632                 }
633 
634                 if ( nFlags != StartAutoScrollFlags::NONE )
635                 {
636                     StartAutoScroll( nFlags );
637                     bRet = true;
638                 }
639             }
640             break;
641 
642             case CommandEventId::Wheel:
643             {
644                 const CommandWheelData* pData = rCmd.GetWheelData();
645 
646                 if ( pData && (CommandWheelMode::SCROLL == pData->GetMode()) )
647                 {
648                     if (!pData->IsDeltaPixel())
649                     {
650                         double nScrollLines = pData->GetScrollLines();
651                         double nLines;
652                         if ( nScrollLines == COMMAND_WHEEL_PAGESCROLL )
653                         {
654                             if ( pData->GetDelta() < 0 )
655                                 nLines = double(-LONG_MAX);
656                             else
657                                 nLines = double(LONG_MAX);
658                         }
659                         else
660                             nLines = pData->GetNotchDelta() * nScrollLines;
661                         if ( nLines )
662                         {
663                             ImplHandleScroll( nullptr,
664                                           0L,
665                                           pData->IsHorz() ? pHScrl : pVScrl,
666                                           nLines );
667                             bRet = true;
668                         }
669                     }
670                     else
671                     {
672                         // Mobile / touch scrolling section
673                         const Point & deltaPoint = rCmd.GetMousePosPixel();
674 
675                         double deltaXInPixels = double(deltaPoint.X());
676                         double deltaYInPixels = double(deltaPoint.Y());
677                         Size winSize = GetOutputSizePixel();
678 
679                         if(pHScrl)
680                         {
681                             double visSizeX = double(pHScrl->GetVisibleSize());
682                             double ratioX = deltaXInPixels / double(winSize.getWidth());
683                             long deltaXInLogic = long(visSizeX * ratioX);
684                             // Touch need to work by pixels. Did not apply this to
685                             // Android, as android code may require adaptations
686                             // to work with this scrolling code
687 #ifndef IOS
688                             long lineSizeX = pHScrl->GetLineSize();
689 
690                             if(lineSizeX)
691                             {
692                                 deltaXInLogic /= lineSizeX;
693                             }
694                             else
695                             {
696                                 deltaXInLogic = 0;
697                             }
698 #endif
699                             if ( deltaXInLogic)
700                             {
701 #ifndef IOS
702                                 bool const isMultiplyByLineSize = true;
703 #else
704                                 bool const isMultiplyByLineSize = false;
705 #endif
706                                 lcl_HandleScrollHelper( pHScrl, deltaXInLogic, isMultiplyByLineSize );
707                                 bRet = true;
708                             }
709                         }
710                         if(pVScrl)
711                         {
712                             double visSizeY = double(pVScrl->GetVisibleSize());
713                             double ratioY = deltaYInPixels / double(winSize.getHeight());
714                             long deltaYInLogic = long(visSizeY * ratioY);
715 
716                             // Touch need to work by pixels. Did not apply this to
717                             // Android, as android code may require adaptations
718                             // to work with this scrolling code
719 #ifndef IOS
720                             long lineSizeY = pVScrl->GetLineSize();
721                             if(lineSizeY)
722                             {
723                                 deltaYInLogic /= lineSizeY;
724                             }
725                             else
726                             {
727                                 deltaYInLogic = 0;
728                             }
729 #endif
730                             if ( deltaYInLogic )
731                             {
732 #ifndef IOS
733                                 bool const isMultiplyByLineSize = true;
734 #else
735                                 bool const isMultiplyByLineSize = false;
736 #endif
737                                 lcl_HandleScrollHelper( pVScrl, deltaYInLogic, isMultiplyByLineSize );
738 
739                                 bRet = true;
740                             }
741                         }
742                     }
743                 }
744             }
745             break;
746 
747             case CommandEventId::Gesture:
748             {
749                 if (pVScrl)
750                 {
751                     const CommandGestureData* pData = rCmd.GetGestureData();
752                     if (pData->meEventType == GestureEventType::PanningBegin)
753                     {
754                         mpWindowImpl->mpFrameData->mnTouchPanPosition = pVScrl->GetThumbPos();
755                     }
756                     else if(pData->meEventType == GestureEventType::PanningUpdate)
757                     {
758                         long nOriginalPosition = mpWindowImpl->mpFrameData->mnTouchPanPosition;
759                         pVScrl->DoScroll(nOriginalPosition + (pData->mfOffset / pVScrl->GetVisibleSize()));
760                     }
761                     if (pData->meEventType == GestureEventType::PanningEnd)
762                     {
763                         mpWindowImpl->mpFrameData->mnTouchPanPosition = -1;
764                     }
765                     bRet = true;
766                 }
767                 break;
768             }
769 
770             case CommandEventId::AutoScroll:
771             {
772                 const CommandScrollData* pData = rCmd.GetAutoScrollData();
773                 if ( pData && (pData->GetDeltaX() || pData->GetDeltaY()) )
774                 {
775                     ImplHandleScroll( pHScrl, pData->GetDeltaX(),
776                                       pVScrl, pData->GetDeltaY() );
777                     bRet = true;
778                 }
779             }
780             break;
781 
782             default:
783             break;
784         }
785     }
786 
787     return bRet;
788 }
789 
790 // Note that when called for CommandEventId::Wheel above, despite its name,
791 // pVScrl isn't necessarily the vertical scroll bar. Depending on
792 // whether the scroll is horizontal or vertical, it is either the
793 // horizontal or vertical scroll bar. nY is correspondingly either
794 // the horizontal or vertical scroll amount.
795 
ImplHandleScroll(ScrollBar * pHScrl,double nX,ScrollBar * pVScrl,double nY)796 void Window::ImplHandleScroll( ScrollBar* pHScrl, double nX,
797                                ScrollBar* pVScrl, double nY )
798 {
799     lcl_HandleScrollHelper( pHScrl, nX, true );
800     lcl_HandleScrollHelper( pVScrl, nY, true );
801 }
802 
GetDockingManager()803 DockingManager* Window::GetDockingManager()
804 {
805     return ImplGetDockingManager();
806 }
807 
EnableDocking(bool bEnable)808 void Window::EnableDocking( bool bEnable )
809 {
810     // update list of dockable windows
811     if( bEnable )
812         ImplGetDockingManager()->AddWindow( this );
813     else
814         ImplGetDockingManager()->RemoveWindow( this );
815 }
816 
817 // retrieves the list of owner draw decorated windows for this window hierarchy
ImplGetOwnerDrawList()818 ::std::vector<VclPtr<vcl::Window> >& Window::ImplGetOwnerDrawList()
819 {
820     return ImplGetTopmostFrameWindow()->mpWindowImpl->mpFrameData->maOwnerDrawList;
821 }
822 
SetHelpId(const OString & rHelpId)823 void Window::SetHelpId( const OString& rHelpId )
824 {
825     mpWindowImpl->maHelpId = rHelpId;
826 }
827 
GetHelpId() const828 const OString& Window::GetHelpId() const
829 {
830     return mpWindowImpl->maHelpId;
831 }
832 
833 // --------- old inline methods ---------------
834 
ImplGetWindow() const835 vcl::Window* Window::ImplGetWindow() const
836 {
837     if ( mpWindowImpl->mpClientWindow )
838         return mpWindowImpl->mpClientWindow;
839     else
840         return const_cast<vcl::Window*>(this);
841 }
842 
ImplGetFrameData()843 ImplFrameData* Window::ImplGetFrameData()
844 {
845     return mpWindowImpl ? mpWindowImpl->mpFrameData : nullptr;
846 }
847 
ImplGetFrame() const848 SalFrame* Window::ImplGetFrame() const
849 {
850     return mpWindowImpl ? mpWindowImpl->mpFrame : nullptr;
851 }
852 
GetFrameWeld() const853 weld::Window* Window::GetFrameWeld() const
854 {
855     SalFrame* pFrame = ImplGetFrame();
856     return pFrame ? pFrame->GetFrameWeld() : nullptr;
857 }
858 
ImplGetParent() const859 vcl::Window* Window::ImplGetParent() const
860 {
861     return mpWindowImpl ? mpWindowImpl->mpParent.get() : nullptr;
862 }
863 
ImplGetClientWindow() const864 vcl::Window* Window::ImplGetClientWindow() const
865 {
866     return mpWindowImpl ? mpWindowImpl->mpClientWindow.get() : nullptr;
867 }
868 
ImplGetBorderWindow() const869 vcl::Window* Window::ImplGetBorderWindow() const
870 {
871     return mpWindowImpl ? mpWindowImpl->mpBorderWindow.get() : nullptr;
872 }
873 
ImplGetFirstOverlapWindow()874 vcl::Window* Window::ImplGetFirstOverlapWindow()
875 {
876     if ( mpWindowImpl->mbOverlapWin )
877         return this;
878     else
879         return mpWindowImpl->mpOverlapWindow;
880 }
881 
ImplGetFirstOverlapWindow() const882 const vcl::Window* Window::ImplGetFirstOverlapWindow() const
883 {
884     if ( mpWindowImpl->mbOverlapWin )
885         return this;
886     else
887         return mpWindowImpl->mpOverlapWindow;
888 }
889 
ImplGetFrameWindow() const890 vcl::Window* Window::ImplGetFrameWindow() const
891 {
892     return mpWindowImpl ? mpWindowImpl->mpFrameWindow.get() : nullptr;
893 }
894 
IsDockingWindow() const895 bool Window::IsDockingWindow() const
896 {
897     return mpWindowImpl && mpWindowImpl->mbDockWin;
898 }
899 
ImplIsFloatingWindow() const900 bool Window::ImplIsFloatingWindow() const
901 {
902     return mpWindowImpl && mpWindowImpl->mbFloatWin;
903 }
904 
ImplIsSplitter() const905 bool Window::ImplIsSplitter() const
906 {
907     return mpWindowImpl && mpWindowImpl->mbSplitter;
908 }
909 
ImplIsPushButton() const910 bool Window::ImplIsPushButton() const
911 {
912     return mpWindowImpl && mpWindowImpl->mbPushButton;
913 }
914 
ImplIsOverlapWindow() const915 bool Window::ImplIsOverlapWindow() const
916 {
917     return mpWindowImpl && mpWindowImpl->mbOverlapWin;
918 }
919 
ImplSetMouseTransparent(bool bTransparent)920 void Window::ImplSetMouseTransparent( bool bTransparent )
921 {
922     if (mpWindowImpl)
923         mpWindowImpl->mbMouseTransparent = bTransparent;
924 }
925 
ImplOutputToFrame(const Point & rPos)926 Point Window::ImplOutputToFrame( const Point& rPos )
927 {
928     return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
929 }
930 
ImplFrameToOutput(const Point & rPos)931 Point Window::ImplFrameToOutput( const Point& rPos )
932 {
933     return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
934 }
935 
SetCompoundControl(bool bCompound)936 void Window::SetCompoundControl( bool bCompound )
937 {
938     if (mpWindowImpl)
939         mpWindowImpl->mbCompoundControl = bCompound;
940 }
941 
GetStyle() const942 WinBits Window::GetStyle() const
943 {
944     return mpWindowImpl ? mpWindowImpl->mnStyle : 0;
945 }
946 
GetPrevStyle() const947 WinBits Window::GetPrevStyle() const
948 {
949     return mpWindowImpl ? mpWindowImpl->mnPrevStyle : 0;
950 }
951 
GetExtendedStyle() const952 WindowExtendedStyle Window::GetExtendedStyle() const
953 {
954     return mpWindowImpl ? mpWindowImpl->mnExtendedStyle : WindowExtendedStyle::NONE;
955 }
956 
SetType(WindowType nType)957 void Window::SetType( WindowType nType )
958 {
959     if (mpWindowImpl)
960         mpWindowImpl->mnType = nType;
961 }
962 
GetType() const963 WindowType Window::GetType() const
964 {
965     if (mpWindowImpl)
966         return mpWindowImpl->mnType;
967     else
968         return WindowType::NONE;
969 }
970 
GetParentDialog() const971 Dialog* Window::GetParentDialog() const
972 {
973     const vcl::Window *pWindow = this;
974 
975     while( pWindow )
976     {
977         if( pWindow->IsDialog() )
978             break;
979 
980         pWindow = pWindow->GetParent();
981     }
982 
983     return const_cast<Dialog *>(dynamic_cast<const Dialog*>(pWindow));
984 }
985 
IsSystemWindow() const986 bool Window::IsSystemWindow() const
987 {
988     return mpWindowImpl && mpWindowImpl->mbSysWin;
989 }
990 
IsDialog() const991 bool Window::IsDialog() const
992 {
993     return mpWindowImpl && mpWindowImpl->mbDialog;
994 }
995 
IsMenuFloatingWindow() const996 bool Window::IsMenuFloatingWindow() const
997 {
998     return mpWindowImpl && mpWindowImpl->mbMenuFloatingWindow;
999 }
1000 
IsToolbarFloatingWindow() const1001 bool Window::IsToolbarFloatingWindow() const
1002 {
1003     return mpWindowImpl && mpWindowImpl->mbToolbarFloatingWindow;
1004 }
1005 
EnableAllResize()1006 void Window::EnableAllResize()
1007 {
1008     mpWindowImpl->mbAllResize = true;
1009 }
1010 
EnableChildTransparentMode(bool bEnable)1011 void Window::EnableChildTransparentMode( bool bEnable )
1012 {
1013     mpWindowImpl->mbChildTransparent = bEnable;
1014 }
1015 
IsChildTransparentModeEnabled() const1016 bool Window::IsChildTransparentModeEnabled() const
1017 {
1018     return mpWindowImpl && mpWindowImpl->mbChildTransparent;
1019 }
1020 
IsMouseTransparent() const1021 bool Window::IsMouseTransparent() const
1022 {
1023     return mpWindowImpl && mpWindowImpl->mbMouseTransparent;
1024 }
1025 
IsPaintTransparent() const1026 bool Window::IsPaintTransparent() const
1027 {
1028     return mpWindowImpl && mpWindowImpl->mbPaintTransparent;
1029 }
1030 
SetDialogControlStart(bool bStart)1031 void Window::SetDialogControlStart( bool bStart )
1032 {
1033     mpWindowImpl->mbDlgCtrlStart = bStart;
1034 }
1035 
IsDialogControlStart() const1036 bool Window::IsDialogControlStart() const
1037 {
1038     return mpWindowImpl && mpWindowImpl->mbDlgCtrlStart;
1039 }
1040 
SetDialogControlFlags(DialogControlFlags nFlags)1041 void Window::SetDialogControlFlags( DialogControlFlags nFlags )
1042 {
1043     mpWindowImpl->mnDlgCtrlFlags = nFlags;
1044 }
1045 
GetDialogControlFlags() const1046 DialogControlFlags Window::GetDialogControlFlags() const
1047 {
1048     return mpWindowImpl->mnDlgCtrlFlags;
1049 }
1050 
GetInputContext() const1051 const InputContext& Window::GetInputContext() const
1052 {
1053     return mpWindowImpl->maInputContext;
1054 }
1055 
IsControlFont() const1056 bool Window::IsControlFont() const
1057 {
1058     return bool(mpWindowImpl->mpControlFont);
1059 }
1060 
GetControlForeground() const1061 const Color& Window::GetControlForeground() const
1062 {
1063     return mpWindowImpl->maControlForeground;
1064 }
1065 
IsControlForeground() const1066 bool Window::IsControlForeground() const
1067 {
1068     return mpWindowImpl->mbControlForeground;
1069 }
1070 
GetControlBackground() const1071 const Color& Window::GetControlBackground() const
1072 {
1073     return mpWindowImpl->maControlBackground;
1074 }
1075 
IsControlBackground() const1076 bool Window::IsControlBackground() const
1077 {
1078     return mpWindowImpl->mbControlBackground;
1079 }
1080 
IsInPaint() const1081 bool Window::IsInPaint() const
1082 {
1083     return mpWindowImpl && mpWindowImpl->mbInPaint;
1084 }
1085 
GetParent() const1086 vcl::Window* Window::GetParent() const
1087 {
1088     return mpWindowImpl ? mpWindowImpl->mpRealParent.get() : nullptr;
1089 }
1090 
IsVisible() const1091 bool Window::IsVisible() const
1092 {
1093     return mpWindowImpl && mpWindowImpl->mbVisible;
1094 }
1095 
IsReallyVisible() const1096 bool Window::IsReallyVisible() const
1097 {
1098     return mpWindowImpl && mpWindowImpl->mbReallyVisible;
1099 }
1100 
IsReallyShown() const1101 bool Window::IsReallyShown() const
1102 {
1103     return mpWindowImpl && mpWindowImpl->mbReallyShown;
1104 }
1105 
IsInInitShow() const1106 bool Window::IsInInitShow() const
1107 {
1108     return mpWindowImpl->mbInInitShow;
1109 }
1110 
IsEnabled() const1111 bool Window::IsEnabled() const
1112 {
1113     return mpWindowImpl && !mpWindowImpl->mbDisabled;
1114 }
1115 
IsInputEnabled() const1116 bool Window::IsInputEnabled() const
1117 {
1118     return mpWindowImpl && !mpWindowImpl->mbInputDisabled;
1119 }
1120 
IsAlwaysEnableInput() const1121 bool Window::IsAlwaysEnableInput() const
1122 {
1123     return mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled;
1124 }
1125 
GetActivateMode() const1126 ActivateModeFlags Window::GetActivateMode() const
1127 {
1128     return mpWindowImpl->mnActivateMode;
1129 
1130 }
1131 
IsAlwaysOnTopEnabled() const1132 bool Window::IsAlwaysOnTopEnabled() const
1133 {
1134     return mpWindowImpl->mbAlwaysOnTop;
1135 }
1136 
IsDefaultPos() const1137 bool Window::IsDefaultPos() const
1138 {
1139     return mpWindowImpl->mbDefPos;
1140 }
1141 
IsDefaultSize() const1142 bool Window::IsDefaultSize() const
1143 {
1144     return mpWindowImpl->mbDefSize;
1145 }
1146 
GetOffsetPixelFrom(const vcl::Window & rWindow) const1147 Point Window::GetOffsetPixelFrom(const vcl::Window& rWindow) const
1148 {
1149     return Point(GetOutOffXPixel() - rWindow.GetOutOffXPixel(), GetOutOffYPixel() - rWindow.GetOutOffYPixel());
1150 }
1151 
EnablePaint(bool bEnable)1152 void Window::EnablePaint( bool bEnable )
1153 {
1154     mpWindowImpl->mbPaintDisabled = !bEnable;
1155 }
1156 
IsPaintEnabled() const1157 bool Window::IsPaintEnabled() const
1158 {
1159     return !mpWindowImpl->mbPaintDisabled;
1160 }
1161 
IsUpdateMode() const1162 bool Window::IsUpdateMode() const
1163 {
1164     return !mpWindowImpl->mbNoUpdate;
1165 }
1166 
SetParentUpdateMode(bool bUpdate)1167 void Window::SetParentUpdateMode( bool bUpdate )
1168 {
1169     mpWindowImpl->mbNoParentUpdate = !bUpdate;
1170 }
1171 
IsActive() const1172 bool Window::IsActive() const
1173 {
1174     return mpWindowImpl->mbActive;
1175 }
1176 
GetGetFocusFlags() const1177 GetFocusFlags Window::GetGetFocusFlags() const
1178 {
1179     return mpWindowImpl->mnGetFocusFlags;
1180 }
1181 
IsCompoundControl() const1182 bool Window::IsCompoundControl() const
1183 {
1184     return mpWindowImpl->mbCompoundControl;
1185 }
1186 
IsWait() const1187 bool Window::IsWait() const
1188 {
1189     return (mpWindowImpl->mnWaitCount != 0);
1190 }
1191 
GetCursor() const1192 vcl::Cursor* Window::GetCursor() const
1193 {
1194     if (!mpWindowImpl)
1195         return nullptr;
1196     return mpWindowImpl->mpCursor;
1197 }
1198 
GetZoom() const1199 const Fraction& Window::GetZoom() const
1200 {
1201     return mpWindowImpl->maZoom;
1202 }
1203 
IsZoom() const1204 bool Window::IsZoom() const
1205 {
1206     return mpWindowImpl->maZoom.GetNumerator() != mpWindowImpl->maZoom.GetDenominator();
1207 }
1208 
SetHelpText(const OUString & rHelpText)1209 void Window::SetHelpText( const OUString& rHelpText )
1210 {
1211     mpWindowImpl->maHelpText = rHelpText;
1212     mpWindowImpl->mbHelpTextDynamic = true;
1213 }
1214 
SetQuickHelpText(const OUString & rHelpText)1215 void Window::SetQuickHelpText( const OUString& rHelpText )
1216 {
1217     if (mpWindowImpl)
1218         mpWindowImpl->maQuickHelpText = rHelpText;
1219 }
1220 
GetQuickHelpText() const1221 const OUString& Window::GetQuickHelpText() const
1222 {
1223     return mpWindowImpl->maQuickHelpText;
1224 }
1225 
IsCreatedWithToolkit() const1226 bool Window::IsCreatedWithToolkit() const
1227 {
1228     return mpWindowImpl->mbCreatedWithToolkit;
1229 }
1230 
SetCreatedWithToolkit(bool b)1231 void Window::SetCreatedWithToolkit( bool b )
1232 {
1233     mpWindowImpl->mbCreatedWithToolkit = b;
1234 }
1235 
GetPointer() const1236 PointerStyle Window::GetPointer() const
1237 {
1238     return mpWindowImpl->maPointer;
1239 }
1240 
GetWindowPeer() const1241 VCLXWindow* Window::GetWindowPeer() const
1242 {
1243     return mpWindowImpl ? mpWindowImpl->mpVCLXWindow : nullptr;
1244 }
1245 
SetPosPixel(const Point & rNewPos)1246 void Window::SetPosPixel( const Point& rNewPos )
1247 {
1248     setPosSizePixel( rNewPos.X(), rNewPos.Y(), 0, 0, PosSizeFlags::Pos );
1249 }
1250 
SetSizePixel(const Size & rNewSize)1251 void Window::SetSizePixel( const Size& rNewSize )
1252 {
1253     setPosSizePixel( 0, 0, rNewSize.Width(), rNewSize.Height(),
1254                      PosSizeFlags::Size );
1255 }
1256 
SetPosSizePixel(const Point & rNewPos,const Size & rNewSize)1257 void Window::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
1258 {
1259     setPosSizePixel( rNewPos.X(), rNewPos.Y(),
1260                      rNewSize.Width(), rNewSize.Height());
1261 }
1262 
SetOutputSizePixel(const Size & rNewSize)1263 void Window::SetOutputSizePixel( const Size& rNewSize )
1264 {
1265     SetSizePixel( Size( rNewSize.Width()+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
1266                         rNewSize.Height()+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder ) );
1267 }
1268 
1269 //When a widget wants to renegotiate layout, get toplevel parent dialog and call
1270 //resize on it. Mark all intermediate containers (or container-alike) widgets
1271 //as dirty for the size remains unchanged, but layout changed circumstances
1272 namespace
1273 {
queue_ungrouped_resize(vcl::Window const * pOrigWindow)1274     bool queue_ungrouped_resize(vcl::Window const *pOrigWindow)
1275     {
1276         bool bSomeoneCares = false;
1277 
1278         vcl::Window *pWindow = pOrigWindow->GetParent();
1279         if (pWindow)
1280         {
1281             if (isContainerWindow(*pWindow))
1282             {
1283                 bSomeoneCares = true;
1284             }
1285             else if (pWindow->GetType() == WindowType::TABCONTROL)
1286             {
1287                 bSomeoneCares = true;
1288             }
1289             pWindow->queue_resize();
1290         }
1291 
1292         return bSomeoneCares;
1293     }
1294 }
1295 
InvalidateSizeCache()1296 void Window::InvalidateSizeCache()
1297 {
1298     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1299     pWindowImpl->mnOptimalWidthCache = -1;
1300     pWindowImpl->mnOptimalHeightCache = -1;
1301 }
1302 
queue_resize(StateChangedType eReason)1303 void Window::queue_resize(StateChangedType eReason)
1304 {
1305     if (IsDisposed())
1306         return;
1307 
1308     bool bSomeoneCares = queue_ungrouped_resize(this);
1309 
1310     if (eReason != StateChangedType::Visible)
1311     {
1312         InvalidateSizeCache();
1313     }
1314 
1315     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1316     if (pWindowImpl->m_xSizeGroup && pWindowImpl->m_xSizeGroup->get_mode() != VclSizeGroupMode::NONE)
1317     {
1318         std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1319         for (VclPtr<vcl::Window> const & pOther : rWindows)
1320         {
1321             if (pOther == this)
1322                 continue;
1323             queue_ungrouped_resize(pOther);
1324         }
1325     }
1326 
1327     if (bSomeoneCares && !mpWindowImpl->mbInDispose)
1328     {
1329         //fdo#57090 force a resync of the borders of the borderwindow onto this
1330         //window in case they have changed
1331         vcl::Window* pBorderWindow = ImplGetBorderWindow();
1332         if (pBorderWindow)
1333             pBorderWindow->Resize();
1334     }
1335 
1336     if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1337     {
1338         if (GetParentDialog() && !pParent->IsInInitShow())
1339             LogicInvalidate(nullptr);
1340     }
1341 }
1342 
1343 namespace
1344 {
toAlign(const OUString & rValue)1345     VclAlign toAlign(const OUString &rValue)
1346     {
1347         VclAlign eRet = VclAlign::Fill;
1348 
1349         if (rValue == "fill")
1350             eRet = VclAlign::Fill;
1351         else if (rValue == "start")
1352             eRet = VclAlign::Start;
1353         else if (rValue == "end")
1354             eRet = VclAlign::End;
1355         else if (rValue == "center")
1356             eRet = VclAlign::Center;
1357         return eRet;
1358     }
1359 }
1360 
set_font_attribute(const OString & rKey,const OUString & rValue)1361 bool Window::set_font_attribute(const OString &rKey, const OUString &rValue)
1362 {
1363     if (rKey == "weight")
1364     {
1365         vcl::Font aFont(GetControlFont());
1366         if (rValue == "thin")
1367             aFont.SetWeight(WEIGHT_THIN);
1368         else if (rValue == "ultralight")
1369             aFont.SetWeight(WEIGHT_ULTRALIGHT);
1370         else if (rValue == "light")
1371             aFont.SetWeight(WEIGHT_LIGHT);
1372         else if (rValue == "book")
1373             aFont.SetWeight(WEIGHT_SEMILIGHT);
1374         else if (rValue == "normal")
1375             aFont.SetWeight(WEIGHT_NORMAL);
1376         else if (rValue == "medium")
1377             aFont.SetWeight(WEIGHT_MEDIUM);
1378         else if (rValue == "semibold")
1379             aFont.SetWeight(WEIGHT_SEMIBOLD);
1380         else if (rValue == "bold")
1381             aFont.SetWeight(WEIGHT_BOLD);
1382         else if (rValue == "ultrabold")
1383             aFont.SetWeight(WEIGHT_ULTRABOLD);
1384         else
1385             aFont.SetWeight(WEIGHT_BLACK);
1386         SetControlFont(aFont);
1387     }
1388     else if (rKey == "style")
1389     {
1390         vcl::Font aFont(GetControlFont());
1391         if (rValue == "normal")
1392             aFont.SetItalic(ITALIC_NONE);
1393         else if (rValue == "oblique")
1394             aFont.SetItalic(ITALIC_OBLIQUE);
1395         else if (rValue == "italic")
1396             aFont.SetItalic(ITALIC_NORMAL);
1397         SetControlFont(aFont);
1398     }
1399     else if (rKey == "underline")
1400     {
1401         vcl::Font aFont(GetControlFont());
1402         aFont.SetUnderline(toBool(rValue) ? LINESTYLE_SINGLE : LINESTYLE_NONE);
1403         SetControlFont(aFont);
1404     }
1405     else if (rKey == "size")
1406     {
1407         vcl::Font aFont(GetControlFont());
1408         sal_Int32 nHeight = rValue.toInt32() / 1000;
1409         aFont.SetFontHeight(nHeight);
1410         SetControlFont(aFont);
1411     }
1412     else
1413     {
1414         SAL_INFO("vcl.layout", "unhandled font attribute: " << rKey);
1415         return false;
1416     }
1417     return true;
1418 }
1419 
set_property(const OString & rKey,const OUString & rValue)1420 bool Window::set_property(const OString &rKey, const OUString &rValue)
1421 {
1422     if ((rKey == "label") || (rKey == "title") || (rKey == "text") )
1423     {
1424         SetText(BuilderUtils::convertMnemonicMarkup(rValue));
1425     }
1426     else if (rKey == "visible")
1427         Show(toBool(rValue));
1428     else if (rKey == "sensitive")
1429         Enable(toBool(rValue));
1430     else if (rKey == "resizable")
1431     {
1432         WinBits nBits = GetStyle();
1433         nBits &= ~WB_SIZEABLE;
1434         if (toBool(rValue))
1435             nBits |= WB_SIZEABLE;
1436         SetStyle(nBits);
1437     }
1438     else if (rKey == "xalign")
1439     {
1440         WinBits nBits = GetStyle();
1441         nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1442 
1443         float f = rValue.toFloat();
1444         if (f == 0.0)
1445             nBits |= WB_LEFT;
1446         else if (f == 1.0)
1447             nBits |= WB_RIGHT;
1448         else if (f == 0.5)
1449             nBits |= WB_CENTER;
1450 
1451         SetStyle(nBits);
1452     }
1453     else if (rKey == "justification")
1454     {
1455         WinBits nBits = GetStyle();
1456         nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1457 
1458         if (rValue == "left")
1459             nBits |= WB_LEFT;
1460         else if (rValue == "right")
1461             nBits |= WB_RIGHT;
1462         else if (rValue == "center")
1463             nBits |= WB_CENTER;
1464 
1465         SetStyle(nBits);
1466     }
1467     else if (rKey == "yalign")
1468     {
1469         WinBits nBits = GetStyle();
1470         nBits &= ~(WB_TOP | WB_VCENTER | WB_BOTTOM);
1471 
1472         float f = rValue.toFloat();
1473         if (f == 0.0)
1474             nBits |= WB_TOP;
1475         else if (f == 1.0)
1476             nBits |= WB_BOTTOM;
1477         else if (f == 0.5)
1478             nBits |= WB_CENTER;
1479 
1480         SetStyle(nBits);
1481     }
1482     else if (rKey == "wrap")
1483     {
1484         WinBits nBits = GetStyle();
1485         nBits &= ~WB_WORDBREAK;
1486         if (toBool(rValue))
1487             nBits |= WB_WORDBREAK;
1488         SetStyle(nBits);
1489     }
1490     else if (rKey == "height-request")
1491         set_height_request(rValue.toInt32());
1492     else if (rKey == "width-request")
1493         set_width_request(rValue.toInt32());
1494     else if (rKey == "hexpand")
1495         set_hexpand(toBool(rValue));
1496     else if (rKey == "vexpand")
1497         set_vexpand(toBool(rValue));
1498     else if (rKey == "halign")
1499         set_halign(toAlign(rValue));
1500     else if (rKey == "valign")
1501         set_valign(toAlign(rValue));
1502     else if (rKey == "tooltip-markup")
1503         SetQuickHelpText(rValue);
1504     else if (rKey == "tooltip-text")
1505         SetQuickHelpText(rValue);
1506     else if (rKey == "border-width")
1507         set_border_width(rValue.toInt32());
1508     else if (rKey == "margin-left")
1509         set_margin_left(rValue.toInt32());
1510     else if (rKey == "margin-right")
1511         set_margin_right(rValue.toInt32());
1512     else if (rKey == "margin-top")
1513         set_margin_top(rValue.toInt32());
1514     else if (rKey == "margin-bottom")
1515         set_margin_bottom(rValue.toInt32());
1516     else if (rKey == "hscrollbar-policy")
1517     {
1518         WinBits nBits = GetStyle();
1519         nBits &= ~(WB_AUTOHSCROLL|WB_HSCROLL);
1520         if (rValue == "always")
1521             nBits |= WB_HSCROLL;
1522         else if (rValue == "automatic")
1523             nBits |= WB_AUTOHSCROLL;
1524         SetStyle(nBits);
1525     }
1526     else if (rKey == "vscrollbar-policy")
1527     {
1528         WinBits nBits = GetStyle();
1529         nBits &= ~(WB_AUTOVSCROLL|WB_VSCROLL);
1530         if (rValue == "always")
1531             nBits |= WB_VSCROLL;
1532         else if (rValue == "automatic")
1533             nBits |= WB_AUTOVSCROLL;
1534         SetStyle(nBits);
1535     }
1536     else if (rKey == "accessible-name")
1537     {
1538         SetAccessibleName(rValue);
1539     }
1540     else if (rKey == "accessible-description")
1541     {
1542         SetAccessibleDescription(rValue);
1543     }
1544     else if (rKey == "accessible-role")
1545     {
1546         sal_Int16 role = BuilderUtils::getRoleFromName(rValue.toUtf8());
1547         if (role != com::sun::star::accessibility::AccessibleRole::UNKNOWN)
1548             SetAccessibleRole(role);
1549     }
1550     else if (rKey == "use-markup")
1551     {
1552         //https://live.gnome.org/GnomeGoals/RemoveMarkupInMessages
1553         SAL_WARN_IF(toBool(rValue), "vcl.layout", "Use pango attributes instead of mark-up");
1554     }
1555     else if (rKey == "has-focus")
1556     {
1557         if (toBool(rValue))
1558             GrabFocus();
1559     }
1560     else if (rKey == "can-focus")
1561     {
1562         WinBits nBits = GetStyle();
1563         nBits &= ~(WB_TABSTOP|WB_NOTABSTOP);
1564         if (toBool(rValue))
1565             nBits |= WB_TABSTOP;
1566         else
1567             nBits |= WB_NOTABSTOP;
1568         SetStyle(nBits);
1569     }
1570     else
1571     {
1572         SAL_INFO("vcl.layout", "unhandled property: " << rKey);
1573         return false;
1574     }
1575     return true;
1576 }
1577 
set_height_request(sal_Int32 nHeightRequest)1578 void Window::set_height_request(sal_Int32 nHeightRequest)
1579 {
1580     if (!mpWindowImpl)
1581         return;
1582 
1583     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1584 
1585     if ( pWindowImpl->mnHeightRequest != nHeightRequest )
1586     {
1587         pWindowImpl->mnHeightRequest = nHeightRequest;
1588         queue_resize();
1589     }
1590 }
1591 
set_width_request(sal_Int32 nWidthRequest)1592 void Window::set_width_request(sal_Int32 nWidthRequest)
1593 {
1594     if (!mpWindowImpl)
1595         return;
1596 
1597     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1598 
1599     if ( pWindowImpl->mnWidthRequest != nWidthRequest )
1600     {
1601         pWindowImpl->mnWidthRequest = nWidthRequest;
1602         queue_resize();
1603     }
1604 }
1605 
get_ungrouped_preferred_size() const1606 Size Window::get_ungrouped_preferred_size() const
1607 {
1608     Size aRet(get_width_request(), get_height_request());
1609     if (aRet.Width() == -1 || aRet.Height() == -1)
1610     {
1611         //cache gets blown away by queue_resize
1612         WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1613         if (pWindowImpl->mnOptimalWidthCache == -1 || pWindowImpl->mnOptimalHeightCache == -1)
1614         {
1615             Size aOptimal(GetOptimalSize());
1616             pWindowImpl->mnOptimalWidthCache = aOptimal.Width();
1617             pWindowImpl->mnOptimalHeightCache = aOptimal.Height();
1618         }
1619 
1620         if (aRet.Width() == -1)
1621             aRet.setWidth( pWindowImpl->mnOptimalWidthCache );
1622         if (aRet.Height() == -1)
1623             aRet.setHeight( pWindowImpl->mnOptimalHeightCache );
1624     }
1625     return aRet;
1626 }
1627 
get_preferred_size() const1628 Size Window::get_preferred_size() const
1629 {
1630     Size aRet(get_ungrouped_preferred_size());
1631 
1632     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1633     if (pWindowImpl->m_xSizeGroup)
1634     {
1635         const VclSizeGroupMode eMode = pWindowImpl->m_xSizeGroup->get_mode();
1636         if (eMode != VclSizeGroupMode::NONE)
1637         {
1638             const bool bIgnoreInHidden = pWindowImpl->m_xSizeGroup->get_ignore_hidden();
1639             const std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1640             for (auto const& window : rWindows)
1641             {
1642                 const vcl::Window *pOther = window;
1643                 if (pOther == this)
1644                     continue;
1645                 if (bIgnoreInHidden && !pOther->IsVisible())
1646                     continue;
1647                 Size aOtherSize = pOther->get_ungrouped_preferred_size();
1648                 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Horizontal)
1649                     aRet.setWidth( std::max(aRet.Width(), aOtherSize.Width()) );
1650                 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Vertical)
1651                     aRet.setHeight( std::max(aRet.Height(), aOtherSize.Height()) );
1652             }
1653         }
1654     }
1655 
1656     return aRet;
1657 }
1658 
get_halign() const1659 VclAlign Window::get_halign() const
1660 {
1661     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1662     return pWindowImpl->meHalign;
1663 }
1664 
set_halign(VclAlign eAlign)1665 void Window::set_halign(VclAlign eAlign)
1666 {
1667     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1668     pWindowImpl->meHalign = eAlign;
1669 }
1670 
get_valign() const1671 VclAlign Window::get_valign() const
1672 {
1673     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1674     return pWindowImpl->meValign;
1675 }
1676 
set_valign(VclAlign eAlign)1677 void Window::set_valign(VclAlign eAlign)
1678 {
1679     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1680     pWindowImpl->meValign = eAlign;
1681 }
1682 
get_hexpand() const1683 bool Window::get_hexpand() const
1684 {
1685     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1686     return pWindowImpl->mbHexpand;
1687 }
1688 
set_hexpand(bool bExpand)1689 void Window::set_hexpand(bool bExpand)
1690 {
1691     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1692     pWindowImpl->mbHexpand = bExpand;
1693 }
1694 
get_vexpand() const1695 bool Window::get_vexpand() const
1696 {
1697     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1698     return pWindowImpl->mbVexpand;
1699 }
1700 
set_vexpand(bool bExpand)1701 void Window::set_vexpand(bool bExpand)
1702 {
1703     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1704     pWindowImpl->mbVexpand = bExpand;
1705 }
1706 
get_expand() const1707 bool Window::get_expand() const
1708 {
1709     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1710     return pWindowImpl->mbExpand;
1711 }
1712 
set_expand(bool bExpand)1713 void Window::set_expand(bool bExpand)
1714 {
1715     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1716     pWindowImpl->mbExpand = bExpand;
1717 }
1718 
get_pack_type() const1719 VclPackType Window::get_pack_type() const
1720 {
1721     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1722     return pWindowImpl->mePackType;
1723 }
1724 
set_pack_type(VclPackType ePackType)1725 void Window::set_pack_type(VclPackType ePackType)
1726 {
1727     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1728     pWindowImpl->mePackType = ePackType;
1729 }
1730 
get_padding() const1731 sal_Int32 Window::get_padding() const
1732 {
1733     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1734     return pWindowImpl->mnPadding;
1735 }
1736 
set_padding(sal_Int32 nPadding)1737 void Window::set_padding(sal_Int32 nPadding)
1738 {
1739     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1740     pWindowImpl->mnPadding = nPadding;
1741 }
1742 
get_fill() const1743 bool Window::get_fill() const
1744 {
1745     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1746     return pWindowImpl->mbFill;
1747 }
1748 
set_fill(bool bFill)1749 void Window::set_fill(bool bFill)
1750 {
1751     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1752     pWindowImpl->mbFill = bFill;
1753 }
1754 
get_grid_width() const1755 sal_Int32 Window::get_grid_width() const
1756 {
1757     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1758     return pWindowImpl->mnGridWidth;
1759 }
1760 
set_grid_width(sal_Int32 nCols)1761 void Window::set_grid_width(sal_Int32 nCols)
1762 {
1763     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1764     pWindowImpl->mnGridWidth = nCols;
1765 }
1766 
get_grid_left_attach() const1767 sal_Int32 Window::get_grid_left_attach() const
1768 {
1769     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1770     return pWindowImpl->mnGridLeftAttach;
1771 }
1772 
set_grid_left_attach(sal_Int32 nAttach)1773 void Window::set_grid_left_attach(sal_Int32 nAttach)
1774 {
1775     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1776     pWindowImpl->mnGridLeftAttach = nAttach;
1777 }
1778 
get_grid_height() const1779 sal_Int32 Window::get_grid_height() const
1780 {
1781     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1782     return pWindowImpl->mnGridHeight;
1783 }
1784 
set_grid_height(sal_Int32 nRows)1785 void Window::set_grid_height(sal_Int32 nRows)
1786 {
1787     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1788     pWindowImpl->mnGridHeight = nRows;
1789 }
1790 
get_grid_top_attach() const1791 sal_Int32 Window::get_grid_top_attach() const
1792 {
1793     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1794     return pWindowImpl->mnGridTopAttach;
1795 }
1796 
set_grid_top_attach(sal_Int32 nAttach)1797 void Window::set_grid_top_attach(sal_Int32 nAttach)
1798 {
1799     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1800     pWindowImpl->mnGridTopAttach = nAttach;
1801 }
1802 
set_border_width(sal_Int32 nBorderWidth)1803 void Window::set_border_width(sal_Int32 nBorderWidth)
1804 {
1805     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1806     pWindowImpl->mnBorderWidth = nBorderWidth;
1807 }
1808 
get_border_width() const1809 sal_Int32 Window::get_border_width() const
1810 {
1811     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1812     return pWindowImpl->mnBorderWidth;
1813 }
1814 
set_margin_left(sal_Int32 nWidth)1815 void Window::set_margin_left(sal_Int32 nWidth)
1816 {
1817     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1818     if (pWindowImpl->mnMarginLeft != nWidth)
1819     {
1820         pWindowImpl->mnMarginLeft = nWidth;
1821         queue_resize();
1822     }
1823 }
1824 
get_margin_left() const1825 sal_Int32 Window::get_margin_left() const
1826 {
1827     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1828     return pWindowImpl->mnMarginLeft;
1829 }
1830 
set_margin_right(sal_Int32 nWidth)1831 void Window::set_margin_right(sal_Int32 nWidth)
1832 {
1833     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1834     if (pWindowImpl->mnMarginRight != nWidth)
1835     {
1836         pWindowImpl->mnMarginRight = nWidth;
1837         queue_resize();
1838     }
1839 }
1840 
get_margin_right() const1841 sal_Int32 Window::get_margin_right() const
1842 {
1843     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1844     return pWindowImpl->mnMarginRight;
1845 }
1846 
set_margin_top(sal_Int32 nWidth)1847 void Window::set_margin_top(sal_Int32 nWidth)
1848 {
1849     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1850     if (pWindowImpl->mnMarginTop != nWidth)
1851     {
1852         pWindowImpl->mnMarginTop = nWidth;
1853         queue_resize();
1854     }
1855 }
1856 
get_margin_top() const1857 sal_Int32 Window::get_margin_top() const
1858 {
1859     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1860     return pWindowImpl->mnMarginTop;
1861 }
1862 
set_margin_bottom(sal_Int32 nWidth)1863 void Window::set_margin_bottom(sal_Int32 nWidth)
1864 {
1865     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1866     if (pWindowImpl->mnMarginBottom != nWidth)
1867     {
1868         pWindowImpl->mnMarginBottom = nWidth;
1869         queue_resize();
1870     }
1871 }
1872 
get_margin_bottom() const1873 sal_Int32 Window::get_margin_bottom() const
1874 {
1875     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1876     return pWindowImpl->mnMarginBottom;
1877 }
1878 
get_height_request() const1879 sal_Int32 Window::get_height_request() const
1880 {
1881     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1882     return pWindowImpl->mnHeightRequest;
1883 }
1884 
get_width_request() const1885 sal_Int32 Window::get_width_request() const
1886 {
1887     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1888     return pWindowImpl->mnWidthRequest;
1889 }
1890 
get_secondary() const1891 bool Window::get_secondary() const
1892 {
1893     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1894     return pWindowImpl->mbSecondary;
1895 }
1896 
set_secondary(bool bSecondary)1897 void Window::set_secondary(bool bSecondary)
1898 {
1899     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1900     pWindowImpl->mbSecondary = bSecondary;
1901 }
1902 
get_non_homogeneous() const1903 bool Window::get_non_homogeneous() const
1904 {
1905     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1906     return pWindowImpl->mbNonHomogeneous;
1907 }
1908 
set_non_homogeneous(bool bNonHomogeneous)1909 void Window::set_non_homogeneous(bool bNonHomogeneous)
1910 {
1911     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1912     pWindowImpl->mbNonHomogeneous = bNonHomogeneous;
1913 }
1914 
add_to_size_group(const std::shared_ptr<VclSizeGroup> & xGroup)1915 void Window::add_to_size_group(const std::shared_ptr<VclSizeGroup>& xGroup)
1916 {
1917     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1918     //To-Do, multiple groups
1919     pWindowImpl->m_xSizeGroup = xGroup;
1920     pWindowImpl->m_xSizeGroup->insert(this);
1921     if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1922         queue_resize();
1923 }
1924 
remove_from_all_size_groups()1925 void Window::remove_from_all_size_groups()
1926 {
1927     WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1928     //To-Do, multiple groups
1929     if (pWindowImpl->m_xSizeGroup)
1930     {
1931         if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1932             queue_resize();
1933         pWindowImpl->m_xSizeGroup->erase(this);
1934         pWindowImpl->m_xSizeGroup.reset();
1935     }
1936 }
1937 
add_mnemonic_label(FixedText * pLabel)1938 void Window::add_mnemonic_label(FixedText *pLabel)
1939 {
1940     std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1941     if (std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel)) != v.end())
1942         return;
1943     v.emplace_back(pLabel);
1944     pLabel->set_mnemonic_widget(this);
1945 }
1946 
remove_mnemonic_label(FixedText * pLabel)1947 void Window::remove_mnemonic_label(FixedText *pLabel)
1948 {
1949     std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1950     auto aFind = std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel));
1951     if (aFind == v.end())
1952         return;
1953     v.erase(aFind);
1954     pLabel->set_mnemonic_widget(nullptr);
1955 }
1956 
list_mnemonic_labels() const1957 const std::vector<VclPtr<FixedText> >& Window::list_mnemonic_labels() const
1958 {
1959     return mpWindowImpl->m_aMnemonicLabels;
1960 }
1961 
1962 } /* namespace vcl */
1963 
DrawFocusRect(vcl::RenderContext & rRenderContext,const tools::Rectangle & rRect)1964 void DrawFocusRect(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
1965 {
1966     const int nBorder = 1;
1967     rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1968     rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Bottom()-nBorder+1), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1969     rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1970     rRenderContext.Invert(tools::Rectangle(Point(rRect.Right()-nBorder+1, rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1971 }
1972 
1973 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1974